Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackManager.js @@ -171,7 +171,7 @@ if (ent.getMetadata(PlayerID, "plan") !== undefined && ent.getMetadata(PlayerID, "plan") != -1) { let subrole = ent.getMetadata(PlayerID, "subrole"); - if (subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) + if (subrole && (subrole === PETRA.Worker.SUBROLE_COMPLETING || subrole === PETRA.Worker.SUBROLE_WALKING || subrole === PETRA.Worker.SUBROLE_ATTACKING)) continue; } let alreadyBombing = false; @@ -393,7 +393,7 @@ } // Check if we have some unused ranged siege unit which could do something useful while waiting - if (this.Config.difficulty > 1 && gameState.ai.playedTurn % 5 == 0) + if (this.Config.difficulty > PETRA.DIFFICULTY_VERY_EASY && gameState.ai.playedTurn % 5 == 0) this.assignBombers(gameState); }; @@ -734,7 +734,7 @@ if (unit && accessOk && attackPlan.isAvailableUnit(gameState, unit)) { unit.setMetadata(PlayerID, "plan", attackPlan.name); - unit.setMetadata(PlayerID, "role", "attack"); + unit.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_ATTACK); attackPlan.unitCollection.updateEnt(unit); } } @@ -745,7 +745,7 @@ return false; } for (let unit of attackPlan.unitCollection.values()) - unit.setMetadata(PlayerID, "role", "attack"); + unit.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_ATTACK); attackPlan.targetPlayer = target.owner(); attackPlan.targetPos = pos; attackPlan.target = target; Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js @@ -170,18 +170,18 @@ // Put some randomness on the attack size let variation = randFloat(0.8, 1.2); // and lower priority and smaller sizes for easier difficulty levels - if (this.Config.difficulty < 2) + if (this.Config.difficulty < PETRA.DIFFICULTY_EASY) { priority *= 0.4; variation *= 0.2; } - else if (this.Config.difficulty < 3) + else if (this.Config.difficulty < PETRA.DIFFICULTY_MEDIUM) { priority *= 0.8; variation *= 0.6; } - if (this.Config.difficulty < 2) + if (this.Config.difficulty < PETRA.DIFFICULTY_EASY) { for (const cat in this.unitStat) { @@ -422,7 +422,7 @@ this.siegeState = PETRA.AttackPlan.SIEGE_ADDED; let targetSize; - if (this.Config.difficulty < 3) + if (this.Config.difficulty < PETRA.DIFFICULTY_MEDIUM) targetSize = this.type === PETRA.AttackPlan.TYPE_HUGE_ATTACK ? Math.max(this.Config.difficulty, 1) : Math.max(this.Config.difficulty - 1, 0); else targetSize = this.type === PETRA.AttackPlan.TYPE_HUGE_ATTACK ? this.Config.difficulty + 1 : this.Config.difficulty - 1; @@ -586,8 +586,8 @@ ent.setMetadata(PlayerID, "plan", -1); continue; } - ent.setMetadata(PlayerID, "role", "attack"); - ent.setMetadata(PlayerID, "subrole", "completing"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_ATTACK); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_COMPLETING); let queued = false; if (ent.resourceCarrying() && ent.resourceCarrying().length) queued = PETRA.returnResources(gameState, ent); @@ -675,7 +675,7 @@ let max = firstOrder[3].batchSize; let specialData = "Plan_" + this.name + "_" + firstOrder[4]; let data = { "plan": this.name, "special": specialData, "base": 0 }; - data.role = gameState.getTemplate(template).hasClass("CitizenSoldier") ? "worker" : "attack"; + data.role = gameState.getTemplate(template).hasClass("CitizenSoldier") ? PETRA.Worker.ROLE_WORKER : PETRA.Worker.ROLE_ATTACK; let trainingPlan = new PETRA.TrainingPlan(gameState, template, data, max, max); if (trainingPlan.template) queue.addPlan(trainingPlan); @@ -746,7 +746,7 @@ // Finally add also some workers for the higher difficulties, // If Rush, assign all kind of workers, keeping only a minimum number of defenders // Otherwise, assign only some idle workers if too much of them - if (this.Config.difficulty <= 2) + if (this.Config.difficulty <= PETRA.DIFFICULTY_EASY) return added; let num = 0; @@ -754,7 +754,7 @@ let keep = this.type !== PETRA.AttackPlan.TYPE_RUSH ? 6 + 4 * gameState.getNumPlayerEnemies() + 8 * this.Config.personality.defensive : 8; keep = Math.round(this.Config.popScaling * keep); - for (const ent of gameState.getOwnEntitiesByRole("worker", true).values()) + for (const ent of gameState.getOwnEntitiesByRole(PETRA.Worker.ROLE_WORKER, true).values()) { if (!ent.hasClass("CitizenSoldier") || !this.isAvailableUnit(gameState, ent)) continue; @@ -769,7 +769,7 @@ } if (num++ < keep || numbase[baseID] < 5) continue; - if (this.type !== PETRA.AttackPlan.TYPE_RUSH && ent.getMetadata(PlayerID, "subrole") != "idle") + if (this.type !== PETRA.AttackPlan.TYPE_RUSH && ent.getMetadata(PlayerID, "subrole") !== PETRA.Worker.SUBROLE_IDLE) continue; ent.setMetadata(PlayerID, "plan", plan); this.unitCollection.updateEnt(ent); @@ -1256,7 +1256,7 @@ for (let ent of this.unitCollection.values()) { - ent.setMetadata(PlayerID, "subrole", "walking"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_WALKING); let stance = ent.isPackable() ? "standground" : "aggressive"; if (ent.getStance() != stance) ent.setStance(stance); @@ -1316,7 +1316,7 @@ this.startingAttack = true; this.unitCollection.forEach(ent => { ent.stopMoving(); - ent.setMetadata(PlayerID, "subrole", "attacking"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_ATTACKING); }); if (this.type === PETRA.AttackPlan.TYPE_RUSH) // try to find a better target for rush { @@ -2041,7 +2041,7 @@ for (let ent of this.unitCollection.values()) { - if (ent.getMetadata(PlayerID, "role") == "attack") + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_ATTACK) ent.stopMoving(); if (rallyPoint) ent.moveToRange(rallyPoint[0], rallyPoint[1], 0, 15); @@ -2057,10 +2057,10 @@ PETRA.AttackPlan.prototype.removeUnit = function(ent, update) { - if (ent.getMetadata(PlayerID, "role") == "attack") + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_ATTACK) { if (ent.hasClass("CitizenSoldier")) - ent.setMetadata(PlayerID, "role", "worker"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER); else ent.setMetadata(PlayerID, "role", undefined); ent.setMetadata(PlayerID, "subrole", undefined); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js @@ -27,7 +27,7 @@ this.constructing = false; // Defenders to train in this cc when its construction is finished - this.neededDefenders = this.Config.difficulty > 2 ? 3 + 2*(this.Config.difficulty - 3) : 0; + this.neededDefenders = this.Config.difficulty > PETRA.DIFFICULTY_EASY ? 3 + 2*(this.Config.difficulty - 3) : 0; // vector for iterating, to check one use the HQ map. this.territoryIndices = []; @@ -62,7 +62,7 @@ this.workerObject = new PETRA.Worker(this); // entitycollections this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); - this.workers = this.units.filter(API3.Filters.byMetadata(PlayerID, "role", "worker")); + this.workers = this.units.filter(API3.Filters.byMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER)); this.buildings = gameState.getOwnStructures().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); this.mobileDropsites = this.units.filter(API3.Filters.isDropsite()); @@ -88,8 +88,7 @@ this.constructing = true; else this.constructing = false; - - if (state !== PETRA.BaseManager.STATE_CAPTURED || this.Config.difficulty < 3) + if (state !== PETRA.BaseManager.STATE_CAPTURED || this.Config.difficulty < PETRA.DIFFICULTY_MEDIUM) this.neededDefenders = 0; else this.neededDefenders = 3 + 2 * (this.Config.difficulty - 3); @@ -510,14 +509,14 @@ }); if (res == "food") { - this.workersBySubrole(gameState, "hunter").forEach(ent => { + this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_HUNTER).forEach(ent => { if (ent.isIdle() || !ent.position()) return; let gRate = ent.currentGatherRate(); if (gRate) currentRates[res] += Math.log(1+gRate)/1.1; }); - this.workersBySubrole(gameState, "fisher").forEach(ent => { + this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_FISHER).forEach(ent => { if (ent.isIdle() || !ent.position()) return; let gRate = ent.currentGatherRate(); @@ -536,7 +535,7 @@ for (let ent of roleless) { if (ent.hasClasses(["Worker", "CitizenSoldier", "FishingBoat"])) - ent.setMetadata(PlayerID, "role", "worker"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER); } }; @@ -632,7 +631,7 @@ // Search for idle workers, and tell them to gather resources based on demand if (!idleWorkers) { - let filter = API3.Filters.byMetadata(PlayerID, "subrole", "idle"); + const filter = API3.Filters.byMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); idleWorkers = gameState.updatingCollection("idle-workers-base-" + this.ID, filter, this.workers).values(); } @@ -660,7 +659,7 @@ continue; if (needed.type != "food" && this.basesManager.isResourceExhausted(needed.type)) continue; - ent.setMetadata(PlayerID, "subrole", "gatherer"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_GATHERER); ent.setMetadata(PlayerID, "gather-type", needed.type); this.basesManager.AddTCResGatherer(needed.type); break; @@ -668,9 +667,9 @@ } } else if (PETRA.isFastMoving(ent) && ent.canGather("food") && ent.canAttackClass("Animal")) - ent.setMetadata(PlayerID, "subrole", "hunter"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_HUNTER); else if (ent.hasClass("FishingBoat")) - ent.setMetadata(PlayerID, "subrole", "fisher"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_FISHER); } }; @@ -681,7 +680,7 @@ PETRA.BaseManager.prototype.gatherersByType = function(gameState, type) { - return gameState.updatingCollection("workers-gathering-" + type +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "gather-type", type), this.workersBySubrole(gameState, "gatherer")); + return gameState.updatingCollection("workers-gathering-" + type +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "gather-type", type), this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_GATHERER)); }; /** @@ -702,13 +701,13 @@ availableWorkers.sort((a, b) => { let vala = 0; let valb = 0; - if (a.getMetadata(PlayerID, "subrole") == "builder") + if (a.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) vala = 100; - if (b.getMetadata(PlayerID, "subrole") == "builder") + if (b.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) valb = 100; - if (a.getMetadata(PlayerID, "subrole") == "idle") + if (a.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_IDLE) vala = -50; - if (b.getMetadata(PlayerID, "subrole") == "idle") + if (b.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_IDLE) valb = -50; if (a.getMetadata(PlayerID, "plan") === undefined) vala = -20; @@ -720,7 +719,7 @@ for (let i = 0; i < needed; ++i) { availableWorkers[i].stopMoving(); - availableWorkers[i].setMetadata(PlayerID, "subrole", "idle"); + availableWorkers[i].setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); workers.addEnt(availableWorkers[i]); } return; @@ -742,7 +741,7 @@ return; let workers = this.workers.filter(ent => ent.isBuilder()); - let builderWorkers = this.workersBySubrole(gameState, "builder"); + const builderWorkers = this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_BUILDER); let idleBuilderWorkers = builderWorkers.filter(API3.Filters.isIdle()); // if we're constructing and we have the foundations to our base anchor, only try building that. @@ -768,7 +767,7 @@ let baseID = this.ID; fromOtherBase.forEach(worker => { worker.setMetadata(PlayerID, "base", baseID); - worker.setMetadata(PlayerID, "subrole", "builder"); + worker.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); workers.updateEnt(worker); builderWorkers.updateEnt(worker); idleBuilderWorkers.updateEnt(worker); @@ -850,7 +849,7 @@ if (assigned >= targetNB || builderTot >= maxTotalBuilders) continue; let nonBuilderWorkers = workers.filter(function(ent) { - if (ent.getMetadata(PlayerID, "subrole") == "builder") + if (ent.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) return false; if (!ent.position()) return false; @@ -878,7 +877,7 @@ ++builderTot; let ent = nonBuilderWorkers[current++]; ent.stopMoving(); - ent.setMetadata(PlayerID, "subrole", "builder"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); ent.setMetadata(PlayerID, "target-foundation", target.id()); } } @@ -933,7 +932,7 @@ if (assigned >= targetNB || builderTot >= maxTotalBuilders) continue; let nonBuilderWorkers = workers.filter(function(ent) { - if (ent.getMetadata(PlayerID, "subrole") == "builder") + if (ent.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) return false; if (!ent.position()) return false; @@ -950,7 +949,7 @@ ++assigned; ++builderTot; ent.stopMoving(); - ent.setMetadata(PlayerID, "subrole", "builder"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); ent.setMetadata(PlayerID, "target-foundation", target.id()); }); } Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/basesManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/basesManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/basesManager.js @@ -175,7 +175,7 @@ { builders.forEach(worker => { worker.setMetadata(PlayerID, "base", newbase.ID); - worker.setMetadata(PlayerID, "subrole", "builder"); + worker.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); worker.setMetadata(PlayerID, "target-foundation", ent.id()); }); } @@ -189,7 +189,7 @@ { builders.forEach(worker => { worker.setMetadata(PlayerID, "base", newbase.ID); - worker.setMetadata(PlayerID, "subrole", "builder"); + worker.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); worker.setMetadata(PlayerID, "target-foundation", ent.id()); }); } @@ -275,7 +275,7 @@ continue; // Assign it immediately to something useful to do. - if (ent.getMetadata(PlayerID, "role") == "worker") + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_WORKER) { let base; if (ent.getMetadata(PlayerID, "base") === undefined) @@ -591,7 +591,7 @@ if (ent.position() && bestbase.ID !== this.noBase.ID) { bestbase.assignRolelessUnits(gameState, [ent]); - if (ent.getMetadata(PlayerID, "role") === "worker") + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_WORKER) { bestbase.reassignIdleWorkers(gameState, [ent]); bestbase.workerObject.update(gameState, ent); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/config.js @@ -1,7 +1,14 @@ -PETRA.Config = function(difficulty, behavior) +// These integers must be sequential +PETRA.DIFFICULTY_SANDBOX = 0; +PETRA.DIFFICULTY_VERY_EASY = 1; +PETRA.DIFFICULTY_EASY = 2; +PETRA.DIFFICULTY_MEDIUM = 3; +PETRA.DIFFICULTY_HARD = 4; +PETRA.DIFFICULTY_VERY_HARD = 5; + +PETRA.Config = function(difficulty = PETRA.DIFFICULTY_MEDIUM, behavior) { - // 0 is sandbox, 1 is very easy, 2 is easy, 3 is medium, 4 is hard and 5 is very hard. - this.difficulty = difficulty !== undefined ? difficulty : 3; + this.difficulty = difficulty; // for instance "balanced", "aggressive" or "defensive" this.behavior = behavior || "random"; @@ -169,7 +176,7 @@ PETRA.Config.prototype.setConfig = function(gameState) { - if (this.difficulty > 0) + if (this.difficulty > PETRA.DIFFICULTY_SANDBOX) { // Setup personality traits according to the user choice: // The parameter used to define the personality is basically the aggressivity or (1-defensiveness) @@ -212,14 +219,14 @@ this.Military.fortressLapseTime = Math.round(this.Military.fortressLapseTime * (1.1 - 0.2 * this.personality.defensive)); this.priorities.defenseBuilding = Math.round(this.priorities.defenseBuilding * (0.9 + 0.2 * this.personality.defensive)); - if (this.difficulty < 2) + if (this.difficulty < PETRA.DIFFICULTY_EASY) { this.popScaling = 0.5; this.Economy.supportRatio = 0.5; this.Economy.provisionFields = 1; this.Military.numSentryTowers = this.personality.defensive > this.personalityCut.strong ? 1 : 0; } - else if (this.difficulty < 3) + else if (this.difficulty < PETRA.DIFFICULTY_MEDIUM) { this.popScaling = 0.7; this.Economy.supportRatio = 0.4; @@ -228,7 +235,7 @@ } else { - if (this.difficulty == 3) + if (this.difficulty == PETRA.DIFFICULTY_MEDIUM) this.Military.numSentryTowers = 1; else this.Military.numSentryTowers = 2; @@ -246,9 +253,9 @@ } let maxPop = gameState.getPopulationMax(); - if (this.difficulty < 2) + if (this.difficulty < PETRA.DIFFICULTY_EASY) this.Economy.targetNumWorkers = Math.max(1, Math.min(40, maxPop)); - else if (this.difficulty < 3) + else if (this.difficulty < PETRA.DIFFICULTY_MEDIUM) this.Economy.targetNumWorkers = Math.max(1, Math.min(60, Math.floor(maxPop/2))); else this.Economy.targetNumWorkers = Math.max(1, Math.min(120, Math.floor(maxPop/3))); @@ -274,7 +281,7 @@ this.Economy.targetNumWorkers = Math.max(this.Economy.targetNumWorkers, this.Economy.popPhase2); this.Economy.workPhase3 = Math.min(this.Economy.workPhase3, this.Economy.targetNumWorkers); this.Economy.workPhase4 = Math.min(this.Economy.workPhase4, this.Economy.targetNumWorkers); - if (this.difficulty < 2) + if (this.difficulty < PETRA.DIFFICULTY_EASY) this.Economy.workPhase3 = Infinity; // prevent the phasing to city phase if (this.debug < 2) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseArmy.js @@ -119,9 +119,9 @@ else ent.setMetadata(PlayerID, "plan", -3); let subrole = ent.getMetadata(PlayerID, "subrole"); - if (subrole === undefined || subrole !== "defender") + if (subrole === undefined || subrole !== PETRA.Worker.SUBROLE_DEFENDER) ent.setMetadata(PlayerID, "formerSubrole", subrole); - ent.setMetadata(PlayerID, "subrole", "defender"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_DEFENDER); return true; }; @@ -159,11 +159,11 @@ ent.setMetadata(PlayerID, "subrole", undefined); ent.setMetadata(PlayerID, "formerSubrole", undefined); - // Remove from tranport plan if not yet on Board + // Remove from transport plan if not yet on Board if (ent.getMetadata(PlayerID, "transport") !== undefined) { let plan = gameState.ai.HQ.navalManager.getPlan(ent.getMetadata(PlayerID, "transport")); - if (plan && plan.state == "boarding" && ent.position()) + if (plan && plan.state === PETRA.TransportPlan.BOARDING && ent.position()) plan.removeUnit(gameState, ent); } Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/defenseManager.js @@ -429,7 +429,8 @@ if (ent.getMetadata(PlayerID, "plan") !== undefined && ent.getMetadata(PlayerID, "plan") != -1) { let subrole = ent.getMetadata(PlayerID, "subrole"); - if (subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) + if (subrole && + (subrole === PETRA.Worker.SUBROLE_COMPLETING || subrole === PETRA.Worker.SUBROLE_WALKING || subrole === PETRA.Worker.SUBROLE_ATTACKING)) return; } potentialDefenders.push(ent.id()); @@ -778,7 +779,8 @@ { let subrole = ent.getMetadata(PlayerID, "subrole"); // When structure decaying (usually because we've just captured it in enemy territory), also allow units from an attack plan. - if (typeGarrison !== PETRA.GarrisonManager.TYPE_DECAY && subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) + if (typeGarrison !== PETRA.GarrisonManager.TYPE_DECAY && subrole && + (subrole === PETRA.Worker.SUBROLE_COMPLETING || subrole === PETRA.Worker.SUBROLE_WALKING || subrole === PETRA.Worker.SUBROLE_ATTACKING)) return false; } if (PETRA.getLandAccess(gameState, ent) != access) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/garrisonManager.js @@ -250,7 +250,7 @@ ent.setMetadata(PlayerID, "plan", -2); else ent.setMetadata(PlayerID, "plan", -3); - ent.setMetadata(PlayerID, "subrole", "garrisoning"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_GARRISONING); ent.setMetadata(PlayerID, "garrisonHolder", holder.id()); ent.setMetadata(PlayerID, "garrisonType", type); ent.garrison(holder); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -151,13 +151,13 @@ ent.setMetadata(PlayerID, "PartOfArmy", undefined); if (ent.hasClass("Trader")) { - ent.setMetadata(PlayerID, "role", "trader"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER); ent.setMetadata(PlayerID, "route", undefined); } if (ent.hasClass("Worker")) { - ent.setMetadata(PlayerID, "role", "worker"); - ent.setMetadata(PlayerID, "subrole", "idle"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); } if (ent.hasClass("Ship")) PETRA.setSeaAccess(gameState, ent); @@ -233,7 +233,7 @@ } // Then deals with decaying structures: destroy them if being lost to enemy (except in easier difficulties) - if (this.Config.difficulty < 2) + if (this.Config.difficulty < PETRA.DIFFICULTY_EASY) return; for (let entId of this.decayingStructures) { @@ -378,7 +378,7 @@ let numberOfWorkers = 0; // all workers let numberOfSupports = 0; // only support workers (i.e. non fighting) gameState.getOwnUnits().forEach(ent => { - if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") === undefined) + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_WORKER && ent.getMetadata(PlayerID, "plan") === undefined) { ++numberOfWorkers; if (ent.hasClass("Support")) @@ -390,7 +390,7 @@ for (let item of ent.trainingQueue()) { numberInTraining += item.count; - if (item.metadata && item.metadata.role && item.metadata.role == "worker" && + if (item.metadata && item.metadata.role && item.metadata.role === PETRA.Worker.ROLE_WORKER && item.metadata.plan === undefined) { numberOfWorkers += item.count; @@ -467,9 +467,9 @@ // If the template variable is empty, the default unit (Support unit) will be used // base "0" means automatic choice of base if (!template && templateDef) - queues.villager.addPlan(new PETRA.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0, "support": true }, size, size)); + queues.villager.addPlan(new PETRA.TrainingPlan(gameState, templateDef, { "role": PETRA.Worker.ROLE_WORKER, "base": 0, "support": true }, size, size)); else if (template) - queues.citizenSoldier.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size)); + queues.citizenSoldier.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": PETRA.Worker.ROLE_WORKER, "base": 0 }, size, size)); }; /** picks the best template based on parameters and classes */ @@ -1867,7 +1867,7 @@ break; } } - let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() }; + const metadata = { "role": PETRA.Worker.ROLE_WORKER, "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() }; if (autogarrison) metadata.garrisonType = PETRA.GarrisonManager.TYPE_PROTECTION; gameState.ai.queues.emergency.addPlan(new PETRA.TrainingPlan(gameState, templateFound[0], metadata, 1, 1)); @@ -2154,12 +2154,12 @@ { if (this.turnCache.accountedWorkers == undefined) { - let workers = gameState.getOwnEntitiesByRole("worker", true).length; + let workers = gameState.getOwnEntitiesByRole(PETRA.Worker.ROLE_WORKER, true).length; for (let ent of gameState.getOwnTrainingFacilities().values()) { for (let item of ent.trainingQueue()) { - if (!item.metadata || !item.metadata.role || item.metadata.role != "worker") + if (!item.metadata || !item.metadata.role || item.metadata.role !== PETRA.Worker.ROLE_WORKER) continue; workers += item.count; } @@ -2273,7 +2273,7 @@ if (gameState.ai.playedTurn % 3 == 0) { this.constructTrainingBuildings(gameState, queues); - if (this.Config.difficulty > 0) + if (this.Config.difficulty > PETRA.DIFFICULTY_SANDBOX) this.buildDefenses(gameState, queues); } @@ -2281,7 +2281,7 @@ this.navalManager.update(gameState, queues, events); - if (this.Config.difficulty > 0 && (this.hasActiveBase() || !this.canBuildUnits)) + if (this.Config.difficulty > PETRA.DIFFICULTY_SANDBOX && (this.hasActiveBase() || !this.canBuildUnits)) this.attackManager.update(gameState, queues, events); this.diplomacyManager.update(gameState, events); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -38,7 +38,7 @@ this.docks = gameState.getOwnStructures().filter(API3.Filters.byClasses(["Dock", "Shipyard"])); this.docks.registerUpdates(); - this.ships = gameState.getOwnUnits().filter(API3.Filters.and(API3.Filters.byClass("Ship"), API3.Filters.not(API3.Filters.byMetadata(PlayerID, "role", "trader")))); + this.ships = gameState.getOwnUnits().filter(API3.Filters.and(API3.Filters.byClass("Ship"), API3.Filters.not(API3.Filters.byMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER)))); // note: those two can overlap (some transport ships are warships too and vice-versa). this.transportShips = this.ships.filter(API3.Filters.and(API3.Filters.byCanGarrison(), API3.Filters.not(API3.Filters.byClass("FishingBoat")))); this.warShips = this.ships.filter(API3.Filters.byClass("Warship")); @@ -285,7 +285,7 @@ let shipId = evt.entityObj.id(); if (this.Config.debug > 1) API3.warn("one ship " + shipId + " from plan " + plan.ID + " destroyed during " + plan.state); - if (plan.state == "boarding") + if (plan.state === PETRA.TransportPlan.BOARDING) { // just reset the units onBoard metadata and wait for a new ship to be assigned to this plan plan.units.forEach(ent => { @@ -295,7 +295,7 @@ }); plan.needTransportShips = !plan.transportShips.hasEntities(); } - else if (plan.state == "sailing") + else if (plan.state === PETRA.TransportPlan.SAILING) { let endIndex = plan.endIndex; for (let ent of plan.units.values()) @@ -361,7 +361,7 @@ let plans = []; for (let plan of this.transportPlans) { - if (plan.startIndex != startIndex || plan.endIndex != endIndex || plan.state != "boarding") + if (plan.startIndex != startIndex || plan.endIndex != endIndex || plan.state !== PETRA.TransportPlan.BOARDING) continue; // Limit the number of siege units per transport to avoid problems when ungarrisoning if (PETRA.isSiegeUnit(ent) && plan.units.filter(unit => PETRA.isSiegeUnit(unit)).length > 3) @@ -514,7 +514,7 @@ let template = this.getBestShip(gameState, sea, "fishing"); if (template) { - queues.ships.addPlan(new PETRA.TrainingPlan(gameState, template, { "base": 0, "role": "worker", "sea": sea }, 1, 1)); + queues.ships.addPlan(new PETRA.TrainingPlan(gameState, template, { "base": 0, "role": PETRA.Worker.ROLE_WORKER, "sea": sea }, 1, 1)); continue; } } @@ -613,7 +613,7 @@ if (!shipPosition) continue; let role = ship.getMetadata(PlayerID, "role"); - if (!role || role != "trader") // already accounted before + if (role === undefined || role !== PETRA.Worker.ROLE_TRADER) // already accounted before continue; let unitAIState = ship.unitAIState(); @@ -691,7 +691,7 @@ if (blockedIds.indexOf(blockingShip.id()) != -1 || !blockingShip.position()) continue; let role = blockingShip.getMetadata(PlayerID, "role"); - if (!role || role != "trader") // already accounted before + if (role === undefined || role !== PETRA.Worker.ROLE_TRADER) // already accounted before continue; let distSquare = API3.SquareVectorDistance(shipPosition, blockingShip.position()); let unitAIState = blockingShip.unitAIState(); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueManager.js @@ -158,7 +158,7 @@ { let numWorkers = 0; gameState.getOwnUnits().forEach(ent => { - if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") === undefined) + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_WORKER && ent.getMetadata(PlayerID, "plan") === undefined) numWorkers++; }); API3.warn("---------- QUEUES ------------ with pop " + gameState.getPopulation() + " and workers " + numWorkers); @@ -414,7 +414,7 @@ // Recovery system: if short of workers after an attack, pause (and reset) some queues to favor worker training PETRA.QueueManager.prototype.checkPausedQueues = function(gameState) { - let numWorkers = gameState.countOwnEntitiesAndQueuedWithRole("worker"); + const numWorkers = gameState.countOwnEntitiesAndQueuedWithRole(PETRA.Worker.ROLE_WORKER); let workersMin = Math.min(Math.max(12, 24 * this.Config.popScaling), this.Config.Economy.popPhase2); for (let q in this.queues) { Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanTraining.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanTraining.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanTraining.js @@ -79,7 +79,7 @@ let wantedIndex; if (this.metadata && this.metadata.index) wantedIndex = this.metadata.index; - let workerUnit = this.metadata && this.metadata.role && this.metadata.role == "worker"; + const workerUnit = this.metadata && this.metadata.role && this.metadata.role === PETRA.Worker.ROLE_WORKER; let supportUnit = this.template.hasClass("Support"); this.trainers.sort(function(a, b) { // Prefer training buildings with short queues Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/researchManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/researchManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/researchManager.js @@ -79,7 +79,7 @@ { let phase1 = gameState.currentPhase() === 1; let available = phase1 ? gameState.ai.queueManager.getAvailableResources(gameState) : null; - let numWorkers = phase1 ? gameState.getOwnEntitiesByRole("worker", true).length : 0; + const numWorkers = phase1 ? gameState.getOwnEntitiesByRole(PETRA.Worker.ROLE_WORKER, true).length : 0; for (let tech of techs) { if (tech[0].indexOf("unlock_champion") == 0) @@ -123,7 +123,7 @@ { let phase2 = gameState.currentPhase() === 2; let available = phase2 ? gameState.ai.queueManager.getAvailableResources(gameState) : null; - let numWorkers = phase2 ? gameState.getOwnEntitiesByRole("worker", true).length : 0; + const numWorkers = phase2 ? gameState.getOwnEntitiesByRole(PETRA.Worker.ROLE_WORKER, true).length : 0; for (let tech of techs) { if (!tech[1]._template.modifications) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js @@ -27,7 +27,7 @@ // Sandbox difficulty should not try to expand - this.canExpand = this.Config.difficulty != 0; + this.canExpand = this.Config.difficulty != PETRA.DIFFICULTY_SANDBOX; // If no base yet, check if we can construct one. If not, dispatch our units to possible tasks/attacks this.canBuildUnits = true; if (!gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).hasEntities()) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/tradeManager.js @@ -13,7 +13,7 @@ PETRA.TradeManager.prototype.init = function(gameState) { - this.traders = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "role", "trader")); + this.traders = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER)); this.traders.registerUpdates(); this.minimalGain = gameState.ai.HQ.navalMap ? 3 : 5; }; @@ -25,7 +25,7 @@ PETRA.TradeManager.prototype.assignTrader = function(ent) { - ent.setMetadata(PlayerID, "role", "trader"); + ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER); this.traders.updateEnt(ent); }; @@ -41,7 +41,7 @@ gameState.getOwnTrainingFacilities().forEach(function(ent) { for (let item of ent.trainingQueue()) { - if (!item.metadata || !item.metadata.role || item.metadata.role != "trader") + if (!item.metadata || !item.metadata.role || item.metadata.role !== PETRA.Worker.ROLE_TRADER) continue; numTraders += item.count; if (item.metadata.sea !== undefined) @@ -56,7 +56,7 @@ return; let template; - let metadata = { "role": "trader" }; + const metadata = { "role": PETRA.Worker.ROLE_TRADER }; if (this.tradeRoute.sea) { // if we have some merchand ships assigned to transport, try first to reassign them @@ -67,7 +67,7 @@ gameState.ai.HQ.navalManager.seaTransportShips[this.tradeRoute.sea].forEach(function(ship) { if (already || !ship.hasClass("Trader")) return; - if (ship.getMetadata(PlayerID, "role") == "switchToTrader") + if (ship.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_SWITCH_TO_TRADER) { already = true; return; @@ -79,9 +79,9 @@ if (shipToSwitch) { if (shipToSwitch.getMetadata(PlayerID, "transporter") === undefined) - shipToSwitch.setMetadata(PlayerID, "role", "trader"); + shipToSwitch.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER); else - shipToSwitch.setMetadata(PlayerID, "role", "switchToTrader"); + shipToSwitch.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_SWITCH_TO_TRADER); return; } @@ -645,7 +645,7 @@ if (gameState.ai.HQ.canBarter && Resources.GetBarterableCodes().length) this.performBarter(gameState); - if (this.Config.difficulty <= 1) + if (this.Config.difficulty <= PETRA.DIFFICULTY_VERY_EASY) return; if (this.checkEvents(gameState, events)) // true if one market was built or destroyed Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/transportPlan.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/transportPlan.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/transportPlan.js @@ -67,13 +67,22 @@ API3.warn("Starting a new transport plan with ID " + this.ID + " to index " + endIndex + " with units length " + units.length); - this.state = "boarding"; + this.state = PETRA.TransportPlan.BOARDING; this.boardingPos = {}; this.needTransportShips = ship === undefined; this.nTry = {}; return true; }; +/** + * We're trying to board units onto our ships. + */ +PETRA.TransportPlan.BOARDING = "boarding"; +/** + * We're moving ships and eventually unload units. + */ +PETRA.TransportPlan.SAILING = "sailing"; + PETRA.TransportPlan.prototype.init = function(gameState) { this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "transport", this.ID)); @@ -117,7 +126,7 @@ ent.setMetadata(PlayerID, "onBoard", ship.id()); if (this.debug > 1) { - if (ent.getMetadata(PlayerID, "role") == "attack") + if (ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_ATTACK) Engine.PostCommand(PlayerID, { "type": "set-shading-color", "entities": [ent.id()], "rgb": [2, 0, 0] }); else Engine.PostCommand(PlayerID, { "type": "set-shading-color", "entities": [ent.id()], "rgb": [0, 2, 0] }); @@ -223,8 +232,8 @@ ship.setStance(defaultStance); ship.setMetadata(PlayerID, "transporter", undefined); - if (ship.getMetadata(PlayerID, "role") == "switchToTrader") - ship.setMetadata(PlayerID, "role", "trader"); + if (ship.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_SWITCH_TO_TRADER) + ship.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_TRADER); }; PETRA.TransportPlan.prototype.releaseAll = function() @@ -273,17 +282,13 @@ /** - * try to move on. There are two states: - * - "boarding" means we're trying to board units onto our ships - * - "sailing" means we're moving ships and eventually unload units - * - then the plan is cleared + * Try to move on and then clear the plan. */ - PETRA.TransportPlan.prototype.update = function(gameState) { - if (this.state == "boarding") + if (this.state === PETRA.TransportPlan.BOARDING) this.onBoarding(gameState); - else if (this.state == "sailing") + else if (this.state === PETRA.TransportPlan.SAILING) this.onSailing(gameState); return this.units.length; @@ -422,7 +427,7 @@ this.boardingPos[ship.id()] = this.getBoardingPos(gameState, ship, this.endIndex, this.sea, this.endPos, true); ship.move(this.boardingPos[ship.id()][0], this.boardingPos[ship.id()][1]); } - this.state = "sailing"; + this.state = PETRA.TransportPlan.SAILING; this.nTry = {}; this.unloaded = []; this.recovered = []; Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/victoryManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/victoryManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/victoryManager.js @@ -78,7 +78,7 @@ for (let worker of builders.values()) { worker.setMetadata(PlayerID, "base", base.ID); - worker.setMetadata(PlayerID, "subrole", "builder"); + worker.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); worker.setMetadata(PlayerID, "target-foundation", ent.id()); } } @@ -141,7 +141,7 @@ for (let entId of evt.entities) { let ent = gameState.getEntityById(entId); - if (ent && ent.isOwn(PlayerID) && ent.getMetadata(PlayerID, "role") == "criticalEntHealer") + if (ent && ent.isOwn(PlayerID) && ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_CRITICAL_ENT_HEALER) this.assignGuardToCriticalEnt(gameState, ent); } @@ -253,8 +253,8 @@ continue; // If this ent travelled to a criticalEnt's accessValue, try again to assign as a guard - if ((ent.getMetadata(PlayerID, "role") == "criticalEntHealer" || - ent.getMetadata(PlayerID, "role") == "criticalEntGuard") && !this.guardEnts.get(evt.entity)) + if ((ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_CRITICAL_ENT_HEALER || + ent.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_CRITICAL_ENT_GUARD) && !this.guardEnts.get(evt.entity)) { this.assignGuardToCriticalEnt(gameState, ent, ent.getMetadata(PlayerID, "guardedEnt")); continue; @@ -342,7 +342,7 @@ if (data.healersAssigned === undefined || data.healersAssigned >= this.healersPerCriticalEnt) continue; let template = gameState.applyCiv("units/{civ}/support_healer_b"); - queues.healer.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": "criticalEntHealer", "base": 0 }, 1, 1)); + queues.healer.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": PETRA.Worker.ROLE_CRITICAL_ENT_HEALER, "base": 0 }, 1, 1)); return; } }; @@ -354,7 +354,7 @@ */ PETRA.VictoryManager.prototype.manageCriticalEntGuards = function(gameState) { - let numWorkers = gameState.getOwnEntitiesByRole("worker", true).length; + let numWorkers = gameState.getOwnEntitiesByRole(PETRA.Worker.ROLE_WORKER, true).length; if (numWorkers < 20) { for (let data of this.criticalEnts.values()) @@ -363,7 +363,7 @@ { let guardEnt = gameState.getEntityById(guardId); if (!guardEnt || !guardEnt.hasClass("CitizenSoldier") || - guardEnt.getMetadata(PlayerID, "role") != "criticalEntGuard") + guardEnt.getMetadata(PlayerID, "role") !== PETRA.Worker.ROLE_CRITICAL_ENT_GUARD) continue; guardEnt.removeGuard(); @@ -451,7 +451,7 @@ return false; guardEnt.setMetadata(PlayerID, "plan", -2); - guardEnt.setMetadata(PlayerID, "role", "criticalEntGuard"); + guardEnt.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_CRITICAL_ENT_GUARD); return true; }; @@ -547,7 +547,7 @@ { let queued = PETRA.returnResources(gameState, guardEnt); guardEnt.guard(criticalEnt, queued); - let guardRole = guardEnt.getMetadata(PlayerID, "role") == "criticalEntHealer" ? "healer" : "guard"; + const guardRole = guardEnt.getMetadata(PlayerID, "role") === PETRA.Worker.ROLE_CRITICAL_ENT_HEALER ? "healer" : "guard"; this.criticalEnts.get(criticalEntId).guards.set(guardEnt.id(), guardRole); // Switch this guard ent to the criticalEnt's base Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js @@ -8,6 +8,24 @@ this.baseID = base.ID; }; +PETRA.Worker.ROLE_ATTACK = "attack"; +PETRA.Worker.ROLE_TRADER = "trader"; +PETRA.Worker.ROLE_SWITCH_TO_TRADER = "switchToTrader"; +PETRA.Worker.ROLE_WORKER = "worker"; +PETRA.Worker.ROLE_CRITICAL_ENT_GUARD = "criticalEntGuard"; +PETRA.Worker.ROLE_CRITICAL_ENT_HEALER = "criticalEntHealer"; + +PETRA.Worker.SUBROLE_DEFENDER = "defender"; +PETRA.Worker.SUBROLE_IDLE = "idle"; +PETRA.Worker.SUBROLE_BUILDER = "builder"; +PETRA.Worker.SUBROLE_COMPLETING = "completing"; +PETRA.Worker.SUBROLE_WALKING = "walking"; +PETRA.Worker.SUBROLE_ATTACKING = "attacking"; +PETRA.Worker.SUBROLE_GATHERER = "gatherer"; +PETRA.Worker.SUBROLE_HUNTER = "hunter"; +PETRA.Worker.SUBROLE_FISHER = "fisher"; +PETRA.Worker.SUBROLE_GARRISONING = "garrisoning"; + PETRA.Worker.prototype.update = function(gameState, ent) { if (!ent.position() || ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) @@ -19,18 +37,18 @@ if (ent.getMetadata(PlayerID, "transport") !== undefined) { // Except if builder with their foundation destroyed, in which case cancel the transport if not yet on board - if (subrole == "builder" && ent.getMetadata(PlayerID, "target-foundation") !== undefined) + if (subrole === PETRA.Worker.SUBROLE_BUILDER && ent.getMetadata(PlayerID, "target-foundation") !== undefined) { let plan = gameState.ai.HQ.navalManager.getPlan(ent.getMetadata(PlayerID, "transport")); let target = gameState.getEntityById(ent.getMetadata(PlayerID, "target-foundation")); - if (!target && plan && plan.state == "boarding" && ent.position()) + if (!target && plan && plan.state === PETRA.TransportPlan.BOARDING && ent.position()) plan.removeUnit(gameState, ent); } // and gatherer if there are no more dropsite accessible in the base the ent is going to - if (subrole == "gatherer" || subrole == "hunter") + if (subrole === PETRA.Worker.SUBROLE_GATHERER || subrole === PETRA.Worker.SUBROLE_HUNTER) { let plan = gameState.ai.HQ.navalManager.getPlan(ent.getMetadata(PlayerID, "transport")); - if (plan.state == "boarding" && ent.position()) + if (plan.state === PETRA.TransportPlan.BOARDING && ent.position()) { let hasDropsite = false; let gatherType = ent.getMetadata(PlayerID, "gather-type") || "food"; @@ -72,9 +90,9 @@ else this.baseAccess = this.base.accessIndex; - if (!subrole) // subrole may-be undefined after a transport, garrisoning, army, ... + if (subrole == undefined) // subrole may-be undefined after a transport, garrisoning, army, ... { - ent.setMetadata(PlayerID, "subrole", "idle"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); this.base.reassignIdleWorkers(gameState, [ent]); this.update(gameState, ent); return; @@ -83,7 +101,7 @@ this.ent = ent; let unitAIState = ent.unitAIState(); - if ((subrole == "hunter" || subrole == "gatherer") && + if ((subrole === PETRA.Worker.SUBROLE_HUNTER || subrole === PETRA.Worker.SUBROLE_GATHERER) && (unitAIState == "INDIVIDUAL.GATHER.GATHERING" || unitAIState == "INDIVIDUAL.GATHER.APPROACHING" || unitAIState == "INDIVIDUAL.COMBAT.APPROACHING")) { @@ -156,7 +174,7 @@ // Also, if we are attacking, do not capture if (unitAIStateOrder == "COMBAT") { - if (subrole == "fisher") + if (subrole === PETRA.Worker.SUBROLE_FISHER) this.startFishing(gameState); else if (unitAIState == "INDIVIDUAL.COMBAT.APPROACHING" && ent.unitAIOrderData().length && !ent.getMetadata(PlayerID, "PartOfArmy")) @@ -193,7 +211,7 @@ // If we're gathering, we'll check that we haven't run idle. // And we'll also check that we're gathering a resource we want to gather. - if (subrole == "gatherer") + if (subrole === PETRA.Worker.SUBROLE_GATHERER) { if (ent.isIdle()) { @@ -290,7 +308,7 @@ } } } - else if (subrole == "builder") + else if (subrole === PETRA.Worker.SUBROLE_BUILDER) { if (unitAIStateOrder == "REPAIR") { @@ -307,7 +325,7 @@ return; } ent.setMetadata(PlayerID, "target-foundation", undefined); - ent.setMetadata(PlayerID, "subrole", "idle"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); ent.stopMoving(); if (this.baseID != gameState.ai.HQ.basesManager.baselessBase().ID) { @@ -328,7 +346,7 @@ let target = gameState.getEntityById(ent.getMetadata(PlayerID, "target-foundation")); if (!target || target.foundationProgress() === undefined && target.needsRepair() === false) { - ent.setMetadata(PlayerID, "subrole", "idle"); + ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); ent.setMetadata(PlayerID, "target-foundation", undefined); if (this.baseID != gameState.ai.HQ.basesManager.baselessBase().ID) { @@ -348,7 +366,7 @@ gameState.ai.HQ.navalManager.requireTransport(gameState, ent, this.entAccess, goalAccess, target.position()); } } - else if (subrole == "hunter") + else if (subrole === PETRA.Worker.SUBROLE_HUNTER) { let lastHuntSearch = ent.getMetadata(PlayerID, "lastHuntSearch"); if (ent.isIdle() && (!lastHuntSearch || gameState.ai.elapsedTime - lastHuntSearch > 20)) @@ -395,7 +413,7 @@ } } } - else if (subrole == "fisher") + else if (subrole === PETRA.Worker.SUBROLE_FISHER) { if (ent.isIdle()) this.startFishing(gameState); @@ -412,13 +430,13 @@ { switch (subrole) { - case "gatherer": + case PETRA.Worker.SUBROLE_GATHERER: return this.startGathering(gameState); - case "hunter": + case PETRA.Worker.SUBROLE_HUNTER: return this.startHunting(gameState); - case "fisher": + case PETRA.Worker.SUBROLE_FISHER: return this.startFishing(gameState); - case "builder": + case PETRA.Worker.SUBROLE_BUILDER: return this.startBuilding(gameState); default: return false; @@ -587,7 +605,7 @@ if (foundation.getMetadata(PlayerID, "base") != this.baseID) this.ent.setMetadata(PlayerID, "base", foundation.getMetadata(PlayerID, "base")); this.ent.setMetadata(PlayerID, "target-foundation", foundation.id()); - this.ent.setMetadata(PlayerID, "subrole", "builder"); + this.ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); this.ent.repair(foundation); return true; } @@ -657,7 +675,7 @@ if (foundation.getMetadata(PlayerID, "base") != this.baseID) this.ent.setMetadata(PlayerID, "base", foundation.getMetadata(PlayerID, "base")); this.ent.setMetadata(PlayerID, "target-foundation", foundation.id()); - this.ent.setMetadata(PlayerID, "subrole", "builder"); + this.ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); return true; } } @@ -720,7 +738,7 @@ gameState.ai.HQ.lastFailedGather[resource] = gameState.ai.elapsedTime; if (gameState.ai.Config.debug > 2) API3.warn(" >>>>> worker with gather-type " + resource + " with nothing to gather "); - this.ent.setMetadata(PlayerID, "subrole", "idle"); + this.ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); return false; }; @@ -925,8 +943,8 @@ this.ent.setMetadata(PlayerID, "target-foundation", undefined); return true; } - if (this.ent.getMetadata(PlayerID, "subrole") == "fisher") - this.ent.setMetadata(PlayerID, "subrole", "idle"); + if (this.ent.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_FISHER) + this.ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); return false; }; @@ -1006,7 +1024,7 @@ return; if (!forced && gameState.ai.elapsedTime < (ent.getMetadata(PlayerID, "nextMoveToGatherer") || 5)) return; - let gatherers = this.base.workersBySubrole(gameState, "gatherer"); + const gatherers = this.base.workersBySubrole(gameState, PETRA.Worker.SUBROLE_GATHERER); let dist = Math.min(); let destination; let access = PETRA.getLandAccess(gameState, ent);