forked from mirrors/0ad
Petra: revisit the attacks + several bugfixes + add some more debug printouts
This was SVN commit r15695.
This commit is contained in:
@@ -120,7 +120,7 @@ m.PetraBot.prototype.initPersonality = function()
|
||||
this.Config.priorities.defenseBuilding = 60;
|
||||
}
|
||||
|
||||
if (this.Config.debug == 0)
|
||||
if (this.Config.debug < 2)
|
||||
return;
|
||||
API3.warn(" >>> Petra bot: personality = " + uneval(this.Config.personality));
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ m.AttackManager.prototype.init = function(gameState, queues, allowRush)
|
||||
// Others once in a while
|
||||
m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
{
|
||||
if (this.Config.debug == 2 && gameState.ai.elapsedTime > this.debugTime + 60)
|
||||
if (this.Config.debug > 2 && gameState.ai.elapsedTime > this.debugTime + 60)
|
||||
{
|
||||
this.debugTime = gameState.ai.elapsedTime;
|
||||
API3.warn(" upcoming attacks =================");
|
||||
@@ -93,7 +93,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
}
|
||||
else if (updateStep === 0 || updateStep === 3)
|
||||
{
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Manager: " + attack.getType() + " plan " + attack.getName() + " aborted.");
|
||||
attack.Abort(gameState, this);
|
||||
this.upcomingAttacks[attackType].splice(i--,1);
|
||||
@@ -114,7 +114,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
var chatText = "I'm starting an attack against " + targetName + ".";
|
||||
gameState.ai.chatTeam(chatText);
|
||||
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Manager: Starting " + attack.getType() + " plan " + attack.getName());
|
||||
this.startedAttacks[attackType].push(attack);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
var chatText = "I'm starting an attack against " + targetName + ".";
|
||||
gameState.ai.chatTeam(chatText);
|
||||
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Manager: Starting " + attack.getType() + " plan " + attack.getName());
|
||||
this.startedAttacks[attackType].push(attack);
|
||||
this.upcomingAttacks[attackType].splice(i--,1);
|
||||
@@ -157,7 +157,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
var remaining = attack.update(gameState, events);
|
||||
if (!remaining)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Military Manager: " + attack.getType() + " plan " + attack.getName() + " is finished with remaining " + remaining);
|
||||
attack.Abort(gameState);
|
||||
this.startedAttacks[attackType].splice(i--,1);
|
||||
@@ -176,7 +176,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
var attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Rush", data);
|
||||
if (!attackPlan.failed)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Headquarters: Rushing plan " + this.totalNumber + " with maxRushes " + this.maxRushes);
|
||||
this.totalNumber++;
|
||||
this.upcomingAttacks["Rush"].push(attackPlan);
|
||||
@@ -201,7 +201,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
this.attackPlansEncounteredWater = true; // hack
|
||||
else
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Military Manager: Creating the plan " + type + " " + this.totalNumber);
|
||||
this.totalNumber++;
|
||||
this.upcomingAttacks[type].push(attackPlan);
|
||||
@@ -226,7 +226,7 @@ m.AttackManager.prototype.update = function(gameState, queues, events)
|
||||
var attackPlan = new m.AttackPlan(gameState, this.Config, this.totalNumber, "Raid", data);
|
||||
if (!attackPlan.failed)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Headquarters: Raiding plan " + this.totalNumber);
|
||||
this.totalNumber++;
|
||||
this.upcomingAttacks["Raid"].push(attackPlan);
|
||||
|
||||
@@ -376,7 +376,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState, events)
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (this.Config.debug > 2 && gameState.ai.playedTurn % 50 === 0)
|
||||
if (this.Config.debug > 3 && gameState.ai.playedTurn % 50 === 0)
|
||||
this.debugAttack();
|
||||
|
||||
// find our target
|
||||
@@ -388,7 +388,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState, events)
|
||||
var oldTargetPlayer = this.targetPlayer;
|
||||
// may-be all our previous enemey targets have been destroyed ?
|
||||
this.targetPlayer = this.getEnemyPlayer(gameState);
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(" === no more target for enemy player " + oldTargetPlayer + " let us switch against player " + this.targetPlayer);
|
||||
this.target = this.getNearestTarget(gameState, this.rallyPoint);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState, events)
|
||||
}
|
||||
else // Abort the plan so that its units will be reassigned to other plans.
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
{
|
||||
var am = gameState.ai.HQ.attackManager;
|
||||
API3.warn(" attacks upcoming: raid " + am.upcomingAttacks["Raid"].length
|
||||
@@ -531,7 +531,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState, events)
|
||||
}
|
||||
var index = gameState.ai.accessibility.getAccessValue(entity.position());
|
||||
if (index === rallyIndex)
|
||||
entity.moveToRange(rallyPoint[0], rallyPoint[1], 0, 25, queued);
|
||||
entity.moveToRange(rallyPoint[0], rallyPoint[1], 0, 15, queued);
|
||||
else
|
||||
gameState.ai.HQ.navalManager.requireTransport(gameState, entity, index, rallyIndex, rallyPoint);
|
||||
});
|
||||
@@ -569,7 +569,7 @@ m.AttackPlan.prototype.trainMoreUnits = function(gameState)
|
||||
return va - vb;
|
||||
});
|
||||
|
||||
if (this.Config.debug > 0 && gameState.ai.playedTurn%50 === 0)
|
||||
if (this.Config.debug > 1 && gameState.ai.playedTurn%50 === 0)
|
||||
{
|
||||
API3.warn("====================================");
|
||||
API3.warn("======== build order for plan " + this.name);
|
||||
@@ -605,14 +605,14 @@ m.AttackPlan.prototype.trainMoreUnits = function(gameState)
|
||||
// effectively removing the unit from the plan.
|
||||
if (template === undefined)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("attack no template found " + this.buildOrder[0][1]);
|
||||
delete this.unitStat[this.buildOrder[0][4]]; // deleting the associated unitstat.
|
||||
this.buildOrder.splice(0,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("attack template " + template + " added for plan " + this.name);
|
||||
var max = this.buildOrder[0][3]["batchSize"];
|
||||
var specialData = "Plan_" + this.name + "_" + this.buildOrder[0][4];
|
||||
@@ -622,7 +622,7 @@ m.AttackPlan.prototype.trainMoreUnits = function(gameState)
|
||||
var trainingPlan = new m.TrainingPlan(gameState, template, { "role": "attack", "plan": this.name, "special": specialData, "base": 0 }, max, max);
|
||||
if (trainingPlan.template)
|
||||
queue.addItem(trainingPlan);
|
||||
else if (this.Config.debug > 0)
|
||||
else if (this.Config.debug > 1)
|
||||
API3.warn("training plan canceled because no template for " + template + " build1 " + uneval(this.buildOrder[0][1])
|
||||
+ " build3 " + uneval(this.buildOrder[0][3]["interests"]));
|
||||
}
|
||||
@@ -930,7 +930,7 @@ m.AttackPlan.prototype.setRallyPoint = function(gameState)
|
||||
// If we're here, it's because we have enough units.
|
||||
m.AttackPlan.prototype.StartAttack = function(gameState)
|
||||
{
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("start attack " + this.name + " with type " + this.type);
|
||||
|
||||
if (!this.target || !gameState.getEntityById(this.target.id())) // our target was destroyed during our preparation
|
||||
@@ -985,7 +985,7 @@ m.AttackPlan.prototype.StartAttack = function(gameState)
|
||||
{
|
||||
if (!this.path[0][0][0] || !this.path[0][0][1])
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("StartAttack: Problem with path " + uneval(this.path));
|
||||
return false;
|
||||
}
|
||||
@@ -1034,9 +1034,9 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
{
|
||||
var done = true;
|
||||
this.unitCollection.forEach(function (entity) {
|
||||
if (self.Config.debug > 0 && entity.getMetadata(PlayerID, "transport") !== undefined)
|
||||
if (self.Config.debug > 1 && entity.getMetadata(PlayerID, "transport") !== undefined)
|
||||
Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [entity.id()], "rgb": [2,2,0]});
|
||||
else if (self.Config.debug > 0)
|
||||
else if (self.Config.debug > 1)
|
||||
Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [entity.id()], "rgb": [1,1,1]});
|
||||
if (!done)
|
||||
return;
|
||||
@@ -1078,6 +1078,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
// In case yes, we'll determine if we're simply off against an enemy army, a lone unit/building
|
||||
// or if we reached the enemy base. Different plans may react differently.
|
||||
var attackedNB = 0;
|
||||
var attackedUnitNB = 0;
|
||||
var attackedEvents = events["Attacked"];
|
||||
for (var evt of attackedEvents)
|
||||
{
|
||||
@@ -1086,14 +1087,26 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
var attacker = gameState.getEntityById(evt.attacker);
|
||||
var ourUnit = gameState.getEntityById(evt.target);
|
||||
|
||||
if (attacker && attacker.position() && attacker.hasClass("Unit") && attacker.owner() != 0)
|
||||
if (attacker && (attacker.owner() != 0 || this.targetPlayer === 0))
|
||||
{
|
||||
attackedNB++;
|
||||
// if we're being attacked by a building, flee.
|
||||
if (attacker && ourUnit && attacker.hasClass("Structure"))
|
||||
ourUnit.flee(attacker);
|
||||
if (attacker.hasClass("Unit"))
|
||||
attackedUnitNB++;
|
||||
}
|
||||
}
|
||||
// Are we arrived at destination ?
|
||||
if ((gameState.ai.HQ.territoryMap.getOwner(this.position) === this.targetPlayer && attackedNB > 1) || attackedNB > 3)
|
||||
var maybe = true;
|
||||
if (attackedUnitNB == 0)
|
||||
{
|
||||
var siegeNB = 0;
|
||||
this.unitCollection.forEach( function (ent) {
|
||||
if (self.isSiegeUnit(gameState, ent))
|
||||
siegeNB++;
|
||||
});
|
||||
if (siegeNB == 0)
|
||||
maybe = false;
|
||||
}
|
||||
if (maybe && ((gameState.ai.HQ.territoryMap.getOwner(this.position) === this.targetPlayer && attackedNB > 1) || attackedNB > 3))
|
||||
this.state = "arrived";
|
||||
}
|
||||
|
||||
@@ -1131,13 +1144,13 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
// there are walls but we can attack
|
||||
if (nexttoWalls && this.unitCollection.filter(API3.Filters.byCanAttack("StoneWall")).length !== 0)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Plan " + this.type + " " + this.name + " has met walls and is not happy.");
|
||||
this.state = "arrived";
|
||||
}
|
||||
else if (nexttoWalls) // abort plan
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Plan " + this.type + " " + this.name + " has met walls and gives up.");
|
||||
Engine.ProfileStop();
|
||||
return 0;
|
||||
@@ -1153,7 +1166,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
{
|
||||
if (API3.SquareVectorDistance(this.position, this.targetPos) < 10000)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Plan " + this.type + " " + this.name + " has arrived to destination.");
|
||||
this.state = "arrived";
|
||||
}
|
||||
@@ -1164,7 +1177,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
this.unitCollection.move(this.path[0][0][0], this.path[0][0][1]);
|
||||
else
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Attack Plan " + this.type + " " + this.name + " has arrived to destination.");
|
||||
this.state = "arrived";
|
||||
}
|
||||
@@ -1237,6 +1250,24 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
var enemyUnits = gameState.getEnemyUnits(this.targetPlayer);
|
||||
var enemyStructures = gameState.getEnemyStructures(this.targetPlayer);
|
||||
|
||||
var targetClassesUnit;
|
||||
var targetClassesSiege;
|
||||
if (this.type === "Rush")
|
||||
targetClassesUnit = {"attack": ["Unit", "Structure"], "avoid": ["StoneWall", "Tower", "Fortress"]};
|
||||
else
|
||||
{
|
||||
if (this.target.hasClass("Fortress"))
|
||||
targetClassesUnit = {"attack": ["Unit", "Structure"], "avoid": ["StoneWall"]};
|
||||
else if (this.target.hasClass("StoneWall"))
|
||||
targetClassesUnit = {"attack": ["Unit", "Structure"], "avoid": ["Fortress"]};
|
||||
else
|
||||
targetClassesUnit = {"attack": ["Unit", "Structure"], "avoid": ["Fortress", "StoneWall"]};
|
||||
}
|
||||
if (this.target.hasClass("Structure"))
|
||||
targetClassesSiege = {"attack": ["Structure"]};
|
||||
else
|
||||
targetClassesSiege = {"attack": ["Unit", "Structure"]};
|
||||
|
||||
if (this.unitCollUpdateArray === undefined || this.unitCollUpdateArray.length === 0)
|
||||
this.unitCollUpdateArray = this.unitCollection.toIdArray();
|
||||
|
||||
@@ -1300,40 +1331,21 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
else if (ent.hasClass("Cavalry"))
|
||||
range += 30;
|
||||
range = range * range;
|
||||
// let's filter targets further based on this unit.
|
||||
var entIndex = gameState.ai.accessibility.getAccessValue(ent.position());
|
||||
var mStruct = enemyStructures.filter(function (enemy) {
|
||||
if (!enemy.position() || (enemy.hasClass("StoneWall") && !ent.canAttackClass("StoneWall")))
|
||||
return false;
|
||||
if (API3.SquareVectorDistance(enemy.position(), ent.position()) > range)
|
||||
return false;
|
||||
if (siegeUnit && enemy.foundationProgress() === 0)
|
||||
return false;
|
||||
if (gameState.ai.accessibility.getAccessValue(enemy.position()) !== entIndex)
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
var nearby = (!ent.hasClass("Cavalry") && !ent.hasClass("Ranged"));
|
||||
var mUnit = enemyUnits.filter(function (enemy) {
|
||||
if (!enemy.position())
|
||||
return false;
|
||||
if (enemy.hasClass("Animal"))
|
||||
return false;
|
||||
if (nearby && enemy.hasClass("Female") && enemy.unitAIState().split(".")[1] == "FLEEING")
|
||||
return false;
|
||||
var dist = API3.SquareVectorDistance(enemy.position(), ent.position());
|
||||
if (dist > range)
|
||||
return false;
|
||||
if (gameState.ai.accessibility.getAccessValue(enemy.position()) !== entIndex)
|
||||
return false;
|
||||
enemy.setMetadata(PlayerID, "distance", Math.sqrt(dist));
|
||||
return true;
|
||||
});
|
||||
// Checking for gates if we're a siege unit.
|
||||
mUnit = mUnit.toEntityArray();
|
||||
mStruct = mStruct.toEntityArray();
|
||||
if (siegeUnit)
|
||||
{
|
||||
var mStruct = enemyStructures.filter(function (enemy) {
|
||||
if (!enemy.position() || (enemy.hasClass("StoneWall") && !ent.canAttackClass("StoneWall")))
|
||||
return false;
|
||||
if (API3.SquareVectorDistance(enemy.position(), ent.position()) > range)
|
||||
return false;
|
||||
if (enemy.foundationProgress() === 0)
|
||||
return false;
|
||||
if (gameState.ai.accessibility.getAccessValue(enemy.position()) !== entIndex)
|
||||
return false;
|
||||
return true;
|
||||
}).toEntityArray();
|
||||
if (mStruct.length !== 0)
|
||||
{
|
||||
mStruct.sort(function (structa,structb)
|
||||
@@ -1363,10 +1375,26 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
}
|
||||
}
|
||||
else
|
||||
ent.attackMove(self.targetPos[0], self.targetPos[1], {"attack": ["Unit", "Structure"]});
|
||||
ent.attackMove(self.targetPos[0], self.targetPos[1], targetClassesSiege);
|
||||
}
|
||||
else
|
||||
{
|
||||
var nearby = (!ent.hasClass("Cavalry") && !ent.hasClass("Ranged"));
|
||||
var mUnit = enemyUnits.filter(function (enemy) {
|
||||
if (!enemy.position())
|
||||
return false;
|
||||
if (enemy.hasClass("Animal"))
|
||||
return false;
|
||||
if (nearby && enemy.hasClass("Female") && enemy.unitAIState().split(".")[1] == "FLEEING")
|
||||
return false;
|
||||
var dist = API3.SquareVectorDistance(enemy.position(), ent.position());
|
||||
if (dist > range)
|
||||
return false;
|
||||
if (gameState.ai.accessibility.getAccessValue(enemy.position()) !== entIndex)
|
||||
return false;
|
||||
enemy.setMetadata(PlayerID, "distance", Math.sqrt(dist));
|
||||
return true;
|
||||
}).toEntityArray();
|
||||
if (mUnit.length !== 0)
|
||||
{
|
||||
mUnit.sort(function (unitA,unitB) {
|
||||
@@ -1389,28 +1417,63 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
ent.attack(mUnit[rand].id());
|
||||
}
|
||||
else if (API3.SquareVectorDistance(self.targetPos, ent.position()) > 2500 )
|
||||
ent.attackMove(self.targetPos[0], self.targetPos[1], {"attack": ["Unit", "Structure"]});
|
||||
else if (mStruct.length !== 0)
|
||||
{
|
||||
mStruct.sort(function (structa,structb) {
|
||||
var vala = structa.costSum();
|
||||
if (structa.hasClass("Gates") && ent.canAttackClass("StoneWall"))
|
||||
vala += 10000;
|
||||
else if (structa.hasClass("ConquestCritical"))
|
||||
vala += 100;
|
||||
var valb = structb.costSum();
|
||||
if (structb.hasClass("Gates") && ent.canAttackClass("StoneWall"))
|
||||
valb += 10000;
|
||||
else if (structb.hasClass("ConquestCritical"))
|
||||
valb += 100;
|
||||
return (valb - vala);
|
||||
});
|
||||
if (mStruct[0].hasClass("Gates"))
|
||||
ent.attack(mStruct[0].id());
|
||||
else
|
||||
ent.attackMove(self.targetPos[0], self.targetPos[1], targetClassesUnit);
|
||||
ent.attackMove(self.targetPos[0], self.targetPos[1], {"attack": ["Unit", "Structure"]}, true); // in case we are blocked by walls
|
||||
}
|
||||
else
|
||||
{
|
||||
var mStruct = enemyStructures.filter(function (enemy) {
|
||||
if (!enemy.position() || (enemy.hasClass("StoneWall") && !ent.canAttackClass("StoneWall")))
|
||||
return false;
|
||||
if (API3.SquareVectorDistance(enemy.position(), ent.position()) > range)
|
||||
return false;
|
||||
if (gameState.ai.accessibility.getAccessValue(enemy.position()) !== entIndex)
|
||||
return false;
|
||||
return true;
|
||||
}).toEntityArray();
|
||||
if (mStruct.length !== 0)
|
||||
{
|
||||
var rand = Math.floor(Math.random() * mStruct.length * 0.2);
|
||||
ent.attack(mStruct[rand].id());
|
||||
mStruct.sort(function (structa,structb) {
|
||||
var vala = structa.costSum();
|
||||
if (structa.hasClass("Gates") && ent.canAttackClass("StoneWall"))
|
||||
vala += 10000;
|
||||
else if (structa.hasClass("ConquestCritical"))
|
||||
vala += 100;
|
||||
var valb = structb.costSum();
|
||||
if (structb.hasClass("Gates") && ent.canAttackClass("StoneWall"))
|
||||
valb += 10000;
|
||||
else if (structb.hasClass("ConquestCritical"))
|
||||
valb += 100;
|
||||
return (valb - vala);
|
||||
});
|
||||
if (mStruct[0].hasClass("Gates"))
|
||||
ent.attack(mStruct[0].id());
|
||||
else
|
||||
{
|
||||
var rand = Math.floor(Math.random() * mStruct.length * 0.2);
|
||||
ent.attack(mStruct[rand].id());
|
||||
}
|
||||
}
|
||||
else if (needsUpdate) // really nothing let's try to help our nearest unit
|
||||
{
|
||||
var distmin = Math.min();
|
||||
var attackerId = undefined;
|
||||
this.unitCollection.forEach( function (unit) {
|
||||
if (!unit.position())
|
||||
return;
|
||||
if (unit.unitAIState().split(".")[1] !== "COMBAT" || unit.unitAIOrderData().length === 0
|
||||
|| !unit.unitAIOrderData()[0]["target"])
|
||||
return;
|
||||
var dist = API3.SquareVectorDistance(unit.position(), ent.position());
|
||||
if (dist > distmin)
|
||||
return;
|
||||
distmin = dist;
|
||||
attackerId = unit.unitAIOrderData()[0]["target"];
|
||||
|
||||
});
|
||||
if (attackerId)
|
||||
ent.attack(attackerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1421,7 +1484,7 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
// updating targets.
|
||||
if (!this.target || !gameState.getEntityById(this.target.id()))
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("Seems like our target has been destroyed. Switching.");
|
||||
this.target = this.getNearestTarget(gameState, this.position, true);
|
||||
if (!this.target)
|
||||
@@ -1447,12 +1510,12 @@ m.AttackPlan.prototype.update = function(gameState, events)
|
||||
|
||||
if (!this.target)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("No new target found. Remaining units " + this.unitCollection.length);
|
||||
Engine.ProfileStop();
|
||||
return false;
|
||||
}
|
||||
else if (this.Config.debug > 0)
|
||||
else if (this.Config.debug > 1)
|
||||
API3.warn("We will help one of our other attacks");
|
||||
}
|
||||
this.targetPos = this.target.position();
|
||||
|
||||
@@ -134,7 +134,7 @@ m.BaseManager.prototype.checkEvents = function (gameState, events, queues)
|
||||
}
|
||||
if (!basemin)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(" base " + this.ID + " destroyed and no other bases found");
|
||||
continue;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ m.BaseManager.prototype.assignResourceToDropsite = function (gameState, dropsite
|
||||
{
|
||||
if (this.dropsites[dropsite.id()])
|
||||
{
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
warn("assignResourceToDropsite: dropsite already in the list. Should never happen");
|
||||
return;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource)
|
||||
bestIdx = j;
|
||||
}
|
||||
|
||||
if (this.Config.debug == 2)
|
||||
if (this.Config.debug > 2)
|
||||
warn(" for dropsite best is " + bestVal);
|
||||
|
||||
if (bestVal <= 0)
|
||||
@@ -670,11 +670,13 @@ m.BaseManager.prototype.gatherersByType = function(gameState, type)
|
||||
m.BaseManager.prototype.pickBuilders = function(gameState, workers, number)
|
||||
{
|
||||
var availableWorkers = this.workers.filter(function (ent) {
|
||||
if (!ent.position())
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "plan") === -2 || ent.getMetadata(PlayerID, "plan") === -3)
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "transport") !== undefined)
|
||||
if (ent.getMetadata(PlayerID, "transport"))
|
||||
return false;
|
||||
if (ent.hasClass("Cavalry") || ent.hasClass("Ship") || ent.position() === undefined)
|
||||
if (ent.hasClass("Cavalry") || ent.hasClass("Ship"))
|
||||
return false;
|
||||
return true;
|
||||
}).toEntityArray();
|
||||
@@ -800,7 +802,17 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
|
||||
});
|
||||
if (assigned + addedToThis < targetNB)
|
||||
{
|
||||
var nonBuilderWorkers = workers.filter(function(ent) { return (ent.getMetadata(PlayerID, "subrole") !== "builder" && ent.position() !== undefined); }).toEntityArray();
|
||||
var nonBuilderWorkers = workers.filter(function(ent) {
|
||||
if (ent.getMetadata(PlayerID, "subrole") === "builder")
|
||||
return false;
|
||||
if (!ent.position())
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "plan") === -2 || ent.getMetadata(PlayerID, "plan") === -3)
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "transport"))
|
||||
return false;
|
||||
return true;
|
||||
}).toEntityArray();
|
||||
var time = target.buildTime();
|
||||
nonBuilderWorkers.sort(function (workerA,workerB)
|
||||
{
|
||||
@@ -848,8 +860,18 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
|
||||
if (assigned < targetNB/3)
|
||||
{
|
||||
if (builderWorkers.length + addedWorkers < targetNB*2)
|
||||
{
|
||||
var nonBuilderWorkers = workers.filter(function(ent) { return (ent.getMetadata(PlayerID, "subrole") !== "builder" && ent.position() !== undefined && ent.getMetadata(PlayerID, "transport") === undefined); });
|
||||
{
|
||||
var nonBuilderWorkers = workers.filter(function(ent) {
|
||||
if (ent.getMetadata(PlayerID, "subrole") === "builder")
|
||||
return false;
|
||||
if (!ent.position())
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "plan") === -2 || ent.getMetadata(PlayerID, "plan") === -3)
|
||||
return false;
|
||||
if (ent.getMetadata(PlayerID, "transport"))
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
var nearestNonBuilders = nonBuilderWorkers.filterNearest(target.position(), targetNB/3 - assigned);
|
||||
|
||||
nearestNonBuilders.forEach(function(ent) {
|
||||
|
||||
@@ -4,6 +4,7 @@ var PETRA = function(m)
|
||||
// this defines the medium difficulty
|
||||
m.Config = function() {
|
||||
this.difficulty = 2; // 0 is sandbox, 1 is easy, 2 is medium, 3 is hard, 4 is very hard.
|
||||
// debug level: 0=none, 1=sanity checks, 2=debug; 3=detailed debug
|
||||
this.debug = 0;
|
||||
|
||||
this.Military = {
|
||||
|
||||
@@ -96,15 +96,6 @@ m.DefenseManager.prototype.isDangerous = function(gameState, entity)
|
||||
return true;
|
||||
}
|
||||
|
||||
var myCCFoundations = gameState.getOwnFoundations().filter(API3.Filters.byClass("CivCentre"));
|
||||
for (var i in myCCFoundations._entities)
|
||||
{
|
||||
if (!myCCFoundations._entities[i].getBuildersNb())
|
||||
continue;
|
||||
if (API3.SquareVectorDistance(myCCFoundations._entities[i].position(), entity.position()) < 6000)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.Config.personality.cooperative > 0.3)
|
||||
{
|
||||
var allyCC = gameState.getExclusiveAllyEntities().filter(API3.Filters.byClass("CivCentre"));
|
||||
@@ -119,8 +110,12 @@ m.DefenseManager.prototype.isDangerous = function(gameState, entity)
|
||||
|
||||
var myBuildings = gameState.getOwnStructures();
|
||||
for (var i in myBuildings._entities)
|
||||
{
|
||||
if (myBuildings._entities[i].foundationProgress() === 0)
|
||||
continue;
|
||||
if (API3.SquareVectorDistance(myBuildings._entities[i].position(), entity.position()) < 6000)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -134,11 +129,9 @@ m.DefenseManager.prototype.checkEnemyUnits = function(gameState)
|
||||
return;
|
||||
|
||||
var self = this;
|
||||
var filter = API3.Filters.and(API3.Filters.byClass("Unit"), API3.Filters.byOwner(i));
|
||||
var enemyUnits = gameState.updatingGlobalCollection("player-" +i + "-units", filter);
|
||||
|
||||
// loop through enemy units
|
||||
enemyUnits.forEach( function (ent) {
|
||||
gameState.getEnemyUnits(i).forEach( function (ent) {
|
||||
// first check: is this unit already part of an army.
|
||||
if (ent.getMetadata(PlayerID, "PartOfArmy") !== undefined)
|
||||
return;
|
||||
@@ -225,7 +218,7 @@ m.DefenseManager.prototype.checkEnemyArmies = function(gameState, events)
|
||||
{
|
||||
if (API3.SquareVectorDistance(bases[i].position(), army.foePosition) < 40000)
|
||||
{
|
||||
if(this.Config.debug > 0)
|
||||
if(this.Config.debug > 1)
|
||||
API3.warn("army in neutral territory, but still near one of our CC");
|
||||
stillDangerous = true;
|
||||
break;
|
||||
@@ -329,7 +322,7 @@ m.DefenseManager.prototype.assignDefenders = function(gameState)
|
||||
};
|
||||
|
||||
// If our defense structures are attacked, garrison soldiers inside when possible
|
||||
// and if a support unit is attacked and has less than 30% health, garrison it inside the nearest cc
|
||||
// and if a support unit is attacked and has less than 45% health, garrison it inside the nearest cc
|
||||
m.DefenseManager.prototype.checkEvents = function(gameState, events)
|
||||
{
|
||||
var self = this;
|
||||
@@ -342,7 +335,8 @@ m.DefenseManager.prototype.checkEvents = function(gameState, events)
|
||||
if (target.hasClass("Ship")) // TODO integrate ships later need to be sure it is accessible
|
||||
continue;
|
||||
|
||||
if (target.hasClass("Support") && target.healthLevel() < 0.4 && !target.getMetadata(PlayerID, "transport"))
|
||||
if (target.hasClass("Support") && target.healthLevel() < 0.45 && !target.getMetadata(PlayerID, "transport")
|
||||
&& target.getMetadata(PlayerID, "plan") !== -2 && target.getMetadata(PlayerID, "plan") !== -3)
|
||||
{
|
||||
this.garrisonUnitForHealing(gameState, target);
|
||||
continue;
|
||||
|
||||
@@ -65,5 +65,29 @@ m.getMaxStrength = function(ent, againstClass)
|
||||
return strength * hp;
|
||||
};
|
||||
|
||||
m.getHolder = function(ent, gameState)
|
||||
{
|
||||
var found = undefined;
|
||||
gameState.getEntities().forEach(function (holder) {
|
||||
if (found || !holder.isGarrisonHolder())
|
||||
return;
|
||||
if (holder._entity.garrisoned.indexOf(ent.id()) !== -1)
|
||||
found = holder;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
m.dumpEntity = function(ent)
|
||||
{
|
||||
if (!ent)
|
||||
return;
|
||||
API3.warn(" >>> pos " + ent.position() + " state " + ent.unitAIState());
|
||||
API3.warn(" >>> role " + ent.getMetadata(PlayerID, "role") + " subrole " + ent.getMetadata(PlayerID, "subrole")
|
||||
+ " garrisoning " + ent.getMetadata(PlayerID, "garrisoning") + " garrisonHolder " + ent.getMetadata(PlayerID, "garrisonHolder")
|
||||
+ " plan " + ent.getMetadata(PlayerID, "plan") + " transport " + ent.getMetadata(PlayerID, "transport")
|
||||
+ " gather-type " + ent.getMetadata(PlayerID, "gather-type") + " target-foundation " + ent.getMetadata(PlayerID, "target-foundation")
|
||||
+ " PartOfArmy " + ent.getMetadata(PlayerID, "PartOfArmy"));
|
||||
};
|
||||
|
||||
return m;
|
||||
}(PETRA);
|
||||
|
||||
@@ -49,6 +49,38 @@ m.GarrisonManager.prototype.update = function(gameState, queues)
|
||||
this.leaveGarrison(ent);
|
||||
list.splice(j--, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ok = false;
|
||||
var orders = ent.unitAIOrderData();
|
||||
for (var order of orders)
|
||||
{
|
||||
if (!order.target || order.target != id)
|
||||
continue;
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
if (ok)
|
||||
continue;
|
||||
if (ent.getMetadata(PlayerID, "garrisonHolder") == +id)
|
||||
{
|
||||
// The garrison order must have failed
|
||||
this.leaveGarrison(ent);
|
||||
list.splice(j--, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
{
|
||||
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(orders));
|
||||
m.dumpEntity(ent);
|
||||
}
|
||||
list.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!holder.position()) // could happen with siege unit inside a ship
|
||||
@@ -113,7 +145,7 @@ m.GarrisonManager.prototype.garrison = function(gameState, ent, holder, type)
|
||||
this.registerHolder(gameState, holder);
|
||||
this.holders[holder.id()].push(ent.id());
|
||||
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
if (gameState.ai.HQ.Config.debug > 2)
|
||||
{
|
||||
warn("garrison unit " + ent.genericName() + " in " + holder.genericName() + " with type " + type);
|
||||
warn(" we try to garrison a unit with plan " + ent.getMetadata(PlayerID, "plan") + " and role " + ent.getMetadata(PlayerID, "role")
|
||||
|
||||
@@ -93,7 +93,7 @@ m.HQ.prototype.init = function(gameState, queues)
|
||||
this.navalRegions.push(i);
|
||||
}
|
||||
}
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
{
|
||||
for (var region in this.allowedRegions)
|
||||
API3.warn(" >>> zone " + region + " taille " + gameState.ai.accessibility.regionSize[region]);
|
||||
@@ -203,7 +203,7 @@ m.HQ.prototype.init = function(gameState, queues)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("starting size " + startingSize + "(cut at 1500 for fish pushing)");
|
||||
if (startingSize < 1500)
|
||||
{
|
||||
@@ -227,7 +227,7 @@ m.HQ.prototype.init = function(gameState, queues)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("startingWood: " + startingWood + "(cut at 8500 for no rush and 6000 for saveResources)");
|
||||
if (startingWood < 6000)
|
||||
{
|
||||
@@ -242,7 +242,7 @@ m.HQ.prototype.init = function(gameState, queues)
|
||||
var template = gameState.getTemplate(this.bBase[0]);
|
||||
if (!template.available(gameState))
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(" this AI is unable to produce any units");
|
||||
this.canBuildUnits = false;
|
||||
var allycc = gameState.getExclusiveAllyEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
||||
@@ -250,7 +250,7 @@ m.HQ.prototype.init = function(gameState, queues)
|
||||
{
|
||||
// if we have some allies, keep a fraction of our units to defend them
|
||||
// and devote the rest to atacks
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(" We have allied cc " + allycc.length + " and " + gameState.getOwnUnits().length + " units ");
|
||||
var units = gameState.getOwnUnits();
|
||||
var num = Math.max(Math.min(Math.round(0.08*(1+this.Config.personality.cooperative)*units.length), 20), 5);
|
||||
@@ -340,7 +340,7 @@ m.HQ.prototype.getSeaIndex = function (gameState, index1, index2)
|
||||
return path[1];
|
||||
else
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
{
|
||||
API3.warn("bad path from " + index1 + " to " + index2 + " ??? " + uneval(path));
|
||||
API3.warn(" regionLinks start " + uneval(gameState.ai.accessibility.regionLinks[index1]));
|
||||
@@ -855,7 +855,7 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, template, resource,
|
||||
var cut = 60;
|
||||
if (fromStrategic) // be less restrictive
|
||||
cut = 30;
|
||||
if (this.Config.debug)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("we have found a base for " + resource + " with best (cut=" + cut + ") = " + bestVal);
|
||||
// not good enough.
|
||||
if (bestVal < cut)
|
||||
@@ -987,7 +987,7 @@ m.HQ.prototype.findStrategicCCLocation = function(gameState, template)
|
||||
bestIdx = j;
|
||||
}
|
||||
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("We've found a strategic base with bestVal = " + bestVal);
|
||||
|
||||
Engine.ProfileStop();
|
||||
@@ -1072,14 +1072,14 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
||||
bestIdx = j;
|
||||
}
|
||||
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("We found a market position with bestVal = " + bestVal);
|
||||
|
||||
if (bestVal === undefined) // no constraints. For the time being, place it arbitrarily by the ConstructionPlan
|
||||
return [-1, -1, -1];
|
||||
|
||||
var expectedGain = Math.round(bestVal / this.Config.distUnitGain);
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("this would give a trading gain of " + expectedGain);
|
||||
// do not keep it if gain is too small, except if this is our first BarterMarket
|
||||
if (expectedGain < 6 && (!template.hasClass("BarterMarket") || gameState.getOwnStructures().filter(API3.Filters.byClass("BarterMarket")).length > 0))
|
||||
@@ -1287,7 +1287,7 @@ m.HQ.prototype.buildMoreHouses = function(gameState,queues)
|
||||
var index = this.stopBuilding.indexOf(gameState.applyCiv("structures/{civ}_house"));
|
||||
if (count < 5 && index !== -1)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no room to place a house ... try to be less restrictive");
|
||||
this.stopBuilding.splice(index, 1);
|
||||
this.requireHouses = true;
|
||||
@@ -1320,7 +1320,7 @@ m.HQ.prototype.buildMoreHouses = function(gameState,queues)
|
||||
var index = this.stopBuilding.indexOf(gameState.applyCiv("structures/{civ}_house"));
|
||||
if (index !== -1)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no room to place a house ... try to improve with technology");
|
||||
this.researchManager.researchPopulationBonus(gameState, queues);
|
||||
}
|
||||
@@ -1341,7 +1341,7 @@ m.HQ.prototype.checkBaseExpansion = function(gameState, queues)
|
||||
// first expand if we have not enough room available for buildings
|
||||
if (this.stopBuilding.length > 1)
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("try to build a new base because not enough room to build " + uneval(this.stopBuilding));
|
||||
this.buildNewBase(gameState, queues);
|
||||
return;
|
||||
@@ -1353,7 +1353,7 @@ m.HQ.prototype.checkBaseExpansion = function(gameState, queues)
|
||||
popForBase = this.Config.Economy.popForTown + 5;
|
||||
if (Math.floor(numUnits/popForBase) >= gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).length)
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("try to build a new base because of population " + numUnits + " for " + numCCs + " CCs");
|
||||
this.buildNewBase(gameState, queues);
|
||||
}
|
||||
@@ -1369,7 +1369,7 @@ m.HQ.prototype.buildNewBase = function(gameState, queues, type)
|
||||
return false;
|
||||
|
||||
// base "-1" means new base.
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("new base planned with type " + type);
|
||||
queues.civilCentre.addItem(new m.ConstructionPlan(gameState, this.bBase[0], { "base": -1, "type": type }));
|
||||
return true;
|
||||
@@ -1842,7 +1842,7 @@ m.HQ.prototype.update = function(gameState, queues, events)
|
||||
|
||||
this.territoryMap = m.createTerritoryMap(gameState);
|
||||
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
{
|
||||
gameState.getOwnUnits().forEach (function (ent) {
|
||||
if (!ent.hasClass("CitizenSoldier") || ent.hasClass("Cavalry"))
|
||||
@@ -1859,15 +1859,7 @@ m.HQ.prototype.update = function(gameState, queues, events)
|
||||
if (gameState.ai.playedTurn - ent.getMetadata(PlayerID, "idleTim") < 50)
|
||||
return;
|
||||
API3.warn(" unit idle since " + (gameState.ai.playedTurn-ent.getMetadata(PlayerID, "idleTim")) + " turns");
|
||||
API3.warn(" unitai state " + ent.unitAIState());
|
||||
API3.warn(" >>> base " + ent.getMetadata(PlayerID, "base"));
|
||||
API3.warn(" >>> role " + ent.getMetadata(PlayerID, "role"));
|
||||
API3.warn(" >>> subrole " + ent.getMetadata(PlayerID, "subrole"));
|
||||
API3.warn(" >>> gather-type " + ent.getMetadata(PlayerID, "gather-type"));
|
||||
API3.warn(" >>> target-foundation " + ent.getMetadata(PlayerID, "target-foundation"));
|
||||
API3.warn(" >>> PartOfArmy " + ent.getMetadata(PlayerID, "PartOfArmy"));
|
||||
API3.warn(" >>> plan " + ent.getMetadata(PlayerID, "plan"));
|
||||
API3.warn(" >>> transport " + ent.getMetadata(PlayerID, "transport"));
|
||||
m.dumpEntity(ent);
|
||||
ent.setMetadata(PlayerID, "idleTim", gameState.ai.playedTurn);
|
||||
});
|
||||
}
|
||||
@@ -1944,18 +1936,6 @@ m.HQ.prototype.update = function(gameState, queues, events)
|
||||
Engine.ProfileStop();
|
||||
};
|
||||
|
||||
m.HQ.prototype.getHolder = function(gameState, ent)
|
||||
{
|
||||
var found = undefined;
|
||||
gameState.getEntities().forEach(function (holder) {
|
||||
if (found || !holder.isGarrisonHolder())
|
||||
return;
|
||||
if (holder._entity.garrisoned.indexOf(ent.id()) !== -1)
|
||||
found = holder;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
return m;
|
||||
|
||||
}(PETRA);
|
||||
|
||||
@@ -280,7 +280,7 @@ m.NavalManager.prototype.checkEvents = function(gameState, queues, events)
|
||||
continue;
|
||||
|
||||
var shipId = evt.entityObj.id();
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("one ship " + shipId + " from plan " + plan.ID + " destroyed during " + plan.state);
|
||||
if (plan.state === "boarding")
|
||||
{
|
||||
@@ -356,7 +356,7 @@ m.NavalManager.prototype.requireTransport = function(gameState, entity, startInd
|
||||
var plan = new m.TransportPlan(gameState, [entity], startIndex, endIndex, endPos);
|
||||
if (plan.failed)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(">>>> transport plan aborted <<<<");
|
||||
return false;
|
||||
}
|
||||
@@ -367,12 +367,12 @@ m.NavalManager.prototype.requireTransport = function(gameState, entity, startInd
|
||||
// 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)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(">>>> split of transport plan started <<<<");
|
||||
var newplan = new m.TransportPlan(gameState, [], plan.startIndex, plan.endIndex, plan.endPos);
|
||||
if (newplan.failed)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(">>>> split of transport plan aborted <<<<");
|
||||
return false;
|
||||
}
|
||||
@@ -384,7 +384,7 @@ m.NavalManager.prototype.splitTransport = function(gameState, plan)
|
||||
++nbUnits;
|
||||
newplan.addUnit(ent, ent.getMetadata(PlayerID, "endPos"));
|
||||
});
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(">>>> previous plan left with units " + plan.units.length);
|
||||
if (nbUnits)
|
||||
this.transportPlans.push(newplan);
|
||||
@@ -625,7 +625,7 @@ m.NavalManager.prototype.update = function(gameState, queues, events)
|
||||
var remaining = this.transportPlans[i].update(gameState);
|
||||
if (remaining === 0)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("no more units on transport plan " + this.transportPlans[i].ID);
|
||||
this.transportPlans[i].releaseAll();
|
||||
this.transportPlans.splice(i--, 1);
|
||||
|
||||
@@ -377,7 +377,7 @@ m.QueueManager.prototype.switchResource = function(gameState, res)
|
||||
this.accounts[j][res] += diff;
|
||||
this.accounts[i][res] -= diff;
|
||||
++otherQueue.switched;
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn ("switching queue " + res + " from " + i + " to " + j + " in amount " + diff);
|
||||
break;
|
||||
}
|
||||
@@ -429,7 +429,7 @@ m.QueueManager.prototype.update = function(gameState)
|
||||
// Start the next item in the queue if we can afford it.
|
||||
this.startNextItems(gameState);
|
||||
|
||||
if (this.Config.debug > 0 && gameState.ai.playedTurn%50 === 0)
|
||||
if (this.Config.debug > 1 && gameState.ai.playedTurn%50 === 0)
|
||||
this.printQueues(gameState);
|
||||
|
||||
Engine.ProfileStop();
|
||||
@@ -511,7 +511,7 @@ m.QueueManager.prototype.getPriority = function(queueName)
|
||||
|
||||
m.QueueManager.prototype.changePriority = function(queueName, newPriority)
|
||||
{
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn(">>> Priority of queue " + queueName + " changed from " + this.priorities[queueName] + " to " + newPriority);
|
||||
var self = this;
|
||||
if (this.queues[queueName] !== undefined)
|
||||
|
||||
@@ -95,7 +95,7 @@ m.TrainingPlan.prototype.start = function(gameState)
|
||||
this.metadata.base = trainers[0].getMetadata(PlayerID, "base");
|
||||
trainers[0].train(this.type, this.number, this.metadata, this.promotedTypes(gameState));
|
||||
}
|
||||
else if (gameState.ai.Config.debug > 0)
|
||||
else if (gameState.ai.Config.debug > 1)
|
||||
warn(" no trainers for this queue " + this.type);
|
||||
this.onStart(gameState);
|
||||
};
|
||||
|
||||
@@ -109,7 +109,7 @@ m.TradeManager.prototype.buildTradeRoute = function(gameState, queues)
|
||||
}
|
||||
if (distmax > 0)
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn(" a second market will be built in base " + base);
|
||||
// TODO build also docks when better
|
||||
queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_market", { "base": base }));
|
||||
@@ -152,11 +152,11 @@ m.TradeManager.prototype.buildTradeRoute = function(gameState, queues)
|
||||
}
|
||||
if (distmax < 0)
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("no trade route possible");
|
||||
return false;
|
||||
}
|
||||
if (this.Config.debug > 0)
|
||||
if (this.Config.debug > 1)
|
||||
API3.warn("one trade route set with gain " + Math.round(distmax / this.Config.distUnitGain));
|
||||
return true;
|
||||
};
|
||||
@@ -201,7 +201,7 @@ m.TradeManager.prototype.setTradingGoods = function(gameState)
|
||||
else
|
||||
tradingGoods[mostNeeded[0].type] += nextNeed;
|
||||
Engine.PostCommand(PlayerID, {"type": "set-trading-goods", "tradingGoods": tradingGoods});
|
||||
if (this.Config.debug == 2)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn(" trading goods set to " + uneval(tradingGoods));
|
||||
};
|
||||
|
||||
@@ -268,7 +268,7 @@ m.TradeManager.prototype.performBarter = function(gameState)
|
||||
if (bestToSell !== undefined)
|
||||
{
|
||||
barterers[0].barter(buy, bestToSell, 100);
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("Necessity bartering: sold " + bestToSell +" for " + buy + " >> need sell " + needs[bestToSell]
|
||||
+ " need buy " + needs[buy] + " rate buy " + rates[buy] + " available sell " + available[bestToSell]
|
||||
+ " available buy " + available[buy] + " barterRate " + bestRate);
|
||||
@@ -301,7 +301,7 @@ m.TradeManager.prototype.performBarter = function(gameState)
|
||||
if (bestToBuy !== undefined)
|
||||
{
|
||||
barterers[0].barter(bestToBuy, "food", 100);
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("Contingency bartering: sold food for " + bestToBuy + " available sell " + available["food"]
|
||||
+ " available buy " + available[bestToBuy] + " barterRate " + getBarterRate(prices, bestToBuy, "food"));
|
||||
return true;
|
||||
@@ -321,7 +321,7 @@ m.TradeManager.prototype.update = function(gameState, queues)
|
||||
var target = this.tradeRoute.target;
|
||||
if (!source || !target || !gameState.getEntityById(source.id()) || !gameState.getEntityById(target.id()))
|
||||
{
|
||||
if (this.Config.debug > 1)
|
||||
if (this.Config.debug > 2)
|
||||
API3.warn("We have lost our trade route");
|
||||
this.tradeRoute = undefined;
|
||||
return;
|
||||
|
||||
@@ -38,7 +38,7 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
|
||||
if (!this.sea)
|
||||
{
|
||||
this.failed = true;
|
||||
if (this.debug > 0)
|
||||
if (this.debug > 1)
|
||||
API3.warn("transport plan with bad path: startIndex " + startIndex + " endIndex " + endIndex);
|
||||
return false;
|
||||
}
|
||||
@@ -53,7 +53,7 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
|
||||
this.units.updateEnt(ent);
|
||||
}
|
||||
|
||||
if (this.debug > 0)
|
||||
if (this.debug > 1)
|
||||
API3.warn("Starting a new transport plan with ID " + this.ID + " to index " + endIndex
|
||||
+ " with units length " + units.length);
|
||||
|
||||
@@ -101,7 +101,7 @@ m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent)
|
||||
{
|
||||
ent.setMetadata(PlayerID, "onBoard", ship.id());
|
||||
done = true;
|
||||
if (self.debug > 0)
|
||||
if (self.debug > 1)
|
||||
{
|
||||
if (ent.getMetadata(PlayerID, "role") === "attack")
|
||||
Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [2,0,0]});
|
||||
@@ -272,7 +272,7 @@ m.TransportPlan.prototype.onBoarding = function(gameState)
|
||||
if (self.nTry[shipId] > 1) // we must have been blocked by something ... try with another boarding point
|
||||
{
|
||||
self.nTry[shipId] = 0;
|
||||
if (self.debug > 0)
|
||||
if (self.debug > 1)
|
||||
API3.warn("ship " + shipId + " new attempt for a landing point ");
|
||||
self.boardingPos[shipId] = self.getBoardingPos(gameState, self.startIndex, self.sea, undefined, false);
|
||||
}
|
||||
@@ -293,7 +293,7 @@ m.TransportPlan.prototype.onBoarding = function(gameState)
|
||||
++self.nTry[ent.id()];
|
||||
if (self.nTry[ent.id()] > 5)
|
||||
{
|
||||
if (self.debug > 0)
|
||||
if (self.debug > 1)
|
||||
API3.warn("unit blocked, but no ways out of the trap ... destroy it");
|
||||
self.resetUnit(gameState, ent);
|
||||
ent.destroy();
|
||||
@@ -399,13 +399,13 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
ship.moveApart(recov.entPos, 15);
|
||||
continue;
|
||||
}
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
API3.warn(">>> transport " + this.ID + " reloading failed ... <<<");
|
||||
// destroy the unit if inaccessible otherwise leave it there
|
||||
var index = gameState.ai.accessibility.getAccessValue(ent.position());
|
||||
if (gameState.ai.HQ.allowedRegions[index])
|
||||
{
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
API3.warn(" recovered entity kept " + ent.id());
|
||||
this.resetUnit(gameState, ent);
|
||||
// TODO we should not destroy it, but now the unit could still be reloaded on the next turn
|
||||
@@ -414,7 +414,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
API3.warn("recovered entity destroyed " + ent.id());
|
||||
this.resetUnit(gameState, ent);
|
||||
ent.destroy();
|
||||
@@ -453,7 +453,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
else if (gameState.ai.accessibility.getAccessValue(ent.position()) !== this.endIndex)
|
||||
{
|
||||
// unit unloaded on a wrong region - try to regarrison it and move a bit the ship
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
API3.warn(">>> unit unloaded on a wrong region ! try to garrison it again <<<");
|
||||
var ship = gameState.getEntityById(ent.getMetadata(PlayerID, "onBoard"));
|
||||
if (ship && !this.canceled)
|
||||
@@ -465,7 +465,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gameState.ai.HQ.Config.debug > 0)
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
API3.warn("no way ... we destroy it");
|
||||
this.resetUnit(gameState, ent);
|
||||
ent.destroy();
|
||||
@@ -537,7 +537,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
|
||||
if (self.nTry[shipId] > 2) // we must have been blocked by something ... try with another boarding point
|
||||
{
|
||||
self.nTry[shipId] = 0;
|
||||
if (self.debug > 0)
|
||||
if (self.debug > 1)
|
||||
API3.warn(shipId + " new attempt for a landing point ");
|
||||
self.boardingPos[shipId] = self.getBoardingPos(gameState, self.endIndex, self.sea, undefined, true);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ m.Worker = function(ent)
|
||||
|
||||
m.Worker.prototype.update = function(baseManager, gameState)
|
||||
{
|
||||
if (!this.ent.position())
|
||||
if (!this.ent.position() || this.ent.getMetadata(PlayerID, "plan") === -2 || this.ent.getMetadata(PlayerID, "plan") === -3)
|
||||
return;
|
||||
|
||||
// If we are waiting for a transport or we are sailing, just wait
|
||||
@@ -490,7 +490,7 @@ m.Worker.prototype.startGathering = function(gameState, baseManager)
|
||||
|
||||
// If we are here, we have nothing left to gather ... certainly no more resources of this type
|
||||
gameState.ai.HQ.lastFailedGather[resource] = gameState.ai.elapsedTime;
|
||||
if (gameState.ai.HQ.Config.debug > 1)
|
||||
if (gameState.ai.HQ.Config.debug > 2)
|
||||
warn(" >>>>> worker with gather-type " + resource + " with nothing to gather ");
|
||||
this.ent.setMetadata(PlayerID, "subrole", "idle");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user