mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
WIP: Remove corp employees as objects (#143)
* Removed employees as objects from corporations * Remove employees from office JSON after loading / convert to new parameters * Showed down morale/etc gain; added optional position to hireEmployee * enum support for corp employee positions Mostly authored-by: Kelenius <kelenius@ya.ru>
This commit is contained in:
parent
6095e63369
commit
0a3ff56331
@ -464,7 +464,7 @@ export const achievements: Record<string, Achievement> = {
|
||||
for (const d of Player.corporation.divisions) {
|
||||
for (const o of Object.values(d.offices)) {
|
||||
if (o === 0) continue;
|
||||
if (o.employees.length >= 3000) return true;
|
||||
if (o.totalEmployees >= 3000) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -302,13 +302,6 @@ export function BuyBackShares(corporation: Corporation, numShares: number): bool
|
||||
return true;
|
||||
}
|
||||
|
||||
export function AssignJob(office: OfficeSpace, employeeName: string, job: string): void {
|
||||
const employee = office.employees.find((e) => e.name === employeeName);
|
||||
if (!employee) throw new Error(`Could not find employee '${name}'.`);
|
||||
if (!checkEnum(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`);
|
||||
office.assignSingleJob(employee, job);
|
||||
}
|
||||
|
||||
export function AutoAssignJob(office: OfficeSpace, job: string, count: number): boolean {
|
||||
if (!checkEnum(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`);
|
||||
return office.autoAssignJob(job, count);
|
||||
@ -344,7 +337,7 @@ export function BuyCoffee(corp: Corporation, office: OfficeSpace): boolean {
|
||||
|
||||
export function ThrowParty(corp: Corporation, office: OfficeSpace, costPerEmployee: number): number {
|
||||
const mult = 1 + costPerEmployee / 10e6;
|
||||
const cost = costPerEmployee * office.employees.length;
|
||||
const cost = costPerEmployee * office.totalEmployees;
|
||||
if (corp.funds < cost) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,125 +0,0 @@
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver";
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
import { Corporation } from "./Corporation";
|
||||
import { Industry } from "./Industry";
|
||||
|
||||
interface IParams {
|
||||
name?: string;
|
||||
morale?: number;
|
||||
happiness?: number;
|
||||
energy?: number;
|
||||
intelligence?: number;
|
||||
charisma?: number;
|
||||
experience?: number;
|
||||
creativity?: number;
|
||||
efficiency?: number;
|
||||
salary?: number;
|
||||
loc?: string;
|
||||
}
|
||||
|
||||
export class Employee {
|
||||
name: string;
|
||||
mor: number;
|
||||
hap: number;
|
||||
ene: number;
|
||||
int: number;
|
||||
cha: number;
|
||||
exp: number;
|
||||
cre: number;
|
||||
eff: number;
|
||||
sal: number;
|
||||
cyclesUntilRaise = CorporationConstants.CyclesPerEmployeeRaise;
|
||||
loc: string;
|
||||
pos: string;
|
||||
nextPos: string;
|
||||
|
||||
constructor(params: IParams = {}) {
|
||||
this.name = params.name ? params.name : "Bobby";
|
||||
|
||||
//Morale, happiness, and energy are 0-100
|
||||
this.mor = params.morale ? params.morale : getRandomInt(50, 100);
|
||||
this.hap = params.happiness ? params.happiness : getRandomInt(50, 100);
|
||||
this.ene = params.energy ? params.energy : getRandomInt(50, 100);
|
||||
|
||||
this.int = params.intelligence ? params.intelligence : getRandomInt(10, 50);
|
||||
this.cha = params.charisma ? params.charisma : getRandomInt(10, 50);
|
||||
this.exp = params.experience ? params.experience : getRandomInt(10, 50);
|
||||
this.cre = params.creativity ? params.creativity : getRandomInt(10, 50);
|
||||
this.eff = params.efficiency ? params.efficiency : getRandomInt(10, 50);
|
||||
this.sal = params.salary ? params.salary : getRandomInt(0.1, 5);
|
||||
|
||||
this.loc = params.loc ? params.loc : "";
|
||||
this.pos = EmployeePositions.Unassigned;
|
||||
this.nextPos = this.pos;
|
||||
}
|
||||
|
||||
//Returns the amount the employee needs to be paid
|
||||
process(marketCycles = 1): number {
|
||||
const gain = 0.003 * marketCycles;
|
||||
const det = gain * Math.random();
|
||||
this.exp += gain;
|
||||
|
||||
//Training
|
||||
const trainingEff = gain * Math.random();
|
||||
if (this.pos === EmployeePositions.Training) {
|
||||
//To increase creativity and intelligence special upgrades are needed
|
||||
this.cha += trainingEff;
|
||||
this.exp += trainingEff;
|
||||
this.eff += trainingEff;
|
||||
}
|
||||
|
||||
this.ene -= det;
|
||||
this.hap -= det;
|
||||
|
||||
const salary = this.sal * marketCycles * CorporationConstants.SecsPerMarketCycle;
|
||||
return salary;
|
||||
}
|
||||
|
||||
calculateProductivity(corporation: Corporation, industry: Industry): number {
|
||||
const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
|
||||
effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
||||
effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
||||
effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
||||
const prodBase = this.mor * this.hap * this.ene * 1e-6;
|
||||
let prodMult = 0;
|
||||
switch (this.pos) {
|
||||
//Calculate productivity based on position. This is multiplied by prodBase
|
||||
//to get final value
|
||||
case EmployeePositions.Operations:
|
||||
prodMult = 0.6 * effInt + 0.1 * effCha + this.exp + 0.5 * effCre + effEff;
|
||||
break;
|
||||
case EmployeePositions.Engineer:
|
||||
prodMult = effInt + 0.1 * effCha + 1.5 * this.exp + effEff;
|
||||
break;
|
||||
case EmployeePositions.Business:
|
||||
prodMult = 0.4 * effInt + effCha + 0.5 * this.exp;
|
||||
break;
|
||||
case EmployeePositions.Management:
|
||||
prodMult = 2 * effCha + this.exp + 0.2 * effCre + 0.7 * effEff;
|
||||
break;
|
||||
case EmployeePositions.RandD:
|
||||
prodMult = 1.5 * effInt + 0.8 * this.exp + effCre + 0.5 * effEff;
|
||||
break;
|
||||
case EmployeePositions.Unassigned:
|
||||
case EmployeePositions.Training:
|
||||
prodMult = 0;
|
||||
break;
|
||||
default:
|
||||
console.error(`Invalid employee position: ${this.pos}`);
|
||||
break;
|
||||
}
|
||||
return prodBase * prodMult;
|
||||
}
|
||||
|
||||
toJSON(): IReviverValue {
|
||||
return Generic_toJSON("Employee", this);
|
||||
}
|
||||
|
||||
static fromJSON(value: IReviverValue): Employee {
|
||||
return Generic_fromJSON(Employee, value.data);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.Employee = Employee;
|
@ -1,9 +1,6 @@
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { generateRandomString } from "../utils/StringHelperFunctions";
|
||||
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver";
|
||||
import { Employee } from "./Employee";
|
||||
import { Industry } from "./Industry";
|
||||
import { Corporation } from "./Corporation";
|
||||
|
||||
@ -24,6 +21,19 @@ export class OfficeSpace {
|
||||
maxHap = 100;
|
||||
maxMor = 100;
|
||||
|
||||
avgEne = 75;
|
||||
avgHap = 75;
|
||||
avgMor = 75;
|
||||
|
||||
avgInt = 75;
|
||||
avgCha = 75;
|
||||
totalExp = 0;
|
||||
avgCre = 75;
|
||||
avgEff = 75;
|
||||
|
||||
totalEmployees = 0;
|
||||
totalSalary = 0;
|
||||
|
||||
autoCoffee = false;
|
||||
autoParty = false;
|
||||
coffeeMult = 0;
|
||||
@ -31,16 +41,17 @@ export class OfficeSpace {
|
||||
coffeeEmployees = 0;
|
||||
partyEmployees = 0;
|
||||
|
||||
employees: Employee[] = [];
|
||||
employeeProd: { [key: string]: number } = {
|
||||
employeeProd: Record<EmployeePositions | "total", number> = {
|
||||
[EmployeePositions.Operations]: 0,
|
||||
[EmployeePositions.Engineer]: 0,
|
||||
[EmployeePositions.Business]: 0,
|
||||
[EmployeePositions.Management]: 0,
|
||||
[EmployeePositions.RandD]: 0,
|
||||
[EmployeePositions.Training]: 0,
|
||||
[EmployeePositions.Unassigned]: 0,
|
||||
total: 0,
|
||||
};
|
||||
employeeJobs: { [key: string]: number } = {
|
||||
employeeJobs: Record<EmployeePositions, number> = {
|
||||
[EmployeePositions.Operations]: 0,
|
||||
[EmployeePositions.Engineer]: 0,
|
||||
[EmployeePositions.Business]: 0,
|
||||
@ -49,7 +60,7 @@ export class OfficeSpace {
|
||||
[EmployeePositions.Training]: 0,
|
||||
[EmployeePositions.Unassigned]: 0,
|
||||
};
|
||||
employeeNextJobs: { [key: string]: number } = {
|
||||
employeeNextJobs: Record<EmployeePositions, number> = {
|
||||
[EmployeePositions.Operations]: 0,
|
||||
[EmployeePositions.Engineer]: 0,
|
||||
[EmployeePositions.Business]: 0,
|
||||
@ -65,24 +76,21 @@ export class OfficeSpace {
|
||||
}
|
||||
|
||||
atCapacity(): boolean {
|
||||
return this.employees.length >= this.size;
|
||||
return this.totalEmployees >= this.size;
|
||||
}
|
||||
|
||||
process(marketCycles = 1, corporation: Corporation, industry: Industry): number {
|
||||
// HRBuddy AutoRecruitment and training
|
||||
if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
|
||||
const emp = this.hireRandomEmployee();
|
||||
if (industry.hasResearch("HRBuddy-Training") && emp !== undefined) {
|
||||
emp.pos = EmployeePositions.Training;
|
||||
}
|
||||
this.hireRandomEmployee(
|
||||
industry.hasResearch("HRBuddy-Training") ? EmployeePositions.Training : EmployeePositions.Unassigned,
|
||||
);
|
||||
}
|
||||
|
||||
// Update employee jobs and job counts
|
||||
for (const employee of this.employees) {
|
||||
employee.pos = employee.nextPos;
|
||||
for (const [pos, jobCount] of Object.entries(this.employeeNextJobs) as [EmployeePositions, number][]) {
|
||||
this.employeeJobs[pos] = jobCount;
|
||||
}
|
||||
this.calculateTotalEmployees();
|
||||
this.calculateNextEmployees();
|
||||
|
||||
// Process Office properties
|
||||
this.maxEne = 100;
|
||||
@ -105,162 +113,149 @@ export class OfficeSpace {
|
||||
this.autoParty = true;
|
||||
}
|
||||
|
||||
// Calculate changes in Morale/Happiness/Energy for Employees
|
||||
let perfMult = 1; //Multiplier for employee morale/happiness/energy based on company performance
|
||||
if (corporation.funds < 0 && industry.lastCycleRevenue < 0) {
|
||||
perfMult = Math.pow(0.99, marketCycles);
|
||||
} else if (corporation.funds > 0 && industry.lastCycleRevenue > 0) {
|
||||
perfMult = Math.pow(1.01, marketCycles);
|
||||
}
|
||||
|
||||
let totalSalary = 0;
|
||||
for (const employee of this.employees) {
|
||||
const salary = employee.process(marketCycles);
|
||||
totalSalary += salary;
|
||||
if (this.totalEmployees > 0) {
|
||||
// Calculate changes in Morale/Happiness/Energy for Employees
|
||||
let perfMult = 1; //Multiplier for employee morale/happiness/energy based on company performance
|
||||
const reduction = 0.0015 * marketCycles; // Passive reduction every cycle
|
||||
if (corporation.funds < 0 && industry.lastCycleRevenue < 0) {
|
||||
perfMult = Math.pow(0.995, marketCycles);
|
||||
} else if (corporation.funds > 0 && industry.lastCycleRevenue > 0) {
|
||||
perfMult = Math.pow(1.005, marketCycles);
|
||||
}
|
||||
|
||||
if (this.autoCoffee) {
|
||||
employee.ene = this.maxEne;
|
||||
this.avgEne = this.maxEne;
|
||||
} else if (this.coffeeMult > 1) {
|
||||
const mult = 1 + ((this.coffeeMult - 1) * this.employees.length) / this.coffeeEmployees;
|
||||
employee.ene *= mult;
|
||||
this.avgEne -= reduction;
|
||||
this.avgEne *= (this.coffeeMult * this.coffeeEmployees) / this.totalEmployees;
|
||||
} else {
|
||||
employee.ene *= perfMult;
|
||||
this.avgEne -= reduction;
|
||||
this.avgEne *= perfMult;
|
||||
}
|
||||
|
||||
if (this.autoParty) {
|
||||
employee.mor = this.maxMor;
|
||||
employee.hap = this.maxHap;
|
||||
this.avgMor = this.maxMor;
|
||||
this.avgHap = this.maxHap;
|
||||
} else if (this.partyMult > 1) {
|
||||
const mult = 1 + ((this.partyMult - 1) * this.employees.length) / this.partyEmployees;
|
||||
employee.mor *= mult;
|
||||
employee.hap *= mult;
|
||||
this.avgHap -= reduction;
|
||||
this.avgMor *= (this.partyMult * this.partyEmployees) / this.totalEmployees;
|
||||
this.avgHap *= (this.partyMult * this.partyEmployees) / this.totalEmployees;
|
||||
} else {
|
||||
employee.mor *= perfMult;
|
||||
employee.hap *= perfMult;
|
||||
this.avgHap -= reduction;
|
||||
this.avgMor *= perfMult;
|
||||
this.avgHap *= perfMult;
|
||||
}
|
||||
|
||||
employee.ene = Math.max(Math.min(employee.ene, this.maxEne), this.minEne);
|
||||
employee.mor = Math.max(Math.min(employee.mor, this.maxMor), this.minMor);
|
||||
employee.hap = Math.max(Math.min(employee.hap, this.maxHap), this.minHap);
|
||||
this.avgEne = Math.max(Math.min(this.avgEne, this.maxEne), this.minEne);
|
||||
this.avgMor = Math.max(Math.min(this.avgMor, this.maxMor), this.minMor);
|
||||
this.avgHap = Math.max(Math.min(this.avgHap, this.maxHap), this.minHap);
|
||||
|
||||
this.coffeeMult = 0;
|
||||
this.partyMult = 0;
|
||||
this.coffeeEmployees = 0;
|
||||
this.partyEmployees = 0;
|
||||
}
|
||||
|
||||
this.coffeeMult = 0;
|
||||
this.partyMult = 0;
|
||||
this.coffeeEmployees = 0;
|
||||
this.partyEmployees = 0;
|
||||
// Get experience increase; unassigned employees do not contribute, employees in training contribute 5x
|
||||
this.totalExp +=
|
||||
0.0015 *
|
||||
marketCycles *
|
||||
(this.totalEmployees -
|
||||
this.employeeJobs[EmployeePositions.Unassigned] +
|
||||
this.employeeJobs[EmployeePositions.Training] * 4);
|
||||
|
||||
this.calculateEmployeeProductivity(corporation, industry);
|
||||
return totalSalary;
|
||||
}
|
||||
|
||||
calculateNextEmployees(): void {
|
||||
//Reset
|
||||
for (const name of Object.keys(this.employeeNextJobs)) {
|
||||
this.employeeNextJobs[name] = 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.employees.length; ++i) {
|
||||
const employee = this.employees[i];
|
||||
this.employeeNextJobs[employee.nextPos]++;
|
||||
}
|
||||
}
|
||||
|
||||
calculateTotalEmployees(): void {
|
||||
//Reset
|
||||
for (const name of Object.keys(this.employeeJobs)) {
|
||||
this.employeeJobs[name] = 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.employees.length; ++i) {
|
||||
const employee = this.employees[i];
|
||||
this.employeeJobs[employee.pos]++;
|
||||
if (this.totalEmployees === 0) {
|
||||
this.totalSalary = 0;
|
||||
} else {
|
||||
this.totalSalary =
|
||||
CorporationConstants.EmployeeSalaryMultiplier *
|
||||
marketCycles *
|
||||
this.totalEmployees *
|
||||
(this.avgInt + this.avgCha + this.totalExp / this.totalEmployees + this.avgCre + this.avgEff);
|
||||
}
|
||||
return this.totalSalary;
|
||||
}
|
||||
|
||||
calculateEmployeeProductivity(corporation: Corporation, industry: Industry): void {
|
||||
//Reset
|
||||
for (const name of Object.keys(this.employeeProd)) {
|
||||
this.employeeProd[name] = 0;
|
||||
}
|
||||
const effCre = this.avgCre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
|
||||
effCha = this.avgCha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
||||
effInt = this.avgInt * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
||||
effEff = this.avgEff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
||||
const prodBase = this.avgMor * this.avgHap * this.avgEne * 1e-6;
|
||||
|
||||
let total = 0;
|
||||
for (let i = 0; i < this.employees.length; ++i) {
|
||||
const employee = this.employees[i];
|
||||
const prod = employee.calculateProductivity(corporation, industry);
|
||||
this.employeeProd[employee.pos] += prod;
|
||||
total += prod;
|
||||
const exp = this.totalExp / this.totalEmployees || 0;
|
||||
for (const name of Object.keys(this.employeeProd) as (EmployeePositions | "total")[]) {
|
||||
let prodMult = 0;
|
||||
switch (name) {
|
||||
case EmployeePositions.Operations:
|
||||
prodMult = 0.6 * effInt + 0.1 * effCha + exp + 0.5 * effCre + effEff;
|
||||
break;
|
||||
case EmployeePositions.Engineer:
|
||||
prodMult = effInt + 0.1 * effCha + 1.5 * exp + effEff;
|
||||
break;
|
||||
case EmployeePositions.Business:
|
||||
prodMult = 0.4 * effInt + effCha + 0.5 * exp;
|
||||
break;
|
||||
case EmployeePositions.Management:
|
||||
prodMult = 2 * effCha + exp + 0.2 * effCre + 0.7 * effEff;
|
||||
break;
|
||||
case EmployeePositions.RandD:
|
||||
prodMult = 1.5 * effInt + 0.8 * exp + effCre + 0.5 * effEff;
|
||||
break;
|
||||
case EmployeePositions.Unassigned:
|
||||
case EmployeePositions.Training:
|
||||
case "total":
|
||||
continue;
|
||||
default:
|
||||
console.error(`Invalid employee position: ${name}`);
|
||||
break;
|
||||
}
|
||||
this.employeeProd[name] = this.employeeJobs[name] * prodMult * prodBase;
|
||||
total += this.employeeProd[name];
|
||||
}
|
||||
|
||||
this.employeeProd.total = total;
|
||||
}
|
||||
|
||||
hireRandomEmployee(): Employee | undefined {
|
||||
if (this.atCapacity()) return;
|
||||
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return;
|
||||
hireRandomEmployee(position: EmployeePositions): boolean {
|
||||
if (this.atCapacity()) return false;
|
||||
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return false;
|
||||
|
||||
//Generate three random employees (meh, decent, amazing)
|
||||
const int = getRandomInt(50, 100),
|
||||
cha = getRandomInt(50, 100),
|
||||
exp = getRandomInt(50, 100),
|
||||
cre = getRandomInt(50, 100),
|
||||
eff = getRandomInt(50, 100),
|
||||
sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
|
||||
++this.totalEmployees;
|
||||
++this.employeeJobs[position];
|
||||
++this.employeeNextJobs[position];
|
||||
|
||||
const emp = new Employee({
|
||||
intelligence: int,
|
||||
charisma: cha,
|
||||
experience: exp,
|
||||
creativity: cre,
|
||||
efficiency: eff,
|
||||
salary: sal,
|
||||
});
|
||||
|
||||
const name = generateRandomString(7);
|
||||
|
||||
for (let i = 0; i < this.employees.length; ++i) {
|
||||
if (this.employees[i].name === name) {
|
||||
return this.hireRandomEmployee();
|
||||
}
|
||||
}
|
||||
emp.name = name;
|
||||
this.employees.push(emp);
|
||||
|
||||
this.calculateTotalEmployees();
|
||||
this.calculateNextEmployees();
|
||||
return emp;
|
||||
this.totalExp += 75;
|
||||
this.avgMor = (this.avgMor * this.totalEmployees + 75) / (this.totalEmployees + 1);
|
||||
this.avgHap = (this.avgHap * this.totalEmployees + 75) / (this.totalEmployees + 1);
|
||||
this.avgEne = (this.avgEne * this.totalEmployees + 75) / (this.totalEmployees + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
assignSingleJob(employee: Employee, job: string): void {
|
||||
employee.nextPos = job;
|
||||
this.calculateNextEmployees();
|
||||
}
|
||||
autoAssignJob(job: EmployeePositions, target: number): boolean {
|
||||
const diff = target - this.employeeNextJobs[job];
|
||||
|
||||
autoAssignJob(job: string, target: number): boolean {
|
||||
let count = this.employeeNextJobs[job];
|
||||
|
||||
for (const employee of this.employees) {
|
||||
if (count === target) {
|
||||
break;
|
||||
} else if (employee.nextPos === EmployeePositions.Unassigned && count <= target) {
|
||||
employee.nextPos = job;
|
||||
count++;
|
||||
} else if (employee.nextPos === job && count >= target) {
|
||||
employee.nextPos = EmployeePositions.Unassigned;
|
||||
count--;
|
||||
}
|
||||
if (diff === 0) {
|
||||
return true;
|
||||
} else if (diff <= this.employeeNextJobs[EmployeePositions.Unassigned]) {
|
||||
// This covers both a negative diff (reducing the amount of employees in position) and a positive (increasing and using up unassigned employees)
|
||||
this.employeeNextJobs[EmployeePositions.Unassigned] -= diff;
|
||||
this.employeeNextJobs[job] = target;
|
||||
return true;
|
||||
}
|
||||
|
||||
this.calculateNextEmployees();
|
||||
return count === target;
|
||||
return false;
|
||||
}
|
||||
|
||||
getCoffeeCost(): number {
|
||||
return 500e3 * this.employees.length;
|
||||
return 500e3 * this.totalEmployees;
|
||||
}
|
||||
|
||||
setCoffee(mult = 1.05): boolean {
|
||||
if (mult > 1 && this.coffeeMult === 0 && !this.autoCoffee && this.employees.length > 0) {
|
||||
if (mult > 1 && this.coffeeMult === 0 && !this.autoCoffee && this.totalEmployees > 0) {
|
||||
this.coffeeMult = mult;
|
||||
this.coffeeEmployees = this.employees.length;
|
||||
this.coffeeEmployees = this.totalEmployees;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -268,9 +263,9 @@ export class OfficeSpace {
|
||||
}
|
||||
|
||||
setParty(mult: number): boolean {
|
||||
if (mult > 1 && this.partyMult === 0 && !this.autoParty && this.employees.length > 0) {
|
||||
if (mult > 1 && this.partyMult === 0 && !this.autoParty && this.totalEmployees > 0) {
|
||||
this.partyMult = mult;
|
||||
this.partyEmployees = this.employees.length;
|
||||
this.partyEmployees = this.totalEmployees;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -282,6 +277,18 @@ export class OfficeSpace {
|
||||
}
|
||||
|
||||
static fromJSON(value: IReviverValue): OfficeSpace {
|
||||
// Convert employees from the old version
|
||||
if (value.data.hasOwnProperty("employees")) {
|
||||
const empCopy: [{ data: { hap: number; mor: number; ene: number; exp: number } }] = value.data.employees;
|
||||
delete value.data.employees;
|
||||
const ret = Generic_fromJSON(OfficeSpace, value.data);
|
||||
ret.totalEmployees = empCopy.length;
|
||||
ret.avgHap = empCopy.reduce((a, b) => a + b.data.hap, 0) / ret.totalEmployees || 75;
|
||||
ret.avgMor = empCopy.reduce((a, b) => a + b.data.mor, 0) / ret.totalEmployees || 75;
|
||||
ret.avgEne = empCopy.reduce((a, b) => a + b.data.ene, 0) / ret.totalEmployees || 75;
|
||||
ret.totalExp = empCopy.reduce((a, b) => a + b.data.exp, 0);
|
||||
return ret;
|
||||
}
|
||||
return Generic_fromJSON(OfficeSpace, value.data);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { OfficeSpace } from "../OfficeSpace";
|
||||
import { Employee } from "../Employee";
|
||||
import { EmployeePositions } from "../EmployeePositions";
|
||||
import { BuyCoffee } from "../Actions";
|
||||
|
||||
@ -23,8 +22,6 @@ import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
|
||||
import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp";
|
||||
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
@ -36,139 +33,9 @@ interface IProps {
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
interface ISwitchProps {
|
||||
manualMode: boolean;
|
||||
switchMode: (f: (b: boolean) => boolean) => void;
|
||||
}
|
||||
|
||||
function SwitchButton(props: ISwitchProps): React.ReactElement {
|
||||
if (props.manualMode) {
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
Switch to Automatic Assignment Mode, which will automatically assign employees to your selected jobs. You
|
||||
simply have to select the number of assignments for each job
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Button onClick={() => props.switchMode((old) => !old)}>Switch to Auto Mode</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
Switch to Manual Assignment Mode, which allows you to specify which employees should get which jobs
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Button onClick={() => props.switchMode((old) => !old)}>Switch to Manual Mode</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function ManualManagement(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const [employee, setEmployee] = useState<Employee | null>(
|
||||
props.office.employees.length > 0 ? props.office.employees[0] : null,
|
||||
);
|
||||
|
||||
// Employee Selector
|
||||
const employees = [];
|
||||
for (let i = 0; i < props.office.employees.length; ++i) {
|
||||
employees.push(
|
||||
<MenuItem key={props.office.employees[i].name} value={props.office.employees[i].name}>
|
||||
{props.office.employees[i].name}
|
||||
</MenuItem>,
|
||||
);
|
||||
}
|
||||
|
||||
function employeeSelectorOnChange(e: SelectChangeEvent<string>): void {
|
||||
const name = e.target.value;
|
||||
for (let i = 0; i < props.office.employees.length; ++i) {
|
||||
if (name === props.office.employees[i].name) {
|
||||
setEmployee(props.office.employees[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
// Employee Positions Selector
|
||||
const emp = employee;
|
||||
let employeePositionSelectorInitialValue = "";
|
||||
const employeePositions = [];
|
||||
const positionNames = Object.values(EmployeePositions);
|
||||
for (let i = 0; i < positionNames.length; ++i) {
|
||||
employeePositions.push(
|
||||
<MenuItem key={positionNames[i]} value={positionNames[i]}>
|
||||
{positionNames[i]}
|
||||
</MenuItem>,
|
||||
);
|
||||
if (emp != null && emp.nextPos === positionNames[i]) {
|
||||
employeePositionSelectorInitialValue = emp.nextPos;
|
||||
}
|
||||
}
|
||||
|
||||
function employeePositionSelectorOnChange(e: SelectChangeEvent<string>): void {
|
||||
if (employee === null) return;
|
||||
props.office.assignSingleJob(employee, e.target.value);
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
// Numeral.js formatter
|
||||
const nf = "0.000";
|
||||
|
||||
// Employee stats (after applying multipliers)
|
||||
const effCre = emp ? emp.cre * corp.getEmployeeCreMultiplier() * division.getEmployeeCreMultiplier() : 0;
|
||||
const effCha = emp ? emp.cha * corp.getEmployeeChaMultiplier() * division.getEmployeeChaMultiplier() : 0;
|
||||
const effInt = emp ? emp.int * corp.getEmployeeIntMultiplier() * division.getEmployeeIntMultiplier() : 0;
|
||||
const effEff = emp ? emp.eff * corp.getEmployeeEffMultiplier() * division.getEmployeeEffMultiplier() : 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<br />
|
||||
<Select value={employee !== null ? employee.name : ""} onChange={employeeSelectorOnChange}>
|
||||
{employees}
|
||||
</Select>
|
||||
{employee != null && (
|
||||
<Typography>
|
||||
Morale: {numeralWrapper.format(employee.mor, nf)}
|
||||
<br />
|
||||
Happiness: {numeralWrapper.format(employee.hap, nf)}
|
||||
<br />
|
||||
Energy: {numeralWrapper.format(employee.ene, nf)}
|
||||
<br />
|
||||
Intelligence: {numeralWrapper.format(effInt, nf)}
|
||||
<br />
|
||||
Charisma: {numeralWrapper.format(effCha, nf)}
|
||||
<br />
|
||||
Experience: {numeralWrapper.format(employee.exp, nf)}
|
||||
<br />
|
||||
Creativity: {numeralWrapper.format(effCre, nf)}
|
||||
<br />
|
||||
Efficiency: {numeralWrapper.format(effEff, nf)}
|
||||
<br />
|
||||
Salary: <Money money={employee.sal} />
|
||||
</Typography>
|
||||
)}
|
||||
{employee != null && (
|
||||
<Select onChange={employeePositionSelectorOnChange} value={employeePositionSelectorInitialValue}>
|
||||
{employeePositions}
|
||||
</Select>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface IAutoAssignProps {
|
||||
office: OfficeSpace;
|
||||
job: string;
|
||||
job: EmployeePositions;
|
||||
desc: string;
|
||||
rerender: () => void;
|
||||
}
|
||||
@ -232,27 +99,6 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
const vechain = corp.unlockUpgrades[4] === 1; // Has Vechain upgrade
|
||||
|
||||
// Calculate average morale, happiness, energy, and salary.
|
||||
let totalMorale = 0,
|
||||
totalHappiness = 0,
|
||||
totalEnergy = 0,
|
||||
totalSalary = 0;
|
||||
for (let i = 0; i < props.office.employees.length; ++i) {
|
||||
totalMorale += props.office.employees[i].mor;
|
||||
totalHappiness += props.office.employees[i].hap;
|
||||
totalEnergy += props.office.employees[i].ene;
|
||||
totalSalary += props.office.employees[i].sal;
|
||||
}
|
||||
|
||||
let avgMorale = 0,
|
||||
avgHappiness = 0,
|
||||
avgEnergy = 0;
|
||||
if (props.office.employees.length > 0) {
|
||||
avgMorale = totalMorale / props.office.employees.length;
|
||||
avgHappiness = totalHappiness / props.office.employees.length;
|
||||
avgEnergy = totalEnergy / props.office.employees.length;
|
||||
}
|
||||
|
||||
const currUna = props.office.employeeJobs[EmployeePositions.Unassigned];
|
||||
const nextUna = props.office.employeeNextJobs[EmployeePositions.Unassigned];
|
||||
|
||||
@ -272,7 +118,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<Typography>Avg Employee Morale:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<Typography>{numeralWrapper.format(avgMorale, "0.000")}</Typography>
|
||||
<Typography>{numeralWrapper.format(props.office.avgMor, "0.000")}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
@ -280,7 +126,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<Typography>Avg Employee Happiness:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<Typography>{numeralWrapper.format(avgHappiness, "0.000")}</Typography>
|
||||
<Typography>{numeralWrapper.format(props.office.avgHap, "0.000")}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
@ -288,7 +134,17 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<Typography>Avg Employee Energy:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<Typography>{numeralWrapper.format(avgEnergy, "0.000")}</Typography>
|
||||
<Typography>{numeralWrapper.format(props.office.avgEne, "0.000")}</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography>Avg Employee Experience:</Typography>
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<Typography>
|
||||
{numeralWrapper.format(props.office.totalExp / props.office.totalEmployees || 0, "0.000")}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
@ -297,7 +153,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography align="right">
|
||||
<Money money={totalSalary} />
|
||||
<Money money={props.office.totalSalary} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@ -419,11 +275,10 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
const [upgradeOfficeSizeOpen, setUpgradeOfficeSizeOpen] = useState(false);
|
||||
const [throwPartyOpen, setThrowPartyOpen] = useState(false);
|
||||
const [employeeManualAssignMode, setEmployeeManualAssignMode] = useState(false);
|
||||
|
||||
function autohireEmployeeButtonOnClick(): void {
|
||||
if (props.office.atCapacity()) return;
|
||||
props.office.hireRandomEmployee();
|
||||
props.office.hireRandomEmployee(EmployeePositions.Unassigned);
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
@ -431,11 +286,11 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<Paper>
|
||||
<Typography>Office Space</Typography>
|
||||
<Typography>
|
||||
Size: {props.office.employees.length} / {props.office.size} employees
|
||||
Size: {props.office.totalEmployees} / {props.office.size} employees
|
||||
</Typography>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr", width: "fit-content" }}>
|
||||
<Box sx={{ gridTemplateColumns: "repeat(3, 1fr)" }}>
|
||||
<Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}>
|
||||
<Tooltip title={<Typography>Hires an employee</Typography>}>
|
||||
<span>
|
||||
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
|
||||
Hire Employee
|
||||
@ -502,13 +357,8 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<SwitchButton manualMode={employeeManualAssignMode} switchMode={setEmployeeManualAssignMode} />
|
||||
</Box>
|
||||
{employeeManualAssignMode ? (
|
||||
<ManualManagement rerender={props.rerender} office={props.office} />
|
||||
) : (
|
||||
<AutoManagement rerender={props.rerender} office={props.office} />
|
||||
)}
|
||||
<AutoManagement rerender={props.rerender} office={props.office} />
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const [cost, setCost] = useState(0);
|
||||
|
||||
const totalCost = cost * props.office.employees.length;
|
||||
const totalCost = cost * props.office.totalEmployees;
|
||||
const canParty = corp.funds >= totalCost;
|
||||
function changeCost(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
let x = parseFloat(event.target.value);
|
||||
|
@ -393,7 +393,6 @@ const corporation = {
|
||||
getPurchaseWarehouseCost: 0,
|
||||
getUpgradeWarehouseCost: 0,
|
||||
hasWarehouse: 0,
|
||||
assignJob: 0,
|
||||
hireEmployee: 0,
|
||||
upgradeOfficeSize: 0,
|
||||
throwParty: 0,
|
||||
@ -401,7 +400,6 @@ const corporation = {
|
||||
hireAdVert: 0,
|
||||
research: 0,
|
||||
getOffice: 0,
|
||||
getEmployee: 0,
|
||||
getHireAdVertCost: 0,
|
||||
getHireAdVertCount: 0,
|
||||
getResearchCost: 0,
|
||||
|
@ -78,20 +78,26 @@ import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||
import { getBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { assert, arrayAssert, stringAssert, objectAssert } from "./utils/helpers/typeAssertion";
|
||||
import { CrimeType } from "./utils/WorkType";
|
||||
import { EmployeePositions } from "./Corporation/EmployeePositions";
|
||||
|
||||
export const enums = {
|
||||
toast: ToastVariant,
|
||||
crimes: CrimeType,
|
||||
CrimeType,
|
||||
};
|
||||
|
||||
export type NSFull = Readonly<NS & INetscriptExtra>;
|
||||
|
||||
export function NetscriptFunctions(workerScript: WorkerScript): NSFull {
|
||||
return wrapAPI(workerScript, ns, workerScript.args.slice());
|
||||
const api = wrapAPI(workerScript, ns, workerScript.args.slice());
|
||||
// Example of conditionally adding optional spoilered content to enums
|
||||
if (Player.sourceFileLvl(3) > 0 || Player.bitNodeN === 3) {
|
||||
api.enums.corp = Object.assign({}, { EmployeePositions });
|
||||
}
|
||||
return api;
|
||||
}
|
||||
|
||||
const base: InternalAPI<NS> = {
|
||||
args: [],
|
||||
//The next line will error if enums does not match the definition in NetscriptDefinitions.d.ts
|
||||
enums,
|
||||
singularity: NetscriptSingularity(),
|
||||
gang: NetscriptGang(),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Player as player } from "../Player";
|
||||
|
||||
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
||||
import { Employee } from "../Corporation/Employee";
|
||||
import { Product } from "../Corporation/Product";
|
||||
import { Material } from "../Corporation/Material";
|
||||
import { Warehouse } from "../Corporation/Warehouse";
|
||||
@ -26,7 +25,6 @@ import {
|
||||
SellProduct,
|
||||
SetSmartSupply,
|
||||
BuyMaterial,
|
||||
AssignJob,
|
||||
AutoAssignJob,
|
||||
UpgradeOfficeSize,
|
||||
PurchaseWarehouse,
|
||||
@ -261,13 +259,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
return product;
|
||||
}
|
||||
|
||||
function getEmployee(divisionName: string, cityName: string, employeeName: string): Employee {
|
||||
const office = getOffice(divisionName, cityName);
|
||||
const employee = office.employees.find((e) => e.name === employeeName);
|
||||
if (employee === undefined) throw new Error(`Invalid employee name: '${employeeName}'`);
|
||||
return employee;
|
||||
}
|
||||
|
||||
function checkAccess(ctx: NetscriptContext, api?: number): void {
|
||||
if (player.corporation === null) throw helpers.makeRuntimeErrorMsg(ctx, "Must own a corporation.");
|
||||
if (!api) return;
|
||||
@ -626,18 +617,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
}
|
||||
return CorporationConstants.OfficeInitialCost * mult;
|
||||
},
|
||||
assignJob: (ctx) => (_divisionName, _cityName, _employeeName, _job) => {
|
||||
checkAccess(ctx, 8);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||
const employeeName = helpers.string(ctx, "employeeName", _employeeName);
|
||||
const job = helpers.string(ctx, "job", _job);
|
||||
|
||||
if (!checkEnum(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`);
|
||||
const office = getOffice(divisionName, cityName);
|
||||
|
||||
AssignJob(office, employeeName, job);
|
||||
},
|
||||
setAutoJobAssignment: (ctx) => (_divisionName, _cityName, _job, _amount) => {
|
||||
checkAccess(ctx, 8);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
@ -647,30 +626,18 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
|
||||
if (!checkEnum(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`);
|
||||
const office = getOffice(divisionName, cityName);
|
||||
|
||||
return AutoAssignJob(office, job, amount);
|
||||
},
|
||||
hireEmployee: (ctx) => (_divisionName, _cityName) => {
|
||||
hireEmployee: (ctx) => (_divisionName, _cityName, _position?) => {
|
||||
checkAccess(ctx, 8);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||
const position = _position ? helpers.string(ctx, "position", _position) : EmployeePositions.Unassigned;
|
||||
if (!checkEnum(EmployeePositions, position)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position: ${position}`);
|
||||
}
|
||||
const office = getOffice(divisionName, cityName);
|
||||
const employee = office.hireRandomEmployee();
|
||||
if (employee === undefined) return undefined;
|
||||
return {
|
||||
name: employee.name,
|
||||
mor: employee.mor,
|
||||
hap: employee.hap,
|
||||
ene: employee.ene,
|
||||
int: employee.int,
|
||||
cha: employee.cha,
|
||||
exp: employee.exp,
|
||||
cre: employee.cre,
|
||||
eff: employee.eff,
|
||||
sal: employee.sal,
|
||||
loc: employee.loc,
|
||||
pos: employee.pos,
|
||||
};
|
||||
return office.hireRandomEmployee(position);
|
||||
},
|
||||
upgradeOfficeSize: (ctx) => (_divisionName, _cityName, _size) => {
|
||||
checkAccess(ctx, 8);
|
||||
@ -691,7 +658,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
if (costPerEmployee < 0) {
|
||||
throw new Error("Invalid value for Cost Per Employee field! Must be numeric and greater than 0");
|
||||
}
|
||||
|
||||
const corporation = getCorporation();
|
||||
const office = getOffice(divisionName, cityName);
|
||||
|
||||
@ -704,7 +670,6 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
|
||||
const corporation = getCorporation();
|
||||
const office = getOffice(divisionName, cityName);
|
||||
|
||||
return BuyCoffee(corporation, office);
|
||||
},
|
||||
hireAdVert: (ctx) => (_divisionName) => {
|
||||
@ -733,46 +698,12 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
maxHap: office.maxHap,
|
||||
minMor: office.minMor,
|
||||
maxMor: office.maxMor,
|
||||
employees: office.employees.map((e) => e.name),
|
||||
employeeProd: {
|
||||
Operations: office.employeeProd[EmployeePositions.Operations],
|
||||
Engineer: office.employeeProd[EmployeePositions.Engineer],
|
||||
Business: office.employeeProd[EmployeePositions.Business],
|
||||
Management: office.employeeProd[EmployeePositions.Management],
|
||||
"Research & Development": office.employeeProd[EmployeePositions.RandD],
|
||||
Training: office.employeeProd[EmployeePositions.Training],
|
||||
Unassigned: 0,
|
||||
},
|
||||
employeeJobs: {
|
||||
Operations: office.employeeJobs[EmployeePositions.Operations],
|
||||
Engineer: office.employeeJobs[EmployeePositions.Engineer],
|
||||
Business: office.employeeJobs[EmployeePositions.Business],
|
||||
Management: office.employeeJobs[EmployeePositions.Management],
|
||||
"Research & Development": office.employeeJobs[EmployeePositions.RandD],
|
||||
Training: office.employeeJobs[EmployeePositions.Training],
|
||||
Unassigned: office.employeeJobs[EmployeePositions.Unassigned],
|
||||
},
|
||||
};
|
||||
},
|
||||
getEmployee: (ctx) => (_divisionName, _cityName, _employeeName) => {
|
||||
checkAccess(ctx, 8);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||
const employeeName = helpers.string(ctx, "employeeName", _employeeName);
|
||||
const employee = getEmployee(divisionName, cityName, employeeName);
|
||||
return {
|
||||
name: employee.name,
|
||||
mor: employee.mor,
|
||||
hap: employee.hap,
|
||||
ene: employee.ene,
|
||||
int: employee.int,
|
||||
cha: employee.cha,
|
||||
exp: employee.exp,
|
||||
cre: employee.cre,
|
||||
eff: employee.eff,
|
||||
sal: employee.sal,
|
||||
loc: employee.loc,
|
||||
pos: employee.pos,
|
||||
employees: office.totalEmployees,
|
||||
avgEne: office.avgEne,
|
||||
avgHap: office.avgHap,
|
||||
avgMor: office.avgMor,
|
||||
employeeProd: Object.assign({}, office.employeeProd),
|
||||
employeeJobs: Object.assign({}, office.employeeJobs),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
82
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
82
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -6872,6 +6872,20 @@ export interface NS {
|
||||
enums: NSEnums;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
declare enum EmployeePositions {
|
||||
Operations = "Operations",
|
||||
Engineer = "Engineer",
|
||||
Business = "Business",
|
||||
Management = "Management",
|
||||
RandD = "Research & Development",
|
||||
Training = "Training",
|
||||
Unassigned = "Unassigned",
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type EmployeePosNames = `${EmployeePositions}`;
|
||||
|
||||
/** @public */
|
||||
declare enum ToastVariant {
|
||||
SUCCESS = "success",
|
||||
@ -6903,7 +6917,8 @@ type CrimeNames = `${CrimeType}`;
|
||||
/** @public */
|
||||
export type NSEnums = {
|
||||
toast: typeof ToastVariant;
|
||||
crimes: typeof CrimeType;
|
||||
CrimeType: typeof CrimeType;
|
||||
corp?: { EmployeePositions: typeof EmployeePositions };
|
||||
};
|
||||
|
||||
/**
|
||||
@ -6912,22 +6927,20 @@ export type NSEnums = {
|
||||
* requires the Office API upgrade from your corporation.
|
||||
* @public
|
||||
*/
|
||||
|
||||
export interface OfficeAPI {
|
||||
/**
|
||||
* Assign an employee to a job.
|
||||
* @param divisionName - Name of the division
|
||||
* @param cityName - Name of the city
|
||||
* @param employeeName - name of the employee
|
||||
* @param job - Name of the job.
|
||||
*/
|
||||
assignJob(divisionName: string, cityName: string, employeeName: string, job: string): void;
|
||||
/**
|
||||
* Hire an employee.
|
||||
* @param divisionName - Name of the division
|
||||
* @param cityName - Name of the city
|
||||
* @returns The newly hired employee, if any
|
||||
* @param employeePosition - Position to place into. Defaults to "Unassigned".
|
||||
* @returns True if an employee was hired, false otherwise
|
||||
*/
|
||||
hireEmployee(divisionName: string, cityName: string): Employee | undefined;
|
||||
hireEmployee(
|
||||
divisionName: string,
|
||||
cityName: string,
|
||||
employeePosition?: EmployeePositions | EmployeePosNames,
|
||||
): boolean;
|
||||
/**
|
||||
* Upgrade office size.
|
||||
* @param divisionName - Name of the division
|
||||
@ -6975,12 +6988,6 @@ export interface OfficeAPI {
|
||||
* @param employeeName - Name of the employee
|
||||
* @returns Employee data
|
||||
*/
|
||||
getEmployee(divisionName: string, cityName: string, employeeName: string): Employee;
|
||||
/**
|
||||
* Get the cost to Hire AdVert
|
||||
* @param divisionName - Name of the division
|
||||
* @returns Cost
|
||||
*/
|
||||
getHireAdVertCost(divisionName: string): number;
|
||||
/**
|
||||
* Get the number of times you have Hired AdVert
|
||||
@ -7436,37 +7443,6 @@ interface CorporationInfo {
|
||||
divisions: Division[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Employee in an office
|
||||
* @public
|
||||
*/
|
||||
export interface Employee {
|
||||
/** Name of the employee */
|
||||
name: string;
|
||||
/** Morale of the employee */
|
||||
mor: number;
|
||||
/** Happiness of the employee */
|
||||
hap: number;
|
||||
/** Energy of the employee */
|
||||
ene: number;
|
||||
/** Intelligence of the employee */
|
||||
int: number;
|
||||
/** Charisma of the employee */
|
||||
cha: number;
|
||||
/** Experience of the employee */
|
||||
exp: number;
|
||||
/** Creativity of the employee */
|
||||
cre: number;
|
||||
/** Efficiency of the employee */
|
||||
eff: number;
|
||||
/** Salary of the employee */
|
||||
sal: number;
|
||||
/** Current Location (city) */
|
||||
loc: string;
|
||||
/** Current job position */
|
||||
pos: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Product in a warehouse
|
||||
* @public
|
||||
@ -7572,8 +7548,14 @@ export interface Office {
|
||||
minMor: number;
|
||||
/** Maximum morale of the employees */
|
||||
maxMor: number;
|
||||
/** Name of all the employees */
|
||||
employees: string[];
|
||||
/** Amount of employees */
|
||||
employees: number;
|
||||
/** Average energy of the employees */
|
||||
avgEne: number;
|
||||
/** Average happiness of the employees */
|
||||
avgHap: number;
|
||||
/** Average morale of the employees */
|
||||
avgMor: number;
|
||||
/** Production of the employees */
|
||||
employeeProd: EmployeeJobs;
|
||||
/** Positions of the employees */
|
||||
|
Loading…
Reference in New Issue
Block a user