Store incoming merchants
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| import { elClassId, getNumber, parseLocation, uniqId, waitForLoad } from './utils'; | import { parseLocation, uniqId, waitForLoad } from './utils'; | ||||||
| import { Scheduler } from './Scheduler'; | import { Scheduler } from './Scheduler'; | ||||||
| import { BuildingPageController } from './Page/BuildingPageController'; | import { BuildingPageController } from './Page/BuildingPageController'; | ||||||
| import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask'; | import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask'; | ||||||
| @@ -18,6 +18,7 @@ import { Resources } from './Core/Resources'; | |||||||
| import { Village } from './Core/Village'; | import { Village } from './Core/Village'; | ||||||
| import { calcGatheringTimings } from './Core/GatheringTimings'; | import { calcGatheringTimings } from './Core/GatheringTimings'; | ||||||
| import { DataStorage } from './DataStorage'; | import { DataStorage } from './DataStorage'; | ||||||
|  | import { getBuildingPageAttributes, isBuildingPage } from './Page/PageDetectors'; | ||||||
| import { debounce } from 'debounce'; | import { debounce } from 'debounce'; | ||||||
|  |  | ||||||
| interface QuickAction { | interface QuickAction { | ||||||
| @@ -108,14 +109,8 @@ export class ControlPanel { | |||||||
|             showBuildingSlotIds(buildingsInQueue); |             showBuildingSlotIds(buildingsInQueue); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (p.pathname === '/build.php') { |         if (isBuildingPage()) { | ||||||
|             const buildPage = new BuildingPageController(this.scheduler, { |             const buildPage = new BuildingPageController(this.scheduler, getBuildingPageAttributes()); | ||||||
|                 buildId: getNumber(p.query.id), |  | ||||||
|                 buildTypeId: getNumber(elClassId(jQuery('#build').attr('class'), 'gid')), |  | ||||||
|                 categoryId: getNumber(p.query.category, 1), |  | ||||||
|                 sheetId: getNumber(p.query.s, 0), |  | ||||||
|                 tabId: getNumber(p.query.t, 0), |  | ||||||
|             }); |  | ||||||
|             buildPage.run(); |             buildPage.run(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -189,6 +184,7 @@ class VillageController { | |||||||
|     public readonly warehouse; |     public readonly warehouse; | ||||||
|     public readonly granary; |     public readonly granary; | ||||||
|     public readonly buildRemainingSeconds; |     public readonly buildRemainingSeconds; | ||||||
|  |     public readonly incomingResources: Resources; | ||||||
|  |  | ||||||
|     constructor(village: Village, state: VillageState, scheduler: Scheduler) { |     constructor(village: Village, state: VillageState, scheduler: Scheduler) { | ||||||
|         const resources = state.getResources(); |         const resources = state.getResources(); | ||||||
| @@ -225,6 +221,7 @@ class VillageController { | |||||||
|         this.warehouse = storage.warehouse; |         this.warehouse = storage.warehouse; | ||||||
|         this.granary = storage.granary; |         this.granary = storage.granary; | ||||||
|         this.buildRemainingSeconds = buildQueueInfo.seconds; |         this.buildRemainingSeconds = buildQueueInfo.seconds; | ||||||
|  |         this.incomingResources = this.calcIncomingResources(state); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     timeToRequired() { |     timeToRequired() { | ||||||
| @@ -243,4 +240,8 @@ class VillageController { | |||||||
|  |  | ||||||
|         return timings.hours * 3600; |         return timings.hours * 3600; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private calcIncomingResources(state: VillageState): Resources { | ||||||
|  |         return state.getIncomingMerchants().reduce((m, i) => m.add(i.resources), new Resources(0, 0, 0, 0)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								src/Core/Buildings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/Core/Buildings.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | export const WAREHOUSE_ID = 10; | ||||||
|  | export const GARNER_ID = 11; | ||||||
|  | export const MARKET_ID = 17; | ||||||
|  | export const QUARTERS_ID = 19; | ||||||
|  | export const HORSE_STABLE_ID = 20; | ||||||
|  | export const EMBASSY_ID = 25; | ||||||
							
								
								
									
										10
									
								
								src/Core/Market.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Core/Market.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | import { Resources } from './Resources'; | ||||||
|  |  | ||||||
|  | export class IncomingMerchant { | ||||||
|  |     readonly resources: Resources; | ||||||
|  |     readonly ts: number; | ||||||
|  |     constructor(resources: Resources, ts: number) { | ||||||
|  |         this.resources = resources; | ||||||
|  |         this.ts = ts; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -85,6 +85,23 @@ | |||||||
|             <td class="right" v-text="timeToTotalRequired(village)"></td> |             <td class="right" v-text="timeToTotalRequired(village)"></td> | ||||||
|             <td></td> |             <td></td> | ||||||
|           </tr> |           </tr> | ||||||
|  |           <tr class="incoming-line"> | ||||||
|  |             <td class="right">Торговцы:</td> | ||||||
|  |             <td class="right"> | ||||||
|  |               <resource :value="village.incomingResources.lumber"></resource> | ||||||
|  |             </td> | ||||||
|  |             <td class="right"> | ||||||
|  |               <resource :value="village.incomingResources.clay"></resource> | ||||||
|  |             </td> | ||||||
|  |             <td class="right"> | ||||||
|  |               <resource :value="village.incomingResources.iron"></resource> | ||||||
|  |             </td> | ||||||
|  |             <td class="right"> | ||||||
|  |               <resource :value="village.incomingResources.crop"></resource> | ||||||
|  |             </td> | ||||||
|  |             <td></td> | ||||||
|  |             <td></td> | ||||||
|  |           </tr> | ||||||
|           <tr class="normal-line"> |           <tr class="normal-line"> | ||||||
|             <td></td> |             <td></td> | ||||||
|             <td class="right" colspan="6"> |             <td class="right" colspan="6"> | ||||||
| @@ -97,6 +114,7 @@ | |||||||
|                 >->{{ v.name }}</a |                 >->{{ v.name }}</a | ||||||
|               > |               > | ||||||
|               <a class="village-quick-link" :href="quartersPath(village)">Казармы</a> |               <a class="village-quick-link" :href="quartersPath(village)">Казармы</a> | ||||||
|  |               <a class="village-quick-link" :href="horseStablePath(village)">Конюшни</a> | ||||||
|             </td> |             </td> | ||||||
|           </tr> |           </tr> | ||||||
|         </template> |         </template> | ||||||
| @@ -109,6 +127,7 @@ | |||||||
| import { path } from '../utils'; | import { path } from '../utils'; | ||||||
| import ResourceBalance from './ResourceBalance'; | import ResourceBalance from './ResourceBalance'; | ||||||
| import VillageResource from './VillageResource'; | import VillageResource from './VillageResource'; | ||||||
|  | import { HORSE_STABLE_ID, MARKET_ID, QUARTERS_ID, WAREHOUSE_ID } from '../Core/Buildings'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -126,13 +145,22 @@ export default { | |||||||
|       return path(name, args); |       return path(name, args); | ||||||
|     }, |     }, | ||||||
|     marketPath(fromVillage, toVillage) { |     marketPath(fromVillage, toVillage) { | ||||||
|       return path('/build.php', { newdid: fromVillage.id, gid: 17, t: 5, x: toVillage.crd.x, y: toVillage.crd.y }); |       return path('/build.php', { | ||||||
|  |         newdid: fromVillage.id, | ||||||
|  |         gid: MARKET_ID, | ||||||
|  |         t: 5, | ||||||
|  |         x: toVillage.crd.x, | ||||||
|  |         y: toVillage.crd.y, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     warehousePath(village) { |     warehousePath(village) { | ||||||
|       return path('/build.php', { newdid: village.id, gid: 10 }); |       return path('/build.php', { newdid: village.id, gid: WAREHOUSE_ID }); | ||||||
|     }, |     }, | ||||||
|     quartersPath(village) { |     quartersPath(village) { | ||||||
|       return path('/build.php', { newdid: village.id, gid: 19 }); |       return path('/build.php', { newdid: village.id, gid: QUARTERS_ID }); | ||||||
|  |     }, | ||||||
|  |     horseStablePath(village) { | ||||||
|  |       return path('/build.php', { newdid: village.id, gid: HORSE_STABLE_ID }); | ||||||
|     }, |     }, | ||||||
|     secondsToTime(value) { |     secondsToTime(value) { | ||||||
|       if (value === 0) { |       if (value === 0) { | ||||||
| @@ -178,12 +206,9 @@ export default { | |||||||
|   border: 1px solid #ddd; |   border: 1px solid #ddd; | ||||||
| } | } | ||||||
|  |  | ||||||
| .performance-line td { | .performance-line td, | ||||||
|   padding: 0 4px 4px; | .required-line td, | ||||||
|   font-size: 90%; | .incoming-line td { | ||||||
| } |  | ||||||
|  |  | ||||||
| .required-line td { |  | ||||||
|   padding: 0 4px 4px; |   padding: 0 4px 4px; | ||||||
|   font-size: 90%; |   font-size: 90%; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ConsoleLogger, Logger, NullLogger } from './Logger'; | import { ConsoleLogger, Logger, NullLogger } from './Logger'; | ||||||
|  | import { Resources } from './Core/Resources'; | ||||||
|  |  | ||||||
| const NAMESPACE = 'travian:v1'; | const NAMESPACE = 'travian:v1'; | ||||||
|  |  | ||||||
| @@ -8,6 +9,36 @@ function join(...parts: Array<string>) { | |||||||
|     return parts.map(p => p.replace(/[:]+$/g, '').replace(/^[:]+/g, '')).join(':'); |     return parts.map(p => p.replace(/[:]+$/g, '').replace(/^[:]+/g, '')).join(':'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | interface EmptyObjectFactory<T> { | ||||||
|  |     (): T; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface ObjectMapper<T> { | ||||||
|  |     (item: any): T; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface ObjectMapperOptions<T> { | ||||||
|  |     factory?: EmptyObjectFactory<T>; | ||||||
|  |     mapper?: ObjectMapper<T>; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function createMapper<T>(options: ObjectMapperOptions<T>): ObjectMapper<T> { | ||||||
|  |     const { mapper, factory } = options; | ||||||
|  |  | ||||||
|  |     if (mapper) { | ||||||
|  |         return mapper; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (factory) { | ||||||
|  |         return plain => { | ||||||
|  |             let item = factory(); | ||||||
|  |             return Object.assign(item, plain) as T; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     throw new Error('Factory or mapper must be specified'); | ||||||
|  | } | ||||||
|  |  | ||||||
| export class DataStorage { | export class DataStorage { | ||||||
|     private readonly logger: Logger; |     private readonly logger: Logger; | ||||||
|     private readonly name: string; |     private readonly name: string; | ||||||
| @@ -40,6 +71,21 @@ export class DataStorage { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getTyped<T>(key: string, options: ObjectMapperOptions<T> = {}): T { | ||||||
|  |         let plain = this.get(key); | ||||||
|  |         const mapper = createMapper(options); | ||||||
|  |         return mapper(plain); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getTypedList<T>(key: string, options: ObjectMapperOptions<T> = {}): Array<T> { | ||||||
|  |         let plain = this.get(key); | ||||||
|  |         if (!Array.isArray(plain)) { | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|  |         const mapper = createMapper(options); | ||||||
|  |         return (plain as Array<any>).map(mapper); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     has(key: string): boolean { |     has(key: string): boolean { | ||||||
|         const fullKey = join(NAMESPACE, this.name, key); |         const fullKey = join(NAMESPACE, this.name, key); | ||||||
|         return storage.getItem(fullKey) !== null; |         return storage.getItem(fullKey) !== null; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import { Grabber } from './Grabber'; | |||||||
| import { VillageResourceGrabber } from './VillageResourceGrabber'; | import { VillageResourceGrabber } from './VillageResourceGrabber'; | ||||||
| import { VillageOverviewPageGrabber } from './VillageOverviewPageGrabber'; | import { VillageOverviewPageGrabber } from './VillageOverviewPageGrabber'; | ||||||
| import { HeroPageGrabber } from './HeroPageGrabber'; | import { HeroPageGrabber } from './HeroPageGrabber'; | ||||||
|  | import { MarketPageGrabber } from './MarketPageGrabber'; | ||||||
|  |  | ||||||
| export class GrabberManager { | export class GrabberManager { | ||||||
|     private readonly grabbers: Array<Grabber> = []; |     private readonly grabbers: Array<Grabber> = []; | ||||||
| @@ -11,6 +12,7 @@ export class GrabberManager { | |||||||
|         this.grabbers.push(new VillageResourceGrabber()); |         this.grabbers.push(new VillageResourceGrabber()); | ||||||
|         this.grabbers.push(new VillageOverviewPageGrabber()); |         this.grabbers.push(new VillageOverviewPageGrabber()); | ||||||
|         this.grabbers.push(new HeroPageGrabber()); |         this.grabbers.push(new HeroPageGrabber()); | ||||||
|  |         this.grabbers.push(new MarketPageGrabber()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     grab() { |     grab() { | ||||||
|   | |||||||
| @@ -1,21 +1,12 @@ | |||||||
| import { Grabber } from './Grabber'; | import { Grabber } from './Grabber'; | ||||||
| import { | import { grabVillageList } from '../Page/VillageBlock'; | ||||||
|     grabActiveVillageId, |  | ||||||
|     grabBuildingQueueInfo, |  | ||||||
|     grabResourcesPerformance, |  | ||||||
|     grabVillageList, |  | ||||||
| } from '../Page/VillageBlock'; |  | ||||||
| import { VillageState } from '../State/VillageState'; |  | ||||||
| import { parseLocation } from '../utils'; |  | ||||||
| import { GrabError } from '../Errors'; |  | ||||||
| import { BuildingQueueInfo } from '../Game'; |  | ||||||
| import { HeroState } from '../State/HeroState'; | import { HeroState } from '../State/HeroState'; | ||||||
| import { grabHeroAttributes, grabHeroVillage } from '../Page/HeroPage'; | import { grabHeroAttributes, grabHeroVillage } from '../Page/HeroPage'; | ||||||
|  | import { isHeroPage } from '../Page/PageDetectors'; | ||||||
|  |  | ||||||
| export class HeroPageGrabber extends Grabber { | export class HeroPageGrabber extends Grabber { | ||||||
|     grab(): void { |     grab(): void { | ||||||
|         const p = parseLocation(); |         if (!isHeroPage()) { | ||||||
|         if (p.pathname !== '/hero.php') { |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/Grabber/MarketPageGrabber.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/Grabber/MarketPageGrabber.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | import { Grabber } from './Grabber'; | ||||||
|  | import { grabActiveVillageId } from '../Page/VillageBlock'; | ||||||
|  | import { VillageState } from '../State/VillageState'; | ||||||
|  | import { grabIncomingMerchants } from '../Page/BuildingPage'; | ||||||
|  | import { isMarketSendResourcesPage } from '../Page/PageDetectors'; | ||||||
|  |  | ||||||
|  | export class MarketPageGrabber extends Grabber { | ||||||
|  |     grab(): void { | ||||||
|  |         if (!isMarketSendResourcesPage()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const villageId = grabActiveVillageId(); | ||||||
|  |         const state = new VillageState(villageId); | ||||||
|  |         state.storeIncomingMerchants(grabIncomingMerchants()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ import { GrabError } from '../Errors'; | |||||||
| import { elClassId, getNumber, trimPrefix, uniqId } from '../utils'; | import { elClassId, getNumber, trimPrefix, uniqId } from '../utils'; | ||||||
| import { Resources } from '../Core/Resources'; | import { Resources } from '../Core/Resources'; | ||||||
| import { Coordinates } from '../Core/Village'; | import { Coordinates } from '../Core/Village'; | ||||||
|  | import { IncomingMerchant } from '../Core/Market'; | ||||||
|  |  | ||||||
| export function clickBuildButton(typeId: number) { | export function clickBuildButton(typeId: number) { | ||||||
|     const section = jQuery(`#contract_building${typeId}`); |     const section = jQuery(`#contract_building${typeId}`); | ||||||
| @@ -140,3 +141,18 @@ export function fillSendResourcesForm(resources: Resources, crd: Coordinates) { | |||||||
| export function clickSendButton() { | export function clickSendButton() { | ||||||
|     jQuery('#enabledButton').trigger('click'); |     jQuery('#enabledButton').trigger('click'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function grabIncomingMerchants(): ReadonlyArray<IncomingMerchant> { | ||||||
|  |     const result: Array<IncomingMerchant> = []; | ||||||
|  |     const root = jQuery('#merchantsOnTheWay .ownMerchants'); | ||||||
|  |     root.find('.traders').each((idx, el) => { | ||||||
|  |         const $el = jQuery(el); | ||||||
|  |         result.push( | ||||||
|  |             new IncomingMerchant( | ||||||
|  |                 grabResourcesFromList($el.find('.resourceWrapper .resources')), | ||||||
|  |                 getNumber($el.find('.timer').attr('value')) | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |     }); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -9,24 +9,14 @@ import { | |||||||
|     createSendResourcesButton, |     createSendResourcesButton, | ||||||
|     createTrainTroopButtons, |     createTrainTroopButtons, | ||||||
|     createUpgradeButton, |     createUpgradeButton, | ||||||
|  |     grabIncomingMerchants, | ||||||
| } from './BuildingPage'; | } from './BuildingPage'; | ||||||
| import { BuildBuildingTask } from '../Task/BuildBuildingTask'; | import { BuildBuildingTask } from '../Task/BuildBuildingTask'; | ||||||
| import { Resources } from '../Core/Resources'; | import { Resources } from '../Core/Resources'; | ||||||
| import { Coordinates } from '../Core/Village'; | import { Coordinates } from '../Core/Village'; | ||||||
| import { SendResourcesTask } from '../Task/SendResourcesTask'; | import { SendResourcesTask } from '../Task/SendResourcesTask'; | ||||||
|  | import { EMBASSY_ID, HORSE_STABLE_ID, QUARTERS_ID } from '../Core/Buildings'; | ||||||
| const MARKET_ID = 17; | import { BuildingPageAttributes, isMarketSendResourcesPage } from './PageDetectors'; | ||||||
| const QUARTERS_ID = 19; |  | ||||||
| const HORSE_STABLE_ID = 20; |  | ||||||
| const EMBASSY_ID = 25; |  | ||||||
|  |  | ||||||
| export interface BuildingPageAttributes { |  | ||||||
|     buildId: number; |  | ||||||
|     buildTypeId: number; |  | ||||||
|     categoryId: number; |  | ||||||
|     sheetId: number; |  | ||||||
|     tabId: number; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class BuildingPageController { | export class BuildingPageController { | ||||||
|     private scheduler: Scheduler; |     private scheduler: Scheduler; | ||||||
| @@ -40,7 +30,7 @@ export class BuildingPageController { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     run() { |     run() { | ||||||
|         const { buildTypeId, sheetId, tabId } = this.attributes; |         const { buildTypeId, sheetId } = this.attributes; | ||||||
|         this.logger.log('BUILD PAGE DETECTED', 'ID', this.attributes.buildId, this.attributes); |         this.logger.log('BUILD PAGE DETECTED', 'ID', this.attributes.buildId, this.attributes); | ||||||
|  |  | ||||||
|         if (buildTypeId) { |         if (buildTypeId) { | ||||||
| @@ -61,7 +51,8 @@ export class BuildingPageController { | |||||||
|             createTrainTroopButtons((troopId, res, count) => this.onScheduleTrainTroopers(troopId, res, count)); |             createTrainTroopButtons((troopId, res, count) => this.onScheduleTrainTroopers(troopId, res, count)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (buildTypeId === MARKET_ID && tabId === 5) { |         if (isMarketSendResourcesPage()) { | ||||||
|  |             console.log('MERCH', grabIncomingMerchants()); | ||||||
|             createSendResourcesButton((res, crd) => this.onSendResources(res, crd)); |             createSendResourcesButton((res, crd) => this.onSendResources(res, crd)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								src/Page/PageDetectors.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/Page/PageDetectors.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | import { elClassId, getNumber, parseLocation } from '../utils'; | ||||||
|  | import { MARKET_ID } from '../Core/Buildings'; | ||||||
|  |  | ||||||
|  | export interface BuildingPageAttributes { | ||||||
|  |     buildId: number; | ||||||
|  |     buildTypeId: number; | ||||||
|  |     categoryId: number; | ||||||
|  |     sheetId: number; | ||||||
|  |     tabId: number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function isBuildingPage() { | ||||||
|  |     const p = parseLocation(); | ||||||
|  |     return p.pathname === '/build.php'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function isHeroPage() { | ||||||
|  |     const p = parseLocation(); | ||||||
|  |     return p.pathname === '/hero.php'; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function getBuildingPageAttributes(): BuildingPageAttributes { | ||||||
|  |     if (!isBuildingPage()) { | ||||||
|  |         throw Error('Not building page'); | ||||||
|  |     } | ||||||
|  |     const p = parseLocation(); | ||||||
|  |     return { | ||||||
|  |         buildId: getNumber(p.query.id), | ||||||
|  |         buildTypeId: getNumber(elClassId(jQuery('#build').attr('class'), 'gid')), | ||||||
|  |         categoryId: getNumber(p.query.category, 1), | ||||||
|  |         sheetId: getNumber(p.query.s, 0), | ||||||
|  |         tabId: getNumber(p.query.t, 0), | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function isMarketSendResourcesPage(): boolean { | ||||||
|  |     if (!isBuildingPage()) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     const { buildTypeId, tabId } = getBuildingPageAttributes(); | ||||||
|  |     return buildTypeId === MARKET_ID && tabId === 5; | ||||||
|  | } | ||||||
| @@ -1,12 +1,18 @@ | |||||||
| import { DataStorage } from '../DataStorage'; | import { DataStorage } from '../DataStorage'; | ||||||
| import { BuildingQueueInfo } from '../Game'; | import { BuildingQueueInfo } from '../Game'; | ||||||
| import { Resources } from '../Core/Resources'; | import { Resources, ResourcesInterface } from '../Core/Resources'; | ||||||
| import { ResourceStorage } from '../Core/ResourceStorage'; | import { ResourceStorage } from '../Core/ResourceStorage'; | ||||||
|  | import { IncomingMerchant } from '../Core/Market'; | ||||||
|  |  | ||||||
| const RESOURCES_KEY = 'res'; | const RESOURCES_KEY = 'res'; | ||||||
| const CAPACITY_KEY = 'cap'; | const CAPACITY_KEY = 'cap'; | ||||||
| const PERFORMANCE_KEY = 'perf'; | const PERFORMANCE_KEY = 'perf'; | ||||||
| const BUILDING_QUEUE_KEY = 'bq'; | const BUILDING_QUEUE_KEY = 'bq'; | ||||||
|  | const INCOMING_MERCHANTS_KEY = 'im'; | ||||||
|  |  | ||||||
|  | const ResourceOptions = { | ||||||
|  |     factory: () => new Resources(0, 0, 0, 0), | ||||||
|  | }; | ||||||
|  |  | ||||||
| export class VillageState { | export class VillageState { | ||||||
|     private storage: DataStorage; |     private storage: DataStorage; | ||||||
| @@ -19,9 +25,7 @@ export class VillageState { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     getResources(): Resources { |     getResources(): Resources { | ||||||
|         let plain = this.storage.get(RESOURCES_KEY); |         return this.storage.getTyped(RESOURCES_KEY, ResourceOptions); | ||||||
|         let res = new Resources(0, 0, 0, 0); |  | ||||||
|         return Object.assign(res, plain) as Resources; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     storeResourceStorage(storage: ResourceStorage) { |     storeResourceStorage(storage: ResourceStorage) { | ||||||
| @@ -39,9 +43,7 @@ export class VillageState { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     getResourcesPerformance(): Resources { |     getResourcesPerformance(): Resources { | ||||||
|         let plain = this.storage.get(PERFORMANCE_KEY); |         return this.storage.getTyped(PERFORMANCE_KEY, ResourceOptions); | ||||||
|         let res = new Resources(0, 0, 0, 0); |  | ||||||
|         return Object.assign(res, plain) as Resources; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     storeBuildingQueueInfo(info: BuildingQueueInfo): void { |     storeBuildingQueueInfo(info: BuildingQueueInfo): void { | ||||||
| @@ -53,4 +55,23 @@ export class VillageState { | |||||||
|         let res = new BuildingQueueInfo(0); |         let res = new BuildingQueueInfo(0); | ||||||
|         return Object.assign(res, plain) as BuildingQueueInfo; |         return Object.assign(res, plain) as BuildingQueueInfo; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     storeIncomingMerchants(merchants: ReadonlyArray<IncomingMerchant>): void { | ||||||
|  |         this.storage.set( | ||||||
|  |             INCOMING_MERCHANTS_KEY, | ||||||
|  |             merchants.map(m => ({ ...m.resources, ts: m.ts })) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getIncomingMerchants(): ReadonlyArray<IncomingMerchant> { | ||||||
|  |         const objects = this.storage.getTypedList<object>(INCOMING_MERCHANTS_KEY, { factory: () => ({}) }); | ||||||
|  |         return objects.map((plain: object) => { | ||||||
|  |             const m = new IncomingMerchant(new Resources(0, 0, 0, 0), 0); | ||||||
|  |             if (typeof plain !== 'object') { | ||||||
|  |                 return m; | ||||||
|  |             } | ||||||
|  |             const norm = plain as ResourcesInterface & { ts: number }; | ||||||
|  |             return new IncomingMerchant(Resources.fromObject(norm), Number(norm.ts || 0)); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import { path } from '../utils'; | |||||||
| import { Task } from '../Queue/TaskQueue'; | import { Task } from '../Queue/TaskQueue'; | ||||||
| import { TaskController, registerTask } from './TaskController'; | import { TaskController, registerTask } from './TaskController'; | ||||||
| import { grabVillageList } from '../Page/VillageBlock'; | import { grabVillageList } from '../Page/VillageBlock'; | ||||||
|  | import { MARKET_ID } from '../Core/Buildings'; | ||||||
|  |  | ||||||
| @registerTask | @registerTask | ||||||
| export class GrabVillageState extends TaskController { | export class GrabVillageState extends TaskController { | ||||||
| @@ -21,6 +22,12 @@ export class GrabVillageState extends TaskController { | |||||||
|                     path: path('/dorf1.php', { newdid: village.id }), |                     path: path('/dorf1.php', { newdid: village.id }), | ||||||
|                 }) |                 }) | ||||||
|             ); |             ); | ||||||
|  |             actions.push( | ||||||
|  |                 new Command(GoToPageAction.name, { | ||||||
|  |                     ...args, | ||||||
|  |                     path: path('/build.php', { newdid: village.id, gid: MARKET_ID, t: 5 }), | ||||||
|  |                 }) | ||||||
|  |             ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         actions.push(new Command(CompleteTaskAction.name, args)); |         actions.push(new Command(CompleteTaskAction.name, args)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user