Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js
Show All 21 Lines | PETRA.BaseManager = function(gameState, basesManager) | ||||
this.accessIndex = undefined; | this.accessIndex = undefined; | ||||
// Maximum distance (from any dropsite) to look for resources | // Maximum distance (from any dropsite) to look for resources | ||||
// 3 areas are used: from 0 to max/4, from max/4 to max/2 and from max/2 to max | // 3 areas are used: from 0 to max/4, from max/4 to max/2 and from max/2 to max | ||||
this.maxDistResourceSquare = 360*360; | this.maxDistResourceSquare = 360*360; | ||||
this.constructing = false; | this.constructing = false; | ||||
// Defenders to train in this cc when its construction is finished | // Defenders to train in this cc when its construction is finished | ||||
this.neededDefenders = this.Config.difficulty > 2 ? 3 + 2*(this.Config.difficulty - 3) : 0; | this.neededDefenders = this.Config.difficulty > PETRA.DIFFICULTY_EASY ? 3 + 2*(this.Config.difficulty - 3) : 0; | ||||
// vector for iterating, to check one use the HQ map. | // vector for iterating, to check one use the HQ map. | ||||
this.territoryIndices = []; | this.territoryIndices = []; | ||||
this.timeNextIdleCheck = 0; | this.timeNextIdleCheck = 0; | ||||
}; | }; | ||||
Show All 18 Lines | |||||
{ | { | ||||
if (state === PETRA.BaseManager.STATE_UNCONSTRUCTED) | if (state === PETRA.BaseManager.STATE_UNCONSTRUCTED) | ||||
this.constructing = true; | this.constructing = true; | ||||
else if (state !== PETRA.BaseManager.STATE_CAPTURED) | else if (state !== PETRA.BaseManager.STATE_CAPTURED) | ||||
this.neededDefenders = 0; | this.neededDefenders = 0; | ||||
this.workerObject = new PETRA.Worker(this); | this.workerObject = new PETRA.Worker(this); | ||||
// entitycollections | // entitycollections | ||||
this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); | this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); | ||||
this.workers = this.units.filter(API3.Filters.byMetadata(PlayerID, "role", "worker")); | this.workers = this.units.filter(API3.Filters.byMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER)); | ||||
this.buildings = gameState.getOwnStructures().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); | this.buildings = gameState.getOwnStructures().filter(API3.Filters.byMetadata(PlayerID, "base", this.ID)); | ||||
this.mobileDropsites = this.units.filter(API3.Filters.isDropsite()); | this.mobileDropsites = this.units.filter(API3.Filters.isDropsite()); | ||||
this.units.registerUpdates(); | this.units.registerUpdates(); | ||||
this.workers.registerUpdates(); | this.workers.registerUpdates(); | ||||
this.buildings.registerUpdates(); | this.buildings.registerUpdates(); | ||||
this.mobileDropsites.registerUpdates(); | this.mobileDropsites.registerUpdates(); | ||||
Show All 9 Lines | |||||
}; | }; | ||||
PETRA.BaseManager.prototype.reset = function(gameState, state) | PETRA.BaseManager.prototype.reset = function(gameState, state) | ||||
{ | { | ||||
if (state === PETRA.BaseManager.STATE_UNCONSTRUCTED) | if (state === PETRA.BaseManager.STATE_UNCONSTRUCTED) | ||||
this.constructing = true; | this.constructing = true; | ||||
else | else | ||||
this.constructing = false; | this.constructing = false; | ||||
if (state !== PETRA.BaseManager.STATE_CAPTURED || this.Config.difficulty < PETRA.DIFFICULTY_MEDIUM) | |||||
if (state !== PETRA.BaseManager.STATE_CAPTURED || this.Config.difficulty < 3) | |||||
this.neededDefenders = 0; | this.neededDefenders = 0; | ||||
else | else | ||||
this.neededDefenders = 3 + 2 * (this.Config.difficulty - 3); | this.neededDefenders = 3 + 2 * (this.Config.difficulty - 3); | ||||
}; | }; | ||||
PETRA.BaseManager.prototype.assignEntity = function(gameState, ent) | PETRA.BaseManager.prototype.assignEntity = function(gameState, ent) | ||||
{ | { | ||||
ent.setMetadata(PlayerID, "base", this.ID); | ent.setMetadata(PlayerID, "base", this.ID); | ||||
▲ Show 20 Lines • Show All 404 Lines • ▼ Show 20 Lines | this.gatherersByType(gameState, res).forEach(ent => { | ||||
if (ent.isIdle() || !ent.position()) | if (ent.isIdle() || !ent.position()) | ||||
return; | return; | ||||
let gRate = ent.currentGatherRate(); | let gRate = ent.currentGatherRate(); | ||||
if (gRate) | if (gRate) | ||||
currentRates[res] += Math.log(1+gRate)/1.1; | currentRates[res] += Math.log(1+gRate)/1.1; | ||||
}); | }); | ||||
if (res == "food") | if (res == "food") | ||||
{ | { | ||||
this.workersBySubrole(gameState, "hunter").forEach(ent => { | this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_HUNTER).forEach(ent => { | ||||
if (ent.isIdle() || !ent.position()) | if (ent.isIdle() || !ent.position()) | ||||
return; | return; | ||||
let gRate = ent.currentGatherRate(); | let gRate = ent.currentGatherRate(); | ||||
if (gRate) | if (gRate) | ||||
currentRates[res] += Math.log(1+gRate)/1.1; | currentRates[res] += Math.log(1+gRate)/1.1; | ||||
}); | }); | ||||
this.workersBySubrole(gameState, "fisher").forEach(ent => { | this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_FISHER).forEach(ent => { | ||||
if (ent.isIdle() || !ent.position()) | if (ent.isIdle() || !ent.position()) | ||||
return; | return; | ||||
let gRate = ent.currentGatherRate(); | let gRate = ent.currentGatherRate(); | ||||
if (gRate) | if (gRate) | ||||
currentRates[res] += Math.log(1+gRate)/1.1; | currentRates[res] += Math.log(1+gRate)/1.1; | ||||
}); | }); | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
PETRA.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) | PETRA.BaseManager.prototype.assignRolelessUnits = function(gameState, roleless) | ||||
{ | { | ||||
if (!roleless) | if (!roleless) | ||||
roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role"))).values(); | roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role"))).values(); | ||||
for (let ent of roleless) | for (let ent of roleless) | ||||
{ | { | ||||
if (ent.hasClasses(["Worker", "CitizenSoldier", "FishingBoat"])) | if (ent.hasClasses(["Worker", "CitizenSoldier", "FishingBoat"])) | ||||
ent.setMetadata(PlayerID, "role", "worker"); | ent.setMetadata(PlayerID, "role", PETRA.Worker.ROLE_WORKER); | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* If the numbers of workers on the resources is unbalanced then set some of workers to idle so | * If the numbers of workers on the resources is unbalanced then set some of workers to idle so | ||||
* they can be reassigned by reassignIdleWorkers. | * they can be reassigned by reassignIdleWorkers. | ||||
* TODO: actually this probably should be in the HQ. | * TODO: actually this probably should be in the HQ. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | PETRA.BaseManager.prototype.switchGatherer = function(gameState, from, to, number) | ||||
return num; | return num; | ||||
}; | }; | ||||
PETRA.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 | // Search for idle workers, and tell them to gather resources based on demand | ||||
if (!idleWorkers) | if (!idleWorkers) | ||||
{ | { | ||||
let filter = API3.Filters.byMetadata(PlayerID, "subrole", "idle"); | const filter = API3.Filters.byMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); | ||||
idleWorkers = gameState.updatingCollection("idle-workers-base-" + this.ID, filter, this.workers).values(); | idleWorkers = gameState.updatingCollection("idle-workers-base-" + this.ID, filter, this.workers).values(); | ||||
} | } | ||||
for (let ent of idleWorkers) | for (let ent of idleWorkers) | ||||
{ | { | ||||
// Check that the worker isn't garrisoned | // Check that the worker isn't garrisoned | ||||
if (!ent.position()) | if (!ent.position()) | ||||
continue; | continue; | ||||
Show All 11 Lines | if (ent.hasClass("Worker")) | ||||
{ | { | ||||
if (!ent.canGather(needed.type)) | if (!ent.canGather(needed.type)) | ||||
continue; | continue; | ||||
let lastFailed = gameState.ai.HQ.lastFailedGather[needed.type]; | let lastFailed = gameState.ai.HQ.lastFailedGather[needed.type]; | ||||
if (lastFailed && gameState.ai.elapsedTime - lastFailed < 20) | if (lastFailed && gameState.ai.elapsedTime - lastFailed < 20) | ||||
continue; | continue; | ||||
if (needed.type != "food" && this.basesManager.isResourceExhausted(needed.type)) | if (needed.type != "food" && this.basesManager.isResourceExhausted(needed.type)) | ||||
continue; | continue; | ||||
ent.setMetadata(PlayerID, "subrole", "gatherer"); | ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_GATHERER); | ||||
ent.setMetadata(PlayerID, "gather-type", needed.type); | ent.setMetadata(PlayerID, "gather-type", needed.type); | ||||
this.basesManager.AddTCResGatherer(needed.type); | this.basesManager.AddTCResGatherer(needed.type); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
else if (PETRA.isFastMoving(ent) && ent.canGather("food") && ent.canAttackClass("Animal")) | else if (PETRA.isFastMoving(ent) && ent.canGather("food") && ent.canAttackClass("Animal")) | ||||
ent.setMetadata(PlayerID, "subrole", "hunter"); | ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_HUNTER); | ||||
else if (ent.hasClass("FishingBoat")) | else if (ent.hasClass("FishingBoat")) | ||||
ent.setMetadata(PlayerID, "subrole", "fisher"); | ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_FISHER); | ||||
} | } | ||||
}; | }; | ||||
PETRA.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); | return gameState.updatingCollection("subrole-" + subrole +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "subrole", subrole), this.workers); | ||||
}; | }; | ||||
PETRA.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")); | return gameState.updatingCollection("workers-gathering-" + type +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "gather-type", type), this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_GATHERER)); | ||||
}; | }; | ||||
/** | /** | ||||
* returns an entity collection of workers. | * returns an entity collection of workers. | ||||
* They are idled immediatly and their subrole set to idle. | * They are idled immediatly and their subrole set to idle. | ||||
*/ | */ | ||||
PETRA.BaseManager.prototype.pickBuilders = function(gameState, workers, number) | PETRA.BaseManager.prototype.pickBuilders = function(gameState, workers, number) | ||||
{ | { | ||||
let availableWorkers = this.workers.filter(ent => { | let availableWorkers = this.workers.filter(ent => { | ||||
if (!ent.position() || !ent.isBuilder()) | if (!ent.position() || !ent.isBuilder()) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "transport")) | if (ent.getMetadata(PlayerID, "transport")) | ||||
return false; | return false; | ||||
return true; | return true; | ||||
}).toEntityArray(); | }).toEntityArray(); | ||||
availableWorkers.sort((a, b) => { | availableWorkers.sort((a, b) => { | ||||
let vala = 0; | let vala = 0; | ||||
let valb = 0; | let valb = 0; | ||||
if (a.getMetadata(PlayerID, "subrole") == "builder") | if (a.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) | ||||
vala = 100; | vala = 100; | ||||
if (b.getMetadata(PlayerID, "subrole") == "builder") | if (b.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) | ||||
valb = 100; | valb = 100; | ||||
if (a.getMetadata(PlayerID, "subrole") == "idle") | if (a.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_IDLE) | ||||
vala = -50; | vala = -50; | ||||
if (b.getMetadata(PlayerID, "subrole") == "idle") | if (b.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_IDLE) | ||||
valb = -50; | valb = -50; | ||||
if (a.getMetadata(PlayerID, "plan") === undefined) | if (a.getMetadata(PlayerID, "plan") === undefined) | ||||
vala = -20; | vala = -20; | ||||
if (b.getMetadata(PlayerID, "plan") === undefined) | if (b.getMetadata(PlayerID, "plan") === undefined) | ||||
valb = -20; | valb = -20; | ||||
return vala - valb; | return vala - valb; | ||||
}); | }); | ||||
let needed = Math.min(number, availableWorkers.length - 3); | let needed = Math.min(number, availableWorkers.length - 3); | ||||
for (let i = 0; i < needed; ++i) | for (let i = 0; i < needed; ++i) | ||||
{ | { | ||||
availableWorkers[i].stopMoving(); | availableWorkers[i].stopMoving(); | ||||
availableWorkers[i].setMetadata(PlayerID, "subrole", "idle"); | availableWorkers[i].setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_IDLE); | ||||
workers.addEnt(availableWorkers[i]); | workers.addEnt(availableWorkers[i]); | ||||
} | } | ||||
return; | return; | ||||
}; | }; | ||||
/** | /** | ||||
* If we have some foundations, and we don't have enough builder-workers, | * If we have some foundations, and we don't have enough builder-workers, | ||||
* try reassigning some other workers who are nearby | * try reassigning some other workers who are nearby | ||||
* AI tries to use builders sensibly, not completely stopping its econ. | * AI tries to use builders sensibly, not completely stopping its econ. | ||||
*/ | */ | ||||
PETRA.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")))); | let foundations = this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(), API3.Filters.not(API3.Filters.byClass("Field")))); | ||||
let damagedBuildings = this.buildings.filter(ent => ent.foundationProgress() === undefined && ent.needsRepair()); | let damagedBuildings = this.buildings.filter(ent => ent.foundationProgress() === undefined && ent.needsRepair()); | ||||
// Check if nothing to build | // Check if nothing to build | ||||
if (!foundations.length && !damagedBuildings.length) | if (!foundations.length && !damagedBuildings.length) | ||||
return; | return; | ||||
let workers = this.workers.filter(ent => ent.isBuilder()); | let workers = this.workers.filter(ent => ent.isBuilder()); | ||||
let builderWorkers = this.workersBySubrole(gameState, "builder"); | const builderWorkers = this.workersBySubrole(gameState, PETRA.Worker.SUBROLE_BUILDER); | ||||
let idleBuilderWorkers = builderWorkers.filter(API3.Filters.isIdle()); | let idleBuilderWorkers = builderWorkers.filter(API3.Filters.isIdle()); | ||||
// if we're constructing and we have the foundations to our base anchor, only try building that. | // if we're constructing and we have the foundations to our base anchor, only try building that. | ||||
if (this.constructing && foundations.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)).hasEntities()) | if (this.constructing && foundations.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)).hasEntities()) | ||||
{ | { | ||||
foundations = foundations.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)); | foundations = foundations.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)); | ||||
let tID = foundations.toEntityArray()[0].id(); | let tID = foundations.toEntityArray()[0].id(); | ||||
workers.forEach(ent => { | workers.forEach(ent => { | ||||
Show All 9 Lines | PETRA.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) | ||||
if (workers.length < 3) | if (workers.length < 3) | ||||
{ | { | ||||
const fromOtherBase = this.basesManager.bulkPickWorkers(gameState, this, 2); | const fromOtherBase = this.basesManager.bulkPickWorkers(gameState, this, 2); | ||||
if (fromOtherBase) | if (fromOtherBase) | ||||
{ | { | ||||
let baseID = this.ID; | let baseID = this.ID; | ||||
fromOtherBase.forEach(worker => { | fromOtherBase.forEach(worker => { | ||||
worker.setMetadata(PlayerID, "base", baseID); | worker.setMetadata(PlayerID, "base", baseID); | ||||
worker.setMetadata(PlayerID, "subrole", "builder"); | worker.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); | ||||
workers.updateEnt(worker); | workers.updateEnt(worker); | ||||
builderWorkers.updateEnt(worker); | builderWorkers.updateEnt(worker); | ||||
idleBuilderWorkers.updateEnt(worker); | idleBuilderWorkers.updateEnt(worker); | ||||
}); | }); | ||||
} | } | ||||
} | } | ||||
let builderTot = builderWorkers.length - idleBuilderWorkers.length; | let builderTot = builderWorkers.length - idleBuilderWorkers.length; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | idleBuilderWorkers.forEach(function(ent) { | ||||
return; | return; | ||||
++assigned; | ++assigned; | ||||
++builderTot; | ++builderTot; | ||||
ent.setMetadata(PlayerID, "target-foundation", target.id()); | ent.setMetadata(PlayerID, "target-foundation", target.id()); | ||||
}); | }); | ||||
if (assigned >= targetNB || builderTot >= maxTotalBuilders) | if (assigned >= targetNB || builderTot >= maxTotalBuilders) | ||||
continue; | continue; | ||||
let nonBuilderWorkers = workers.filter(function(ent) { | let nonBuilderWorkers = workers.filter(function(ent) { | ||||
if (ent.getMetadata(PlayerID, "subrole") == "builder") | if (ent.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) | ||||
return false; | return false; | ||||
if (!ent.position()) | if (!ent.position()) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "transport")) | if (ent.getMetadata(PlayerID, "transport")) | ||||
return false; | return false; | ||||
return true; | return true; | ||||
Show All 11 Lines | for (let target of foundations.values()) | ||||
let current = 0; | let current = 0; | ||||
let nonBuilderTot = nonBuilderWorkers.length; | let nonBuilderTot = nonBuilderWorkers.length; | ||||
while (assigned < targetNB && builderTot < maxTotalBuilders && current < nonBuilderTot) | while (assigned < targetNB && builderTot < maxTotalBuilders && current < nonBuilderTot) | ||||
{ | { | ||||
++assigned; | ++assigned; | ||||
++builderTot; | ++builderTot; | ||||
let ent = nonBuilderWorkers[current++]; | let ent = nonBuilderWorkers[current++]; | ||||
ent.stopMoving(); | ent.stopMoving(); | ||||
ent.setMetadata(PlayerID, "subrole", "builder"); | ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); | ||||
ent.setMetadata(PlayerID, "target-foundation", target.id()); | ent.setMetadata(PlayerID, "target-foundation", target.id()); | ||||
} | } | ||||
} | } | ||||
for (let target of damagedBuildings.values()) | for (let target of damagedBuildings.values()) | ||||
{ | { | ||||
// Don't repair if we're still under attack, unless it's a vital (civcentre or wall) building | // Don't repair if we're still under attack, unless it's a vital (civcentre or wall) building | ||||
// that's being destroyed. | // that's being destroyed. | ||||
Show All 38 Lines | idleBuilderWorkers.forEach(function(ent) { | ||||
return; | return; | ||||
++assigned; | ++assigned; | ||||
++builderTot; | ++builderTot; | ||||
ent.setMetadata(PlayerID, "target-foundation", target.id()); | ent.setMetadata(PlayerID, "target-foundation", target.id()); | ||||
}); | }); | ||||
if (assigned >= targetNB || builderTot >= maxTotalBuilders) | if (assigned >= targetNB || builderTot >= maxTotalBuilders) | ||||
continue; | continue; | ||||
let nonBuilderWorkers = workers.filter(function(ent) { | let nonBuilderWorkers = workers.filter(function(ent) { | ||||
if (ent.getMetadata(PlayerID, "subrole") == "builder") | if (ent.getMetadata(PlayerID, "subrole") === PETRA.Worker.SUBROLE_BUILDER) | ||||
return false; | return false; | ||||
if (!ent.position()) | if (!ent.position()) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | if (ent.getMetadata(PlayerID, "plan") == -2 || ent.getMetadata(PlayerID, "plan") == -3) | ||||
return false; | return false; | ||||
if (ent.getMetadata(PlayerID, "transport")) | if (ent.getMetadata(PlayerID, "transport")) | ||||
return false; | return false; | ||||
return true; | return true; | ||||
}); | }); | ||||
let num = Math.min(nonBuilderWorkers.length, targetNB-assigned); | let num = Math.min(nonBuilderWorkers.length, targetNB-assigned); | ||||
let nearestNonBuilders = nonBuilderWorkers.filterNearest(target.position(), num); | let nearestNonBuilders = nonBuilderWorkers.filterNearest(target.position(), num); | ||||
nearestNonBuilders.forEach(function(ent) { | nearestNonBuilders.forEach(function(ent) { | ||||
++assigned; | ++assigned; | ||||
++builderTot; | ++builderTot; | ||||
ent.stopMoving(); | ent.stopMoving(); | ||||
ent.setMetadata(PlayerID, "subrole", "builder"); | ent.setMetadata(PlayerID, "subrole", PETRA.Worker.SUBROLE_BUILDER); | ||||
ent.setMetadata(PlayerID, "target-foundation", target.id()); | ent.setMetadata(PlayerID, "target-foundation", target.id()); | ||||
}); | }); | ||||
} | } | ||||
}; | }; | ||||
/** Return false when the base is not active (no workers on it) */ | /** Return false when the base is not active (no workers on it) */ | ||||
PETRA.BaseManager.prototype.update = function(gameState, queues, events) | PETRA.BaseManager.prototype.update = function(gameState, queues, events) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 170 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator