Add sending overflow resources
This commit is contained in:
		@@ -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();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['value', 'max', 'speed'],
 | 
			
		||||
  props: ['value', 'warning', 'critical', 'full'],
 | 
			
		||||
  data() {
 | 
			
		||||
    return {};
 | 
			
		||||
  },
 | 
			
		||||
@@ -13,31 +13,18 @@ export default {
 | 
			
		||||
      return this.value;
 | 
			
		||||
    },
 | 
			
		||||
    percent() {
 | 
			
		||||
      return Math.floor((this.value / this.max) * 100);
 | 
			
		||||
      return Math.floor((this.value / this.full) * 100);
 | 
			
		||||
    },
 | 
			
		||||
    title() {
 | 
			
		||||
      if (this.speed < 0) {
 | 
			
		||||
        const time = this.fractionalHourToTime(this.value / this.speed);
 | 
			
		||||
        return `${this.value}, ${this.percent}%, опустеет через ${time}`;
 | 
			
		||||
      } else {
 | 
			
		||||
        const time = this.fractionalHourToTime((this.max - this.value) / this.speed);
 | 
			
		||||
        return `${this.value}, ${this.percent}%, заполнится через ${time}`;
 | 
			
		||||
      }
 | 
			
		||||
      return `${this.value}/${this.full}, ${this.percent}%`;
 | 
			
		||||
    },
 | 
			
		||||
    classes() {
 | 
			
		||||
      return {
 | 
			
		||||
        warning: this.percent >= 70 && this.percent < 95,
 | 
			
		||||
        bad: this.percent >= 95,
 | 
			
		||||
        warning: this.value >= this.warning && this.value < this.critical,
 | 
			
		||||
        bad: this.value >= this.critical,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    fractionalHourToTime(value) {
 | 
			
		||||
      const hours = Math.floor(value);
 | 
			
		||||
      const minutes = Math.round((value - hours) * 60);
 | 
			
		||||
      return `${hours}:${String(minutes).padStart(2, '0')}`;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,52 +30,40 @@
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <filling
 | 
			
		||||
                :value="villageState.resources.lumber"
 | 
			
		||||
                :max="villageState.storage.capacity.lumber"
 | 
			
		||||
                :speed="villageState.performance.lumber"
 | 
			
		||||
                :warning="villageState.storageOptimumFullness.lumber"
 | 
			
		||||
                :critical="villageState.upperCriticalLevel.lumber"
 | 
			
		||||
                :full="villageState.storage.capacity.lumber"
 | 
			
		||||
              ></filling>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <filling
 | 
			
		||||
                :value="villageState.resources.clay"
 | 
			
		||||
                :max="villageState.storage.capacity.clay"
 | 
			
		||||
                :speed="villageState.performance.clay"
 | 
			
		||||
                :warning="villageState.storageOptimumFullness.clay"
 | 
			
		||||
                :critical="villageState.upperCriticalLevel.clay"
 | 
			
		||||
                :full="villageState.storage.capacity.clay"
 | 
			
		||||
              ></filling>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <filling
 | 
			
		||||
                :value="villageState.resources.iron"
 | 
			
		||||
                :max="villageState.storage.capacity.iron"
 | 
			
		||||
                :speed="villageState.performance.iron"
 | 
			
		||||
                :warning="villageState.storageOptimumFullness.iron"
 | 
			
		||||
                :critical="villageState.upperCriticalLevel.iron"
 | 
			
		||||
                :full="villageState.storage.capacity.iron"
 | 
			
		||||
              ></filling>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <filling
 | 
			
		||||
                :value="villageState.resources.crop"
 | 
			
		||||
                :max="villageState.storage.capacity.crop"
 | 
			
		||||
                :speed="villageState.performance.crop"
 | 
			
		||||
                :warning="villageState.storageOptimumFullness.crop"
 | 
			
		||||
                :critical="villageState.upperCriticalLevel.crop"
 | 
			
		||||
                :full="villageState.storage.capacity.crop"
 | 
			
		||||
              ></filling>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right" v-text="storageTime(villageState)"></td>
 | 
			
		||||
            <td></td>
 | 
			
		||||
          </tr>
 | 
			
		||||
 | 
			
		||||
          <tr class="performance-line">
 | 
			
		||||
            <td class="right">Прирост:</td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource :value="villageState.performance.lumber"></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource :value="villageState.performance.clay"></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource :value="villageState.performance.iron"></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource :value="villageState.performance.crop"></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td></td>
 | 
			
		||||
            <td></td>
 | 
			
		||||
          </tr>
 | 
			
		||||
          <resource-line :title="'Прирост:'" :resources="villageState.performance" />
 | 
			
		||||
 | 
			
		||||
          <resource-line
 | 
			
		||||
            v-if="isExtended(villageState.id)"
 | 
			
		||||
@@ -84,43 +72,11 @@
 | 
			
		||||
            :resources="villageState.upperCriticalLevel"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <tr class="required-line" v-if="villageState.required.active">
 | 
			
		||||
            <td class="right">След. задача:</td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource
 | 
			
		||||
                :value="villageState.required.resources.lumber"
 | 
			
		||||
                :hide-zero="true"
 | 
			
		||||
                :color="false"
 | 
			
		||||
                :sign="false"
 | 
			
		||||
              ></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource
 | 
			
		||||
                :value="villageState.required.resources.clay"
 | 
			
		||||
                :hide-zero="true"
 | 
			
		||||
                :color="false"
 | 
			
		||||
                :sign="false"
 | 
			
		||||
              ></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource
 | 
			
		||||
                :value="villageState.required.resources.iron"
 | 
			
		||||
                :hide-zero="true"
 | 
			
		||||
                :color="false"
 | 
			
		||||
                :sign="false"
 | 
			
		||||
              ></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td class="right">
 | 
			
		||||
              <resource
 | 
			
		||||
                :value="villageState.required.resources.crop"
 | 
			
		||||
                :hide-zero="true"
 | 
			
		||||
                :color="false"
 | 
			
		||||
                :sign="false"
 | 
			
		||||
              ></resource>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td></td>
 | 
			
		||||
            <td></td>
 | 
			
		||||
          </tr>
 | 
			
		||||
          <resource-line
 | 
			
		||||
            v-if="villageState.required.active"
 | 
			
		||||
            :title="'След. задача:'"
 | 
			
		||||
            :resources="villageState.required.resources"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <resource-line
 | 
			
		||||
            v-if="villageState.required.active"
 | 
			
		||||
@@ -169,6 +125,8 @@
 | 
			
		||||
            :title="'Крит. уровень:'"
 | 
			
		||||
            :hint="'Критический уровень'"
 | 
			
		||||
            :hide-zero="true"
 | 
			
		||||
            :color="false"
 | 
			
		||||
            :sign="false"
 | 
			
		||||
            :resources="villageState.upperCriticalLevel"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
@@ -177,6 +135,8 @@
 | 
			
		||||
            :title="'Опт. уровень:'"
 | 
			
		||||
            :hint="'Оптимальный уровень'"
 | 
			
		||||
            :hide-zero="true"
 | 
			
		||||
            :color="false"
 | 
			
		||||
            :sign="false"
 | 
			
		||||
            :resources="villageState.storageOptimumFullness"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
@@ -192,6 +152,11 @@
 | 
			
		||||
                "
 | 
			
		||||
                >$->{{ s.village.name }}</a
 | 
			
		||||
              >
 | 
			
		||||
            </td>
 | 
			
		||||
          </tr>
 | 
			
		||||
 | 
			
		||||
          <tr class="normal-line">
 | 
			
		||||
            <td class="right" colspan="7">
 | 
			
		||||
              <a class="village-quick-link" :href="quartersPath(villageState.village)">Казармы</a>
 | 
			
		||||
              <a class="village-quick-link" :href="horseStablePath(villageState.village)"
 | 
			
		||||
                >Конюшни</a
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,16 @@
 | 
			
		||||
  <tr class="resource-line">
 | 
			
		||||
    <td class="title" v-text="title" :title="hint"></td>
 | 
			
		||||
    <td class="lumber">
 | 
			
		||||
      <resource :value="resources.lumber" :hide-zero="hideZero" />
 | 
			
		||||
      <resource :value="resources.lumber" :hide-zero="hideZero" :color="color" :sign="sign" />
 | 
			
		||||
    </td>
 | 
			
		||||
    <td class="clay">
 | 
			
		||||
      <resource :value="resources.clay" :hide-zero="hideZero" />
 | 
			
		||||
      <resource :value="resources.clay" :hide-zero="hideZero" :color="color" :sign="sign" />
 | 
			
		||||
    </td>
 | 
			
		||||
    <td class="iron">
 | 
			
		||||
      <resource :value="resources.iron" :hide-zero="hideZero" />
 | 
			
		||||
      <resource :value="resources.iron" :hide-zero="hideZero" :color="color" :sign="sign" />
 | 
			
		||||
    </td>
 | 
			
		||||
    <td class="crop">
 | 
			
		||||
      <resource :value="resources.crop" :hide-zero="hideZero" />
 | 
			
		||||
      <resource :value="resources.crop" :hide-zero="hideZero" :color="color" :sign="sign" />
 | 
			
		||||
    </td>
 | 
			
		||||
    <td class="time1" v-text="time1"></td>
 | 
			
		||||
    <td class="time2" v-text="time2"></td>
 | 
			
		||||
@@ -48,6 +48,14 @@ export default {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false,
 | 
			
		||||
    },
 | 
			
		||||
    color: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: true,
 | 
			
		||||
    },
 | 
			
		||||
    sign: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -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()];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,10 @@ export class ResourceTransferStorage {
 | 
			
		||||
                    iron: 0,
 | 
			
		||||
                    crop: 0,
 | 
			
		||||
                },
 | 
			
		||||
                score: 0,
 | 
			
		||||
                score: {
 | 
			
		||||
                    amount: 0,
 | 
			
		||||
                    overflow: false,
 | 
			
		||||
                },
 | 
			
		||||
            }),
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
        );
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user