Add optimum storage fill strategy

This commit is contained in:
Anton Vakhrushev 2020-06-07 12:12:24 +03:00
parent 9acc1d32fa
commit 11b93526cd
6 changed files with 105 additions and 21 deletions

View File

@ -35,14 +35,21 @@ export class Village {
}
}
export enum ReceiveResourcesMode {
Required = 'required',
Optimum = 'optimum',
}
export type VillageList = Array<Village>;
export interface VillageSettings {
sendResourcesThreshold: number;
sendResourcesMultiplier: number;
receiveResourcesMode: ReceiveResourcesMode;
}
export const VillageSettingsDefaults: VillageSettings = {
sendResourcesThreshold: 100,
sendResourcesMultiplier: 10,
receiveResourcesMode: ReceiveResourcesMode.Required,
} as const;

View File

@ -1,6 +1,6 @@
import Vuex from 'vuex';
import { LogStorage } from '../Storage/LogStorage';
import { VillageSettings, VillageSettingsDefaults } from '../Core/Village';
import { ReceiveResourcesMode, VillageSettings, VillageSettingsDefaults } from '../Core/Village';
import { getNumber, notify } from '../utils';
import { VillageStorage } from '../Storage/VillageStorage';
import { VillageFactory } from '../VillageFactory';
@ -13,13 +13,13 @@ export enum Mutations {
ToggleVillageEditor = 'toggle_village_editor',
SetVillageSettings = 'set_village_settings',
UpdateVillageSendResourceThreshold = 'UpdateVillageSendResourceThreshold',
UpdateVillageSendResourceTimeout = 'UpdateVillageSendResourceTimeout',
UpdateVillageSendResourcesMultiplier = 'UpdateVillageSendResourcesMultiplier',
}
export enum Actions {
OpenVillageEditor = 'open_village_editor',
SaveVillageSettings = 'save_village_settings',
ToggleVillageReceiveMode = 'toggle_village_receive_mode',
}
export function createStore(villageFactory: VillageFactory) {
@ -83,8 +83,9 @@ export function createStore(villageFactory: VillageFactory) {
commit(Mutations.ToggleVillageEditor, true);
},
[Actions.SaveVillageSettings]({ state }) {
const villageId = state.villageSettings.villageId;
const villageName = state.villageSettings.villageName;
const villageId = state.villageSettings.villageId;
const villageState = villageFactory.createState(villageId);
const newSettings: VillageSettings = {
sendResourcesThreshold:
state.villageSettings.sendResourcesThreshold ||
@ -92,11 +93,16 @@ export function createStore(villageFactory: VillageFactory) {
sendResourcesMultiplier:
state.villageSettings.sendResourcesMultiplier ||
VillageSettingsDefaults.sendResourcesMultiplier,
receiveResourcesMode: villageState.settings.receiveResourcesMode,
};
const storage = new VillageStorage(villageId);
storage.storeSettings(newSettings);
notify(`Настройки для ${villageName} сохранены`);
},
[Actions.ToggleVillageReceiveMode]({}, { villageId }) {
const controller = villageFactory.createController(villageId);
controller.toggleReceiveResourcesMode();
},
},
});

View File

@ -143,9 +143,7 @@
</td>
</tr>
<tr class="normal-line">
<td class="right" colspan="7" v-text="villageStatus(villageState)"></td>
</tr>
<status-line :village-state="villageState" />
</template>
</tbody>
</table>
@ -160,6 +158,7 @@ import { path } from '../Helpers/Path';
import { Actions } from './Store';
import { translateProductionQueue } from '../Core/ProductionQueue';
import VillageStateResourceLine from './VillageStateResourceLine';
import VillageStateStatusLine from './VillageStateStatusLine';
function secondsToTime(value) {
if (value === 0) {
@ -176,6 +175,7 @@ export default {
'resource': ResourceBalance,
'filling': VillageResource,
'resource-line': VillageStateResourceLine,
'status-line': VillageStateStatusLine,
},
data() {
return {
@ -189,11 +189,6 @@ export default {
const name = villageState.village.name;
return `${name}, ${id}`;
},
villageStatus(villageState) {
const threshold = villageState.settings.sendResourcesThreshold;
const multiplier = villageState.settings.sendResourcesMultiplier;
return `порог ${threshold}, множ. ${multiplier}`;
},
path(name, args) {
return path(name, args);
},

View File

@ -0,0 +1,51 @@
<template>
<tr>
<td class="status-line" colspan="7">
режим
<a href="#" v-text="settings.receiveResourcesMode" v-on:click.prevent="toggleMode()"></a>,
<span v-text="status"></span>
</td>
</tr>
</template>
<script>
import { Actions } from './Store';
export default {
props: {
villageState: {
type: Object,
},
},
computed: {
settings() {
return this.villageState.settings;
},
status() {
const settings = this.villageState.settings;
const threshold = settings.sendResourcesThreshold;
const multiplier = settings.sendResourcesMultiplier;
return `порог ${threshold}, множ. ${multiplier}`;
},
},
methods: {
toggleMode() {
const villageId = this.villageState.id;
this.$store.dispatch(Actions.ToggleVillageReceiveMode, { villageId });
},
},
};
</script>
<style scoped lang="scss">
%right {
text-align: right;
}
%small-cell {
padding: 0 4px 4px;
font-size: 90%;
}
.status-line {
@extend %right;
}
</style>

View File

@ -3,10 +3,9 @@ import { Task, TaskId } from './Queue/TaskProvider';
import { Args } from './Queue/Args';
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';
import { ReceiveResourcesMode } from './Core/Village';
export class VillageController {
private readonly villageId: number;
@ -85,19 +84,32 @@ export class VillageController {
}
getRequiredResources(): Resources {
const maxPossibleToStore = this.state.storageOptimumFullness;
const mode = this.state.settings.receiveResourcesMode;
const optimumToStoreResources = this.state.storageOptimumFullness;
const currentResources = this.state.resources;
const incomingResources = this.state.incomingResources;
const requirementResources = this.state.required.resources;
const missingResources = requirementResources
.min(maxPossibleToStore)
let missingResources;
switch (mode) {
case ReceiveResourcesMode.Required:
missingResources = requirementResources
.min(optimumToStoreResources)
.sub(incomingResources)
.sub(currentResources)
.max(Resources.zero());
break;
case ReceiveResourcesMode.Optimum:
missingResources = optimumToStoreResources
.sub(incomingResources)
.sub(currentResources)
.max(Resources.zero());
break;
}
console.table([
{ name: 'Recipient max possible', ...maxPossibleToStore },
{ name: 'Recipient max possible', ...optimumToStoreResources },
{ name: 'Recipient resources', ...currentResources },
{ name: 'Recipient incoming', ...incomingResources },
{ name: 'Recipient requirements', ...requirementResources },
@ -113,4 +125,16 @@ export class VillageController {
return maxPossibleToStore.sub(currentResources).max(Resources.zero());
}
toggleReceiveResourcesMode(): void {
const current = this.state.settings.receiveResourcesMode;
let next;
if (current === ReceiveResourcesMode.Required) {
next = ReceiveResourcesMode.Optimum;
} else {
next = ReceiveResourcesMode.Required;
}
const newSettings = { ...this.state.settings, receiveResourcesMode: next };
this.storage.storeSettings(newSettings);
}
}

View File

@ -230,6 +230,7 @@ function createVillageOwnState(
storage: VillageStorage,
taskCollection: VillageTaskCollection
): VillageOwnState {
const settings = storage.getSettings();
const resources = storage.getResources();
const storageResources = Resources.fromStorage(storage.getResourceStorage());
const performance = storage.getResourcesPerformance();
@ -257,7 +258,7 @@ function createVillageOwnState(
frontierRequired: makeResourceBalance(frontierResources, resources, performance),
totalRequired: makeResourceBalance(totalRequiredResources, resources, performance),
incomingResources: calcIncomingResources(storage),
settings: storage.getSettings(),
settings,
};
}