Change hero balance action
Target - required by next build resources
This commit is contained in:
parent
236135f1ca
commit
809b54e0b9
@ -1,25 +1,53 @@
|
|||||||
import { ActionController, registerAction } from './ActionController';
|
import { ActionController, registerAction } from './ActionController';
|
||||||
import { Args } from '../Common';
|
import { Args } from '../Common';
|
||||||
import { Task } from '../Storage/TaskQueue';
|
import { Task } from '../Storage/TaskQueue';
|
||||||
import { grabResources } from '../Page/ResourcesBlock';
|
import { grabResources, grabResourceStorage } from '../Page/ResourcesBlock';
|
||||||
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
|
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
|
||||||
import { HeroAllResources } from '../Game';
|
import { HeroAllResources, Resources } from '../Game';
|
||||||
|
import { grabActiveVillageId } from '../Page/VillageBlock';
|
||||||
|
|
||||||
@registerAction
|
@registerAction
|
||||||
export class BalanceHeroResourcesAction extends ActionController {
|
export class BalanceHeroResourcesAction extends ActionController {
|
||||||
async run(args: Args, task: Task): Promise<any> {
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
const resourcesAsList = grabResources().asList();
|
const resources = this.getRequirements();
|
||||||
|
|
||||||
|
const resourcesAsList = resources.asList();
|
||||||
const currentType = grabCurrentHeroResource();
|
const currentType = grabCurrentHeroResource();
|
||||||
|
|
||||||
const sorted = resourcesAsList.sort((x, y) => x.value - y.value);
|
const sorted = resourcesAsList.sort((x, y) => y.value - x.value);
|
||||||
const min = sorted[0];
|
const maxRequirement = sorted[0];
|
||||||
const max = sorted[sorted.length - 1];
|
const minRequirement = sorted[sorted.length - 1];
|
||||||
const delta = max.value - min.value;
|
const delta = maxRequirement.value - minRequirement.value;
|
||||||
const eps = max.value / 10;
|
const eps = maxRequirement.value / 10;
|
||||||
|
|
||||||
const resType = delta > eps ? min.type : HeroAllResources;
|
const resType = delta > eps ? maxRequirement.type : HeroAllResources;
|
||||||
if (resType !== currentType) {
|
if (resType !== currentType) {
|
||||||
changeHeroResource(resType);
|
changeHeroResource(resType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getRequirements() {
|
||||||
|
const resources = grabResources();
|
||||||
|
|
||||||
|
const villageId = grabActiveVillageId();
|
||||||
|
const requiredResources = this.scheduler.getVillageRequiredResources(villageId);
|
||||||
|
|
||||||
|
if (requiredResources) {
|
||||||
|
return new Resources(
|
||||||
|
requiredResources.lumber - resources.lumber,
|
||||||
|
requiredResources.clay - resources.clay,
|
||||||
|
requiredResources.iron - resources.iron,
|
||||||
|
requiredResources.crop - resources.crop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storage = grabResourceStorage();
|
||||||
|
|
||||||
|
return new Resources(
|
||||||
|
storage.warehouse - resources.lumber,
|
||||||
|
storage.warehouse - resources.clay,
|
||||||
|
storage.warehouse - resources.iron,
|
||||||
|
storage.granary - resources.crop
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
21
src/Action/UpdateBuildingTaskResourcesAction.ts
Normal file
21
src/Action/UpdateBuildingTaskResourcesAction.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { ActionController, registerAction } from './ActionController';
|
||||||
|
import { Args } from '../Common';
|
||||||
|
import { Task } from '../Storage/TaskQueue';
|
||||||
|
import { grabContractResources } from '../Page/BuildingPage';
|
||||||
|
|
||||||
|
@registerAction
|
||||||
|
export class UpdateBuildingTaskResourcesAction extends ActionController {
|
||||||
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
|
const buildingTaskId = args.taskId;
|
||||||
|
if (buildingTaskId === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resources = grabContractResources();
|
||||||
|
this.scheduler.updateResources(buildingTaskId, resources);
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { ResourcesInterface } from './Game';
|
import { ResourcesInterface } from './Game';
|
||||||
|
import { TaskId } from './Storage/TaskQueue';
|
||||||
|
|
||||||
export interface Args {
|
export interface Args {
|
||||||
villageId?: number;
|
villageId?: number;
|
||||||
@ -6,6 +7,7 @@ export interface Args {
|
|||||||
categoryId?: number;
|
categoryId?: number;
|
||||||
buildTypeId?: number;
|
buildTypeId?: number;
|
||||||
resources?: ResourcesInterface;
|
resources?: ResourcesInterface;
|
||||||
|
taskId?: TaskId;
|
||||||
[name: string]: any;
|
[name: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ export class ControlPanel {
|
|||||||
const storage = state.getResourceStorage();
|
const storage = state.getResourceStorage();
|
||||||
const performance = state.getResourcesPerformance();
|
const performance = state.getResourcesPerformance();
|
||||||
const buildQueueInfo = state.getBuildingQueueInfo();
|
const buildQueueInfo = state.getBuildingQueueInfo();
|
||||||
|
const requiredResources = scheduler.getVillageRequiredResources(village.id);
|
||||||
return {
|
return {
|
||||||
id: village.id,
|
id: village.id,
|
||||||
name: village.name,
|
name: village.name,
|
||||||
@ -85,6 +86,10 @@ export class ControlPanel {
|
|||||||
clay_hour: performance.clay,
|
clay_hour: performance.clay,
|
||||||
iron_hour: performance.iron,
|
iron_hour: performance.iron,
|
||||||
crop_hour: performance.crop,
|
crop_hour: performance.crop,
|
||||||
|
lumber_need: requiredResources && requiredResources.lumber,
|
||||||
|
clay_need: requiredResources && requiredResources.clay,
|
||||||
|
iron_need: requiredResources && requiredResources.iron,
|
||||||
|
crop_need: requiredResources && requiredResources.crop,
|
||||||
warehouse: storage.warehouse,
|
warehouse: storage.warehouse,
|
||||||
granary: storage.granary,
|
granary: storage.granary,
|
||||||
buildRemainingSeconds: buildQueueInfo.seconds,
|
buildRemainingSeconds: buildQueueInfo.seconds,
|
||||||
|
@ -41,12 +41,30 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="right" v-text="village.granary"></td>
|
<td class="right" v-text="village.granary"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="required-line">
|
||||||
|
<td class="right">След:</td>
|
||||||
|
<td class="right" v-text="village.lumber_need || ''"></td>
|
||||||
|
<td class="right" v-text="village.clay_need || ''"></td>
|
||||||
|
<td class="right" v-text="village.iron_need || ''"></td>
|
||||||
|
<td class="right" v-text="village.crop_need || ''"></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="required-line">
|
||||||
|
<td class="right">Необх:</td>
|
||||||
|
<td class="right" v-text="village.lumber_need - village.lumber || ''"></td>
|
||||||
|
<td class="right" v-text="village.clay_need - village.clay || ''"></td>
|
||||||
|
<td class="right" v-text="village.iron_need - village.iron || ''"></td>
|
||||||
|
<td class="right" v-text="village.crop_need - village.crop || ''"></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr class="performance-line">
|
<tr class="performance-line">
|
||||||
<td class="right small" v-text="secondsToTime(village.buildRemainingSeconds)"></td>
|
<td class="right" v-text="secondsToTime(village.buildRemainingSeconds)"></td>
|
||||||
<td class="right small">+{{ village.lumber_hour }}</td>
|
<td class="right">+{{ village.lumber_hour }}</td>
|
||||||
<td class="right small">+{{ village.clay_hour }}</td>
|
<td class="right">+{{ village.clay_hour }}</td>
|
||||||
<td class="right small">+{{ village.iron_hour }}</td>
|
<td class="right">+{{ village.iron_hour }}</td>
|
||||||
<td class="right small">+{{ village.crop_hour }}</td>
|
<td class="right">+{{ village.crop_hour }}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -130,6 +148,12 @@ export default {
|
|||||||
|
|
||||||
.performance-line td {
|
.performance-line td {
|
||||||
padding: 0 4px 4px;
|
padding: 0 4px 4px;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.required-line td {
|
||||||
|
padding: 0 4px 4px;
|
||||||
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.village-table td.active {
|
.village-table td.active {
|
||||||
@ -144,10 +168,6 @@ export default {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small {
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.village-quick-link {
|
.village-quick-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ export class Resources implements ResourcesInterface {
|
|||||||
this.crop = crop;
|
this.crop = crop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromObject(obj: ResourcesInterface) {
|
||||||
|
return new Resources(obj.lumber, obj.clay, obj.iron, obj.crop);
|
||||||
|
}
|
||||||
|
|
||||||
getByType(type: ResourceType): number {
|
getByType(type: ResourceType): number {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ResourceType.Lumber:
|
case ResourceType.Lumber:
|
||||||
|
@ -8,6 +8,8 @@ import { ConsoleLogger, Logger } from './Logger';
|
|||||||
import { BuildBuildingTask } from './Task/BuildBuildingTask';
|
import { BuildBuildingTask } from './Task/BuildBuildingTask';
|
||||||
import { GrabVillageState } from './Task/GrabVillageState';
|
import { GrabVillageState } from './Task/GrabVillageState';
|
||||||
import { ActionQueue } from './Storage/ActionQueue';
|
import { ActionQueue } from './Storage/ActionQueue';
|
||||||
|
import { Resources, ResourcesInterface } from './Game';
|
||||||
|
import { UpdateResourceContracts } from './Task/UpdateResourceContracts';
|
||||||
|
|
||||||
export class Scheduler {
|
export class Scheduler {
|
||||||
private taskQueue: TaskQueue;
|
private taskQueue: TaskQueue;
|
||||||
@ -20,17 +22,18 @@ export class Scheduler {
|
|||||||
this.logger = new ConsoleLogger(this.constructor.name);
|
this.logger = new ConsoleLogger(this.constructor.name);
|
||||||
|
|
||||||
// this.taskQueue.push(GrabVillageState.name, {}, timestamp());
|
// this.taskQueue.push(GrabVillageState.name, {}, timestamp());
|
||||||
|
// this.taskQueue.push(UpdateResourceContracts.name, {}, timestamp());
|
||||||
|
// this.taskQueue.push(BalanceHeroResourcesTask.name, {}, timestamp());
|
||||||
|
|
||||||
this.scheduleUniqTask(3600, SendOnAdventureTask.name);
|
this.createUniqTaskTimer(3600, SendOnAdventureTask.name);
|
||||||
this.scheduleUniqTask(1200, BalanceHeroResourcesTask.name);
|
this.createUniqTaskTimer(1200, BalanceHeroResourcesTask.name);
|
||||||
this.scheduleUniqTask(180, GrabVillageState.name);
|
this.createUniqTaskTimer(180, GrabVillageState.name);
|
||||||
|
this.createUniqTaskTimer(300, UpdateResourceContracts.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private scheduleUniqTask(seconds: number, name: string, args: Args = {}) {
|
public createUniqTaskTimer(seconds: number, name: string, args: Args = {}) {
|
||||||
const taskScheduler = () => {
|
const taskScheduler = () => {
|
||||||
if (!this.taskQueue.has(t => t.name === name)) {
|
this.scheduleUniqTask(name, args, timestamp() + Math.min(seconds, 5 * 60));
|
||||||
this.scheduleTask(name, args, timestamp() + Math.min(seconds, 5 * 60));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
taskScheduler();
|
taskScheduler();
|
||||||
setInterval(taskScheduler, seconds * 1000);
|
setInterval(taskScheduler, seconds * 1000);
|
||||||
@ -63,6 +66,13 @@ export class Scheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleUniqTask(name: string, args: Args, ts?: number | undefined): void {
|
||||||
|
let alreadyHasTask = this.taskQueue.has(t => t.name === name);
|
||||||
|
if (!alreadyHasTask) {
|
||||||
|
this.scheduleTask(name, args, ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
completeTask(id: TaskId) {
|
completeTask(id: TaskId) {
|
||||||
this.taskQueue.remove(id);
|
this.taskQueue.remove(id);
|
||||||
this.actionQueue.clear();
|
this.actionQueue.clear();
|
||||||
@ -87,6 +97,13 @@ export class Scheduler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateResources(taskId: TaskId, resources: Resources): void {
|
||||||
|
this.taskQueue.modify(
|
||||||
|
t => t.id === taskId,
|
||||||
|
t => withResources(t, resources)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
scheduleActions(actions: Array<Command>): void {
|
scheduleActions(actions: Array<Command>): void {
|
||||||
this.actionQueue.assign(actions);
|
this.actionQueue.assign(actions);
|
||||||
}
|
}
|
||||||
@ -94,6 +111,15 @@ export class Scheduler {
|
|||||||
clearActions() {
|
clearActions() {
|
||||||
this.actionQueue.clear();
|
this.actionQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getVillageRequiredResources(villageId): ResourcesInterface | undefined {
|
||||||
|
const tasks = this.taskQueue.seeItems().filter(t => isBuildingTask(t.name) && sameVillage(villageId, t.args));
|
||||||
|
const first = tasks.shift();
|
||||||
|
if (first && first.args.resources) {
|
||||||
|
return first.args.resources;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBuildingTask(taskName: string) {
|
function isBuildingTask(taskName: string) {
|
||||||
@ -104,10 +130,14 @@ function sameVillage(villageId: number | undefined, args: Args) {
|
|||||||
return villageId !== undefined && args.villageId === villageId;
|
return villageId !== undefined && args.villageId === villageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withTime(task: Task, ts: number): Task {
|
function withTime(task: Task, ts: number): Task {
|
||||||
return new Task(task.id, ts, task.name, task.args);
|
return new Task(task.id, ts, task.name, task.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function withResources(task: Task, resources: ResourcesInterface): Task {
|
||||||
|
return new Task(task.id, task.ts, task.name, { ...task.args, resources });
|
||||||
|
}
|
||||||
|
|
||||||
function calculateTimeToPushAfter(tasks: TaskList, predicate: (t: Task) => boolean, ts: number | undefined): number {
|
function calculateTimeToPushAfter(tasks: TaskList, predicate: (t: Task) => boolean, ts: number | undefined): number {
|
||||||
const normalizedTs = ts || timestamp();
|
const normalizedTs = ts || timestamp();
|
||||||
const queuedTaskIndex = findLastIndex(tasks, predicate);
|
const queuedTaskIndex = findLastIndex(tasks, predicate);
|
||||||
|
@ -107,7 +107,7 @@ export class TaskQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private flushItems(items: TaskList): void {
|
private flushItems(items: TaskList): void {
|
||||||
const normalized = items.sort((x, y) => x.ts - y.ts);
|
const normalized = items.sort((x, y) => x.ts - y.ts || x.id.localeCompare(y.id));
|
||||||
this.storage.set(QUEUE_NAME, normalized);
|
this.storage.set(QUEUE_NAME, normalized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
src/Task/UpdateResourceContracts.ts
Normal file
35
src/Task/UpdateResourceContracts.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Args, Command } from '../Common';
|
||||||
|
import { Task } from '../Storage/TaskQueue';
|
||||||
|
import { TaskController, registerTask } from './TaskController';
|
||||||
|
import { GoToPageAction } from '../Action/GoToPageAction';
|
||||||
|
import { path } from '../utils';
|
||||||
|
import { UpgradeBuildingTask } from './UpgradeBuildingTask';
|
||||||
|
import { UpdateBuildingTaskResourcesAction } from '../Action/UpdateBuildingTaskResourcesAction';
|
||||||
|
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
|
||||||
|
|
||||||
|
@registerTask
|
||||||
|
export class UpdateResourceContracts extends TaskController {
|
||||||
|
async run(task: Task) {
|
||||||
|
const args: Args = { ...task.args, taskId: task.id };
|
||||||
|
|
||||||
|
const actions: Array<Command> = [];
|
||||||
|
|
||||||
|
const tasks = this.scheduler.getTaskItems();
|
||||||
|
for (let task of tasks) {
|
||||||
|
const { villageId, buildId } = task.args;
|
||||||
|
if (task.name === UpgradeBuildingTask.name && villageId && buildId) {
|
||||||
|
actions.push(
|
||||||
|
new Command(GoToPageAction.name, {
|
||||||
|
...args,
|
||||||
|
path: path('/build.php', { newdid: villageId, id: buildId }),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
actions.push(new Command(UpdateBuildingTaskResourcesAction.name, { ...args, taskId: task.id }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.push(new Command(CompleteTaskAction.name, args));
|
||||||
|
|
||||||
|
this.scheduler.scheduleActions(actions);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user