1
0
forked from 0ad/0ad

Stop the AI wasting time chasing after any animals except chickens.

Make the AI behave better when it can't find any viable food sources.

This was SVN commit r9046.
This commit is contained in:
Ykkrosh 2011-03-08 01:40:44 +00:00
parent 9787f963ba
commit 8a0cbe009a
3 changed files with 65 additions and 50 deletions

View File

@ -130,7 +130,11 @@ var EntityTemplate = Class({
isUnhuntable: function() {
if (!this._template.UnitAI || !this._template.UnitAI.NaturalBehaviour)
return false;
return (this._template.UnitAI.NaturalBehaviour == "skittish");
// return (this._template.UnitAI.NaturalBehaviour == "skittish");
// Actually, since the AI is currently rubbish at hunting, skip all animals
// that aren't really weak:
return this._template.Health.Max >= 10;
},
});

View File

@ -75,8 +75,10 @@ var EconomyManager = Class({
}
},
pickMostNeededResource: function(gameState)
pickMostNeededResources: function(gameState)
{
var self = this;
// Find what resource type we're most in need of
var numGatherers = {};
for (var type in this.gatherWeights)
@ -87,19 +89,15 @@ var EconomyManager = Class({
numGatherers[ent.getMetadata("gather-type")] += 1;
});
var bestType = "food";
var bestTypeVal = Infinity; // num gatherers divided by weight
for (var type in this.gatherWeights)
{
var v = numGatherers[type] / this.gatherWeights[type];
if (v < bestTypeVal)
{
bestTypeVal = v;
bestType = type;
}
}
var types = Object.keys(this.gatherWeights);
types.sort(function(a, b) {
// Prefer fewer gatherers (divided by weight)
var va = numGatherers[a] / self.gatherWeights[a];
var vb = numGatherers[b] / self.gatherWeights[b];
return va - vb;
});
return bestType;
return types;
},
reassignRolelessUnits: function(gameState)
@ -133,43 +131,53 @@ var EconomyManager = Class({
idleWorkers.forEach(function(ent) {
var type = self.pickMostNeededResource(gameState);
// Make sure there's actually some of that type
// (We probably shouldn't pick impossible ones in the first place)
if (!resourceSupplies[type])
return;
// Pick the closest one.
// TODO: we should care about distance to dropsites, not (just) to the worker,
// and gather rates of workers
var workerPosition = ent.position();
var supplies = [];
resourceSupplies[type].forEach(function(supply) {
// Skip targets that are too hard to hunt
if (supply.entity.isUnhuntable())
return;
var dist = VectorDistance(supply.position, workerPosition);
supplies.push({ dist: dist, entity: supply.entity });
});
supplies.sort(function (a, b) {
// Prefer smaller distances
if (a.dist != b.dist)
return a.dist - b.dist;
return false;
});
// Start gathering
if (supplies.length)
var types = self.pickMostNeededResources(gameState);
for each (var type in types)
{
ent.gather(supplies[0].entity);
ent.setMetadata("subrole", "gatherer");
ent.setMetadata("gather-type", type);
// Make sure there's actually some of that type
if (!resourceSupplies[type])
continue;
// Pick the closest one.
// TODO: we should care about distance to dropsites, not (just) to the worker,
// and gather rates of workers
var workerPosition = ent.position();
var supplies = [];
resourceSupplies[type].forEach(function(supply) {
// Skip targets that are too hard to hunt
if (supply.entity.isUnhuntable())
return;
var dist = VectorDistance(supply.position, workerPosition);
// Skip targets that are far too far away (e.g. in the enemy base)
if (dist > 512)
return;
supplies.push({ dist: dist, entity: supply.entity });
});
supplies.sort(function (a, b) {
// Prefer smaller distances
if (a.dist != b.dist)
return a.dist - b.dist;
return false;
});
// Start gathering
if (supplies.length)
{
ent.gather(supplies[0].entity);
ent.setMetadata("subrole", "gatherer");
ent.setMetadata("gather-type", type);
return;
}
}
// Couldn't find any types to gather
ent.setMetadata("subrole", "idle");
});
}
},

View File

@ -1182,7 +1182,10 @@ UnitAI.prototype.IsAnimal = function()
*/
UnitAI.prototype.IsUnhuntable = function()
{
return (this.template.NaturalBehaviour && this.template.NaturalBehaviour == "skittish");
// return (this.template.NaturalBehaviour && this.template.NaturalBehaviour == "skittish");
// Actually, since the AI is currently rubbish at hunting, skip all animals
// that aren't really weak:
return this.IsAnimal() && Engine.QueryInterface(this.entity, IID_Health).GetMaxHitpoints() >= 10;
};
UnitAI.prototype.IsIdle = function()