mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-11-08 10:09:16 +00:00
Remove destroyed resources from the AI resource maps again
Sinced18a6392b3all resource maps were rebuilt whenever an entity in SharedScript.resources was destroyed. As every entity was listed there, not only resources, that happened on almost every turn and took most of the AI time in big games. Keep instead the influence of each resource on the maps, and subtract it when the resource is destroyed. Liked18a6392b3, this does not need entityObj.
This commit is contained in:
1 parent
88f5cbc922
commit
38c2e1a61e
1 file changed
+48
-20
@@ -127,7 +127,8 @@ export class SharedScript
|
||||
this.influenceRadius = { "abundant": 36, "sparse": 48 };
|
||||
this.ccInfluenceRadius = { "abundant": 60, "sparse": 120 };
|
||||
|
||||
this.resources = []; // Contains entityIds of all resources in the maps.
|
||||
// The influence of each resource on the resource maps, by entity id, to remove it when the resource is destroyed.
|
||||
this.resources = new Map();
|
||||
this.resourceMaps = {}; // Contains maps showing the density of resources
|
||||
this.ccResourceMaps = {}; // Contains maps showing the density of resources, optimized for CC placement.
|
||||
this.createResourceMaps();
|
||||
@@ -401,11 +402,13 @@ export class SharedScript
|
||||
*/
|
||||
updateResourceMaps(events)
|
||||
{
|
||||
if (events.Destroy.some(e => this.resources.includes(e.entity)))
|
||||
for (const e of events.Destroy)
|
||||
{
|
||||
this.resources = [];
|
||||
this.resourceMaps = {};
|
||||
this.createResourceMaps();
|
||||
const influence = this.resources.get(e.entity);
|
||||
if (!influence)
|
||||
continue;
|
||||
this.applyResourceInfluence(influence, -1);
|
||||
this.resources.delete(e.entity);
|
||||
}
|
||||
|
||||
for (const e of events.Create)
|
||||
@@ -418,8 +421,13 @@ export class SharedScript
|
||||
*/
|
||||
addEntityToResourceMap(entity)
|
||||
{
|
||||
this.changeEntityInResourceMapHelper(entity, 1);
|
||||
this.resources.push(entity.id());
|
||||
if (this.resources.has(entity.id()))
|
||||
return;
|
||||
const influence = this.getResourceInfluence(entity);
|
||||
if (!influence)
|
||||
return;
|
||||
this.applyResourceInfluence(influence, 1);
|
||||
this.resources.set(entity.id(), influence);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,29 +435,49 @@ export class SharedScript
|
||||
*/
|
||||
removeEntityFromResourceMap(entity)
|
||||
{
|
||||
this.changeEntityInResourceMapHelper(entity, -1);
|
||||
const influence = this.resources.get(entity.id());
|
||||
if (!influence)
|
||||
return;
|
||||
this.applyResourceInfluence(influence, -1);
|
||||
this.resources.delete(entity.id());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {entity} ent - The entity to add to the resource map.
|
||||
* @param {entity} ent - A resource.
|
||||
* @return {Object|undefined} - The influence of the resource on the resource maps, as
|
||||
* { "resource", "x", "y", "strength" }, or undefined if it has none.
|
||||
*/
|
||||
changeEntityInResourceMapHelper(ent, multiplication = 1)
|
||||
getResourceInfluence(ent)
|
||||
{
|
||||
if (!ent)
|
||||
return;
|
||||
return undefined;
|
||||
const entPos = ent.position();
|
||||
if (!entPos)
|
||||
return;
|
||||
return undefined;
|
||||
const resource = ent.resourceSupplyType()?.generic;
|
||||
if (!resource || !this.resourceMaps[resource])
|
||||
return;
|
||||
const cellSize = this.resourceMaps[resource].cellSize;
|
||||
const x = Math.floor(entPos[0] / cellSize);
|
||||
const y = Math.floor(entPos[1] / cellSize);
|
||||
return undefined;
|
||||
const [x, y] = this.resourceMaps[resource].gamePosToMapPos(entPos);
|
||||
const grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup;
|
||||
const strength = multiplication * ent.resourceSupplyMax() / this.normalizationFactor[grp];
|
||||
this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, strength / 2, "constant");
|
||||
this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, strength / 2);
|
||||
this.ccResourceMaps[resource].addInfluence(x, y, this.ccInfluenceRadius[grp] / cellSize, strength, "constant");
|
||||
return {
|
||||
"resource": resource,
|
||||
"x": x,
|
||||
"y": y,
|
||||
"strength": ent.resourceSupplyMax() / this.normalizationFactor[grp]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add (multiplication 1) or remove (-1) the influence of a resource on the resource maps.
|
||||
* @param {Object} influence - As returned by getResourceInfluence.
|
||||
*/
|
||||
applyResourceInfluence({ resource, x, y, strength }, multiplication)
|
||||
{
|
||||
const cellSize = this.resourceMaps[resource].cellSize;
|
||||
const grp = Resources.GetResource(resource).aiAnalysisInfluenceGroup;
|
||||
const amount = multiplication * strength;
|
||||
this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, amount / 2, "constant");
|
||||
this.resourceMaps[resource].addInfluence(x, y, this.influenceRadius[grp] / cellSize, amount / 2);
|
||||
this.ccResourceMaps[resource].addInfluence(x, y, this.ccInfluenceRadius[grp] / cellSize, amount, "constant");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user