1
0
forked from 0ad/0ad

Don't store the gatherers per player.

94c02ec33c deprecated the use of storing the gatherers on a per player
basis.
This removes it entirely thus saving a few useless calls and operations.

Refs #1387.
Differential Revision: D2755
Reviewed by: @bb.
This was SVN commit r24036.
This commit is contained in:
Freagarach 2020-09-11 10:19:09 +00:00
parent e543b01077
commit 277fb13ba0
3 changed files with 50 additions and 63 deletions

View File

@ -32,11 +32,7 @@ ResourceSupply.prototype.Init = function()
// Current resource amount (non-negative)
this.amount = this.GetMaxAmount();
// List of IDs for each player
this.gatherers = [];
let numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers();
for (let i = 0; i < numPlayers; ++i)
this.gatherers.push([]);
let [type, subtype] = this.template.Type.split('.');
this.cachedType = { "generic": type, "specific": subtype };
@ -69,7 +65,7 @@ ResourceSupply.prototype.GetMaxGatherers = function()
ResourceSupply.prototype.GetNumGatherers = function()
{
return this.gatherers.reduce((a, b) => a + b.length, 0);
return this.gatherers.length;
};
/**
@ -81,13 +77,29 @@ ResourceSupply.prototype.GetType = function()
};
/**
* @param {number} gathererID The gatherer's entity id.
* @param {number} player The gatherer's id.
* @return {boolean} Whether the ResourceSupply can have additional gatherers.
* @param {number} gathererID - The gatherer's entity id.
* @return {boolean} - Whether the ResourceSupply can have this additional gatherer or it is already gathering.
*/
ResourceSupply.prototype.IsAvailable = function(player, gathererID)
ResourceSupply.prototype.IsAvailableTo = function(gathererID)
{
return this.GetCurrentAmount() > 0 && (this.GetNumGatherers() < this.GetMaxGatherers() || this.gatherers[player].indexOf(gathererID) != -1);
return this.IsAvailable() || this.IsGatheringUs(gathererID);
};
/**
* @return {boolean} - Whether this entity can have an additional gatherer.
*/
ResourceSupply.prototype.IsAvailable = function()
{
return this.amount && this.gatherers.length < this.GetMaxGatherers();
};
/**
* @param {number} entity - The entityID to check for.
* @return {boolean} - Whether the given entity is already gathering at us.
*/
ResourceSupply.prototype.IsGatheringUs = function(entity)
{
return this.gatherers.indexOf(entity) !== -1;
};
/**
@ -138,47 +150,35 @@ ResourceSupply.prototype.TakeResources = function(amount)
};
/**
* @param {number} player The gatherer's id.
* @param {number} gathererID The gatherer's player id.
* @returns {boolean} Whether the gatherer was successfully added to the entity's gatherers list.
* @param {number} gathererID - The gatherer to add.
* @return {boolean} - Whether the gatherer was successfully added to the entity's gatherers list
* or the entity was already gathering us.
*/
ResourceSupply.prototype.AddGatherer = function(player, gathererID)
ResourceSupply.prototype.AddGatherer = function(gathererID)
{
if (!this.IsAvailable(player, gathererID))
if (!this.IsAvailable())
return false;
if (this.gatherers[player].indexOf(gathererID) == -1)
{
this.gatherers[player].push(gathererID);
// broadcast message, mainly useful for the AIs.
Engine.PostMessage(this.entity, MT_ResourceSupplyNumGatherersChanged, { "to": this.GetNumGatherers() });
}
if (this.IsGatheringUs(gathererID))
return true;
this.gatherers.push(gathererID);
Engine.PostMessage(this.entity, MT_ResourceSupplyNumGatherersChanged, { "to": this.GetNumGatherers() });
return true;
};
/**
* @param {number} gathererID - The gatherer's entity id.
* @param {number} player - The gatherer's player id.
* @todo: Should this return false if the gatherer didn't gather from said resource?
*/
ResourceSupply.prototype.RemoveGatherer = function(gathererID, player)
ResourceSupply.prototype.RemoveGatherer = function(gathererID)
{
// This can happen if the unit is dead
if (player == undefined || player == INVALID_PLAYER)
{
for (let i = 0; i < this.gatherers.length; ++i)
this.RemoveGatherer(gathererID, i);
return;
}
let index = this.gatherers[player].indexOf(gathererID);
let index = this.gatherers.indexOf(gathererID);
if (index == -1)
return;
this.gatherers[player].splice(index, 1);
// Broadcast message, mainly useful for the AIs.
this.gatherers.splice(index, 1);
Engine.PostMessage(this.entity, MT_ResourceSupplyNumGatherersChanged, { "to": this.GetNumGatherers() });
};

View File

@ -2265,11 +2265,10 @@ UnitAI.prototype.UnitFsmSpec = {
this.gatheringTarget = this.order.data.target; // temporary, deleted in "leave".
// Check that we can gather from the resource we're supposed to gather from.
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
let cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage);
if ((!cmpMirage || !cmpMirage.Mirages(IID_ResourceSupply)) &&
(!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)) ||
(!cmpSupply || !cmpSupply.AddGatherer(this.entity)) ||
!this.MoveTo(this.order.data, IID_ResourceGatherer))
{
// If the target's last known position is in FOW, try going there
@ -2343,11 +2342,8 @@ UnitAI.prototype.UnitFsmSpec = {
// Check if the resource is full.
// Will only be added if we're not already in.
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
let cmpSupply;
if (cmpOwnership)
cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
if (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity))
let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
if (!cmpSupply || !cmpSupply.AddGatherer(this.entity))
{
this.SetNextState("FINDINGNEWTARGET");
return true;
@ -2414,10 +2410,6 @@ UnitAI.prototype.UnitFsmSpec = {
let resourceTemplate = this.order.data.template;
let resourceType = this.order.data.type;
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return;
// TODO: we are leaking information here - if the target died in FOW, we'll know it's dead
// straight away.
// Seems one would have to listen to ownership changed messages to make it work correctly
@ -2425,7 +2417,7 @@ UnitAI.prototype.UnitFsmSpec = {
let cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
// If we can't gather from the target, find a new one.
if (!cmpSupply || !cmpSupply.IsAvailable(cmpOwnership.GetOwner(), this.entity) ||
if (!cmpSupply || !cmpSupply.IsAvailableTo(this.entity) ||
!this.CanGather(this.gatheringTarget))
{
this.SetNextState("FINDINGNEWTARGET");
@ -4371,11 +4363,6 @@ UnitAI.prototype.FindNearbyResource = function(position, filter)
if (!position)
return undefined;
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership || cmpOwnership.GetOwner() == INVALID_PLAYER)
return undefined;
let owner = cmpOwnership.GetOwner();
// We accept resources owned by Gaia or any player
let players = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetAllPlayers();
@ -4396,7 +4383,7 @@ UnitAI.prototype.FindNearbyResource = function(position, filter)
if (template.indexOf("resource|") != -1)
template = template.slice(9);
return amount > 0 && cmpResourceSupply.IsAvailable(owner, this.entity) && filter(ent, type, template);
return amount > 0 && cmpResourceSupply.IsAvailableTo(this.entity) && filter(ent, type, template);
});
};

View File

@ -45,30 +45,30 @@ TS_ASSERT_EQUALS(cmpResourceSupply.GetDiminishingReturns(), null);
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 0);
TS_ASSERT(cmpResourceSupply.IsAvailable(1, 70));
TS_ASSERT(cmpResourceSupply.AddGatherer(1, 70));
TS_ASSERT(cmpResourceSupply.IsAvailableTo(70));
TS_ASSERT(cmpResourceSupply.AddGatherer(70));
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 1);
TS_ASSERT(cmpResourceSupply.AddGatherer(1, 71));
TS_ASSERT(cmpResourceSupply.AddGatherer(71));
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 2);
TS_ASSERT(!cmpResourceSupply.AddGatherer(2, 72));
TS_ASSERT(!cmpResourceSupply.AddGatherer(72));
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 2);
TS_ASSERT(cmpResourceSupply.IsAvailable(1, 70));
TS_ASSERT(!cmpResourceSupply.IsAvailable(1, 73));
TS_ASSERT(!cmpResourceSupply.AddGatherer(1, 73));
TS_ASSERT(cmpResourceSupply.IsAvailableTo(70));
TS_ASSERT(!cmpResourceSupply.IsAvailableTo(73));
TS_ASSERT(!cmpResourceSupply.AddGatherer(73));
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 2);
cmpResourceSupply.RemoveGatherer(70, 1);
cmpResourceSupply.RemoveGatherer(70);
TS_ASSERT_EQUALS(cmpResourceSupply.GetNumGatherers(), 1);
TS_ASSERT_UNEVAL_EQUALS(cmpResourceSupply.GetCurrentAmount(), 1000);
TS_ASSERT_UNEVAL_EQUALS(cmpResourceSupply.TakeResources(300), { "amount": 300, "exhausted": false });
TS_ASSERT_EQUALS(cmpResourceSupply.GetCurrentAmount(), 700);
TS_ASSERT(cmpResourceSupply.IsAvailable(1, 70));
TS_ASSERT(cmpResourceSupply.IsAvailableTo(70));
TS_ASSERT_UNEVAL_EQUALS(cmpResourceSupply.TakeResources(800), { "amount": 700, "exhausted": true });
TS_ASSERT_EQUALS(cmpResourceSupply.GetCurrentAmount(), 0);
// The resource is not available when exhausted
TS_ASSERT(!cmpResourceSupply.IsAvailable(1, 70));
TS_ASSERT(!cmpResourceSupply.IsAvailableTo(70));