Bunch of petra bug fixes: fixes #2685, #2686 and makes 074cf06803 really working

This was SVN commit r15570.
This commit is contained in:
mimo 2014-07-27 15:25:26 +00:00
parent 64efbfeae3
commit fe8e19ebfe
5 changed files with 60 additions and 61 deletions

View File

@ -57,7 +57,7 @@ m.Army.prototype.recalculatePosition = function(gameState, force)
for (var id of this.foeEntities)
{
var ent = gameState.getEntityById(id);
if (!ent)
if (!ent || !ent.position())
continue;
npos++;
var epos = ent.position();
@ -106,11 +106,11 @@ m.Army.prototype.evaluateStrength = function (ent, isOwn, remove)
// add an entity to the enemy army
// Will return true if the entity was added and false otherwise.
// won't recalculate our position but will dirty it.
m.Army.prototype.addFoe = function (gameState, enemyID, force)
m.Army.prototype.addFoe = function (gameState, enemyId, force)
{
if (this.foeEntities.indexOf(enemyID) !== -1)
if (this.foeEntities.indexOf(enemyId) !== -1)
return false;
var ent = gameState.getEntityById(enemyID);
var ent = gameState.getEntityById(enemyId);
if (ent === undefined || ent.position() === undefined)
return false;
@ -118,8 +118,8 @@ m.Army.prototype.addFoe = function (gameState, enemyID, force)
if (!force && API3.SquareVectorDistance(ent.position(), this.foePosition) > this.compactSize)
return false;
this.foeEntities.push(enemyID);
this.assignedAgainst[enemyID] = [];
this.foeEntities.push(enemyId);
this.assignedAgainst[enemyId] = [];
this.positionLastUpdate = 0;
this.evaluateStrength(ent);
ent.setMetadata(PlayerID, "PartOfArmy", this.ID);
@ -129,12 +129,12 @@ m.Army.prototype.addFoe = function (gameState, enemyID, force)
// 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.Army.prototype.removeFoe = function (gameState, enemyID, enemyEntity)
m.Army.prototype.removeFoe = function (gameState, enemyId, enemyEntity)
{
var idx = this.foeEntities.indexOf(enemyID);
var idx = this.foeEntities.indexOf(enemyId);
if (idx === -1)
return false;
var ent = enemyEntity === undefined ? gameState.getEntityById(enemyID) : enemyEntity;
var ent = enemyEntity === undefined ? gameState.getEntityById(enemyId) : enemyEntity;
if (ent === undefined)
{
warn("Trying to remove a non-existing enemy entity, crashing for stacktrace");
@ -144,27 +144,30 @@ m.Army.prototype.removeFoe = function (gameState, enemyID, enemyEntity)
this.evaluateStrength(ent, false, true);
ent.setMetadata(PlayerID, "PartOfArmy", undefined);
this.assignedAgainst[enemyID] = undefined;
this.assignedAgainst[enemyId] = undefined;
for (var to in this.assignedTo)
if (this.assignedTo[to] == enemyID)
if (this.assignedTo[to] == enemyId)
this.assignedTo[to] = undefined;
return true;
}
// adds a defender but doesn't assign him yet.
m.Army.prototype.addOwn = function (gameState, ID)
// 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.Army.prototype.addOwn = function (gameState, id, force)
{
if (this.ownEntities.indexOf(ID) !== -1)
if (this.ownEntities.indexOf(id) !== -1)
return false;
var ent = gameState.getEntityById(ID);
if (ent === undefined || ent.position() === undefined)
var ent = gameState.getEntityById(id);
if (ent === undefined)
return false;
if(!ent.position() && !force)
return false;
this.ownEntities.push(ID);
this.ownEntities.push(id);
this.evaluateStrength(ent, true);
ent.setMetadata(PlayerID, "PartOfArmy", this.ID);
this.assignedTo[ID] = 0;
this.assignedTo[id] = 0;
var plan = ent.getMetadata(PlayerID, "plan");
if (plan !== undefined)
@ -178,15 +181,15 @@ m.Army.prototype.addOwn = function (gameState, ID)
return true;
}
m.Army.prototype.removeOwn = function (gameState, ID, Entity)
m.Army.prototype.removeOwn = function (gameState, id, Entity)
{
var idx = this.ownEntities.indexOf(ID);
var idx = this.ownEntities.indexOf(id);
if (idx === -1)
return false;
var ent = Entity === undefined ? gameState.getEntityById(ID) : Entity;
var ent = Entity === undefined ? gameState.getEntityById(id) : Entity;
if (ent === undefined)
{
warn( ID);
warn( id);
warn("Trying to remove a non-existing entity, crashing for stacktrace");
xgzrg();
}
@ -199,13 +202,13 @@ m.Army.prototype.removeOwn = function (gameState, ID, Entity)
else
ent.setMetadata(PlayerID, "plan", undefined);
if (this.assignedTo[ID] !== 0)
if (this.assignedTo[id] !== 0)
{
var temp = this.assignedAgainst[this.assignedTo[ID]];
var temp = this.assignedAgainst[this.assignedTo[id]];
if (temp)
temp.splice(temp.indexOf(ID), 1);
temp.splice(temp.indexOf(id), 1);
}
this.assignedTo[ID] = undefined;
this.assignedTo[id] = undefined;
var formerSubrole = ent.getMetadata(PlayerID, "formerSubrole");
if (formerSubrole !== undefined)
@ -217,12 +220,8 @@ m.Army.prototype.removeOwn = function (gameState, ID, Entity)
if (!ent.position()) // this unit must still be in a transport plan ... try to cancel it
{
var planID = ent.getMetadata(PlayerID, "transport");
if (!planID) // no plans ? do not know what to do
{
warn(" ERROR in army.js: ent from army without position nor transport plan");
ent.destroy();
}
else
// no plans must mean that the unit was in a ship which was destroyed, so do nothing
if (planID)
{
if (gameState.ai.HQ.Config.debug > 0)
warn("ent from army still in transport plan: plan " + planID + " canceled");
@ -283,7 +282,7 @@ m.Army.prototype.merge = function (gameState, otherArmy)
this.addFoe(gameState, id);
// TODO: reassign those ?
for (var id of otherArmy.ownEntities)
this.addOwn(gameState, id);
this.addOwn(gameState, id, true);
this.recalculatePosition(gameState, true);
this.recalculateStrengths(gameState);
@ -350,7 +349,8 @@ m.Army.prototype.checkEvents = function (gameState, events)
// we have converted an enemy, let's assign it as a defender
if (this.removeFoe(gameState, msg.entity))
this.addOwn(gameState, msg.entity);
} else if (msg.from === PlayerID)
}
else if (msg.from === PlayerID)
this.removeOwn(gameState, msg.entity); // TODO: add allies
}
}
@ -374,10 +374,12 @@ m.Army.prototype.onUpdate = function (gameState)
{
var id = this.foeEntities[i];
var ent = gameState.getEntityById(id);
if (!ent || !ent.position())
continue;
if (API3.SquareVectorDistance(ent.position(), this.foePosition) > this.breakawaySize)
{
breakaways.push(id);
if(this.removeFoe(gameState, id))
if (this.removeFoe(gameState, id))
i--;
}
}

View File

@ -447,9 +447,7 @@ m.AttackPlan.prototype.updatePreparation = function(gameState, events)
if (this.overseas && !gameState.ai.HQ.navalManager.seaTransportShips.length)
return 1;
// if we add units to this plan, wait next turn for the collections to be updated
if (this.assignUnits(gameState))
return 1;
this.assignUnits(gameState);
// special case: if we've reached max pop, and we can start the plan, start it.
if (gameState.getPopulationMax() - gameState.getPopulation() < 10)
@ -623,7 +621,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
{
var plan = this.name;
var added = false;
var self = this;
// If we can not build units, assign all available except those affcted to allied defnse to the current attack
if (!this.canBuildUnits)
{
@ -637,6 +635,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
if (ent.getMetadata(PlayerID, "allied"))
return;
ent.setMetadata(PlayerID, "plan", plan);
self.unitCollection.updateEnt(ent);
added = true;
});
return added;
@ -657,6 +656,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
if (num++ < 2)
return;
ent.setMetadata(PlayerID, "plan", plan);
self.unitCollection.updateEnt(ent);
added = true;
});
return added;
@ -673,6 +673,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
if (ent.hasClass("Ship") || ent.hasClass("Support") || ent.attackTypes() === undefined)
return;
ent.setMetadata(PlayerID, "plan", plan);
self.unitCollection.updateEnt(ent);
added = true;
});
// Add units previously in a plan, but which left it because needed for defense or attack finished
@ -682,6 +683,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
if (ent.getMetadata(PlayerID, "transport") !== undefined || ent.getMetadata(PlayerID, "transporter") !== undefined)
return;
ent.setMetadata(PlayerID, "plan", plan);
self.unitCollection.updateEnt(ent);
added = true;
});
@ -703,6 +705,7 @@ m.AttackPlan.prototype.assignUnits = function(gameState)
if (num++ < 9)
return;
ent.setMetadata(PlayerID, "plan", plan);
self.unitCollection.updateEnt(ent);
added = true;
});
return added;

View File

@ -387,13 +387,6 @@ m.DefenseManager.prototype.garrisonRangedUnitsInside = function(gameState, targe
}
if (gameState.ai.accessibility.getAccessValue(ent.position()) !== index)
return;
var army = ent.getMetadata(PlayerID, "PartOfArmy");
if (army !== undefined)
{
army = self.getArmy(army);
if (army !== undefined)
army.removeOwn(gameState, ent.id(), ent);
}
garrisonManager.garrison(gameState, ent, target, "protection");
});
};

View File

@ -292,12 +292,6 @@ m.NavalManager.prototype.requireTransport = function(gameState, entity, startInd
continue
if (plan.state !== "boarding")
continue
// if (plan.transportShips.length && !plan.countFreeSlots())
// continue;
// else if (!plan.transportShips.length && plan.units.length > 14)
// continue;
if (plan.units.length > 14)
continue;
plan.addUnit(entity, endPos);
return true;
}
@ -315,6 +309,8 @@ 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)
API3.warn(">>>> split of transport plan started <<<<");
var newplan = new m.TransportPlan(gameState, [], plan.startIndex, plan.endIndex, plan.endPos, false);
if (newplan.failed)
{
@ -325,11 +321,13 @@ m.NavalManager.prototype.splitTransport = function(gameState, plan)
var nbUnits = 0;
plan.units.forEach(function (ent) {
if (ent.setMetadata(PlayerID, "onBoard"))
if (ent.getMetadata(PlayerID, "onBoard"))
return;
++nbUnits;
newplan.addUnit(ent, ent.getMetadata(PlayerID, "endPos"));
});
if (this.Config.debug > 0)
API3.warn(">>>> previous plan left with units " + plan.units.length);
if (nbUnits)
this.transportPlans.push(newplan);
return (nbUnits !== 0);
@ -413,7 +411,7 @@ m.NavalManager.prototype.maintainFleet = function(gameState, queues)
};
// assigns free ships to plans that need some
m.NavalManager.prototype.assignToPlans = function(gameState)
m.NavalManager.prototype.assignShipsToPlans = function(gameState)
{
for (var plan of this.transportPlans)
if (plan.needTransportShips)
@ -564,7 +562,7 @@ m.NavalManager.prototype.update = function(gameState, queues, events)
}
// assign free ships to plans which need them
this.assignToPlans(gameState);
this.assignShipsToPlans(gameState);
// and require for more ships if needed
this.checkLevels(gameState, queues);
this.maintainFleet(gameState, queues);

View File

@ -42,7 +42,7 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
API3.warn("transport plan with bad path: startIndex " + startIndex + " endIndex " + endIndex);
return false;
}
this.units = gameState.getOwnUnits().filter(API3.Filters.byMetadata(PlayerID, "transport", this.ID));
this.units.registerUpdates();
@ -67,10 +67,6 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
this.state = "boarding";
this.boardingPos = {};
this.needTransportShips = true;
if (units.length)
this.assignShip(gameState, units[0].position());
else
this.assignShip(gameState);
this.nTry = {};
return true;
};
@ -123,11 +119,18 @@ m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent)
gameState.ai.HQ.navalManager.splitTransport(gameState, this);
};
// Assign a ship to this plan. If pos is given, take the nearest from this position
m.TransportPlan.prototype.assignShip = function(gameState, pos)
m.TransportPlan.prototype.assignShip = function(gameState)
{
var distmin = Math.min();
var nearest = undefined;
var pos = undefined;
// choose a unit of this plan not yet assigned to a ship
this.units.forEach(function (ent) {
if (pos || ent.getMetadata(PlayerID, "onBoard") !== undefined || !ent.position())
return;
pos = ent.position();
});
// and choose the nearest available ship from this unit
for each (var ship in gameState.ai.HQ.navalManager.seaTransportShips[this.sea]._entities)
{
if (ship.getMetadata(PlayerID, "transporter"))