1
0
forked from 0ad/0ad

Store the garrisonHolder in cmpGarrisonable instead of iterating orders.

Refs. f6c9db33d6, 4fadd75ace
Differential revision: D2376
Comments by: @elexis, @Stan, @wraitii
This was SVN commit r24502.
This commit is contained in:
Freagarach 2021-01-02 07:34:52 +00:00
parent 32583008a0
commit 3851a48298
9 changed files with 81 additions and 23 deletions

View File

@ -409,14 +409,14 @@ function updatePlayerData()
}
/**
* Returns the entity itself except when garrisoned where it returns its garrisonHolder
* @param {number} ent - The entity to get its ID for.
* @return {number} - The entity ID of the entity or of its garrisonHolder.
*/
function getEntityOrHolder(ent)
{
let entState = GetEntityState(ent);
if (entState && !entState.position && entState.unitAI && entState.unitAI.orders.length &&
entState.unitAI.orders[0].type == "Garrison")
return getEntityOrHolder(entState.unitAI.orders[0].data.target);
if (entState && !entState.position && entState.garrisonable && entState.garrisonable.holder != INVALID_ENTITY)
return getEntityOrHolder(entState.garrisonable.holder);
return ent;
}

View File

@ -697,7 +697,7 @@ var g_UnitActions =
},
"getActionInfo": function(entState, targetState)
{
if (!entState.canGarrison || !targetState || !targetState.garrisonHolder ||
if (!entState.garrisonable || !targetState || !targetState.garrisonHolder ||
!playerCheck(entState, targetState, ["Player", "MutualAlly"]))
return false;

View File

@ -150,11 +150,7 @@ GarrisonHolder.prototype.IsAllowedToGarrison = function(entity)
return false;
let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
if (!cmpIdentity)
return false;
let entityClasses = cmpIdentity.GetClassesList();
return MatchesClassList(entityClasses, this.allowedClasses) && !!Engine.QueryInterface(entity, IID_Garrisonable);
return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), this.allowedClasses);
};
/**
@ -171,6 +167,10 @@ GarrisonHolder.prototype.Garrison = function(entity, renamed = false)
if (!this.HasEnoughHealth())
return false;
let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable);
if (!cmpGarrisonable || !cmpGarrisonable.Garrison(this.entity))
return false;
if (!this.timer && this.GetHealRate() > 0)
{
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
@ -264,6 +264,10 @@ GarrisonHolder.prototype.Eject = function(entity, forced, renamed = false)
cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos));
}
let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable);
if (cmpGarrisonable)
cmpGarrisonable.UnGarrison();
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
"added": [],
"removed": [entity],

View File

@ -6,6 +6,33 @@ Garrisonable.prototype.Init = function()
{
};
Garrisonable.prototype.Serialize = null;
/**
* @return {number} - The entity ID of the entity this entity is garrisoned in.
*/
Garrisonable.prototype.HolderID = function()
{
return this.holder || INVALID_ENTITY;
};
/**
* @param {number} entity - The entity ID of the entity this entity is being garrisoned in.
* @return {boolean} - Whether garrisoning succeeded.
*/
Garrisonable.prototype.Garrison = function(entity)
{
if (this.holder)
return false;
this.holder = entity;
return true;
};
/**
* Resets the garrisonHolder.
*/
Garrisonable.prototype.UnGarrison = function()
{
delete this.holder;
};
Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable);

View File

@ -377,7 +377,11 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
"turretPoints": cmpTurretHolder.GetTurretPoints()
};
ret.canGarrison = !!Engine.QueryInterface(ent, IID_Garrisonable);
let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable);
if (cmpGarrisonable)
ret.garrisonable = {
"holder": cmpGarrisonable.HolderID()
};
let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
if (cmpUnitAI)

View File

@ -3517,13 +3517,11 @@ UnitAI.prototype.SetGarrisoned = function()
UnitAI.prototype.GetGarrisonHolder = function()
{
if (this.IsGarrisoned())
{
for (let order of this.orderQueue)
if (order.type == "Garrison")
return order.data.target;
}
return INVALID_ENTITY;
if (!this.isGarrisoned)
return INVALID_ENTITY;
let cmpGarrisonable = Engine.QueryInterface(this.entity, IID_Garrisonable);
return cmpGarrisonable ? cmpGarrisonable.HolderID() : INVALID_ENTITY;
};
UnitAI.prototype.ShouldRespondToEndOfAlert = function()

View File

@ -68,7 +68,10 @@ for (let i = 24; i <= 34; ++i)
"GetOwner": () => friendlyPlayer
});
AddMock(i, IID_Garrisonable, {});
AddMock(i, IID_Garrisonable, {
"Garrison": entity => true,
"UnGarrison": () => {}
});
AddMock(i, IID_Position, {
"GetHeightOffset": () => 0,
@ -212,7 +215,10 @@ let currentSiegePlayer = player;
AddMock(siegeEngineId, IID_Ownership, {
"GetOwner": () => currentSiegePlayer
});
AddMock(siegeEngineId, IID_Garrisonable, {});
AddMock(siegeEngineId, IID_Garrisonable, {
"Garrison": entity => true,
"UnGarrison": () => {}
});
let cavalryId = 46;
AddMock(cavalryId, IID_Identity, {
"GetClassesList": () => ["Infantry", "Ranged"]
@ -230,7 +236,10 @@ let currentCavalryPlayer = player;
AddMock(cavalryId, IID_Ownership, {
"GetOwner": () => currentCavalryPlayer
});
AddMock(cavalryId, IID_Garrisonable, {});
AddMock(cavalryId, IID_Garrisonable, {
"Garrison": entity => true,
"UnGarrison": () => {}
});
TS_ASSERT(cmpGarrisonHolder.Garrison(siegeEngineId));
TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 1);
cmpGarrisonHolder.OnGlobalEntityRenamed({

View File

@ -0,0 +1,17 @@
Engine.LoadComponentScript("interfaces/Garrisonable.js");
Engine.LoadComponentScript("Garrisonable.js");
const garrisonHolderID = 1;
const garrisonableID = 2;
let cmpGarrisonable = ConstructComponent(garrisonableID, "Garrisonable", {
});
TS_ASSERT(cmpGarrisonable.Garrison(garrisonHolderID));
TS_ASSERT_UNEVAL_EQUALS(cmpGarrisonable.HolderID(), garrisonHolderID);
TS_ASSERT(!cmpGarrisonable.Garrison(garrisonHolderID));
TS_ASSERT_UNEVAL_EQUALS(cmpGarrisonable.HolderID(), garrisonHolderID);
cmpGarrisonable.UnGarrison();
TS_ASSERT_UNEVAL_EQUALS(cmpGarrisonable.HolderID(), INVALID_ENTITY);

View File

@ -603,7 +603,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetEntityState(-1, 10), {
"needsRepair": false,
"needsHeal": true,
"builder": true,
"canGarrison": false,
"visibility": "visible",
"isBarterMarket": true,
"resourceTrickle": {