diff --git a/src/Action/FindSendResourcesPath.ts b/src/Action/FindSendResourcesPath.ts index 1722ff6..e5cd59e 100644 --- a/src/Action/FindSendResourcesPath.ts +++ b/src/Action/FindSendResourcesPath.ts @@ -9,7 +9,11 @@ import { clickSendButton, fillSendResourcesForm } from '../Page/BuildingPage/Mar import { VillageState } from '../VillageState'; import { MerchantsInfo } from '../Core/Market'; import { goToMarketSendResourcesPage, goToResourceViewPage } from '../Task/ActionBundles'; -import { ResourceTransferCalculator, ResourceTransferReport } from '../ResourceTransfer'; +import { + compareReports, + ResourceTransferCalculator, + ResourceTransferReport, +} from '../ResourceTransfer'; import { ResourceTransferStorage } from '../Storage/ResourceTransferStorage'; import { path } from '../Helpers/Path'; import { MARKET_ID } from '../Core/Buildings'; @@ -29,7 +33,7 @@ export class FindSendResourcesPath extends ActionController { } } - reports.sort((r1, r2) => r2.score - r1.score); + reports.sort(compareReports); const bestReport = reports.shift(); diff --git a/src/DashboardView/VillageResource.vue b/src/DashboardView/VillageResource.vue index 0d150ab..a4c94e5 100644 --- a/src/DashboardView/VillageResource.vue +++ b/src/DashboardView/VillageResource.vue @@ -4,7 +4,7 @@ diff --git a/src/DashboardView/VillageStateList.vue b/src/DashboardView/VillageStateList.vue index e3b68cd..efefbf4 100644 --- a/src/DashboardView/VillageStateList.vue +++ b/src/DashboardView/VillageStateList.vue @@ -30,52 +30,40 @@ - - Прирост: - - - - - - - - - - - - - - - + - - След. задача: - - - - - - - - - - - - - - - + @@ -177,6 +135,8 @@ :title="'Опт. уровень:'" :hint="'Оптимальный уровень'" :hide-zero="true" + :color="false" + :sign="false" :resources="villageState.storageOptimumFullness" /> @@ -192,6 +152,11 @@ " >$->{{ s.village.name }} + + + + + Казармы Конюшни - + - + - + - + @@ -48,6 +48,14 @@ export default { type: Boolean, default: false, }, + color: { + type: Boolean, + default: true, + }, + sign: { + type: Boolean, + default: true, + }, }, }; diff --git a/src/ResourceTransfer.ts b/src/ResourceTransfer.ts index 928ac23..e8a3a48 100644 --- a/src/ResourceTransfer.ts +++ b/src/ResourceTransfer.ts @@ -1,11 +1,26 @@ import { VillageFactory } from './VillageFactory'; -import { ResourcesInterface } from './Core/Resources'; +import { Resources, ResourcesInterface } from './Core/Resources'; +import { VillageController } from './VillageController'; + +export interface ResourceTransferScore { + amount: number; + overflow: boolean; +} export interface ResourceTransferReport { fromVillageId: number; toVillageId: number; resources: ResourcesInterface; - score: number; + score: ResourceTransferScore; +} + +export function compareReports(r1: ResourceTransferReport, r2: ResourceTransferReport): number { + if (r1.score.overflow !== r2.score.overflow) { + const o1 = r1.score.overflow ? 1 : 0; + const o2 = r2.score.overflow ? 1 : 0; + return o2 - o1; + } + return r2.score.amount - r1.score.amount; } export class ResourceTransferCalculator { @@ -15,20 +30,21 @@ export class ResourceTransferCalculator { } calc(fromVillageId: number, toVillageId: number): ResourceTransferReport { - const senderState = this.factory.createState(fromVillageId); - const senderController = this.factory.createController(fromVillageId); - const senderStorage = this.factory.createStorage(fromVillageId); + const sender = this.factory.createController(fromVillageId); + const recipient = this.factory.createController(toVillageId); - const recipientController = this.factory.createController(toVillageId); + let [senderReadyResources, recipientNeedResources] = this.getTransferResourcePair( + sender, + recipient + ); + + const multiplier = sender.getSendResourcesMultiplier(); + senderReadyResources = senderReadyResources.downTo(multiplier); + recipientNeedResources = recipientNeedResources.upTo(multiplier); - const multiplier = senderState.settings.sendResourcesMultiplier; - const senderReadyResources = senderController - .getAvailableForSendResources() - .downTo(multiplier); - const recipientNeedResources = recipientController.getRequiredResources().upTo(multiplier); const contractResources = senderReadyResources.min(recipientNeedResources); - const merchantsInfo = senderStorage.getMerchantsInfo(); + const merchantsInfo = sender.getMerchantsInfo(); const merchantsCapacity = merchantsInfo.available * merchantsInfo.carry; let readyToTransfer = contractResources; @@ -50,7 +66,21 @@ export class ResourceTransferCalculator { fromVillageId, toVillageId, resources: readyToTransfer, - score: readyToTransfer.amount(), + score: { + amount: readyToTransfer.amount(), + overflow: sender.getState().isOverflowing, + }, }; } + + private getTransferResourcePair( + sender: VillageController, + recipient: VillageController + ): [Resources, Resources] { + if (sender.getState().isOverflowing) { + return [sender.getOverflowResources(), recipient.getAvailableToReceiveResources()]; + } + + return [sender.getFreeResources(), recipient.getRequiredResources()]; + } } diff --git a/src/Storage/ResourceTransferStorage.ts b/src/Storage/ResourceTransferStorage.ts index 56809cd..d132fde 100644 --- a/src/Storage/ResourceTransferStorage.ts +++ b/src/Storage/ResourceTransferStorage.ts @@ -26,7 +26,10 @@ export class ResourceTransferStorage { iron: 0, crop: 0, }, - score: 0, + score: { + amount: 0, + overflow: false, + }, }), }); } diff --git a/src/VillageController.ts b/src/VillageController.ts index a0296d3..82cdef6 100644 --- a/src/VillageController.ts +++ b/src/VillageController.ts @@ -5,14 +5,23 @@ import { VillageState } from './VillageState'; import { Resources } from './Core/Resources'; import { TryLaterError } from './Errors'; import { aroundMinutes } from './utils'; +import { MerchantsInfo } from './Core/Market'; +import { VillageStorage } from './Storage/VillageStorage'; export class VillageController { private readonly villageId: number; + private readonly storage: VillageStorage; private readonly taskCollection: VillageTaskCollection; private readonly state: VillageState; - constructor(villageId: number, taskCollection: VillageTaskCollection, state: VillageState) { + constructor( + villageId: number, + storage: VillageStorage, + taskCollection: VillageTaskCollection, + state: VillageState + ) { this.villageId = villageId; + this.storage = storage; this.taskCollection = taskCollection; this.state = state; } @@ -21,6 +30,10 @@ export class VillageController { return this.villageId; } + getState(): VillageState { + return this.state; + } + getReadyProductionTask(): Task | undefined { return this.taskCollection.getReadyForProductionTask(); } @@ -37,7 +50,22 @@ export class VillageController { this.taskCollection.postponeTask(taskId, seconds); } - getAvailableForSendResources(): Resources { + getMerchantsInfo(): MerchantsInfo { + return this.storage.getMerchantsInfo(); + } + + getSendResourcesMultiplier(): number { + return this.state.settings.sendResourcesMultiplier; + } + + getOverflowResources(): Resources { + const limit = this.state.storageOptimumFullness; + const currentResources = this.state.resources; + + return currentResources.sub(limit).max(Resources.zero()); + } + + getFreeResources(): Resources { const balance = this.state.required.balance; const free = balance.max(Resources.zero()); @@ -57,11 +85,11 @@ export class VillageController { } getRequiredResources(): Resources { - const performance = this.state.performance; - const maxPossibleToStore = this.state.storage.capacity.sub(performance); + const maxPossibleToStore = this.state.storageOptimumFullness; const currentResources = this.state.resources; const incomingResources = this.state.incomingResources; const requirementResources = this.state.required.resources; + const missingResources = requirementResources .min(maxPossibleToStore) .sub(incomingResources) @@ -78,4 +106,11 @@ export class VillageController { return missingResources; } + + getAvailableToReceiveResources(): Resources { + const maxPossibleToStore = this.state.storageOptimumFullness; + const currentResources = this.state.resources; + + return maxPossibleToStore.sub(currentResources).max(Resources.zero()); + } } diff --git a/src/VillageFactory.ts b/src/VillageFactory.ts index 9690482..efb1b4b 100644 --- a/src/VillageFactory.ts +++ b/src/VillageFactory.ts @@ -63,6 +63,7 @@ export class VillageFactory { const village = this.villageRepository.get(villageId); return new VillageController( village.id, + this.createStorage(village.id), this.createTaskCollection(village.id), this.createState(village.id) ); diff --git a/src/VillageState.ts b/src/VillageState.ts index ac16cb4..45e7942 100644 --- a/src/VillageState.ts +++ b/src/VillageState.ts @@ -67,6 +67,7 @@ interface VillageOwnState { storage: VillageStorageState; upperCriticalLevel: Resources; storageOptimumFullness: Resources; + isOverflowing: boolean; /** * Required resources for nearest task */ @@ -197,8 +198,9 @@ function createVillageOwnState( const resources = storage.getResources(); const resourceStorage = storage.getResourceStorage(); const performance = storage.getResourcesPerformance(); - const upperCriticalLevel = Resources.fromStorage(resourceStorage).sub(performance.scale(2)); - const storageOptimumFullness = Resources.fromStorage(resourceStorage).sub(performance.scale(3)); + const upperCriticalLevel = Resources.fromStorage(resourceStorage).sub(performance.scale(1)); + const storageOptimumFullness = Resources.fromStorage(resourceStorage).sub(performance.scale(2)); + const isOverflowing = upperCriticalLevel.anyLower(resources); const requiredResources = taskCollection.getReadyTaskRequiredResources(); const frontierResources = taskCollection.getFrontierResources(); const totalRequiredResources = taskCollection.getAllTasksRequiredResources(); @@ -212,6 +214,7 @@ function createVillageOwnState( required: calcResourceBalance(requiredResources, resources, performance), upperCriticalLevel, storageOptimumFullness, + isOverflowing, frontierRequired: calcResourceBalance(frontierResources, resources, performance), totalRequired: calcResourceBalance(totalRequiredResources, resources, performance), incomingResources: calcIncomingResources(storage),