Add troopers training
This commit is contained in:
		@@ -2,12 +2,15 @@ import { ResourcesInterface } from './Game';
 | 
			
		||||
import { TaskId } from './Queue/TaskQueue';
 | 
			
		||||
 | 
			
		||||
export interface Args {
 | 
			
		||||
    taskId?: TaskId;
 | 
			
		||||
    villageId?: number;
 | 
			
		||||
    buildId?: number;
 | 
			
		||||
    categoryId?: number;
 | 
			
		||||
    tabId?: number;
 | 
			
		||||
    buildTypeId?: number;
 | 
			
		||||
    troopId?: number;
 | 
			
		||||
    trainCount?: number;
 | 
			
		||||
    resources?: ResourcesInterface;
 | 
			
		||||
    taskId?: TaskId;
 | 
			
		||||
    [name: string]: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import { getNumber, parseLocation, uniqId, waitForLoad } from './utils';
 | 
			
		||||
import { elClassId, getNumber, parseLocation, uniqId, waitForLoad } from './utils';
 | 
			
		||||
import { Scheduler } from './Scheduler';
 | 
			
		||||
import { BuildPage } from './Page/BuildPage';
 | 
			
		||||
import { BuildingPageController } from './Page/BuildingPageController';
 | 
			
		||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
 | 
			
		||||
import { grabActiveVillageId, grabVillageList } from './Page/VillageBlock';
 | 
			
		||||
import {
 | 
			
		||||
@@ -127,7 +127,13 @@ export class ControlPanel {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (p.pathname === '/build.php') {
 | 
			
		||||
            new BuildPage(this.scheduler, getNumber(p.query.id), getNumber(p.query.category, 1)).run();
 | 
			
		||||
            const buildPage = new BuildingPageController(this.scheduler, {
 | 
			
		||||
                buildId: getNumber(p.query.id),
 | 
			
		||||
                buildTypeId: getNumber(elClassId(jQuery('#build').attr('class'), 'gid')),
 | 
			
		||||
                categoryId: getNumber(p.query.category, 1),
 | 
			
		||||
                tabId: getNumber(p.query.s, 0),
 | 
			
		||||
            });
 | 
			
		||||
            buildPage.run();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.createControlPanel(state);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/Game.ts
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/Game.ts
									
									
									
									
									
								
							@@ -42,10 +42,14 @@ export class Resources implements ResourcesInterface {
 | 
			
		||||
        this.crop = crop;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static fromObject(obj: ResourcesInterface) {
 | 
			
		||||
    static fromObject(obj: ResourcesInterface): Resources {
 | 
			
		||||
        return new Resources(obj.lumber, obj.clay, obj.iron, obj.crop);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static fromStorage(warehouse: number, granary: number): Resources {
 | 
			
		||||
        return new Resources(warehouse, warehouse, warehouse, granary);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getByType(type: ResourceType): number {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case ResourceType.Lumber:
 | 
			
		||||
@@ -66,6 +70,28 @@ export class Resources implements ResourcesInterface {
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    scale(n: number): Resources {
 | 
			
		||||
        return new Resources(this.lumber * n, this.clay * n, this.iron * n, this.crop * n);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add(other: Resources): Resources {
 | 
			
		||||
        return new Resources(
 | 
			
		||||
            this.lumber + other.lumber,
 | 
			
		||||
            this.clay + other.clay,
 | 
			
		||||
            this.iron + other.iron,
 | 
			
		||||
            this.crop + other.crop
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sub(other: Resources): Resources {
 | 
			
		||||
        return new Resources(
 | 
			
		||||
            this.lumber - other.lumber,
 | 
			
		||||
            this.clay - other.clay,
 | 
			
		||||
            this.iron - other.iron,
 | 
			
		||||
            this.crop - other.crop
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ResourceStorage {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
import { elClassId, notify, split, uniqId } from '../utils';
 | 
			
		||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
 | 
			
		||||
import { Scheduler } from '../Scheduler';
 | 
			
		||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
 | 
			
		||||
import { grabActiveVillageId } from './VillageBlock';
 | 
			
		||||
import { ConsoleLogger, Logger } from '../Logger';
 | 
			
		||||
import { createBuildButton, createUpgradeButton, grabContractResources } from './BuildingPage';
 | 
			
		||||
import { BuildBuildingTask } from '../Task/BuildBuildingTask';
 | 
			
		||||
 | 
			
		||||
const QUARTERS_ID = 19;
 | 
			
		||||
 | 
			
		||||
export class BuildPage {
 | 
			
		||||
    private scheduler: Scheduler;
 | 
			
		||||
    private readonly buildId: number;
 | 
			
		||||
    private readonly logger;
 | 
			
		||||
    private readonly categoryId: number;
 | 
			
		||||
 | 
			
		||||
    constructor(scheduler: Scheduler, buildId: number, categoryId: number) {
 | 
			
		||||
        this.scheduler = scheduler;
 | 
			
		||||
        this.buildId = buildId;
 | 
			
		||||
        this.categoryId = categoryId;
 | 
			
		||||
        this.logger = new ConsoleLogger(this.constructor.name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    run() {
 | 
			
		||||
        const buildTypeId = elClassId(jQuery('#build').attr('class') || '', 'gid');
 | 
			
		||||
        this.logger.log('BUILD PAGE DETECTED', 'ID', this.buildId, 'TYPE', buildTypeId);
 | 
			
		||||
 | 
			
		||||
        createBuildButton(buildTypeId => this.onScheduleBuildBuilding(buildTypeId));
 | 
			
		||||
        createUpgradeButton(() => this.onScheduleUpgradeBuilding());
 | 
			
		||||
 | 
			
		||||
        if (buildTypeId === QUARTERS_ID) {
 | 
			
		||||
            this.createTrainTroopButton();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onScheduleBuildBuilding(buildTypeId: number) {
 | 
			
		||||
        const buildId = this.buildId;
 | 
			
		||||
        const categoryId = this.categoryId;
 | 
			
		||||
        const villageId = grabActiveVillageId();
 | 
			
		||||
        const resources = grabContractResources();
 | 
			
		||||
        this.scheduler.scheduleTask(BuildBuildingTask.name, { villageId, buildId, categoryId, buildTypeId, resources });
 | 
			
		||||
        notify(`Building ${buildId} scheduled`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onScheduleUpgradeBuilding() {
 | 
			
		||||
        const buildId = this.buildId;
 | 
			
		||||
        const villageId = grabActiveVillageId();
 | 
			
		||||
        const resources = grabContractResources();
 | 
			
		||||
        this.scheduler.scheduleTask(UpgradeBuildingTask.name, { villageId, buildId, resources });
 | 
			
		||||
        notify(`Upgrading ${buildId} scheduled`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private createTrainTroopButton() {
 | 
			
		||||
        const troopBlocks = jQuery('#nonFavouriteTroops .action.troop:not(.empty) .innerTroopWrapper');
 | 
			
		||||
        troopBlocks.each((idx, el) => {
 | 
			
		||||
            const troopId = elClassId(jQuery(el).attr('class') || '', 'troop');
 | 
			
		||||
            this.logger.log('TROOP', troopId);
 | 
			
		||||
            if (troopId) {
 | 
			
		||||
                const id = uniqId();
 | 
			
		||||
                jQuery(el)
 | 
			
		||||
                    .find('.details')
 | 
			
		||||
                    .append(`<div style="padding: 8px 0"><a id="${id}" href="#">Обучить</a></div>`);
 | 
			
		||||
                jQuery(`#${id}`).on('click', evt => {
 | 
			
		||||
                    evt.preventDefault();
 | 
			
		||||
                    this.onTrainTroopClick(this.buildId, troopId, el);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onTrainTroopClick(buildId: number, troopId: number, el: HTMLElement) {
 | 
			
		||||
        this.logger.log('TRAIN TROOPERS', 'TROOP ID', troopId, 'BUILDING ID', buildId);
 | 
			
		||||
        const villageId = grabActiveVillageId();
 | 
			
		||||
        const input = jQuery(el).find(`input[name="t${troopId}"]`);
 | 
			
		||||
        const count = Number(input.val());
 | 
			
		||||
        if (!isNaN(count) && count > 0) {
 | 
			
		||||
            this.logger.log('PREPARE TO TRAIN', count, 'TROOPERS');
 | 
			
		||||
            for (let n of split(count)) {
 | 
			
		||||
                this.scheduler.scheduleTask(TrainTroopTask.name, {
 | 
			
		||||
                    villageId,
 | 
			
		||||
                    buildId,
 | 
			
		||||
                    troopId,
 | 
			
		||||
                    trainCount: n,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import { GrabError } from '../Errors';
 | 
			
		||||
import { getNumber, trimPrefix, uniqId } from '../utils';
 | 
			
		||||
import { elClassId, getNumber, split, trimPrefix, uniqId } from '../utils';
 | 
			
		||||
import { Resources } from '../Game';
 | 
			
		||||
import { grabActiveVillageId } from './VillageBlock';
 | 
			
		||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
 | 
			
		||||
 | 
			
		||||
export function clickBuildButton(typeId: number) {
 | 
			
		||||
    const section = jQuery(`#contract_building${typeId}`);
 | 
			
		||||
@@ -52,16 +54,47 @@ export function createUpgradeButton(onClickHandler: () => void) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function grabResourcesFromList($els) {
 | 
			
		||||
    const getText = n =>
 | 
			
		||||
        jQuery($els.get(n))
 | 
			
		||||
            .find('.value')
 | 
			
		||||
            .text();
 | 
			
		||||
    const grab = n => getNumber(getText(n));
 | 
			
		||||
    return new Resources(grab(0), grab(1), grab(2), grab(3));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function grabContractResources(): Resources {
 | 
			
		||||
    const $els = jQuery('#contract .resource');
 | 
			
		||||
    if ($els.length === 0) {
 | 
			
		||||
        throw new GrabError('No resource contract element');
 | 
			
		||||
    }
 | 
			
		||||
    const grab = n =>
 | 
			
		||||
        getNumber(
 | 
			
		||||
            jQuery($els.get(n))
 | 
			
		||||
                .find('.value')
 | 
			
		||||
                .text()
 | 
			
		||||
        );
 | 
			
		||||
    return new Resources(grab(0), grab(1), grab(2), grab(3));
 | 
			
		||||
    return grabResourcesFromList($els);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createTrainTroopButtons(
 | 
			
		||||
    onClickHandler: (troopId: number, resources: Resources, count: number) => void
 | 
			
		||||
) {
 | 
			
		||||
    const troopBlocks = jQuery('.action.troop:not(.empty) .innerTroopWrapper');
 | 
			
		||||
    if (troopBlocks.length === 0) {
 | 
			
		||||
        throw new GrabError('No troop blocks');
 | 
			
		||||
    }
 | 
			
		||||
    troopBlocks.each((idx, el) => {
 | 
			
		||||
        const $el = jQuery(el);
 | 
			
		||||
        const troopId = elClassId($el.attr('class'), 'troop');
 | 
			
		||||
        if (troopId === undefined) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const id = uniqId();
 | 
			
		||||
        $el.find('.details').append(`<div style="padding: 8px 0"><a id="${id}" href="#">Обучить</a></div>`);
 | 
			
		||||
        const resElement = $el.find('.resourceWrapper .resource');
 | 
			
		||||
        const resources = grabResourcesFromList(resElement);
 | 
			
		||||
        jQuery(`#${id}`).on('click', evt => {
 | 
			
		||||
            evt.preventDefault();
 | 
			
		||||
            const input = $el.find(`input[name="t${troopId}"]`);
 | 
			
		||||
            const count = getNumber(input.val());
 | 
			
		||||
            if (count > 0) {
 | 
			
		||||
                onClickHandler(troopId, resources, count);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								src/Page/BuildingPageController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/Page/BuildingPageController.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
import { elClassId, notify, split, uniqId } from '../utils';
 | 
			
		||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
 | 
			
		||||
import { Scheduler } from '../Scheduler';
 | 
			
		||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
 | 
			
		||||
import { grabActiveVillageId } from './VillageBlock';
 | 
			
		||||
import { ConsoleLogger, Logger } from '../Logger';
 | 
			
		||||
import { createBuildButton, createTrainTroopButtons, createUpgradeButton, grabContractResources } from './BuildingPage';
 | 
			
		||||
import { BuildBuildingTask } from '../Task/BuildBuildingTask';
 | 
			
		||||
import { Resources } from '../Game';
 | 
			
		||||
 | 
			
		||||
const QUARTERS_ID = 19;
 | 
			
		||||
const HORSE_STABLE_ID = 20;
 | 
			
		||||
const EMBASSY_ID = 25;
 | 
			
		||||
 | 
			
		||||
export interface BuildingPageAttributes {
 | 
			
		||||
    buildId: number;
 | 
			
		||||
    buildTypeId: number;
 | 
			
		||||
    categoryId: number;
 | 
			
		||||
    tabId: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BuildingPageController {
 | 
			
		||||
    private scheduler: Scheduler;
 | 
			
		||||
    private readonly attributes: BuildingPageAttributes;
 | 
			
		||||
    private readonly logger;
 | 
			
		||||
 | 
			
		||||
    constructor(scheduler: Scheduler, attributes: BuildingPageAttributes) {
 | 
			
		||||
        this.scheduler = scheduler;
 | 
			
		||||
        this.attributes = attributes;
 | 
			
		||||
        this.logger = new ConsoleLogger(this.constructor.name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    run() {
 | 
			
		||||
        const buildTypeId = this.attributes.buildTypeId;
 | 
			
		||||
        this.logger.log('BUILD PAGE DETECTED', 'ID', this.attributes.buildId, 'TYPE', buildTypeId);
 | 
			
		||||
 | 
			
		||||
        createBuildButton(buildTypeId => this.onScheduleBuildBuilding(buildTypeId));
 | 
			
		||||
        createUpgradeButton(() => this.onScheduleUpgradeBuilding());
 | 
			
		||||
 | 
			
		||||
        if (buildTypeId === QUARTERS_ID) {
 | 
			
		||||
            createTrainTroopButtons((troopId, res, count) => this.onScheduleTrainTroopers(troopId, res, count));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (buildTypeId === HORSE_STABLE_ID) {
 | 
			
		||||
            createTrainTroopButtons((troopId, res, count) => this.onScheduleTrainTroopers(troopId, res, count));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (buildTypeId === EMBASSY_ID && this.attributes.tabId === 1) {
 | 
			
		||||
            createTrainTroopButtons((troopId, res, count) => this.onScheduleTrainTroopers(troopId, res, count));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onScheduleBuildBuilding(buildTypeId: number) {
 | 
			
		||||
        const buildId = this.attributes.buildId;
 | 
			
		||||
        const categoryId = this.attributes.categoryId;
 | 
			
		||||
        const villageId = grabActiveVillageId();
 | 
			
		||||
        const resources = grabContractResources();
 | 
			
		||||
        this.scheduler.scheduleTask(BuildBuildingTask.name, { villageId, buildId, categoryId, buildTypeId, resources });
 | 
			
		||||
        notify(`Building ${buildId} scheduled`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onScheduleUpgradeBuilding() {
 | 
			
		||||
        const buildId = this.attributes.buildId;
 | 
			
		||||
        const villageId = grabActiveVillageId();
 | 
			
		||||
        const resources = grabContractResources();
 | 
			
		||||
        this.scheduler.scheduleTask(UpgradeBuildingTask.name, { villageId, buildId, resources });
 | 
			
		||||
        notify(`Upgrading ${buildId} scheduled`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onScheduleTrainTroopers(troopId: number, resources: Resources, count: number) {
 | 
			
		||||
        const tabId = this.attributes.tabId;
 | 
			
		||||
        for (let chunk of split(count)) {
 | 
			
		||||
            const args = {
 | 
			
		||||
                villageId: grabActiveVillageId(),
 | 
			
		||||
                buildId: this.attributes.buildId,
 | 
			
		||||
                buildTypeId: this.attributes.buildTypeId,
 | 
			
		||||
                tabId,
 | 
			
		||||
                troopId,
 | 
			
		||||
                resources: resources.scale(chunk),
 | 
			
		||||
                trainCount: chunk,
 | 
			
		||||
            };
 | 
			
		||||
            console.log('TRAIN TROOP', args);
 | 
			
		||||
            this.scheduler.scheduleTask(TrainTroopTask.name, args);
 | 
			
		||||
        }
 | 
			
		||||
        notify(`Training ${count} troopers scheduled`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -9,7 +9,7 @@ interface Slot {
 | 
			
		||||
function slotElements(prefix: string): Array<Slot> {
 | 
			
		||||
    const result: Array<Slot> = [];
 | 
			
		||||
    jQuery('.level.colorLayer').each((idx, el) => {
 | 
			
		||||
        const buildId = getNumber(elClassId(jQuery(el).attr('class') || '', prefix));
 | 
			
		||||
        const buildId = getNumber(elClassId(jQuery(el).attr('class'), prefix));
 | 
			
		||||
        result.push({ el, buildId });
 | 
			
		||||
    });
 | 
			
		||||
    return result;
 | 
			
		||||
@@ -58,7 +58,7 @@ export function onResourceSlotCtrlClick(cb: (buildId: number) => void): void {
 | 
			
		||||
 | 
			
		||||
function slotToDepositMapper(slot: Slot): ResourceDeposit {
 | 
			
		||||
    const el = slot.el;
 | 
			
		||||
    const classes = jQuery(el).attr('class') || '';
 | 
			
		||||
    const classes = jQuery(el).attr('class');
 | 
			
		||||
    const buildId = getNumber(elClassId(classes, 'buildingSlot'));
 | 
			
		||||
    const level = getNumber(elClassId(classes, 'level'));
 | 
			
		||||
    const type = getNumber(elClassId(classes, 'gid'));
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ export class Scheduler {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getVillageRequiredResources(villageId): ResourcesInterface | undefined {
 | 
			
		||||
        const tasks = this.taskQueue.seeItems().filter(t => isBuildingTask(t.name) && sameVillage(villageId, t.args));
 | 
			
		||||
        const tasks = this.taskQueue.seeItems().filter(t => sameVillage(villageId, t.args) && t.args.resources);
 | 
			
		||||
        const first = tasks.shift();
 | 
			
		||||
        if (first && first.args.resources) {
 | 
			
		||||
            return first.args.resources;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,18 @@ import { path } from '../utils';
 | 
			
		||||
export class TrainTroopTask extends TaskController {
 | 
			
		||||
    async run(task: Task) {
 | 
			
		||||
        const args: Args = { ...task.args, taskId: task.id };
 | 
			
		||||
 | 
			
		||||
        const pathArgs = {
 | 
			
		||||
            newdid: args.villageId,
 | 
			
		||||
            gid: args.buildTypeId || undefined,
 | 
			
		||||
            id: args.buildId || undefined,
 | 
			
		||||
            s: args.tabId,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const pagePath = path('/build.php', pathArgs);
 | 
			
		||||
 | 
			
		||||
        this.scheduler.scheduleActions([
 | 
			
		||||
            new Command(GoToPageAction.name, {
 | 
			
		||||
                ...args,
 | 
			
		||||
                path: path('/build.php', { newdid: args.villageId, id: args.buildId }),
 | 
			
		||||
            }),
 | 
			
		||||
            new Command(GoToPageAction.name, { ...args, path: pagePath }),
 | 
			
		||||
            new Command(TrainTrooperAction.name, args),
 | 
			
		||||
            new Command(CompleteTaskAction.name, args),
 | 
			
		||||
        ]);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								src/utils.ts
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/utils.ts
									
									
									
									
									
								
							@@ -53,23 +53,23 @@ export function trimPrefix(text: string, prefix: string): string {
 | 
			
		||||
    return text.startsWith(prefix) ? text.substr(prefix.length) : text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function elClassId(classes: string, prefix: string): number | undefined {
 | 
			
		||||
export function elClassId(classes: string | undefined, prefix: string): number | undefined {
 | 
			
		||||
    if (classes === undefined) {
 | 
			
		||||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
    let result: number | undefined = undefined;
 | 
			
		||||
    classes.split(/\s/).forEach(part => {
 | 
			
		||||
        if (part.startsWith(prefix)) {
 | 
			
		||||
            result = Number(part.substr(prefix.length));
 | 
			
		||||
            if (isNaN(result)) {
 | 
			
		||||
                result = undefined;
 | 
			
		||||
            }
 | 
			
		||||
            result = toNumber(part.substr(prefix.length));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function* split(n: number) {
 | 
			
		||||
export function* split(n: number, from: number = 2, to: number = 6) {
 | 
			
		||||
    let c = n;
 | 
			
		||||
    while (c > 0) {
 | 
			
		||||
        const next = 2 + Math.floor(Math.random() * 3);
 | 
			
		||||
        const next = from + Math.floor(Math.random() * (to - from));
 | 
			
		||||
        if (next < c) {
 | 
			
		||||
            yield next;
 | 
			
		||||
            c -= next;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user