Remove tasks from village task queue state if task can not be build now
This commit is contained in:
parent
effc1b1626
commit
b6d86ee659
@ -21,6 +21,7 @@ export function uniqTaskId(): TaskId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskCore {
|
export interface TaskCore {
|
||||||
|
readonly id: TaskId;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly args: Args;
|
readonly args: Args;
|
||||||
}
|
}
|
||||||
@ -48,7 +49,7 @@ export interface TaskProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskMatcher {
|
export interface TaskMatcher {
|
||||||
(task: Task): boolean;
|
(task: TaskCore): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskTransformer {
|
export interface TaskTransformer {
|
||||||
|
@ -4,10 +4,10 @@ import { VillageStorage } from './Storage/VillageStorage';
|
|||||||
import { calcGatheringTimings, GatheringTime } from './Core/GatheringTimings';
|
import { calcGatheringTimings, GatheringTime } from './Core/GatheringTimings';
|
||||||
import { VillageRepositoryInterface } from './VillageRepository';
|
import { VillageRepositoryInterface } from './VillageRepository';
|
||||||
import { VillageNotFound } from './Errors';
|
import { VillageNotFound } from './Errors';
|
||||||
import { ProductionQueue } from './Core/ProductionQueue';
|
import { OrderedProductionQueues, ProductionQueue } from './Core/ProductionQueue';
|
||||||
import { Task, TaskId } from './Queue/TaskProvider';
|
import { isInQueue, TaskCore, TaskId } from './Queue/TaskProvider';
|
||||||
import { timestamp } from './utils';
|
import { timestamp } from './utils';
|
||||||
import { QueueTasks, VillageTaskCollection } from './VillageTaskCollection';
|
import { VillageTaskCollection } from './VillageTaskCollection';
|
||||||
import { TrainTroopTask } from './Task/TrainTroopTask';
|
import { TrainTroopTask } from './Task/TrainTroopTask';
|
||||||
import { Args } from './Queue/Args';
|
import { Args } from './Queue/Args';
|
||||||
|
|
||||||
@ -20,7 +20,13 @@ export interface TaskState {
|
|||||||
canBeBuilt: boolean;
|
canBeBuilt: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VillageStorageState {
|
export interface TaskQueueState {
|
||||||
|
queue: ProductionQueue;
|
||||||
|
tasks: ReadonlyArray<TaskState>;
|
||||||
|
finishTs: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VillageWarehouseState {
|
||||||
resources: Resources;
|
resources: Resources;
|
||||||
capacity: Resources;
|
capacity: Resources;
|
||||||
balance: Resources;
|
balance: Resources;
|
||||||
@ -56,7 +62,7 @@ interface ResourceLineState {
|
|||||||
|
|
||||||
interface VillageProductionQueueState {
|
interface VillageProductionQueueState {
|
||||||
queue: ProductionQueue;
|
queue: ProductionQueue;
|
||||||
tasks: Array<TaskState>;
|
tasks: ReadonlyArray<TaskState>;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
isWaiting: boolean;
|
isWaiting: boolean;
|
||||||
currentTaskFinishTimestamp: number;
|
currentTaskFinishTimestamp: number;
|
||||||
@ -80,7 +86,7 @@ interface VillageOwnState {
|
|||||||
*/
|
*/
|
||||||
resources: Resources;
|
resources: Resources;
|
||||||
performance: Resources;
|
performance: Resources;
|
||||||
storage: VillageStorageState;
|
storage: VillageWarehouseState;
|
||||||
queues: Array<VillageProductionQueueState>;
|
queues: Array<VillageProductionQueueState>;
|
||||||
tasks: Array<TaskState>;
|
tasks: Array<TaskState>;
|
||||||
firstReadyTask: TaskState | undefined;
|
firstReadyTask: TaskState | undefined;
|
||||||
@ -120,7 +126,7 @@ function makeStorageState(
|
|||||||
resources: Resources,
|
resources: Resources,
|
||||||
storage: Resources,
|
storage: Resources,
|
||||||
performance: Resources
|
performance: Resources
|
||||||
): VillageStorageState {
|
): VillageWarehouseState {
|
||||||
const optimumFullness = storage.sub(performance.scale(3));
|
const optimumFullness = storage.sub(performance.scale(3));
|
||||||
const criticalFullness = storage.sub(performance.scale(1));
|
const criticalFullness = storage.sub(performance.scale(1));
|
||||||
return {
|
return {
|
||||||
@ -158,19 +164,13 @@ function calcIncomingResources(storage: VillageStorage): Resources {
|
|||||||
return storage.getIncomingMerchants().reduce((m, i) => m.add(i.resources), Resources.zero());
|
return storage.getIncomingMerchants().reduce((m, i) => m.add(i.resources), Resources.zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
function taskResourceReducer(resources: Resources, task: Task) {
|
|
||||||
return task.args.resources
|
|
||||||
? resources.add(Resources.fromObject(task.args.resources))
|
|
||||||
: resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createProductionQueueState(
|
function createProductionQueueState(
|
||||||
taskQueueInfo: QueueTasks,
|
taskQueueState: TaskQueueState,
|
||||||
storage: VillageStorageState
|
storage: VillageWarehouseState
|
||||||
): VillageProductionQueueState {
|
): VillageProductionQueueState {
|
||||||
const queue = taskQueueInfo.queue;
|
const queue = taskQueueState.queue;
|
||||||
const tasks = taskQueueInfo.tasks;
|
const tasks = taskQueueState.tasks;
|
||||||
const taskEndingTimestamp = taskQueueInfo.finishTs;
|
const taskEndingTimestamp = taskQueueState.finishTs;
|
||||||
const resources = storage.resources;
|
const resources = storage.resources;
|
||||||
const performance = storage.performance;
|
const performance = storage.performance;
|
||||||
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
||||||
@ -180,7 +180,7 @@ function createProductionQueueState(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
queue,
|
queue,
|
||||||
tasks: tasks.map(t => makeTaskState(t, storage.optimumFullness)),
|
tasks,
|
||||||
isActive: tasks.length !== 0 || taskEndingTimestamp > currentTimestamp,
|
isActive: tasks.length !== 0 || taskEndingTimestamp > currentTimestamp,
|
||||||
isWaiting: tasks.length !== 0 && taskEndingTimestamp < currentTimestamp,
|
isWaiting: tasks.length !== 0 && taskEndingTimestamp < currentTimestamp,
|
||||||
currentTaskFinishTimestamp: taskEndingTimestamp,
|
currentTaskFinishTimestamp: taskEndingTimestamp,
|
||||||
@ -194,13 +194,30 @@ function createProductionQueueState(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAllProductionQueueStates(
|
function getGroupedByQueueTasks(
|
||||||
storage: VillageStorageState,
|
tasks: ReadonlyArray<TaskState>,
|
||||||
taskCollection: VillageTaskCollection
|
storage: VillageStorage
|
||||||
|
): Array<TaskQueueState> {
|
||||||
|
const result: Array<TaskQueueState> = [];
|
||||||
|
for (let queue of OrderedProductionQueues) {
|
||||||
|
result.push({
|
||||||
|
queue,
|
||||||
|
tasks: tasks.filter(isInQueue(queue)),
|
||||||
|
finishTs: storage.getQueueTaskEnding(queue),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTaskQueueStates(
|
||||||
|
warehouse: VillageWarehouseState,
|
||||||
|
tasks: ReadonlyArray<TaskState>,
|
||||||
|
storage: VillageStorage
|
||||||
) {
|
) {
|
||||||
let result: Array<VillageProductionQueueState> = [];
|
let result: Array<VillageProductionQueueState> = [];
|
||||||
for (let taskQueueInfo of taskCollection.getGroupedByQueueTasks()) {
|
const possibleTasks = tasks.filter(task => task.canBeBuilt);
|
||||||
result.push(createProductionQueueState(taskQueueInfo, storage));
|
for (let taskQueueInfo of getGroupedByQueueTasks(possibleTasks, storage)) {
|
||||||
|
result.push(createProductionQueueState(taskQueueInfo, warehouse));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -216,27 +233,27 @@ function getReadyForProductionTask(
|
|||||||
return firstReadyQueue.tasks.find(task => task.name === TrainTroopTask.name || task.canBeBuilt);
|
return firstReadyQueue.tasks.find(task => task.name === TrainTroopTask.name || task.canBeBuilt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTaskResources(task: Task | TaskState | undefined): Resources {
|
function getTaskResources(task: TaskCore | undefined): Resources {
|
||||||
if (task && task.args.resources) {
|
if (task && task.args.resources) {
|
||||||
return Resources.fromObject(task.args.resources);
|
return Resources.fromObject(task.args.resources);
|
||||||
}
|
}
|
||||||
return Resources.zero();
|
return Resources.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTaskState(task: Task, maxResourcesForTask: Resources): TaskState {
|
function taskResourceReducer(resources: Resources, task: TaskCore) {
|
||||||
const taskResources = getTaskResources(task);
|
return task.args.resources
|
||||||
const taskWarehouseRequirements = new Resources(
|
? resources.add(Resources.fromObject(task.args.resources))
|
||||||
taskResources.lumber,
|
: resources;
|
||||||
taskResources.clay,
|
}
|
||||||
taskResources.iron,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const isEnoughWarehouseCapacity = maxResourcesForTask.allGreaterOrEqual(
|
|
||||||
taskWarehouseRequirements
|
|
||||||
);
|
|
||||||
|
|
||||||
const taskGranaryRequirements = new Resources(0, 0, 0, taskResources.crop);
|
function makeTaskState(task: TaskCore, maxResourcesForTask: Resources): TaskState {
|
||||||
const isEnoughGranaryCapacity = maxResourcesForTask.allGreaterOrEqual(taskGranaryRequirements);
|
const taskResources = getTaskResources(task);
|
||||||
|
const isEnoughWarehouseCapacity = maxResourcesForTask.allGreaterOrEqual(
|
||||||
|
new Resources(taskResources.lumber, taskResources.clay, taskResources.iron, 0)
|
||||||
|
);
|
||||||
|
const isEnoughGranaryCapacity = maxResourcesForTask.allGreaterOrEqual(
|
||||||
|
new Resources(0, 0, 0, taskResources.crop)
|
||||||
|
);
|
||||||
|
|
||||||
const canBeBuilt = isEnoughWarehouseCapacity && isEnoughGranaryCapacity;
|
const canBeBuilt = isEnoughWarehouseCapacity && isEnoughGranaryCapacity;
|
||||||
|
|
||||||
@ -260,9 +277,11 @@ function createVillageOwnState(
|
|||||||
const storageResources = Resources.fromStorage(storage.getResourceStorage());
|
const storageResources = Resources.fromStorage(storage.getResourceStorage());
|
||||||
const performance = storage.getResourcesPerformance();
|
const performance = storage.getResourcesPerformance();
|
||||||
const storageState = makeStorageState(resources, storageResources, performance);
|
const storageState = makeStorageState(resources, storageResources, performance);
|
||||||
const queues = createAllProductionQueueStates(storageState, taskCollection);
|
const tasks = taskCollection
|
||||||
|
.getTasks()
|
||||||
|
.map(t => makeTaskState(t, storageState.optimumFullness));
|
||||||
|
const queues = createTaskQueueStates(storageState, tasks, storage);
|
||||||
const firstReadyTask = getReadyForProductionTask(queues);
|
const firstReadyTask = getReadyForProductionTask(queues);
|
||||||
|
|
||||||
const requiredResources = getTaskResources(firstReadyTask);
|
const requiredResources = getTaskResources(firstReadyTask);
|
||||||
return {
|
return {
|
||||||
id: village.id,
|
id: village.id,
|
||||||
@ -271,8 +290,8 @@ function createVillageOwnState(
|
|||||||
performance,
|
performance,
|
||||||
storage: storageState,
|
storage: storageState,
|
||||||
required: makeResourceState(requiredResources, resources, performance),
|
required: makeResourceState(requiredResources, resources, performance),
|
||||||
|
tasks,
|
||||||
queues,
|
queues,
|
||||||
tasks: taskCollection.getTasks().map(t => makeTaskState(t, storageState.optimumFullness)),
|
|
||||||
firstReadyTask,
|
firstReadyTask,
|
||||||
incomingResources: calcIncomingResources(storage),
|
incomingResources: calcIncomingResources(storage),
|
||||||
settings,
|
settings,
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
import { VillageStorage } from './Storage/VillageStorage';
|
import { VillageStorage } from './Storage/VillageStorage';
|
||||||
import { isInQueue, Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
|
import { Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
|
||||||
import { Args } from './Queue/Args';
|
import { Args } from './Queue/Args';
|
||||||
import { isProductionTask, OrderedProductionQueues, ProductionQueue } from './Core/ProductionQueue';
|
import { isProductionTask } from './Core/ProductionQueue';
|
||||||
import { timestamp } from './utils';
|
import { timestamp } from './utils';
|
||||||
import { Resources } from './Core/Resources';
|
import { Resources } from './Core/Resources';
|
||||||
import { ContractAttributes, ContractType } from './Core/Contract';
|
import { ContractAttributes, ContractType } from './Core/Contract';
|
||||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||||
import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
|
import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
|
||||||
|
|
||||||
export interface QueueTasks {
|
|
||||||
queue: ProductionQueue;
|
|
||||||
tasks: Array<Task>;
|
|
||||||
finishTs: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VillageTaskCollection {
|
export class VillageTaskCollection {
|
||||||
private readonly storage: VillageStorage;
|
private readonly storage: VillageStorage;
|
||||||
private readonly villageId: number;
|
private readonly villageId: number;
|
||||||
@ -104,17 +98,4 @@ export class VillageTaskCollection {
|
|||||||
this.modifyTasks(predicate, withResources(resources));
|
this.modifyTasks(predicate, withResources(resources));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getGroupedByQueueTasks(): Array<QueueTasks> {
|
|
||||||
const tasks = this.storage.getTasks();
|
|
||||||
const result: Array<QueueTasks> = [];
|
|
||||||
for (let queue of OrderedProductionQueues) {
|
|
||||||
result.push({
|
|
||||||
queue,
|
|
||||||
tasks: tasks.filter(isInQueue(queue)),
|
|
||||||
finishTs: this.storage.getQueueTaskEnding(queue),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user