Move Resources to Core module
This commit is contained in:
		| @@ -6,7 +6,7 @@ import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage'; | ||||
| import { HeroAllResources } from '../Game'; | ||||
| import { grabActiveVillageId } from '../Page/VillageBlock'; | ||||
| import { HeroState } from '../State/HeroState'; | ||||
| import { Core } from '../Core/HeroBalance'; | ||||
| import { calcHeroResource } from '../Core/HeroBalance'; | ||||
|  | ||||
| @registerAction | ||||
| export class BalanceHeroResourcesAction extends ActionController { | ||||
| @@ -25,7 +25,7 @@ export class BalanceHeroResourcesAction extends ActionController { | ||||
|         const storage = grabResourceStorage(); | ||||
|         const currentType = grabCurrentHeroResource(); | ||||
|  | ||||
|         const heroType = Core.calcHeroResource(resources, requiredResources, totalRequiredResources, storage); | ||||
|         const heroType = calcHeroResource(resources, requiredResources, totalRequiredResources, storage); | ||||
|  | ||||
|         if (heroType !== currentType) { | ||||
|             changeHeroResource(heroType); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { ResourcesInterface } from './Game'; | ||||
| import { TaskId } from './Queue/TaskQueue'; | ||||
| import { ResourcesInterface } from './Core/Resources'; | ||||
|  | ||||
| export interface Args { | ||||
|     taskId?: TaskId; | ||||
|   | ||||
| @@ -14,7 +14,8 @@ import DashboardApp from './DashboardView/Dashboard.vue'; | ||||
| import { ResourcesToLevel } from './Task/ResourcesToLevel'; | ||||
| import { ConsoleLogger, Logger } from './Logger'; | ||||
| import { VillageState } from './State/VillageState'; | ||||
| import { Resources, Village } from './Game'; | ||||
| import { Village } from './Game'; | ||||
| import { Resources } from './Core/Resources'; | ||||
|  | ||||
| interface QuickAction { | ||||
|     label: string; | ||||
|   | ||||
| @@ -1,39 +1,38 @@ | ||||
| import { HeroAllResources, HeroResourceType, Resources, ResourceStorage } from '../Game'; | ||||
| import { Resources } from './Resources'; | ||||
| import { HeroAllResources, HeroResourceType, ResourceStorage } from '../Game'; | ||||
|  | ||||
| export namespace Core { | ||||
|     export function calcHeroResource( | ||||
|         current: Resources, | ||||
|         required: Resources, | ||||
|         totalRequired: Resources, | ||||
|         storage: ResourceStorage | ||||
|     ): HeroResourceType { | ||||
|         const resourceDiff = calcNeedResources(current, required, totalRequired, storage); | ||||
|         const resourcesAsList = resourceDiff.asList(); | ||||
| export function calcHeroResource( | ||||
|     current: Resources, | ||||
|     required: Resources, | ||||
|     totalRequired: Resources, | ||||
|     storage: ResourceStorage | ||||
| ): HeroResourceType { | ||||
|     const resourceDiff = calcNeedResources(current, required, totalRequired, storage); | ||||
|     const resourcesAsList = resourceDiff.asList(); | ||||
|  | ||||
|         const sorted = resourcesAsList.sort((x, y) => y.value - x.value); | ||||
|     const sorted = resourcesAsList.sort((x, y) => y.value - x.value); | ||||
|  | ||||
|         const maxRequirement = sorted[0]; | ||||
|         const minRequirement = sorted[sorted.length - 1]; | ||||
|         const delta = maxRequirement.value - minRequirement.value; | ||||
|         const eps = maxRequirement.value / 10; | ||||
|     const maxRequirement = sorted[0]; | ||||
|     const minRequirement = sorted[sorted.length - 1]; | ||||
|     const delta = maxRequirement.value - minRequirement.value; | ||||
|     const eps = maxRequirement.value / 10; | ||||
|  | ||||
|         return delta > eps ? maxRequirement.type : HeroAllResources; | ||||
|     } | ||||
|  | ||||
|     function calcNeedResources( | ||||
|         current: Resources, | ||||
|         required: Resources, | ||||
|         totalRequired: Resources, | ||||
|         storage: ResourceStorage | ||||
|     ): Resources { | ||||
|         if (!current.gt(required)) { | ||||
|             return required.sub(current); | ||||
|         } | ||||
|  | ||||
|         if (!current.gt(totalRequired)) { | ||||
|             return totalRequired.sub(current); | ||||
|         } | ||||
|  | ||||
|         return Resources.fromStorage(storage).sub(current); | ||||
|     } | ||||
|     return delta > eps ? maxRequirement.type : HeroAllResources; | ||||
| } | ||||
|  | ||||
| function calcNeedResources( | ||||
|     current: Resources, | ||||
|     required: Resources, | ||||
|     totalRequired: Resources, | ||||
|     storage: ResourceStorage | ||||
| ): Resources { | ||||
|     if (!current.gt(required)) { | ||||
|         return required.sub(current); | ||||
|     } | ||||
|  | ||||
|     if (!current.gt(totalRequired)) { | ||||
|         return totalRequired.sub(current); | ||||
|     } | ||||
|  | ||||
|     return Resources.fromStorage(storage).sub(current); | ||||
| } | ||||
|   | ||||
							
								
								
									
										24
									
								
								src/Core/ResourceType.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/Core/ResourceType.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| export enum ResourceType { | ||||
|     Lumber = 1, | ||||
|     Clay = 2, | ||||
|     Iron = 3, | ||||
|     Crop = 4, | ||||
| } | ||||
|  | ||||
| export const ResourceMapping: ReadonlyArray<{ num: number; type: ResourceType }> = [ | ||||
|     { num: 1, type: ResourceType.Lumber }, | ||||
|     { num: 2, type: ResourceType.Clay }, | ||||
|     { num: 3, type: ResourceType.Iron }, | ||||
|     { num: 4, type: ResourceType.Crop }, | ||||
| ]; | ||||
|  | ||||
| export function numberToResourceType(typeAsNumber: number): ResourceType { | ||||
|     for (let mp of ResourceMapping) { | ||||
|         if (typeAsNumber === mp.num) { | ||||
|             return mp.type; | ||||
|         } | ||||
|     } | ||||
|     throw new Error(`Type ${typeAsNumber} in not valid`); | ||||
| } | ||||
|  | ||||
| export type ResourceList = Array<{ num: number; type: ResourceType; value: number }>; | ||||
							
								
								
									
										90
									
								
								src/Core/Resources.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/Core/Resources.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| import { ResourceStorage } from '../Game'; | ||||
| import { ResourceList, ResourceMapping, ResourceType } from './ResourceType'; | ||||
|  | ||||
| export interface ResourcesInterface { | ||||
|     lumber: number; | ||||
|     clay: number; | ||||
|     iron: number; | ||||
|     crop: number; | ||||
| } | ||||
|  | ||||
| export class Resources implements ResourcesInterface { | ||||
|     readonly lumber: number; | ||||
|     readonly clay: number; | ||||
|     readonly iron: number; | ||||
|     readonly crop: number; | ||||
|  | ||||
|     constructor(lumber: number, clay: number, iron: number, crop: number) { | ||||
|         this.lumber = Math.floor(lumber); | ||||
|         this.clay = Math.floor(clay); | ||||
|         this.iron = Math.floor(iron); | ||||
|         this.crop = Math.floor(crop); | ||||
|     } | ||||
|  | ||||
|     static fromObject(obj: ResourcesInterface): Resources { | ||||
|         return new Resources(obj.lumber, obj.clay, obj.iron, obj.crop); | ||||
|     } | ||||
|  | ||||
|     static fromStorage(storage: ResourceStorage): Resources { | ||||
|         return new Resources(storage.warehouse, storage.warehouse, storage.warehouse, storage.granary); | ||||
|     } | ||||
|  | ||||
|     getByType(type: ResourceType): number { | ||||
|         switch (type) { | ||||
|             case ResourceType.Lumber: | ||||
|                 return this.lumber; | ||||
|             case ResourceType.Clay: | ||||
|                 return this.clay; | ||||
|             case ResourceType.Iron: | ||||
|                 return this.iron; | ||||
|             case ResourceType.Crop: | ||||
|                 return this.crop; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     asList(): ResourceList { | ||||
|         const result: ResourceList = []; | ||||
|         for (let mp of ResourceMapping) { | ||||
|             result.push({ num: mp.num, type: mp.type, value: this.getByType(mp.type) }); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     scale(n: number): Resources { | ||||
|         return new Resources(this.lumber * n, this.clay * n, this.iron * n, this.crop * n); | ||||
|     } | ||||
|  | ||||
|     add(other: ResourcesInterface): Resources { | ||||
|         return new Resources( | ||||
|             this.lumber + other.lumber, | ||||
|             this.clay + other.clay, | ||||
|             this.iron + other.iron, | ||||
|             this.crop + other.crop | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     sub(other: ResourcesInterface): Resources { | ||||
|         return new Resources( | ||||
|             this.lumber - other.lumber, | ||||
|             this.clay - other.clay, | ||||
|             this.iron - other.iron, | ||||
|             this.crop - other.crop | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     lt(other: Resources): boolean { | ||||
|         return this.lumber < other.lumber && this.clay < other.clay && this.iron < other.iron && this.crop < other.crop; | ||||
|     } | ||||
|  | ||||
|     gt(other: Resources): boolean { | ||||
|         return this.lumber > other.lumber && this.clay > other.clay && this.iron > other.iron && this.crop > other.crop; | ||||
|     } | ||||
|  | ||||
|     lte(other: Resources): boolean { | ||||
|         return !this.gt(other); | ||||
|     } | ||||
|  | ||||
|     gte(other: Resources): boolean { | ||||
|         return !this.lt(other); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										113
									
								
								src/Game.ts
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								src/Game.ts
									
									
									
									
									
								
							| @@ -1,115 +1,4 @@ | ||||
| export enum ResourceType { | ||||
|     Lumber = 1, | ||||
|     Clay = 2, | ||||
|     Iron = 3, | ||||
|     Crop = 4, | ||||
| } | ||||
|  | ||||
| export const ResourceMapping: ReadonlyArray<{ num: number; type: ResourceType }> = [ | ||||
|     { num: 1, type: ResourceType.Lumber }, | ||||
|     { num: 2, type: ResourceType.Clay }, | ||||
|     { num: 3, type: ResourceType.Iron }, | ||||
|     { num: 4, type: ResourceType.Crop }, | ||||
| ]; | ||||
|  | ||||
| export function numberToResourceType(typeAsNumber: number): ResourceType { | ||||
|     for (let mp of ResourceMapping) { | ||||
|         if (typeAsNumber === mp.num) { | ||||
|             return mp.type; | ||||
|         } | ||||
|     } | ||||
|     throw new Error(`Type ${typeAsNumber} in not valid`); | ||||
| } | ||||
|  | ||||
| export type ResourceList = Array<{ num: number; type: ResourceType; value: number }>; | ||||
|  | ||||
| export interface ResourcesInterface { | ||||
|     lumber: number; | ||||
|     clay: number; | ||||
|     iron: number; | ||||
|     crop: number; | ||||
| } | ||||
|  | ||||
| export class Resources implements ResourcesInterface { | ||||
|     readonly lumber: number; | ||||
|     readonly clay: number; | ||||
|     readonly iron: number; | ||||
|     readonly crop: number; | ||||
|  | ||||
|     constructor(lumber: number, clay: number, iron: number, crop: number) { | ||||
|         this.lumber = Math.floor(lumber); | ||||
|         this.clay = Math.floor(clay); | ||||
|         this.iron = Math.floor(iron); | ||||
|         this.crop = Math.floor(crop); | ||||
|     } | ||||
|  | ||||
|     static fromObject(obj: ResourcesInterface): Resources { | ||||
|         return new Resources(obj.lumber, obj.clay, obj.iron, obj.crop); | ||||
|     } | ||||
|  | ||||
|     static fromStorage(storage: ResourceStorage): Resources { | ||||
|         return new Resources(storage.warehouse, storage.warehouse, storage.warehouse, storage.granary); | ||||
|     } | ||||
|  | ||||
|     getByType(type: ResourceType): number { | ||||
|         switch (type) { | ||||
|             case ResourceType.Lumber: | ||||
|                 return this.lumber; | ||||
|             case ResourceType.Clay: | ||||
|                 return this.clay; | ||||
|             case ResourceType.Iron: | ||||
|                 return this.iron; | ||||
|             case ResourceType.Crop: | ||||
|                 return this.crop; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     asList(): ResourceList { | ||||
|         const result: ResourceList = []; | ||||
|         for (let mp of ResourceMapping) { | ||||
|             result.push({ num: mp.num, type: mp.type, value: this.getByType(mp.type) }); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     scale(n: number): Resources { | ||||
|         return new Resources(this.lumber * n, this.clay * n, this.iron * n, this.crop * n); | ||||
|     } | ||||
|  | ||||
|     add(other: ResourcesInterface): Resources { | ||||
|         return new Resources( | ||||
|             this.lumber + other.lumber, | ||||
|             this.clay + other.clay, | ||||
|             this.iron + other.iron, | ||||
|             this.crop + other.crop | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     sub(other: ResourcesInterface): Resources { | ||||
|         return new Resources( | ||||
|             this.lumber - other.lumber, | ||||
|             this.clay - other.clay, | ||||
|             this.iron - other.iron, | ||||
|             this.crop - other.crop | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     lt(other: Resources): boolean { | ||||
|         return this.lumber < other.lumber && this.clay < other.clay && this.iron < other.iron && this.crop < other.crop; | ||||
|     } | ||||
|  | ||||
|     gt(other: Resources): boolean { | ||||
|         return this.lumber > other.lumber && this.clay > other.clay && this.iron > other.iron && this.crop > other.crop; | ||||
|     } | ||||
|  | ||||
|     lte(other: Resources): boolean { | ||||
|         return !this.gt(other); | ||||
|     } | ||||
|  | ||||
|     gte(other: Resources): boolean { | ||||
|         return !this.lt(other); | ||||
|     } | ||||
| } | ||||
| import { ResourceType } from './Core/ResourceType'; | ||||
|  | ||||
| export class ResourceStorage { | ||||
|     readonly warehouse: number; | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| import { GrabError } from '../Errors'; | ||||
| import { elClassId, getNumber, split, trimPrefix, uniqId } from '../utils'; | ||||
| import { Resources } from '../Game'; | ||||
| import { grabActiveVillageId } from './VillageBlock'; | ||||
| import { TrainTroopTask } from '../Task/TrainTroopTask'; | ||||
| import { elClassId, getNumber, trimPrefix, uniqId } from '../utils'; | ||||
| import { Resources } from '../Core/Resources'; | ||||
|  | ||||
| export function clickBuildButton(typeId: number) { | ||||
|     const section = jQuery(`#contract_building${typeId}`); | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import { grabActiveVillageId } from './VillageBlock'; | ||||
| import { ConsoleLogger } from '../Logger'; | ||||
| import { createBuildButton, createTrainTroopButtons, createUpgradeButton } from './BuildingPage'; | ||||
| import { BuildBuildingTask } from '../Task/BuildBuildingTask'; | ||||
| import { Resources } from '../Game'; | ||||
| import { Resources } from '../Core/Resources'; | ||||
|  | ||||
| const QUARTERS_ID = 19; | ||||
| const HORSE_STABLE_ID = 20; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { ActionError, GrabError } from '../Errors'; | ||||
| import { HeroAllResources, HeroAttributes, HeroResourceType, ResourceMapping, ResourceType } from '../Game'; | ||||
| import { GrabError } from '../Errors'; | ||||
| import { HeroAllResources, HeroAttributes, HeroResourceType } from '../Game'; | ||||
| import { getNumber } from '../utils'; | ||||
| import { ResourceMapping, ResourceType } from '../Core/ResourceType'; | ||||
|  | ||||
| export function grabHeroAttributes(): HeroAttributes { | ||||
|     const healthElement = jQuery('#attributes .attribute.health .powervalue .value'); | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import { Resources, ResourceStorage, ResourceType } from '../Game'; | ||||
| import { ResourceStorage } from '../Game'; | ||||
| import { GrabError } from '../Errors'; | ||||
| import { getNumber } from '../utils'; | ||||
| import { Resources } from '../Core/Resources'; | ||||
| import { ResourceType } from '../Core/ResourceType'; | ||||
|  | ||||
| export function grabResources(): Resources { | ||||
|     const lumber = grabResource(ResourceType.Lumber); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { elClassId, getNumber } from '../utils'; | ||||
| import { numberToResourceType, ResourceDeposit } from '../Game'; | ||||
| import { ResourceDeposit } from '../Game'; | ||||
| import { numberToResourceType } from '../Core/ResourceType'; | ||||
|  | ||||
| interface Slot { | ||||
|     el: HTMLElement; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { BuildingQueueInfo, Coordinates, Resources, Village, VillageList } from '../Game'; | ||||
| import { BuildingQueueInfo, Coordinates, Village, VillageList } from '../Game'; | ||||
| import { GrabError } from '../Errors'; | ||||
| import { getNumber, parseLocation } from '../utils'; | ||||
| import { Resources } from '../Core/Resources'; | ||||
|  | ||||
| function getVillageListItems() { | ||||
|     const $elements = jQuery('#sidebarBoxVillagelist ul li a'); | ||||
|   | ||||
| @@ -8,9 +8,9 @@ import { ConsoleLogger, Logger } from './Logger'; | ||||
| import { BuildBuildingTask } from './Task/BuildBuildingTask'; | ||||
| import { GrabVillageState } from './Task/GrabVillageState'; | ||||
| import { ActionQueue, ImmutableActionList } from './Queue/ActionQueue'; | ||||
| import { Resources, ResourcesInterface } from './Game'; | ||||
| import { UpdateResourceContracts } from './Task/UpdateResourceContracts'; | ||||
| import { TrainTroopTask } from './Task/TrainTroopTask'; | ||||
| import { Resources, ResourcesInterface } from './Core/Resources'; | ||||
|  | ||||
| export class Scheduler { | ||||
|     private taskQueue: TaskQueue; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { DataStorage } from '../DataStorage'; | ||||
| import { BuildingQueueInfo, Resources, ResourceStorage } from '../Game'; | ||||
| import { BuildingQueueInfo, ResourceStorage } from '../Game'; | ||||
| import { Resources } from '../Core/Resources'; | ||||
|  | ||||
| const RESOURCES_KEY = 'res'; | ||||
| const CAPACITY_KEY = 'cap'; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user