Quick fix for total requirement resources

This commit is contained in:
Anton Vakhrushev 2020-10-12 13:20:26 +03:00
parent 25969b8c0f
commit 7f3642d626
3 changed files with 83 additions and 98 deletions

View File

@ -22,7 +22,9 @@ export class BalanceHeroResourcesAction extends BaseAction {
const thisVillageState = this.villageFactory.getById(thisVillageId).state(); const thisVillageState = this.villageFactory.getById(thisVillageId).state();
const requirements = [ const requirements = [
// current balance of village
thisVillageState.required.balance, thisVillageState.required.balance,
//
thisVillageState.resources.sub(thisVillageState.warehouse.capacity), thisVillageState.resources.sub(thisVillageState.warehouse.capacity),
]; ];

View File

@ -1,12 +1,6 @@
import { BaseAction } from './BaseAction'; import { BaseAction } from './BaseAction';
import { FailTaskError, taskError, TryLaterError } from '../../Errors'; import { FailTaskError } from '../../Errors';
import { Resources } from '../../Core/Resources';
import { Coordinates } from '../../Core/Village';
import { Args } from '../../Queue/Args'; import { Args } from '../../Queue/Args';
import { clickSendButton, fillSendResourcesForm } from '../../Page/BuildingPage/MarketPage';
import { VillageState } from '../../Village/VillageState';
import { MerchantsInfo } from '../../Core/Market';
import { goToMarketSendResourcesPage, goToResourceViewPage } from '../ActionBundles';
import { import {
compareReports, compareReports,
ResourceTransferCalculator, ResourceTransferCalculator,
@ -15,7 +9,6 @@ import {
import { ResourceTransferStorage } from '../../Storage/ResourceTransferStorage'; import { ResourceTransferStorage } from '../../Storage/ResourceTransferStorage';
import { path } from '../../Helpers/Path'; import { path } from '../../Helpers/Path';
import { MARKET_ID } from '../../Core/Buildings'; import { MARKET_ID } from '../../Core/Buildings';
import { aroundMinutes, timestamp } from '../../Helpers/Time';
import { registerAction } from '../ActionMap'; import { registerAction } from '../ActionMap';
import { Task } from '../../Queue/Task'; import { Task } from '../../Queue/Task';

View File

@ -8,45 +8,6 @@ import { timestamp } from '../Helpers/Time';
import { isInQueue, TaskCore } from '../Queue/Task'; import { isInQueue, TaskCore } from '../Queue/Task';
import { TaskId } from '../Queue/TaskId'; import { TaskId } from '../Queue/TaskId';
export interface TaskState {
id: TaskId;
name: string;
args: Args;
isEnoughWarehouseCapacity: boolean;
isEnoughGranaryCapacity: boolean;
canBeBuilt: boolean;
}
export interface TaskQueueState {
queue: ProductionQueue;
tasks: ReadonlyArray<TaskState>;
finishTs: number;
}
interface VillageProductionQueueState {
queue: ProductionQueue;
tasks: ReadonlyArray<TaskState>;
isActive: boolean;
isWaiting: boolean;
currentTaskFinishTimestamp: number;
currentTaskFinishSeconds: number;
firstTask: ResourceLineState;
allTasks: ResourceLineState;
taskCount: number;
}
interface VillageWarehouseState {
resources: Resources;
capacity: Resources;
balance: Resources;
performance: Resources;
timeToZero: GatheringTime;
timeToFull: GatheringTime;
optimumFullness: Resources;
criticalFullness: Resources;
isOverflowing: boolean;
}
/** /**
* State of one or more tasks, which required some resources. * State of one or more tasks, which required some resources.
*/ */
@ -69,6 +30,45 @@ interface ResourceLineState {
active: boolean; active: boolean;
} }
export interface TaskState {
id: TaskId;
name: string;
args: Args;
isEnoughWarehouseCapacity: boolean;
isEnoughGranaryCapacity: boolean;
canBeBuilt: boolean;
}
interface TaskQueueState {
queue: ProductionQueue;
tasks: ReadonlyArray<TaskState>;
finishTs: number;
}
interface ProductionQueueState {
queue: ProductionQueue;
tasks: ReadonlyArray<TaskState>;
isActive: boolean;
isWaiting: boolean;
currentTaskFinishTimestamp: number;
currentTaskFinishSeconds: number;
firstTask: ResourceLineState;
allTasks: ResourceLineState;
taskCount: number;
}
interface WarehouseState {
resources: Resources;
capacity: Resources;
balance: Resources;
performance: Resources;
timeToZero: GatheringTime;
timeToFull: GatheringTime;
optimumFullness: Resources;
criticalFullness: Resources;
isOverflowing: boolean;
}
export interface VillageState { export interface VillageState {
/** /**
* Village id * Village id
@ -83,8 +83,8 @@ export interface VillageState {
*/ */
resources: Resources; resources: Resources;
performance: Resources; performance: Resources;
warehouse: VillageWarehouseState; warehouse: WarehouseState;
queues: Array<VillageProductionQueueState>; queues: Array<ProductionQueueState>;
tasks: Array<TaskState>; tasks: Array<TaskState>;
firstReadyTask: TaskState | undefined; firstReadyTask: TaskState | undefined;
/** /**
@ -95,24 +95,24 @@ export interface VillageState {
settings: VillageSettings; settings: VillageSettings;
} }
function makeResourceState( function makeResourceLineState(
resources: Resources, desired: Resources,
current: Resources, current: Resources,
performance: Resources performance: Resources
): ResourceLineState { ): ResourceLineState {
return { return {
resources, resources: desired,
balance: current.sub(resources), balance: current.sub(desired),
time: timeToAllResources(current, resources, performance), time: calcGatheringTimings(current, desired, performance).slowest,
active: !resources.empty(), active: !desired.empty(),
}; };
} }
function makeWarehouseState( function makeWarehouseState(
resources: Resources, current: Resources,
capacity: Resources, capacity: Resources,
performance: Resources performance: Resources
): VillageWarehouseState { ): WarehouseState {
// @fixme Если у героя большая добыча ресурсов, а склад маленький, то значения получаются тож маленькими // @fixme Если у героя большая добыча ресурсов, а склад маленький, то значения получаются тож маленькими
// @fixme с одной деревней это не прокатывает, и даже не построить склад // @fixme с одной деревней это не прокатывает, и даже не построить склад
// const optimumFullness = capacity.sub(performance.scale(3)); // const optimumFullness = capacity.sub(performance.scale(3));
@ -120,49 +120,31 @@ function makeWarehouseState(
const optimumFullness = capacity.scale(0.9); const optimumFullness = capacity.scale(0.9);
const criticalFullness = capacity.scale(0.98); const criticalFullness = capacity.scale(0.98);
return { return {
resources, resources: current,
capacity, capacity,
performance, performance,
balance: capacity.sub(resources), balance: capacity.sub(current),
timeToZero: timeToFastestResource(resources, Resources.zero(), performance), timeToZero: calcGatheringTimings(current, Resources.zero(), performance).fastest,
timeToFull: timeToFastestResource(resources, capacity, performance), timeToFull: calcGatheringTimings(current, capacity, performance).fastest,
optimumFullness: optimumFullness, optimumFullness,
criticalFullness: criticalFullness, criticalFullness,
isOverflowing: criticalFullness.anyLower(resources), isOverflowing: criticalFullness.anyLower(current),
}; };
} }
function timeToAllResources(
current: Resources,
desired: Resources,
performance: Resources
): GatheringTime {
const timings = calcGatheringTimings(current, desired, performance);
return timings.slowest;
}
function timeToFastestResource(
current: Resources,
desired: Resources,
performance: Resources
): GatheringTime {
const timings = calcGatheringTimings(current, desired, performance);
return timings.fastest;
}
function calcIncomingResources(storage: VillageStorage): Resources { 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 createProductionQueueState( function createProductionQueueState(
taskQueueState: TaskQueueState, taskQueueState: TaskQueueState,
storage: VillageWarehouseState warehouseState: WarehouseState
): VillageProductionQueueState { ): ProductionQueueState {
const queue = taskQueueState.queue; const queue = taskQueueState.queue;
const tasks = taskQueueState.tasks; const tasks = taskQueueState.tasks;
const taskEndingTimestamp = taskQueueState.finishTs; const taskEndingTimestamp = taskQueueState.finishTs;
const resources = storage.resources; const resources = warehouseState.resources;
const performance = storage.performance; const performance = warehouseState.performance;
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());
@ -178,8 +160,8 @@ function createProductionQueueState(
taskEndingTimestamp ? taskEndingTimestamp - currentTimestamp : 0, taskEndingTimestamp ? taskEndingTimestamp - currentTimestamp : 0,
0 0
), ),
firstTask: makeResourceState(firstTaskResources, resources, performance), firstTask: makeResourceLineState(firstTaskResources, resources, performance),
allTasks: makeResourceState(allTaskResources, resources, performance), allTasks: makeResourceLineState(allTaskResources, resources, performance),
taskCount: tasks.length, taskCount: tasks.length,
}; };
} }
@ -200,12 +182,12 @@ function getGroupedByQueueTasks(
} }
function createTaskQueueStates( function createTaskQueueStates(
warehouse: VillageWarehouseState, warehouse: WarehouseState,
tasks: ReadonlyArray<TaskState>, tasks: ReadonlyArray<TaskState>,
storage: VillageStorage storage: VillageStorage
) { ) {
let result: Array<VillageProductionQueueState> = []; let result: Array<ProductionQueueState> = [];
const possibleTasks = tasks.filter((task) => task.canBeBuilt); const possibleTasks = tasks.filter((taskState) => taskState.canBeBuilt);
for (let taskQueueInfo of getGroupedByQueueTasks(possibleTasks, storage)) { for (let taskQueueInfo of getGroupedByQueueTasks(possibleTasks, storage)) {
result.push(createProductionQueueState(taskQueueInfo, warehouse)); result.push(createProductionQueueState(taskQueueInfo, warehouse));
} }
@ -213,7 +195,7 @@ function createTaskQueueStates(
} }
function getReadyForProductionTask( function getReadyForProductionTask(
queues: ReadonlyArray<VillageProductionQueueState> queues: ReadonlyArray<ProductionQueueState>
): TaskState | undefined { ): TaskState | undefined {
const firstReadyQueue = queues.find((queue) => queue.isWaiting); const firstReadyQueue = queues.find((queue) => queue.isWaiting);
if (!firstReadyQueue) { if (!firstReadyQueue) {
@ -230,6 +212,14 @@ function getTaskResources(task: TaskCore | undefined): Resources {
return Resources.zero(); return Resources.zero();
} }
function getTotalTaskResources(task: TaskCore | undefined): Resources {
if (task && task.args.resources) {
const count = task.args.count || 1;
return Resources.fromObject(task.args.resources).scale(count);
}
return Resources.zero();
}
function taskResourceReducer(resources: Resources, task: TaskCore) { function taskResourceReducer(resources: Resources, task: TaskCore) {
return task.args.resources return task.args.resources
? resources.add(Resources.fromObject(task.args.resources)) ? resources.add(Resources.fromObject(task.args.resources))
@ -262,18 +252,18 @@ function createVillageState(village: Village, storage: VillageStorage): VillageS
const resources = storage.getResources(); const resources = storage.getResources();
const capacity = storage.getWarehouseCapacity(); const capacity = storage.getWarehouseCapacity();
const performance = storage.getResourcesPerformance(); const performance = storage.getResourcesPerformance();
const storageState = makeWarehouseState(resources, capacity, performance); const warehouse = makeWarehouseState(resources, capacity, performance);
const tasks = storage.getTasks().map((t) => makeTaskState(t, storageState.optimumFullness)); const tasks = storage.getTasks().map((t) => makeTaskState(t, warehouse.optimumFullness));
const queues = createTaskQueueStates(storageState, tasks, storage); const queues = createTaskQueueStates(warehouse, tasks, storage);
const firstReadyTask = getReadyForProductionTask(queues); const firstReadyTask = getReadyForProductionTask(queues);
const requiredResources = getTaskResources(firstReadyTask); const firstTaskResources = getTotalTaskResources(firstReadyTask);
return { return {
id: village.id, id: village.id,
village, village,
resources, resources,
performance, performance,
warehouse: storageState, warehouse,
required: makeResourceState(requiredResources, resources, performance), required: makeResourceLineState(firstTaskResources, resources, performance),
tasks, tasks,
queues, queues,
firstReadyTask, firstReadyTask,