1
0
forked from mirrors/0ad

Petra: deals more efficiently with naval transport

This was SVN commit r15559.
This commit is contained in:
mimo
2014-07-25 18:16:33 +00:00
parent 05de9def0b
commit 074cf06803
2 changed files with 64 additions and 36 deletions
@@ -220,7 +220,7 @@ m.NavalManager.prototype.getDockIndex = function(gameState, dock, onWater)
}
}
if (index < 2)
warn("ERROR in Petra navalManager because of dock position (onWater=" + onWater + ") index " + index);
API3.warn("ERROR in Petra navalManager because of dock position (onWater=" + onWater + ") index " + index);
return index;
};
@@ -276,12 +276,13 @@ m.NavalManager.prototype.addPlan = function(plan)
// complete already existing plan or create a new one for this requirement
// (many units can then call this separately and end up in the same plan)
// TODO check garrison classes
m.NavalManager.prototype.requireTransport = function(gameState, entity, startIndex, endIndex, endPos)
{
if (entity.getMetadata(PlayerID, "transport") !== undefined)
{
if (this.Config.debug > 0)
warn("Petra naval manager error: unit " + entity.id() + " has already required a transport");
API3.warn("Petra naval manager error: unit " + entity.id() + " has already required a transport");
return false;
}
@@ -291,7 +292,9 @@ m.NavalManager.prototype.requireTransport = function(gameState, entity, startInd
continue
if (plan.state !== "boarding")
continue
if (plan.units.length > 12) // TODO to be improved ... check on ship capacity
if (plan.transportShips.length && !plan.countFreeSlots())
continue;
else if (!plan.transportShips.length && plan.units.length > 12)
continue;
plan.addUnit(entity, endPos);
return true;
@@ -300,7 +303,7 @@ m.NavalManager.prototype.requireTransport = function(gameState, entity, startInd
if (plan.failed)
{
if (this.Config.debug > 0)
warn(">>>> transport plan aborted <<<<");
API3.warn(">>>> transport plan aborted <<<<");
return false;
}
this.transportPlans.push(plan);
@@ -314,7 +317,7 @@ m.NavalManager.prototype.splitTransport = function(gameState, plan)
if (newplan.failed)
{
if (this.Config.debug > 0)
warn(">>>> split of transport plan aborted <<<<");
API3.warn(">>>> split of transport plan aborted <<<<");
return false;
}
@@ -411,19 +414,8 @@ m.NavalManager.prototype.maintainFleet = function(gameState, queues)
m.NavalManager.prototype.assignToPlans = function(gameState)
{
for (var plan of this.transportPlans)
{
if (!plan.needTransportShips)
continue;
for each (var ship in this.seaTransportShips[plan.sea]._entities)
{
if (ship.getMetadata(PlayerID, "transporter"))
continue;
plan.assignShip(ship);
plan.needTransportShips = false;
break;
}
}
if (plan.needTransportShips)
plan.assignShip(gameState);
};
// let blocking ships move apart from active ships (waiting for a better pathfinder)
@@ -563,7 +555,7 @@ m.NavalManager.prototype.update = function(gameState, queues, events)
if (remaining === 0)
{
if (this.Config.debug > 0)
warn("no more units on transport plan " + this.transportPlans[i].ID);
API3.warn("no more units on transport plan " + this.transportPlans[i].ID);
this.transportPlans[i].releaseAll();
this.transportPlans.splice(i--, 1);
}
@@ -39,7 +39,7 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
{
this.failed = true;
if (this.debug > 0)
warn("transport plan with bad path: startIndex " + startIndex + " endIndex " + endIndex);
API3.warn("transport plan with bad path: startIndex " + startIndex + " endIndex " + endIndex);
return false;
}
@@ -50,10 +50,11 @@ m.TransportPlan = function(gameState, units, startIndex, endIndex, endPos)
{
ent.setMetadata(PlayerID, "transport", this.ID);
ent.setMetadata(PlayerID, "endPos", endPos);
this.units.updateEnt(ent);
}
if (this.debug > 0)
warn("Starting a new transport plan with ID " + this.ID + " to index " + endIndex
API3.warn("Starting a new transport plan with ID " + this.ID + " to index " + endIndex
+ " with units length " + units.length);
this.ships = gameState.ai.HQ.navalManager.ships.filter(API3.Filters.byMetadata(PlayerID, "transporter", this.ID));
@@ -66,6 +67,10 @@ 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;
};
@@ -76,13 +81,14 @@ m.TransportPlan.prototype.countFreeSlots = function()
var self = this;
var slots = 0;
this.transportShips.forEach(function (ship) { slots += self.countFreeSlotsOnShip(ship); });
return slots;
};
m.TransportPlan.prototype.countFreeSlotsOnShip = function(ship)
{
var occupied = ship.garrisoned().length
var occupied = ship._entity.garrisoned.length
+ this.units.filter(API3.Filters.byMetadata(PlayerID, "onBoard", ship.id())).length;
return ship.garrisonMax() - occupied;
return (ship.garrisonMax() - occupied);
};
m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent)
@@ -117,9 +123,38 @@ m.TransportPlan.prototype.assignUnitToShip = function(gameState, ent)
gameState.ai.HQ.navalManager.splitTransport(gameState, this);
};
m.TransportPlan.prototype.assignShip = function(ship)
// Assign a ship to this plan. If pos is given, take the nearest from this position
m.TransportPlan.prototype.assignShip = function(gameState, pos)
{
ship.setMetadata(PlayerID, "transporter", this.ID);
var distmin = Math.min();
var nearest = undefined;
for each (var ship in gameState.ai.HQ.navalManager.seaTransportShips[this.sea]._entities)
{
if (ship.getMetadata(PlayerID, "transporter"))
continue;
if (pos)
{
var dist = API3.SquareVectorDistance(pos, ship.position());
if (dist > distmin)
continue;
distmin = dist;
nearest = ship;
}
else
{
nearest = ship;
break;
}
}
if (nearest)
{
nearest.setMetadata(PlayerID, "transporter", this.ID);
this.ships.updateEnt(nearest);
this.transportShips.updateEnt(nearest);
this.needTransportShips = false;
return true;
}
return false;
};
// add a unit to this plan
@@ -127,6 +162,7 @@ m.TransportPlan.prototype.addUnit = function(unit, endPos)
{
unit.setMetadata(PlayerID, "transport", this.ID);
unit.setMetadata(PlayerID, "endPos", endPos);
this.units.updateEnt(unit);
};
m.TransportPlan.prototype.releaseAll = function()
@@ -235,7 +271,7 @@ m.TransportPlan.prototype.onBoarding = function(gameState)
{
self.nTry[shipId] = 0;
if (self.debug > 0)
warn(shipId + " new attempt for a landing point ");
API3.warn(shipId + " new attempt for a landing point ");
self.boardingPos[shipId] = self.getBoardingPos(gameState, self.startIndex, self.sea, undefined, false);
}
ship.move(self.boardingPos[shipId][0], self.boardingPos[shipId][1]);
@@ -257,7 +293,7 @@ m.TransportPlan.prototype.onBoarding = function(gameState)
if (self.nTry[ent.id()] > 5)
{
if (self.debug > 0)
warn("unit blocked, but no ways out of the trap ... destroy it");
API3.warn("unit blocked, but no ways out of the trap ... destroy it");
ent.destroy();
return;
}
@@ -317,7 +353,7 @@ m.TransportPlan.prototype.getBoardingPos = function(gameState, landIndex, seaInd
{
if (!gameState.ai.HQ.navalManager.landingZones[landIndex][seaIndex])
{
warn(" >>> no landing zone for land " + landIndex + " and sea " + seaIndex);
API3.warn(" >>> no landing zone for land " + landIndex + " and sea " + seaIndex);
return destination;
}
@@ -370,7 +406,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
continue;
}
if (gameState.ai.HQ.Config.debug > 0)
warn(">>> reloading failed ... <<<");
API3.warn(">>> reloading failed ... <<<");
// destroy the unit if inaccessible otherwise leave it
var index = gameState.ai.accessibility.getAccessValue(ent.position());
if (gameState.ai.HQ.allowedRegions[index])
@@ -379,12 +415,12 @@ m.TransportPlan.prototype.onSailing = function(gameState)
ent.setMetadata(PlayerID, "onBoard", undefined);
ent.setMetadata(PlayerID, "endPos", undefined);
if (gameState.ai.HQ.Config.debug > 0)
warn("recovered entity kept " + ent.id());
API3.warn("recovered entity kept " + ent.id());
}
else
{
if (gameState.ai.HQ.Config.debug > 0)
warn("recovered entity destroyed " + ent.id());
API3.warn("recovered entity destroyed " + ent.id());
ent.destroy();
}
}
@@ -406,13 +442,13 @@ m.TransportPlan.prototype.onSailing = function(gameState)
ent.setMetadata(PlayerID, "onBoard", "onBoard");
else
{
warn("Petra transportPlan problem: unit not on ship without position ???");
API3.warn("Petra transportPlan problem: unit not on ship without position ???");
ent.destroy();
}
}
else
{
warn("Petra transportPlan problem: unit on ship, but no ship ???");
API3.warn("Petra transportPlan problem: unit on ship, but no ship ???");
ent.destroy();
}
}
@@ -420,7 +456,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
{
// unit unloaded on a wrong region - try to regarrison it and move a bit the ship
if (gameState.ai.HQ.Config.debug > 0)
warn(">>> unit unloaded on a wrong region ! try to garrison it again <<<");
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)
{
@@ -432,7 +468,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
else
{
if (gameState.ai.HQ.Config.debug > 0)
warn("no way ... we destroy it");
API3.warn("no way ... we destroy it");
ent.destroy();
}
}
@@ -497,7 +533,7 @@ m.TransportPlan.prototype.onSailing = function(gameState)
{
self.nTry[shipId] = 0;
if (self.debug > 0)
warn(shipId + " new attempt for a landing point ");
API3.warn(shipId + " new attempt for a landing point ");
self.boardingPos[shipId] = self.getBoardingPos(gameState, self.endIndex, self.sea, undefined, true);
}
ship.move(self.boardingPos[shipId][0], self.boardingPos[shipId][1]);