Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/_petrabot.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/_petrabot.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/_petrabot.js @@ -1,9 +1,8 @@ Engine.IncludeModule("common-api"); -var PETRA = (function() { -var m = {}; +var PETRA = {}; -m.PetraBot = function PetraBot(settings) +PETRA.PetraBot = function(settings) { API3.BaseAI.call(this, settings); @@ -17,14 +16,14 @@ "transports": 1 // transport plans start at 1 because 0 might be used as none }; - this.Config = new m.Config(settings.difficulty, settings.behavior); + this.Config = new PETRA.Config(settings.difficulty, settings.behavior); this.savedEvents = {}; }; -m.PetraBot.prototype = new API3.BaseAI(); +PETRA.PetraBot.prototype = new API3.BaseAI(); -m.PetraBot.prototype.CustomInit = function(gameState) +PETRA.PetraBot.prototype.CustomInit = function(gameState) { if (this.isDeserialized) { @@ -52,11 +51,11 @@ this.Config.Deserialize(this.data.config); - this.queueManager = new m.QueueManager(this.Config, {}); + this.queueManager = new PETRA.QueueManager(this.Config, {}); this.queueManager.Deserialize(gameState, this.data.queueManager); this.queues = this.queueManager.queues; - this.HQ = new m.HQ(this.Config); + this.HQ = new PETRA.HQ(this.Config); this.HQ.init(gameState, this.queues); this.HQ.Deserialize(gameState, this.data.HQ); @@ -74,11 +73,11 @@ // this.queues can only be modified by the queue manager or things will go awry. this.queues = {}; for (let i in this.Config.priorities) - this.queues[i] = new m.Queue(); + this.queues[i] = new PETRA.Queue(); - this.queueManager = new m.QueueManager(this.Config, this.queues); + this.queueManager = new PETRA.QueueManager(this.Config, this.queues); - this.HQ = new m.HQ(this.Config); + this.HQ = new PETRA.HQ(this.Config); this.HQ.init(gameState, this.queues); @@ -87,7 +86,7 @@ } }; -m.PetraBot.prototype.OnUpdate = function(sharedScript) +PETRA.PetraBot.prototype.OnUpdate = function(sharedScript) { if (this.gameFinished) return; @@ -129,7 +128,7 @@ this.turn++; }; -m.PetraBot.prototype.Serialize = function() +PETRA.PetraBot.prototype.Serialize = function() { let savedEvents = {}; for (let key in this.savedEvents) @@ -160,11 +159,8 @@ }; }; -m.PetraBot.prototype.Deserialize = function(data, sharedScript) +PETRA.PetraBot.prototype.Deserialize = function(data, sharedScript) { this.isDeserialized = true; this.data = data; }; - -return m; -}()); 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 @@ -1,9 +1,7 @@ -var PETRA = function(m) -{ - -/** Attack Manager */ - -m.AttackManager = function(Config) +/** + * Attack Manager + */ +PETRA.AttackManager = function(Config) { this.Config = Config; @@ -22,13 +20,13 @@ }; /** More initialisation for stuff that needs the gameState */ -m.AttackManager.prototype.init = function(gameState) +PETRA.AttackManager.prototype.init = function(gameState) { this.outOfPlan = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "plan", -1)); this.outOfPlan.registerUpdates(); }; -m.AttackManager.prototype.setRushes = function(allowed) +PETRA.AttackManager.prototype.setRushes = function(allowed) { if (this.Config.personality.aggressive > this.Config.personalityCut.strong && allowed > 2) { @@ -47,7 +45,7 @@ } }; -m.AttackManager.prototype.checkEvents = function(gameState, events) +PETRA.AttackManager.prototype.checkEvents = function(gameState, events) { for (let evt of events.PlayerDefeated) this.defeated[evt.playerId] = true; @@ -102,7 +100,7 @@ break; // take only the first attack request into account } if (targetPlayer !== undefined) - m.chatAnswerRequestAttack(gameState, targetPlayer, answer, other); + PETRA.chatAnswerRequestAttack(gameState, targetPlayer, answer, other); for (let evt of events.EntityRenamed) // take care of packing units in bombing attacks { @@ -125,7 +123,7 @@ /** * Check for any structure in range from within our territory, and bomb it */ -m.AttackManager.prototype.assignBombers = function(gameState) +PETRA.AttackManager.prototype.assignBombers = function(gameState) { // First some cleaning of current bombing attacks for (let [targetId, unitIds] of this.bombingAttacks) @@ -179,7 +177,7 @@ let range = ent.attackRange("Ranged").max; let entPos = ent.position(); - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); for (let struct of gameState.getEnemyStructures().values()) { let structPos = struct.position(); @@ -234,7 +232,7 @@ * Some functions are run every turn * Others once in a while */ -m.AttackManager.prototype.update = function(gameState, queues, events) +PETRA.AttackManager.prototype.update = function(gameState, queues, events) { if (this.Config.debug > 2 && gameState.ai.elapsedTime > this.debugTime + 60) { @@ -285,7 +283,7 @@ if (this.Config.debug > 1) API3.warn("Attack Manager: Starting " + attack.getType() + " plan " + attack.getName()); if (this.Config.chat) - m.chatLaunchAttack(gameState, attack.targetPlayer, attack.getType()); + PETRA.chatLaunchAttack(gameState, attack.targetPlayer, attack.getType()); this.startedAttacks[attackType].push(attack); } else @@ -324,7 +322,7 @@ { // we have a barracks and we want to rush, rush. let data = { "targetSize": this.rushSize[this.rushNumber] }; - let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Rush", data); + let attackPlan = new PETRA.AttackPlan(gameState, this.Config, this.totalNumber, "Rush", data); if (!attackPlan.failed) { if (this.Config.debug > 1) @@ -344,7 +342,7 @@ !gameState.ai.HQ.baseManagers[1]) // if we have no base ... nothing else to do than attack { let type = this.attackNumber < 2 || this.startedAttacks.HugeAttack.length > 0 ? "Attack" : "HugeAttack"; - let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, type); + let attackPlan = new PETRA.AttackPlan(gameState, this.Config, this.totalNumber, type); if (attackPlan.failed) this.attackPlansEncounteredWater = true; // hack else @@ -380,7 +378,7 @@ this.assignBombers(gameState); }; -m.AttackManager.prototype.getPlan = function(planName) +PETRA.AttackManager.prototype.getPlan = function(planName) { for (let attackType in this.upcomingAttacks) { @@ -397,21 +395,21 @@ return undefined; }; -m.AttackManager.prototype.pausePlan = function(planName) +PETRA.AttackManager.prototype.pausePlan = function(planName) { let attack = this.getPlan(planName); if (attack) attack.setPaused(true); }; -m.AttackManager.prototype.unpausePlan = function(planName) +PETRA.AttackManager.prototype.unpausePlan = function(planName) { let attack = this.getPlan(planName); if (attack) attack.setPaused(false); }; -m.AttackManager.prototype.pauseAllPlans = function() +PETRA.AttackManager.prototype.pauseAllPlans = function() { for (let attackType in this.upcomingAttacks) for (let attack of this.upcomingAttacks[attackType]) @@ -422,7 +420,7 @@ attack.setPaused(true); }; -m.AttackManager.prototype.unpauseAllPlans = function() +PETRA.AttackManager.prototype.unpauseAllPlans = function() { for (let attackType in this.upcomingAttacks) for (let attack of this.upcomingAttacks[attackType]) @@ -433,7 +431,7 @@ attack.setPaused(false); }; -m.AttackManager.prototype.getAttackInPreparation = function(type) +PETRA.AttackManager.prototype.getAttackInPreparation = function(type) { return this.upcomingAttacks[type].length ? this.upcomingAttacks[type][0] : undefined; }; @@ -443,7 +441,7 @@ * attack.targetPlayer is undefined and in that case, we keep track of the chosen target * for future attacks. */ -m.AttackManager.prototype.getEnemyPlayer = function(gameState, attack) +PETRA.AttackManager.prototype.getEnemyPlayer = function(gameState, attack) { let enemyPlayer; @@ -499,14 +497,14 @@ if (ourcc.owner() != PlayerID) continue; let ourPos = ourcc.position(); - let access = m.getLandAccess(gameState, ourcc); + let access = PETRA.getLandAccess(gameState, ourcc); for (let enemycc of ccEnts.values()) { if (veto[enemycc.owner()]) continue; if (!gameState.isPlayerEnemy(enemycc.owner())) continue; - if (access != m.getLandAccess(gameState, enemycc)) + if (access != PETRA.getLandAccess(gameState, enemycc)) continue; let dist = API3.SquareVectorDistance(ourPos, enemycc.position()); if (distmin && dist > distmin) @@ -557,7 +555,7 @@ * Target the player with the most advanced wonder. * TODO currently the first built wonder is kept, should chek on the minimum wonderDuration left instead. */ -m.AttackManager.prototype.getWonderEnemyPlayer = function(gameState, attack) +PETRA.AttackManager.prototype.getWonderEnemyPlayer = function(gameState, attack) { let enemyPlayer; let enemyWonder; @@ -589,7 +587,7 @@ /** * Target the player with the most relics (including gaia). */ -m.AttackManager.prototype.getRelicEnemyPlayer = function(gameState, attack) +PETRA.AttackManager.prototype.getRelicEnemyPlayer = function(gameState, attack) { let enemyPlayer; let allRelics = gameState.updatingGlobalCollection("allRelics", API3.Filters.byClass("Relic")); @@ -617,7 +615,7 @@ }; /** f.e. if we have changed diplomacy with another player. */ -m.AttackManager.prototype.cancelAttacksAgainstPlayer = function(gameState, player) +PETRA.AttackManager.prototype.cancelAttacksAgainstPlayer = function(gameState, player) { for (let attackType in this.upcomingAttacks) for (let attack of this.upcomingAttacks[attackType]) @@ -636,10 +634,10 @@ } }; -m.AttackManager.prototype.raidTargetEntity = function(gameState, ent) +PETRA.AttackManager.prototype.raidTargetEntity = function(gameState, ent) { let data = { "target": ent }; - let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Raid", data); + let attackPlan = new PETRA.AttackPlan(gameState, this.Config, this.totalNumber, "Raid", data); if (attackPlan.failed) return null; if (this.Config.debug > 1) @@ -654,7 +652,7 @@ /** * Return the number of units from any of our attacking armies around this position */ -m.AttackManager.prototype.numAttackingUnitsAround = function(pos, dist) +PETRA.AttackManager.prototype.numAttackingUnitsAround = function(pos, dist) { let num = 0; for (let attackType in this.startedAttacks) @@ -674,7 +672,7 @@ * data.armyID: transform only the defense army ID into a new attack * data.uniqueTarget: the attack will stop when the target is destroyed or captured */ -m.AttackManager.prototype.switchDefenseToAttack = function(gameState, target, data) +PETRA.AttackManager.prototype.switchDefenseToAttack = function(gameState, target, data) { if (!target || !target.position()) return false; @@ -686,14 +684,14 @@ let attackData = data.uniqueTarget ? { "uniqueTargetId": target.id() } : undefined; let pos = target.position(); let attackType = "Attack"; - let attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, attackType, attackData); + let attackPlan = new PETRA.AttackPlan(gameState, this.Config, this.totalNumber, attackType, attackData); if (attackPlan.failed) return false; this.totalNumber++; attackPlan.init(gameState); this.startedAttacks[attackType].push(attackPlan); - let targetAccess = m.getLandAccess(gameState, target); + let targetAccess = PETRA.getLandAccess(gameState, target); for (let army of gameState.ai.HQ.defenseManager.armies) { if (data.range) @@ -713,7 +711,7 @@ army.removeOwn(gameState, unitId); let unit = gameState.getEntityById(unitId); let accessOk = unit.getMetadata(PlayerID, "transport") !== undefined || - unit.position() && m.getLandAccess(gameState, unit) == targetAccess; + unit.position() && PETRA.getLandAccess(gameState, unit) == targetAccess; if (unit && accessOk && attackPlan.isAvailableUnit(gameState, unit)) { unit.setMetadata(PlayerID, "plan", attackPlan.name); @@ -736,7 +734,7 @@ return true; }; -m.AttackManager.prototype.Serialize = function() +PETRA.AttackManager.prototype.Serialize = function() { let properties = { "totalNumber": this.totalNumber, @@ -769,7 +767,7 @@ return { "properties": properties, "upcomingAttacks": upcomingAttacks, "startedAttacks": startedAttacks }; }; -m.AttackManager.prototype.Deserialize = function(gameState, data) +PETRA.AttackManager.prototype.Deserialize = function(gameState, data) { for (let key in data.properties) this[key] = data.properties[key]; @@ -780,7 +778,7 @@ this.upcomingAttacks[key] = []; for (let dataAttack of data.upcomingAttacks[key]) { - let attack = new m.AttackPlan(gameState, this.Config, dataAttack.properties.name); + let attack = new PETRA.AttackPlan(gameState, this.Config, dataAttack.properties.name); attack.Deserialize(gameState, dataAttack); attack.init(gameState); this.upcomingAttacks[key].push(attack); @@ -793,13 +791,10 @@ this.startedAttacks[key] = []; for (let dataAttack of data.startedAttacks[key]) { - let attack = new m.AttackPlan(gameState, this.Config, dataAttack.properties.name); + let attack = new PETRA.AttackPlan(gameState, this.Config, dataAttack.properties.name); attack.Deserialize(gameState, dataAttack); attack.init(gameState); this.startedAttacks[key].push(attack); } } }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * This is an attack plan: * It deals with everything in an attack, from picking a target to picking a path to it @@ -8,7 +5,7 @@ * It also handles the actual attack, though much work is needed on that. */ -m.AttackPlan = function(gameState, Config, uniqueID, type, data) +PETRA.AttackPlan = function(gameState, Config, uniqueID, type, data) { this.Config = Config; this.name = uniqueID; @@ -39,7 +36,7 @@ { if (!base.anchor || !base.anchor.position()) continue; - let access = m.getLandAccess(gameState, base.anchor); + let access = PETRA.getLandAccess(gameState, base.anchor); if (!rallyPoint) { rallyPoint = base.anchor.position(); @@ -54,7 +51,7 @@ { if (!ent.position()) continue; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); rallyPoint = ent.position(); rallyAccess = access; allAccesses[access] = rallyPoint; @@ -76,7 +73,7 @@ continue; if (!structure.position()) continue; - let access = m.getLandAccess(gameState, structure); + let access = PETRA.getLandAccess(gameState, structure); if (access in allAccesses) { this.overseas = 0; @@ -217,7 +214,7 @@ return true; }; -m.AttackPlan.prototype.init = function(gameState) +PETRA.AttackPlan.prototype.init = function(gameState) { this.queue = gameState.ai.queues["plan_" + this.name]; this.queueChamp = gameState.ai.queues["plan_" + this.name +"_champ"]; @@ -240,27 +237,27 @@ } }; -m.AttackPlan.prototype.getName = function() +PETRA.AttackPlan.prototype.getName = function() { return this.name; }; -m.AttackPlan.prototype.getType = function() +PETRA.AttackPlan.prototype.getType = function() { return this.type; }; -m.AttackPlan.prototype.isStarted = function() +PETRA.AttackPlan.prototype.isStarted = function() { return this.state !== "unexecuted" && this.state !== "completing"; }; -m.AttackPlan.prototype.isPaused = function() +PETRA.AttackPlan.prototype.isPaused = function() { return this.paused; }; -m.AttackPlan.prototype.setPaused = function(boolValue) +PETRA.AttackPlan.prototype.setPaused = function(boolValue) { this.paused = boolValue; }; @@ -269,7 +266,7 @@ * Returns true if the attack can be executed at the current time * Basically it checks we have enough units. */ -m.AttackPlan.prototype.canStart = function() +PETRA.AttackPlan.prototype.canStart = function() { if (!this.canBuildUnits) return true; @@ -281,7 +278,7 @@ return true; }; -m.AttackPlan.prototype.mustStart = function() +PETRA.AttackPlan.prototype.mustStart = function() { if (this.isPaused()) return false; @@ -311,7 +308,7 @@ return false; }; -m.AttackPlan.prototype.forceStart = function() +PETRA.AttackPlan.prototype.forceStart = function() { for (let unitCat in this.unitStat) { @@ -323,7 +320,7 @@ }; /** Adds a build order. If resetQueue is true, this will reset the queue. */ -m.AttackPlan.prototype.addBuildOrder = function(gameState, name, unitStats, resetQueue) +PETRA.AttackPlan.prototype.addBuildOrder = function(gameState, name, unitStats, resetQueue) { if (!this.isStarted()) { @@ -342,7 +339,7 @@ } }; -m.AttackPlan.prototype.addSiegeUnits = function(gameState) +PETRA.AttackPlan.prototype.addSiegeUnits = function(gameState) { if (this.siegeState == 2 || this.state !== "unexecuted") return false; @@ -394,7 +391,7 @@ }; /** Three returns possible: 1 is "keep going", 0 is "failed plan", 2 is "start". */ -m.AttackPlan.prototype.updatePreparation = function(gameState) +PETRA.AttackPlan.prototype.updatePreparation = function(gameState) { // the completing step is used to return resources and regroup the units // so we check that we have no more forced order before starting the attack @@ -550,8 +547,8 @@ ent.setMetadata(PlayerID, "subrole", "completing"); let queued = false; if (ent.resourceCarrying() && ent.resourceCarrying().length) - queued = m.returnResources(gameState, ent); - let index = m.getLandAccess(gameState, ent); + queued = PETRA.returnResources(gameState, ent); + let index = PETRA.getLandAccess(gameState, ent); if (index == rallyIndex) ent.moveToRange(rallyPoint[0], rallyPoint[1], 0, 15, queued); else @@ -567,7 +564,7 @@ }; -m.AttackPlan.prototype.trainMoreUnits = function(gameState) +PETRA.AttackPlan.prototype.trainMoreUnits = function(gameState) { // let's sort by training advancement, ie 'current size / target size' // count the number of queued units too. @@ -641,7 +638,7 @@ 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"; - let trainingPlan = new m.TrainingPlan(gameState, template, data, max, max); + let trainingPlan = new PETRA.TrainingPlan(gameState, template, data, max, max); if (trainingPlan.template) queue.addPlan(trainingPlan); else if (this.Config.debug > 1) @@ -652,7 +649,7 @@ } }; -m.AttackPlan.prototype.assignUnits = function(gameState) +PETRA.AttackPlan.prototype.assignUnits = function(gameState) { let plan = this.name; let added = false; @@ -726,7 +723,7 @@ else { API3.warn("Petra problem ent without base "); - m.dumpEntity(ent); + PETRA.dumpEntity(ent); continue; } if (num++ < keep || numbase[baseID] < 5) @@ -740,7 +737,7 @@ return added; }; -m.AttackPlan.prototype.isAvailableUnit = function(gameState, ent) +PETRA.AttackPlan.prototype.isAvailableUnit = function(gameState, ent) { if (!ent.position()) return false; @@ -753,7 +750,7 @@ }; /** Reassign one (at each turn) Cav unit to fasten raid preparation. */ -m.AttackPlan.prototype.reassignCavUnit = function(gameState) +PETRA.AttackPlan.prototype.reassignCavUnit = function(gameState) { for (let ent of this.unitCollection.values()) { @@ -769,7 +766,7 @@ } }; -m.AttackPlan.prototype.chooseTarget = function(gameState) +PETRA.AttackPlan.prototype.chooseTarget = function(gameState) { if (this.targetPlayer === undefined) { @@ -794,7 +791,7 @@ this.targetPos = this.target.position(); // redefine a new rally point for this target if we have a base on the same land // find a new one on the pseudo-nearest base (dist weighted by the size of the island) - let targetIndex = m.getLandAccess(gameState, this.target); + let targetIndex = PETRA.getLandAccess(gameState, this.target); let rallyIndex = gameState.ai.accessibility.getAccessValue(this.rallyPoint); if (targetIndex != rallyIndex) { @@ -856,7 +853,7 @@ /** * sameLand true means that we look for a target for which we do not need to take a transport */ -m.AttackPlan.prototype.getNearestTarget = function(gameState, position, sameLand) +PETRA.AttackPlan.prototype.getNearestTarget = function(gameState, position, sameLand) { this.isBlocked = false; // Temporary variables needed by isValidTarget @@ -928,7 +925,7 @@ * Default target finder aims for conquest critical targets * We must apply the *same* selection (isValidTarget) as done in getNearestTarget */ -m.AttackPlan.prototype.defaultTargetFinder = function(gameState, playerEnemy) +PETRA.AttackPlan.prototype.defaultTargetFinder = function(gameState, playerEnemy) { let targets = new API3.EntityCollection(gameState.sharedScript); if (gameState.getVictoryConditions().has("wonder")) @@ -961,17 +958,17 @@ return targets; }; -m.AttackPlan.prototype.isValidTarget = function(ent) +PETRA.AttackPlan.prototype.isValidTarget = function(ent) { if (!ent.position()) return false; - if (this.sameLand && m.getLandAccess(this.gameState, ent) != this.sameLand) + if (this.sameLand && PETRA.getLandAccess(this.gameState, ent) != this.sameLand) return false; return !ent.decaying() || ent.getDefaultArrow() || ent.isGarrisonHolder() && ent.garrisoned().length; }; /** Rush target finder aims at isolated non-defended buildings */ -m.AttackPlan.prototype.rushTargetFinder = function(gameState, playerEnemy) +PETRA.AttackPlan.prototype.rushTargetFinder = function(gameState, playerEnemy) { let targets = new API3.EntityCollection(gameState.sharedScript); let buildings; @@ -1027,7 +1024,7 @@ }; /** Raid target finder aims at destructing foundations from which our defenseManager has attacked the builders */ -m.AttackPlan.prototype.raidTargetFinder = function(gameState) +PETRA.AttackPlan.prototype.raidTargetFinder = function(gameState) { let targets = new API3.EntityCollection(gameState.sharedScript); for (let targetId of gameState.ai.HQ.defenseManager.targetList) @@ -1044,9 +1041,9 @@ * otherwise we may be blocked by walls and try to react accordingly * This is done only when attacker and target are on the same land */ -m.AttackPlan.prototype.checkTargetObstruction = function(gameState, target, position) +PETRA.AttackPlan.prototype.checkTargetObstruction = function(gameState, target, position) { - if (m.getLandAccess(gameState, target) != gameState.ai.accessibility.getAccessValue(position)) + if (PETRA.getLandAccess(gameState, target) != gameState.ai.accessibility.getAccessValue(position)) return target; let targetPos = target.position(); @@ -1159,10 +1156,10 @@ return target; }; -m.AttackPlan.prototype.getPathToTarget = function(gameState, fixedRallyPoint = false) +PETRA.AttackPlan.prototype.getPathToTarget = function(gameState, fixedRallyPoint = false) { let startAccess = gameState.ai.accessibility.getAccessValue(this.rallyPoint); - let endAccess = m.getLandAccess(gameState, this.target); + let endAccess = PETRA.getLandAccess(gameState, this.target); if (startAccess != endAccess) return false; @@ -1185,7 +1182,7 @@ }; /** Set rally point at the border of our territory */ -m.AttackPlan.prototype.setRallyPoint = function(gameState) +PETRA.AttackPlan.prototype.setRallyPoint = function(gameState) { for (let i = 0; i < this.path.length; ++i) { @@ -1212,7 +1209,7 @@ * Executes the attack plan, after this is executed the update function will be run every turn * If we're here, it's because we have enough units. */ -m.AttackPlan.prototype.StartAttack = function(gameState) +PETRA.AttackPlan.prototype.StartAttack = function(gameState) { if (this.Config.debug > 1) API3.warn("start attack " + this.name + " with type " + this.type); @@ -1236,7 +1233,7 @@ } let rallyAccess = gameState.ai.accessibility.getAccessValue(this.rallyPoint); - let targetAccess = m.getLandAccess(gameState, this.target); + let targetAccess = PETRA.getLandAccess(gameState, this.target); if (rallyAccess == targetAccess) { if (!this.path) @@ -1262,7 +1259,7 @@ }; /** Runs every turn after the attack is executed */ -m.AttackPlan.prototype.update = function(gameState, events) +PETRA.AttackPlan.prototype.update = function(gameState, events) { if (!this.unitCollection.hasEntities()) return 0; @@ -1327,20 +1324,20 @@ attackedByStructure[evt.target] = true; continue; } - if (m.isSiegeUnit(ourUnit)) + if (PETRA.isSiegeUnit(ourUnit)) { // if our siege units are attacked, we'll send some units to deal with enemies. let collec = this.unitCollection.filter(API3.Filters.not(API3.Filters.byClass("Siege"))).filterNearest(ourUnit.position(), 5); for (let ent of collec.values()) { - if (m.isSiegeUnit(ent)) // needed as mauryan elephants are not filtered out + if (PETRA.isSiegeUnit(ent)) // needed as mauryan elephants are not filtered out continue; - ent.attack(attacker.id(), m.allowCapture(gameState, ent, attacker)); + ent.attack(attacker.id(), PETRA.allowCapture(gameState, ent, attacker)); ent.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); } // And if this attacker is a non-ranged siege unit and our unit also, attack it - if (m.isSiegeUnit(attacker) && attacker.hasClass("Melee") && ourUnit.hasClass("Melee")) + if (PETRA.isSiegeUnit(attacker) && attacker.hasClass("Melee") && ourUnit.hasClass("Melee")) { - ourUnit.attack(attacker.id(), m.allowCapture(gameState, ourUnit, attacker)); + ourUnit.attack(attacker.id(), PETRA.allowCapture(gameState, ourUnit, attacker)); ourUnit.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); } } @@ -1352,12 +1349,12 @@ // TODO check that the attacker is from behind the wall continue; } - else if (m.isSiegeUnit(attacker)) + else if (PETRA.isSiegeUnit(attacker)) { // if our unit is attacked by a siege unit, we'll send some melee units to help it. let collec = this.unitCollection.filter(API3.Filters.byClass("Melee")).filterNearest(ourUnit.position(), 5); for (let ent of collec.values()) { - ent.attack(attacker.id(), m.allowCapture(gameState, ent, attacker)); + ent.attack(attacker.id(), PETRA.allowCapture(gameState, ent, attacker)); ent.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); } } @@ -1367,7 +1364,7 @@ let collec = this.unitCollection.filterNearest(ourUnit.position(), 2); for (let ent of collec.values()) { - if (m.isSiegeUnit(ent)) + if (PETRA.isSiegeUnit(ent)) continue; let orderData = ent.unitAIOrderData(); if (orderData && orderData.length && orderData[0].target) @@ -1378,7 +1375,7 @@ if (target && !target.hasClass("Structure") && !target.hasClass("Support")) continue; } - ent.attack(attacker.id(), m.allowCapture(gameState, ent, attacker)); + ent.attack(attacker.id(), PETRA.allowCapture(gameState, ent, attacker)); ent.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); } // Then the unit under attack: abandon its target (if it was a structure or a support) and retaliate @@ -1395,7 +1392,7 @@ continue; } } - ourUnit.attack(attacker.id(), m.allowCapture(gameState, ourUnit, attacker)); + ourUnit.attack(attacker.id(), PETRA.allowCapture(gameState, ourUnit, attacker)); ourUnit.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); } } @@ -1419,7 +1416,7 @@ continue; if (!(targetId in unitTargets)) { - if (m.isSiegeUnit(target) || target.hasClass("Hero")) + if (PETRA.isSiegeUnit(target) || target.hasClass("Hero")) unitTargets[targetId] = -8; else if (target.hasClass("Champion") || target.hasClass("Ship")) unitTargets[targetId] = -5; @@ -1480,7 +1477,7 @@ // update the order if needed let needsUpdate = false; let maybeUpdate = false; - let siegeUnit = m.isSiegeUnit(ent); + let siegeUnit = PETRA.isSiegeUnit(ent); if (ent.isIdle()) needsUpdate = true; else if (siegeUnit && targetId) @@ -1542,7 +1539,7 @@ else if (ent.hasClass("Cavalry")) range += 30; range = range * range; - let entAccess = m.getLandAccess(gameState, ent); + let entAccess = PETRA.getLandAccess(gameState, ent); // Checking for gates if we're a siege unit. if (siegeUnit) { @@ -1553,7 +1550,7 @@ return false; if (enemy.foundationProgress() == 0) return false; - if (m.getLandAccess(gameState, enemy) != entAccess) + if (PETRA.getLandAccess(gameState, enemy) != entAccess) return false; return true; }).toEntityArray(); @@ -1577,11 +1574,11 @@ return valb - vala; }); if (mStruct[0].hasClass("Gates")) - ent.attack(mStruct[0].id(), m.allowCapture(gameState, ent, mStruct[0])); + ent.attack(mStruct[0].id(), PETRA.allowCapture(gameState, ent, mStruct[0])); else { let rand = randIntExclusive(0, mStruct.length * 0.2); - ent.attack(mStruct[rand].id(), m.allowCapture(gameState, ent, mStruct[rand])); + ent.attack(mStruct[rand].id(), PETRA.allowCapture(gameState, ent, mStruct[rand])); } } else @@ -1608,7 +1605,7 @@ let dist = API3.SquareVectorDistance(enemy.position(), ent.position()); if (dist > range) return false; - if (m.getLandAccess(gameState, enemy) != entAccess) + if (PETRA.getLandAccess(gameState, enemy) != entAccess) return false; // if already too much units targeting this enemy, let's continue towards our main target if (veto[enemy.id()] && API3.SquareVectorDistance(this.targetPos, ent.position()) > 2500) @@ -1639,7 +1636,7 @@ return valb - vala; }); let rand = randIntExclusive(0, mUnit.length * 0.1); - ent.attack(mUnit[rand].id(), m.allowCapture(gameState, ent, mUnit[rand])); + ent.attack(mUnit[rand].id(), PETRA.allowCapture(gameState, ent, mUnit[rand])); } else if (this.isBlocked) ent.attack(this.target.id(), false); @@ -1666,7 +1663,7 @@ return false; if (API3.SquareVectorDistance(enemy.position(), ent.position()) > range) return false; - if (m.getLandAccess(gameState, enemy) != entAccess) + if (PETRA.getLandAccess(gameState, enemy) != entAccess) return false; return true; }, this).toEntityArray(); @@ -1690,7 +1687,7 @@ else { let rand = randIntExclusive(0, mStruct.length * 0.2); - ent.attack(mStruct[rand].id(), m.allowCapture(gameState, ent, mStruct[rand])); + ent.attack(mStruct[rand].id(), PETRA.allowCapture(gameState, ent, mStruct[rand])); } } else if (needsUpdate) // really nothing let's try to help our nearest unit @@ -1712,7 +1709,7 @@ attacker = gameState.getEntityById(unit.unitAIOrderData()[0].target); }); if (attacker) - ent.attack(attacker.id(), m.allowCapture(gameState, ent, attacker)); + ent.attack(attacker.id(), PETRA.allowCapture(gameState, ent, attacker)); } } } @@ -1730,7 +1727,7 @@ return this.unitCollection.length; }; -m.AttackPlan.prototype.UpdateTransporting = function(gameState, events) +PETRA.AttackPlan.prototype.UpdateTransporting = function(gameState, events) { let done = true; for (let ent of this.unitCollection.values()) @@ -1765,13 +1762,13 @@ continue; if (!ent.isIdle()) continue; - ent.attack(attacker.id(), m.allowCapture(gameState, ent, attacker)); + ent.attack(attacker.id(), PETRA.allowCapture(gameState, ent, attacker)); } break; } }; -m.AttackPlan.prototype.UpdateWalking = function(gameState, events) +PETRA.AttackPlan.prototype.UpdateWalking = function(gameState, events) { // we're marching towards the target // Let's check if any of our unit has been attacked. @@ -1874,7 +1871,7 @@ return true; }; -m.AttackPlan.prototype.UpdateTarget = function(gameState) +PETRA.AttackPlan.prototype.UpdateTarget = function(gameState) { // First update the target position in case it's a unit (and check if it has garrisoned) if (this.target && this.target.hasClass("Unit")) @@ -1882,7 +1879,7 @@ this.targetPos = this.target.position(); if (!this.targetPos) { - let holder = m.getHolder(gameState, this.target); + let holder = PETRA.getHolder(gameState, this.target); if (holder && gameState.isPlayerEnemy(holder.owner())) { this.target = holder; @@ -1927,7 +1924,7 @@ if (!attack.target || !gameState.getEntityById(attack.target.id()) || !gameState.isPlayerEnemy(attack.target.owner())) continue; - if (accessIndex != m.getLandAccess(gameState, attack.target)) + if (accessIndex != PETRA.getLandAccess(gameState, attack.target)) continue; if (attack.target.owner() == 0 && attack.targetPlayer != 0) // looks like it has resigned continue; @@ -1962,7 +1959,7 @@ }; /** reset any units */ -m.AttackPlan.prototype.Abort = function(gameState) +PETRA.AttackPlan.prototype.Abort = function(gameState) { this.unitCollection.unregister(); if (this.unitCollection.hasEntities()) @@ -1983,7 +1980,7 @@ { if (!base.anchor || !base.anchor.position()) continue; - if (m.getLandAccess(gameState, base.anchor) != access) + if (PETRA.getLandAccess(gameState, base.anchor) != access) continue; let newdist = API3.SquareVectorDistance(this.position, base.anchor.position()); if (newdist > dist) @@ -2011,7 +2008,7 @@ gameState.ai.queueManager.removeQueue("plan_" + this.name + "_siege"); }; -m.AttackPlan.prototype.removeUnit = function(ent, update) +PETRA.AttackPlan.prototype.removeUnit = function(ent, update) { if (ent.getMetadata(PlayerID, "role") == "attack") { @@ -2026,7 +2023,7 @@ this.unitCollection.updateEnt(ent); }; -m.AttackPlan.prototype.checkEvents = function(gameState, events) +PETRA.AttackPlan.prototype.checkEvents = function(gameState, events) { for (let evt of events.EntityRenamed) { @@ -2062,7 +2059,7 @@ continue; if (!gameState.isPlayerEnemy(ent.owner())) continue; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); for (let base of gameState.ai.HQ.baseManagers) { if (!base.anchor || !base.anchor.position()) @@ -2075,7 +2072,7 @@ } }; -m.AttackPlan.prototype.waitingForTransport = function() +PETRA.AttackPlan.prototype.waitingForTransport = function() { for (let ent of this.unitCollection.values()) if (ent.getMetadata(PlayerID, "transport") !== undefined) @@ -2083,15 +2080,15 @@ return false; }; -m.AttackPlan.prototype.hasSiegeUnits = function() +PETRA.AttackPlan.prototype.hasSiegeUnits = function() { for (let ent of this.unitCollection.values()) - if (m.isSiegeUnit(ent)) + if (PETRA.isSiegeUnit(ent)) return true; return false; }; -m.AttackPlan.prototype.hasForceOrder = function(data, value) +PETRA.AttackPlan.prototype.hasForceOrder = function(data, value) { for (let ent of this.unitCollection.values()) { @@ -2109,15 +2106,15 @@ * The center position of this attack may be in an inaccessible area. So we use the access * of the unit nearest to this center position. */ -m.AttackPlan.prototype.getAttackAccess = function(gameState) +PETRA.AttackPlan.prototype.getAttackAccess = function(gameState) { for (let ent of this.unitCollection.filterNearest(this.position, 1).values()) - return m.getLandAccess(gameState, ent); + return PETRA.getLandAccess(gameState, ent); return 0; }; -m.AttackPlan.prototype.debugAttack = function() +PETRA.AttackPlan.prototype.debugAttack = function() { API3.warn("---------- attack " + this.name); for (let unitCat in this.unitStat) @@ -2128,7 +2125,7 @@ API3.warn("------------------------------"); }; -m.AttackPlan.prototype.Serialize = function() +PETRA.AttackPlan.prototype.Serialize = function() { let properties = { "name": this.name, @@ -2156,7 +2153,7 @@ return { "properties": properties }; }; -m.AttackPlan.prototype.Deserialize = function(gameState, data) +PETRA.AttackPlan.prototype.Deserialize = function(gameState, data) { for (let key in data.properties) this[key] = data.properties[key]; @@ -2166,6 +2163,3 @@ this.failed = undefined; }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Base Manager * Handles lower level economic stuffs. @@ -13,7 +10,7 @@ * -updating whatever needs updating, keeping track of stuffs (rebuilding needs…) */ -m.BaseManager = function(gameState, Config) +PETRA.BaseManager = function(gameState, Config) { this.Config = Config; this.ID = gameState.ai.uniqueIDs.bases++; @@ -37,13 +34,13 @@ this.timeNextIdleCheck = 0; }; -m.BaseManager.prototype.init = function(gameState, state) +PETRA.BaseManager.prototype.init = function(gameState, state) { if (state == "unconstructed") this.constructing = true; else if (state != "captured") this.neededDefenders = 0; - this.workerObject = new m.Worker(this); + 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")); @@ -66,7 +63,7 @@ } }; -m.BaseManager.prototype.reset = function(gameState, state) +PETRA.BaseManager.prototype.reset = function(gameState, state) { if (state == "unconstructed") this.constructing = true; @@ -79,7 +76,7 @@ this.neededDefenders = 3 + 2 * (this.Config.difficulty - 3); }; -m.BaseManager.prototype.assignEntity = function(gameState, ent) +PETRA.BaseManager.prototype.assignEntity = function(gameState, ent) { ent.setMetadata(PlayerID, "base", this.ID); this.units.updateEnt(ent); @@ -89,7 +86,7 @@ this.assignResourceToDropsite(gameState, ent); }; -m.BaseManager.prototype.setAnchor = function(gameState, anchorEntity) +PETRA.BaseManager.prototype.setAnchor = function(gameState, anchorEntity) { if (!anchorEntity.hasClass("CivCentre")) API3.warn("Error: Petra base " + this.ID + " has been assigned " + ent.templateName() + " as anchor."); @@ -102,12 +99,12 @@ } anchorEntity.setMetadata(PlayerID, "base", this.ID); this.buildings.updateEnt(anchorEntity); - this.accessIndex = m.getLandAccess(gameState, anchorEntity); + this.accessIndex = PETRA.getLandAccess(gameState, anchorEntity); return true; }; /* we lost our anchor. Let's reassign our units and buildings */ -m.BaseManager.prototype.anchorLost = function(gameState, ent) +PETRA.BaseManager.prototype.anchorLost = function(gameState, ent) { this.anchor = undefined; this.anchorId = undefined; @@ -116,17 +113,17 @@ }; /** Set a building of an anchorless base */ -m.BaseManager.prototype.setAnchorlessEntity = function(gameState, ent) +PETRA.BaseManager.prototype.setAnchorlessEntity = function(gameState, ent) { if (!this.buildings.hasEntities()) { - if (!m.getBuiltEntity(gameState, ent).resourceDropsiteTypes()) + if (!PETRA.getBuiltEntity(gameState, ent).resourceDropsiteTypes()) API3.warn("Error: Petra base " + this.ID + " has been assigned " + ent.templateName() + " as origin."); - this.accessIndex = m.getLandAccess(gameState, ent); + this.accessIndex = PETRA.getLandAccess(gameState, ent); } - else if (this.accessIndex != m.getLandAccess(gameState, ent)) + else if (this.accessIndex != PETRA.getLandAccess(gameState, ent)) API3.warn(" Error: Petra base " + this.ID + " with access " + this.accessIndex + - " has been assigned " + ent.templateName() + " with access" + m.getLandAccess(gameState, ent)); + " has been assigned " + ent.templateName() + " with access" + PETRA.getLandAccess(gameState, ent)); ent.setMetadata(PlayerID, "base", this.ID); this.buildings.updateEnt(ent); @@ -137,7 +134,7 @@ * Assign the resources around the dropsites of this basis in three areas according to distance, and sort them in each area. * Moving resources (animals) and buildable resources (fields) are treated elsewhere. */ -m.BaseManager.prototype.assignResourceToDropsite = function(gameState, dropsite) +PETRA.BaseManager.prototype.assignResourceToDropsite = function(gameState, dropsite) { if (this.dropsites[dropsite.id()]) { @@ -152,7 +149,7 @@ this.dropsites[dropsiteId] = true; if (this.ID == gameState.ai.HQ.baseManagers[0].ID) - accessIndex = m.getLandAccess(gameState, dropsite); + accessIndex = PETRA.getLandAccess(gameState, dropsite); let maxDistResourceSquare = this.maxDistResourceSquare; for (let type of dropsite.resourceDropsiteTypes()) @@ -176,7 +173,7 @@ if (supply.resourceSupplyType().generic == "treasure") // treasures are treated separately return; // quick accessibility check - if (m.getLandAccess(gameState, supply) != accessIndex) + if (PETRA.getLandAccess(gameState, supply) != accessIndex) return; let dist = API3.SquareVectorDistance(supply.position(), dropsitePos); @@ -220,7 +217,7 @@ }; // completely remove the dropsite resources from our list. -m.BaseManager.prototype.removeDropsite = function(gameState, ent) +PETRA.BaseManager.prototype.removeDropsite = function(gameState, ent) { if (!ent.id()) return; @@ -250,7 +247,7 @@ /** * Returns the position of the best place to build a new dropsite for the specified resource */ -m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource) +PETRA.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource) { let template = gameState.getTemplate(gameState.applyCiv("structures/{civ}_storehouse")); @@ -265,7 +262,7 @@ // Then checks for a good spot in the territory. If none, and town/city phase, checks outside // The AI will currently not build a CC if it wouldn't connect with an existing CC. - let obstructions = m.createObstructionMap(gameState, this.accessIndex, template); + let obstructions = PETRA.createObstructionMap(gameState, this.accessIndex, template); let ccEnts = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).toEntityArray(); let dpEnts = gameState.getOwnStructures().filter(API3.Filters.byClassesOr(["Storehouse", "Dock"])).toEntityArray(); @@ -346,7 +343,7 @@ return { "quality": bestVal, "pos": [x, z] }; }; -m.BaseManager.prototype.getResourceLevel = function(gameState, type, nearbyOnly = false) +PETRA.BaseManager.prototype.getResourceLevel = function(gameState, type, nearbyOnly = false) { let count = 0; let check = {}; @@ -371,7 +368,7 @@ }; /** check our resource levels and react accordingly */ -m.BaseManager.prototype.checkResourceLevels = function(gameState, queues) +PETRA.BaseManager.prototype.checkResourceLevels = function(gameState, queues) { for (let type of Resources.GetCodes()) { @@ -388,7 +385,7 @@ { if (count < 600) { - queues.field.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); + queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); gameState.ai.HQ.needFarm = true; } } @@ -399,11 +396,11 @@ if (gameState.ai.HQ.saveResources || gameState.ai.HQ.saveSpace || count > 300 || numFarms > 5) goal = Math.max(goal-1, 1); if (numFound + numQueue < goal) - queues.field.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); + queues.field.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_field", { "favoredBase": this.ID })); } else if (gameState.ai.HQ.needCorral && !gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && !queues.corral.hasQueuedUnits() && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_corral")) - queues.corral.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); + queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); continue; } if (!gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && @@ -412,7 +409,7 @@ let count = this.getResourceLevel(gameState, type, gameState.currentPhase() > 1); // animals are not accounted if (count < 900) { - queues.corral.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); + queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_corral", { "favoredBase": this.ID })); gameState.ai.HQ.needCorral = true; } } @@ -445,7 +442,7 @@ { let newDP = this.findBestDropsiteLocation(gameState, type); if (newDP.quality > 50 && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_storehouse")) - queues.dropsites.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); + queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); else if (!gameState.getOwnFoundations().filter(API3.Filters.byClass("CivCentre")).hasEntities() && !queues.civilCentre.hasQueuedUnits()) { // No good dropsite, try to build a new base if no base already planned, @@ -453,7 +450,7 @@ if ((!gameState.ai.HQ.canExpand || !gameState.ai.HQ.buildNewBase(gameState, queues, type)) && newDP.quality > Math.min(25, 50*0.15/ratio) && gameState.ai.HQ.canBuild(gameState, "structures/{civ}_storehouse")) - queues.dropsites.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); + queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_storehouse", { "base": this.ID, "type": type }, newDP.pos)); } } this.gatherers[type].nextCheck = gameState.ai.playedTurn + 20; @@ -467,7 +464,7 @@ }; /** Adds the estimated gather rates from this base to the currentRates */ -m.BaseManager.prototype.addGatherRates = function(gameState, currentRates) +PETRA.BaseManager.prototype.addGatherRates = function(gameState, currentRates) { for (let res in currentRates) { @@ -504,7 +501,7 @@ } }; -m.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) +PETRA.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) { if (!roleless) roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role"))).values(); @@ -523,7 +520,7 @@ * they can be reassigned by reassignIdleWorkers. * TODO: actually this probably should be in the HQ. */ -m.BaseManager.prototype.setWorkersIdleByPriority = function(gameState) +PETRA.BaseManager.prototype.setWorkersIdleByPriority = function(gameState) { this.timeNextIdleCheck = gameState.ai.elapsedTime + 8; // change resource only towards one which is more needed, and if changing will not change this order @@ -579,7 +576,7 @@ * and return remaining number of possible switches. * Prefer FemaleCitizen for food and CitizenSoldier for other resources. */ -m.BaseManager.prototype.switchGatherer = function(gameState, from, to, number) +PETRA.BaseManager.prototype.switchGatherer = function(gameState, from, to, number) { let num = number; let only; @@ -605,7 +602,7 @@ return num; }; -m.BaseManager.prototype.reassignIdleWorkers = function(gameState, idleWorkers) +PETRA.BaseManager.prototype.reassignIdleWorkers = function(gameState, idleWorkers) { // Search for idle workers, and tell them to gather resources based on demand if (!idleWorkers) @@ -658,12 +655,12 @@ } }; -m.BaseManager.prototype.workersBySubrole = function(gameState, subrole) +PETRA.BaseManager.prototype.workersBySubrole = function(gameState, subrole) { return gameState.updatingCollection("subrole-" + subrole +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "subrole", subrole), this.workers); }; -m.BaseManager.prototype.gatherersByType = function(gameState, type) +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")); }; @@ -672,7 +669,7 @@ * returns an entity collection of workers. * They are idled immediatly and their subrole set to idle. */ -m.BaseManager.prototype.pickBuilders = function(gameState, workers, number) +PETRA.BaseManager.prototype.pickBuilders = function(gameState, workers, number) { let availableWorkers = this.workers.filter(ent => { if (!ent.position() || !ent.isBuilder()) @@ -715,7 +712,7 @@ * try reassigning some other workers who are nearby * AI tries to use builders sensibly, not completely stopping its econ. */ -m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) +PETRA.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) { let foundations = this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(), API3.Filters.not(API3.Filters.byClass("Field")))); @@ -787,7 +784,7 @@ continue; // if our territory has shrinked since this foundation was positioned, do not build it - if (m.isNotWorthBuilding(gameState, target)) + if (PETRA.isNotWorthBuilding(gameState, target)) continue; let assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length; @@ -948,7 +945,7 @@ }; /** Return false when the base is not active (no workers on it) */ -m.BaseManager.prototype.update = function(gameState, queues, events) +PETRA.BaseManager.prototype.update = function(gameState, queues, events) { if (this.ID == gameState.ai.HQ.baseManagers[0].ID) // base for unaffected units { @@ -958,13 +955,13 @@ { for (let ent of this.units.values()) { - let bestBase = m.getBestBase(gameState, ent); + let bestBase = PETRA.getBestBase(gameState, ent); if (bestBase.ID != this.ID) bestBase.assignEntity(gameState, ent); } for (let ent of this.buildings.values()) { - let bestBase = m.getBestBase(gameState, ent); + let bestBase = PETRA.getBestBase(gameState, ent); if (!bestBase) { if (ent.hasClass("Dock")) @@ -998,7 +995,7 @@ // Reassign all remaining entities to its nearest base for (let ent of this.units.values()) { - let base = m.getBestBase(gameState, ent, false, this.ID); + let base = PETRA.getBestBase(gameState, ent, false, this.ID); base.assignEntity(gameState, ent); } return false; @@ -1009,7 +1006,7 @@ { if (!ent.position()) continue; - let base = m.getBestBase(gameState, ent); + let base = PETRA.getBestBase(gameState, ent); if (base.anchor) reassignedBase = base; break; @@ -1083,7 +1080,7 @@ return true; }; -m.BaseManager.prototype.Serialize = function() +PETRA.BaseManager.prototype.Serialize = function() { return { "ID": this.ID, @@ -1098,14 +1095,10 @@ }; }; -m.BaseManager.prototype.Deserialize = function(gameState, data) +PETRA.BaseManager.prototype.Deserialize = function(gameState, data) { for (let key in data) this[key] = data[key]; this.anchor = this.anchorId !== undefined ? gameState.getEntityById(this.anchorId) : undefined; }; - -return m; - -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/buildManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/buildManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/buildManager.js @@ -1,13 +1,10 @@ -var PETRA = function(m) -{ - /** * One task of this manager is to cache the list of structures we have builders for, * to avoid having to loop on all entities each time. * It also takes care of the structures we can't currently build and should not try to build endlessly. */ -m.BuildManager = function() +PETRA.BuildManager = function() { // List of buildings we have builders for, with number of possible builders. this.builderCounters = new Map(); @@ -17,14 +14,14 @@ }; /** Initialization at start of game */ -m.BuildManager.prototype.init = function(gameState) +PETRA.BuildManager.prototype.init = function(gameState) { let civ = gameState.getPlayerCiv(); for (let ent of gameState.getOwnUnits().values()) this.incrementBuilderCounters(civ, ent, 1); }; -m.BuildManager.prototype.incrementBuilderCounters = function(civ, ent, increment) +PETRA.BuildManager.prototype.incrementBuilderCounters = function(civ, ent, increment) { for (let buildable of ent.buildableEntities(civ)) { @@ -46,7 +43,7 @@ }; /** Update the builders counters */ -m.BuildManager.prototype.checkEvents = function(gameState, events) +PETRA.BuildManager.prototype.checkEvents = function(gameState, events) { this.elapsedTime = gameState.ai.elapsedTime; let civ = gameState.getPlayerCiv(); @@ -89,7 +86,7 @@ * Get the first buildable structure with a given class * TODO when several available, choose the best one */ -m.BuildManager.prototype.findStructureWithClass = function(gameState, classes) +PETRA.BuildManager.prototype.findStructureWithClass = function(gameState, classes) { for (let [templateName, count] of this.builderCounters) { @@ -104,25 +101,25 @@ return undefined; }; -m.BuildManager.prototype.hasBuilder = function(template) +PETRA.BuildManager.prototype.hasBuilder = function(template) { let numBuilders = this.builderCounters.get(template); return numBuilders && numBuilders > 0; }; -m.BuildManager.prototype.isUnbuildable = function(gameState, template) +PETRA.BuildManager.prototype.isUnbuildable = function(gameState, template) { return this.unbuildables.has(template) && this.unbuildables.get(template).time > gameState.ai.elapsedTime; }; -m.BuildManager.prototype.setBuildable = function(template) +PETRA.BuildManager.prototype.setBuildable = function(template) { if (this.unbuildables.has(template)) this.unbuildables.delete(template); }; /** Time is the duration in second that we will wait before checking again if it is buildable */ -m.BuildManager.prototype.setUnbuildable = function(gameState, template, time = 90, reason = "room") +PETRA.BuildManager.prototype.setUnbuildable = function(gameState, template, time = 90, reason = "room") { if (!this.unbuildables.has(template)) this.unbuildables.set(template, { "reason": reason, "time": gameState.ai.elapsedTime + time }); @@ -138,7 +135,7 @@ }; /** Return the number of unbuildables due to missing room */ -m.BuildManager.prototype.numberMissingRoom = function(gameState) +PETRA.BuildManager.prototype.numberMissingRoom = function(gameState) { let num = 0; for (let unbuildable of this.unbuildables.values()) @@ -148,14 +145,14 @@ }; /** Reset the unbuildables due to missing room */ -m.BuildManager.prototype.resetMissingRoom = function(gameState) +PETRA.BuildManager.prototype.resetMissingRoom = function(gameState) { for (let [key, unbuildable] of this.unbuildables) if (unbuildable.reason == "room") this.unbuildables.delete(key); }; -m.BuildManager.prototype.Serialize = function() +PETRA.BuildManager.prototype.Serialize = function() { return { "builderCounters": this.builderCounters, @@ -163,11 +160,8 @@ }; }; -m.BuildManager.prototype.Deserialize = function(data) +PETRA.BuildManager.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/chatHelper.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/chatHelper.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/chatHelper.js @@ -1,7 +1,4 @@ -var PETRA = function(m) -{ - -m.launchAttackMessages = { +PETRA.launchAttackMessages = { "hugeAttack": [ markForTranslation("I am starting a massive military campaign against %(_player_)s, come and join me."), markForTranslation("I have set up a huge army to crush %(_player_)s. Join me and you will have your share of the loot.") @@ -12,7 +9,7 @@ ] }; -m.answerRequestAttackMessages = { +PETRA.answerRequestAttackMessages = { "join": [ markForTranslation("Let me regroup my army and I will then join you against %(_player_)s."), markForTranslation("I am finishing preparations to attack %(_player_)s.") @@ -26,24 +23,24 @@ ] }; -m.sentTributeMessages = [ +PETRA.sentTributeMessages = [ markForTranslation("Here is a gift for you, %(_player_)s. Make good use of it."), markForTranslation("I see you are in a bad situation, %(_player_)s. I hope this helps."), markForTranslation("I can help you this time, %(_player_)s, but you should manage your resources more carefully in the future.") ]; -m.requestTributeMessages = [ +PETRA.requestTributeMessages = [ markForTranslation("I am in need of %(resource)s, can you help? I will make it up to you."), markForTranslation("I would participate more efficiently in our common war effort if you could provide me some %(resource)s."), markForTranslation("If you can spare me some %(resource)s, I will be able to strengthen my army.") ]; -m.newTradeRouteMessages = [ +PETRA.newTradeRouteMessages = [ markForTranslation("I have set up a new route with %(_player_)s. Trading will be profitable for all of us."), markForTranslation("A new trade route is set up with %(_player_)s. Take your share of the profits.") ]; -m.newDiplomacyMessages = { +PETRA.newDiplomacyMessages = { "ally": [ markForTranslation("%(_player_)s and I are now allies.") ], @@ -55,7 +52,7 @@ ] }; -m.answerDiplomacyRequestMessages = { +PETRA.answerDiplomacyRequestMessages = { "ally": { "decline": [ markForTranslation("I cannot accept your offer to become allies, %(_player_)s.") @@ -113,7 +110,7 @@ } }; -m.sendDiplomacyRequestMessages = { +PETRA.sendDiplomacyRequestMessages = { "ally": { "sendRequest": [ markForTranslation("%(_player_)s, it would help both of our civilizations if we formed an alliance. If you become allies with me, I will respond in kind.") @@ -135,7 +132,7 @@ } }; -m.chatLaunchAttack = function(gameState, player, type) +PETRA.chatLaunchAttack = function(gameState, player, type) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -146,7 +143,7 @@ }); }; -m.chatAnswerRequestAttack = function(gameState, player, answer, other) +PETRA.chatAnswerRequestAttack = function(gameState, player, answer, other) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -157,7 +154,7 @@ }); }; -m.chatSentTribute = function(gameState, player) +PETRA.chatSentTribute = function(gameState, player) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -168,7 +165,7 @@ }); }; -m.chatRequestTribute = function(gameState, resource) +PETRA.chatRequestTribute = function(gameState, resource) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -179,7 +176,7 @@ }); }; -m.chatNewTradeRoute = function(gameState, player) +PETRA.chatNewTradeRoute = function(gameState, player) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -190,7 +187,7 @@ }); }; -m.chatNewPhase = function(gameState, phase, status) +PETRA.chatNewPhase = function(gameState, phase, status) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -201,7 +198,7 @@ }); }; -m.chatNewDiplomacy = function(gameState, player, newDiplomaticStance) +PETRA.chatNewDiplomacy = function(gameState, player, newDiplomaticStance) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -212,7 +209,7 @@ }); }; -m.chatAnswerRequestDiplomacy = function(gameState, player, requestType, response, requiredTribute) +PETRA.chatAnswerRequestDiplomacy = function(gameState, player, requestType, response, requiredTribute) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -226,7 +223,7 @@ }); }; -m.chatNewRequestDiplomacy = function(gameState, player, requestType, status) +PETRA.chatNewRequestDiplomacy = function(gameState, player, requestType, status) { Engine.PostCommand(PlayerID, { "type": "aichat", @@ -237,6 +234,3 @@ "parameters": { "_player_": player } }); }; - -return m; -}(PETRA); 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,4 @@ -var PETRA = function(m) -{ - -m.Config = function(difficulty, behavior) +PETRA.Config = function(difficulty, 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; @@ -108,7 +105,7 @@ "defensive": 0.5 }; - // See m.QueueManager.prototype.wantedGatherRates() + // See PETRA.QueueManager.prototype.wantedGatherRates() this.queues = { "firstTurn": { @@ -132,7 +129,7 @@ this.garrisonHealthLevel = { "low": 0.4, "medium": 0.55, "high": 0.7 }; }; -m.Config.prototype.setConfig = function(gameState) +PETRA.Config.prototype.setConfig = function(gameState) { if (this.difficulty > 0) { @@ -246,7 +243,7 @@ API3.warn(" >>> Petra bot: personality = " + uneval(this.personality)); }; -m.Config.prototype.Serialize = function() +PETRA.Config.prototype.Serialize = function() { var data = {}; for (let key in this) @@ -255,11 +252,8 @@ return data; }; -m.Config.prototype.Deserialize = function(data) +PETRA.Config.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); 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 @@ -1,7 +1,5 @@ -var PETRA = function(m) -{ - -/** Armies used by the defense manager. +/** + * Armies used by the defense manager. * An army is a collection of own entities and enemy entities. * * Types of armies: @@ -9,7 +7,7 @@ * "capturing": army set to capture a gaia building or recover capture points to one of its own structures * It must contain only one foe (the building to capture) and never be merged */ -m.DefenseArmy = function(gameState, foeEntities, type) +PETRA.DefenseArmy = function(gameState, foeEntities, type) { this.ID = gameState.ai.uniqueIDs.armies++; this.type = type || "default"; @@ -50,7 +48,7 @@ * won't recalculate our position but will dirty it. * force is true at army creation or when merging armies, so in this case we should add it even if far */ -m.DefenseArmy.prototype.addFoe = function(gameState, enemyId, force) +PETRA.DefenseArmy.prototype.addFoe = function(gameState, enemyId, force) { if (this.foeEntities.indexOf(enemyId) !== -1) return false; @@ -75,7 +73,7 @@ * returns true if the entity was removed and false otherwise. * TODO: when there is a technology update, we should probably recompute the strengths, or weird stuffs will happen. */ -m.DefenseArmy.prototype.removeFoe = function(gameState, enemyId, enemyEntity) +PETRA.DefenseArmy.prototype.removeFoe = function(gameState, enemyId, enemyEntity) { let idx = this.foeEntities.indexOf(enemyId); if (idx === -1) @@ -102,7 +100,7 @@ * adds a defender but doesn't assign him yet. * force is true when merging armies, so in this case we should add it even if no position as it can be in a ship */ -m.DefenseArmy.prototype.addOwn = function(gameState, id, force) +PETRA.DefenseArmy.prototype.addOwn = function(gameState, id, force) { if (this.ownEntities.indexOf(id) !== -1) return false; @@ -127,7 +125,7 @@ return true; }; -m.DefenseArmy.prototype.removeOwn = function(gameState, id, Entity) +PETRA.DefenseArmy.prototype.removeOwn = function(gameState, id, Entity) { let idx = this.ownEntities.indexOf(id); if (idx === -1) @@ -193,7 +191,7 @@ * resets the army properly. * assumes we already cleared dead units. */ -m.DefenseArmy.prototype.clear = function(gameState) +PETRA.DefenseArmy.prototype.clear = function(gameState) { while (this.foeEntities.length > 0) this.removeFoe(gameState, this.foeEntities[0]); @@ -249,7 +247,7 @@ let pos = struct.position(); if (!pos || !gameState.isPlayerMutualAlly(gameState.ai.HQ.territoryMap.getOwner(pos))) continue; - if (m.getLandAccess(gameState, struct) !== armyAccess) + if (PETRA.getLandAccess(gameState, struct) !== armyAccess) continue; let defensiveStruct = struct.hasDefensiveFire(); if (defensiveFound && !defensiveStruct) @@ -292,7 +290,7 @@ this.recalculatePosition(gameState); }; -m.DefenseArmy.prototype.assignUnit = function(gameState, entID) +PETRA.DefenseArmy.prototype.assignUnit = function(gameState, entID) { // we'll assume this defender is ours already. // we'll also override any previous assignment @@ -302,7 +300,7 @@ return false; // try to return its resources, and if any, the attack order will be queued - let queued = m.returnResources(gameState, ent); + let queued = PETRA.returnResources(gameState, ent); let idMin; let distMin; @@ -323,7 +321,7 @@ // already enough units against it if (this.assignedAgainst[id].length > 8 || - this.assignedAgainst[id].length > 5 && !eEnt.hasClass("Hero") && !m.isSiegeUnit(eEnt)) + this.assignedAgainst[id].length > 5 && !eEnt.hasClass("Hero") && !PETRA.isSiegeUnit(eEnt)) continue; let dist = API3.SquareVectorDistance(ent.position(), eEnt.position()); @@ -349,7 +347,7 @@ else return false; - let ownIndex = m.getLandAccess(gameState, ent); + let ownIndex = PETRA.getLandAccess(gameState, ent); let foeEnt = gameState.getEntityById(idFoe); let foePosition = foeEnt.position(); let foeIndex = gameState.ai.accessibility.getAccessValue(foePosition); @@ -357,19 +355,19 @@ { this.assignedTo[entID] = idFoe; this.assignedAgainst[idFoe].push(entID); - ent.attack(idFoe, m.allowCapture(gameState, ent, foeEnt), queued); + ent.attack(idFoe, PETRA.allowCapture(gameState, ent, foeEnt), queued); } else gameState.ai.HQ.navalManager.requireTransport(gameState, ent, ownIndex, foeIndex, foePosition); return true; }; -m.DefenseArmy.prototype.getType = function() +PETRA.DefenseArmy.prototype.getType = function() { return this.type; }; -m.DefenseArmy.prototype.getState = function() +PETRA.DefenseArmy.prototype.getState = function() { if (!this.foeEntities.length) return 0; @@ -381,7 +379,7 @@ * assumes units are in only one army. * also assumes that all have been properly cleaned up (no dead units). */ -m.DefenseArmy.prototype.merge = function(gameState, otherArmy) +PETRA.DefenseArmy.prototype.merge = function(gameState, otherArmy) { // copy over all parameters. for (let i in otherArmy.assignedAgainst) @@ -406,7 +404,7 @@ return true; }; -m.DefenseArmy.prototype.needsDefenders = function(gameState) +PETRA.DefenseArmy.prototype.needsDefenders = function(gameState) { let defenseRatio; let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(this.foePosition); @@ -435,7 +433,7 @@ /** if not forced, will only recalculate if on a different turn. */ -m.DefenseArmy.prototype.recalculatePosition = function(gameState, force) +PETRA.DefenseArmy.prototype.recalculatePosition = function(gameState, force) { if (!force && this.positionLastUpdate === gameState.ai.elapsedTime) return; @@ -462,7 +460,7 @@ this.positionLastUpdate = gameState.ai.elapsedTime; }; -m.DefenseArmy.prototype.recalculateStrengths = function(gameState) +PETRA.DefenseArmy.prototype.recalculateStrengths = function(gameState) { this.ownStrength = 0; this.foeStrength = 0; @@ -474,7 +472,7 @@ }; /** adds or remove the strength of the entity either to the enemy or to our units. */ -m.DefenseArmy.prototype.evaluateStrength = function(ent, isOwn, remove) +PETRA.DefenseArmy.prototype.evaluateStrength = function(ent, isOwn, remove) { if (!ent) return; @@ -488,7 +486,7 @@ entStrength = 2; } else - entStrength = m.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); + entStrength = PETRA.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); // TODO adapt the getMaxStrength function for animals. // For the time being, just increase it for elephants as the returned value is too small. @@ -504,7 +502,7 @@ this.foeStrength += entStrength; }; -m.DefenseArmy.prototype.checkEvents = function(gameState, events) +PETRA.DefenseArmy.prototype.checkEvents = function(gameState, events) { // Warning the metadata is already cloned in shared.js. Futhermore, changes should be done before destroyEvents // otherwise it would remove the old entity from this army list @@ -560,7 +558,7 @@ } }; -m.DefenseArmy.prototype.update = function(gameState) +PETRA.DefenseArmy.prototype.update = function(gameState) { for (let entId of this.ownEntities) { @@ -573,7 +571,7 @@ else if (orderData.length && orderData[0].target && orderData[0].attackType && orderData[0].attackType === "Capture") { let target = gameState.getEntityById(orderData[0].target); - if (target && !m.allowCapture(gameState, ent, target)) + if (target && !PETRA.allowCapture(gameState, ent, target)) ent.attack(orderData[0].target, false); } } @@ -625,7 +623,7 @@ return breakaways; }; -m.DefenseArmy.prototype.Serialize = function() +PETRA.DefenseArmy.prototype.Serialize = function() { return { "ID": this.ID, @@ -641,11 +639,8 @@ }; }; -m.DefenseArmy.prototype.Deserialize = function(data) +PETRA.DefenseArmy.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); 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 @@ -1,7 +1,4 @@ -var PETRA = function(m) -{ - -m.DefenseManager = function(Config) +PETRA.DefenseManager = function(Config) { this.armies = []; // array of "army" Objects this.Config = Config; @@ -16,7 +13,7 @@ this.attackedAllies = {}; }; -m.DefenseManager.prototype.update = function(gameState, events) +PETRA.DefenseManager.prototype.update = function(gameState, events) { Engine.ProfileStart("Defense Manager"); @@ -67,7 +64,7 @@ Engine.ProfileStop(); }; -m.DefenseManager.prototype.makeIntoArmy = function(gameState, entityID, type = "default") +PETRA.DefenseManager.prototype.makeIntoArmy = function(gameState, entityID, type = "default") { if (type == "default") { @@ -78,12 +75,12 @@ } // Create a new army for it. - let army = new m.DefenseArmy(gameState, [entityID], type); + let army = new PETRA.DefenseArmy(gameState, [entityID], type); this.armies.push(army); }; -m.DefenseManager.prototype.getArmy = function(partOfArmy) +PETRA.DefenseManager.prototype.getArmy = function(partOfArmy) { // Find the army corresponding to this ID partOfArmy for (let army of this.armies) @@ -93,7 +90,7 @@ return undefined; }; -m.DefenseManager.prototype.isDangerous = function(gameState, entity) +PETRA.DefenseManager.prototype.isDangerous = function(gameState, entity) { if (!entity.position()) return false; @@ -202,7 +199,7 @@ return false; }; -m.DefenseManager.prototype.checkEnemyUnits = function(gameState) +PETRA.DefenseManager.prototype.checkEnemyUnits = function(gameState) { const nbPlayers = gameState.sharedScript.playersData.length; let i = gameState.ai.playedTurn % nbPlayers; @@ -279,7 +276,7 @@ } }; -m.DefenseManager.prototype.checkEnemyArmies = function(gameState) +PETRA.DefenseManager.prototype.checkEnemyArmies = function(gameState) { for (let i = 0; i < this.armies.length; ++i) { @@ -391,7 +388,7 @@ } }; -m.DefenseManager.prototype.assignDefenders = function(gameState) +PETRA.DefenseManager.prototype.assignDefenders = function(gameState) { if (!this.armies.length) return; @@ -410,7 +407,7 @@ let ent = gameState.getEntityById(entId); if (!ent || !ent.position()) continue; - armyAccess = m.getLandAccess(gameState, ent); + armyAccess = PETRA.getLandAccess(gameState, ent); break; } if (!armyAccess) @@ -462,7 +459,7 @@ continue; let aMin; let distMin; - let access = ipass == 0 ? m.getLandAccess(gameState, ent) : undefined; + let access = ipass == 0 ? PETRA.getLandAccess(gameState, ent) : undefined; for (let a = 0; a < armiesNeeding.length; ++a) { if (access && armiesNeeding[a].access != access) @@ -486,7 +483,7 @@ else if (aMin === undefined) continue; - armiesNeeding[aMin].need -= m.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); + armiesNeeding[aMin].need -= PETRA.getMaxStrength(ent, this.Config.debug, this.Config.DamageTypeImportance); armiesNeeding[aMin].army.addOwn(gameState, potentialDefenders[i]); armiesNeeding[aMin].army.assignUnit(gameState, potentialDefenders[i]); potentialDefenders[i] = undefined; @@ -505,7 +502,7 @@ gameState.ai.HQ.trainEmergencyUnits(gameState, armiesPos); }; -m.DefenseManager.prototype.abortArmy = function(gameState, army) +PETRA.DefenseManager.prototype.abortArmy = function(gameState, army) { army.clear(gameState); for (let i = 0; i < this.armies.length; ++i) @@ -523,7 +520,7 @@ * and if a ranged siege unit (not used for defense) is attacked, garrison it in the nearest fortress * If our hero is attacked with regicide victory condition, the victoryManager will handle it */ -m.DefenseManager.prototype.checkEvents = function(gameState, events) +PETRA.DefenseManager.prototype.checkEvents = function(gameState, events) { // must be called every turn for all armies for (let army of this.armies) @@ -691,7 +688,7 @@ continue; if (unitAIStateOrder == "REPAIR" && currentTarget.hasDefensiveFire()) continue; - if (unitAIStateOrder == "COMBAT" && !m.isSiegeUnit(currentTarget) && + if (unitAIStateOrder == "COMBAT" && !PETRA.isSiegeUnit(currentTarget) && gameState.ai.HQ.capturableTargets.has(orderData[0].target)) { // take the nearest unit also attacking this structure to help us @@ -724,16 +721,16 @@ if (minEnt) { capturableTarget.ents.delete(minEnt.id()); - minEnt.attack(attacker.id(), m.allowCapture(gameState, minEnt, attacker)); + minEnt.attack(attacker.id(), PETRA.allowCapture(gameState, minEnt, attacker)); } } } - target.attack(attacker.id(), m.allowCapture(gameState, target, attacker)); + target.attack(attacker.id(), PETRA.allowCapture(gameState, target, attacker)); } } }; -m.DefenseManager.prototype.garrisonUnitsInside = function(gameState, target, data) +PETRA.DefenseManager.prototype.garrisonUnitsInside = function(gameState, target, data) { if (target.hitpoints() < target.garrisonEjectHealth() * target.maxHitpoints()) return false; @@ -750,7 +747,7 @@ if (dist >= range*range) return false; } - let access = m.getLandAccess(gameState, target); + let access = PETRA.getLandAccess(gameState, target); let garrisonManager = gameState.ai.HQ.garrisonManager; let garrisonArrowClasses = target.getGarrisonArrowClasses(); let typeGarrison = data.type || "protection"; @@ -759,7 +756,7 @@ { // Should be kept in sync with garrisonManager to avoid garrisoning-ungarrisoning some units if (data.attacker) - allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !m.isSiegeUnit(data.attacker); + allowMelee = data.attacker.hasClass("Structure") ? data.attacker.attackRange("Ranged") : !PETRA.isSiegeUnit(data.attacker); else allowMelee = true; } @@ -782,7 +779,7 @@ if (typeGarrison != "decay" && subrole && (subrole == "completing" || subrole == "walking" || subrole == "attacking")) return false; } - if (m.getLandAccess(gameState, ent) != access) + if (PETRA.getLandAccess(gameState, ent) != access) return false; return true; }).filterNearest(target.position()); @@ -808,11 +805,11 @@ }; /** garrison a attacked siege ranged unit inside the nearest fortress */ -m.DefenseManager.prototype.garrisonSiegeUnit = function(gameState, unit) +PETRA.DefenseManager.prototype.garrisonSiegeUnit = function(gameState, unit) { let distmin = Math.min(); let nearest; - let unitAccess = m.getLandAccess(gameState, unit); + let unitAccess = PETRA.getLandAccess(gameState, unit); let garrisonManager = gameState.ai.HQ.garrisonManager; for (let ent of gameState.getAllyStructures().values()) { @@ -824,7 +821,7 @@ continue; if (ent.hitpoints() < ent.garrisonEjectHealth() * ent.maxHitpoints()) continue; - if (m.getLandAccess(gameState, ent) != unitAccess) + if (PETRA.getLandAccess(gameState, ent) != unitAccess) continue; let dist = API3.SquareVectorDistance(ent.position(), unit.position()); if (dist > distmin) @@ -842,11 +839,11 @@ * If emergency is true, the unit will be garrisoned in the closest possible structure * Otherwise, it will garrison in the closest healing structure */ -m.DefenseManager.prototype.garrisonAttackedUnit = function(gameState, unit, emergency = false) +PETRA.DefenseManager.prototype.garrisonAttackedUnit = function(gameState, unit, emergency = false) { let distmin = Math.min(); let nearest; - let unitAccess = m.getLandAccess(gameState, unit); + let unitAccess = PETRA.getLandAccess(gameState, unit); let garrisonManager = gameState.ai.HQ.garrisonManager; for (let ent of gameState.getAllyStructures().values()) { @@ -861,7 +858,7 @@ continue; if (ent.hitpoints() < ent.garrisonEjectHealth() * ent.maxHitpoints()) continue; - if (m.getLandAccess(gameState, ent) != unitAccess) + if (PETRA.getLandAccess(gameState, ent) != unitAccess) continue; let dist = API3.SquareVectorDistance(ent.position(), unit.position()); if (dist > distmin) @@ -887,7 +884,7 @@ /** * Be more inclined to help an ally attacked by several enemies */ -m.DefenseManager.prototype.GetCooperationLevel = function(ally) +PETRA.DefenseManager.prototype.GetCooperationLevel = function(ally) { let cooperation = this.Config.personality.cooperative; if (this.attackedAllies[ally] && this.attackedAllies[ally] > 1) @@ -898,7 +895,7 @@ /** * Switch a defense army into an attack if needed */ -m.DefenseManager.prototype.switchToAttack = function(gameState, army) +PETRA.DefenseManager.prototype.switchToAttack = function(gameState, army) { if (!army) return; @@ -907,12 +904,12 @@ let target = gameState.getEntityById(targetId); if (!target || !target.position() || !gameState.isPlayerEnemy(target.owner())) continue; - let targetAccess = m.getLandAccess(gameState, target); + let targetAccess = PETRA.getLandAccess(gameState, target); let targetPos = target.position(); for (let entId of army.ownEntities) { let ent = gameState.getEntityById(entId); - if (!ent || !ent.position() || m.getLandAccess(gameState, ent) != targetAccess) + if (!ent || !ent.position() || PETRA.getLandAccess(gameState, ent) != targetAccess) continue; if (API3.SquareVectorDistance(targetPos, ent.position()) > 14400) continue; @@ -922,7 +919,7 @@ } }; -m.DefenseManager.prototype.Serialize = function() +PETRA.DefenseManager.prototype.Serialize = function() { let properties = { "targetList": this.targetList, @@ -939,7 +936,7 @@ return { "properties": properties, "armies": armies }; }; -m.DefenseManager.prototype.Deserialize = function(gameState, data) +PETRA.DefenseManager.prototype.Deserialize = function(gameState, data) { for (let key in data.properties) this[key] = data.properties[key]; @@ -947,11 +944,8 @@ this.armies = []; for (let dataArmy of data.armies) { - let army = new m.DefenseArmy(gameState, []); + let army = new PETRA.DefenseArmy(gameState, []); army.Deserialize(dataArmy); this.armies.push(army); } }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Manage the diplomacy: * update our cooperative trait @@ -23,7 +20,7 @@ * sent through AIInterface. It is expected that the other player will change their diplomacy stance to the stance * that we suggested within a period of time, or else the request will be deleted from this.sentDiplomacyRequests. */ -m.DiplomacyManager = function(Config) +PETRA.DiplomacyManager = function(Config) { this.Config = Config; this.nextTributeUpdate = 90; @@ -41,7 +38,7 @@ * If there are any players that are allied/neutral with us but we are not allied/neutral with them, * treat this situation like an ally/neutral request. */ -m.DiplomacyManager.prototype.init = function(gameState) +PETRA.DiplomacyManager.prototype.init = function(gameState) { this.lastManStandingCheck(gameState); @@ -63,7 +60,7 @@ * Check if any allied needs help (tribute) and sent it if we have enough resource * or ask for a tribute if we are in need and one ally can help */ -m.DiplomacyManager.prototype.tributes = function(gameState) +PETRA.DiplomacyManager.prototype.tributes = function(gameState) { this.nextTributeUpdate = gameState.ai.elapsedTime + 30; let totalResources = gameState.getResources(); @@ -104,7 +101,7 @@ { this.nextTributeRequest.set("all", gameState.ai.elapsedTime + 90); this.nextTributeRequest.set(res, gameState.ai.elapsedTime + 240); - m.chatRequestTribute(gameState, res); + PETRA.chatRequestTribute(gameState, res); if (this.Config.debug > 1) API3.warn("Tribute on " + res + " requested to player " + i); break; @@ -117,12 +114,12 @@ if (this.Config.debug > 1) API3.warn("Tribute " + uneval(tribute) + " sent to player " + i); if (this.Config.chat) - m.chatSentTribute(gameState, i); + PETRA.chatSentTribute(gameState, i); Engine.PostCommand(PlayerID, { "type": "tribute", "player": i, "amounts": tribute }); } }; -m.DiplomacyManager.prototype.checkEvents = function(gameState, events) +PETRA.DiplomacyManager.prototype.checkEvents = function(gameState, events) { // Increase slowly the cooperative personality trait either when we receive tribute from our allies // or if our allies attack enemies inside our territory @@ -214,7 +211,7 @@ { let response = request !== undefined && (request.status === "declinedRequest" || request.status === "allianceBroken") ? "decline" : "declineSuggestNeutral"; - m.chatAnswerRequestDiplomacy(gameState, evt.player, "ally", response); + PETRA.chatAnswerRequestDiplomacy(gameState, evt.player, "ally", response); } else if (gameState.sharedScript.playersData[evt.player].isAlly[PlayerID] && gameState.isPlayerNeutral(evt.player)) this.handleDiplomacyRequest(gameState, evt.player, "ally"); @@ -270,7 +267,7 @@ * If the "Last Man Standing" option is enabled, check if the only remaining players are allies or neutral. * If so, turn against the strongest first, but be more likely to first turn against neutral players, if there are any. */ -m.DiplomacyManager.prototype.lastManStandingCheck = function(gameState) +PETRA.DiplomacyManager.prototype.lastManStandingCheck = function(gameState) { if (gameState.sharedScript.playersData[PlayerID].teamsLocked || gameState.isCeasefireActive() || gameState.getAlliedVictory() && gameState.hasAllies()) @@ -351,7 +348,7 @@ if (request && request.status !== "allianceBroken") { if (request.status === "waitingForTribute") - m.chatAnswerRequestDiplomacy(gameState, player, request.requestType, "decline"); + PETRA.chatAnswerRequestDiplomacy(gameState, player, request.requestType, "decline"); request.status = request.status === "accepted" ? "allianceBroken" : "declinedRequest"; } // If we had sent this player a diplomacy request, just rescind it @@ -365,7 +362,7 @@ * Do not become allies with a player if the game would be over. * Overall, be reluctant to become allies with any one player, but be more likely to accept neutral requests. */ -m.DiplomacyManager.prototype.handleDiplomacyRequest = function(gameState, player, requestType) +PETRA.DiplomacyManager.prototype.handleDiplomacyRequest = function(gameState, player, requestType) { if (gameState.sharedScript.playersData[PlayerID].teamsLocked) return; @@ -414,10 +411,10 @@ "requestType": requestType }); } - m.chatAnswerRequestDiplomacy(gameState, player, requestType, response, requiredTribute); + PETRA.chatAnswerRequestDiplomacy(gameState, player, requestType, response, requiredTribute); }; -m.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance) +PETRA.DiplomacyManager.prototype.changePlayerDiplomacy = function(gameState, player, newDiplomaticStance) { if (gameState.isPlayerEnemy(player) && (newDiplomaticStance === "ally" || newDiplomaticStance === "neutral")) gameState.ai.HQ.attackManager.cancelAttacksAgainstPlayer(gameState, player); @@ -425,10 +422,10 @@ if (this.Config.debug > 1) API3.warn("diplomacy stance with player " + player + " is now " + newDiplomaticStance); if (this.Config.chat) - m.chatNewDiplomacy(gameState, player, newDiplomaticStance); + PETRA.chatNewDiplomacy(gameState, player, newDiplomaticStance); }; -m.DiplomacyManager.prototype.checkRequestedTributes = function(gameState) +PETRA.DiplomacyManager.prototype.checkRequestedTributes = function(gameState) { for (let [player, data] of this.receivedDiplomacyRequests) if (data.status === "waitingForTribute" && gameState.ai.elapsedTime > data.warnTime) @@ -436,13 +433,13 @@ if (data.sentWarning) { this.receivedDiplomacyRequests.delete(player); - m.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "decline"); + PETRA.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "decline"); } else { data.sentWarning = true; data.warnTime = gameState.ai.elapsedTime + 60; - m.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "waitingForTribute", { + PETRA.chatAnswerRequestDiplomacy(gameState, player, data.requestType, "waitingForTribute", { "wanted": data.wanted, "type": data.type }); @@ -454,7 +451,7 @@ * Try to become allies with a player who has a lot of mutual enemies in common with us. * TODO: Possibly let human players demand tributes from AIs who send diplomacy requests. */ -m.DiplomacyManager.prototype.sendDiplomacyRequest = function(gameState) +PETRA.DiplomacyManager.prototype.sendDiplomacyRequest = function(gameState) { let player; let max = 0; @@ -493,21 +490,21 @@ if (this.Config.debug > 0) API3.warn("Sending diplomacy request to player " + player + " with " + requestType); Engine.PostCommand(PlayerID, { "type": "diplomacy-request", "source": PlayerID, "player": player, "to": requestType }); - m.chatNewRequestDiplomacy(gameState, player, requestType, "sendRequest"); + PETRA.chatNewRequestDiplomacy(gameState, player, requestType, "sendRequest"); }; -m.DiplomacyManager.prototype.checkSentDiplomacyRequests = function(gameState) +PETRA.DiplomacyManager.prototype.checkSentDiplomacyRequests = function(gameState) { for (let [player, data] of this.sentDiplomacyRequests) if (gameState.ai.elapsedTime > data.timeSent + 60 && !gameState.ai.HQ.saveResources && gameState.getPopulation() > 70) { - m.chatNewRequestDiplomacy(gameState, player, data.requestType, "requestExpired"); + PETRA.chatNewRequestDiplomacy(gameState, player, data.requestType, "requestExpired"); this.sentDiplomacyRequests.delete(player); } }; -m.DiplomacyManager.prototype.update = function(gameState, events) +PETRA.DiplomacyManager.prototype.update = function(gameState, events) { this.checkEvents(gameState, events); @@ -535,7 +532,7 @@ this.checkSentDiplomacyRequests(gameState); }; -m.DiplomacyManager.prototype.Serialize = function() +PETRA.DiplomacyManager.prototype.Serialize = function() { return { "nextTributeUpdate": this.nextTributeUpdate, @@ -549,11 +546,8 @@ }; }; -m.DiplomacyManager.prototype.Deserialize = function(data) +PETRA.DiplomacyManager.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js @@ -1,14 +1,11 @@ -var PETRA = function(m) -{ - /** returns true if this unit should be considered as a siege unit */ -m.isSiegeUnit = function(ent) +PETRA.isSiegeUnit = function(ent) { return ent.hasClass("Siege") || ent.hasClass("Elephant") && ent.hasClass("Melee") && ent.hasClass("Champion"); }; /** returns some sort of DPS * health factor. If you specify a class, it'll use the modifiers against that class too. */ -m.getMaxStrength = function(ent, debugLevel, DamageTypeImportance, againstClass) +PETRA.getMaxStrength = function(ent, debugLevel, DamageTypeImportance, againstClass) { let strength = 0; let attackTypes = ent.attackTypes(); @@ -69,7 +66,7 @@ }; /** Get access and cache it (except for units as it can change) in metadata if not already done */ -m.getLandAccess = function(gameState, ent) +PETRA.getLandAccess = function(gameState, ent) { if (ent.hasClass("Unit")) return gameState.ai.accessibility.getAccessValue(ent.position()); @@ -104,7 +101,7 @@ }; /** Sea access always cached as it never changes */ -m.getSeaAccess = function(gameState, ent) +PETRA.getSeaAccess = function(gameState, ent) { let sea = ent.getMetadata(PlayerID, "sea"); if (!sea) @@ -130,13 +127,13 @@ return sea; }; -m.setSeaAccess = function(gameState, ent) +PETRA.setSeaAccess = function(gameState, ent) { - m.getSeaAccess(gameState, ent); + PETRA.getSeaAccess(gameState, ent); }; /** Decide if we should try to capture (returns true) or destroy (return false) */ -m.allowCapture = function(gameState, ent, target) +PETRA.allowCapture = function(gameState, ent, target) { if (!target.isCapturable() || !ent.canCapture(target)) return false; @@ -156,7 +153,7 @@ let capturableTargets = gameState.ai.HQ.capturableTargets; if (!capturableTargets.has(target.id())) { - capture = ent.captureStrength() * m.getAttackBonus(ent, target, "Capture"); + capture = ent.captureStrength() * PETRA.getAttackBonus(ent, target, "Capture"); capturableTargets.set(target.id(), { "strength": capture, "ents": new Set([ent.id()]) }); } else @@ -164,7 +161,7 @@ let capturable = capturableTargets.get(target.id()); if (!capturable.ents.has(ent.id())) { - capturable.strength += ent.captureStrength() * m.getAttackBonus(ent, target, "Capture"); + capturable.strength += ent.captureStrength() * PETRA.getAttackBonus(ent, target, "Capture"); capturable.ents.add(ent.id()); } capture = capturable.strength; @@ -176,7 +173,7 @@ return capture > antiCapture + sumCapturePoints/80; }; -m.getAttackBonus = function(ent, target, type) +PETRA.getAttackBonus = function(ent, target, type) { let attackBonus = 1; if (!ent.get("Attack/" + type) || !ent.get("Attack/" + type + "/Bonuses")) @@ -195,7 +192,7 @@ }; /** Makes the worker deposit the currently carried resources at the closest accessible dropsite */ -m.returnResources = function(gameState, ent) +PETRA.returnResources = function(gameState, ent) { if (!ent.resourceCarrying() || !ent.resourceCarrying().length || !ent.position()) return false; @@ -204,7 +201,7 @@ let closestDropsite; let distmin = Math.min(); - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); let dropsiteCollection = gameState.playerData.hasSharedDropsites ? gameState.getAnyDropsites(resource) : gameState.getOwnDropsites(resource); for (let dropsite of dropsiteCollection.values()) @@ -215,7 +212,7 @@ // owner !== PlayerID can only happen when hasSharedDropsites === true, so no need to test it again if (owner !== PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - if (m.getLandAccess(gameState, dropsite) != access) + if (PETRA.getLandAccess(gameState, dropsite) != access) continue; let dist = API3.SquareVectorDistance(ent.position(), dropsite.position()); if (dist > distmin) @@ -231,7 +228,7 @@ }; /** is supply full taking into account gatherers affected during this turn */ -m.IsSupplyFull = function(gameState, ent) +PETRA.IsSupplyFull = function(gameState, ent) { return ent.isFull() === true || ent.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(ent.id()) >= ent.maxGatherers(); @@ -243,24 +240,24 @@ * If nothing found, return the base[0] for units and undefined for structures. * If exclude is given, we exclude the base with ID = exclude. */ -m.getBestBase = function(gameState, ent, onlyConstructedBase = false, exclude = false) +PETRA.getBestBase = function(gameState, ent, onlyConstructedBase = false, exclude = false) { let pos = ent.position(); let accessIndex; if (!pos) { - let holder = m.getHolder(gameState, ent); + let holder = PETRA.getHolder(gameState, ent); if (!holder || !holder.position()) { API3.warn("Petra error: entity without position, but not garrisoned"); - m.dumpEntity(ent); + PETRA.dumpEntity(ent); return gameState.ai.HQ.baseManagers[0]; } pos = holder.position(); - accessIndex = m.getLandAccess(gameState, holder); + accessIndex = PETRA.getLandAccess(gameState, holder); } else - accessIndex = m.getLandAccess(gameState, ent); + accessIndex = PETRA.getLandAccess(gameState, ent); let distmin = Math.min(); let dist; @@ -303,7 +300,7 @@ return bestbase; }; -m.getHolder = function(gameState, ent) +PETRA.getHolder = function(gameState, ent) { for (let holder of gameState.getEntities().values()) { @@ -314,7 +311,7 @@ }; /** return the template of the built foundation if a foundation, otherwise return the entity itself */ -m.getBuiltEntity = function(gameState, ent) +PETRA.getBuiltEntity = function(gameState, ent) { if (ent.foundationProgress() !== undefined) return gameState.getBuiltTemplate(ent.templateName()); @@ -326,7 +323,7 @@ * return true if it is not worth finishing this building (it would surely decay) * TODO implement the other conditions */ -m.isNotWorthBuilding = function(gameState, ent) +PETRA.isNotWorthBuilding = function(gameState, ent) { if (gameState.ai.HQ.territoryMap.getOwner(ent.position()) !== PlayerID) { @@ -340,7 +337,7 @@ /** * Check if the straight line between the two positions crosses an enemy territory */ -m.isLineInsideEnemyTerritory = function(gameState, pos1, pos2, step=70) +PETRA.isLineInsideEnemyTerritory = function(gameState, pos1, pos2, step=70) { let n = Math.floor(Math.sqrt(API3.SquareVectorDistance(pos1, pos2))/step) + 1; let stepx = (pos2[0] - pos1[0]) / n; @@ -355,7 +352,7 @@ return false; }; -m.gatherTreasure = function(gameState, ent, water = false) +PETRA.gatherTreasure = function(gameState, ent, water = false) { if (!gameState.ai.HQ.treasures.hasEntities()) return false; @@ -366,18 +363,18 @@ return false; let treasureFound; let distmin = Math.min(); - let access = water ? m.getSeaAccess(gameState, ent) : m.getLandAccess(gameState, ent); + let access = water ? PETRA.getSeaAccess(gameState, ent) : PETRA.getLandAccess(gameState, ent); for (let treasure of gameState.ai.HQ.treasures.values()) { - if (m.IsSupplyFull(gameState, treasure)) + if (PETRA.IsSupplyFull(gameState, treasure)) continue; // let some time for the previous gatherer to reach the treasure before trying again let lastGathered = treasure.getMetadata(PlayerID, "lastGathered"); if (lastGathered && gameState.ai.elapsedTime - lastGathered < 20) continue; - if (!water && access != m.getLandAccess(gameState, treasure)) + if (!water && access != PETRA.getLandAccess(gameState, treasure)) continue; - if (water && access != m.getSeaAccess(gameState, treasure)) + if (water && access != PETRA.getSeaAccess(gameState, treasure)) continue; let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(treasure.position()); if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) @@ -399,7 +396,7 @@ return true; }; -m.dumpEntity = function(ent) +PETRA.dumpEntity = function(ent) { if (!ent) return; @@ -417,6 +414,3 @@ " target-foundation " + ent.getMetadata(PlayerID, "target-foundation") + " PartOfArmy " + ent.getMetadata(PlayerID, "PartOfArmy")); }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Manage the garrisonHolders * When a unit is ordered to garrison, it must be done through this.garrison() function so that @@ -9,14 +6,14 @@ * Futhermore garrison units have a metadata garrisonType describing its reason (protection, transport, ...) */ -m.GarrisonManager = function(Config) +PETRA.GarrisonManager = function(Config) { this.Config = Config; this.holders = new Map(); this.decayingStructures = new Map(); }; -m.GarrisonManager.prototype.update = function(gameState, events) +PETRA.GarrisonManager.prototype.update = function(gameState, events) { // First check for possible upgrade of a structure for (let evt of events.EntityRenamed) @@ -112,7 +109,7 @@ API3.warn("Petra garrison error: unit " + ent.id() + " (" + ent.genericName() + ") is expected to garrison in " + id + " (" + holder.genericName() + "), but has no such garrison order " + uneval(ent.unitAIOrderData())); - m.dumpEntity(ent); + PETRA.dumpEntity(ent); } list.splice(j--, 1); } @@ -148,7 +145,7 @@ continue; if (ent.hasClass("Structure")) around.defenseStructure = true; - else if (m.isSiegeUnit(ent)) + else if (PETRA.isSiegeUnit(ent)) { if (ent.attackTypes().indexOf("Melee") !== -1) around.meleeSiege = true; @@ -202,7 +199,7 @@ }; /** TODO should add the units garrisoned inside garrisoned units */ -m.GarrisonManager.prototype.numberOfGarrisonedUnits = function(holder) +PETRA.GarrisonManager.prototype.numberOfGarrisonedUnits = function(holder) { if (!this.holders.has(holder.id())) return holder.garrisoned().length; @@ -210,7 +207,7 @@ return holder.garrisoned().length + this.holders.get(holder.id()).list.length; }; -m.GarrisonManager.prototype.allowMelee = function(holder) +PETRA.GarrisonManager.prototype.allowMelee = function(holder) { if (!this.holders.has(holder.id())) return undefined; @@ -219,7 +216,7 @@ }; /** This is just a pre-garrison state, while the entity walk to the garrison holder */ -m.GarrisonManager.prototype.garrison = function(gameState, ent, holder, type) +PETRA.GarrisonManager.prototype.garrison = function(gameState, ent, holder, type) { if (this.numberOfGarrisonedUnits(holder) >= holder.garrisonMax() || !ent.canGarrison()) return; @@ -250,7 +247,7 @@ This function is for internal use inside garrisonManager. From outside, you should also update the holder and then using cancelGarrison should be the preferred solution */ -m.GarrisonManager.prototype.leaveGarrison = function(ent) +PETRA.GarrisonManager.prototype.leaveGarrison = function(ent) { ent.setMetadata(PlayerID, "subrole", undefined); if (ent.getMetadata(PlayerID, "plan") === -2) @@ -261,7 +258,7 @@ }; /** Cancel a pre-garrison state */ -m.GarrisonManager.prototype.cancelGarrison = function(ent) +PETRA.GarrisonManager.prototype.cancelGarrison = function(ent) { ent.stopMoving(); this.leaveGarrison(ent); @@ -274,7 +271,7 @@ list.splice(index, 1); }; -m.GarrisonManager.prototype.keepGarrisoned = function(ent, holder, around) +PETRA.GarrisonManager.prototype.keepGarrisoned = function(ent, holder, around) { switch (ent.getMetadata(PlayerID, "garrisonType")) { @@ -299,8 +296,8 @@ if (ent.attackTypes() && ent.attackTypes().indexOf("Melee") !== -1) return false; if (around.unit) - return ent.hasClass("Support") || m.isSiegeUnit(ent); // only ranged siege here and below as melee siege already released above - if (m.isSiegeUnit(ent)) + return ent.hasClass("Support") || PETRA.isSiegeUnit(ent); // only ranged siege here and below as melee siege already released above + if (PETRA.isSiegeUnit(ent)) return around.meleeSiege; return holder.buffHeal() && ent.needsHeal(); case 'decay': @@ -324,7 +321,7 @@ }; /** Add this holder in the list managed by the garrisonManager */ -m.GarrisonManager.prototype.registerHolder = function(gameState, holder) +PETRA.GarrisonManager.prototype.registerHolder = function(gameState, holder) { if (this.holders.has(holder.id())) // already registered return; @@ -337,7 +334,7 @@ * do it only for structures useful for defense, except if we are expanding (justCaptured=true) * in which case we also do it for structures useful for unit trainings (TODO only Barracks are done) */ -m.GarrisonManager.prototype.addDecayingStructure = function(gameState, entId, justCaptured) +PETRA.GarrisonManager.prototype.addDecayingStructure = function(gameState, entId, justCaptured) { if (this.decayingStructures.has(entId)) return true; @@ -351,23 +348,20 @@ return true; }; -m.GarrisonManager.prototype.removeDecayingStructure = function(entId) +PETRA.GarrisonManager.prototype.removeDecayingStructure = function(entId) { if (!this.decayingStructures.has(entId)) return; this.decayingStructures.delete(entId); }; -m.GarrisonManager.prototype.Serialize = function() +PETRA.GarrisonManager.prototype.Serialize = function() { return { "holders": this.holders, "decayingStructures": this.decayingStructures }; }; -m.GarrisonManager.prototype.Deserialize = function(data) +PETRA.GarrisonManager.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Headquarters * Deal with high level logic for the AI. Most of the interesting stuff gets done here. @@ -14,8 +11,7 @@ * -planning attacks -> attackManager * -picking new CC locations. */ - -m.HQ = function(Config) +PETRA.HQ = function(Config) { this.Config = Config; this.phasing = 0; // existing values: 0 means no, i > 0 means phasing towards phase i @@ -40,29 +36,29 @@ this.extraFortresses = Math.round(Math.max(Math.min(this.Config.difficulty - 1, 2), 0) * this.Config.personality.defensive); this.baseManagers = []; - this.attackManager = new m.AttackManager(this.Config); - this.buildManager = new m.BuildManager(); - this.defenseManager = new m.DefenseManager(this.Config); - this.tradeManager = new m.TradeManager(this.Config); - this.navalManager = new m.NavalManager(this.Config); - this.researchManager = new m.ResearchManager(this.Config); - this.diplomacyManager = new m.DiplomacyManager(this.Config); - this.garrisonManager = new m.GarrisonManager(this.Config); - this.victoryManager = new m.VictoryManager(this.Config); + this.attackManager = new PETRA.AttackManager(this.Config); + this.buildManager = new PETRA.BuildManager(); + this.defenseManager = new PETRA.DefenseManager(this.Config); + this.tradeManager = new PETRA.TradeManager(this.Config); + this.navalManager = new PETRA.NavalManager(this.Config); + this.researchManager = new PETRA.ResearchManager(this.Config); + this.diplomacyManager = new PETRA.DiplomacyManager(this.Config); + this.garrisonManager = new PETRA.GarrisonManager(this.Config); + this.victoryManager = new PETRA.VictoryManager(this.Config); this.capturableTargets = new Map(); this.capturableTargetsTime = 0; }; /** More initialisation for stuff that needs the gameState */ -m.HQ.prototype.init = function(gameState, queues) +PETRA.HQ.prototype.init = function(gameState, queues) { - this.territoryMap = m.createTerritoryMap(gameState); + this.territoryMap = PETRA.createTerritoryMap(gameState); // initialize base map. Each pixel is a base ID, or 0 if not or not accessible this.basesMap = new API3.Map(gameState.sharedScript, "territory"); // create borderMap: flag cells on the border of the map // then this map will be completed with our frontier in updateTerritories - this.borderMap = m.createBorderMap(gameState); + this.borderMap = PETRA.createBorderMap(gameState); // list of allowed regions this.landRegions = {}; // try to determine if we have a water map @@ -81,7 +77,7 @@ /** * initialization needed after deserialization (only called when deserialization) */ -m.HQ.prototype.postinit = function(gameState) +PETRA.HQ.prototype.postinit = function(gameState) { // Rebuild the base maps from the territory indices of each base this.basesMap = new API3.Map(gameState.sharedScript, "territory"); @@ -115,9 +111,9 @@ * "captured" => captured base with an anchor * "anchorless" => anchorless base, currently with dock */ -m.HQ.prototype.createBase = function(gameState, ent, type) +PETRA.HQ.prototype.createBase = function(gameState, ent, type) { - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); let newbase; for (let base of this.baseManagers) { @@ -154,7 +150,7 @@ if (!newbase) { - newbase = new m.BaseManager(gameState, this.Config); + newbase = new PETRA.BaseManager(gameState, this.Config); newbase.init(gameState, type); this.baseManagers.push(newbase); } @@ -174,7 +170,7 @@ * otherwise return undefined * for the moment, only the case land-sea-land is supported */ -m.HQ.prototype.getSeaBetweenIndices = function(gameState, index1, index2) +PETRA.HQ.prototype.getSeaBetweenIndices = function(gameState, index1, index2) { let path = gameState.ai.accessibility.getTrajectToIndex(index1, index2); if (path && path.length == 3 && gameState.ai.accessibility.regionType[path[1]] == "water") @@ -190,7 +186,7 @@ }; /** TODO check if the new anchorless bases should be added to addBase */ -m.HQ.prototype.checkEvents = function(gameState, events) +PETRA.HQ.prototype.checkEvents = function(gameState, events) { let addBase = false; @@ -324,7 +320,7 @@ continue; if (ent.hasClass("Unit")) { - m.getBestBase(gameState, ent).assignEntity(gameState, ent); + PETRA.getBestBase(gameState, ent).assignEntity(gameState, ent); ent.setMetadata(PlayerID, "role", undefined); ent.setMetadata(PlayerID, "subrole", undefined); ent.setMetadata(PlayerID, "plan", undefined); @@ -340,7 +336,7 @@ ent.setMetadata(PlayerID, "subrole", "idle"); } if (ent.hasClass("Ship")) - m.setSeaAccess(gameState, ent); + PETRA.setSeaAccess(gameState, ent); if (!ent.hasClass("Support") && !ent.hasClass("Ship") && ent.attackTypes() !== undefined) ent.setMetadata(PlayerID, "plan", -1); continue; @@ -364,7 +360,7 @@ if (!ent.decaying() && ent.resourceDropsiteTypes()) base = this.createBase(gameState, ent, "anchorless"); else - base = m.getBestBase(gameState, ent) || this.baseManagers[0]; + base = PETRA.getBestBase(gameState, ent) || this.baseManagers[0]; base.assignEntity(gameState, ent); if (ent.decaying()) { @@ -431,7 +427,7 @@ let base; if (ent.getMetadata(PlayerID, "base") === undefined) { - base = m.getBestBase(gameState, ent); + base = PETRA.getBestBase(gameState, ent); base.assignEntity(gameState, ent); } else @@ -446,12 +442,12 @@ continue; let dropsites = gameState.getOwnDropsites(type.generic); let pos = ent.position(); - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); let distmin = Math.min(); let goal; for (let dropsite of dropsites.values()) { - if (!dropsite.position() || m.getLandAccess(gameState, dropsite) != access) + if (!dropsite.position() || PETRA.getLandAccess(gameState, dropsite) != access) continue; let dist = API3.SquareVectorDistance(pos, dropsite.position()); if (dist > distmin) @@ -538,7 +534,7 @@ }; /** Ensure that all requirements are met when phasing up*/ -m.HQ.prototype.checkPhaseRequirements = function(gameState, queues) +PETRA.HQ.prototype.checkPhaseRequirements = function(gameState, queues) { if (gameState.getNumberOfPhases() == this.currentPhase) return; @@ -563,27 +559,27 @@ if (!gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities() && this.canBuild(gameState, "structures/{civ}_market")) { - plan = new m.ConstructionPlan(gameState, "structures/{civ}_market", { "phaseUp": true }); + plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_market", { "phaseUp": true }); queue = "economicBuilding"; break; } if (!gameState.getOwnEntitiesByClass("Temple", true).hasEntities() && this.canBuild(gameState, "structures/{civ}_temple")) { - plan = new m.ConstructionPlan(gameState, "structures/{civ}_temple", { "phaseUp": true }); + plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_temple", { "phaseUp": true }); queue = "economicBuilding"; break; } if (!gameState.getOwnEntitiesByClass("Blacksmith", true).hasEntities() && this.canBuild(gameState, "structures/{civ}_blacksmith")) { - plan = new m.ConstructionPlan(gameState, "structures/{civ}_blacksmith", { "phaseUp": true }); + plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_blacksmith", { "phaseUp": true }); queue = "militaryBuilding"; break; } if (this.canBuild(gameState, "structures/{civ}_defense_tower")) { - plan = new m.ConstructionPlan(gameState, "structures/{civ}_defense_tower", { "phaseUp": true }); + plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_defense_tower", { "phaseUp": true }); queue = "defenseBuilding"; break; } @@ -597,7 +593,7 @@ { let structure = this.buildManager.findStructureWithClass(gameState, [entityReq.class]); if (structure && this.canBuild(gameState, structure)) - plan = new m.ConstructionPlan(gameState, structure, { "phaseUp": true }); + plan = new PETRA.ConstructionPlan(gameState, structure, { "phaseUp": true }); } } @@ -620,12 +616,12 @@ }; /** Called by any "phase" research plan once it's started */ -m.HQ.prototype.OnPhaseUp = function(gameState, phase) +PETRA.HQ.prototype.OnPhaseUp = function(gameState, phase) { }; /** This code trains citizen workers, trying to keep close to a ratio of worker/soldiers */ -m.HQ.prototype.trainMoreWorkers = function(gameState, queues) +PETRA.HQ.prototype.trainMoreWorkers = function(gameState, queues) { // default template let requirementsDef = [ ["costsResource", 1, "food"] ]; @@ -725,13 +721,13 @@ // 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 m.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0, "support": true }, size, size)); + queues.villager.addPlan(new PETRA.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0, "support": true }, size, size)); else if (template) - queues.citizenSoldier.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size)); + queues.citizenSoldier.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size)); }; /** picks the best template based on parameters and classes */ -m.HQ.prototype.findBestTrainableUnit = function(gameState, classes, requirements) +PETRA.HQ.prototype.findBestTrainableUnit = function(gameState, classes, requirements) { let units; if (classes.indexOf("Hero") != -1) @@ -776,13 +772,13 @@ { if (param[0] == "strength") { - aValue += m.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; - bValue += m.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; + aValue += PETRA.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; + bValue += PETRA.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance) * param[1]; } else if (param[0] == "siegeStrength") { - aValue += m.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; - bValue += m.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; + aValue += PETRA.getMaxStrength(a[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; + bValue += PETRA.getMaxStrength(b[1], gameState.ai.Config.debug, gameState.ai.Config.DamageTypeImportance, "Structure") * param[1]; } else if (param[0] == "speed") { @@ -817,7 +813,7 @@ * returns an entity collection of workers through BaseManager.pickBuilders * TODO: when same accessIndex, sort by distance */ -m.HQ.prototype.bulkPickWorkers = function(gameState, baseRef, number) +PETRA.HQ.prototype.bulkPickWorkers = function(gameState, baseRef, number) { let accessIndex = baseRef.accessIndex; if (!accessIndex) @@ -847,7 +843,7 @@ return workers; }; -m.HQ.prototype.getTotalResourceLevel = function(gameState) +PETRA.HQ.prototype.getTotalResourceLevel = function(gameState) { let total = {}; for (let res of Resources.GetCodes()) @@ -863,7 +859,7 @@ * Returns the current gather rate * This is not per-se exact, it performs a few adjustments ad-hoc to account for travel distance, stuffs like that. */ -m.HQ.prototype.GetCurrentGatherRates = function(gameState) +PETRA.HQ.prototype.GetCurrentGatherRates = function(gameState) { if (!this.turnCache.currentRates) { @@ -886,7 +882,7 @@ /** * Returns the wanted gather rate. */ -m.HQ.prototype.GetWantedGatherRates = function(gameState) +PETRA.HQ.prototype.GetWantedGatherRates = function(gameState) { if (!this.turnCache.wantedRates) this.turnCache.wantedRates = gameState.ai.queueManager.wantedGatherRates(gameState); @@ -902,7 +898,7 @@ * We compare; we pick the one where the discrepancy is highest. * Need to balance long-term needs and possible short-term needs. */ -m.HQ.prototype.pickMostNeededResources = function(gameState) +PETRA.HQ.prototype.pickMostNeededResources = function(gameState) { let wantedRates = this.GetWantedGatherRates(gameState); let currentRates = this.GetCurrentGatherRates(gameState); @@ -935,7 +931,7 @@ * Returns the best position to build a new Civil Center * Whose primary function would be to reach new resources of type "resource". */ -m.HQ.prototype.findEconomicCCLocation = function(gameState, template, resource, proximity, fromStrategic) +PETRA.HQ.prototype.findEconomicCCLocation = function(gameState, template, resource, proximity, fromStrategic) { // This builds a map. The procedure is fairly simple. It adds the resource maps // (which are dynamically updated and are made so that they will facilitate DP placement) @@ -944,7 +940,7 @@ Engine.ProfileStart("findEconomicCCLocation"); // obstruction map - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); let halfSize = 0; if (template.get("Footprint/Square")) halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; @@ -1042,7 +1038,7 @@ if (dist < minDist) minDist = dist; - accessible = accessible || index == m.getLandAccess(gameState, cc.ent); + accessible = accessible || index == PETRA.getLandAccess(gameState, cc.ent); } if (norm == 0) continue; @@ -1064,7 +1060,7 @@ } // Not near any of our dropsite, except for oversea docks - oversea = !accessible && dpList.some(dp => m.getLandAccess(gameState, dp.ent) == index); + oversea = !accessible && dpList.some(dp => PETRA.getLandAccess(gameState, dp.ent) == index); if (!oversea) { for (let dp of dpList) @@ -1083,7 +1079,7 @@ continue; } - if (this.borderMap.map[j] & m.fullBorder_Mask) // disfavor the borders of the map + if (this.borderMap.map[j] & PETRA.fullBorder_Mask) // disfavor the borders of the map norm *= 0.5; let val = 2*gameState.sharedScript.ccResourceMaps[resource].map[j]; @@ -1135,7 +1131,7 @@ * Returns the best position to build a new Civil Center * Whose primary function would be to assure territorial continuity with our allies */ -m.HQ.prototype.findStrategicCCLocation = function(gameState, template) +PETRA.HQ.prototype.findStrategicCCLocation = function(gameState, template) { // This builds a map. The procedure is fairly simple. // We minimize the Sum((dist-300)**2) where the sum is on the three nearest allied CC @@ -1158,7 +1154,7 @@ Engine.ProfileStart("findStrategicCCLocation"); // obstruction map - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); let halfSize = 0; if (template.get("Footprint/Square")) halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; @@ -1238,7 +1234,7 @@ currentVal += delta*delta; } // disfavor border of the map - if (this.borderMap.map[j] & m.fullBorder_Mask) + if (this.borderMap.map[j] & PETRA.fullBorder_Mask) currentVal += 10000; if (bestVal !== undefined && currentVal > bestVal) @@ -1281,7 +1277,7 @@ * To do so, we suppose that the gain/distance is an increasing function of distance and look for the max distance * for performance reasons. */ -m.HQ.prototype.findMarketLocation = function(gameState, template) +PETRA.HQ.prototype.findMarketLocation = function(gameState, template) { let markets = gameState.updatingCollection("diplo-ExclusiveAllyMarkets", API3.Filters.byClass("Market"), gameState.getExclusiveAllyEntities()).toEntityArray(); if (!markets.length) @@ -1291,7 +1287,7 @@ return [-1, -1, -1, 0]; // obstruction map - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); let halfSize = 0; if (template.get("Footprint/Square")) halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; @@ -1314,7 +1310,7 @@ for (let j = 0; j < this.territoryMap.length; ++j) { // do not try on the narrow border of our territory - if (this.borderMap.map[j] & m.narrowFrontier_Mask) + if (this.borderMap.map[j] & PETRA.narrowFrontier_Mask) continue; if (this.basesMap.map[j] == 0) // only in our territory continue; @@ -1335,12 +1331,12 @@ { if (isNavalMarket && market.hasClass("NavalMarket")) { - if (m.getSeaAccess(gameState, market) != gameState.ai.accessibility.getAccessValue(pos, true)) + if (PETRA.getSeaAccess(gameState, market) != gameState.ai.accessibility.getAccessValue(pos, true)) continue; gainMultiplier = traderTemplatesGains.navalGainMultiplier; } - else if (m.getLandAccess(gameState, market) == index && - !m.isLineInsideEnemyTerritory(gameState, market.position(), pos)) + else if (PETRA.getLandAccess(gameState, market) == index && + !PETRA.isLineInsideEnemyTerritory(gameState, market.position(), pos)) gainMultiplier = traderTemplatesGains.landGainMultiplier; else continue; @@ -1397,7 +1393,7 @@ * Returns the best position to build defensive buildings (fortress and towers) * Whose primary function is to defend our borders */ -m.HQ.prototype.findDefensiveLocation = function(gameState, template) +PETRA.HQ.prototype.findDefensiveLocation = function(gameState, template) { // We take the point in our territory which is the nearest to any enemy cc // but requiring a minimal distance with our other defensive structures @@ -1430,7 +1426,7 @@ } // obstruction map - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); let halfSize = 0; if (template.get("Footprint/Square")) halfSize = Math.max(+template.get("Footprint/Square/@depth"), +template.get("Footprint/Square/@width")) / 2; @@ -1456,9 +1452,9 @@ if (!wonderMode) { // do not try if well inside or outside territory - if (!(this.borderMap.map[j] & m.fullFrontier_Mask)) + if (!(this.borderMap.map[j] & PETRA.fullFrontier_Mask)) continue; - if (this.borderMap.map[j] & m.largeFrontier_Mask && isTower) + if (this.borderMap.map[j] & PETRA.largeFrontier_Mask && isTower) continue; } if (this.basesMap.map[j] == 0) // inaccessible cell @@ -1531,7 +1527,7 @@ return [x, z, this.basesMap.map[bestJdx]]; }; -m.HQ.prototype.buildTemple = function(gameState, queues) +PETRA.HQ.prototype.buildTemple = function(gameState, queues) { // at least one market (which have the same queue) should be build before any temple if (queues.economicBuilding.hasQueuedUnits() || @@ -1547,10 +1543,10 @@ templateName = "structures/{civ}_temple_vesta"; else if (!this.canBuild(gameState, templateName)) return; - queues.economicBuilding.addPlan(new m.ConstructionPlan(gameState, templateName)); + queues.economicBuilding.addPlan(new PETRA.ConstructionPlan(gameState, templateName)); }; -m.HQ.prototype.buildMarket = function(gameState, queues) +PETRA.HQ.prototype.buildMarket = function(gameState, queues) { if (gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities() || !this.canBuild(gameState, "structures/{civ}_market")) @@ -1580,13 +1576,13 @@ } gameState.ai.queueManager.changePriority("economicBuilding", 3*this.Config.priorities.economicBuilding); - let plan = new m.ConstructionPlan(gameState, "structures/{civ}_market"); + let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_market"); plan.queueToReset = "economicBuilding"; queues.economicBuilding.addPlan(plan); }; /** Build a farmstead */ -m.HQ.prototype.buildFarmstead = function(gameState, queues) +PETRA.HQ.prototype.buildFarmstead = function(gameState, queues) { // Only build one farmstead for the time being ("DropsiteFood" does not refer to CCs) if (gameState.getOwnEntitiesByClass("Farmstead", true).hasEntities()) @@ -1601,14 +1597,14 @@ if (!this.canBuild(gameState, "structures/{civ}_farmstead")) return; - queues.economicBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_farmstead")); + queues.economicBuilding.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_farmstead")); }; /** * Try to build a wonder when required * force = true when called from the victoryManager in case of Wonder victory condition. */ -m.HQ.prototype.buildWonder = function(gameState, queues, force = false) +PETRA.HQ.prototype.buildWonder = function(gameState, queues, force = false) { if (queues.wonder && queues.wonder.hasQueuedUnits() || gameState.getOwnEntitiesByClass("Wonder", true).hasEntities() || @@ -1634,11 +1630,11 @@ return; } - queues.wonder.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_wonder")); + queues.wonder.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_wonder")); }; /** Build a corral, and train animals there */ -m.HQ.prototype.manageCorral = function(gameState, queues) +PETRA.HQ.prototype.manageCorral = function(gameState, queues) { if (queues.corral.hasQueuedUnits()) return; @@ -1649,7 +1645,7 @@ { if (this.canBuild(gameState, "structures/{civ}_corral")) { - queues.corral.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_corral")); + queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_corral")); return; } if (!nCorral) @@ -1675,7 +1671,7 @@ count += item.count; if (count > nCorral) continue; - queues.corral.addPlan(new m.TrainingPlan(gameState, trainable, { "trainer": corral.id() })); + queues.corral.addPlan(new PETRA.TrainingPlan(gameState, trainable, { "trainer": corral.id() })); return; } } @@ -1685,7 +1681,7 @@ * build more houses if needed. * kinda ugly, lots of special cases to both build enough houses but not tooo many… */ -m.HQ.prototype.buildMoreHouses = function(gameState, queues) +PETRA.HQ.prototype.buildMoreHouses = function(gameState, queues) { if (!gameState.isTemplateAvailable(gameState.applyCiv("structures/{civ}_house")) || gameState.getPopulationMax() <= gameState.getPopulationLimit()) @@ -1694,7 +1690,7 @@ let numPlanned = queues.house.length(); if (numPlanned < 3 || numPlanned < 5 && gameState.getPopulation() > 80) { - let plan = new m.ConstructionPlan(gameState, "structures/{civ}_house"); + let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_house"); // change the starting condition according to the situation. plan.goRequirement = "houseNeeded"; queues.house.addPlan(plan); @@ -1768,7 +1764,7 @@ }; /** Checks the status of the territory expansion. If no new economic bases created, build some strategic ones. */ -m.HQ.prototype.checkBaseExpansion = function(gameState, queues) +PETRA.HQ.prototype.checkBaseExpansion = function(gameState, queues) { if (queues.civilCentre.hasQueuedUnits()) return; @@ -1801,7 +1797,7 @@ } }; -m.HQ.prototype.buildNewBase = function(gameState, queues, resource) +PETRA.HQ.prototype.buildNewBase = function(gameState, queues, resource) { if (this.numPotentialBases() > 0 && this.currentPhase == 1 && !gameState.isResearching(gameState.getPhaseName(2))) return false; @@ -1830,12 +1826,12 @@ // base "-1" means new base. if (this.Config.debug > 1) API3.warn("new base " + gameState.applyCiv(template) + " planned with resource " + resource); - queues.civilCentre.addPlan(new m.ConstructionPlan(gameState, template, { "base": -1, "resource": resource })); + queues.civilCentre.addPlan(new PETRA.ConstructionPlan(gameState, template, { "base": -1, "resource": resource })); return true; }; /** Deals with building fortresses and towers along our border with enemies. */ -m.HQ.prototype.buildDefenses = function(gameState, queues) +PETRA.HQ.prototype.buildDefenses = function(gameState, queues) { if (this.saveResources && !this.canBarter || queues.defenseBuilding.hasQueuedUnits()) return; @@ -1854,7 +1850,7 @@ this.fortressStartTime = gameState.ai.elapsedTime; if (!numFortresses) gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding); - let plan = new m.ConstructionPlan(gameState, "structures/{civ}_fortress"); + let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_fortress"); plan.queueToReset = "defenseBuilding"; queues.defenseBuilding.addPlan(plan); return; @@ -1869,7 +1865,7 @@ if (numTowers < this.Config.Military.numSentryTowers && gameState.ai.elapsedTime > towerLapseTime + this.fortStartTime) { this.fortStartTime = gameState.ai.elapsedTime; - queues.defenseBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_sentry_tower")); + queues.defenseBuilding.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_sentry_tower")); } return; } @@ -1887,13 +1883,13 @@ this.towerStartTime = gameState.ai.elapsedTime; if (numTowers > 2 * this.numActiveBases() + 3) gameState.ai.queueManager.changePriority("defenseBuilding", Math.round(0.7*this.Config.priorities.defenseBuilding)); - let plan = new m.ConstructionPlan(gameState, "structures/{civ}_defense_tower"); + let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_defense_tower"); plan.queueToReset = "defenseBuilding"; queues.defenseBuilding.addPlan(plan); } }; -m.HQ.prototype.buildBlacksmith = function(gameState, queues) +PETRA.HQ.prototype.buildBlacksmith = function(gameState, queues) { if (this.getAccountedPopulation(gameState) < this.Config.Military.popForBlacksmith || queues.militaryBuilding.hasQueuedUnits() || gameState.getOwnEntitiesByClass("Blacksmith", true).length) @@ -1903,14 +1899,14 @@ return; if (this.canBuild(gameState, "structures/{civ}_blacksmith")) - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_blacksmith")); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_blacksmith")); }; /** * Deals with constructing military buildings (barracks, stables…) * They are mostly defined by Config.js. This is unreliable since changes could be done easily. */ -m.HQ.prototype.constructTrainingBuildings = function(gameState, queues) +PETRA.HQ.prototype.constructTrainingBuildings = function(gameState, queues) { if (this.saveResources && !this.canBarter || queues.militaryBuilding.hasQueuedUnits()) return; @@ -1937,7 +1933,7 @@ if (template) { gameState.ai.queueManager.changePriority("militaryBuilding", 2 * this.Config.priorities.militaryBuilding); - let plan = new m.ConstructionPlan(gameState, template, { "militaryBase": true }); + let plan = new PETRA.ConstructionPlan(gameState, template, { "militaryBase": true }); plan.queueToReset = "militaryBuilding"; queues.militaryBuilding.addPlan(plan); return; @@ -1945,7 +1941,7 @@ } if (numStables == 0 && stableTemplate) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, stableTemplate, { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, stableTemplate, { "militaryBase": true })); return; } @@ -1955,13 +1951,13 @@ let template = numBarracks == 0 ? (barracksTemplate || rangeTemplate) : (rangeTemplate || barracksTemplate); if (template) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, template, { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, template, { "militaryBase": true })); return; } } if (numStables == 1 && stableTemplate && this.getAccountedPopulation(gameState) > this.Config.Military.popForBarracks2) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, stableTemplate, { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, stableTemplate, { "militaryBase": true })); return; } @@ -1971,7 +1967,7 @@ let template = barracksTemplate || stableTemplate || rangeTemplate; if (template) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, template, { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, template, { "militaryBase": true })); return; } } @@ -1985,13 +1981,13 @@ if (this.canBuild(gameState, "structures/{civ}_elephant_stables") && !gameState.getOwnEntitiesByClass("ElephantStable", true).hasEntities()) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_elephant_stables", { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_elephant_stables", { "militaryBase": true })); return; } if (this.canBuild(gameState, "structures/{civ}_workshop") && !gameState.getOwnEntitiesByClass("Workshop", true).hasEntities()) { - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_workshop", { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_workshop", { "militaryBase": true })); return; } @@ -2014,9 +2010,9 @@ continue; let civ = gameState.getPlayerCiv(); if (template.hasDefensiveFire() || template.trainableEntities(civ)) - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced, { "militaryBase": true })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, advanced, { "militaryBase": true })); else // not a military building, but still use this queue - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, advanced)); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, advanced)); return; } } @@ -2025,7 +2021,7 @@ /** * Find base nearest to ennemies for military buildings. */ -m.HQ.prototype.findBestBaseForMilitary = function(gameState) +PETRA.HQ.prototype.findBestBaseForMilitary = function(gameState) { let ccEnts = gameState.updatingGlobalCollection("allCCs", API3.Filters.byClass("CivCentre")).toEntityArray(); let bestBase; @@ -2037,13 +2033,13 @@ continue; if (enemyFound && !gameState.isPlayerEnemy(cce.owner())) continue; - let access = m.getLandAccess(gameState, cce); + let access = PETRA.getLandAccess(gameState, cce); let isEnemy = gameState.isPlayerEnemy(cce.owner()); for (let cc of ccEnts) { if (cc.owner() != PlayerID) continue; - if (m.getLandAccess(gameState, cc) != access) + if (PETRA.getLandAccess(gameState, cc) != access) continue; let dist = API3.SquareVectorDistance(cc.position(), cce.position()); if (!enemyFound && isEnemy) @@ -2061,7 +2057,7 @@ * train with highest priority ranged infantry in the nearest civil center from a given set of positions * and garrison them there for defense */ -m.HQ.prototype.trainEmergencyUnits = function(gameState, positions) +PETRA.HQ.prototype.trainEmergencyUnits = function(gameState, positions) { if (gameState.ai.queues.emergency.hasQueuedUnits()) return false; @@ -2079,7 +2075,7 @@ { if (!base.anchor || !base.anchor.position()) continue; - if (m.getLandAccess(gameState, base.anchor) != access) + if (PETRA.getLandAccess(gameState, base.anchor) != access) continue; if (!base.anchor.trainableEntities(civ)) // base still in construction continue; @@ -2162,11 +2158,11 @@ let metadata = { "role": "worker", "base": nearestAnchor.getMetadata(PlayerID, "base"), "plan": -1, "trainer": nearestAnchor.id() }; if (autogarrison) metadata.garrisonType = "protection"; - gameState.ai.queues.emergency.addPlan(new m.TrainingPlan(gameState, templateFound[0], metadata, 1, 1)); + gameState.ai.queues.emergency.addPlan(new PETRA.TrainingPlan(gameState, templateFound[0], metadata, 1, 1)); return true; }; -m.HQ.prototype.canBuild = function(gameState, structure) +PETRA.HQ.prototype.canBuild = function(gameState, structure) { let type = gameState.applyCiv(structure); if (this.buildManager.isUnbuildable(gameState, type)) @@ -2220,7 +2216,7 @@ return true; }; -m.HQ.prototype.updateTerritories = function(gameState) +PETRA.HQ.prototype.updateTerritories = function(gameState) { const around = [ [-0.7, 0.7], [0, 1], [0.7, 0.7], [1, 0], [0.7, -0.7], [0, -1], [-0.7, -0.7], [-1, 0] ]; let alliedVictory = gameState.getAlliedVictory(); @@ -2233,10 +2229,10 @@ for (let j = 0; j < this.territoryMap.length; ++j) { - if (this.borderMap.map[j] & m.outside_Mask) + if (this.borderMap.map[j] & PETRA.outside_Mask) continue; - if (this.borderMap.map[j] & m.fullFrontier_Mask) - this.borderMap.map[j] &= ~m.fullFrontier_Mask; // reset the frontier + if (this.borderMap.map[j] & PETRA.fullFrontier_Mask) + this.borderMap.map[j] &= ~PETRA.fullFrontier_Mask; // reset the frontier if (this.territoryMap.getOwnerIndex(j) != PlayerID) { @@ -2270,12 +2266,12 @@ let jz = iz + Math.round(insideSmall*a[1]); if (jz < 0 || jz >= width) continue; - if (this.borderMap.map[jx+width*jz] & m.outside_Mask) + if (this.borderMap.map[jx+width*jz] & PETRA.outside_Mask) continue; let territoryOwner = this.territoryMap.getOwnerIndex(jx+width*jz); if (territoryOwner != PlayerID && !(alliedVictory && gameState.isPlayerAlly(territoryOwner))) { - this.borderMap.map[j] |= m.narrowFrontier_Mask; + this.borderMap.map[j] |= PETRA.narrowFrontier_Mask; break; } jx = ix + Math.round(insideLarge*a[0]); @@ -2284,14 +2280,14 @@ jz = iz + Math.round(insideLarge*a[1]); if (jz < 0 || jz >= width) continue; - if (this.borderMap.map[jx+width*jz] & m.outside_Mask) + if (this.borderMap.map[jx+width*jz] & PETRA.outside_Mask) continue; territoryOwner = this.territoryMap.getOwnerIndex(jx+width*jz); if (territoryOwner != PlayerID && !(alliedVictory && gameState.isPlayerAlly(territoryOwner))) onFrontier = true; } - if (onFrontier && !(this.borderMap.map[j] & m.narrowFrontier_Mask)) - this.borderMap.map[j] |= m.largeFrontier_Mask; + if (onFrontier && !(this.borderMap.map[j] & PETRA.narrowFrontier_Mask)) + this.borderMap.map[j] |= PETRA.largeFrontier_Mask; // If this tile was not already accounted, add it. if (this.basesMap.map[j] != 0) @@ -2343,7 +2339,7 @@ }; /** Reassign territories when a base is going to be deleted */ -m.HQ.prototype.reassignTerritories = function(deletedBase) +PETRA.HQ.prototype.reassignTerritories = function(deletedBase) { let cellSize = this.territoryMap.cellSize; let width = this.territoryMap.width; @@ -2386,7 +2382,7 @@ /** * returns the base corresponding to baseID */ -m.HQ.prototype.getBaseByID = function(baseID) +PETRA.HQ.prototype.getBaseByID = function(baseID) { for (let base of this.baseManagers) if (base.ID == baseID) @@ -2400,21 +2396,21 @@ * ActiveBases includes only those with a built cc * PotentialBases includes also those with a cc in construction */ -m.HQ.prototype.numActiveBases = function() +PETRA.HQ.prototype.numActiveBases = function() { if (!this.turnCache.base) this.updateBaseCache(); return this.turnCache.base.active; }; -m.HQ.prototype.numPotentialBases = function() +PETRA.HQ.prototype.numPotentialBases = function() { if (!this.turnCache.base) this.updateBaseCache(); return this.turnCache.base.potential; }; -m.HQ.prototype.updateBaseCache = function() +PETRA.HQ.prototype.updateBaseCache = function() { this.turnCache.base = { "active": 0, "potential": 0 }; for (let base of this.baseManagers) @@ -2427,7 +2423,7 @@ } }; -m.HQ.prototype.resetBaseCache = function() +PETRA.HQ.prototype.resetBaseCache = function() { this.turnCache.base = undefined; }; @@ -2436,7 +2432,7 @@ * Count gatherers returning resources in the number of gatherers of resourceSupplies * to prevent the AI always reassigning idle workers to these resourceSupplies (specially in naval maps). */ -m.HQ.prototype.assignGatherers = function() +PETRA.HQ.prototype.assignGatherers = function() { for (let base of this.baseManagers) { @@ -2452,13 +2448,13 @@ } }; -m.HQ.prototype.isDangerousLocation = function(gameState, pos, radius) +PETRA.HQ.prototype.isDangerousLocation = function(gameState, pos, radius) { return this.isNearInvadingArmy(pos) || this.isUnderEnemyFire(gameState, pos, radius); }; /** Check that the chosen position is not too near from an invading army */ -m.HQ.prototype.isNearInvadingArmy = function(pos) +PETRA.HQ.prototype.isNearInvadingArmy = function(pos) { for (let army of this.defenseManager.armies) if (army.foePosition && API3.SquareVectorDistance(army.foePosition, pos) < 12000) @@ -2466,7 +2462,7 @@ return false; }; -m.HQ.prototype.isUnderEnemyFire = function(gameState, pos, radius = 0) +PETRA.HQ.prototype.isUnderEnemyFire = function(gameState, pos, radius = 0) { if (!this.turnCache.firingStructures) this.turnCache.firingStructures = gameState.updatingCollection("diplo-FiringStructures", API3.Filters.hasDefensiveFire(), gameState.getEnemyStructures()); @@ -2480,7 +2476,7 @@ }; /** Compute the capture strength of all units attacking a capturable target */ -m.HQ.prototype.updateCaptureStrength = function(gameState) +PETRA.HQ.prototype.updateCaptureStrength = function(gameState) { this.capturableTargets.clear(); for (let ent of gameState.getOwnUnits().values()) @@ -2499,13 +2495,13 @@ continue; if (!this.capturableTargets.has(targetId)) this.capturableTargets.set(targetId, { - "strength": ent.captureStrength() * m.getAttackBonus(ent, target, "Capture"), + "strength": ent.captureStrength() * PETRA.getAttackBonus(ent, target, "Capture"), "ents": new Set([ent.id()]) }); else { let capturableTarget = this.capturableTargets.get(target.id()); - capturableTarget.strength += ent.captureStrength() * m.getAttackBonus(ent, target, "Capture"); + capturableTarget.strength += ent.captureStrength() * PETRA.getAttackBonus(ent, target, "Capture"); capturableTarget.ents.add(ent.id()); } } @@ -2518,7 +2514,7 @@ { let ent = gameState.getEntityById(entId); if (allowCapture === undefined) - allowCapture = m.allowCapture(gameState, ent, target); + allowCapture = PETRA.allowCapture(gameState, ent, target); let orderData = ent.unitAIOrderData(); if (!orderData || !orderData.length || !orderData[0].attackType) continue; @@ -2533,7 +2529,7 @@ /** Some functions that register that we assigned a gatherer to a resource this turn */ /** add a gatherer to the turn cache for this supply. */ -m.HQ.prototype.AddTCGatherer = function(supplyID) +PETRA.HQ.prototype.AddTCGatherer = function(supplyID) { if (this.turnCache.resourceGatherer && this.turnCache.resourceGatherer[supplyID] !== undefined) ++this.turnCache.resourceGatherer[supplyID]; @@ -2546,7 +2542,7 @@ }; /** remove a gatherer to the turn cache for this supply. */ -m.HQ.prototype.RemoveTCGatherer = function(supplyID) +PETRA.HQ.prototype.RemoveTCGatherer = function(supplyID) { if (this.turnCache.resourceGatherer && this.turnCache.resourceGatherer[supplyID]) --this.turnCache.resourceGatherer[supplyID]; @@ -2558,7 +2554,7 @@ } }; -m.HQ.prototype.GetTCGatherer = function(supplyID) +PETRA.HQ.prototype.GetTCGatherer = function(supplyID) { if (this.turnCache.resourceGatherer && this.turnCache.resourceGatherer[supplyID]) return this.turnCache.resourceGatherer[supplyID]; @@ -2567,7 +2563,7 @@ }; /** The next two are to register that we assigned a gatherer to a resource this turn. */ -m.HQ.prototype.AddTCResGatherer = function(resource) +PETRA.HQ.prototype.AddTCResGatherer = function(resource) { if (this.turnCache["resourceGatherer-" + resource]) ++this.turnCache["resourceGatherer-" + resource]; @@ -2578,7 +2574,7 @@ this.turnCache.currentRates[resource] += 0.5; }; -m.HQ.prototype.GetTCResGatherer = function(resource) +PETRA.HQ.prototype.GetTCResGatherer = function(resource) { if (this.turnCache["resourceGatherer-" + resource]) return this.turnCache["resourceGatherer-" + resource]; @@ -2589,7 +2585,7 @@ /** * flag a resource as exhausted */ -m.HQ.prototype.isResourceExhausted = function(resource) +PETRA.HQ.prototype.isResourceExhausted = function(resource) { if (this.turnCache["exhausted-" + resource] == undefined) this.turnCache["exhausted-" + resource] = this.baseManagers.every(base => @@ -2603,7 +2599,7 @@ /** * Check if a structure in blinking territory should/can be defended (currently if it has some attacking armies around) */ -m.HQ.prototype.isDefendable = function(ent) +PETRA.HQ.prototype.isDefendable = function(ent) { if (!this.turnCache.numAround) this.turnCache.numAround = {}; @@ -2615,7 +2611,7 @@ /** * Get the number of population already accounted for */ -m.HQ.prototype.getAccountedPopulation = function(gameState) +PETRA.HQ.prototype.getAccountedPopulation = function(gameState) { if (this.turnCache.accountedPopulation == undefined) { @@ -2639,7 +2635,7 @@ /** * Get the number of workers already accounted for */ -m.HQ.prototype.getAccountedWorkers = function(gameState) +PETRA.HQ.prototype.getAccountedWorkers = function(gameState) { if (this.turnCache.accountedWorkers == undefined) { @@ -2662,11 +2658,11 @@ * Some functions are run every turn * Others once in a while */ -m.HQ.prototype.update = function(gameState, queues, events) +PETRA.HQ.prototype.update = function(gameState, queues, events) { Engine.ProfileStart("Headquarters update"); this.turnCache = {}; - this.territoryMap = m.createTerritoryMap(gameState); + this.territoryMap = PETRA.createTerritoryMap(gameState); this.canBarter = gameState.getOwnEntitiesByClass("BarterMarket", true).filter(API3.Filters.isBuilt()).hasEntities(); // TODO find a better way to update if (this.currentPhase != gameState.currentPhase()) @@ -2688,7 +2684,7 @@ gameState.getOwnUnits().forEach (function (ent) { if (!ent.position()) return; - m.dumpEntity(ent); + PETRA.dumpEntity(ent); }); } */ @@ -2778,7 +2774,7 @@ Engine.ProfileStop(); }; -m.HQ.prototype.Serialize = function() +PETRA.HQ.prototype.Serialize = function() { let properties = { "phasing": this.phasing, @@ -2843,7 +2839,7 @@ }; }; -m.HQ.prototype.Deserialize = function(gameState, data) +PETRA.HQ.prototype.Deserialize = function(gameState, data) { for (let key in data.properties) this[key] = data.properties[key]; @@ -2852,45 +2848,41 @@ for (let base of data.baseManagers) { // the first call to deserialize set the ID base needed by entitycollections - let newbase = new m.BaseManager(gameState, this.Config); + let newbase = new PETRA.BaseManager(gameState, this.Config); newbase.Deserialize(gameState, base); newbase.init(gameState); newbase.Deserialize(gameState, base); this.baseManagers.push(newbase); } - this.navalManager = new m.NavalManager(this.Config); + this.navalManager = new PETRA.NavalManager(this.Config); this.navalManager.init(gameState, true); this.navalManager.Deserialize(gameState, data.navalManager); - this.attackManager = new m.AttackManager(this.Config); + this.attackManager = new PETRA.AttackManager(this.Config); this.attackManager.Deserialize(gameState, data.attackManager); this.attackManager.init(gameState); this.attackManager.Deserialize(gameState, data.attackManager); - this.buildManager = new m.BuildManager(); + this.buildManager = new PETRA.BuildManager(); this.buildManager.Deserialize(data.buildManager); - this.defenseManager = new m.DefenseManager(this.Config); + this.defenseManager = new PETRA.DefenseManager(this.Config); this.defenseManager.Deserialize(gameState, data.defenseManager); - this.tradeManager = new m.TradeManager(this.Config); + this.tradeManager = new PETRA.TradeManager(this.Config); this.tradeManager.init(gameState); this.tradeManager.Deserialize(gameState, data.tradeManager); - this.researchManager = new m.ResearchManager(this.Config); + this.researchManager = new PETRA.ResearchManager(this.Config); this.researchManager.Deserialize(data.researchManager); - this.diplomacyManager = new m.DiplomacyManager(this.Config); + this.diplomacyManager = new PETRA.DiplomacyManager(this.Config); this.diplomacyManager.Deserialize(data.diplomacyManager); - this.garrisonManager = new m.GarrisonManager(this.Config); + this.garrisonManager = new PETRA.GarrisonManager(this.Config); this.garrisonManager.Deserialize(data.garrisonManager); - this.victoryManager = new m.VictoryManager(this.Config); + this.victoryManager = new PETRA.VictoryManager(this.Config); this.victoryManager.Deserialize(data.victoryManager); }; - -return m; - -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js @@ -1,12 +1,9 @@ -var PETRA = function(m) -{ - /** map functions */ -m.TERRITORY_PLAYER_MASK = 0x1F; -m.TERRITORY_BLINKING_MASK = 0x40; +PETRA.TERRITORY_PLAYER_MASK = 0x1F; +PETRA.TERRITORY_BLINKING_MASK = 0x40; -m.createObstructionMap = function(gameState, accessIndex, template) +PETRA.createObstructionMap = function(gameState, accessIndex, template) { let passabilityMap = gameState.getPassabilityMap(); let territoryMap = gameState.ai.territoryMap; @@ -44,8 +41,8 @@ for (let k = 0; k < territoryMap.data.length; ++k) { - let tilePlayer = territoryMap.data[k] & m.TERRITORY_PLAYER_MASK; - let isConnected = (territoryMap.data[k] & m.TERRITORY_BLINKING_MASK) == 0; + let tilePlayer = territoryMap.data[k] & PETRA.TERRITORY_PLAYER_MASK; + let isConnected = (territoryMap.data[k] & PETRA.TERRITORY_BLINKING_MASK) == 0; if (tilePlayer === PlayerID) { if (!buildOwn || !buildNeutral && !isConnected) @@ -114,14 +111,14 @@ }; -m.createTerritoryMap = function(gameState) +PETRA.createTerritoryMap = function(gameState) { let map = gameState.ai.territoryMap; let ret = new API3.Map(gameState.sharedScript, "territory", map.data); - ret.getOwner = function(p) { return this.point(p) & m.TERRITORY_PLAYER_MASK; }; - ret.getOwnerIndex = function(p) { return this.map[p] & m.TERRITORY_PLAYER_MASK; }; - ret.isBlinking = function(p) { return (this.point(p) & m.TERRITORY_BLINKING_MASK) != 0; }; + ret.getOwner = function(p) { return this.point(p) & PETRA.TERRITORY_PLAYER_MASK; }; + ret.getOwnerIndex = function(p) { return this.map[p] & PETRA.TERRITORY_PLAYER_MASK; }; + ret.isBlinking = function(p) { return (this.point(p) & PETRA.TERRITORY_BLINKING_MASK) != 0; }; return ret; }; @@ -135,14 +132,14 @@ * - large border (inside our territory, exclusive of narrow) => bit 3 */ -m.outside_Mask = 1; -m.border_Mask = 2; -m.fullBorder_Mask = m.outside_Mask | m.border_Mask; -m.narrowFrontier_Mask = 4; -m.largeFrontier_Mask = 8; -m.fullFrontier_Mask = m.narrowFrontier_Mask | m.largeFrontier_Mask; +PETRA.outside_Mask = 1; +PETRA.border_Mask = 2; +PETRA.fullBorder_Mask = PETRA.outside_Mask | PETRA.border_Mask; +PETRA.narrowFrontier_Mask = 4; +PETRA.largeFrontier_Mask = 8; +PETRA.fullFrontier_Mask = PETRA.narrowFrontier_Mask | PETRA.largeFrontier_Mask; -m.createBorderMap = function(gameState) +PETRA.createBorderMap = function(gameState) { let map = new API3.Map(gameState.sharedScript, "territory"); let width = map.width; @@ -160,13 +157,13 @@ let radius = dx*dx + dy*dy; if (radius < radcut) continue; - map.map[j] = m.outside_Mask; + map.map[j] = PETRA.outside_Mask; let ind = API3.getMapIndices(j, map, passabilityMap); for (let k of ind) { if (passabilityMap.data[k] & obstructionMask) continue; - map.map[j] = m.border_Mask; + map.map[j] = PETRA.border_Mask; break; } } @@ -180,13 +177,13 @@ let iy = Math.floor(j/width); if (ix < border || ix >= borderCut || iy < border || iy >= borderCut) { - map.map[j] = m.outside_Mask; + map.map[j] = PETRA.outside_Mask; let ind = API3.getMapIndices(j, map, passabilityMap); for (let k of ind) { if (passabilityMap.data[k] & obstructionMask) continue; - map.map[j] = m.border_Mask; + map.map[j] = PETRA.border_Mask; break; } } @@ -197,7 +194,7 @@ return map; }; -m.debugMap = function(gameState, map) +PETRA.debugMap = function(gameState, map) { let width = map.width; let cell = map.cellSize; @@ -216,6 +213,3 @@ Engine.PostCommand(PlayerID, { "type": "set-shading-color", "entities": [ent.id()], "rgb": [0, 0, 2] }); }); }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Naval Manager * Will deal with anything ships. @@ -10,8 +7,7 @@ * -Scouting, ultimately. * Also deals with handling docks, making sure we have access and stuffs like that. */ - -m.NavalManager = function(Config) +PETRA.NavalManager = function(Config) { this.Config = Config; @@ -36,7 +32,7 @@ }; /** More initialisation for stuff that needs the gameState */ -m.NavalManager.prototype.init = function(gameState, deserializing) +PETRA.NavalManager.prototype.init = function(gameState, deserializing) { // docks this.docks = gameState.getOwnStructures().filter(API3.Filters.byClassesOr(["Dock", "Shipyard"])); @@ -156,18 +152,18 @@ // Assign our initial docks and ships for (let ship of this.ships.values()) - m.setSeaAccess(gameState, ship); + PETRA.setSeaAccess(gameState, ship); for (let dock of this.docks.values()) - m.setSeaAccess(gameState, dock); + PETRA.setSeaAccess(gameState, dock); }; -m.NavalManager.prototype.updateFishingBoats = function(sea, num) +PETRA.NavalManager.prototype.updateFishingBoats = function(sea, num) { if (this.wantedFishShips[sea]) this.wantedFishShips[sea] = num; }; -m.NavalManager.prototype.resetFishingBoats = function(gameState, sea) +PETRA.NavalManager.prototype.resetFishingBoats = function(gameState, sea) { if (sea !== undefined) this.wantedFishShips[sea] = 0; @@ -176,7 +172,7 @@ }; /** Get the sea, cache it if not yet done and check if in opensea */ -m.NavalManager.prototype.getFishSea = function(gameState, fish) +PETRA.NavalManager.prototype.getFishSea = function(gameState, fish) { let sea = fish.getMetadata(PlayerID, "sea"); if (sea) @@ -213,7 +209,7 @@ }; /** check if we can safely fish at the fish position */ -m.NavalManager.prototype.canFishSafely = function(gameState, fish) +PETRA.NavalManager.prototype.canFishSafely = function(gameState, fish) { if (fish.getMetadata(PlayerID, "opensea")) return true; @@ -239,20 +235,20 @@ }; /** get the list of seas (or lands) around this region not connected by a dock */ -m.NavalManager.prototype.getUnconnectedSeas = function(gameState, region) +PETRA.NavalManager.prototype.getUnconnectedSeas = function(gameState, region) { let seas = gameState.ai.accessibility.regionLinks[region].slice(); this.docks.forEach(dock => { - if (!dock.hasClass("Dock") || m.getLandAccess(gameState, dock) != region) + if (!dock.hasClass("Dock") || PETRA.getLandAccess(gameState, dock) != region) return; - let i = seas.indexOf(m.getSeaAccess(gameState, dock)); + let i = seas.indexOf(PETRA.getSeaAccess(gameState, dock)); if (i != -1) seas.splice(i--, 1); }); return seas; }; -m.NavalManager.prototype.checkEvents = function(gameState, queues, events) +PETRA.NavalManager.prototype.checkEvents = function(gameState, queues, events) { for (let evt of events.Create) { @@ -260,7 +256,7 @@ continue; let ent = gameState.getEntityById(evt.entity); if (ent && ent.isOwn(PlayerID) && ent.foundationProgress() !== undefined && (ent.hasClass("Dock") || ent.hasClass("Shipyard"))) - m.setSeaAccess(gameState, ent); + PETRA.setSeaAccess(gameState, ent); } for (let evt of events.TrainingFinished) @@ -272,7 +268,7 @@ let ent = gameState.getEntityById(entId); if (!ent || !ent.hasClass("Ship") || !ent.isOwn(PlayerID)) continue; - m.setSeaAccess(gameState, ent); + PETRA.setSeaAccess(gameState, ent); } } @@ -306,7 +302,7 @@ { if (!ent.position()) // unit from another ship of this plan ... do nothing continue; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); let endPos = ent.getMetadata(PlayerID, "endPos"); ent.setMetadata(PlayerID, "transport", undefined); ent.setMetadata(PlayerID, "onBoard", undefined); @@ -327,12 +323,12 @@ continue; let ent = gameState.getEntityById(evt.entity); if (ent && (ent.hasClass("Dock") || ent.hasClass("Shipyard"))) - m.setSeaAccess(gameState, ent); + PETRA.setSeaAccess(gameState, ent); } }; -m.NavalManager.prototype.getPlan = function(ID) +PETRA.NavalManager.prototype.getPlan = function(ID) { for (let plan of this.transportPlans) if (plan.ID === ID) @@ -340,7 +336,7 @@ return undefined; }; -m.NavalManager.prototype.addPlan = function(plan) +PETRA.NavalManager.prototype.addPlan = function(plan) { this.transportPlans.push(plan); }; @@ -350,7 +346,7 @@ * (many units can then call this separately and end up in the same plan) * TODO check garrison classes */ -m.NavalManager.prototype.requireTransport = function(gameState, ent, startIndex, endIndex, endPos) +PETRA.NavalManager.prototype.requireTransport = function(gameState, ent, startIndex, endIndex, endPos) { if (!ent.canGarrison()) return false; @@ -368,7 +364,7 @@ if (plan.startIndex != startIndex || plan.endIndex != endIndex || plan.state != "boarding") continue; // Limit the number of siege units per transport to avoid problems when ungarrisoning - if (m.isSiegeUnit(ent) && plan.units.filter(unit => m.isSiegeUnit(unit)).length > 3) + if (PETRA.isSiegeUnit(ent) && plan.units.filter(unit => PETRA.isSiegeUnit(unit)).length > 3) continue; plans.push(plan); } @@ -380,7 +376,7 @@ return true; } - let plan = new m.TransportPlan(gameState, [ent], startIndex, endIndex, endPos); + let plan = new PETRA.TransportPlan(gameState, [ent], startIndex, endIndex, endPos); if (plan.failed) { if (this.Config.debug > 1) @@ -393,11 +389,11 @@ }; /** split a transport plan in two, moving all entities not yet affected to a ship in the new plan */ -m.NavalManager.prototype.splitTransport = function(gameState, plan) +PETRA.NavalManager.prototype.splitTransport = function(gameState, plan) { if (this.Config.debug > 1) API3.warn(">>>> split of transport plan started <<<<"); - let newplan = new m.TransportPlan(gameState, [], plan.startIndex, plan.endIndex, plan.endPos); + let newplan = new PETRA.TransportPlan(gameState, [], plan.startIndex, plan.endIndex, plan.endPos); if (newplan.failed) { if (this.Config.debug > 1) @@ -423,7 +419,7 @@ * create a transport from a garrisoned ship to a land location * needed at start game when starting with a garrisoned ship */ -m.NavalManager.prototype.createTransportIfNeeded = function(gameState, fromPos, toPos, toAccess) +PETRA.NavalManager.prototype.createTransportIfNeeded = function(gameState, fromPos, toPos, toAccess) { let fromAccess = gameState.ai.accessibility.getAccessValue(fromPos); if (fromAccess !== 1) @@ -441,7 +437,7 @@ for (let entId of ship.garrisoned()) units.push(gameState.getEntityById(entId)); // TODO check that the garrisoned units have not another purpose - let plan = new m.TransportPlan(gameState, units, fromAccess, toAccess, toPos, ship); + let plan = new PETRA.TransportPlan(gameState, units, fromAccess, toAccess, toPos, ship); if (plan.failed) continue; plan.init(gameState); @@ -450,7 +446,7 @@ }; // set minimal number of needed ships when a new event (new base or new attack plan) -m.NavalManager.prototype.setMinimalTransportShips = function(gameState, sea, number) +PETRA.NavalManager.prototype.setMinimalTransportShips = function(gameState, sea, number) { if (!sea) return; @@ -459,7 +455,7 @@ }; // bumps up the number of ships we want if we need more. -m.NavalManager.prototype.checkLevels = function(gameState, queues) +PETRA.NavalManager.prototype.checkLevels = function(gameState, queues) { if (queues.ships.hasQueuedUnits()) return; @@ -488,7 +484,7 @@ ++this.wantedTransportShips[sea]; }; -m.NavalManager.prototype.maintainFleet = function(gameState, queues) +PETRA.NavalManager.prototype.maintainFleet = function(gameState, queues) { if (queues.ships.hasQueuedUnits()) return; @@ -507,7 +503,7 @@ let template = this.getBestShip(gameState, sea, "transport"); if (template) { - queues.ships.addPlan(new m.TrainingPlan(gameState, template, { "sea": sea }, 1, 1)); + queues.ships.addPlan(new PETRA.TrainingPlan(gameState, template, { "sea": sea }, 1, 1)); continue; } } @@ -518,7 +514,7 @@ let template = this.getBestShip(gameState, sea, "fishing"); if (template) { - queues.ships.addPlan(new m.TrainingPlan(gameState, template, { "base": 0, "role": "worker", "sea": sea }, 1, 1)); + queues.ships.addPlan(new PETRA.TrainingPlan(gameState, template, { "base": 0, "role": "worker", "sea": sea }, 1, 1)); continue; } } @@ -526,7 +522,7 @@ }; /** assigns free ships to plans that need some */ -m.NavalManager.prototype.assignShipsToPlans = function(gameState) +PETRA.NavalManager.prototype.assignShipsToPlans = function(gameState) { for (let plan of this.transportPlans) if (plan.needTransportShips) @@ -534,7 +530,7 @@ }; /** Return true if this ship is likeky (un)garrisoning units */ -m.NavalManager.prototype.isShipBoarding = function(ship) +PETRA.NavalManager.prototype.isShipBoarding = function(ship) { if (!ship.position()) return false; @@ -548,7 +544,7 @@ * TODO Ships entity collections are currently in two parts as the trader ships are dealt with * in the tradeManager. That should be modified to avoid dupplicating all the code here. */ -m.NavalManager.prototype.moveApart = function(gameState) +PETRA.NavalManager.prototype.moveApart = function(gameState) { let blockedShips = []; let blockedIds = []; @@ -595,13 +591,13 @@ continue; ship.setMetadata(PlayerID, "stationnary", true); // Check if there are some treasure around - if (m.gatherTreasure(gameState, ship, true)) + if (PETRA.gatherTreasure(gameState, ship, true)) continue; // Do not stay idle near a dock to not disturb other ships let sea = ship.getMetadata(PlayerID, "sea"); for (let dock of gameState.getAllyStructures().filter(API3.Filters.byClass("Dock")).values()) { - if (m.getSeaAccess(gameState, dock) != sea) + if (PETRA.getSeaAccess(gameState, dock) != sea) continue; if (API3.SquareVectorDistance(shipPosition, dock.position()) > 4900) continue; @@ -652,13 +648,13 @@ continue; ship.setMetadata(PlayerID, "stationnary", true); // Check if there are some treasure around - if (m.gatherTreasure(gameState, ship, true)) + if (PETRA.gatherTreasure(gameState, ship, true)) continue; // Do not stay idle near a dock to not disturb other ships let sea = ship.getMetadata(PlayerID, "sea"); for (let dock of gameState.getAllyStructures().filter(API3.Filters.byClass("Dock")).values()) { - if (m.getSeaAccess(gameState, dock) != sea) + if (PETRA.getSeaAccess(gameState, dock) != sea) continue; if (API3.SquareVectorDistance(shipPosition, dock.position()) > 4900) continue; @@ -710,7 +706,7 @@ } }; -m.NavalManager.prototype.buildNavalStructures = function(gameState, queues) +PETRA.NavalManager.prototype.buildNavalStructures = function(gameState, queues) { if (!gameState.ai.HQ.navalMap || !gameState.ai.HQ.baseManagers[1]) return; @@ -735,7 +731,7 @@ continue; let wantedLand = {}; wantedLand[base.accessIndex] = true; - queues.dock.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_dock", { "land": wantedLand, "sea": sea })); + queues.dock.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_dock", { "land": wantedLand, "sea": sea })); dockStarted = true; break; } @@ -765,11 +761,11 @@ if (base.anchor) wantedLand[base.accessIndex] = true; let sea = this.docks.toEntityArray()[0].getMetadata(PlayerID, "sea"); - queues.militaryBuilding.addPlan(new m.ConstructionPlan(gameState, template, { "land": wantedLand, "sea": sea })); + queues.militaryBuilding.addPlan(new PETRA.ConstructionPlan(gameState, template, { "land": wantedLand, "sea": sea })); }; /** goal can be either attack (choose ship with best arrowCount) or transport (choose ship with best capacity) */ -m.NavalManager.prototype.getBestShip = function(gameState, sea, goal) +PETRA.NavalManager.prototype.getBestShip = function(gameState, sea, goal) { let civ = gameState.getPlayerCiv(); let trainableShips = []; @@ -826,7 +822,7 @@ return bestShip; }; -m.NavalManager.prototype.update = function(gameState, queues, events) +PETRA.NavalManager.prototype.update = function(gameState, queues, events) { Engine.ProfileStart("Naval Manager update"); @@ -857,7 +853,7 @@ Engine.ProfileStop(); }; -m.NavalManager.prototype.Serialize = function() +PETRA.NavalManager.prototype.Serialize = function() { let properties = { "wantedTransportShips": this.wantedTransportShips, @@ -875,7 +871,7 @@ return { "properties": properties, "transports": transports }; }; -m.NavalManager.prototype.Deserialize = function(gameState, data) +PETRA.NavalManager.prototype.Deserialize = function(gameState, data) { for (let key in data.properties) this[key] = data.properties[key]; @@ -884,13 +880,9 @@ for (let i in data.transports) { let dataPlan = data.transports[i]; - let plan = new m.TransportPlan(gameState, [], dataPlan.startIndex, dataPlan.endIndex, dataPlan.endPos); + let plan = new PETRA.TransportPlan(gameState, [], dataPlan.startIndex, dataPlan.endIndex, dataPlan.endPos); plan.Deserialize(dataPlan); plan.init(gameState); this.transportPlans.push(plan); } }; - - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queue.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queue.js @@ -1,23 +1,19 @@ -var PETRA = function(m) -{ - /** * Holds a list of wanted plans to train or construct */ - -m.Queue = function() +PETRA.Queue = function() { this.plans = []; this.paused = false; this.switched = 0; }; -m.Queue.prototype.empty = function() +PETRA.Queue.prototype.empty = function() { this.plans = []; }; -m.Queue.prototype.addPlan = function(newPlan) +PETRA.Queue.prototype.addPlan = function(newPlan) { if (!newPlan) return; @@ -34,7 +30,7 @@ this.plans.push(newPlan); }; -m.Queue.prototype.check= function(gameState) +PETRA.Queue.prototype.check= function(gameState) { while (this.plans.length > 0) { @@ -46,14 +42,14 @@ } }; -m.Queue.prototype.getNext = function() +PETRA.Queue.prototype.getNext = function() { if (this.plans.length > 0) return this.plans[0]; return null; }; -m.Queue.prototype.startNext = function(gameState) +PETRA.Queue.prototype.startNext = function(gameState) { if (this.plans.length > 0) { @@ -67,7 +63,7 @@ * returns the maximal account we'll accept for this queue. * Currently all the cost of the first element and fraction of that of the second */ -m.Queue.prototype.maxAccountWanted = function(gameState, fraction) +PETRA.Queue.prototype.maxAccountWanted = function(gameState, fraction) { let cost = new API3.Resources(); if (this.plans.length > 0 && this.plans[0].isGo(gameState)) @@ -81,7 +77,7 @@ return cost; }; -m.Queue.prototype.queueCost = function() +PETRA.Queue.prototype.queueCost = function() { let cost = new API3.Resources(); for (let plan of this.plans) @@ -89,17 +85,17 @@ return cost; }; -m.Queue.prototype.length = function() +PETRA.Queue.prototype.length = function() { return this.plans.length; }; -m.Queue.prototype.hasQueuedUnits = function() +PETRA.Queue.prototype.hasQueuedUnits = function() { return this.plans.length > 0; }; -m.Queue.prototype.countQueuedUnits = function() +PETRA.Queue.prototype.countQueuedUnits = function() { let count = 0; for (let plan of this.plans) @@ -107,12 +103,12 @@ return count; }; -m.Queue.prototype.hasQueuedUnitsWithClass = function(classe) +PETRA.Queue.prototype.hasQueuedUnitsWithClass = function(classe) { return this.plans.some(plan => plan.template && plan.template.hasClass(classe)); }; -m.Queue.prototype.countQueuedUnitsWithClass = function(classe) +PETRA.Queue.prototype.countQueuedUnitsWithClass = function(classe) { let count = 0; for (let plan of this.plans) @@ -121,7 +117,7 @@ return count; }; -m.Queue.prototype.countQueuedUnitsWithMetadata = function(data, value) +PETRA.Queue.prototype.countQueuedUnitsWithMetadata = function(data, value) { let count = 0; for (let plan of this.plans) @@ -130,7 +126,7 @@ return count; }; -m.Queue.prototype.Serialize = function() +PETRA.Queue.prototype.Serialize = function() { let plans = []; for (let plan of this.plans) @@ -139,7 +135,7 @@ return { "plans": plans, "paused": this.paused, "switched": this.switched }; }; -m.Queue.prototype.Deserialize = function(gameState, data) +PETRA.Queue.prototype.Deserialize = function(gameState, data) { this.paused = data.paused; this.switched = data.switched; @@ -148,11 +144,11 @@ { let plan; if (dataPlan.category == "unit") - plan = new m.TrainingPlan(gameState, dataPlan.type); + plan = new PETRA.TrainingPlan(gameState, dataPlan.type); else if (dataPlan.category == "building") - plan = new m.ConstructionPlan(gameState, dataPlan.type); + plan = new PETRA.ConstructionPlan(gameState, dataPlan.type); else if (dataPlan.category == "technology") - plan = new m.ResearchPlan(gameState, dataPlan.type); + plan = new PETRA.ResearchPlan(gameState, dataPlan.type); else { API3.warn("Petra deserialization error: plan unknown " + uneval(dataPlan)); @@ -162,6 +158,3 @@ this.plans.push(plan); } }; - -return m; -}(PETRA); 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 @@ -1,26 +1,25 @@ -var PETRA = function(m) -{ - -// This takes the input queues and picks which items to fund with resources until no more resources are left to distribute. -// -// Currently this manager keeps accounts for each queue, split between the 4 main resources -// -// Each time resources are available (ie not in any account), it is split between the different queues -// Mostly based on priority of the queue, and existing needs. -// Each turn, the queue Manager checks if a queue can afford its next item, then it does. -// -// A consequence of the system it's not really revertible. Once a queue has an account of 500 food, it'll keep it -// If for some reason the AI stops getting new food, and this queue lacks, say, wood, no other queues will -// be able to benefit form the 500 food (even if they only needed food). -// This is not to annoying as long as all goes well. If the AI loses many workers, it starts being problematic. -// -// It also has the effect of making the AI more or less always sit on a few hundreds resources since most queues -// get some part of the total, and if all queues have 70% of their needs, nothing gets done -// Particularly noticeable when phasing: the AI often overshoots by a good 200/300 resources before starting. -// -// This system should be improved. It's probably not flexible enough. +/** + * This takes the input queues and picks which items to fund with resources until no more resources are left to distribute. + * + * Currently this manager keeps accounts for each queue, split between the 4 main resources + * + * Each time resources are available (ie not in any account), it is split between the different queues + * Mostly based on priority of the queue, and existing needs. + * Each turn, the queue Manager checks if a queue can afford its next item, then it does. + * + * A consequence of the system it's not really revertible. Once a queue has an account of 500 food, it'll keep it + * If for some reason the AI stops getting new food, and this queue lacks, say, wood, no other queues will + * be able to benefit form the 500 food (even if they only needed food). + * This is not to annoying as long as all goes well. If the AI loses many workers, it starts being problematic. + * + * It also has the effect of making the AI more or less always sit on a few hundreds resources since most queues + * get some part of the total, and if all queues have 70% of their needs, nothing gets done + * Particularly noticeable when phasing: the AI often overshoots by a good 200/300 resources before starting. + * + * This system should be improved. It's probably not flexible enough. + */ -m.QueueManager = function(Config, queues) +PETRA.QueueManager = function(Config, queues) { this.Config = Config; this.queues = queues; @@ -40,7 +39,7 @@ this.queueArrays.sort((a, b) => priorities[b[0]] - priorities[a[0]]); }; -m.QueueManager.prototype.getAvailableResources = function(gameState) +PETRA.QueueManager.prototype.getAvailableResources = function(gameState) { let resources = gameState.getResources(); for (let key in this.queues) @@ -48,7 +47,7 @@ return resources; }; -m.QueueManager.prototype.getTotalAccountedResources = function() +PETRA.QueueManager.prototype.getTotalAccountedResources = function() { let resources = new API3.Resources(); for (let key in this.queues) @@ -56,7 +55,7 @@ return resources; }; -m.QueueManager.prototype.currentNeeds = function(gameState) +PETRA.QueueManager.prototype.currentNeeds = function(gameState) { let needed = new API3.Resources(); // queueArrays because it's faster. @@ -78,7 +77,7 @@ // calculate the gather rates we'd want to be able to start all elements in our queues // TODO: many things. -m.QueueManager.prototype.wantedGatherRates = function(gameState) +PETRA.QueueManager.prototype.wantedGatherRates = function(gameState) { // default values for first turn when we have not yet set our queues. if (gameState.ai.playedTurn === 0) @@ -155,7 +154,7 @@ return rates; }; -m.QueueManager.prototype.printQueues = function(gameState) +PETRA.QueueManager.prototype.printQueues = function(gameState) { let numWorkers = 0; gameState.getOwnUnits().forEach(ent => { @@ -191,7 +190,7 @@ API3.warn("------------------------------------"); }; -m.QueueManager.prototype.clear = function() +PETRA.QueueManager.prototype.clear = function() { for (let i in this.queues) this.queues[i].empty(); @@ -200,7 +199,7 @@ /** * set accounts of queue i from the unaccounted resources */ -m.QueueManager.prototype.setAccounts = function(gameState, cost, i) +PETRA.QueueManager.prototype.setAccounts = function(gameState, cost, i) { let available = this.getAvailableResources(gameState); for (let res of Resources.GetCodes()) @@ -214,7 +213,7 @@ /** * transfer accounts from queue i to queue j */ -m.QueueManager.prototype.transferAccounts = function(cost, i, j) +PETRA.QueueManager.prototype.transferAccounts = function(cost, i, j) { for (let res of Resources.GetCodes()) { @@ -229,7 +228,7 @@ /** * distribute the resources between the different queues according to their priorities */ -m.QueueManager.prototype.distributeResources = function(gameState) +PETRA.QueueManager.prototype.distributeResources = function(gameState) { let availableRes = this.getAvailableResources(gameState); for (let res of Resources.GetCodes()) @@ -318,7 +317,7 @@ } }; -m.QueueManager.prototype.switchResource = function(gameState, res) +PETRA.QueueManager.prototype.switchResource = function(gameState, res) { // We have no available resources, see if we can't "compact" them in one queue. // compare queues 2 by 2, and if one with a higher priority could be completed by our amount, give it. @@ -355,7 +354,7 @@ }; // Start the next item in the queue if we can afford it. -m.QueueManager.prototype.startNextItems = function(gameState) +PETRA.QueueManager.prototype.startNextItems = function(gameState) { for (let q of this.queueArrays) { @@ -384,7 +383,7 @@ } }; -m.QueueManager.prototype.update = function(gameState) +PETRA.QueueManager.prototype.update = function(gameState) { Engine.ProfileStart("Queue Manager"); @@ -413,7 +412,7 @@ }; // Recovery system: if short of workers after an attack, pause (and reset) some queues to favor worker training -m.QueueManager.prototype.checkPausedQueues = function(gameState) +PETRA.QueueManager.prototype.checkPausedQueues = function(gameState) { let numWorkers = gameState.countOwnEntitiesAndQueuedWithRole("worker"); let workersMin = Math.min(Math.max(12, 24 * this.Config.popScaling), this.Config.Economy.popPhase2); @@ -467,14 +466,14 @@ } }; -m.QueueManager.prototype.canAfford = function(queue, cost) +PETRA.QueueManager.prototype.canAfford = function(queue, cost) { if (!this.accounts[queue]) return false; return this.accounts[queue].canAfford(cost); }; -m.QueueManager.prototype.pauseQueue = function(queue, scrapAccounts) +PETRA.QueueManager.prototype.pauseQueue = function(queue, scrapAccounts) { if (!this.queues[queue]) return; @@ -483,13 +482,13 @@ this.accounts[queue].reset(); }; -m.QueueManager.prototype.unpauseQueue = function(queue) +PETRA.QueueManager.prototype.unpauseQueue = function(queue) { if (this.queues[queue]) this.queues[queue].paused = false; }; -m.QueueManager.prototype.pauseAll = function(scrapAccounts, but) +PETRA.QueueManager.prototype.pauseAll = function(scrapAccounts, but) { for (let q in this.queues) { @@ -501,7 +500,7 @@ } }; -m.QueueManager.prototype.unpauseAll = function(but) +PETRA.QueueManager.prototype.unpauseAll = function(but) { for (let q in this.queues) if (q != but) @@ -509,12 +508,12 @@ }; -m.QueueManager.prototype.addQueue = function(queueName, priority) +PETRA.QueueManager.prototype.addQueue = function(queueName, priority) { if (this.queues[queueName] !== undefined) return; - this.queues[queueName] = new m.Queue(); + this.queues[queueName] = new PETRA.Queue(); this.priorities[queueName] = priority; this.accounts[queueName] = new API3.Resources(); @@ -525,7 +524,7 @@ this.queueArrays.sort((a, b) => priorities[b[0]] - priorities[a[0]]); }; -m.QueueManager.prototype.removeQueue = function(queueName) +PETRA.QueueManager.prototype.removeQueue = function(queueName) { if (this.queues[queueName] === undefined) return; @@ -541,12 +540,12 @@ this.queueArrays.sort((a, b) => priorities[b[0]] - priorities[a[0]]); }; -m.QueueManager.prototype.getPriority = function(queueName) +PETRA.QueueManager.prototype.getPriority = function(queueName) { return this.priorities[queueName]; }; -m.QueueManager.prototype.changePriority = function(queueName, newPriority) +PETRA.QueueManager.prototype.changePriority = function(queueName, newPriority) { if (this.Config.debug > 1) API3.warn(">>> Priority of queue " + queueName + " changed from " + this.priorities[queueName] + " to " + newPriority); @@ -556,7 +555,7 @@ this.queueArrays.sort((a, b) => priorities[b[0]] - priorities[a[0]]); }; -m.QueueManager.prototype.Serialize = function() +PETRA.QueueManager.prototype.Serialize = function() { let accounts = {}; let queues = {}; @@ -576,7 +575,7 @@ }; }; -m.QueueManager.prototype.Deserialize = function(gameState, data) +PETRA.QueueManager.prototype.Deserialize = function(gameState, data) { this.priorities = data.priorities; this.queues = {}; @@ -586,7 +585,7 @@ this.queueArrays = []; for (let q in data.queues) { - this.queues[q] = new m.Queue(); + this.queues[q] = new PETRA.Queue(); this.queues[q].Deserialize(gameState, data.queues[q]); this.accounts[q] = new API3.Resources(); this.accounts[q].Deserialize(data.accounts[q]); @@ -594,6 +593,3 @@ } this.queueArrays.sort((a, b) => data.priorities[b[0]] - data.priorities[a[0]]); }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplan.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplan.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplan.js @@ -1,10 +1,8 @@ -var PETRA = function(m) -{ /** * Common functions and variables to all queue plans. */ -m.QueuePlan = function(gameState, type, metadata) +PETRA.QueuePlan = function(gameState, type, metadata) { this.type = gameState.applyCiv(type); this.metadata = metadata; @@ -24,30 +22,30 @@ }; /** Check the content of this queue */ -m.QueuePlan.prototype.isInvalid = function(gameState) +PETRA.QueuePlan.prototype.isInvalid = function(gameState) { return false; }; /** if true, the queue manager will begin increasing this plan's account. */ -m.QueuePlan.prototype.isGo = function(gameState) +PETRA.QueuePlan.prototype.isGo = function(gameState) { return true; }; /** can we start this plan immediately? */ -m.QueuePlan.prototype.canStart = function(gameState) +PETRA.QueuePlan.prototype.canStart = function(gameState) { return false; }; /** process the plan. */ -m.QueuePlan.prototype.start = function(gameState) +PETRA.QueuePlan.prototype.start = function(gameState) { // should call onStart. }; -m.QueuePlan.prototype.getCost = function() +PETRA.QueuePlan.prototype.getCost = function() { let costs = new API3.Resources(); costs.add(this.cost); @@ -62,9 +60,6 @@ * Need to be updated to actually do something if you want them to. * this is called by "Start" if it succeeds. */ -m.QueuePlan.prototype.onStart = function(gameState) +PETRA.QueuePlan.prototype.onStart = function(gameState) { }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js @@ -1,14 +1,11 @@ -var PETRA = function(m) -{ - /** * Defines a construction plan, ie a building. * We'll try to fing a good position if non has been provided */ -m.ConstructionPlan = function(gameState, type, metadata, position) +PETRA.ConstructionPlan = function(gameState, type, metadata, position) { - if (!m.QueuePlan.call(this, gameState, type, metadata)) + if (!PETRA.QueuePlan.call(this, gameState, type, metadata)) return false; this.position = position ? position : 0; @@ -18,9 +15,9 @@ return true; }; -m.ConstructionPlan.prototype = Object.create(m.QueuePlan.prototype); +PETRA.ConstructionPlan.prototype = Object.create(PETRA.QueuePlan.prototype); -m.ConstructionPlan.prototype.canStart = function(gameState) +PETRA.ConstructionPlan.prototype.canStart = function(gameState) { if (gameState.ai.HQ.turnCache.buildingBuilt) // do not start another building if already one this turn return false; @@ -34,7 +31,7 @@ return gameState.ai.HQ.buildManager.hasBuilder(this.type); }; -m.ConstructionPlan.prototype.start = function(gameState) +PETRA.ConstructionPlan.prototype.start = function(gameState) { Engine.ProfileStart("Building construction start"); @@ -109,7 +106,7 @@ gameState.ai.HQ.navalManager.createTransportIfNeeded(gameState, this.metadata.proximity, [pos.x, pos.z], this.metadata.access); }; -m.ConstructionPlan.prototype.findGoodPosition = function(gameState) +PETRA.ConstructionPlan.prototype.findGoodPosition = function(gameState) { let template = this.template; @@ -217,7 +214,7 @@ let x = Math.round(pos[0] / cellSize); let z = Math.round(pos[1] / cellSize); - let struct = m.getBuiltEntity(gameState, ent); + let struct = PETRA.getBuiltEntity(gameState, ent); if (struct.resourceDropsiteTypes() && struct.resourceDropsiteTypes().indexOf("food") != -1) { if (template.hasClass("Field") || template.hasClass("Corral")) @@ -251,7 +248,7 @@ for (let j = 0; j < placement.map.length; ++j) { let value = placement.map[j] - gameState.sharedScript.resourceMaps.wood.map[j]/3; - if (HQ.borderMap.map[j] & m.fullBorder_Mask) + if (HQ.borderMap.map[j] & PETRA.fullBorder_Mask) value /= 2; // we need space around farmstead, so disfavor map border placement.set(j, value); } @@ -273,9 +270,9 @@ placement.map[j] = 0; else if (placement.map[j] > 0) { - if (favorBorder && HQ.borderMap.map[j] & m.border_Mask) + if (favorBorder && HQ.borderMap.map[j] & PETRA.border_Mask) placement.set(j, placement.map[j] + 50); - else if (disfavorBorder && !(HQ.borderMap.map[j] & m.fullBorder_Mask)) + else if (disfavorBorder && !(HQ.borderMap.map[j] & PETRA.fullBorder_Mask)) placement.set(j, placement.map[j] + 10); let x = (j % placement.width + 0.5) * cellSize; @@ -293,9 +290,9 @@ placement.map[j] = 0; else if (placement.map[j] > 0) { - if (favorBorder && HQ.borderMap.map[j] & m.border_Mask) + if (favorBorder && HQ.borderMap.map[j] & PETRA.border_Mask) placement.set(j, placement.map[j] + 50); - else if (disfavorBorder && !(HQ.borderMap.map[j] & m.fullBorder_Mask)) + else if (disfavorBorder && !(HQ.borderMap.map[j] & PETRA.fullBorder_Mask)) placement.set(j, placement.map[j] + 10); let x = (j % placement.width + 0.5) * cellSize; @@ -314,7 +311,7 @@ // note: not for houses and dropsites who ought to be closer to either each other or a resource. // also not for fields who can be stacked quite a bit - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); // obstructions.dumpIm(template.buildPlacementType() + "_obstructions.png"); let radius = 0; @@ -363,12 +360,12 @@ * => we try not to be too far from our territory * In all cases, we add a bonus for nearby resources, and when a large extend of water in front ot it. */ -m.ConstructionPlan.prototype.findDockPosition = function(gameState) +PETRA.ConstructionPlan.prototype.findDockPosition = function(gameState) { let template = this.template; let territoryMap = gameState.ai.HQ.territoryMap; - let obstructions = m.createObstructionMap(gameState, 0, template); + let obstructions = PETRA.createObstructionMap(gameState, 0, template); // obstructions.dumpIm(template.buildPlacementType() + "_obstructions.png"); let bestIdx; @@ -471,7 +468,7 @@ let dockDist = 0; for (let dock of docks.values()) { - if (m.getSeaAccess(gameState, dock) != navalPassMap[i]) + if (PETRA.getSeaAccess(gameState, dock) != navalPassMap[i]) continue; let dist = API3.SquareVectorDistance(pos, dock.position()); if (dist > dockDist) @@ -487,7 +484,7 @@ } // Add a penalty if on the map border as ship movement will be difficult - if (gameState.ai.HQ.borderMap.map[j] & m.fullBorder_Mask) + if (gameState.ai.HQ.borderMap.map[j] & PETRA.fullBorder_Mask) score += 20; // Do a pre-selection, supposing we will have the best possible water @@ -538,7 +535,7 @@ /** * Find a good island to build a dock. */ -m.ConstructionPlan.prototype.buildOverseaDock = function(gameState, template) +PETRA.ConstructionPlan.prototype.buildOverseaDock = function(gameState, template) { let docks = gameState.getOwnStructures().filter(API3.Filters.byClass("Dock")); if (!docks.hasEntities()) @@ -558,7 +555,7 @@ let keep = true; for (let dock of docks.values()) { - if (m.getLandAccess(gameState, dock) != i) + if (PETRA.getLandAccess(gameState, dock) != i) continue; keep = false; break; @@ -568,7 +565,7 @@ let sea; for (let cc of ccEnts.values()) { - let ccAccess = m.getLandAccess(gameState, cc); + let ccAccess = PETRA.getLandAccess(gameState, cc); if (ccAccess != i) { if (cc.owner() == PlayerID && !sea) @@ -619,7 +616,7 @@ }; /** Algorithm taken from the function GetDockAngle in simulation/helpers/Commands.js */ -m.ConstructionPlan.prototype.getDockAngle = function(gameState, x, z, size) +PETRA.ConstructionPlan.prototype.getDockAngle = function(gameState, x, z, size) { let pos = gameState.ai.accessibility.gamePosToMapPos([x, z]); let k = pos[0] + pos[1]*gameState.ai.accessibility.width; @@ -681,7 +678,7 @@ * to determine the special dock requirements * returns {"land": land index for this dock, "water": amount of water around this spot} */ -m.ConstructionPlan.prototype.checkDockPlacement = function(gameState, x, z, halfDepth, halfWidth, angle) +PETRA.ConstructionPlan.prototype.checkDockPlacement = function(gameState, x, z, halfDepth, halfWidth, angle) { let sz = halfDepth * Math.sin(angle); let cz = halfDepth * Math.cos(angle); @@ -746,7 +743,7 @@ const around = [[ 1.0, 0.0], [ 0.87, 0.50], [ 0.50, 0.87], [ 0.0, 1.0], [-0.50, 0.87], [-0.87, 0.50], [-1.0, 0.0], [-0.87,-0.50], [-0.50,-0.87], [ 0.0,-1.0], [ 0.50,-0.87], [ 0.87,-0.50]]; -m.ConstructionPlan.prototype.isDockLocation = function(gameState, j, dimension, wantedLand, wantedSea) +PETRA.ConstructionPlan.prototype.isDockLocation = function(gameState, j, dimension, wantedLand, wantedSea) { let width = gameState.ai.HQ.territoryMap.width; let cellSize = gameState.ai.HQ.territoryMap.cellSize; @@ -793,7 +790,7 @@ * return a measure of the proximity to our frontier (including our allies) * 0=inside, 1=less than 24m, 2= less than 48m, 3= less than 72m, 4=less than 96m, 5=above 96m */ -m.ConstructionPlan.prototype.getFrontierProximity = function(gameState, j) +PETRA.ConstructionPlan.prototype.getFrontierProximity = function(gameState, j) { let alliedVictory = gameState.getAlliedVictory(); let territoryMap = gameState.ai.HQ.territoryMap; @@ -817,7 +814,7 @@ let jz = iz + Math.round(i*step*a[1]); if (jz < 0 || jz >= width) continue; - if (borderMap.map[jx+width*jz] & m.outside_Mask) + if (borderMap.map[jx+width*jz] & PETRA.outside_Mask) continue; territoryOwner = territoryMap.getOwnerIndex(jx+width*jz); if (alliedVictory && gameState.isPlayerAlly(territoryOwner) || territoryOwner == PlayerID) @@ -837,7 +834,7 @@ * get the sum of the resources (except food) around, inside a given radius * resources have a weight (1 if dist=0 and 0 if dist=size) doubled for wood */ -m.ConstructionPlan.prototype.getResourcesAround = function(gameState, types, i, radius) +PETRA.ConstructionPlan.prototype.getResourcesAround = function(gameState, types, i, radius) { let resourceMaps = gameState.sharedScript.resourceMaps; let w = resourceMaps.wood.width; @@ -890,7 +887,7 @@ return nbcell ? total / nbcell : 0; }; -m.ConstructionPlan.prototype.isGo = function(gameState) +PETRA.ConstructionPlan.prototype.isGo = function(gameState) { if (this.goRequirement && this.goRequirement == "houseNeeded") { @@ -917,13 +914,13 @@ return true; }; -m.ConstructionPlan.prototype.onStart = function(gameState) +PETRA.ConstructionPlan.prototype.onStart = function(gameState) { if (this.queueToReset) gameState.ai.queueManager.changePriority(this.queueToReset, gameState.ai.Config.priorities[this.queueToReset]); }; -m.ConstructionPlan.prototype.Serialize = function() +PETRA.ConstructionPlan.prototype.Serialize = function() { return { "category": this.category, @@ -938,7 +935,7 @@ }; }; -m.ConstructionPlan.prototype.Deserialize = function(gameState, data) +PETRA.ConstructionPlan.prototype.Deserialize = function(gameState, data) { for (let key in data) this[key] = data[key]; @@ -946,6 +943,3 @@ this.cost = new API3.Resources(); this.cost.Deserialize(data.cost); }; - -return m; -}(PETRA); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanResearch.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanResearch.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/queueplanResearch.js @@ -1,9 +1,6 @@ -var PETRA = function(m) +PETRA.ResearchPlan = function(gameState, type, rush = false) { - -m.ResearchPlan = function(gameState, type, rush = false) -{ - if (!m.QueuePlan.call(this, gameState, type, {})) + if (!PETRA.QueuePlan.call(this, gameState, type, {})) return false; if (this.template.researchTime === undefined) @@ -20,9 +17,9 @@ return true; }; -m.ResearchPlan.prototype = Object.create(m.QueuePlan.prototype); +PETRA.ResearchPlan.prototype = Object.create(PETRA.QueuePlan.prototype); -m.ResearchPlan.prototype.canStart = function(gameState) +PETRA.ResearchPlan.prototype.canStart = function(gameState) { this.researchers = this.getBestResearchers(gameState); if (!this.researchers) @@ -31,7 +28,7 @@ return true; }; -m.ResearchPlan.prototype.getBestResearchers = function(gameState, noRequirementCheck = false) +PETRA.ResearchPlan.prototype.getBestResearchers = function(gameState, noRequirementCheck = false) { let allResearchers = gameState.findResearchers(this.type, noRequirementCheck); if (!allResearchers || !allResearchers.hasEntities()) @@ -54,12 +51,12 @@ return researchers; }; -m.ResearchPlan.prototype.isInvalid = function(gameState) +PETRA.ResearchPlan.prototype.isInvalid = function(gameState) { return gameState.isResearched(this.type) || gameState.isResearching(this.type); }; -m.ResearchPlan.prototype.start = function(gameState) +PETRA.ResearchPlan.prototype.start = function(gameState) { // Prefer researcher with shortest queues (no need to serialize this.researchers // as the functions canStart and start are always called on the same turn) @@ -71,7 +68,7 @@ this.onStart(gameState); }; -m.ResearchPlan.prototype.onStart = function(gameState) +PETRA.ResearchPlan.prototype.onStart = function(gameState) { if (this.queueToReset) gameState.ai.queueManager.changePriority(this.queueToReset, gameState.ai.Config.priorities[this.queueToReset]); @@ -86,7 +83,7 @@ } }; -m.ResearchPlan.prototype.Serialize = function() +PETRA.ResearchPlan.prototype.Serialize = function() { return { "category": this.category, @@ -100,7 +97,7 @@ }; }; -m.ResearchPlan.prototype.Deserialize = function(gameState, data) +PETRA.ResearchPlan.prototype.Deserialize = function(gameState, data) { for (let key in data) this[key] = data[key]; @@ -108,6 +105,3 @@ this.cost = new API3.Resources(); this.cost.Deserialize(data.cost); }; - -return m; -}(PETRA); 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 @@ -1,9 +1,6 @@ -var PETRA = function(m) +PETRA.TrainingPlan = function(gameState, type, metadata, number = 1, maxMerge = 5) { - -m.TrainingPlan = function(gameState, type, metadata, number = 1, maxMerge = 5) -{ - if (!m.QueuePlan.call(this, gameState, type, metadata)) + if (!PETRA.QueuePlan.call(this, gameState, type, metadata)) { API3.warn(" Plan training " + type + " canceled"); return false; @@ -21,9 +18,9 @@ return true; }; -m.TrainingPlan.prototype = Object.create(m.QueuePlan.prototype); +PETRA.TrainingPlan.prototype = Object.create(PETRA.QueuePlan.prototype); -m.TrainingPlan.prototype.canStart = function(gameState) +PETRA.TrainingPlan.prototype.canStart = function(gameState) { this.trainers = this.getBestTrainers(gameState); if (!this.trainers) @@ -32,7 +29,7 @@ return true; }; -m.TrainingPlan.prototype.getBestTrainers = function(gameState) +PETRA.TrainingPlan.prototype.getBestTrainers = function(gameState) { if (this.metadata && this.metadata.trainer) { @@ -66,7 +63,7 @@ return trainers; }; -m.TrainingPlan.prototype.start = function(gameState) +PETRA.TrainingPlan.prototype.start = function(gameState) { if (this.metadata && this.metadata.trainer) { @@ -132,13 +129,13 @@ this.onStart(gameState); }; -m.TrainingPlan.prototype.addItem = function(amount = 1) +PETRA.TrainingPlan.prototype.addItem = function(amount = 1) { this.number += amount; }; /** Find the promoted types corresponding to this.type */ -m.TrainingPlan.prototype.promotedTypes = function(gameState) +PETRA.TrainingPlan.prototype.promotedTypes = function(gameState) { let types = []; let promotion = this.template.promotion(); @@ -167,7 +164,7 @@ return types; }; -m.TrainingPlan.prototype.Serialize = function() +PETRA.TrainingPlan.prototype.Serialize = function() { return { "category": this.category, @@ -180,7 +177,7 @@ }; }; -m.TrainingPlan.prototype.Deserialize = function(gameState, data) +PETRA.TrainingPlan.prototype.Deserialize = function(gameState, data) { for (let key in data) this[key] = data[key]; @@ -188,6 +185,3 @@ this.cost = new API3.Resources(); this.cost.Deserialize(data.cost); }; - -return m; -}(PETRA); 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 @@ -1,11 +1,7 @@ -var PETRA = function(m) -{ - /** * Manage the research */ - -m.ResearchManager = function(Config) +PETRA.ResearchManager = function(Config) { this.Config = Config; }; @@ -13,7 +9,7 @@ /** * Check if we can go to the next phase */ -m.ResearchManager.prototype.checkPhase = function(gameState, queues) +PETRA.ResearchManager.prototype.checkPhase = function(gameState, queues) { if (queues.majorTech.hasQueuedUnits()) return; @@ -35,11 +31,11 @@ gameState.ai.HQ.phasing = currentPhaseIndex + 1; // Reset the queue priority in case it was changed during a previous phase update gameState.ai.queueManager.changePriority("majorTech", gameState.ai.Config.priorities.majorTech); - queues.majorTech.addPlan(new m.ResearchPlan(gameState, nextPhaseName, true)); + queues.majorTech.addPlan(new PETRA.ResearchPlan(gameState, nextPhaseName, true)); } }; -m.ResearchManager.prototype.researchPopulationBonus = function(gameState, queues) +PETRA.ResearchManager.prototype.researchPopulationBonus = function(gameState, queues) { if (queues.minorTech.hasQueuedUnits()) return; @@ -52,12 +48,12 @@ // TODO may-be loop on all modifs and check if the effect if positive ? if (tech[1]._template.modifications[0].value !== "Cost/PopulationBonus") continue; - queues.minorTech.addPlan(new m.ResearchPlan(gameState, tech[0])); + queues.minorTech.addPlan(new PETRA.ResearchPlan(gameState, tech[0])); break; } }; -m.ResearchManager.prototype.researchTradeBonus = function(gameState, queues) +PETRA.ResearchManager.prototype.researchTradeBonus = function(gameState, queues) { if (queues.minorTech.hasQueuedUnits()) return; @@ -73,13 +69,13 @@ if (tech[1]._template.modifications[0].value !== "UnitMotion/WalkSpeed" && tech[1]._template.modifications[0].value !== "Trader/GainMultiplier") continue; - queues.minorTech.addPlan(new m.ResearchPlan(gameState, tech[0])); + queues.minorTech.addPlan(new PETRA.ResearchPlan(gameState, tech[0])); break; } }; /** Techs to be searched for as soon as they are available */ -m.ResearchManager.prototype.researchWantedTechs = function(gameState, techs) +PETRA.ResearchManager.prototype.researchWantedTechs = function(gameState, techs) { let phase1 = gameState.currentPhase() === 1; let available = phase1 ? gameState.ai.queueManager.getAvailableResources(gameState) : null; @@ -118,7 +114,7 @@ }; /** Techs to be searched for as soon as they are available, but only after phase 2 */ -m.ResearchManager.prototype.researchPreferredTechs = function(gameState, techs) +PETRA.ResearchManager.prototype.researchPreferredTechs = function(gameState, techs) { let phase2 = gameState.currentPhase() === 2; let available = phase2 ? gameState.ai.queueManager.getAvailableResources(gameState) : null; @@ -154,7 +150,7 @@ return null; }; -m.ResearchManager.prototype.update = function(gameState, queues) +PETRA.ResearchManager.prototype.update = function(gameState, queues) { if (queues.minorTech.hasQueuedUnits() || queues.majorTech.hasQueuedUnits()) return; @@ -167,12 +163,12 @@ if (techName.increasePriority) { gameState.ai.queueManager.changePriority("minorTech", 2*this.Config.priorities.minorTech); - let plan = new m.ResearchPlan(gameState, techName.name); + let plan = new PETRA.ResearchPlan(gameState, techName.name); plan.queueToReset = "minorTech"; queues.minorTech.addPlan(plan); } else - queues.minorTech.addPlan(new m.ResearchPlan(gameState, techName.name)); + queues.minorTech.addPlan(new PETRA.ResearchPlan(gameState, techName.name)); return; } @@ -185,12 +181,12 @@ if (techName.increasePriority) { gameState.ai.queueManager.changePriority("minorTech", 2*this.Config.priorities.minorTech); - let plan = new m.ResearchPlan(gameState, techName.name); + let plan = new PETRA.ResearchPlan(gameState, techName.name); plan.queueToReset = "minorTech"; queues.minorTech.addPlan(plan); } else - queues.minorTech.addPlan(new m.ResearchPlan(gameState, techName.name)); + queues.minorTech.addPlan(new PETRA.ResearchPlan(gameState, techName.name)); return; } @@ -220,10 +216,10 @@ return; // randomly pick one. No worries about pairs in that case. - queues.minorTech.addPlan(new m.ResearchPlan(gameState, pickRandom(techs)[0])); + queues.minorTech.addPlan(new PETRA.ResearchPlan(gameState, pickRandom(techs)[0])); }; -m.ResearchManager.prototype.CostSum = function(cost) +PETRA.ResearchManager.prototype.CostSum = function(cost) { let costSum = 0; for (let res in cost) @@ -231,14 +227,11 @@ return costSum; }; -m.ResearchManager.prototype.Serialize = function() +PETRA.ResearchManager.prototype.Serialize = function() { return {}; }; -m.ResearchManager.prototype.Deserialize = function(data) +PETRA.ResearchManager.prototype.Deserialize = function(data) { }; - -return m; -}(PETRA); 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 @@ -1,10 +1,9 @@ -var PETRA = function(m) -{ /** - * determines the strategy to adopt when starting a new game, depending on the initial conditions + * Determines the strategy to adopt when starting a new game, + * depending on the initial conditions */ -m.HQ.prototype.gameAnalysis = function(gameState) +PETRA.HQ.prototype.gameAnalysis = function(gameState) { // Analysis of the terrain and the different access regions if (!this.regionAnalysis(gameState)) @@ -20,7 +19,7 @@ this.structureAnalysis(gameState); // Let's get our initial situation here. - let nobase = new m.BaseManager(gameState, this.Config); + let nobase = new PETRA.BaseManager(gameState, this.Config); nobase.init(gameState); nobase.accessIndex = 0; this.baseManagers.push(nobase); // baseManagers[0] will deal with unit/structure without base @@ -62,7 +61,7 @@ /** * Assign the starting entities to the different bases */ -m.HQ.prototype.assignStartingEntities = function(gameState) +PETRA.HQ.prototype.assignStartingEntities = function(gameState) { for (let ent of gameState.getOwnEntities().values()) { @@ -113,7 +112,7 @@ if (ent.hasClass("Structure") && !ent.decaying() && ent.resourceDropsiteTypes()) bestbase = this.createBase(gameState, ent, "anchorless"); else - bestbase = m.getBestBase(gameState, ent) || this.baseManagers[0]; + bestbase = PETRA.getBestBase(gameState, ent) || this.baseManagers[0]; bestbase.assignEntity(gameState, ent); } // now assign entities garrisoned inside this entity @@ -137,7 +136,7 @@ * determine the main land Index (or water index if none) * as well as the list of allowed (land andf water) regions */ -m.HQ.prototype.regionAnalysis = function(gameState) +PETRA.HQ.prototype.regionAnalysis = function(gameState) { let accessibility = gameState.ai.accessibility; let landIndex; @@ -231,7 +230,7 @@ * load units and buildings from the config files * TODO: change that to something dynamic */ -m.HQ.prototype.structureAnalysis = function(gameState) +PETRA.HQ.prototype.structureAnalysis = function(gameState) { let civref = gameState.playerData.civ; let civ = civref in this.Config.buildings ? civref : 'default'; @@ -245,7 +244,7 @@ * build our first base * if not enough resource, try first to do a dock */ -m.HQ.prototype.buildFirstBase = function(gameState) +PETRA.HQ.prototype.buildFirstBase = function(gameState) { if (gameState.ai.queues.civilCentre.hasQueuedUnits()) return; @@ -267,7 +266,7 @@ continue; // If we can get a treasure around, just do it if (ent.isIdle()) - m.gatherTreasure(gameState, ent); + PETRA.gatherTreasure(gameState, ent); // Then count the resources from the treasures being collected let supplyId = ent.getMetadata(PlayerID, "supply"); if (!supplyId) @@ -312,7 +311,7 @@ let pos = ent.position(); if (!pos) { - let holder = m.getHolder(gameState, ent); + let holder = PETRA.getHolder(gameState, ent); if (!holder || !holder.position()) continue; pos = holder.position(); @@ -346,10 +345,10 @@ if (goal == "dock") { let sea = startingPoint[imax].sea > 1 ? startingPoint[imax].sea : undefined; - gameState.ai.queues.dock.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_dock", { "sea": sea, "proximity": startingPoint[imax].pos })); + gameState.ai.queues.dock.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_dock", { "sea": sea, "proximity": startingPoint[imax].pos })); } else - gameState.ai.queues.civilCentre.addPlan(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base": -1, "resource": "wood", "proximity": startingPoint[imax].pos })); + gameState.ai.queues.civilCentre.addPlan(new PETRA.ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base": -1, "resource": "wood", "proximity": startingPoint[imax].pos })); }; /** @@ -357,7 +356,7 @@ * - if one of our allies has a cc, affect a small fraction of our army for his defense, the rest will attack * - otherwise all units will attack */ -m.HQ.prototype.dispatchUnits = function(gameState) +PETRA.HQ.prototype.dispatchUnits = function(gameState) { let allycc = gameState.getExclusiveAllyEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray(); if (allycc.length) @@ -374,10 +373,10 @@ return; if (ent.getMetadata(PlayerID, "allied")) return; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); for (let cc of allycc) { - if (!cc.position() || m.getLandAccess(gameState, cc) != access) + if (!cc.position() || PETRA.getLandAccess(gameState, cc) != access) continue; --num; --num1; @@ -393,10 +392,10 @@ return; if (ent.getMetadata(PlayerID, "allied")) return; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); for (let cc of allycc) { - if (!cc.position() || m.getLandAccess(gameState, cc) != access) + if (!cc.position() || PETRA.getLandAccess(gameState, cc) != access) continue; --num; --num2; @@ -412,10 +411,10 @@ return; if (ent.getMetadata(PlayerID, "allied")) return; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); for (let cc of allycc) { - if (!cc.position() || m.getLandAccess(gameState, cc) != access) + if (!cc.position() || PETRA.getLandAccess(gameState, cc) != access) continue; if (!ent.hasClass("Support")) --num; @@ -433,7 +432,7 @@ * - if on a small island, favor fishing * - count the available wood resource, and allow rushes only if enough (we should otherwise favor expansion) */ -m.HQ.prototype.configFirstBase = function(gameState) +PETRA.HQ.prototype.configFirstBase = function(gameState) { if (this.baseManagers.length < 2) return; @@ -561,7 +560,7 @@ let cost = new API3.Resources(gameState.getTemplate(template).cost()); gameState.ai.queueManager.setAccounts(gameState, cost, "dropsites"); } - gameState.ai.queues.dropsites.addPlan(new m.ConstructionPlan(gameState, template, { "base": this.baseManagers[1].ID }, newDP.pos)); + gameState.ai.queues.dropsites.addPlan(new PETRA.ConstructionPlan(gameState, template, { "base": this.baseManagers[1].ID }, newDP.pos)); } } // and build immediately a corral if needed @@ -569,10 +568,6 @@ { template = gameState.applyCiv("structures/{civ}_corral"); if (!gameState.getOwnEntitiesByClass("Corral", true).hasEntities() && this.canBuild(gameState, template)) - gameState.ai.queues.corral.addPlan(new m.ConstructionPlan(gameState, template, { "base": this.baseManagers[1].ID })); + gameState.ai.queues.corral.addPlan(new PETRA.ConstructionPlan(gameState, template, { "base": this.baseManagers[1].ID })); } }; - -return m; - -}(PETRA); 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 @@ -1,11 +1,7 @@ -var PETRA = function(m) -{ - /** * Manage the trade */ - -m.TradeManager = function(Config) +PETRA.TradeManager = function(Config) { this.Config = Config; this.tradeRoute = undefined; @@ -15,25 +11,25 @@ this.warnedAllies = {}; }; -m.TradeManager.prototype.init = function(gameState) +PETRA.TradeManager.prototype.init = function(gameState) { this.traders = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "role", "trader")); this.traders.registerUpdates(); this.minimalGain = gameState.ai.HQ.navalMap ? 3 : 5; }; -m.TradeManager.prototype.hasTradeRoute = function() +PETRA.TradeManager.prototype.hasTradeRoute = function() { return this.tradeRoute !== undefined; }; -m.TradeManager.prototype.assignTrader = function(ent) +PETRA.TradeManager.prototype.assignTrader = function(ent) { ent.setMetadata(PlayerID, "role", "trader"); this.traders.updateEnt(ent); }; -m.TradeManager.prototype.trainMoreTraders = function(gameState, queues) +PETRA.TradeManager.prototype.trainMoreTraders = function(gameState, queues) { if (!this.hasTradeRoute() || queues.trader.hasQueuedUnits()) return; @@ -108,14 +104,14 @@ gameState.getPlayerCiv() + " but no template found."); return; } - queues.trader.addPlan(new m.TrainingPlan(gameState, template, metadata, 1, 1)); + queues.trader.addPlan(new PETRA.TrainingPlan(gameState, template, metadata, 1, 1)); }; -m.TradeManager.prototype.updateTrader = function(gameState, ent) +PETRA.TradeManager.prototype.updateTrader = function(gameState, ent) { if (ent.hasClass("Ship") && gameState.ai.playedTurn % 5 == 0 && !ent.unitAIState().startsWith("INDIVIDUAL.GATHER") && - m.gatherTreasure(gameState, ent, true)) + PETRA.gatherTreasure(gameState, ent, true)) return; if (!this.hasTradeRoute() || !ent.isIdle() || !ent.position()) @@ -126,7 +122,7 @@ // TODO if the trader is idle and has workOrders, restore them to avoid losing the current gain Engine.ProfileStart("Trade Manager"); - let access = ent.hasClass("Ship") ? m.getSeaAccess(gameState, ent) : m.getLandAccess(gameState, ent); + let access = ent.hasClass("Ship") ? PETRA.getSeaAccess(gameState, ent) : PETRA.getLandAccess(gameState, ent); let route = this.checkRoutes(gameState, access); if (!route) { @@ -159,7 +155,7 @@ Engine.ProfileStop(); }; -m.TradeManager.prototype.setTradingGoods = function(gameState) +PETRA.TradeManager.prototype.setTradingGoods = function(gameState) { let tradingGoods = {}; for (let res of Resources.GetCodes()) @@ -213,7 +209,7 @@ * Try to barter unneeded resources for needed resources. * only once per turn because the info is not updated within a turn */ -m.TradeManager.prototype.performBarter = function(gameState) +PETRA.TradeManager.prototype.performBarter = function(gameState) { let barterers = gameState.getOwnEntitiesByClass("BarterMarket", true).filter(API3.Filters.isBuilt()).toEntityArray(); if (barterers.length == 0) @@ -327,7 +323,7 @@ return false; }; -m.TradeManager.prototype.checkEvents = function(gameState, events) +PETRA.TradeManager.prototype.checkEvents = function(gameState, events) { // check if one market from a traderoute is renamed, change the route accordingly for (let evt of events.EntityRenamed) @@ -396,7 +392,7 @@ return false; }; -m.TradeManager.prototype.activateProspection = function(gameState) +PETRA.TradeManager.prototype.activateProspection = function(gameState) { this.routeProspection = true; gameState.ai.HQ.buildManager.setBuildable(gameState.applyCiv("structures/{civ}_market")); @@ -407,7 +403,7 @@ * fills the best trade route in this.tradeRoute and the best potential route in this.potentialTradeRoute * If an index is given, it returns the best route with this index or the best land route if index is a land index */ -m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex) +PETRA.TradeManager.prototype.checkRoutes = function(gameState, accessIndex) { let market1 = gameState.updatingCollection("OwnMarkets", API3.Filters.byClass("Market"), gameState.getOwnStructures()); let market2 = gameState.updatingCollection("diplo-ExclusiveAllyMarkets", API3.Filters.byClass("Market"), gameState.getExclusiveAllyEntities()); @@ -433,21 +429,21 @@ { if (!m1.position()) continue; - let access1 = m.getLandAccess(gameState, m1); - let sea1 = m1.hasClass("NavalMarket") ? m.getSeaAccess(gameState, m1) : undefined; + let access1 = PETRA.getLandAccess(gameState, m1); + let sea1 = m1.hasClass("NavalMarket") ? PETRA.getSeaAccess(gameState, m1) : undefined; for (let m2 of market2.values()) { if (onlyOurs && m1.id() >= m2.id()) continue; if (!m2.position()) continue; - let access2 = m.getLandAccess(gameState, m2); - let sea2 = m2.hasClass("NavalMarket") ? m.getSeaAccess(gameState, m2) : undefined; + let access2 = PETRA.getLandAccess(gameState, m2); + let sea2 = m2.hasClass("NavalMarket") ? PETRA.getSeaAccess(gameState, m2) : undefined; let land = access1 == access2 ? access1 : undefined; let sea = sea1 && sea1 == sea2 ? sea1 : undefined; if (!land && !sea) continue; - if (land && m.isLineInsideEnemyTerritory(gameState, m1.position(), m2.position())) + if (land && PETRA.isLineInsideEnemyTerritory(gameState, m1.position(), m2.position())) continue; let gainMultiplier; if (land && traderTemplatesGains.landGainMultiplier) @@ -521,7 +517,7 @@ owner = this.tradeRoute.target.owner(); if (owner != PlayerID && !this.warnedAllies[owner]) { // Warn an ally that we have a trade route with him - m.chatNewTradeRoute(gameState, owner); + PETRA.chatNewTradeRoute(gameState, owner); this.warnedAllies[owner] = true; } } @@ -538,7 +534,7 @@ }; /** Called when a market was built or destroyed, and checks if trader orders should be changed */ -m.TradeManager.prototype.checkTrader = function(gameState, ent) +PETRA.TradeManager.prototype.checkTrader = function(gameState, ent) { let presentRoute = ent.getMetadata(PlayerID, "route"); if (!presentRoute) @@ -551,7 +547,7 @@ return; } - let access = ent.hasClass("Ship") ? m.getSeaAccess(gameState, ent) : m.getLandAccess(gameState, ent); + let access = ent.hasClass("Ship") ? PETRA.getSeaAccess(gameState, ent) : PETRA.getLandAccess(gameState, ent); let possibleRoute = this.checkRoutes(gameState, access); // Warning: presentRoute is from metadata, so contains entity ids if (!possibleRoute || @@ -562,7 +558,7 @@ ent.setMetadata(PlayerID, "route", undefined); if (!possibleRoute && !ent.hasClass("Ship")) { - let closestBase = m.getBestBase(gameState, ent, true); + let closestBase = PETRA.getBestBase(gameState, ent, true); if (closestBase.accessIndex == access) { let closestBasePos = closestBase.anchor.position(); @@ -574,7 +570,7 @@ } }; -m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues) +PETRA.TradeManager.prototype.prospectForNewMarket = function(gameState, queues) { if (queues.economicBuilding.hasQueuedUnitsWithClass("Market") || queues.dock.hasQueuedUnitsWithClass("Market")) return; @@ -612,13 +608,13 @@ if (!this.tradeRoute) gameState.ai.queueManager.changePriority("economicBuilding", 2*this.Config.priorities.economicBuilding); - let plan = new m.ConstructionPlan(gameState, "structures/{civ}_market"); + let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_market"); if (!this.tradeRoute) plan.queueToReset = "economicBuilding"; queues.economicBuilding.addPlan(plan); }; -m.TradeManager.prototype.isNewMarketWorth = function(expectedGain) +PETRA.TradeManager.prototype.isNewMarketWorth = function(expectedGain) { if (expectedGain < this.minimalGain) return false; @@ -628,7 +624,7 @@ return true; }; -m.TradeManager.prototype.update = function(gameState, events, queues) +PETRA.TradeManager.prototype.update = function(gameState, events, queues) { if (gameState.ai.HQ.canBarter) this.performBarter(gameState); @@ -657,7 +653,7 @@ this.prospectForNewMarket(gameState, queues); }; -m.TradeManager.prototype.routeEntToId = function(route) +PETRA.TradeManager.prototype.routeEntToId = function(route) { if (!route) return undefined; @@ -677,7 +673,7 @@ return ret; }; -m.TradeManager.prototype.routeIdToEnt = function(gameState, route) +PETRA.TradeManager.prototype.routeIdToEnt = function(gameState, route) { if (!route) return undefined; @@ -697,7 +693,7 @@ return ret; }; -m.TradeManager.prototype.Serialize = function() +PETRA.TradeManager.prototype.Serialize = function() { return { "tradeRoute": this.routeEntToId(this.tradeRoute), @@ -708,7 +704,7 @@ }; }; -m.TradeManager.prototype.Deserialize = function(gameState, data) +PETRA.TradeManager.prototype.Deserialize = function(gameState, data) { for (let key in data) { @@ -718,6 +714,3 @@ this[key] = data[key]; } }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Describes a transport plan * Constructor assign units (units is an ID array), a destination (position). @@ -23,7 +20,7 @@ * transporter = this.ID */ -m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos, ship) +PETRA.TransportPlan = function(gameState, units, startIndex, endIndex, endPos, ship) { this.ID = gameState.ai.uniqueIDs.transports++; this.debug = gameState.ai.Config.debug; @@ -77,7 +74,7 @@ return true; }; -m.TransportPlan.prototype.init = function(gameState) +PETRA.TransportPlan.prototype.init = function(gameState) { this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "transport", this.ID)); this.ships = gameState.ai.HQ.navalManager.ships.filter(API3.Filters.byMetadata(PlayerID, "transporter", this.ID)); @@ -91,7 +88,7 @@ }; /** count available slots */ -m.TransportPlan.prototype.countFreeSlots = function() +PETRA.TransportPlan.prototype.countFreeSlots = function() { let slots = 0; for (let ship of this.transportShips.values()) @@ -99,7 +96,7 @@ return slots; }; -m.TransportPlan.prototype.countFreeSlotsOnShip = function(ship) +PETRA.TransportPlan.prototype.countFreeSlotsOnShip = function(ship) { if (ship.hitpoints() < ship.garrisonEjectHealth() * ship.maxHitpoints()) return 0; @@ -108,7 +105,7 @@ return Math.max(ship.garrisonMax() - occupied, 0); }; -m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent) +PETRA.TransportPlan.prototype.assignUnitToShip = function(gameState, ent) { if (this.needTransportShips) return; @@ -140,7 +137,7 @@ this.needSplit.push(ent); }; -m.TransportPlan.prototype.assignShip = function(gameState) +PETRA.TransportPlan.prototype.assignShip = function(gameState) { let pos; // choose a unit of this plan not yet assigned to a ship @@ -180,7 +177,7 @@ }; /** add a unit to this plan */ -m.TransportPlan.prototype.addUnit = function(unit, endPos) +PETRA.TransportPlan.prototype.addUnit = function(unit, endPos) { unit.setMetadata(PlayerID, "transport", this.ID); unit.setMetadata(PlayerID, "endPos", endPos); @@ -188,7 +185,7 @@ }; /** remove a unit from this plan, if not yet on board */ -m.TransportPlan.prototype.removeUnit = function(gameState, unit) +PETRA.TransportPlan.prototype.removeUnit = function(gameState, unit) { let shipId = unit.getMetadata(PlayerID, "onBoard"); if (shipId == "onBoard") @@ -212,7 +209,7 @@ } }; -m.TransportPlan.prototype.releaseShip = function(ship) +PETRA.TransportPlan.prototype.releaseShip = function(ship) { if (ship.getMetadata(PlayerID, "transporter") != this.ID) { @@ -230,7 +227,7 @@ ship.setMetadata(PlayerID, "role", "trader"); }; -m.TransportPlan.prototype.releaseAll = function() +PETRA.TransportPlan.prototype.releaseAll = function() { for (let ship of this.ships.values()) this.releaseShip(ship); @@ -250,7 +247,7 @@ }; /** TODO not currently used ... to be fixed */ -m.TransportPlan.prototype.cancelTransport = function(gameState) +PETRA.TransportPlan.prototype.cancelTransport = function(gameState) { let ent = this.units.toEntityArray()[0]; let base = gameState.ai.HQ.getBaseByID(ent.getMetadata(PlayerID, "base")); @@ -282,7 +279,7 @@ * - then the plan is cleared */ -m.TransportPlan.prototype.update = function(gameState) +PETRA.TransportPlan.prototype.update = function(gameState) { if (this.state == "boarding") this.onBoarding(gameState); @@ -292,7 +289,7 @@ return this.units.length; }; -m.TransportPlan.prototype.onBoarding = function(gameState) +PETRA.TransportPlan.prototype.onBoarding = function(gameState) { let ready = true; let time = gameState.ai.elapsedTime; @@ -432,7 +429,7 @@ }; /** tell if a unit is garrisoned in one of the ships of this plan, and update its metadata if yes */ -m.TransportPlan.prototype.isOnBoard = function(ent) +PETRA.TransportPlan.prototype.isOnBoard = function(ent) { for (let ship of this.transportShips.values()) { @@ -445,7 +442,7 @@ }; /** when avoidEnnemy is true, we try to not board/unboard in ennemy territory */ -m.TransportPlan.prototype.getBoardingPos = function(gameState, ship, landIndex, seaIndex, destination, avoidEnnemy) +PETRA.TransportPlan.prototype.getBoardingPos = function(gameState, ship, landIndex, seaIndex, destination, avoidEnnemy) { if (!gameState.ai.HQ.navalManager.landingZones[landIndex]) { @@ -508,7 +505,7 @@ return posmin; }; -m.TransportPlan.prototype.onSailing = function(gameState) +PETRA.TransportPlan.prototype.onSailing = function(gameState) { // Check that the units recovered on the previous turn have been reloaded for (let recov of this.recovered) @@ -526,7 +523,7 @@ if (this.debug > 1) API3.warn(">>> transport " + this.ID + " reloading failed ... <<<"); // destroy the unit if inaccessible otherwise leave it there - let index = m.getLandAccess(gameState, ent); + let index = PETRA.getLandAccess(gameState, ent); if (gameState.ai.HQ.landRegions[index]) { if (this.debug > 1) @@ -574,7 +571,7 @@ ent.destroy(); } } - else if (m.getLandAccess(gameState, ent) != this.endIndex) + else if (PETRA.getLandAccess(gameState, ent) != this.endIndex) { // unit unloaded on a wrong region - try to regarrison it and move a bit the ship if (this.debug > 1) @@ -678,7 +675,7 @@ } }; -m.TransportPlan.prototype.resetUnit = function(gameState, ent) +PETRA.TransportPlan.prototype.resetUnit = function(gameState, ent) { ent.setMetadata(PlayerID, "transport", undefined); ent.setMetadata(PlayerID, "onBoard", undefined); @@ -698,7 +695,7 @@ } }; -m.TransportPlan.prototype.Serialize = function() +PETRA.TransportPlan.prototype.Serialize = function() { return { "ID": this.ID, @@ -717,13 +714,10 @@ }; }; -m.TransportPlan.prototype.Deserialize = function(data) +PETRA.TransportPlan.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; this.failed = false; }; - -return m; -}(PETRA); 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 @@ -1,6 +1,3 @@ -var PETRA = function(m) -{ - /** * Handle events that are important to specific victory conditions: * in capture_the_relic, capture gaia relics and train military guards. @@ -8,7 +5,7 @@ * in wonder, train military guards. */ -m.VictoryManager = function(Config) +PETRA.VictoryManager = function(Config) { this.Config = Config; this.criticalEnts = new Map(); @@ -24,7 +21,7 @@ /** * Cache the ids of any inital victory-critical entities. */ -m.VictoryManager.prototype.init = function(gameState) +PETRA.VictoryManager.prototype.init = function(gameState) { if (gameState.getVictoryConditions().has("wonder")) { @@ -63,7 +60,7 @@ * If it is less than 40%, try to garrison in the closest possible structure * If the hero cannot garrison, retreat it to the closest base */ -m.VictoryManager.prototype.checkEvents = function(gameState, events) +PETRA.VictoryManager.prototype.checkEvents = function(gameState, events) { if (gameState.getVictoryConditions().has("wonder")) { @@ -307,7 +304,7 @@ } }; -m.VictoryManager.prototype.removeCriticalEnt = function(gameState, criticalEntId) +PETRA.VictoryManager.prototype.removeCriticalEnt = function(gameState, criticalEntId) { for (let [guardId, role] of this.criticalEnts.get(criticalEntId).guards) { @@ -333,7 +330,7 @@ /** * Train more healers to be later affected to critical entities if needed */ -m.VictoryManager.prototype.manageCriticalEntHealers = function(gameState, queues) +PETRA.VictoryManager.prototype.manageCriticalEntHealers = function(gameState, queues) { if (gameState.ai.HQ.saveResources || queues.healer.hasQueuedUnits() || !gameState.getOwnEntitiesByClass("Temple", true).hasEntities() || @@ -345,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 m.TrainingPlan(gameState, template, { "role": "criticalEntHealer", "base": 0 }, 1, 1)); + queues.healer.addPlan(new PETRA.TrainingPlan(gameState, template, { "role": "criticalEntHealer", "base": 0 }, 1, 1)); return; } }; @@ -355,7 +352,7 @@ * If we have too low a population and require units for other needs, remove guards so they can be reassigned. * TODO: Swap citizen soldier guards with champions if they become available. */ -m.VictoryManager.prototype.manageCriticalEntGuards = function(gameState) +PETRA.VictoryManager.prototype.manageCriticalEntGuards = function(gameState) { let numWorkers = gameState.getOwnEntitiesByRole("worker", true).length; if (numWorkers < 20) @@ -442,12 +439,12 @@ } }; -m.VictoryManager.prototype.tryAssignMilitaryGuard = function(gameState, guardEnt, criticalEnt, checkForSameAccess) +PETRA.VictoryManager.prototype.tryAssignMilitaryGuard = function(gameState, guardEnt, criticalEnt, checkForSameAccess) { if (guardEnt.getMetadata(PlayerID, "plan") !== undefined || guardEnt.getMetadata(PlayerID, "transport") !== undefined || this.criticalEnts.has(guardEnt.id()) || checkForSameAccess && (!guardEnt.position() || !criticalEnt.position() || - m.getLandAccess(gameState, criticalEnt) != m.getLandAccess(gameState, guardEnt))) + PETRA.getLandAccess(gameState, criticalEnt) != PETRA.getLandAccess(gameState, guardEnt))) return false; if (!this.assignGuardToCriticalEnt(gameState, guardEnt, criticalEnt.id())) @@ -458,7 +455,7 @@ return true; }; -m.VictoryManager.prototype.pickCriticalEntRetreatLocation = function(gameState, criticalEnt, emergency) +PETRA.VictoryManager.prototype.pickCriticalEntRetreatLocation = function(gameState, criticalEnt, emergency) { gameState.ai.HQ.defenseManager.garrisonAttackedUnit(gameState, criticalEnt, emergency); let plan = criticalEnt.getMetadata(PlayerID, "plan"); @@ -472,8 +469,8 @@ // Couldn't find a place to garrison, so the ent will flee from attacks if (!criticalEnt.hasClass("Relic") && criticalEnt.getStance() != "passive") criticalEnt.setStance("passive"); - let accessIndex = m.getLandAccess(gameState, criticalEnt); - let bestBase = m.getBestBase(gameState, criticalEnt, true); + let accessIndex = PETRA.getLandAccess(gameState, criticalEnt); + let bestBase = PETRA.getBestBase(gameState, criticalEnt, true); if (bestBase.accessIndex == accessIndex) { let bestBasePos = bestBase.anchor.position(); @@ -489,7 +486,7 @@ * which will be used once its transport has finished. * Return false if the guardEnt is not a valid guard unit (i.e. cannot guard or is being transported). */ -m.VictoryManager.prototype.assignGuardToCriticalEnt = function(gameState, guardEnt, criticalEntId) +PETRA.VictoryManager.prototype.assignGuardToCriticalEnt = function(gameState, guardEnt, criticalEntId) { if (guardEnt.getMetadata(PlayerID, "transport") !== undefined || !guardEnt.canGuard()) return false; @@ -544,11 +541,11 @@ if (guardEnt.getMetadata(PlayerID, "guardedEnt") != criticalEntId) guardEnt.setMetadata(PlayerID, "guardedEnt", criticalEntId); - let guardEntAccess = m.getLandAccess(gameState, guardEnt); - let criticalEntAccess = m.getLandAccess(gameState, criticalEnt); + let guardEntAccess = PETRA.getLandAccess(gameState, guardEnt); + let criticalEntAccess = PETRA.getLandAccess(gameState, criticalEnt); if (guardEntAccess == criticalEntAccess) { - let queued = m.returnResources(gameState, guardEnt); + let queued = PETRA.returnResources(gameState, guardEnt); guardEnt.guard(criticalEnt, queued); let guardRole = guardEnt.getMetadata(PlayerID, "role") == "criticalEntHealer" ? "healer" : "guard"; this.criticalEnts.get(criticalEntId).guards.set(guardEnt.id(), guardRole); @@ -564,14 +561,14 @@ return true; }; -m.VictoryManager.prototype.resetCaptureGaiaRelic = function(gameState) +PETRA.VictoryManager.prototype.resetCaptureGaiaRelic = function(gameState) { // Do not capture gaia relics too frequently as the ai has access to the entire map this.tryCaptureGaiaRelicLapseTime = gameState.ai.elapsedTime + 240 - 30 * (this.Config.difficulty - 3); this.tryCaptureGaiaRelic = false; }; -m.VictoryManager.prototype.update = function(gameState, events, queues) +PETRA.VictoryManager.prototype.update = function(gameState, events, queues) { // Wait a turn for trigger scripts to spawn any critical ents (i.e. in regicide) if (gameState.ai.playedTurn == 1) @@ -651,7 +648,7 @@ /** * Send an expedition to capture a gaia relic, or reinforce an existing one. */ -m.VictoryManager.prototype.captureGaiaRelic = function(gameState, relic) +PETRA.VictoryManager.prototype.captureGaiaRelic = function(gameState, relic) { let capture = -relic.defaultRegenRate(); let sumCapturePoints = relic.capturePoints().reduce((a, b) => a + b); @@ -662,13 +659,13 @@ if (!attack) continue; for (let ent of attack.unitCollection.values()) - capture += ent.captureStrength() * m.getAttackBonus(ent, relic, "Capture"); + capture += ent.captureStrength() * PETRA.getAttackBonus(ent, relic, "Capture"); } // No need to make a new attack if already enough units if (capture > sumCapturePoints / 50) return; let relicPosition = relic.position(); - let access = m.getLandAccess(gameState, relic); + let access = PETRA.getLandAccess(gameState, relic); let units = gameState.getOwnUnits().filter(ent => { if (!ent.position() || !ent.canCapture(relic)) return false; @@ -685,14 +682,14 @@ if (attack && (attack.state != "unexecuted" || attack.type == "Raid")) return false; } - if (m.getLandAccess(gameState, ent) != access) + if (PETRA.getLandAccess(gameState, ent) != access) return false; return true; }).filterNearest(relicPosition); let expedition = []; for (let ent of units.values()) { - capture += ent.captureStrength() * m.getAttackBonus(ent, relic, "Capture"); + capture += ent.captureStrength() * PETRA.getAttackBonus(ent, relic, "Capture"); expedition.push(ent); if (capture > sumCapturePoints / 25) break; @@ -715,7 +712,7 @@ this.targetedGaiaRelics.get(relic.id()).push(plan); }; -m.VictoryManager.prototype.abortCaptureGaiaRelic = function(gameState, relicId) +PETRA.VictoryManager.prototype.abortCaptureGaiaRelic = function(gameState, relicId) { for (let plan of this.targetedGaiaRelics.get(relicId)) { @@ -726,7 +723,7 @@ this.targetedGaiaRelics.delete(relicId); }; -m.VictoryManager.prototype.Serialize = function() +PETRA.VictoryManager.prototype.Serialize = function() { return { "criticalEnts": this.criticalEnts, @@ -738,11 +735,8 @@ }; }; -m.VictoryManager.prototype.Deserialize = function(data) +PETRA.VictoryManager.prototype.Deserialize = function(data) { for (let key in data) this[key] = data[key]; }; - -return m; -}(PETRA); 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 @@ -1,18 +1,14 @@ -var PETRA = function(m) -{ - /** * This class makes a worker do as instructed by the economy manager */ - -m.Worker = function(base) +PETRA.Worker = function(base) { this.ent = undefined; this.base = base; this.baseID = base.ID; }; -m.Worker.prototype.update = function(gameState, ent) +PETRA.Worker.prototype.update = function(gameState, ent) { if (!ent.position() || ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) return; @@ -40,9 +36,9 @@ let gatherType = ent.getMetadata(PlayerID, "gather-type") || "food"; for (let structure of gameState.getOwnStructures().values()) { - if (m.getLandAccess(gameState, structure) != plan.endIndex) + if (PETRA.getLandAccess(gameState, structure) != plan.endIndex) continue; - let resourceDropsiteTypes = m.getBuiltEntity(gameState, structure).resourceDropsiteTypes(); + let resourceDropsiteTypes = PETRA.getBuiltEntity(gameState, structure).resourceDropsiteTypes(); if (!resourceDropsiteTypes || resourceDropsiteTypes.indexOf(gatherType) == -1) continue; hasDropsite = true; @@ -52,7 +48,7 @@ { for (let unit of gameState.getOwnUnits().filter(API3.Filters.byClass("Support")).values()) { - if (!unit.position() || m.getLandAccess(gameState, unit) != plan.endIndex) + if (!unit.position() || PETRA.getLandAccess(gameState, unit) != plan.endIndex) continue; let resourceDropsiteTypes = unit.resourceDropsiteTypes(); if (!resourceDropsiteTypes || resourceDropsiteTypes.indexOf(gatherType) == -1) @@ -69,7 +65,7 @@ return; } - this.entAccess = m.getLandAccess(gameState, ent); + this.entAccess = PETRA.getLandAccess(gameState, ent); // base 0 for unassigned entities has no accessIndex, so take the one from the entity if (this.baseID == gameState.ai.HQ.baseManagers[0].ID) this.baseAccess = this.entAccess; @@ -117,7 +113,7 @@ else if (!gameState.isPlayerAlly(territoryOwner)) { let distanceSquare = ent.hasClass("Cavalry") ? 90000 : 30000; - let targetAccess = m.getLandAccess(gameState, target); + let targetAccess = PETRA.getLandAccess(gameState, target); let foodDropsites = gameState.playerData.hasSharedDropsites ? gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food"); let hasFoodDropsiteWithinDistance = false; @@ -129,7 +125,7 @@ // owner != PlayerID can only happen when hasSharedDropsites == true, so no need to test it again if (owner != PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - if (targetAccess != m.getLandAccess(gameState, dropsite)) + if (targetAccess != PETRA.getLandAccess(gameState, dropsite)) continue; if (API3.SquareVectorDistance(target.position(), dropsite.position()) < distanceSquare) { @@ -169,7 +165,7 @@ if (orderData && orderData.target) { let target = gameState.getEntityById(orderData.target); - if (target && (!target.position() || m.getLandAccess(gameState, target) != this.entAccess)) + if (target && (!target.position() || PETRA.getLandAccess(gameState, target) != this.entAccess)) { if (this.retryWorking(gameState, subrole)) return; @@ -187,7 +183,7 @@ // and UnitAI sent it fight back with allowCapture=true let target = gameState.getEntityById(orderData.target); if (target && target.owner() > 0 && !gameState.isPlayerAlly(target.owner())) - ent.attack(orderData.target, m.allowCapture(gameState, ent, target)); + ent.attack(orderData.target, PETRA.allowCapture(gameState, ent, target)); } } return; @@ -209,7 +205,7 @@ { this.startGathering(gameState); } - else if (!m.returnResources(gameState, ent)) // try to deposit resources + else if (!PETRA.returnResources(gameState, ent)) // try to deposit resources { // no dropsite, abandon old resources and start gathering new ones this.startGathering(gameState); @@ -265,8 +261,8 @@ { // Check from time to time that UnitAI does not send us to an inaccessible dropsite let dropsite = gameState.getEntityById(ent.unitAIOrderData()[0].target); - if (dropsite && dropsite.position() && this.entAccess != m.getLandAccess(gameState, dropsite)) - m.returnResources(gameState, this.ent); + if (dropsite && dropsite.position() && this.entAccess != PETRA.getLandAccess(gameState, dropsite)) + PETRA.returnResources(gameState, this.ent); } // If gathering a sparse resource, we may have been sent to a faraway resource if the one nearby was full. @@ -348,8 +344,8 @@ } else { - let goalAccess = m.getLandAccess(gameState, target); - let queued = m.returnResources(gameState, ent); + let goalAccess = PETRA.getLandAccess(gameState, target); + let queued = PETRA.returnResources(gameState, ent); if (this.entAccess == goalAccess) ent.repair(target, target.hasClass("House"), queued); // autocontinue=true for houses else @@ -397,8 +393,8 @@ { // Check that UnitAI does not send us to an inaccessible dropsite let dropsite = gameState.getEntityById(ent.unitAIOrderData()[0].target); - if (dropsite && dropsite.position() && this.entAccess != m.getLandAccess(gameState, dropsite)) - m.returnResources(gameState, ent); + if (dropsite && dropsite.position() && this.entAccess != PETRA.getLandAccess(gameState, dropsite)) + PETRA.returnResources(gameState, ent); } } } @@ -416,7 +412,7 @@ } }; -m.Worker.prototype.retryWorking = function(gameState, subrole) +PETRA.Worker.prototype.retryWorking = function(gameState, subrole) { switch (subrole) { @@ -433,21 +429,21 @@ } }; -m.Worker.prototype.startBuilding = function(gameState) +PETRA.Worker.prototype.startBuilding = function(gameState) { let target = gameState.getEntityById(this.ent.getMetadata(PlayerID, "target-foundation")); if (!target || target.foundationProgress() === undefined && target.needsRepair() == false) return false; - if (m.getLandAccess(gameState, target) != this.entAccess) + if (PETRA.getLandAccess(gameState, target) != this.entAccess) return false; this.ent.repair(target, target.hasClass("House")); // autocontinue=true for houses return true; }; -m.Worker.prototype.startGathering = function(gameState) +PETRA.Worker.prototype.startGathering = function(gameState) { // First look for possible treasure if any - if (m.gatherTreasure(gameState, this.ent)) + if (PETRA.gatherTreasure(gameState, this.ent)) return true; let resource = this.ent.getMetadata(PlayerID, "gather-type"); @@ -467,7 +463,7 @@ supplies.splice(i--, 1); continue; } - if (m.IsSupplyFull(gameState, supplies[i].ent)) + if (PETRA.IsSupplyFull(gameState, supplies[i].ent)) continue; let inaccessibleTime = supplies[i].ent.getMetadata(PlayerID, "inaccessibleTime"); if (inaccessibleTime && gameState.ai.elapsedTime < inaccessibleTime) @@ -586,7 +582,7 @@ // Try to help building one if any accessible foundation available let foundations = gameState.getOwnFoundations().toEntityArray(); let shouldBuild = this.ent.isBuilder() && foundations.some(function(foundation) { - if (!foundation || m.getLandAccess(gameState, foundation) != this.entAccess) + if (!foundation || PETRA.getLandAccess(gameState, foundation) != this.entAccess) return false; let structure = gameState.getBuiltTemplate(foundation.templateName()); if (structure.resourceDropsiteTypes() && structure.resourceDropsiteTypes().indexOf(resource) != -1) @@ -653,12 +649,12 @@ // Okay so we haven't found any appropriate dropsite anywhere. // Try to help building one if any non-accessible foundation available shouldBuild = this.ent.isBuilder() && foundations.some(function(foundation) { - if (!foundation || m.getLandAccess(gameState, foundation) == this.entAccess) + if (!foundation || PETRA.getLandAccess(gameState, foundation) == this.entAccess) return false; let structure = gameState.getBuiltTemplate(foundation.templateName()); if (structure.resourceDropsiteTypes() && structure.resourceDropsiteTypes().indexOf(resource) != -1) { - let foundationAccess = m.getLandAccess(gameState, foundation); + let foundationAccess = PETRA.getLandAccess(gameState, foundation); if (navalManager.requireTransport(gameState, this.ent, this.entAccess, foundationAccess, foundation.position())) { if (foundation.getMetadata(PlayerID, "base") != this.baseID) @@ -735,10 +731,10 @@ * if position is given, we only check if we could hunt from this position but do nothing * otherwise the position of the entity is taken, and if something is found, we directly start the hunt */ -m.Worker.prototype.startHunting = function(gameState, position) +PETRA.Worker.prototype.startHunting = function(gameState, position) { // First look for possible treasure if any - if (!position && m.gatherTreasure(gameState, this.ent)) + if (!position && PETRA.gatherTreasure(gameState, this.ent)) return true; let resources = gameState.getHuntableSupplies(); @@ -764,7 +760,7 @@ // owner != PlayerID can only happen when hasSharedDropsites == true, so no need to test it again if (owner != PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - if (supplyAccess != m.getLandAccess(gameState, dropsite)) + if (supplyAccess != PETRA.getLandAccess(gameState, dropsite)) continue; if (API3.SquareVectorDistance(supplyPosition, dropsite.position()) < distSquare) return true; @@ -786,7 +782,7 @@ if (!gatherRates[supplyType]) continue; - if (m.IsSupplyFull(gameState, supply)) + if (PETRA.IsSupplyFull(gameState, supply)) continue; // check if available resource is worth one additionnal gatherer (except for farms) let nbGatherers = supply.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(supply.id()); @@ -798,7 +794,7 @@ if (canFlee && !isCavalry && !isRanged) continue; - let supplyAccess = m.getLandAccess(gameState, supply); + let supplyAccess = PETRA.getLandAccess(gameState, supply); if (supplyAccess != this.entAccess) continue; @@ -843,7 +839,7 @@ return false; }; -m.Worker.prototype.startFishing = function(gameState) +PETRA.Worker.prototype.startFishing = function(gameState) { if (!this.ent.position()) return false; @@ -859,7 +855,7 @@ let nearestSupplyDist = Math.min(); let nearestSupply; - let fisherSea = m.getSeaAccess(gameState, this.ent); + let fisherSea = PETRA.getSeaAccess(gameState, this.ent); let fishDropsites = (gameState.playerData.hasSharedDropsites ? gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food")). filter(API3.Filters.byClass("Dock")).toEntityArray(); @@ -874,7 +870,7 @@ // owner != PlayerID can only happen when hasSharedDropsites == true, so no need to test it again if (owner != PlayerID && (!dropsite.isSharedDropsite() || !gameState.isPlayerMutualAlly(owner))) continue; - if (fisherSea != m.getSeaAccess(gameState, dropsite)) + if (fisherSea != PETRA.getSeaAccess(gameState, dropsite)) continue; distMin = Math.min(distMin, API3.SquareVectorDistance(pos, dropsite.position())); } @@ -898,7 +894,7 @@ if (!gatherRates[supplyType]) return; - if (m.IsSupplyFull(gameState, supply)) + if (PETRA.IsSupplyFull(gameState, supply)) return; // check if available resource is worth one additionnal gatherer (except for farms) let nbGatherers = supply.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(supply.id()); @@ -938,7 +934,7 @@ return false; }; -m.Worker.prototype.gatherNearestField = function(gameState, baseID) +PETRA.Worker.prototype.gatherNearestField = function(gameState, baseID) { let ownFields = gameState.getOwnEntitiesByClass("Field", true).filter(API3.Filters.isBuilt()).filter(API3.Filters.byMetadata(PlayerID, "base", baseID)); let bestFarm; @@ -946,7 +942,7 @@ let gatherRates = this.ent.resourceGatherRates(); for (let field of ownFields.values()) { - if (m.IsSupplyFull(gameState, field)) + if (PETRA.IsSupplyFull(gameState, field)) continue; let supplyType = field.get("ResourceSupply/Type"); if (!gatherRates[supplyType]) @@ -978,7 +974,7 @@ * WARNING with the present options of AI orders, the unit will not gather after building the farm. * This is done by calling the gatherNearestField function when construction is completed. */ -m.Worker.prototype.buildAnyField = function(gameState, baseID) +PETRA.Worker.prototype.buildAnyField = function(gameState, baseID) { if (!this.ent.isBuilder()) return false; @@ -1007,7 +1003,7 @@ * For the time being, we move towards the nearest gatherer (providing him a dropsite). * BaseManager does also use that function to deal with its mobile dropsites. */ -m.Worker.prototype.moveToGatherer = function(gameState, ent, forced) +PETRA.Worker.prototype.moveToGatherer = function(gameState, ent, forced) { let pos = ent.position(); if (!pos || ent.getMetadata(PlayerID, "target-foundation") !== undefined) @@ -1017,7 +1013,7 @@ let gatherers = this.base.workersBySubrole(gameState, "gatherer"); let dist = Math.min(); let destination; - let access = m.getLandAccess(gameState, ent); + let access = PETRA.getLandAccess(gameState, ent); let types = ent.resourceDropsiteTypes(); for (let gatherer of gatherers.values()) { @@ -1025,7 +1021,7 @@ if (!gathererType || types.indexOf(gathererType) == -1) continue; if (!gatherer.position() || gatherer.getMetadata(PlayerID, "transport") !== undefined || - m.getLandAccess(gameState, gatherer) != access || gatherer.isIdle()) + PETRA.getLandAccess(gameState, gatherer) != access || gatherer.isIdle()) continue; let distance = API3.SquareVectorDistance(pos, gatherer.position()); if (distance > dist) @@ -1043,7 +1039,7 @@ * inside obstruction of other entities). The resource will be flagged as inaccessible during 10 mn (in case * it will be cleared later). */ -m.Worker.prototype.isInaccessibleSupply = function(gameState) +PETRA.Worker.prototype.isInaccessibleSupply = function(gameState) { if (!this.ent.unitAIOrderData()[0] || !this.ent.unitAIOrderData()[0].target) return false; @@ -1109,6 +1105,3 @@ } return false; }; - -return m; -}(PETRA);