102 lines
3.5 KiB
TypeScript
102 lines
3.5 KiB
TypeScript
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) => {
|
|
const villageRequired = ownStates[villageId].required;
|
|
const missing = villageRequired.balance.min(Resources.zero());
|
|
return res.add(missing);
|
|
}, 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));
|
|
}
|