Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/components/Garrisonable.js
Show All 39 Lines | |||||
* @return {number} - The entity ID of the entity this entity is garrisoned in. | * @return {number} - The entity ID of the entity this entity is garrisoned in. | ||||
*/ | */ | ||||
Garrisonable.prototype.HolderID = function() | Garrisonable.prototype.HolderID = function() | ||||
{ | { | ||||
return this.holder || INVALID_ENTITY; | return this.holder || INVALID_ENTITY; | ||||
}; | }; | ||||
/** | /** | ||||
* @param {number} - The entity ID to check. | |||||
* @return {boolean} - Whether we can garrison. | |||||
*/ | |||||
Garrisonable.prototype.CanGarrison = function(entity) | |||||
{ | |||||
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder); | |||||
return cmpGarrisonHolder && cmpGarrisonHolder.IsAllowedToGarrison(this.entity); | |||||
}; | |||||
/** | |||||
* @param {number} entity - The entity ID of the entity this entity is being garrisoned in. | * @param {number} entity - The entity ID of the entity this entity is being garrisoned in. | ||||
* @return {boolean} - Whether garrisoning succeeded. | * @return {boolean} - Whether garrisoning succeeded. | ||||
*/ | */ | ||||
Garrisonable.prototype.Garrison = function(entity) | Garrisonable.prototype.Garrison = function(entity, renamed = false) | ||||
{ | { | ||||
if (this.holder) | if (this.holder) | ||||
return false; | return false; | ||||
let cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder); | |||||
if (!cmpGarrisonHolder || !cmpGarrisonHolder.Garrison(this.entity, renamed)) | |||||
return false; | |||||
this.holder = entity; | this.holder = entity; | ||||
let cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); | let cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); | ||||
if (cmpProductionQueue) | if (cmpProductionQueue) | ||||
cmpProductionQueue.PauseProduction(); | cmpProductionQueue.PauseProduction(); | ||||
let cmpAura = Engine.QueryInterface(this.entity, IID_Auras); | let cmpAura = Engine.QueryInterface(this.entity, IID_Auras); | ||||
if (cmpAura && cmpAura.HasGarrisonAura()) | if (cmpAura && cmpAura.HasGarrisonAura()) | ||||
cmpAura.ApplyGarrisonAura(entity); | cmpAura.ApplyGarrisonAura(entity); | ||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
if (cmpPosition) | if (cmpPosition) | ||||
cmpPosition.MoveOutOfWorld(); | cmpPosition.MoveOutOfWorld(); | ||||
if (renamed) | |||||
return true; | |||||
let cmpTurretHolder = Engine.QueryInterface(entity, IID_TurretHolder); | |||||
if (cmpTurretHolder) | |||||
cmpTurretHolder.OccupyTurret(this.entity); | |||||
return true; | return true; | ||||
}; | }; | ||||
/** | /** | ||||
* Called on game init when the entity was part of init garrison. | |||||
* @param {number} entity - The entityID to autogarrison. | |||||
*/ | |||||
Garrisonable.prototype.Autogarrison = function(entity) | |||||
{ | |||||
if (!this.Garrison(entity)) | |||||
return; | |||||
let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); | |||||
if (cmpUnitAI) | |||||
cmpUnitAI.Autogarrison(this.entity); | |||||
}; | |||||
/** | |||||
* @param {boolean} forced - Optionally whether the spawning is forced. | * @param {boolean} forced - Optionally whether the spawning is forced. | ||||
* @param {boolean} renamed - Optionally whether the ungarrisoning is due to renaming. | |||||
* @return {boolean} - Whether the ungarrisoning succeeded. | * @return {boolean} - Whether the ungarrisoning succeeded. | ||||
*/ | */ | ||||
Garrisonable.prototype.UnGarrison = function(forced) | Garrisonable.prototype.UnGarrison = function(forced = false, renamed = false) | ||||
{ | { | ||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
if (cmpPosition) | if (cmpPosition) | ||||
{ | { | ||||
let pos; | let pos; | ||||
let cmpGarrisonHolder = Engine.QueryInterface(this.holder, IID_GarrisonHolder); | let cmpGarrisonHolder = Engine.QueryInterface(this.holder, IID_GarrisonHolder); | ||||
if (cmpGarrisonHolder) | if (cmpGarrisonHolder) | ||||
pos = cmpGarrisonHolder.GetSpawnPosition(this.entity, forced); | pos = cmpGarrisonHolder.GetSpawnPosition(this.entity, forced); | ||||
Show All 16 Lines | Garrisonable.prototype.UnGarrison = function(forced = false, renamed = false) | ||||
let cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); | let cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); | ||||
if (cmpProductionQueue) | if (cmpProductionQueue) | ||||
cmpProductionQueue.UnpauseProduction(); | cmpProductionQueue.UnpauseProduction(); | ||||
let cmpAura = Engine.QueryInterface(this.entity, IID_Auras); | let cmpAura = Engine.QueryInterface(this.entity, IID_Auras); | ||||
if (cmpAura && cmpAura.HasGarrisonAura()) | if (cmpAura && cmpAura.HasGarrisonAura()) | ||||
cmpAura.RemoveGarrisonAura(this.holder); | cmpAura.RemoveGarrisonAura(this.holder); | ||||
if (renamed) | |||||
return true; | |||||
let cmpTurretHolder = Engine.QueryInterface(this.holder, IID_TurretHolder); | |||||
if (cmpTurretHolder) | |||||
cmpTurretHolder.LeaveTurret(this.entity); | |||||
delete this.holder; | delete this.holder; | ||||
return true; | return true; | ||||
}; | }; | ||||
Garrisonable.prototype.OnEntityRenamed = function(msg) | |||||
{ | |||||
if (!this.holder) | |||||
return; | |||||
let cmpGarrisonHolder = Engine.QueryInterface(this.holder, IID_GarrisonHolder); | |||||
if (cmpGarrisonHolder) | |||||
{ | |||||
// ToDo: Clean this by using cmpGarrisonable to ungarrison. | |||||
cmpGarrisonHolder.Eject(msg.entity, true, true); | |||||
let cmpGarrisonable = Engine.QueryInterface(msg.newentity, IID_Garrisonable); | |||||
if (cmpGarrisonable) | |||||
cmpGarrisonable.Garrison(this.holder, true); | |||||
} | |||||
// We process EntityRenamed of turrets here because we need to be sure that we | |||||
wraitii: It's a bit inefficient to eject then re-garrison, to be honest. I wouldn't complain too much… | |||||
Done Inline ActionsWell, that basically boils down to ejecting and regarrisoning? Any of the prerequisites may have changed, so they all need to be checked. Freagarach: Well, that basically boils down to ejecting and regarrisoning? Any of the prerequisites may… | |||||
Done Inline ActionsYes but if you can skip calling Garrisonable.Ungarrison, you can remove the 'renamed' hack from there. Which I think would be good. wraitii: Yes but if you can skip calling `Garrisonable.Ungarrison`, you can remove the 'renamed' hack… | |||||
Done Inline ActionsBut you can't skip that? You need to update auras? Freagarach: But you can't skip that? You need to update auras? | |||||
Done Inline Actionsmh, isn't the garrison aura a property of the garrison holder rather than the garrisonable? wraitii: mh, isn't the garrison aura a property of the `garrison holder` rather than the `garrisonable`? | |||||
// receive it after it is processed by GarrisonHolder.js. | |||||
// ToDo: Make this not needed by fully separating TurretHolder from GarrisonHolder. | |||||
// That means an entity with TurretHolder should not need a GarrisonHolder | |||||
// for e.g. the garrisoning logic. | |||||
let cmpTurretHolder = Engine.QueryInterface(this.holder, IID_TurretHolder); | |||||
if (cmpTurretHolder) | |||||
cmpTurretHolder.SwapEntities(msg.entity, msg.newentity); | |||||
delete this.holder; | |||||
}; | |||||
Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable); | Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable); |
Wildfire Games · Phabricator
It's a bit inefficient to eject then re-garrison, to be honest. I wouldn't complain too much but renaming is already slow enough.
I think you should check if the new entity is garrison able, and if so implement a SwapEntities fast track that does only the necessary stuff.