Move first task calculation to state
This commit is contained in:
parent
2622d0cc6e
commit
277a338164
@ -68,6 +68,9 @@
|
|||||||
<resource-line
|
<resource-line
|
||||||
v-if="villageState.required.active"
|
v-if="villageState.required.active"
|
||||||
:title="'След. задача:'"
|
:title="'След. задача:'"
|
||||||
|
:color="false"
|
||||||
|
:sign="false"
|
||||||
|
:hide-zero="false"
|
||||||
:resources="villageState.required.resources"
|
:resources="villageState.required.resources"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export class VillageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getReadyProductionTask(): Task | undefined {
|
getReadyProductionTask(): Task | undefined {
|
||||||
return this.taskCollection.getReadyForProductionTask();
|
return this.state.firstReadyTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
addTask(name: string, args: Args) {
|
addTask(name: string, args: Args) {
|
||||||
|
@ -4,10 +4,11 @@ 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, OrderedProductionQueues } from './Core/ProductionQueue';
|
import { ProductionQueue } from './Core/ProductionQueue';
|
||||||
import { Task } from './Queue/TaskProvider';
|
import { Task } from './Queue/TaskProvider';
|
||||||
import { timestamp } from './utils';
|
import { timestamp } from './utils';
|
||||||
import { VillageTaskCollection } from './VillageTaskCollection';
|
import { QueueTasks, VillageTaskCollection } from './VillageTaskCollection';
|
||||||
|
import { TrainTroopTask } from './Task/TrainTroopTask';
|
||||||
|
|
||||||
interface VillageStorageState {
|
interface VillageStorageState {
|
||||||
resources: Resources;
|
resources: Resources;
|
||||||
@ -42,6 +43,7 @@ interface ResourceLineState {
|
|||||||
|
|
||||||
interface VillageProductionQueueState {
|
interface VillageProductionQueueState {
|
||||||
queue: ProductionQueue;
|
queue: ProductionQueue;
|
||||||
|
tasks: Array<Task>;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
currentTaskFinishTimestamp: number;
|
currentTaskFinishTimestamp: number;
|
||||||
currentTaskFinishSeconds: number;
|
currentTaskFinishSeconds: number;
|
||||||
@ -50,6 +52,10 @@ interface VillageProductionQueueState {
|
|||||||
taskCount: number;
|
taskCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface VillageProductionQueueStateDict {
|
||||||
|
[queue: string]: VillageProductionQueueState;
|
||||||
|
}
|
||||||
|
|
||||||
interface VillageOwnState {
|
interface VillageOwnState {
|
||||||
/**
|
/**
|
||||||
* Village id
|
* Village id
|
||||||
@ -68,6 +74,8 @@ interface VillageOwnState {
|
|||||||
upperCriticalLevel: Resources;
|
upperCriticalLevel: Resources;
|
||||||
storageOptimumFullness: Resources;
|
storageOptimumFullness: Resources;
|
||||||
isOverflowing: boolean;
|
isOverflowing: boolean;
|
||||||
|
queues: VillageProductionQueueStateDict;
|
||||||
|
firstReadyTask: Task | undefined;
|
||||||
/**
|
/**
|
||||||
* Required resources for nearest task
|
* Required resources for nearest task
|
||||||
*/
|
*/
|
||||||
@ -82,7 +90,6 @@ interface VillageOwnState {
|
|||||||
totalRequired: ResourceLineState;
|
totalRequired: ResourceLineState;
|
||||||
incomingResources: Resources;
|
incomingResources: Resources;
|
||||||
settings: VillageSettings;
|
settings: VillageSettings;
|
||||||
queues: { [queue: string]: VillageProductionQueueState | undefined };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VillageOwnStateDictionary {
|
interface VillageOwnStateDictionary {
|
||||||
@ -96,7 +103,7 @@ export interface VillageState extends VillageOwnState {
|
|||||||
commitments: Resources;
|
commitments: Resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcResourceBalance(
|
function makeResourceBalance(
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
current: Resources,
|
current: Resources,
|
||||||
performance: Resources
|
performance: Resources
|
||||||
@ -109,7 +116,7 @@ function calcResourceBalance(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcStorageBalance(
|
function makeStorageBalance(
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
storage: Resources,
|
storage: Resources,
|
||||||
performance: Resources
|
performance: Resources
|
||||||
@ -153,28 +160,29 @@ function taskResourceReducer(resources: Resources, task: Task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createProductionQueueState(
|
function createProductionQueueState(
|
||||||
queue: ProductionQueue,
|
taskQueueInfo: QueueTasks,
|
||||||
storage: VillageStorage,
|
storage: VillageStorage
|
||||||
taskCollection: VillageTaskCollection
|
|
||||||
): VillageProductionQueueState {
|
): VillageProductionQueueState {
|
||||||
|
const queue = taskQueueInfo.queue;
|
||||||
|
const tasks = taskQueueInfo.tasks;
|
||||||
const resources = storage.getResources();
|
const resources = storage.getResources();
|
||||||
const performance = storage.getResourcesPerformance();
|
const performance = storage.getResourcesPerformance();
|
||||||
const tasks = taskCollection.getTasksInProductionQueue(queue);
|
|
||||||
|
|
||||||
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
const firstTaskResources = tasks.slice(0, 1).reduce(taskResourceReducer, Resources.zero());
|
||||||
const allTaskResources = tasks.reduce(taskResourceReducer, Resources.zero());
|
const allTaskResources = tasks.reduce(taskResourceReducer, Resources.zero());
|
||||||
const taskEndingTimestamp = storage.getQueueTaskEnding(queue);
|
const taskEndingTimestamp = taskQueueInfo.finishTs;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
queue,
|
queue,
|
||||||
|
tasks,
|
||||||
isActive: tasks.length !== 0 || taskEndingTimestamp > timestamp(),
|
isActive: tasks.length !== 0 || taskEndingTimestamp > timestamp(),
|
||||||
currentTaskFinishTimestamp: taskEndingTimestamp,
|
currentTaskFinishTimestamp: taskEndingTimestamp,
|
||||||
currentTaskFinishSeconds: Math.max(
|
currentTaskFinishSeconds: Math.max(
|
||||||
taskEndingTimestamp ? taskEndingTimestamp - timestamp() : 0,
|
taskEndingTimestamp ? taskEndingTimestamp - timestamp() : 0,
|
||||||
0
|
0
|
||||||
),
|
),
|
||||||
firstTask: calcResourceBalance(firstTaskResources, resources, performance),
|
firstTask: makeResourceBalance(firstTaskResources, resources, performance),
|
||||||
allTasks: calcResourceBalance(allTaskResources, resources, performance),
|
allTasks: makeResourceBalance(allTaskResources, resources, performance),
|
||||||
taskCount: tasks.length,
|
taskCount: tasks.length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -183,25 +191,54 @@ function createAllProductionQueueStates(
|
|||||||
storage: VillageStorage,
|
storage: VillageStorage,
|
||||||
taskCollection: VillageTaskCollection
|
taskCollection: VillageTaskCollection
|
||||||
) {
|
) {
|
||||||
let result: { [queue: string]: VillageProductionQueueState } = {};
|
let result: VillageProductionQueueStateDict = {};
|
||||||
for (let queue of OrderedProductionQueues) {
|
for (let taskQueueInfo of taskCollection.getQueueGroupedTasks()) {
|
||||||
result[queue] = createProductionQueueState(queue, storage, taskCollection);
|
result[taskQueueInfo.queue] = createProductionQueueState(taskQueueInfo, storage);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReadyForProductionTask(
|
||||||
|
queues: VillageProductionQueueStateDict,
|
||||||
|
maxResourcesForTask: Resources
|
||||||
|
): Task | undefined {
|
||||||
|
const nowTs = timestamp();
|
||||||
|
const firstReadyGroup = Object.values(queues).find(
|
||||||
|
group => group.currentTaskFinishTimestamp <= nowTs && group.tasks.length !== 0
|
||||||
|
);
|
||||||
|
if (!firstReadyGroup) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstReadyGroup.tasks.find(
|
||||||
|
t =>
|
||||||
|
t.name === TrainTroopTask.name ||
|
||||||
|
!t.args.resources ||
|
||||||
|
maxResourcesForTask.allGreaterOrEqual(Resources.fromObject(t.args.resources))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReadyTaskRequiredResources(task: Task | undefined): Resources {
|
||||||
|
if (task && task.args.resources) {
|
||||||
|
return Resources.fromObject(task.args.resources);
|
||||||
|
}
|
||||||
|
return Resources.zero();
|
||||||
|
}
|
||||||
|
|
||||||
function createVillageOwnState(
|
function createVillageOwnState(
|
||||||
village: Village,
|
village: Village,
|
||||||
storage: VillageStorage,
|
storage: VillageStorage,
|
||||||
taskCollection: VillageTaskCollection
|
taskCollection: VillageTaskCollection
|
||||||
): VillageOwnState {
|
): VillageOwnState {
|
||||||
const resources = storage.getResources();
|
const resources = storage.getResources();
|
||||||
const resourceStorage = storage.getResourceStorage();
|
const storageResources = Resources.fromStorage(storage.getResourceStorage());
|
||||||
const performance = storage.getResourcesPerformance();
|
const performance = storage.getResourcesPerformance();
|
||||||
const upperCriticalLevel = Resources.fromStorage(resourceStorage).sub(performance.scale(1));
|
const upperCriticalLevel = storageResources.sub(performance.scale(1));
|
||||||
const storageOptimumFullness = Resources.fromStorage(resourceStorage).sub(performance.scale(3));
|
const storageOptimumFullness = storageResources.sub(performance.scale(3));
|
||||||
const isOverflowing = upperCriticalLevel.anyLower(resources);
|
const isOverflowing = upperCriticalLevel.anyLower(resources);
|
||||||
const requiredResources = taskCollection.getReadyTaskRequiredResources();
|
const queues = createAllProductionQueueStates(storage, taskCollection);
|
||||||
|
const firstReadyTask = getReadyForProductionTask(queues, storageOptimumFullness);
|
||||||
|
const requiredResources = getReadyTaskRequiredResources(firstReadyTask);
|
||||||
const frontierResources = taskCollection.getFrontierResources();
|
const frontierResources = taskCollection.getFrontierResources();
|
||||||
const totalRequiredResources = taskCollection.getAllTasksRequiredResources();
|
const totalRequiredResources = taskCollection.getAllTasksRequiredResources();
|
||||||
|
|
||||||
@ -210,16 +247,17 @@ function createVillageOwnState(
|
|||||||
village,
|
village,
|
||||||
resources,
|
resources,
|
||||||
performance,
|
performance,
|
||||||
storage: calcStorageBalance(resources, Resources.fromStorage(resourceStorage), performance),
|
storage: makeStorageBalance(resources, storageResources, performance),
|
||||||
required: calcResourceBalance(requiredResources, resources, performance),
|
required: makeResourceBalance(requiredResources, resources, performance),
|
||||||
upperCriticalLevel,
|
upperCriticalLevel,
|
||||||
storageOptimumFullness,
|
storageOptimumFullness,
|
||||||
isOverflowing,
|
isOverflowing,
|
||||||
frontierRequired: calcResourceBalance(frontierResources, resources, performance),
|
queues,
|
||||||
totalRequired: calcResourceBalance(totalRequiredResources, resources, performance),
|
firstReadyTask,
|
||||||
|
frontierRequired: makeResourceBalance(frontierResources, resources, performance),
|
||||||
|
totalRequired: makeResourceBalance(totalRequiredResources, resources, performance),
|
||||||
incomingResources: calcIncomingResources(storage),
|
incomingResources: calcIncomingResources(storage),
|
||||||
settings: storage.getSettings(),
|
settings: storage.getSettings(),
|
||||||
queues: createAllProductionQueueStates(storage, taskCollection),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,8 @@ 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';
|
||||||
import * as _ from 'underscore';
|
import * as _ from 'underscore';
|
||||||
import { TrainTroopTask } from './Task/TrainTroopTask';
|
|
||||||
|
|
||||||
interface QueueTasks {
|
export interface QueueTasks {
|
||||||
queue: ProductionQueue;
|
queue: ProductionQueue;
|
||||||
tasks: Array<Task>;
|
tasks: Array<Task>;
|
||||||
finishTs: number;
|
finishTs: number;
|
||||||
@ -61,7 +60,7 @@ export class VillageTaskCollection {
|
|||||||
this.removeTasks(t => t.id === taskId);
|
this.removeTasks(t => t.id === taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getQueueGroupedTasks(): Array<QueueTasks> {
|
getQueueGroupedTasks(): Array<QueueTasks> {
|
||||||
const tasks = this.storage.getTasks();
|
const tasks = this.storage.getTasks();
|
||||||
const result: Array<QueueTasks> = [];
|
const result: Array<QueueTasks> = [];
|
||||||
for (let queue of OrderedProductionQueues) {
|
for (let queue of OrderedProductionQueues) {
|
||||||
@ -74,28 +73,6 @@ export class VillageTaskCollection {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTasksInProductionQueue(queue: ProductionQueue): Array<Task> {
|
|
||||||
return this.storage.getTasks().filter(isInQueue(queue));
|
|
||||||
}
|
|
||||||
|
|
||||||
getReadyForProductionTask(): Task | undefined {
|
|
||||||
const groups = this.getQueueGroupedTasks();
|
|
||||||
const nowTs = timestamp();
|
|
||||||
const firstReadyGroup = groups.find(g => g.finishTs <= nowTs && g.tasks.length !== 0);
|
|
||||||
if (!firstReadyGroup) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxCapacity = Resources.fromStorage(this.storage.getResourceStorage());
|
|
||||||
|
|
||||||
return firstReadyGroup.tasks.find(
|
|
||||||
t =>
|
|
||||||
t.name === TrainTroopTask.name ||
|
|
||||||
!t.args.resources ||
|
|
||||||
maxCapacity.allGreaterOrEqual(Resources.fromObject(t.args.resources))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
postponeTask(taskId: TaskId, seconds: number) {
|
postponeTask(taskId: TaskId, seconds: number) {
|
||||||
const modifyTime = withTime(timestamp() + seconds);
|
const modifyTime = withTime(timestamp() + seconds);
|
||||||
this.modifyTasks(task => task.id === taskId, modifyTime);
|
this.modifyTasks(task => task.id === taskId, modifyTime);
|
||||||
@ -116,14 +93,6 @@ export class VillageTaskCollection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getReadyTaskRequiredResources(): Resources {
|
|
||||||
const first = this.getReadyForProductionTask();
|
|
||||||
if (first && first.args.resources) {
|
|
||||||
return Resources.fromObject(first.args.resources);
|
|
||||||
}
|
|
||||||
return Resources.zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
getFrontierResources(): Resources {
|
getFrontierResources(): Resources {
|
||||||
let result = Resources.zero();
|
let result = Resources.zero();
|
||||||
const groups = this.getQueueGroupedTasks();
|
const groups = this.getQueueGroupedTasks();
|
||||||
|
Loading…
Reference in New Issue
Block a user