Fix arrow count not being properly calculated when autogarrisoning.
423b3cbcaa
Moved the message sent that an entity garrisons from `PerformGarrison` to `Garrison`. However, when an entity is autogarrisoned from `ProductionQueue` `PerformGarrison` is called thus not triggering the message. When ejecting the entity from the structure there is a message sent that the entity is removed, thus allowing for a negative amount of archers/arrows in `BuildingAI` (see 423b3cbcaa#42654). Note that `PerformGarrison` was explicitly split in2102648f7c
when introducing autogarrisoning. It probably has something to do with the position, since that was split. But I couldn't find any reason why it cannot be used now. A side effect of this is that when autogarrisoning an entity with visible garrison points those will be occupied as well now. Reviewed By: wraitii Differential Revision: https://code.wildfiregames.com/D2790 This was SVN commit r23743.
This commit is contained in:
parent
4588ee3bbc
commit
759bc754c3
@ -173,20 +173,27 @@ GarrisonHolder.prototype.GetGarrisonedEntitiesCount = function()
|
||||
return count;
|
||||
};
|
||||
|
||||
GarrisonHolder.prototype.IsAllowedToGarrison = function(ent)
|
||||
GarrisonHolder.prototype.IsAllowedToGarrison = function(entity)
|
||||
{
|
||||
if (!this.IsGarrisoningAllowed())
|
||||
return false;
|
||||
|
||||
if (!IsOwnedByMutualAllyOfEntity(ent, this.entity))
|
||||
if (!IsOwnedByMutualAllyOfEntity(entity, this.entity))
|
||||
return false;
|
||||
|
||||
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||
let extraCount = 0;
|
||||
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
|
||||
if (cmpGarrisonHolder)
|
||||
extraCount += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
|
||||
if (this.GetGarrisonedEntitiesCount() + extraCount >= this.GetCapacity())
|
||||
return false;
|
||||
|
||||
let cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
|
||||
if (!cmpIdentity)
|
||||
return false;
|
||||
|
||||
let entityClasses = cmpIdentity.GetClassesList();
|
||||
return MatchesClassList(entityClasses, this.template.List._string) && !!Engine.QueryInterface(ent, IID_Garrisonable);
|
||||
return MatchesClassList(entityClasses, this.template.List._string) && !!Engine.QueryInterface(entity, IID_Garrisonable);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -214,12 +221,31 @@ GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(entity, visibleG
|
||||
*/
|
||||
GarrisonHolder.prototype.Garrison = function(entity, vgpEntity)
|
||||
{
|
||||
if (!this.IsAllowedToGarrison(entity))
|
||||
return false;
|
||||
|
||||
if (!this.HasEnoughHealth())
|
||||
return false;
|
||||
|
||||
let cmpPosition = Engine.QueryInterface(entity, IID_Position);
|
||||
if (!cmpPosition)
|
||||
return false;
|
||||
|
||||
if (!this.PerformGarrison(entity))
|
||||
return false;
|
||||
if (!this.timer && this.GetHealRate() > 0)
|
||||
{
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
|
||||
}
|
||||
|
||||
this.entities.push(entity);
|
||||
this.UpdateGarrisonFlag();
|
||||
let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
|
||||
if (cmpProductionQueue)
|
||||
cmpProductionQueue.PauseProduction();
|
||||
|
||||
let cmpAura = Engine.QueryInterface(entity, IID_Auras);
|
||||
if (cmpAura && cmpAura.HasGarrisonAura())
|
||||
cmpAura.ApplyGarrisonAura(this.entity);
|
||||
|
||||
let visibleGarrisonPoint;
|
||||
if (vgpEntity && this.AllowedToVisibleGarrisoning(entity, vgpEntity))
|
||||
@ -273,46 +299,6 @@ GarrisonHolder.prototype.Garrison = function(entity, vgpEntity)
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the entity was garrisonned.
|
||||
*/
|
||||
GarrisonHolder.prototype.PerformGarrison = function(entity)
|
||||
{
|
||||
if (!this.HasEnoughHealth())
|
||||
return false;
|
||||
|
||||
// Check if the unit is allowed to be garrisoned inside the building
|
||||
if (!this.IsAllowedToGarrison(entity))
|
||||
return false;
|
||||
|
||||
// Check the capacity
|
||||
let extraCount = 0;
|
||||
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
|
||||
if (cmpGarrisonHolder)
|
||||
extraCount += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
|
||||
if (this.GetGarrisonedEntitiesCount() + extraCount >= this.GetCapacity())
|
||||
return false;
|
||||
|
||||
if (!this.timer && this.GetHealRate() > 0)
|
||||
{
|
||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
|
||||
}
|
||||
|
||||
// Actual garrisoning happens here
|
||||
this.entities.push(entity);
|
||||
this.UpdateGarrisonFlag();
|
||||
let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
|
||||
if (cmpProductionQueue)
|
||||
cmpProductionQueue.PauseProduction();
|
||||
|
||||
let cmpAura = Engine.QueryInterface(entity, IID_Auras);
|
||||
if (cmpAura && cmpAura.HasGarrisonAura())
|
||||
cmpAura.ApplyGarrisonAura(this.entity);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simply eject the unit from the garrisoning entity without moving it
|
||||
* @param {number} entity - Id of the entity to be ejected.
|
||||
|
@ -626,7 +626,7 @@ ProductionQueue.prototype.SpawnUnits = function(templateName, count, metadata)
|
||||
{
|
||||
// Temporary owner affectation needed for GarrisonHolder checks.
|
||||
cmpNewOwnership.SetOwnerQuiet(cmpOwnership.GetOwner());
|
||||
garrisoned = cmpAutoGarrison.PerformGarrison(ent);
|
||||
garrisoned = cmpAutoGarrison.Garrison(ent);
|
||||
cmpNewOwnership.SetOwnerQuiet(INVALID_PLAYER);
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ TS_ASSERT_EQUALS(cmpGarrisonHolder.IsFull(), false);
|
||||
TS_ASSERT_EQUALS(cmpGarrisonHolder.IsAllowedToGarrison(enemyUnitId), false);
|
||||
TS_ASSERT_EQUALS(cmpGarrisonHolder.IsAllowedToGarrison(unitToGarrisonId), true);
|
||||
TS_ASSERT_EQUALS(cmpGarrisonHolder.HasEnoughHealth(), false);
|
||||
TS_ASSERT_EQUALS(cmpGarrisonHolder.PerformGarrison(unitToGarrisonId), false);
|
||||
TS_ASSERT_EQUALS(cmpGarrisonHolder.Garrison(unitToGarrisonId), false);
|
||||
|
||||
AddMock(garrisonHolderId, IID_Health, {
|
||||
"GetHitpoints": () => 600,
|
||||
|
Loading…
Reference in New Issue
Block a user