mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-01-11 07:47:33 +01:00
Only switch employee jobs at the start of corp cycles
This commit is contained in:
parent
6f017bf4f6
commit
b9356ea782
@ -304,9 +304,19 @@ export function BuyBackShares(corporation: ICorporation, player: IPlayer, numSha
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AssignJob(employee: Employee, job: string): void {
|
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 (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
employee.pos = job;
|
|
||||||
|
office.assignSingleJob(employee, job);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AutoAssignJob(office: OfficeSpace, job: string, count: number): boolean {
|
||||||
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
|
|
||||||
|
return office.autoAssignJob(job, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size: number): void {
|
export function UpgradeOfficeSize(corp: ICorporation, office: OfficeSpace, size: number): void {
|
||||||
|
@ -34,6 +34,7 @@ export class Employee {
|
|||||||
cyclesUntilRaise = CorporationConstants.CyclesPerEmployeeRaise;
|
cyclesUntilRaise = CorporationConstants.CyclesPerEmployeeRaise;
|
||||||
loc: string;
|
loc: string;
|
||||||
pos: string;
|
pos: string;
|
||||||
|
nextPos: string;
|
||||||
|
|
||||||
constructor(params: IParams = {}) {
|
constructor(params: IParams = {}) {
|
||||||
this.name = params.name ? params.name : "Bobby";
|
this.name = params.name ? params.name : "Bobby";
|
||||||
@ -52,6 +53,7 @@ export class Employee {
|
|||||||
|
|
||||||
this.loc = params.loc ? params.loc : "";
|
this.loc = params.loc ? params.loc : "";
|
||||||
this.pos = EmployeePositions.Unassigned;
|
this.pos = EmployeePositions.Unassigned;
|
||||||
|
this.nextPos = this.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the amount the employee needs to be paid
|
//Returns the amount the employee needs to be paid
|
||||||
|
@ -37,7 +37,15 @@ export class OfficeSpace {
|
|||||||
[EmployeePositions.RandD]: 0,
|
[EmployeePositions.RandD]: 0,
|
||||||
[EmployeePositions.Training]: 0,
|
[EmployeePositions.Training]: 0,
|
||||||
[EmployeePositions.Unassigned]: 0,
|
[EmployeePositions.Unassigned]: 0,
|
||||||
total: 0,
|
};
|
||||||
|
employeeNextJobs: { [key: string]: number } = {
|
||||||
|
[EmployeePositions.Operations]: 0,
|
||||||
|
[EmployeePositions.Engineer]: 0,
|
||||||
|
[EmployeePositions.Business]: 0,
|
||||||
|
[EmployeePositions.Management]: 0,
|
||||||
|
[EmployeePositions.RandD]: 0,
|
||||||
|
[EmployeePositions.Training]: 0,
|
||||||
|
[EmployeePositions.Unassigned]: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(params: IParams = {}) {
|
constructor(params: IParams = {}) {
|
||||||
@ -58,7 +66,13 @@ export class OfficeSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.employees.length; ++i) {
|
||||||
|
const emp = this.employees[i];
|
||||||
|
emp.pos = emp.nextPos;
|
||||||
|
}
|
||||||
|
|
||||||
this.calculateTotalEmployees();
|
this.calculateTotalEmployees();
|
||||||
|
this.calculateNextEmployees();
|
||||||
|
|
||||||
// Process Office properties
|
// Process Office properties
|
||||||
this.maxEne = 100;
|
this.maxEne = 100;
|
||||||
@ -113,6 +127,18 @@ export class OfficeSpace {
|
|||||||
return salaryPaid;
|
return salaryPaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
calculateTotalEmployees(): void {
|
||||||
//Reset
|
//Reset
|
||||||
for (const name of Object.keys(this.employeeJobs)) {
|
for (const name of Object.keys(this.employeeJobs)) {
|
||||||
@ -123,7 +149,6 @@ export class OfficeSpace {
|
|||||||
const employee = this.employees[i];
|
const employee = this.employees[i];
|
||||||
this.employeeJobs[employee.pos]++;
|
this.employeeJobs[employee.pos]++;
|
||||||
}
|
}
|
||||||
this.employeeJobs.total = this.employees.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateEmployeeProductivity(corporation: ICorporation, industry: IIndustry): void {
|
calculateEmployeeProductivity(corporation: ICorporation, industry: IIndustry): void {
|
||||||
@ -173,45 +198,33 @@ export class OfficeSpace {
|
|||||||
emp.name = name;
|
emp.name = name;
|
||||||
this.employees.push(emp);
|
this.employees.push(emp);
|
||||||
|
|
||||||
|
this.calculateTotalEmployees();
|
||||||
|
this.calculateNextEmployees();
|
||||||
return emp;
|
return emp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Finds the first unassigned employee and assigns its to the specified job
|
assignSingleJob(employee: Employee, job: string): void {
|
||||||
assignEmployeeToJob(job: string): boolean {
|
employee.nextPos = job;
|
||||||
for (let i = 0; i < this.employees.length; ++i) {
|
this.calculateNextEmployees();
|
||||||
if (this.employees[i].pos === EmployeePositions.Unassigned) {
|
|
||||||
this.employees[i].pos = job;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Finds the first employee with the given job and unassigns it
|
autoAssignJob(job: string, target: number): boolean {
|
||||||
unassignEmployeeFromJob(job: string): boolean {
|
let count = this.employeeNextJobs[job];
|
||||||
for (let i = 0; i < this.employees.length; ++i) {
|
|
||||||
if (this.employees[i].pos === job) {
|
|
||||||
this.employees[i].pos = EmployeePositions.Unassigned;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setEmployeeToJob(job: string, amount: number): boolean {
|
|
||||||
let jobCount = this.employees.reduce((acc, employee) => (employee.pos === job ? acc + 1 : acc), 0);
|
|
||||||
|
|
||||||
for (const employee of this.employees) {
|
for (const employee of this.employees) {
|
||||||
if (jobCount == amount) return true;
|
if (count === target) {
|
||||||
if (employee.pos === EmployeePositions.Unassigned && jobCount <= amount) {
|
break;
|
||||||
employee.pos = job;
|
} else if (employee.nextPos === EmployeePositions.Unassigned && count <= target) {
|
||||||
jobCount++;
|
employee.nextPos = job;
|
||||||
} else if (employee.pos === job && jobCount >= amount) {
|
count++;
|
||||||
employee.pos = EmployeePositions.Unassigned;
|
} else if (employee.nextPos === job && count >= target) {
|
||||||
jobCount--;
|
employee.nextPos = EmployeePositions.Unassigned;
|
||||||
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return jobCount === amount;
|
|
||||||
|
this.calculateNextEmployees();
|
||||||
|
return count === target;
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON(): any {
|
toJSON(): any {
|
||||||
|
@ -115,14 +115,14 @@ function ManualManagement(props: IProps): React.ReactElement {
|
|||||||
{positionNames[i]}
|
{positionNames[i]}
|
||||||
</MenuItem>,
|
</MenuItem>,
|
||||||
);
|
);
|
||||||
if (emp != null && emp.pos === positionNames[i]) {
|
if (emp != null && emp.nextPos === positionNames[i]) {
|
||||||
employeePositionSelectorInitialValue = positionNames[i];
|
employeePositionSelectorInitialValue = emp.nextPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function employeePositionSelectorOnChange(e: SelectChangeEvent<string>): void {
|
function employeePositionSelectorOnChange(e: SelectChangeEvent<string>): void {
|
||||||
if (employee === null) return;
|
if (employee === null) return;
|
||||||
employee.pos = e.target.value;
|
props.office.assignSingleJob(employee, e.target.value);
|
||||||
props.rerender();
|
props.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,38 +181,40 @@ interface IAutoAssignProps {
|
|||||||
function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const division = useDivision();
|
const division = useDivision();
|
||||||
const numJob = countEmployee(props.office.employees, props.job);
|
|
||||||
const numUnassigned = countEmployee(props.office.employees, EmployeePositions.Unassigned);
|
const currJob = props.office.employeeJobs[props.job];
|
||||||
|
const nextJob = props.office.employeeNextJobs[props.job];
|
||||||
|
const nextUna = props.office.employeeNextJobs[EmployeePositions.Unassigned];
|
||||||
|
|
||||||
function assignEmployee(): void {
|
function assignEmployee(): void {
|
||||||
if (numUnassigned <= 0) {
|
if (nextUna <= 0) {
|
||||||
console.warn("Cannot assign employee. No unassigned employees available");
|
console.warn("Cannot assign employee. No unassigned employees available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
props.office.assignEmployeeToJob(props.job);
|
props.office.autoAssignJob(props.job, nextJob + 1);
|
||||||
props.office.calculateEmployeeProductivity(corp, division);
|
|
||||||
props.rerender();
|
props.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
function unassignEmployee(): void {
|
function unassignEmployee(): void {
|
||||||
props.office.unassignEmployeeFromJob(props.job);
|
props.office.autoAssignJob(props.job, nextJob - 1);
|
||||||
props.office.calculateEmployeeProductivity(corp, division);
|
|
||||||
props.rerender();
|
props.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title={props.desc}>
|
<Tooltip title={props.desc}>
|
||||||
<Typography>
|
<Typography>
|
||||||
{props.job} ({numJob})
|
{props.job} ({(currJob == nextJob ? currJob : `${currJob} -> ${nextJob}`)})
|
||||||
</Typography>
|
</Typography>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<IconButton disabled={numUnassigned === 0} onClick={assignEmployee}>
|
<IconButton disabled={nextUna === 0} onClick={assignEmployee}>
|
||||||
<ArrowDropUpIcon />
|
<ArrowDropUpIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton disabled={numJob === 0} onClick={unassignEmployee}>
|
<IconButton disabled={nextJob === 0} onClick={unassignEmployee}>
|
||||||
<ArrowDropDownIcon />
|
<ArrowDropDownIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@ -223,7 +225,6 @@ function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
|||||||
function AutoManagement(props: IProps): React.ReactElement {
|
function AutoManagement(props: IProps): React.ReactElement {
|
||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const division = useDivision();
|
const division = useDivision();
|
||||||
const numUnassigned = countEmployee(props.office.employees, EmployeePositions.Unassigned);
|
|
||||||
const vechain = corp.unlockUpgrades[4] === 1; // Has Vechain upgrade
|
const vechain = corp.unlockUpgrades[4] === 1; // Has Vechain upgrade
|
||||||
|
|
||||||
// Calculate average morale, happiness, energy, and salary.
|
// Calculate average morale, happiness, energy, and salary.
|
||||||
@ -247,6 +248,9 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
avgEnergy = totalEnergy / props.office.employees.length;
|
avgEnergy = totalEnergy / props.office.employees.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currUna = props.office.employeeJobs[EmployeePositions.Unassigned];
|
||||||
|
const nextUna = props.office.employeeNextJobs[EmployeePositions.Unassigned];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Table padding="none">
|
<Table padding="none">
|
||||||
@ -256,7 +260,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
|||||||
<Typography>Unassigned Employees:</Typography>
|
<Typography>Unassigned Employees:</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography>{numUnassigned}</Typography>
|
<Typography>{(currUna == nextUna ? currUna : `${currUna} -> ${nextUna}`)}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -34,6 +34,7 @@ import {
|
|||||||
SetSmartSupply,
|
SetSmartSupply,
|
||||||
BuyMaterial,
|
BuyMaterial,
|
||||||
AssignJob,
|
AssignJob,
|
||||||
|
AutoAssignJob,
|
||||||
UpgradeOfficeSize,
|
UpgradeOfficeSize,
|
||||||
ThrowParty,
|
ThrowParty,
|
||||||
PurchaseWarehouse,
|
PurchaseWarehouse,
|
||||||
@ -685,20 +686,6 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
|
|||||||
const researchName = ctx.helper.string("researchName", _researchName);
|
const researchName = ctx.helper.string("researchName", _researchName);
|
||||||
return hasResearched(getDivision(divisionName), researchName);
|
return hasResearched(getDivision(divisionName), researchName);
|
||||||
},
|
},
|
||||||
setAutoJobAssignment:
|
|
||||||
(ctx: NetscriptContext) =>
|
|
||||||
(_divisionName: unknown, _cityName: unknown, _job: unknown, _amount: unknown): Promise<boolean> => {
|
|
||||||
checkAccess(ctx, 8);
|
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
|
||||||
const amount = ctx.helper.number("amount", _amount);
|
|
||||||
const job = ctx.helper.string("job", _job);
|
|
||||||
const office = getOffice(divisionName, cityName);
|
|
||||||
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
|
||||||
return netscriptDelay(1000, workerScript).then(function () {
|
|
||||||
return Promise.resolve(office.setEmployeeToJob(job, amount));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getOfficeSizeUpgradeCost:
|
getOfficeSizeUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _size: unknown): number => {
|
(_divisionName: unknown, _cityName: unknown, _size: unknown): number => {
|
||||||
@ -724,10 +711,31 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
|
|||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = ctx.helper.city("cityName", _cityName);
|
||||||
const employeeName = ctx.helper.string("employeeName", _employeeName);
|
const employeeName = ctx.helper.string("employeeName", _employeeName);
|
||||||
const job = ctx.helper.string("job", _job);
|
const job = ctx.helper.string("job", _job);
|
||||||
const employee = getEmployee(divisionName, cityName, employeeName);
|
|
||||||
return netscriptDelay(["Training", "Unassigned"].includes(employee.pos) ? 0 : 1000, workerScript).then(function () {
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
return Promise.resolve(AssignJob(employee, job));
|
const office = getOffice(divisionName, cityName);
|
||||||
|
|
||||||
|
return netscriptDelay(0, workerScript).then(function () {
|
||||||
|
return Promise.resolve(AssignJob(office, employeeName, job));
|
||||||
});
|
});
|
||||||
|
//return AssignJob(office, employeeName, job);
|
||||||
|
},
|
||||||
|
setAutoJobAssignment:
|
||||||
|
(ctx: NetscriptContext) =>
|
||||||
|
(_divisionName: unknown, _cityName: unknown, _job: unknown, _amount: unknown): Promise<boolean> => {
|
||||||
|
checkAccess(ctx, 8);
|
||||||
|
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
||||||
|
const cityName = ctx.helper.city("cityName", _cityName);
|
||||||
|
const amount = ctx.helper.number("amount", _amount);
|
||||||
|
const job = ctx.helper.string("job", _job);
|
||||||
|
|
||||||
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
|
const office = getOffice(divisionName, cityName);
|
||||||
|
|
||||||
|
return netscriptDelay(0, workerScript).then(function () {
|
||||||
|
return Promise.resolve(AutoAssignJob(office, job, amount));
|
||||||
|
});
|
||||||
|
//return AutoAssignJob(office, job, amount);
|
||||||
},
|
},
|
||||||
hireEmployee:
|
hireEmployee:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user