Improve village state management
This commit is contained in:
parent
8bea617f5b
commit
301b1a6ca9
@ -5,7 +5,7 @@ import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { VillageStorage } from '../Storage/VillageStorage';
|
||||
import { VillageStateRepository } from '../VillageState';
|
||||
import { VillageFactory } from '../VillageFactory';
|
||||
|
||||
const actionMap: { [name: string]: Function | undefined } = {};
|
||||
|
||||
@ -16,22 +16,22 @@ export function registerAction(constructor: Function) {
|
||||
export function createActionHandler(
|
||||
name: string,
|
||||
scheduler: Scheduler,
|
||||
villageStateRepository: VillageStateRepository
|
||||
villageFactory: VillageFactory
|
||||
): ActionController | undefined {
|
||||
const storedFunction = actionMap[name];
|
||||
if (storedFunction === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const constructor = (storedFunction as unknown) as typeof ActionController;
|
||||
return new constructor(scheduler, villageStateRepository);
|
||||
return new constructor(scheduler, villageFactory);
|
||||
}
|
||||
|
||||
export class ActionController {
|
||||
protected scheduler: Scheduler;
|
||||
protected villageStateRepository: VillageStateRepository;
|
||||
constructor(scheduler: Scheduler, villageStateRepository: VillageStateRepository) {
|
||||
protected readonly scheduler: Scheduler;
|
||||
protected readonly villageFactory: VillageFactory;
|
||||
constructor(scheduler: Scheduler, villageFactory: VillageFactory) {
|
||||
this.scheduler = scheduler;
|
||||
this.villageStateRepository = villageStateRepository;
|
||||
this.villageFactory = villageFactory;
|
||||
}
|
||||
|
||||
async run(args: Args, task: Task) {}
|
||||
|
@ -18,7 +18,7 @@ export class BalanceHeroResourcesAction extends ActionController {
|
||||
return;
|
||||
}
|
||||
|
||||
const thisVillageState = this.villageStateRepository.getVillageState(thisVillageId);
|
||||
const thisVillageState = this.villageFactory.createState(thisVillageId);
|
||||
|
||||
const requirements = [
|
||||
thisVillageState.required.balance,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { AbortTaskError, taskError } from '../Errors';
|
||||
import { taskError } from '../Errors';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
|
||||
|
@ -18,8 +18,8 @@ export class SendResourcesAction extends ActionController {
|
||||
|
||||
const coordinates = Coordinates.fromObject(args.coordinates || taskError('No coordinates'));
|
||||
|
||||
const senderVillage = this.villageStateRepository.getVillageState(senderVillageId);
|
||||
const recipientVillage = this.villageStateRepository.getVillageState(targetVillageId);
|
||||
const senderVillage = this.villageFactory.createState(senderVillageId);
|
||||
const recipientVillage = this.villageFactory.createState(targetVillageId);
|
||||
|
||||
const readyToTransfer = this.getResourcesForTransfer(senderVillage, recipientVillage);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { AbortTaskError, ActionError, taskError, TryLaterError } from '../Errors';
|
||||
import { ActionError, taskError, TryLaterError } from '../Errors';
|
||||
import { grabResourceDeposits } from '../Page/SlotBlock';
|
||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||
import { ResourceDeposit } from '../Game';
|
||||
|
@ -8,9 +8,8 @@ import { DataStorageTaskProvider } from './Queue/DataStorageTaskProvider';
|
||||
import { Statistics } from './Statistics';
|
||||
import { StatisticsStorage } from './Storage/StatisticsStorage';
|
||||
import { VillageRepository } from './VillageRepository';
|
||||
import { VillageStateRepository } from './VillageState';
|
||||
import { LogStorage } from './Storage/LogStorage';
|
||||
import { VillageControllerFactory } from './VillageControllerFactory';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
import { GrabberManager } from './Grabber/GrabberManager';
|
||||
|
||||
export class Container {
|
||||
@ -42,15 +41,15 @@ export class Container {
|
||||
return this._statistics;
|
||||
}
|
||||
|
||||
private _villageControllerFactory: VillageControllerFactory | undefined;
|
||||
private _villageFactory: VillageFactory | undefined;
|
||||
|
||||
get villageControllerFactory(): VillageControllerFactory {
|
||||
this._villageControllerFactory =
|
||||
this._villageControllerFactory ||
|
||||
get villageFactory(): VillageFactory {
|
||||
this._villageFactory =
|
||||
this._villageFactory ||
|
||||
(() => {
|
||||
return new VillageControllerFactory(this.villageRepository);
|
||||
return new VillageFactory(this.villageRepository);
|
||||
})();
|
||||
return this._villageControllerFactory;
|
||||
return this._villageFactory;
|
||||
}
|
||||
|
||||
private _scheduler: Scheduler | undefined;
|
||||
@ -68,31 +67,20 @@ export class Container {
|
||||
taskQueue,
|
||||
actionQueue,
|
||||
this.villageRepository,
|
||||
this.villageControllerFactory,
|
||||
this.villageFactory,
|
||||
new ConsoleLogger(Scheduler.name)
|
||||
);
|
||||
})();
|
||||
return this._scheduler;
|
||||
}
|
||||
|
||||
private _villageStateRepository: VillageStateRepository | undefined;
|
||||
|
||||
get villageStateRepository(): VillageStateRepository {
|
||||
this._villageStateRepository =
|
||||
this._villageStateRepository ||
|
||||
(() => {
|
||||
return new VillageStateRepository(this.villageRepository, this.villageControllerFactory);
|
||||
})();
|
||||
return this._villageStateRepository;
|
||||
}
|
||||
|
||||
private _grabberManager: GrabberManager | undefined;
|
||||
|
||||
get grabberManager(): GrabberManager {
|
||||
this._grabberManager =
|
||||
this._grabberManager ||
|
||||
(() => {
|
||||
return new GrabberManager(this.villageControllerFactory);
|
||||
return new GrabberManager(this.villageFactory);
|
||||
})();
|
||||
return this._grabberManager;
|
||||
}
|
||||
@ -110,8 +98,7 @@ export class Container {
|
||||
return new Executor(
|
||||
this.version,
|
||||
this.scheduler,
|
||||
this.villageStateRepository,
|
||||
this.villageControllerFactory,
|
||||
this.villageFactory,
|
||||
this.grabberManager,
|
||||
this.statistics,
|
||||
logger
|
||||
@ -126,12 +113,7 @@ export class Container {
|
||||
this._controlPanel =
|
||||
this._controlPanel ||
|
||||
(() => {
|
||||
return new ControlPanel(
|
||||
this.version,
|
||||
this.scheduler,
|
||||
this.villageStateRepository,
|
||||
this.villageControllerFactory
|
||||
);
|
||||
return new ControlPanel(this.version, this.scheduler, this.villageFactory);
|
||||
})();
|
||||
return this._controlPanel;
|
||||
}
|
||||
|
@ -18,11 +18,11 @@ import { ConsoleLogger, Logger } from './Logger';
|
||||
import { DataStorage } from './DataStorage';
|
||||
import { getBuildingPageAttributes, isBuildingPage } from './Page/PageDetectors';
|
||||
import { ExecutionStorage } from './Storage/ExecutionStorage';
|
||||
import { VillageState, VillageStateRepository } from './VillageState';
|
||||
import { VillageState } from './VillageState';
|
||||
import { Task } from './Queue/TaskProvider';
|
||||
import { Action } from './Queue/ActionQueue';
|
||||
import { createStore } from './DashboardView/Store';
|
||||
import { VillageControllerFactory } from './VillageControllerFactory';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
@ -52,20 +52,13 @@ interface GameState {
|
||||
export class ControlPanel {
|
||||
private readonly version: string;
|
||||
private readonly scheduler: Scheduler;
|
||||
private readonly villageStateRepository: VillageStateRepository;
|
||||
private readonly logger: Logger;
|
||||
private villageControllerFactory: VillageControllerFactory;
|
||||
private readonly villageFactory: VillageFactory;
|
||||
|
||||
constructor(
|
||||
version: string,
|
||||
scheduler: Scheduler,
|
||||
villageStateRepository: VillageStateRepository,
|
||||
villageControllerFactory: VillageControllerFactory
|
||||
) {
|
||||
constructor(version: string, scheduler: Scheduler, villageFactory: VillageFactory) {
|
||||
this.version = version;
|
||||
this.scheduler = scheduler;
|
||||
this.villageStateRepository = villageStateRepository;
|
||||
this.villageControllerFactory = villageControllerFactory;
|
||||
this.villageFactory = villageFactory;
|
||||
this.logger = new ConsoleLogger(this.constructor.name);
|
||||
}
|
||||
|
||||
@ -78,7 +71,7 @@ export class ControlPanel {
|
||||
const villageId = grabActiveVillageId();
|
||||
|
||||
const scheduler = this.scheduler;
|
||||
const villageStateRepository = this.villageStateRepository;
|
||||
const villageFactory = this.villageFactory;
|
||||
|
||||
const executionState = new ExecutionStorage();
|
||||
|
||||
@ -106,7 +99,7 @@ export class ControlPanel {
|
||||
},
|
||||
|
||||
refreshVillages() {
|
||||
this.villageStates = villageStateRepository.getAllVillageStates();
|
||||
this.villageStates = villageFactory.getAllVillageStates();
|
||||
for (let state of this.villageStates) {
|
||||
if (state.village.active) {
|
||||
this.activeVillageState = state;
|
||||
@ -136,8 +129,8 @@ export class ControlPanel {
|
||||
DataStorage.onChange(() => state.refresh());
|
||||
|
||||
const getBuildingsInQueue = () =>
|
||||
this.villageControllerFactory
|
||||
.create(villageId)
|
||||
this.villageFactory
|
||||
.createTaskCollection(villageId)
|
||||
.getTasks()
|
||||
.filter(t => t.name === UpgradeBuildingTask.name)
|
||||
.map(t => t.args.buildId || 0);
|
||||
@ -163,21 +156,21 @@ export class ControlPanel {
|
||||
const buildPage = new BuildingPageController(
|
||||
this.scheduler,
|
||||
getBuildingPageAttributes(),
|
||||
this.villageControllerFactory.create(villageId)
|
||||
this.villageFactory.createController(villageId)
|
||||
);
|
||||
buildPage.run();
|
||||
}
|
||||
|
||||
this.createControlPanel(state, villageStateRepository);
|
||||
this.createControlPanel(state, villageFactory);
|
||||
}
|
||||
|
||||
private createControlPanel(gameState: GameState, villageStateRepository: VillageStateRepository) {
|
||||
private createControlPanel(gameState: GameState, villageFactory: VillageFactory) {
|
||||
const appId = `app-${uniqId()}`;
|
||||
jQuery('body').prepend(`<div id="${appId}"></div>`);
|
||||
new Vue({
|
||||
el: `#${appId}`,
|
||||
data: gameState,
|
||||
store: createStore(villageStateRepository),
|
||||
store: createStore(villageFactory),
|
||||
render: h => h(DashboardApp),
|
||||
});
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import Vuex from 'vuex';
|
||||
import { LogStorage } from '../Storage/LogStorage';
|
||||
import { VillageStateRepository } from '../VillageState';
|
||||
import { VillageSettings, VillageSettingsDefaults } from '../Core/Village';
|
||||
import { getNumber, notify } from '../utils';
|
||||
import { VillageStorage } from '../Storage/VillageStorage';
|
||||
import { VillageFactory } from '../VillageFactory';
|
||||
|
||||
export enum Mutations {
|
||||
showLogs = 'showLogs',
|
||||
@ -22,7 +22,7 @@ export enum Actions {
|
||||
SaveVillageSettings = 'save_village_settings',
|
||||
}
|
||||
|
||||
export function createStore(villageStateRepository: VillageStateRepository) {
|
||||
export function createStore(villageFactory: VillageFactory) {
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
views: {
|
||||
@ -74,7 +74,7 @@ export function createStore(villageStateRepository: VillageStateRepository) {
|
||||
},
|
||||
actions: {
|
||||
[Actions.OpenVillageEditor]({ commit }, { villageId }) {
|
||||
const state = villageStateRepository.getVillageState(villageId);
|
||||
const state = villageFactory.createState(villageId);
|
||||
const settings = state.settings;
|
||||
commit(Mutations.SetVillageSettings, {
|
||||
villageId: state.id,
|
||||
|
@ -10,8 +10,8 @@ import { ExecutionStorage } from './Storage/ExecutionStorage';
|
||||
import { Action } from './Queue/ActionQueue';
|
||||
import { Task } from './Queue/TaskProvider';
|
||||
import { createTaskHandler } from './Task/TaskMap';
|
||||
import { VillageStateRepository } from './VillageState';
|
||||
import { VillageControllerFactory } from './VillageControllerFactory';
|
||||
import { VillageStateFactory } from './VillageState';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
|
||||
export interface ExecutionSettings {
|
||||
pauseTs: number;
|
||||
@ -20,8 +20,7 @@ export interface ExecutionSettings {
|
||||
export class Executor {
|
||||
private readonly version: string;
|
||||
private readonly scheduler: Scheduler;
|
||||
private readonly villageStateRepository: VillageStateRepository;
|
||||
private villageControllerFactory: VillageControllerFactory;
|
||||
private villageFactory: VillageFactory;
|
||||
private grabberManager: GrabberManager;
|
||||
private statistics: Statistics;
|
||||
private executionState: ExecutionStorage;
|
||||
@ -30,16 +29,14 @@ export class Executor {
|
||||
constructor(
|
||||
version: string,
|
||||
scheduler: Scheduler,
|
||||
villageStateRepository: VillageStateRepository,
|
||||
villageControllerFactory: VillageControllerFactory,
|
||||
villageFactory: VillageFactory,
|
||||
grabberManager: GrabberManager,
|
||||
statistics: Statistics,
|
||||
logger: Logger
|
||||
) {
|
||||
this.version = version;
|
||||
this.scheduler = scheduler;
|
||||
this.villageStateRepository = villageStateRepository;
|
||||
this.villageControllerFactory = villageControllerFactory;
|
||||
this.villageFactory = villageFactory;
|
||||
this.grabberManager = grabberManager;
|
||||
this.statistics = statistics;
|
||||
this.executionState = new ExecutionStorage();
|
||||
@ -109,7 +106,7 @@ export class Executor {
|
||||
}
|
||||
|
||||
private async processActionCommand(action: Action, task: Task) {
|
||||
const actionHandler = createActionHandler(action.name, this.scheduler, this.villageStateRepository);
|
||||
const actionHandler = createActionHandler(action.name, this.scheduler, this.villageFactory);
|
||||
this.logger.info('Process action', action.name, actionHandler);
|
||||
if (actionHandler) {
|
||||
this.statistics.incrementAction(timestamp());
|
||||
|
@ -20,7 +20,7 @@ export class BuildingContractGrabber extends Grabber {
|
||||
|
||||
const contract = grabContractResources();
|
||||
|
||||
this.controller.updateResources(contract, {
|
||||
this.taskCollection.updateResources(contract, {
|
||||
type: ContractType.UpgradeBuilding,
|
||||
buildId: building.buildId,
|
||||
});
|
||||
|
@ -20,7 +20,7 @@ export class ForgePageGrabber extends Grabber {
|
||||
const contracts = grabImprovementContracts();
|
||||
|
||||
for (let { resources, unitId } of contracts) {
|
||||
this.controller.updateResources(resources, {
|
||||
this.taskCollection.updateResources(resources, {
|
||||
type: ContractType.ImproveTrooper,
|
||||
buildId,
|
||||
unitId,
|
||||
@ -29,8 +29,7 @@ export class ForgePageGrabber extends Grabber {
|
||||
}
|
||||
|
||||
private grabTimer(): void {
|
||||
const storage = this.controller.getStorage();
|
||||
const seconds = grabRemainingSeconds();
|
||||
storage.storeQueueTaskEnding(ProductionQueue.UpgradeUnit, seconds ? seconds + timestamp() : 0);
|
||||
this.storage.storeQueueTaskEnding(ProductionQueue.UpgradeUnit, seconds ? seconds + timestamp() : 0);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
import { VillageController } from '../VillageController';
|
||||
import { VillageTaskCollection } from '../VillageTaskCollection';
|
||||
import { VillageStorage } from '../Storage/VillageStorage';
|
||||
|
||||
export abstract class Grabber {
|
||||
protected controller: VillageController;
|
||||
protected taskCollection: VillageTaskCollection;
|
||||
protected storage: VillageStorage;
|
||||
|
||||
constructor(controller: VillageController) {
|
||||
this.controller = controller;
|
||||
constructor(taskCollection: VillageTaskCollection, storage: VillageStorage) {
|
||||
this.taskCollection = taskCollection;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
abstract grab(): void;
|
||||
|
@ -6,12 +6,12 @@ import { MarketPageGrabber } from './MarketPageGrabber';
|
||||
import { BuildingContractGrabber } from './BuildingContractGrabber';
|
||||
import { ForgePageGrabber } from './ForgePageGrabber';
|
||||
import { GuildHallPageGrabber } from './GuildHallPageGrabber';
|
||||
import { VillageControllerFactory } from '../VillageControllerFactory';
|
||||
import { VillageFactory } from '../VillageFactory';
|
||||
|
||||
export class GrabberManager {
|
||||
private factory: VillageControllerFactory;
|
||||
private factory: VillageFactory;
|
||||
|
||||
constructor(factory: VillageControllerFactory) {
|
||||
constructor(factory: VillageFactory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@ -23,15 +23,16 @@ export class GrabberManager {
|
||||
}
|
||||
|
||||
private createGrabbers(): Array<Grabber> {
|
||||
const controller = this.factory.getActive();
|
||||
const storage = this.factory.createStorageForActiveVillage();
|
||||
const taskCollection = this.factory.createTaskCollectionForActiveVillage();
|
||||
const grabbers: Array<Grabber> = [];
|
||||
grabbers.push(new VillageResourceGrabber(controller));
|
||||
grabbers.push(new VillageOverviewPageGrabber(controller));
|
||||
grabbers.push(new HeroPageGrabber(controller));
|
||||
grabbers.push(new MarketPageGrabber(controller));
|
||||
grabbers.push(new BuildingContractGrabber(controller));
|
||||
grabbers.push(new ForgePageGrabber(controller));
|
||||
grabbers.push(new GuildHallPageGrabber(controller));
|
||||
grabbers.push(new VillageResourceGrabber(taskCollection, storage));
|
||||
grabbers.push(new VillageOverviewPageGrabber(taskCollection, storage));
|
||||
grabbers.push(new HeroPageGrabber(taskCollection, storage));
|
||||
grabbers.push(new MarketPageGrabber(taskCollection, storage));
|
||||
grabbers.push(new BuildingContractGrabber(taskCollection, storage));
|
||||
grabbers.push(new ForgePageGrabber(taskCollection, storage));
|
||||
grabbers.push(new GuildHallPageGrabber(taskCollection, storage));
|
||||
return grabbers;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ export class GuildHallPageGrabber extends Grabber {
|
||||
}
|
||||
|
||||
const seconds = grabRemainingSeconds();
|
||||
const storage = this.controller.getStorage();
|
||||
storage.storeQueueTaskEnding(ProductionQueue.Celebration, seconds ? seconds + timestamp() : 0);
|
||||
this.storage.storeQueueTaskEnding(ProductionQueue.Celebration, seconds ? seconds + timestamp() : 0);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ export class MarketPageGrabber extends Grabber {
|
||||
return;
|
||||
}
|
||||
|
||||
const storage = this.controller.getStorage();
|
||||
storage.storeIncomingMerchants(grabIncomingMerchants());
|
||||
this.storage.storeIncomingMerchants(grabIncomingMerchants());
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,12 @@ export class VillageOverviewPageGrabber extends Grabber {
|
||||
return;
|
||||
}
|
||||
|
||||
const storage = this.controller.getStorage();
|
||||
storage.storeResourcesPerformance(grabResourcesPerformance());
|
||||
storage.storeBuildingQueueInfo(this.grabBuildingQueueInfoOrDefault());
|
||||
this.storage.storeResourcesPerformance(grabResourcesPerformance());
|
||||
this.storage.storeBuildingQueueInfo(this.grabBuildingQueueInfoOrDefault());
|
||||
|
||||
const buildingQueueInfo = this.grabBuildingQueueInfoOrDefault();
|
||||
const buildingEndTime = buildingQueueInfo.seconds ? buildingQueueInfo.seconds + timestamp() : 0;
|
||||
storage.storeQueueTaskEnding(ProductionQueue.Building, buildingEndTime);
|
||||
this.storage.storeQueueTaskEnding(ProductionQueue.Building, buildingEndTime);
|
||||
}
|
||||
|
||||
private grabBuildingQueueInfoOrDefault() {
|
||||
|
@ -3,8 +3,7 @@ import { grabVillageResources, grabVillageResourceStorage } from '../Page/Resour
|
||||
|
||||
export class VillageResourceGrabber extends Grabber {
|
||||
grab(): void {
|
||||
const storage = this.controller.getStorage();
|
||||
storage.storeResources(grabVillageResources());
|
||||
storage.storeResourceStorage(grabVillageResourceStorage());
|
||||
this.storage.storeResources(grabVillageResources());
|
||||
this.storage.storeResourceStorage(grabVillageResourceStorage());
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,9 @@ import { ImmutableTaskList, Task, TaskId, uniqTaskId, withTime } from './Queue/T
|
||||
import { MARKET_ID } from './Core/Buildings';
|
||||
import { VillageRepositoryInterface } from './VillageRepository';
|
||||
import { isProductionTask } from './Core/ProductionQueue';
|
||||
import { VillageControllerFactory } from './VillageControllerFactory';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
import { RunVillageProductionTask } from './Task/RunVillageProductionTask';
|
||||
import { VillageNotFound } from './Errors';
|
||||
|
||||
export interface NextExecution {
|
||||
task?: Task;
|
||||
@ -24,14 +25,14 @@ export class Scheduler {
|
||||
private taskQueue: TaskQueue;
|
||||
private actionQueue: ActionQueue;
|
||||
private villageRepository: VillageRepositoryInterface;
|
||||
private villageControllerFactory: VillageControllerFactory;
|
||||
private villageControllerFactory: VillageFactory;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
taskQueue: TaskQueue,
|
||||
actionQueue: ActionQueue,
|
||||
villageRepository: VillageRepositoryInterface,
|
||||
villageControllerFactory: VillageControllerFactory,
|
||||
villageControllerFactory: VillageFactory,
|
||||
logger: Logger
|
||||
) {
|
||||
this.taskQueue = taskQueue;
|
||||
@ -96,13 +97,13 @@ export class Scheduler {
|
||||
private replaceTask(task: Task): Task | undefined {
|
||||
if (task.name === RunVillageProductionTask.name && task.args.villageId) {
|
||||
const villageId = task.args.villageId;
|
||||
const controller = this.villageControllerFactory.create(villageId);
|
||||
const controller = this.villageControllerFactory.createController(villageId);
|
||||
const villageTask = controller.getReadyProductionTask();
|
||||
if (villageTask) {
|
||||
this.removeTask(task.id);
|
||||
const newTask = new Task(villageTask.id, 0, villageTask.name, {
|
||||
...villageTask.args,
|
||||
villageId: controller.villageId,
|
||||
villageId: controller.getVillageId(),
|
||||
});
|
||||
this.taskQueue.add(newTask);
|
||||
return newTask;
|
||||
@ -113,7 +114,7 @@ export class Scheduler {
|
||||
|
||||
scheduleTask(name: string, args: Args, ts?: number | undefined): void {
|
||||
if (isProductionTask(name) && args.villageId) {
|
||||
const controller = this.villageControllerFactory.create(args.villageId);
|
||||
const controller = this.villageControllerFactory.createController(args.villageId);
|
||||
controller.addTask(name, args);
|
||||
} else {
|
||||
this.logger.info('Schedule task', name, args, ts);
|
||||
@ -143,7 +144,7 @@ export class Scheduler {
|
||||
const task = this.taskQueue.findById(taskId);
|
||||
const villageId = task ? task.args.villageId : undefined;
|
||||
if (villageId) {
|
||||
const controller = this.villageControllerFactory.create(villageId);
|
||||
const controller = this.villageControllerFactory.createController(villageId);
|
||||
controller.removeTask(taskId);
|
||||
}
|
||||
this.removeTask(taskId);
|
||||
@ -156,7 +157,7 @@ export class Scheduler {
|
||||
}
|
||||
|
||||
if (isProductionTask(task.name) && task.args.villageId) {
|
||||
const controller = this.villageControllerFactory.create(task.args.villageId);
|
||||
const controller = this.villageControllerFactory.createController(task.args.villageId);
|
||||
controller.postponeTask(taskId, seconds);
|
||||
this.removeTask(taskId);
|
||||
} else {
|
||||
@ -186,7 +187,7 @@ export class Scheduler {
|
||||
this.dropResourceTransferTasks(fromVillageId, toVillageId);
|
||||
const village = this.villageRepository.all().find(v => v.id === toVillageId);
|
||||
if (!village) {
|
||||
throw new Error('No village');
|
||||
throw new VillageNotFound(`Village ${toVillageId} not found`);
|
||||
}
|
||||
this.scheduleTask(SendResourcesTask.name, {
|
||||
villageId: fromVillageId,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { DataStorage } from '../DataStorage';
|
||||
import { ActionStatistics, StatisticsStorageInterface } from '../Statistics';
|
||||
import { LogStorageInterface, StorageLogRecord } from '../Logger';
|
||||
|
||||
const NAMESPACE = 'logs.v1';
|
||||
|
@ -112,41 +112,7 @@ export class VillageStorage {
|
||||
});
|
||||
}
|
||||
|
||||
addTask(task: Task): void {
|
||||
const tasks = this.getTasks();
|
||||
tasks.push(task);
|
||||
this.storeTaskList(tasks);
|
||||
}
|
||||
|
||||
modifyTasks(predicate: (t: Task) => boolean, modifier: (t: Task) => Task): number {
|
||||
const [matched, other] = this.split(predicate);
|
||||
const modified = matched.map(modifier);
|
||||
const modifiedCount = modified.length;
|
||||
this.storeTaskList(modified.concat(other));
|
||||
return modifiedCount;
|
||||
}
|
||||
|
||||
removeTasks(predicate: (t: Task) => boolean): number {
|
||||
const [_, other] = this.split(predicate);
|
||||
const result = other.length;
|
||||
this.storeTaskList(other);
|
||||
return result;
|
||||
}
|
||||
|
||||
private split(predicate: (t: Task) => boolean): [TaskList, TaskList] {
|
||||
const matched: TaskList = [];
|
||||
const other: TaskList = [];
|
||||
this.getTasks().forEach(t => {
|
||||
if (predicate(t)) {
|
||||
matched.push(t);
|
||||
} else {
|
||||
other.push(t);
|
||||
}
|
||||
});
|
||||
return [matched, other];
|
||||
}
|
||||
|
||||
private storeTaskList(tasks: Array<Task>): void {
|
||||
storeTaskList(tasks: Array<Task>): void {
|
||||
this.storage.set(TASK_LIST_KEY, tasks);
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +1,36 @@
|
||||
import { Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { VillageTaskCollection } from './VillageTaskCollection';
|
||||
import { Task, TaskId } from './Queue/TaskProvider';
|
||||
import { Args } from './Queue/Args';
|
||||
import { isProductionTask, ProductionQueue, ProductionQueueTypes } from './Core/ProductionQueue';
|
||||
import { Resources } from './Core/Resources';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
|
||||
import { ContractType, ContractAttributes } from './Core/Contract';
|
||||
import { timestamp } from './utils';
|
||||
import { getProductionQueue } from './Task/TaskMap';
|
||||
import { VillageState } from './VillageState';
|
||||
|
||||
export class VillageController {
|
||||
private readonly _villageId: number;
|
||||
private readonly _storage: VillageStorage;
|
||||
private readonly villageId: number;
|
||||
private taskCollection: VillageTaskCollection;
|
||||
private readonly state: VillageState;
|
||||
|
||||
constructor(villageId: number, storage: VillageStorage) {
|
||||
this._villageId = villageId;
|
||||
this._storage = storage;
|
||||
constructor(villageId: number, taskCollection: VillageTaskCollection, state: VillageState) {
|
||||
this.villageId = villageId;
|
||||
this.taskCollection = taskCollection;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
get villageId() {
|
||||
return this._villageId;
|
||||
}
|
||||
|
||||
getStorage(): VillageStorage {
|
||||
return this._storage;
|
||||
}
|
||||
|
||||
addTask(name: string, args: Args) {
|
||||
if (!isProductionTask(name)) {
|
||||
throw new Error(`Task "${name}" is not production task`);
|
||||
}
|
||||
if (args.villageId !== this._villageId) {
|
||||
throw new Error(`Task village id (${args.villageId}) not equal controller village id (${this._villageId}`);
|
||||
}
|
||||
const task = new Task(uniqTaskId(), 0, name, { villageId: this._villageId, ...args });
|
||||
this._storage.addTask(task);
|
||||
}
|
||||
|
||||
getTasks(): Array<Task> {
|
||||
return this._storage.getTasks();
|
||||
}
|
||||
|
||||
removeTask(taskId: TaskId) {
|
||||
this._storage.removeTasks(t => t.id === taskId);
|
||||
}
|
||||
|
||||
getTasksInProductionQueue(queue: ProductionQueue): Array<Task> {
|
||||
return this._storage.getTasks().filter(task => getProductionQueue(task.name) === queue);
|
||||
getVillageId() {
|
||||
return this.villageId;
|
||||
}
|
||||
|
||||
getReadyProductionTask(): Task | undefined {
|
||||
let sortedTasks: Array<Task> = [];
|
||||
for (let queue of ProductionQueueTypes) {
|
||||
const tasks = this.getTasksInProductionQueue(queue);
|
||||
sortedTasks = sortedTasks.concat(tasks);
|
||||
return this.taskCollection.getReadyProductionTask();
|
||||
}
|
||||
return sortedTasks.shift();
|
||||
|
||||
addTask(name: string, args: Args) {
|
||||
this.taskCollection.addTask(name, args);
|
||||
}
|
||||
|
||||
removeTask(taskId: TaskId) {
|
||||
this.taskCollection.removeTask(taskId);
|
||||
}
|
||||
|
||||
postponeTask(taskId: TaskId, seconds: number) {
|
||||
const modifyTime = withTime(timestamp() + seconds);
|
||||
this._storage.modifyTasks(task => task.id === taskId, modifyTime);
|
||||
}
|
||||
|
||||
updateResources(resources: Resources, attr: ContractAttributes): void {
|
||||
if (attr.type === ContractType.UpgradeBuilding && attr.buildId) {
|
||||
const predicate = (t: Task) => t.name === UpgradeBuildingTask.name && t.args.buildId === attr.buildId;
|
||||
this._storage.modifyTasks(predicate, withResources(resources));
|
||||
}
|
||||
if (attr.type === ContractType.ImproveTrooper && attr.buildId && attr.unitId) {
|
||||
const predicate = (t: Task) =>
|
||||
t.name === ForgeImprovementTask.name &&
|
||||
t.args.buildId === attr.buildId &&
|
||||
t.args.unitId === attr.unitId;
|
||||
this._storage.modifyTasks(predicate, withResources(resources));
|
||||
}
|
||||
}
|
||||
|
||||
getVillageRequiredResources(): Resources {
|
||||
const tasks = this._storage.getTasks().filter(t => t.args.resources);
|
||||
const first = tasks.shift();
|
||||
if (first && first.args.resources) {
|
||||
return Resources.fromObject(first.args.resources);
|
||||
}
|
||||
return Resources.zero();
|
||||
}
|
||||
|
||||
getTotalVillageRequiredResources(): Resources {
|
||||
const tasks = this._storage.getTasks().filter(t => t.args.resources);
|
||||
return tasks.reduce((acc, t) => acc.add(t.args.resources!), Resources.zero());
|
||||
this.taskCollection.postponeTask(taskId, seconds);
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
import { VillageController } from './VillageController';
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { VillageRepository } from './VillageRepository';
|
||||
|
||||
export class VillageControllerFactory {
|
||||
private villageRepository: VillageRepository;
|
||||
|
||||
constructor(villageRepository: VillageRepository) {
|
||||
this.villageRepository = villageRepository;
|
||||
}
|
||||
|
||||
create(villageId: number): VillageController {
|
||||
const village = this.villageRepository.get(villageId);
|
||||
return new VillageController(village.id, new VillageStorage(village.id));
|
||||
}
|
||||
|
||||
getActive(): VillageController {
|
||||
const village = this.villageRepository.getActive();
|
||||
return this.create(village.id);
|
||||
}
|
||||
}
|
57
src/VillageFactory.ts
Normal file
57
src/VillageFactory.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { VillageController } from './VillageController';
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { VillageRepository } from './VillageRepository';
|
||||
import { VillageTaskCollection } from './VillageTaskCollection';
|
||||
import { VillageState, VillageStateFactory } from './VillageState';
|
||||
|
||||
export class VillageFactory {
|
||||
private readonly villageRepository: VillageRepository;
|
||||
|
||||
constructor(villageRepository: VillageRepository) {
|
||||
this.villageRepository = villageRepository;
|
||||
}
|
||||
|
||||
createStorage(villageId: number): VillageStorage {
|
||||
const village = this.villageRepository.get(villageId);
|
||||
return new VillageStorage(village.id);
|
||||
}
|
||||
|
||||
createStorageForActiveVillage(): VillageStorage {
|
||||
const village = this.villageRepository.getActive();
|
||||
return this.createStorage(village.id);
|
||||
}
|
||||
|
||||
createTaskCollection(villageId: number): VillageTaskCollection {
|
||||
const village = this.villageRepository.get(villageId);
|
||||
return new VillageTaskCollection(village.id, this.createStorage(villageId));
|
||||
}
|
||||
|
||||
createTaskCollectionForActiveVillage(): VillageTaskCollection {
|
||||
const village = this.villageRepository.getActive();
|
||||
return this.createTaskCollection(village.id);
|
||||
}
|
||||
|
||||
createState(villageId: number): VillageState {
|
||||
const village = this.villageRepository.get(villageId);
|
||||
const stateFactory = new VillageStateFactory(
|
||||
this.villageRepository,
|
||||
(id: number) => this.createStorage(id),
|
||||
(id: number) => this.createTaskCollection(id)
|
||||
);
|
||||
return stateFactory.getVillageState(village.id);
|
||||
}
|
||||
|
||||
getAllVillageStates(): Array<VillageState> {
|
||||
const stateFactory = new VillageStateFactory(
|
||||
this.villageRepository,
|
||||
(id: number) => this.createStorage(id),
|
||||
(id: number) => this.createTaskCollection(id)
|
||||
);
|
||||
return stateFactory.getAllVillageStates();
|
||||
}
|
||||
|
||||
createController(villageId: number): VillageController {
|
||||
const village = this.villageRepository.get(villageId);
|
||||
return new VillageController(village.id, this.createTaskCollection(village.id), this.createState(village.id));
|
||||
}
|
||||
}
|
@ -7,8 +7,7 @@ import { VillageNotFound } from './Errors';
|
||||
import { ProductionQueue, ProductionQueueTypes } from './Core/ProductionQueue';
|
||||
import { Task } from './Queue/TaskProvider';
|
||||
import { timestamp } from './utils';
|
||||
import { VillageControllerFactory } from './VillageControllerFactory';
|
||||
import { VillageController } from './VillageController';
|
||||
import { VillageTaskCollection } from './VillageTaskCollection';
|
||||
|
||||
interface VillageStorageState {
|
||||
resources: Resources;
|
||||
@ -134,12 +133,12 @@ function taskResourceReducer(resources: Resources, task: Task) {
|
||||
|
||||
function createProductionQueueState(
|
||||
queue: ProductionQueue,
|
||||
controller: VillageController
|
||||
storage: VillageStorage,
|
||||
taskCollection: VillageTaskCollection
|
||||
): VillageProductionQueueState {
|
||||
const storage = controller.getStorage();
|
||||
const resources = storage.getResources();
|
||||
const performance = storage.getResourcesPerformance();
|
||||
const tasks = controller.getTasksInProductionQueue(queue);
|
||||
const tasks = taskCollection.getTasksInProductionQueue(queue);
|
||||
|
||||
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
||||
const allTaskResources = tasks.reduce(taskResourceReducer, Resources.zero());
|
||||
@ -156,33 +155,36 @@ function createProductionQueueState(
|
||||
};
|
||||
}
|
||||
|
||||
function createAllProductionQueueStates(controller: VillageController) {
|
||||
function createAllProductionQueueStates(storage: VillageStorage, taskCollection: VillageTaskCollection) {
|
||||
let result: { [queue: string]: VillageProductionQueueState } = {};
|
||||
for (let queue of ProductionQueueTypes) {
|
||||
result[queue] = createProductionQueueState(queue, controller);
|
||||
result[queue] = createProductionQueueState(queue, storage, taskCollection);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function calcFrontierResources(controller: VillageController): Resources {
|
||||
function calcFrontierResources(taskCollection: VillageTaskCollection): Resources {
|
||||
let result = Resources.zero();
|
||||
for (let queue of ProductionQueueTypes) {
|
||||
const tasks = controller.getTasksInProductionQueue(queue);
|
||||
const tasks = taskCollection.getTasksInProductionQueue(queue);
|
||||
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
||||
result = result.add(firstTaskResources);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function createVillageOwnState(village: Village, controller: VillageController): VillageOwnState {
|
||||
const storage = controller.getStorage();
|
||||
function createVillageOwnState(
|
||||
village: Village,
|
||||
storage: VillageStorage,
|
||||
taskCollection: VillageTaskCollection
|
||||
): VillageOwnState {
|
||||
const resources = storage.getResources();
|
||||
const resourceStorage = storage.getResourceStorage();
|
||||
const performance = storage.getResourcesPerformance();
|
||||
const buildQueueInfo = storage.getBuildingQueueInfo();
|
||||
const requiredResources = controller.getVillageRequiredResources();
|
||||
const frontierResources = calcFrontierResources(controller);
|
||||
const totalRequiredResources = controller.getTotalVillageRequiredResources();
|
||||
const requiredResources = taskCollection.getVillageRequiredResources();
|
||||
const frontierResources = calcFrontierResources(taskCollection);
|
||||
const totalRequiredResources = taskCollection.getTotalVillageRequiredResources();
|
||||
|
||||
return {
|
||||
id: village.id,
|
||||
@ -196,18 +198,22 @@ function createVillageOwnState(village: Village, controller: VillageController):
|
||||
buildRemainingSeconds: buildQueueInfo.seconds,
|
||||
incomingResources: calcIncomingResources(storage),
|
||||
settings: storage.getSettings(),
|
||||
queues: createAllProductionQueueStates(controller),
|
||||
queues: createAllProductionQueueStates(storage, taskCollection),
|
||||
};
|
||||
}
|
||||
|
||||
function createVillageOwnStates(
|
||||
villages: Array<Village>,
|
||||
villageControllerFactory: VillageControllerFactory
|
||||
storageFactory: VillageStorageFactory,
|
||||
taskCollectionFactory: VillageTaskCollectionFactory
|
||||
): VillageOwnStateDictionary {
|
||||
const result: VillageOwnStateDictionary = {};
|
||||
for (let village of villages) {
|
||||
const villageController = villageControllerFactory.create(village.id);
|
||||
result[village.id] = createVillageOwnState(village, villageController);
|
||||
result[village.id] = createVillageOwnState(
|
||||
village,
|
||||
storageFactory(village.id),
|
||||
taskCollectionFactory(village.id)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -226,27 +232,42 @@ function createVillageState(state: VillageOwnState, ownStates: VillageOwnStateDi
|
||||
|
||||
function getVillageStates(
|
||||
villages: Array<Village>,
|
||||
villageControllerFactory: VillageControllerFactory
|
||||
storageFactory: VillageStorageFactory,
|
||||
taskCollectionFactory: VillageTaskCollectionFactory
|
||||
): Array<VillageState> {
|
||||
const ownStates = createVillageOwnStates(villages, villageControllerFactory);
|
||||
const ownStates = createVillageOwnStates(villages, storageFactory, taskCollectionFactory);
|
||||
return villages.map(village => createVillageState(ownStates[village.id], ownStates));
|
||||
}
|
||||
|
||||
export class VillageStateRepository {
|
||||
private villageRepository: VillageRepositoryInterface;
|
||||
private villageControllerFactory: VillageControllerFactory;
|
||||
interface VillageStorageFactory {
|
||||
(villageId: number): VillageStorage;
|
||||
}
|
||||
|
||||
constructor(villageRepository: VillageRepositoryInterface, villageControllerFactory: VillageControllerFactory) {
|
||||
interface VillageTaskCollectionFactory {
|
||||
(villageId: number): VillageTaskCollection;
|
||||
}
|
||||
|
||||
export class VillageStateFactory {
|
||||
private readonly villageRepository: VillageRepositoryInterface;
|
||||
private readonly storageFactory: VillageStorageFactory;
|
||||
private readonly taskCollectionFactory: VillageTaskCollectionFactory;
|
||||
|
||||
constructor(
|
||||
villageRepository: VillageRepositoryInterface,
|
||||
storageFactory: VillageStorageFactory,
|
||||
taskCollectionFactory: VillageTaskCollectionFactory
|
||||
) {
|
||||
this.villageRepository = villageRepository;
|
||||
this.villageControllerFactory = villageControllerFactory;
|
||||
this.storageFactory = storageFactory;
|
||||
this.taskCollectionFactory = taskCollectionFactory;
|
||||
}
|
||||
|
||||
getAllVillageStates(): Array<VillageState> {
|
||||
return getVillageStates(this.villageRepository.all(), this.villageControllerFactory);
|
||||
return getVillageStates(this.villageRepository.all(), this.storageFactory, this.taskCollectionFactory);
|
||||
}
|
||||
|
||||
getVillageState(villageId: number): VillageState {
|
||||
const states = getVillageStates(this.villageRepository.all(), this.villageControllerFactory);
|
||||
const states = getVillageStates(this.villageRepository.all(), this.storageFactory, this.taskCollectionFactory);
|
||||
const needle = states.find(s => s.id === villageId);
|
||||
if (!needle) {
|
||||
throw new VillageNotFound(`Village ${villageId} not found`);
|
||||
|
116
src/VillageTaskCollection.ts
Normal file
116
src/VillageTaskCollection.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { Task, TaskId, TaskList, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
|
||||
import { Args } from './Queue/Args';
|
||||
import { isProductionTask, ProductionQueue, ProductionQueueTypes } from './Core/ProductionQueue';
|
||||
import { getProductionQueue } from './Task/TaskMap';
|
||||
import { timestamp } from './utils';
|
||||
import { Resources } from './Core/Resources';
|
||||
import { ContractAttributes, ContractType } from './Core/Contract';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
|
||||
|
||||
export class VillageTaskCollection {
|
||||
private readonly storage: VillageStorage;
|
||||
private readonly villageId: number;
|
||||
|
||||
constructor(villageId: number, storage: VillageStorage) {
|
||||
this.villageId = villageId;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
getTasks(): Array<Task> {
|
||||
return this.storage.getTasks();
|
||||
}
|
||||
|
||||
private modifyTasks(predicate: (t: Task) => boolean, modifier: (t: Task) => Task): number {
|
||||
const [matched, other] = this.split(predicate);
|
||||
const modified = matched.map(modifier);
|
||||
const modifiedCount = modified.length;
|
||||
this.storage.storeTaskList(modified.concat(other));
|
||||
return modifiedCount;
|
||||
}
|
||||
|
||||
private removeTasks(predicate: (t: Task) => boolean): number {
|
||||
const [_, other] = this.split(predicate);
|
||||
const result = other.length;
|
||||
this.storage.storeTaskList(other);
|
||||
return result;
|
||||
}
|
||||
|
||||
private split(predicate: (t: Task) => boolean): [TaskList, TaskList] {
|
||||
const matched: TaskList = [];
|
||||
const other: TaskList = [];
|
||||
this.getTasks().forEach(t => {
|
||||
if (predicate(t)) {
|
||||
matched.push(t);
|
||||
} else {
|
||||
other.push(t);
|
||||
}
|
||||
});
|
||||
return [matched, other];
|
||||
}
|
||||
|
||||
addTask(name: string, args: Args) {
|
||||
if (!isProductionTask(name)) {
|
||||
throw new Error(`Task "${name}" is not production task`);
|
||||
}
|
||||
if (args.villageId !== this.villageId) {
|
||||
throw new Error(`Task village id (${args.villageId}) not equal controller village id (${this.villageId}`);
|
||||
}
|
||||
const task = new Task(uniqTaskId(), 0, name, { villageId: this.villageId, ...args });
|
||||
|
||||
const tasks = this.getTasks();
|
||||
tasks.push(task);
|
||||
this.storage.storeTaskList(tasks);
|
||||
}
|
||||
|
||||
removeTask(taskId: TaskId) {
|
||||
this.removeTasks(t => t.id === taskId);
|
||||
}
|
||||
|
||||
getTasksInProductionQueue(queue: ProductionQueue): Array<Task> {
|
||||
return this.storage.getTasks().filter(task => getProductionQueue(task.name) === queue);
|
||||
}
|
||||
|
||||
getReadyProductionTask(): Task | undefined {
|
||||
let sortedTasks: Array<Task> = [];
|
||||
for (let queue of ProductionQueueTypes) {
|
||||
const tasks = this.getTasksInProductionQueue(queue);
|
||||
sortedTasks = sortedTasks.concat(tasks);
|
||||
}
|
||||
return sortedTasks.shift();
|
||||
}
|
||||
|
||||
postponeTask(taskId: TaskId, seconds: number) {
|
||||
const modifyTime = withTime(timestamp() + seconds);
|
||||
this.modifyTasks(task => task.id === taskId, modifyTime);
|
||||
}
|
||||
|
||||
updateResources(resources: Resources, attr: ContractAttributes): void {
|
||||
if (attr.type === ContractType.UpgradeBuilding && attr.buildId) {
|
||||
const predicate = (t: Task) => t.name === UpgradeBuildingTask.name && t.args.buildId === attr.buildId;
|
||||
this.modifyTasks(predicate, withResources(resources));
|
||||
}
|
||||
if (attr.type === ContractType.ImproveTrooper && attr.buildId && attr.unitId) {
|
||||
const predicate = (t: Task) =>
|
||||
t.name === ForgeImprovementTask.name &&
|
||||
t.args.buildId === attr.buildId &&
|
||||
t.args.unitId === attr.unitId;
|
||||
this.modifyTasks(predicate, withResources(resources));
|
||||
}
|
||||
}
|
||||
|
||||
getVillageRequiredResources(): Resources {
|
||||
const tasks = this.storage.getTasks().filter(t => t.args.resources);
|
||||
const first = tasks.shift();
|
||||
if (first && first.args.resources) {
|
||||
return Resources.fromObject(first.args.resources);
|
||||
}
|
||||
return Resources.zero();
|
||||
}
|
||||
|
||||
getTotalVillageRequiredResources(): Resources {
|
||||
const tasks = this.storage.getTasks().filter(t => t.args.resources);
|
||||
return tasks.reduce((acc, t) => acc.add(t.args.resources!), Resources.zero());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user