1
0
forked from 0ad/0ad

Petra: various small tweaks

This was SVN commit r16152.
This commit is contained in:
mimo 2015-01-17 12:53:33 +00:00
parent 02a50fce62
commit 993d9c72d3
11 changed files with 217 additions and 89 deletions

View File

@ -57,12 +57,14 @@ m.BaseManager.prototype.init = function(gameState, unconstructed)
}
};
m.BaseManager.prototype.assignEntity = function(unit)
m.BaseManager.prototype.assignEntity = function(gameState, ent)
{
unit.setMetadata(PlayerID, "base", this.ID);
this.units.updateEnt(unit);
this.workers.updateEnt(unit);
this.buildings.updateEnt(unit);
ent.setMetadata(PlayerID, "base", this.ID);
this.units.updateEnt(ent);
this.workers.updateEnt(ent);
this.buildings.updateEnt(ent);
if (ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
this.assignResourceToDropsite(gameState, ent);
};
m.BaseManager.prototype.setAnchor = function(gameState, anchorEntity)
@ -111,10 +113,10 @@ m.BaseManager.prototype.checkEvents = function (gameState, events, queues)
let bestbase = m.getBestBase(ent, gameState);
this.newbaseID = bestbase.ID;
for (let entity of this.units.values())
bestbase.assignEntity(entity);
for (let entity of this.buildings.values())
bestbase.assignEntity(entity);
}
bestbase.assignEntity(gameState, entity);
for (let entity of this.buildings.values())
bestbase.assignEntity(gameState, entity);
}
}
}
@ -128,7 +130,7 @@ m.BaseManager.prototype.checkEvents = function (gameState, events, queues)
if (evt.newentity == evt.entity) // repaired building
continue;
if (ent.getMetadata(PlayerID,"base") == this.ID)
if (ent.getMetadata(PlayerID, "base") == this.ID)
{
if (ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
this.assignResourceToDropsite(gameState, ent);
@ -171,6 +173,18 @@ m.BaseManager.prototype.assignResourceToDropsite = function (gameState, dropsite
this.dropsites[dropsite.id()] = true;
var self = this;
let dropsitePos = dropsite.position();
let accessIndex = this.accessIndex;
if (this.ID === gameState.ai.HQ.baseManagers[0].ID)
{
accessIndex = dropsite.getMetadata(PlayerID, "access");
if (!accessIndex)
{
accessIndex = gameState.ai.accessibility.getAccessValue(dropsitePos);
dropsite.setMetadata(PlayerID, "access", accessIndex);
}
}
for (var type of dropsite.resourceDropsiteTypes())
{
var resources = gameState.getResourceSupplies(type);
@ -198,10 +212,10 @@ m.BaseManager.prototype.assignResourceToDropsite = function (gameState, dropsite
access = gameState.ai.accessibility.getAccessValue(supply.position());
supply.setMetadata(PlayerID, "access", access);
}
if (access != self.accessIndex)
if (access !== accessIndex)
return;
let dist = API3.SquareVectorDistance(supply.position(), dropsite.position());
let dist = API3.SquareVectorDistance(supply.position(), dropsitePos);
if (dist < self.maxDistResourceSquare)
{
if (dist < self.maxDistResourceSquare/16) // distmax/4
@ -538,9 +552,6 @@ m.BaseManager.prototype.assignRolelessUnits = function(gameState)
// TODO: actually this probably should be in the HQ.
m.BaseManager.prototype.setWorkersIdleByPriority = function(gameState)
{
if (gameState.currentPhase() < 2)
return;
// change resource only towards one which is more needed, and if changing will not change this order
var nb = 1; // no more than 1 change per turn (otherwise we should update the rates)
var mostNeeded = gameState.ai.HQ.pickMostNeededResources(gameState);
@ -763,6 +774,10 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
if (!target.hasClass("CivCentre") && !target.hasClass("StoneWall") && (!target.hasClass("Wonder") || gameState.getGameType() !== "wonder"))
continue;
// if our territory has shrinked since this foundation was positioned, do not build it
if (m.isNotWorthBuilding(target, gameState))
continue;
var assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length;
var maxTotalBuilders = Math.ceil(workers.length * 0.2);
var targetNB = 2;
@ -777,6 +792,12 @@ m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
targetNB = 15;
maxTotalBuilders = Math.max(maxTotalBuilders, 15);
}
// if no base yet, everybody should build
if (gameState.ai.HQ.numActiveBase() === 0)
{
targetNB = workers.length;
maxTotalBuilders = targetNB;
}
if (assigned < targetNB)
{
@ -911,12 +932,19 @@ m.BaseManager.prototype.update = function(gameState, queues, events)
if (gameState.ai.HQ.numActiveBase() > 0)
{
for (var ent of this.units.values())
m.getBestBase(ent, gameState).assignEntity(ent, gameState);
m.getBestBase(ent, gameState).assignEntity(gameState, ent);
for (var ent of this.buildings.values())
m.getBestBase(ent, gameState).assignEntity(ent, gameState);
{
if (ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
this.removeDropsite(gameState, ent);
m.getBestBase(ent, gameState).assignEntity(gameState, ent);
}
}
else if (gameState.ai.HQ.canBuildUnits)
{
this.assignToFoundations(gameState);
if (gameState.ai.playedTurn % 4 === 0)
this.setWorkersIdleByPriority(gameState);
this.assignRolelessUnits(gameState);
this.reassignIdleWorkers(gameState);
for (var ent of this.workers.values())
@ -967,7 +995,7 @@ m.BaseManager.prototype.update = function(gameState, queues, events)
}
}
if (gameState.ai.playedTurn % 2 == 0)
if (gameState.ai.playedTurn % 2 === 0 && gameState.currentPhase() > 1)
this.setWorkersIdleByPriority(gameState);
this.assignRolelessUnits(gameState);

View File

@ -84,6 +84,7 @@ m.Config = function(difficulty)
"house" : 350,
"dropsites" : 200,
"field" : 400,
"dock" : 90,
"economicBuilding" : 90,
"militaryBuilding" : 130,
"defenseBuilding" : 70,

View File

@ -143,6 +143,21 @@ m.getHolder = function(ent, gameState)
return found;
};
/**
* return true if it is not worth finishing this building (it would surely decay)
* TODO implement the other conditions
*/
m.isNotWorthBuilding = function(ent, gameState)
{
if (gameState.ai.HQ.territoryMap.getOwner(ent.position()) !== PlayerID)
{
let buildTerritories = ent.buildTerritories();
if (buildTerritories && (!buildTerritories.length || (buildTerritories.length === 1 && buildTerritories[0] === "own")))
return true;
}
return false;
};
m.dumpEntity = function(ent)
{
if (!ent)

View File

@ -1535,7 +1535,6 @@ m.HQ.prototype.canBuild = function(gameState, structure)
return false;
}
// build limits
var template = gameState.getTemplate(type);
if (!template)
{
@ -1545,6 +1544,19 @@ m.HQ.prototype.canBuild = function(gameState, structure)
}
if (!template || !template.available(gameState))
return false;
if (this.numActiveBase() < 1)
{
// if no base, check that we can build outside our territory
var buildTerritories = template.buildTerritories();
if (buildTerritories && (!buildTerritories.length || (buildTerritories.length === 1 && buildTerritories[0] === "own")))
{
this.stopBuilding.push(type);
return false;
}
}
// build limits
var limits = gameState.getEntityLimits();
var category = template.buildCategory();
if (category && limits[category] && gameState.getEntityCounts()[category] >= limits[category])

View File

@ -55,6 +55,18 @@ m.NavalManager.prototype.init = function(gameState, deserializing)
this.warShips.registerUpdates();
this.fishShips.registerUpdates();
var fishes = gameState.getFishableSupplies();
var availableFishes = {};
for (let fish of fishes.values())
{
let sea = gameState.ai.accessibility.getAccessValue(fish.position(), true);
fish.setMetadata(PlayerID, "sea", sea);
if (availableFishes[sea])
availableFishes[sea] += fish.resourceSupplyAmount();
else
availableFishes[sea] = fish.resourceSupplyAmount();
}
for (var i = 0; i < gameState.ai.accessibility.regionSize.length; ++i)
{
if (!gameState.ai.HQ.navalRegions[i])
@ -86,7 +98,10 @@ m.NavalManager.prototype.init = function(gameState, deserializing)
this.seaFishShips.push(collec);
this.wantedTransportShips.push(0);
this.wantedWarShips.push(0);
this.wantedFishShips.push(this.Config.Economy.targetNumFishers);
if (availableFishes[i] && availableFishes[i] > 1000)
this.wantedFishShips.push(this.Config.Economy.targetNumFishers);
else
this.wantedFishShips.push(0);
this.neededTransportShips.push(0);
this.neededWarShips.push(0);
}
@ -564,7 +579,7 @@ m.NavalManager.prototype.buildNavalStructures = function(gameState, queues)
if (gameState.getPopulation() > this.Config.Economy.popForDock)
{
if (queues.economicBuilding.countQueuedUnitsWithClass("NavalMarket") === 0
if (queues.dock.countQueuedUnitsWithClass("NavalMarket") === 0
&& gameState.getOwnStructures().filter(API3.Filters.and(API3.Filters.byClass("NavalMarket"), API3.Filters.isFoundation())).length === 0
&& gameState.ai.HQ.canBuild(gameState, "structures/{civ}_dock"))
{
@ -580,7 +595,7 @@ m.NavalManager.prototype.buildNavalStructures = function(gameState, queues)
{
if (!gameState.ai.HQ.navalRegions[sea])
continue;
queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_dock", { "land": [base.accessIndex], "sea": sea }));
queues.dock.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_dock", { "land": [base.accessIndex], "sea": sea }));
dockStarted = true;
break;
}

View File

@ -109,7 +109,7 @@ m.Queue.prototype.countQueuedUnitsWithClass = function(classe)
count += this.queue[i].number;
return count;
};
m.Queue.prototype.countQueuedUnitsWithMetadata = function(data,value)
m.Queue.prototype.countQueuedUnitsWithMetadata = function(data, value)
{
var count = 0;
for (var i in this.queue)

View File

@ -454,16 +454,16 @@ m.QueueManager.prototype.checkPausedQueues = function(gameState)
for (let q in this.queues)
{
let toBePaused = false;
if (numWorkers < 8)
toBePaused = (q != "citizenSoldier" && q != "villager"
&& (q != "civilCentre" || gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")) > 0));
if (gameState.ai.HQ.numActiveBase() === 0)
toBePaused = (q !== "dock" && q !== "civilCentre");
else if (numWorkers < 8)
toBePaused = (q !== "citizenSoldier" && q !== "villager");
else if (numWorkers < 16)
toBePaused = (q == "economicBuilding" || q == "militaryBuilding" || q == "defenseBuilding"
|| (q == "civilCentre" && gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")) > 0)
|| q == "majorTech" || q == "minorTech" || q.indexOf("plan_") != -1);
toBePaused = (q === "civilCentre" || q === "economicBuilding"
|| q === "militaryBuilding" || q === "defenseBuilding"
|| q === "majorTech" || q === "minorTech" || q.indexOf("plan_") !== -1);
else if (numWorkers < 24)
toBePaused = (q == "defenseBuilding"
|| (q == "civilCentre" && gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")) > 0)
toBePaused = (q === "civilCentre" || q === "defenseBuilding"
|| q == "majorTech" || q.indexOf("_siege") != -1 || q.indexOf("_champ") != -1);
let queue = this.queues[q];

View File

@ -52,12 +52,24 @@ m.ConstructionPlan.prototype.start = function(gameState)
Engine.ProfileStop();
return;
}
else if (this.metadata && this.metadata.expectedGain)
{
// Check if this market is still worth building (others may have been built making it useless)
let tradeManager = gameState.ai.HQ.tradeManager;
tradeManager.checkRoutes(gameState);
if (!tradeManager.isNewMarketWorth(this.metadata.expectedGain))
{
Engine.ProfileStop();
return;
}
}
gameState.buildingsBuilt++;
if (this.metadata === undefined)
this.metadata = { "base": pos.base };
else if (this.metadata.base === undefined)
this.metadata.base = pos.base;
if (pos.access)
this.metadata.access = pos.access; // needed for Docks for the position is on water
else
@ -105,7 +117,7 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
{
if (template.hasClass("CivCentre"))
{
if (this.metadata.resource)
if (this.metadata && this.metadata.resource)
{
var proximity = this.metadata.proximity ? this.metadata.proximity : undefined;
var pos = gameState.ai.HQ.findEconomicCCLocation(gameState, template, this.metadata.resource, proximity);
@ -132,11 +144,16 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
// if this fortress is our first siege unit builder, just try the standard placement as we want siege units
return false;
}
else if (template.hasClass("Market"))
else if (template.hasClass("Market")) // Docks (i.e. NavalMarket) are done before
{
var pos = gameState.ai.HQ.findMarketLocation(gameState, template);
if (pos && pos[2] > 0)
{
if (!this.metadata)
this.metadata = {};
this.metadata.expectedGain = pos[3];
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": pos[2] };
}
else if (!pos)
return false;
}
@ -322,7 +339,10 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
"base": gameState.ai.HQ.basesMap.map[bestIdx] };
};
// Placement of buildings with Dock build category
/**
* Placement of buildings with Dock build category
* metadata.proximity is defined when first dock without any territory
*/
m.ConstructionPlan.prototype.findDockPosition = function(gameState)
{
var template = this.template;
@ -337,6 +357,14 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
var bestVal = 0;
var landPassMap = gameState.ai.accessibility.landPassMap;
var navalPassMap = gameState.ai.accessibility.navalPassMap;
var width = gameState.ai.HQ.territoryMap.width;
var cellSize = gameState.ai.HQ.territoryMap.cellSize;
var nbShips = gameState.ai.HQ.navalManager.transportShips.length;
var proxyAccess = undefined;
if (this.metadata.proximity)
proxyAccess = gameState.ai.accessibility.getAccessValue(this.metadata.proximity);
for (let j = 0; j < territoryMap.length; ++j)
{
if (obstructions.map[j] <= 0)
@ -347,18 +375,32 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
continue;
if (this.metadata.sea && navalPassMap[j] !== this.metadata.sea)
continue;
if (nbShips === 0 && proxyAccess && proxyAccess > 1 && landPassMap[j] !== proxyAccess)
continue;
}
let tileOwner = territoryMap.getOwnerIndex(j);
if (tileOwner !== 0 && gameState.isPlayerEnemy(tileOwner))
continue;
// if not in our (or allied) territory, we do not want it too far to be able to defend it
let nearby = m.getFrontierProximity(gameState, j);
if (nearby > 4)
continue;
bestVal = 1;
bestIdx = j;
if (this.metadata.proximity)
{
// if proximity is given, we look for the nearest point
let pos = [cellSize * (j%width+0.5), cellSize * (Math.floor(j/width)+0.5)];
let dist = API3.SquareVectorDistance(this.metadata.proximity, pos);
if (bestIdx !== undefined && dist > bestVal)
continue;
bestVal = dist;
bestIdx = j;
}
else
{
// if not in our (or allied) territory, we do not want it too far to be able to defend it
let nearby = m.getFrontierProximity(gameState, j);
if (nearby > 4)
continue;
bestVal = 1;
bestIdx = j;
}
}
if (bestVal <= 0)
@ -391,7 +433,12 @@ m.ConstructionPlan.prototype.findDockPosition = function(gameState)
break;
}
if (!baseIndex)
API3.warn("Petra: dock constructed without base index " + baseIndex);
{
if (gameState.ai.HQ.numActiveBase() > 0)
API3.warn("Petra: dock constructed without base index " + baseIndex);
else
baseIndex = gameState.ai.HQ.baseManagers[0].ID;
}
}
return { "x": x, "z": z, "angle": angle, "xx": x, "zz": z, "base": baseIndex, "access": access };

View File

@ -99,24 +99,19 @@ m.HQ.prototype.assignStartingEntities = function(gameState)
var base = this.baseManagers[i];
if (base.territoryIndices.indexOf(index) === -1)
continue;
base.assignEntity(ent);
if (ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
base.assignResourceToDropsite(gameState, ent);
base.assignEntity(gameState, ent);
bestbase = base;
break;
}
if (!bestbase)
if (!bestbase) // entity outside our territory
{
// entity outside our territory
bestbase = m.getBestBase(ent, gameState);
bestbase.assignEntity(ent);
if (bestbase.ID !== this.baseManagers[0].ID && ent.resourceDropsiteTypes() && !ent.hasClass("Elephant"))
bestbase.assignResourceToDropsite(gameState, ent);
bestbase.assignEntity(gameState, ent);
}
// now assign entities garrisoned inside this entity
if (ent.isGarrisonHolder() && ent.garrisoned().length)
for (let id of ent.garrisoned())
bestbase.assignEntity(gameState.getEntityById(id));
bestbase.assignEntity(gameState, gameState.getEntityById(id));
}
};
@ -126,12 +121,13 @@ m.HQ.prototype.assignStartingEntities = function(gameState)
*/
m.HQ.prototype.regionAnalysis = function(gameState)
{
var accessibility = gameState.ai.accessibility;
let landIndex = undefined;
let seaIndex = undefined;
var ccEnts = gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre"));
for (let cc of ccEnts.values())
{
let land = gameState.ai.accessibility.getAccessValue(cc.position());
let land = accessibility.getAccessValue(cc.position());
if (land > 1)
{
landIndex = land;
@ -144,13 +140,13 @@ m.HQ.prototype.regionAnalysis = function(gameState)
{
if (!ent.position() || (!ent.hasClass("Unit") && !ent.trainableEntities()))
continue;
let land = gameState.ai.accessibility.getAccessValue(ent.position());
let land = accessibility.getAccessValue(ent.position());
if (land > 1)
{
landIndex = land;
break;
}
let sea = gameState.ai.accessibility.getAccessValue(ent.position(), true);
let sea = accessibility.getAccessValue(ent.position(), true);
if (!seaIndex && sea > 1)
seaIndex = sea;
}
@ -161,18 +157,18 @@ m.HQ.prototype.regionAnalysis = function(gameState)
var passabilityMap = gameState.getMap();
var totalSize = passabilityMap.width * passabilityMap.width;
var minLandSize = Math.floor(0.1*totalSize);
var minWaterSize = Math.floor(0.3*totalSize);
var minWaterSize = Math.floor(0.2*totalSize);
var cellArea = passabilityMap.cellSize * passabilityMap.cellSize;
for (var i = 0; i < gameState.ai.accessibility.regionSize.length; ++i)
for (var i = 0; i < accessibility.regionSize.length; ++i)
{
if (landIndex && i == landIndex)
this.landRegions[i] = true;
else if (gameState.ai.accessibility.regionType[i] === "land" && cellArea*gameState.ai.accessibility.regionSize[i] > 320)
else if (accessibility.regionType[i] === "land" && cellArea*accessibility.regionSize[i] > 320)
{
if (landIndex)
{
var sea = this.getSeaIndex(gameState, landIndex, i);
if (sea && (gameState.ai.accessibility.regionSize[i] > minLandSize || gameState.ai.accessibility.regionSize[sea] > minWaterSize))
if (sea && (accessibility.regionSize[i] > minLandSize || accessibility.regionSize[sea] > minWaterSize))
{
this.navalMap = true;
this.landRegions[i] = true;
@ -181,7 +177,7 @@ m.HQ.prototype.regionAnalysis = function(gameState)
}
else
{
var traject = gameState.ai.accessibility.getTrajectToIndex(seaIndex, i);
var traject = accessibility.getTrajectToIndex(seaIndex, i);
if (traject && traject.length === 2)
{
this.navalMap = true;
@ -190,11 +186,13 @@ m.HQ.prototype.regionAnalysis = function(gameState)
}
}
}
else if (gameState.ai.accessibility.regionType[i] === "water" && gameState.ai.accessibility.regionSize[i] > minWaterSize)
else if (accessibility.regionType[i] === "water" && accessibility.regionSize[i] > minWaterSize)
{
this.navalMap = true;
this.navalRegions[i] = true;
}
else if (accessibility.regionType[i] === "water" && cellArea*accessibility.regionSize[i] > 3600)
this.navalRegions[i] = true;
}
if (this.Config.debug < 3)
@ -230,27 +228,29 @@ m.HQ.prototype.structureAnalysis = function(gameState)
/**
* build our first base
* if not enough resource, try first to do a dock
*/
m.HQ.prototype.buildFirstBase = function(gameState)
{
var total = gameState.getResources();
var template = gameState.getTemplate(gameState.applyCiv("structures/{civ}_civil_centre"));
if (!total.canAfford(new API3.Resources(template.cost())))
{
/* API3.warn("not enough resource to build a cc, try with a dock");
template = gameState.applyCiv("structures/{civ}_dock");
if (!gameState.isDisabledTemplates(template))
{
template = gameState.getTemplate(template);
if (!total.canAfford(new API3.Resources(template.cost())))
{
API3.warn("not enough resource for dock ... return");
return;
}
API3.warn("but we could still build a dock if it was implemented");
return;
} */
var template = gameState.applyCiv("structures/{civ}_civil_centre");
if (gameState.isDisabledTemplates(template))
return;
var template = gameState.getTemplate(template);
var goal = "civil_centre";
var docks = gameState.getOwnStructures().filter(API3.Filters.byClass("Dock"));
if (!total.canAfford(new API3.Resources(template.cost())) && !docks.length)
{
// not enough resource to build a cc, try with a dock to accumulate resources if none yet
if (gameState.ai.queues.dock.countQueuedUnits())
return;
template = gameState.applyCiv("structures/{civ}_dock");
if (gameState.isDisabledTemplates(template))
return;
template = gameState.getTemplate(template);
if (!total.canAfford(new API3.Resources(template.cost())))
return;
var goal = "dock";
}
// We first choose as startingPoint the point where we have the more units
@ -288,17 +288,20 @@ m.HQ.prototype.buildFirstBase = function(gameState)
startingPoint.push({"pos": pos, "land": land, "sea": sea, "weight": 1});
}
if (!startingPoint.length)
{
API3.warn("Petra error in buildFirstBase, can not find a starting position");
return;
}
let imax = 0;
for (let i = 1; i < startingPoint.length; ++i)
if (startingPoint[i].weight > startingPoint[imax].weight)
imax = i;
var template = gameState.applyCiv("structures/{civ}_civil_centre");
gameState.ai.queues.civilCentre.addItem(new m.ConstructionPlan(gameState, template, { "base": -1, "resource": "wood", "proximity": startingPoint[imax].pos }));
if (goal === "dock")
{
let sea = startingPoint[imax].sea > 1 ? startingPoint[imax].sea : undefined;
gameState.ai.queues.dock.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_dock", { "sea": sea, "proximity": startingPoint[imax].pos }));
}
else
gameState.ai.queues.civilCentre.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base": -1, "resource": "wood", "proximity": startingPoint[imax].pos }));
};
/**

View File

@ -370,7 +370,7 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex)
if (!m1.position())
continue;
var access1 = gameState.ai.accessibility.getAccessValue(m1.position());
var sea1 = m1.hasClass("Dock") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m1, true) : undefined;
var sea1 = m1.hasClass("NavalMarket") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m1, true) : undefined;
for (var m2 of market2)
{
if (m1.id() === m2.id())
@ -378,7 +378,7 @@ m.TradeManager.prototype.checkRoutes = function(gameState, accessIndex)
if (!m2.position())
continue;
var access2 = gameState.ai.accessibility.getAccessValue(m2.position());
var sea2 = m2.hasClass("Dock") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m2, true) : undefined;
var sea2 = m2.hasClass("NavalMarket") ? gameState.ai.HQ.navalManager.getDockIndex(gameState, m2, true) : undefined;
var land = (access1 == access2) ? access1 : undefined;
var sea = (sea1 && sea1 == sea2) ? sea1 : undefined;
if (!land && !sea)
@ -502,7 +502,7 @@ m.TradeManager.prototype.checkTrader = function(gameState, ent)
m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
{
if (queues.economicBuilding.countQueuedUnitsWithClass("Market") > 0)
if (queues.economicBuilding.countQueuedUnitsWithClass("Market") + queues.dock.countQueuedUnitsWithClass("Market") > 0)
return;
if (!gameState.ai.HQ.canBuild(gameState, "structures/{civ}_market"))
return;
@ -520,8 +520,7 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
return;
}
this.routeProspection = false;
if (this.potentialTradeRoute && marketPos[3] < 2*this.potentialTradeRoute.gain
&& marketPos[3] < this.potentialTradeRoute.gain + 20)
if (!this.isNewMarketWorth(marketPos[3]))
return; // position found, but not enough gain compared to our present route
if (this.Config.debug > 1)
@ -536,6 +535,14 @@ m.TradeManager.prototype.prospectForNewMarket = function(gameState, queues)
queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_market"));
};
m.TradeManager.prototype.isNewMarketWorth = function(expectedGain)
{
if (this.potentialTradeRoute && expectedGain < 2*this.potentialTradeRoute.gain
&& expectedGain < this.potentialTradeRoute.gain + 20)
return false;
return true;
};
m.TradeManager.prototype.update = function(gameState, events, queues)
{
this.performBarter(gameState);

View File

@ -120,9 +120,9 @@ m.Worker.prototype.update = function(ent, gameState)
}
}
else if (subrole === "builder")
{
{
if (this.ent.unitAIState().split(".")[1] === "REPAIR")
return;
return;
// okay so apparently we aren't working.
// Unless we've been explicitely told to keep our role, make us idle.
var target = gameState.getEntityById(this.ent.getMetadata(PlayerID, "target-foundation"));
@ -273,7 +273,7 @@ m.Worker.prototype.startGathering = function(gameState)
var supply;
// first look in our own base if accessible from our present position
if (this.base.accessIndex === access)
if (this.accessIndex === access)
{
if ((supply = findSupply(this.ent, this.base.dropsiteSupplies[resource]["nearby"])))
{