Rebuild village state calculation
This commit is contained in:
parent
3d54294043
commit
129f107881
@ -1,4 +1,4 @@
|
||||
import { parseLocation, timestamp, uniqId, waitForLoad } from './utils';
|
||||
import { notify, parseLocation, timestamp, uniqId, waitForLoad } from './utils';
|
||||
import { Scheduler } from './Scheduler';
|
||||
import { BuildingPageController } from './Page/BuildingPageController';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
@ -13,21 +13,35 @@ import Vue from 'vue';
|
||||
import DashboardApp from './DashboardView/Dashboard.vue';
|
||||
import { ResourcesToLevel } from './Task/ResourcesToLevel';
|
||||
import { ConsoleLogger, Logger } from './Logger';
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { Resources } from './Core/Resources';
|
||||
import { Coordinates, Village } from './Core/Village';
|
||||
import { calcGatheringTimings } from './Core/GatheringTimings';
|
||||
import { DataStorage } from './DataStorage';
|
||||
import { getBuildingPageAttributes, isBuildingPage } from './Page/PageDetectors';
|
||||
import { debounce } from 'debounce';
|
||||
import { ExecutionStorage } from './Storage/ExecutionStorage';
|
||||
import { ResourceStorage } from './Core/ResourceStorage';
|
||||
import { createVillageStates, VillageState } from './VillageState';
|
||||
import { Task } from './Queue/TaskProvider';
|
||||
import { Action } from './Queue/ActionQueue';
|
||||
|
||||
interface QuickAction {
|
||||
label: string;
|
||||
cb: () => void;
|
||||
}
|
||||
|
||||
interface GameState {
|
||||
name: string;
|
||||
version: string;
|
||||
activeVillageState: VillageState | undefined;
|
||||
villageStates: ReadonlyArray<VillageState>;
|
||||
taskList: ReadonlyArray<Task>;
|
||||
actionList: ReadonlyArray<Action>;
|
||||
quickActions: Array<QuickAction>;
|
||||
pauseSeconds: number;
|
||||
|
||||
refresh(): void;
|
||||
removeTask(taskId: string): void;
|
||||
refreshVillages(): void;
|
||||
pause(): void;
|
||||
}
|
||||
|
||||
export class ControlPanel {
|
||||
private readonly version: string;
|
||||
private readonly scheduler: Scheduler;
|
||||
@ -48,18 +62,17 @@ export class ControlPanel {
|
||||
const villageId = grabActiveVillageId();
|
||||
|
||||
const scheduler = this.scheduler;
|
||||
const quickActions: QuickAction[] = [];
|
||||
|
||||
const executionState = new ExecutionStorage();
|
||||
|
||||
const state: any = {
|
||||
name: 'Dashboard',
|
||||
const state: GameState = {
|
||||
name: 'Control',
|
||||
version: this.version,
|
||||
activeVillage: {},
|
||||
villages: [],
|
||||
activeVillageState: undefined,
|
||||
villageStates: [],
|
||||
taskList: [],
|
||||
actionList: [],
|
||||
quickActions: quickActions,
|
||||
quickActions: [],
|
||||
pauseSeconds: 0,
|
||||
|
||||
refresh() {
|
||||
@ -76,12 +89,10 @@ export class ControlPanel {
|
||||
},
|
||||
|
||||
refreshVillages() {
|
||||
this.villages = grabVillageList().map(village => {
|
||||
return new VillageController(village, new VillageStorage(village.id), scheduler);
|
||||
});
|
||||
for (let village of this.villages) {
|
||||
if (village.active) {
|
||||
this.activeVillage = village;
|
||||
this.villageStates = createVillageStates(grabVillageList(), scheduler);
|
||||
for (let state of this.villageStates) {
|
||||
if (state.village.active) {
|
||||
this.activeVillageState = state;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -111,7 +122,7 @@ export class ControlPanel {
|
||||
if (p.pathname === '/dorf1.php') {
|
||||
showResourceSlotIds(buildingsInQueue);
|
||||
onResourceSlotCtrlClick(buildId => this.onResourceSlotCtrlClick(villageId, buildId));
|
||||
quickActions.push(...this.createDepositsQuickActions(villageId));
|
||||
state.quickActions.push(...this.createDepositsQuickActions(villageId));
|
||||
}
|
||||
|
||||
if (p.pathname === '/dorf2.php') {
|
||||
@ -126,12 +137,12 @@ export class ControlPanel {
|
||||
this.createControlPanel(state);
|
||||
}
|
||||
|
||||
private createControlPanel(state: any) {
|
||||
private createControlPanel(gameState: GameState) {
|
||||
const appId = `app-${uniqId()}`;
|
||||
jQuery('body').prepend(`<div id="${appId}"></div>`);
|
||||
new Vue({
|
||||
el: `#${appId}`,
|
||||
data: state,
|
||||
data: gameState,
|
||||
render: h => h(DashboardApp),
|
||||
});
|
||||
}
|
||||
@ -157,78 +168,6 @@ export class ControlPanel {
|
||||
|
||||
private onResourceSlotCtrlClick(villageId: number, buildId: number) {
|
||||
this.scheduler.scheduleTask(UpgradeBuildingTask.name, { villageId, buildId });
|
||||
const n = new Notification(`Building ${buildId} scheduled`);
|
||||
setTimeout(() => n && n.close(), 4000);
|
||||
}
|
||||
}
|
||||
|
||||
class VillageController {
|
||||
public readonly id: number;
|
||||
public readonly name: string;
|
||||
public readonly crd: Coordinates;
|
||||
public readonly active: boolean;
|
||||
public readonly lumber: number;
|
||||
public readonly clay: number;
|
||||
public readonly iron: number;
|
||||
public readonly crop: number;
|
||||
public readonly resources: Resources;
|
||||
public readonly performance: Resources;
|
||||
public readonly requiredResources: Resources;
|
||||
public readonly requiredBalance: Resources;
|
||||
public readonly totalRequiredResources: Resources;
|
||||
public readonly totalRequiredBalance: Resources;
|
||||
public readonly incomingResources: Resources;
|
||||
public readonly storage: ResourceStorage;
|
||||
public readonly warehouse: number;
|
||||
public readonly granary: number;
|
||||
public readonly buildRemainingSeconds: number;
|
||||
|
||||
constructor(village: Village, state: VillageStorage, scheduler: Scheduler) {
|
||||
const resources = state.getResources();
|
||||
const storage = state.getResourceStorage();
|
||||
const performance = state.getResourcesPerformance();
|
||||
const buildQueueInfo = state.getBuildingQueueInfo();
|
||||
const requiredResources = scheduler.getVillageRequiredResources(village.id);
|
||||
const totalRequiredResources = scheduler.getTotalVillageRequiredResources(village.id);
|
||||
this.id = village.id;
|
||||
this.name = village.name;
|
||||
this.crd = village.crd;
|
||||
this.active = village.active;
|
||||
this.lumber = resources.lumber;
|
||||
this.clay = resources.clay;
|
||||
this.iron = resources.iron;
|
||||
this.crop = resources.crop;
|
||||
this.resources = resources;
|
||||
this.performance = performance;
|
||||
this.requiredResources = requiredResources;
|
||||
this.requiredBalance = resources.sub(requiredResources);
|
||||
this.totalRequiredResources = totalRequiredResources;
|
||||
this.totalRequiredBalance = resources.sub(totalRequiredResources);
|
||||
this.storage = storage;
|
||||
this.warehouse = storage.warehouse;
|
||||
this.granary = storage.granary;
|
||||
this.buildRemainingSeconds = buildQueueInfo.seconds;
|
||||
this.incomingResources = this.calcIncomingResources(state);
|
||||
}
|
||||
|
||||
timeToRequired() {
|
||||
return this.timeToResources(this.requiredResources);
|
||||
}
|
||||
|
||||
timeToTotalRequired() {
|
||||
return this.timeToResources(this.totalRequiredResources);
|
||||
}
|
||||
|
||||
private timeToResources(resources: Resources): number {
|
||||
const timings = calcGatheringTimings(this.resources, resources, this.performance);
|
||||
if (timings.never) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return timings.hours * 3600;
|
||||
}
|
||||
|
||||
private calcIncomingResources(state: VillageStorage): Resources {
|
||||
return state.getIncomingMerchants().reduce((m, i) => m.add(i.resources), new Resources(0, 0, 0, 0));
|
||||
notify(`Building ${buildId} scheduled`);
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
villageName() {
|
||||
let village = this.shared.activeVillage;
|
||||
return village ? village.name : 'Unknown';
|
||||
let state = this.shared.activeVillageState;
|
||||
return state ? state.village.name : 'Unknown';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -25,13 +25,12 @@
|
||||
|
||||
<script>
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { timestamp } from '../utils';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
shared: this.$root.$data,
|
||||
activeVillage: this.$root.$data.activeVillage,
|
||||
activeVillageState: this.$root.$data.activeVillageState,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -49,7 +48,7 @@ export default {
|
||||
},
|
||||
isThisVillageTask(task) {
|
||||
const taskVillageId = (task.args || {}).villageId;
|
||||
const currentVillageId = this.activeVillage.id;
|
||||
const currentVillageId = this.activeVillageState.id;
|
||||
return taskVillageId !== undefined && taskVillageId === currentVillageId;
|
||||
},
|
||||
onRemove(taskId) {
|
||||
|
@ -13,39 +13,57 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="village in shared.villages">
|
||||
<template v-for="villageState in shared.villageStates">
|
||||
<tr class="normal-line top-line">
|
||||
<td :class="{ active: village.active }" :title="village.id">{{ village.name }}</td>
|
||||
<td class="right">
|
||||
<filling :value="village.lumber" :max="village.warehouse" :speed="village.performance.lumber"></filling>
|
||||
<td :class="{ active: villageState.village.active }" :title="villageState.id">
|
||||
{{ villageState.village.name }}
|
||||
</td>
|
||||
<td class="right">
|
||||
<filling :value="village.clay" :max="village.warehouse" :speed="village.performance.clay"></filling>
|
||||
<filling
|
||||
:value="villageState.resources.lumber"
|
||||
:max="villageState.storage.lumber"
|
||||
:speed="villageState.performance.lumber"
|
||||
></filling>
|
||||
</td>
|
||||
<td class="right">
|
||||
<filling :value="village.iron" :max="village.warehouse" :speed="village.performance.iron"></filling>
|
||||
<filling
|
||||
:value="villageState.resources.clay"
|
||||
:max="villageState.storage.clay"
|
||||
:speed="villageState.performance.clay"
|
||||
></filling>
|
||||
</td>
|
||||
<td class="right">
|
||||
<filling :value="village.crop" :max="village.granary" :speed="village.performance.crop"></filling>
|
||||
<filling
|
||||
:value="villageState.resources.iron"
|
||||
:max="villageState.storage.iron"
|
||||
:speed="villageState.performance.iron"
|
||||
></filling>
|
||||
</td>
|
||||
<td class="right">
|
||||
<a :href="warehousePath(village)" v-text="village.warehouse"></a>
|
||||
<filling
|
||||
:value="villageState.resources.crop"
|
||||
:max="villageState.storage.crop"
|
||||
:speed="villageState.performance.crop"
|
||||
></filling>
|
||||
</td>
|
||||
<td class="right" v-text="village.granary"></td>
|
||||
<td class="right">
|
||||
<a :href="warehousePath(villageState.village)" v-text="villageState.storage.lumber"></a>
|
||||
</td>
|
||||
<td class="right" v-text="villageState.storage.crop"></td>
|
||||
</tr>
|
||||
<tr class="performance-line">
|
||||
<td class="right">Прирост:</td>
|
||||
<td class="right">
|
||||
<resource :value="village.performance.lumber"></resource>
|
||||
<resource :value="villageState.performance.lumber"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.performance.clay"></resource>
|
||||
<resource :value="villageState.performance.clay"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.performance.iron"></resource>
|
||||
<resource :value="villageState.performance.iron"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.performance.crop"></resource>
|
||||
<resource :value="villageState.performance.crop"></resource>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
@ -54,7 +72,7 @@
|
||||
<td class="right">След:</td>
|
||||
<td class="right">
|
||||
<resource
|
||||
:value="village.requiredResources.lumber"
|
||||
:value="villageState.required.resources.lumber"
|
||||
:hide-zero="true"
|
||||
:color="false"
|
||||
:sign="false"
|
||||
@ -62,7 +80,7 @@
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource
|
||||
:value="village.requiredResources.clay"
|
||||
:value="villageState.required.resources.clay"
|
||||
:hide-zero="true"
|
||||
:color="false"
|
||||
:sign="false"
|
||||
@ -70,7 +88,7 @@
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource
|
||||
:value="village.requiredResources.iron"
|
||||
:value="villageState.required.resources.iron"
|
||||
:hide-zero="true"
|
||||
:color="false"
|
||||
:sign="false"
|
||||
@ -78,62 +96,79 @@
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource
|
||||
:value="village.requiredResources.crop"
|
||||
:value="villageState.required.resources.crop"
|
||||
:hide-zero="true"
|
||||
:color="false"
|
||||
:sign="false"
|
||||
></resource>
|
||||
</td>
|
||||
<td class="right" v-text="secondsToTime(village.buildRemainingSeconds)"></td>
|
||||
<td class="right" v-text="secondsToRequiredTime(villageState.buildRemainingSeconds)"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="required-line">
|
||||
<td class="right">Баланс:</td>
|
||||
<td class="right">
|
||||
<resource :value="village.requiredBalance.lumber"></resource>
|
||||
<resource :value="villageState.required.balance.lumber"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.requiredBalance.clay"></resource>
|
||||
<resource :value="villageState.required.balance.clay"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.requiredBalance.iron"></resource>
|
||||
<resource :value="villageState.required.balance.iron"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.requiredBalance.crop"></resource>
|
||||
<resource :value="villageState.required.balance.crop"></resource>
|
||||
</td>
|
||||
<td class="right" v-text="timeToRequired(village)"></td>
|
||||
<td class="right" v-text="secondsToRequiredTime(villageState.required.time)"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="required-line">
|
||||
<td class="right">Баланс очереди:</td>
|
||||
<td class="right">
|
||||
<resource :value="village.totalRequiredBalance.lumber"></resource>
|
||||
<resource :value="villageState.totalRequired.balance.lumber"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.totalRequiredBalance.clay"></resource>
|
||||
<resource :value="villageState.totalRequired.balance.clay"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.totalRequiredBalance.iron"></resource>
|
||||
<resource :value="villageState.totalRequired.balance.iron"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.totalRequiredBalance.crop"></resource>
|
||||
<resource :value="villageState.totalRequired.balance.crop"></resource>
|
||||
</td>
|
||||
<td class="right" v-text="timeToTotalRequired(village)"></td>
|
||||
<td class="right" v-text="secondsToRequiredTime(villageState.totalRequired.time)"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="commitments-line">
|
||||
<td class="right">Обязательства:</td>
|
||||
<td class="right">
|
||||
<resource :value="villageState.commitments.lumber" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="villageState.commitments.clay" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="villageState.commitments.iron" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="villageState.commitments.crop" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="incoming-line">
|
||||
<td class="right">Торговцы:</td>
|
||||
<td class="right">
|
||||
<resource :value="village.incomingResources.lumber" :hide-zero="true"></resource>
|
||||
<resource :value="villageState.incomingResources.lumber" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.incomingResources.clay" :hide-zero="true"></resource>
|
||||
<resource :value="villageState.incomingResources.clay" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.incomingResources.iron" :hide-zero="true"></resource>
|
||||
<resource :value="villageState.incomingResources.iron" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td class="right">
|
||||
<resource :value="village.incomingResources.crop" :hide-zero="true"></resource>
|
||||
<resource :value="villageState.incomingResources.crop" :hide-zero="true"></resource>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
@ -143,14 +178,14 @@
|
||||
<td class="right" colspan="6">
|
||||
<a
|
||||
class="village-quick-link"
|
||||
v-for="v in shared.villages"
|
||||
v-if="v.id !== village.id"
|
||||
:href="marketPath(village, v)"
|
||||
:title="'Отправить ресурсы из ' + village.name + ' в ' + v.name"
|
||||
>->{{ v.name }}</a
|
||||
v-for="s in shared.villageStates"
|
||||
v-if="s.id !== villageState.id"
|
||||
:href="marketPath(villageState.village, s.village)"
|
||||
:title="'Отправить ресурсы из ' + villageState.village.name + ' в ' + s.village.name"
|
||||
>->{{ s.village.name }}</a
|
||||
>
|
||||
<a class="village-quick-link" :href="quartersPath(village)">Казармы</a>
|
||||
<a class="village-quick-link" :href="horseStablePath(village)">Конюшни</a>
|
||||
<a class="village-quick-link" :href="quartersPath(villageState.village)">Казармы</a>
|
||||
<a class="village-quick-link" :href="horseStablePath(villageState.village)">Конюшни</a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
@ -173,7 +208,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
shared: this.$root.$data,
|
||||
activeVillage: this.$root.$data.activeVillage,
|
||||
activeVillageState: this.$root.$data.activeVillageState,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -213,12 +248,6 @@ export default {
|
||||
}
|
||||
return this.secondsToTime(value);
|
||||
},
|
||||
timeToRequired(village) {
|
||||
return this.secondsToRequiredTime(village.timeToRequired());
|
||||
},
|
||||
timeToTotalRequired(village) {
|
||||
return this.secondsToRequiredTime(village.timeToTotalRequired());
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -244,6 +273,7 @@ export default {
|
||||
|
||||
.performance-line td,
|
||||
.required-line td,
|
||||
.commitments-line td,
|
||||
.incoming-line td {
|
||||
padding: 0 4px 4px;
|
||||
font-size: 90%;
|
||||
|
@ -6,6 +6,7 @@ export interface Args {
|
||||
taskId?: TaskId;
|
||||
targetTaskId?: TaskId;
|
||||
villageId?: number;
|
||||
targetVillageId?: number;
|
||||
buildId?: number;
|
||||
categoryId?: number;
|
||||
sheetId?: number;
|
||||
|
@ -133,6 +133,18 @@ export class Scheduler {
|
||||
return tasks.reduce((acc, t) => acc.add(t.args.resources!), new Resources(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
getResourceCommitments(villageId: number): Array<number> {
|
||||
const tasks = this.taskQueue
|
||||
.seeItems()
|
||||
.filter(
|
||||
t =>
|
||||
t.name === SendResourcesTask.name &&
|
||||
t.args.villageId === villageId &&
|
||||
t.args.targetVillageId !== undefined
|
||||
);
|
||||
return tasks.map(t => t.args.targetVillageId!);
|
||||
}
|
||||
|
||||
private reorderVillageTasks(villageId: number) {
|
||||
const tasks = this.taskQueue.seeItems();
|
||||
const trainPred = (t: Task) => isTrainTroopTask(t.name) && sameVillage(villageId, t.args);
|
||||
|
100
src/VillageState.ts
Normal file
100
src/VillageState.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { Village } from './Core/Village';
|
||||
import { Scheduler } from './Scheduler';
|
||||
import { Resources } from './Core/Resources';
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { calcGatheringTimings } from './Core/GatheringTimings';
|
||||
|
||||
interface RequiredResources {
|
||||
resources: Resources;
|
||||
balance: Resources;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface VillageOwnState {
|
||||
id: number;
|
||||
village: Village;
|
||||
resources: Resources;
|
||||
performance: Resources;
|
||||
required: RequiredResources;
|
||||
totalRequired: RequiredResources;
|
||||
incomingResources: Resources;
|
||||
storage: Resources;
|
||||
buildRemainingSeconds: number;
|
||||
}
|
||||
|
||||
interface VillageOwnStateDictionary {
|
||||
[id: number]: VillageOwnState;
|
||||
}
|
||||
|
||||
export interface VillageState extends VillageOwnState {
|
||||
commitments: Resources;
|
||||
}
|
||||
|
||||
function calcResourceBalance(resources: Resources, current: Resources, performance: Resources): RequiredResources {
|
||||
return {
|
||||
resources: resources,
|
||||
balance: current.sub(resources),
|
||||
time: timeToResources(current, resources, performance),
|
||||
};
|
||||
}
|
||||
|
||||
function timeToResources(current: Resources, desired: Resources, performance: Resources): number {
|
||||
const timings = calcGatheringTimings(current, desired, performance);
|
||||
if (timings.never) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return timings.hours * 3600;
|
||||
}
|
||||
|
||||
function calcIncomingResources(storage: VillageStorage): Resources {
|
||||
return storage.getIncomingMerchants().reduce((m, i) => m.add(i.resources), Resources.zero());
|
||||
}
|
||||
|
||||
function createVillageOwnState(village: Village, scheduler: Scheduler): VillageOwnState {
|
||||
const storage = new VillageStorage(village.id);
|
||||
const resources = storage.getResources();
|
||||
const resourceStorage = storage.getResourceStorage();
|
||||
const performance = storage.getResourcesPerformance();
|
||||
const buildQueueInfo = storage.getBuildingQueueInfo();
|
||||
const requiredResources = scheduler.getVillageRequiredResources(village.id);
|
||||
const totalRequiredResources = scheduler.getTotalVillageRequiredResources(village.id);
|
||||
|
||||
return {
|
||||
id: village.id,
|
||||
village,
|
||||
resources,
|
||||
performance,
|
||||
required: calcResourceBalance(requiredResources, resources, performance),
|
||||
totalRequired: calcResourceBalance(totalRequiredResources, resources, performance),
|
||||
storage: Resources.fromStorage(resourceStorage),
|
||||
buildRemainingSeconds: buildQueueInfo.seconds,
|
||||
incomingResources: calcIncomingResources(storage),
|
||||
};
|
||||
}
|
||||
|
||||
function createVillageOwnStates(villages: Array<Village>, scheduler: Scheduler): VillageOwnStateDictionary {
|
||||
const result: VillageOwnStateDictionary = {};
|
||||
for (let village of villages) {
|
||||
result[village.id] = createVillageOwnState(village, scheduler);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function createVillageState(
|
||||
state: VillageOwnState,
|
||||
ownStates: VillageOwnStateDictionary,
|
||||
scheduler: Scheduler
|
||||
): VillageState {
|
||||
const villageIds = scheduler.getResourceCommitments(state.id);
|
||||
const commitments = villageIds.reduce(
|
||||
(res, villageId) => res.add(ownStates[villageId].required.balance),
|
||||
Resources.zero()
|
||||
);
|
||||
return { ...state, commitments };
|
||||
}
|
||||
|
||||
export function createVillageStates(villages: Array<Village>, scheduler: Scheduler): Array<VillageState> {
|
||||
const ownStates = createVillageOwnStates(villages, scheduler);
|
||||
return villages.map(village => createVillageState(ownStates[village.id], ownStates, scheduler));
|
||||
}
|
Loading…
Reference in New Issue
Block a user