diff --git a/src/Action/TrainTrooperAction.ts b/src/Action/TrainTrooperAction.ts index 06df3c4..4668452 100644 --- a/src/Action/TrainTrooperAction.ts +++ b/src/Action/TrainTrooperAction.ts @@ -1,57 +1,31 @@ -import { ActionController, registerAction } from './ActionController'; -import { ActionError, TryLaterError } from '../Errors'; -import { getNumber, toNumber } from '../utils'; +import { ActionController, err, registerAction } from './ActionController'; +import { TryLaterError } from '../Errors'; +import { aroundMinutes } from '../utils'; import { Args } from '../Queue/Args'; import { Task } from '../Queue/TaskProvider'; +import { clickTrainButton, fillTrainCount, getAvailableCount } from '../Page/BuildingPage/TrooperPage'; +import { TrainTroopTask } from '../Task/TrainTroopTask'; @registerAction export class TrainTrooperAction extends ActionController { async run(args: Args, task: Task): Promise { - const troopId = this.getTroopId(args); - const trainCount = this.getTrainCount(args); + const troopId = args.troopId || err('No troop id'); + const trainCount = args.trainCount || err('No troop train count'); - const block = jQuery(`.innerTroopWrapper[data-troopid="${troopId}"]`); - if (block.length !== 1) { - throw new ActionError(`Troop block not found`); + const availableCount = getAvailableCount(troopId); + + const readyToTrainCount = Math.min(availableCount, trainCount); + const nextToTrainCount = trainCount - readyToTrainCount; + + if (readyToTrainCount <= 0) { + throw new TryLaterError(aroundMinutes(15), 'No ready to train troops'); } - const countLink = block.find('.cta a'); - if (countLink.length !== 1) { - throw new ActionError(`Link with max count not found`); + if (nextToTrainCount > 0) { + this.scheduler.scheduleTask(TrainTroopTask.name, { ...task.args, trainCount: nextToTrainCount }); } - const maxCount = getNumber(countLink.text()); - if (maxCount < trainCount) { - throw new TryLaterError(20 * 60, `Max count ${maxCount} less then need ${trainCount}`); - } - - const input = block.find(`input[name="t${troopId}"]`); - if (input.length !== 1) { - throw new ActionError(`Input element not found`); - } - - const trainButton = jQuery('.startTraining.green').first(); - if (trainButton.length !== 1) { - throw new ActionError('Train button not found'); - } - - input.val(trainCount); - trainButton.trigger('click'); - } - - private getTroopId(args: Args): number { - const troopId = toNumber(args.troopId); - if (troopId === undefined) { - throw new ActionError(`Troop id must be a number, given "${args.troopId}"`); - } - return troopId; - } - - private getTrainCount(args: Args): number { - const trainCount = toNumber(args.trainCount); - if (trainCount === undefined) { - throw new ActionError(`Train count must be a number, given "${args.trainCount}"`); - } - return trainCount; + fillTrainCount(troopId, readyToTrainCount); + clickTrainButton(); } } diff --git a/src/Page/BuildingPage/TrooperPage.ts b/src/Page/BuildingPage/TrooperPage.ts index 5d2b24c..149af4f 100644 --- a/src/Page/BuildingPage/TrooperPage.ts +++ b/src/Page/BuildingPage/TrooperPage.ts @@ -30,3 +30,37 @@ export function createTrainTroopButtons( }); }); } + +function getTroopBlock(troopId: number): JQuery { + const $block = jQuery(`.innerTroopWrapper[data-troopid="${troopId}"]`); + if ($block.length !== 1) { + throw new GrabError(`Troop block not found`); + } + return $block; +} + +export function getAvailableCount(troopId: number): number { + const $block = getTroopBlock(troopId); + const $countLink = $block.find('.cta a'); + if ($countLink.length !== 1) { + throw new GrabError(`Link with max count not found`); + } + return getNumber($countLink.text()); +} + +export function fillTrainCount(troopId: number, trainCount: number): void { + const $block = getTroopBlock(troopId); + const input = $block.find(`input[name="t${troopId}"]`); + if (input.length !== 1) { + throw new GrabError(`Input element not found`); + } + input.val(trainCount); +} + +export function clickTrainButton(): void { + const $trainButton = jQuery('.startTraining.green').first(); + if ($trainButton.length !== 1) { + throw new GrabError('Train button not found'); + } + $trainButton.trigger('click'); +} diff --git a/src/Page/BuildingPageController.ts b/src/Page/BuildingPageController.ts index de79a73..6e7147a 100644 --- a/src/Page/BuildingPageController.ts +++ b/src/Page/BuildingPageController.ts @@ -83,20 +83,18 @@ export class BuildingPageController { notify(`Upgrading ${buildId} scheduled`); } - private onScheduleTrainTroopers(troopId: number, resources: Resources, count: number) { - for (let chunk of split(count)) { - const args = { - villageId: grabActiveVillageId(), - buildId: this.attributes.buildId, - buildTypeId: this.attributes.buildTypeId, - sheetId: this.attributes.sheetId, - troopId, - resources: resources.scale(chunk), - trainCount: chunk, - }; - this.scheduler.scheduleTask(TrainTroopTask.name, args); - } - notify(`Training ${count} troopers scheduled`); + private onScheduleTrainTroopers(troopId: number, resources: Resources, trainCount: number) { + const args = { + villageId: grabActiveVillageId(), + buildId: this.attributes.buildId, + buildTypeId: this.attributes.buildTypeId, + sheetId: this.attributes.sheetId, + troopId, + trainCount, + resources: resources.scale(trainCount), + }; + this.scheduler.scheduleTask(TrainTroopTask.name, args); + notify(`Training ${trainCount} troopers scheduled`); } private onSendResources(resources: Resources, coordinates: Coordinates) { diff --git a/src/Task/TrainTroopTask.ts b/src/Task/TrainTroopTask.ts index bb9e565..f10a200 100644 --- a/src/Task/TrainTroopTask.ts +++ b/src/Task/TrainTroopTask.ts @@ -1,17 +1,15 @@ -import { TaskController } from './TaskController'; +import { ActionDefinition, TaskController } from './TaskController'; import { GoToPageAction } from '../Action/GoToPageAction'; import { CompleteTaskAction } from '../Action/CompleteTaskAction'; import { TrainTrooperAction } from '../Action/TrainTrooperAction'; -import { Action } from '../Queue/ActionQueue'; -import { Args } from '../Queue/Args'; import { Task } from '../Queue/TaskProvider'; import { path } from '../Helpers/Path'; import { registerTask, TaskType } from './TaskMap'; @registerTask({ type: TaskType.TrainUnit }) export class TrainTroopTask extends TaskController { - async run(task: Task) { - const args: Args = { ...task.args, taskId: task.id }; + defineActions(task: Task): Array { + const args = task.args; const pathArgs = { newdid: args.villageId, @@ -20,10 +18,10 @@ export class TrainTroopTask extends TaskController { s: args.sheetId, }; - this.scheduler.scheduleActions([ - new Action(GoToPageAction.name, { ...args, path: path('/build.php', pathArgs) }), - new Action(TrainTrooperAction.name, args), - new Action(CompleteTaskAction.name, args), - ]); + return [ + [GoToPageAction.name, { path: path('/build.php', pathArgs) }], + [TrainTrooperAction.name], + [CompleteTaskAction.name], + ]; } }