Changeset View
Standalone View
binaries/data/mods/public/simulation/components/GarrisonHolder.js
function GarrisonHolder() {} | function GarrisonHolder() {} | ||||
GarrisonHolder.prototype.Schema = | GarrisonHolder.prototype.Schema = | ||||
"<element name='Max' a:help='Maximum number of entities which can be garrisoned inside this holder'>" + | "<element name='Max' a:help='Maximum number of entities which can be garrisoned inside this holder'>" + | ||||
"<data type='positiveInteger'/>" + | "<data type='positiveInteger'/>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='List' a:help='Classes of entities which are allowed to garrison inside this holder (from Identity)'>" + | "<element name='List' a:help='Classes of entities which are allowed to garrison inside this holder (from Identity)'>" + | ||||
elexis: -inside? | |||||
"<attribute name='datatype'>" + | "<attribute name='datatype'>" + | ||||
"<value>tokens</value>" + | "<value>tokens</value>" + | ||||
"</attribute>" + | "</attribute>" + | ||||
"<text/>" + | "<text/>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='EjectHealth' a:help='Percentage of maximum health below which this holder no longer allows garrisoning'>" + | "<element name='EjectHealth' a:help='Percentage of maximum health below which this holder no longer allows garrisoning'>" + | ||||
"<ref name='nonNegativeDecimal'/>" + | "<ref name='nonNegativeDecimal'/>" + | ||||
"</element>" + | "</element>" + | ||||
Show All 25 Lines | "<element name='VisibleGarrisonPoints' a:help='Points that will be used to visibly garrison a unit'>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='Y'>" + | "<element name='Y'>" + | ||||
"<data type='decimal'/>" + | "<data type='decimal'/>" + | ||||
"</element>" + | "</element>" + | ||||
"<element name='Z'>" + | "<element name='Z'>" + | ||||
"<data type='decimal'/>" + | "<data type='decimal'/>" + | ||||
"</element>" + | "</element>" + | ||||
"<optional>" + | "<optional>" + | ||||
"<element name='AllowedClasses'>" + | |||||
"<attribute name='datatype'>" + | |||||
"<value>tokens</value>" + | |||||
"</attribute>" + | |||||
"<text/>" + | |||||
"</element>" + | |||||
"</optional>"+ | |||||
"<optional>" + | |||||
"<element name='Angle' a:help='Angle in degrees relative to the garrisonHolder direction'>" + | "<element name='Angle' a:help='Angle in degrees relative to the garrisonHolder direction'>" + | ||||
Done Inline ActionsJust AllowedClasses would suffice? Freagarach: Just `AllowedClasses` would suffice? | |||||
Done Inline ActionsI guess. Stan: I guess. | |||||
Done Inline Actionshelp text should be added and state that if not present, default x+y will be used Silier: help text should be added and state that if not present, default x+y will be used | |||||
Done Inline Actionswill they ? Silier: will they ?
you default to "Infantry+Ranged" at L90 | |||||
Done Inline ActionsFrom https://code.wildfiregames.com/D2308#111472
(also will be used is ambiguous, used for what?)
elexis: From https://code.wildfiregames.com/D2308#111472
> should that description be the following?
>>… | |||||
"<data type='decimal'/>" + | "<data type='decimal'/>" + | ||||
"</element>" + | "</element>" + | ||||
"</optional>" + | "</optional>" + | ||||
"</interleave>" + | "</interleave>" + | ||||
"</element>" + | "</element>" + | ||||
"</zeroOrMore>" + | "</zeroOrMore>" + | ||||
"</element>" + | "</element>" + | ||||
"</optional>"; | "</optional>"; | ||||
/** | /** | ||||
* Initialize GarrisonHolder Component | * Initialize GarrisonHolder Component | ||||
* Garrisoning when loading a map is set in the script of the map, by setting initGarrison | * Garrisoning when loading a map is set in the script of the map, by setting initGarrison | ||||
* which should contain the array of garrisoned entities. | * which should contain the array of garrisoned entities. | ||||
*/ | */ | ||||
GarrisonHolder.prototype.Init = function() | GarrisonHolder.prototype.Init = function() | ||||
{ | { | ||||
// Garrisoned Units | // Garrisoned Units | ||||
this.entities = []; | this.entities = []; | ||||
this.timer = undefined; | this.timer = undefined; | ||||
this.allowGarrisoning = new Map(); | this.allowGarrisoning = new Map(); | ||||
this.visibleGarrisonPoints = []; | this.visibleGarrisonPoints = []; | ||||
if (this.template.VisibleGarrisonPoints) | if (!this.template.VisibleGarrisonPoints) | ||||
Done Inline ActionsWhy within the offset? (Besides you forgot to change the VisibleGarrisonAllowedClasses here.) Freagarach: Why within the offset? (Besides you forgot to change the `VisibleGarrisonAllowedClasses` here.)… | |||||
{ | return; | ||||
let points = this.template.VisibleGarrisonPoints; | let points = this.template.VisibleGarrisonPoints; | ||||
for (let point in points) | for (let point in points) | ||||
this.visibleGarrisonPoints.push({ | this.visibleGarrisonPoints.push({ | ||||
"offset": { | "offset": { | ||||
"x": +points[point].X, | "x": +points[point].X, | ||||
"y": +points[point].Y, | "y": +points[point].Y, | ||||
"z": +points[point].Z | "z": +points[point].Z, | ||||
Done Inline Actions-, Freagarach: -`,` | |||||
}, | }, | ||||
"allowedClasses": points[point].AllowedClasses ? points[point].AllowedClasses : { "_string": "Infantry+Ranged" }, | |||||
Done Inline Actions"allowedClasses": points[point].AllowedClasses || "Infantry+Ranged", Freagarach: `"allowedClasses": points[point].AllowedClasses || "Infantry+Ranged",` | |||||
Done Inline ActionsThen ._string wouldn't work would it ? Stan: Then ._string wouldn't work would it ?
"allowedClasses": points[point].AllowedClasses || {… | |||||
Done Inline ActionsWell, I tested my solution and it works? I get no warnings and everything behaves as it should? I agree that as is now is strange ;) Freagarach: Well, I tested my solution and it works? I get no warnings and everything behaves as it should? | |||||
Done Inline ActionsThere is no actually ^^ It doesn't comme to my mind because the coalesce operator is ?? in C# Stan: There is no actually ^^ It doesn't comme to my mind because the coalesce operator is ?? in C# | |||||
Done Inline ActionsThe componetn should be agnostic of identity classes (Infantry+Ranged), make it a error if the template doesn't specify one and manifest it in the schema elexis: The componetn should be agnostic of identity classes (Infantry+Ranged), make it a error if the… | |||||
Done Inline ActionsAgreed. I think it makes more sense to fallback to everything allowed to garrison by default. Hence the last change just right before your comment :) Stan: Agreed. I think it makes more sense to fallback to everything allowed to garrison by default. | |||||
"angle": points[point].Angle ? +points[point].Angle * Math.PI / 180 : null, | "angle": points[point].Angle ? +points[point].Angle * Math.PI / 180 : null, | ||||
"entity": null | "entity": null | ||||
}); | }); | ||||
} | |||||
}; | }; | ||||
/** | /** | ||||
* @return {Object} max and min range at which entities can garrison the holder. | * @return {Object} max and min range at which entities can garrison the holder. | ||||
*/ | */ | ||||
GarrisonHolder.prototype.GetLoadingRange = function() | GarrisonHolder.prototype.GetLoadingRange = function() | ||||
{ | { | ||||
return { "max": +this.template.LoadingRange, "min": 0 }; | return { "max": +this.template.LoadingRange, "min": 0 }; | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | GarrisonHolder.prototype.IsAllowedToGarrison = function(ent) | ||||
if (!cmpIdentity) | if (!cmpIdentity) | ||||
return false; | return false; | ||||
let entityClasses = cmpIdentity.GetClassesList(); | 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(ent, IID_Garrisonable); | ||||
}; | }; | ||||
/** | /** | ||||
* @param {number} entity - The entity's id. | |||||
Done Inline Actions.. Freagarach: `.`. | |||||
* @param {Object} visibleGarrisonPoint - The vgp object | |||||
* @return {boolean} true if the unit is allowed be visible on that garrison point, false otherwise. | |||||
Done Inline ActionsGetAllowedVisibleClasses perhaps? Freagarach: `GetAllowedVisibleClasses` perhaps? | |||||
*/ | |||||
GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(entity, visibleGarrisonPoint) | |||||
{ | |||||
let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); | |||||
if (!cmpIdentity) | |||||
return false; | |||||
Done Inline Actions@param @return ? Freagarach: ```
@param
@return
```
? | |||||
return MatchesClassList(cmpIdentity.GetClassesList(), visibleGarrisonPoint ? visibleGarrisonPoint.allowedClasses._string : ""); | |||||
Done Inline ActionsNot sure why, but I would switch the two parameters. Freagarach: Not sure why, but I would switch the two parameters. | |||||
Done Inline ActionsMakes sense actually. Stan: Makes sense actually. | |||||
}; | |||||
Done Inline ActionsCheck for cmpIdentity first? Freagarach: Check for `cmpIdentity` first? | |||||
/** | |||||
* Garrison a unit inside. The timer for AutoHeal is started here. | * Garrison a unit inside. The timer for AutoHeal is started here. | ||||
* @param {number} vgpEntity - The visual garrison point that will be used. | * @param {number} vgpEntity - The visual garrison point that will be used. | ||||
Done Inline Actionsits not an object if it's falsy elexis: its not an object if it's falsy | |||||
Done Inline Actions+. Freagarach: +`.` | |||||
* If vgpEntity is given, this visualGarrisonPoint will be used for the entity. | * If vgpEntity is given, this visualGarrisonPoint will be used for the entity. | ||||
Done Inline Actions- between type and comment? Freagarach: `-` between type and comment? | |||||
* @return {boolean} Whether the entity was garrisonned. | * @return {boolean} Whether the entity was garrisoned. | ||||
Done Inline Actions-n. Freagarach: -`n`. | |||||
Done Inline ActionsYou've got a - between the type and description above. Freagarach: You've got a `-` between the type and description above. | |||||
*/ | */ | ||||
GarrisonHolder.prototype.Garrison = function(entity, vgpEntity) | GarrisonHolder.prototype.Garrison = function(entity, vgpEntity) | ||||
{ | { | ||||
let cmpPosition = Engine.QueryInterface(entity, IID_Position); | let cmpPosition = Engine.QueryInterface(entity, IID_Position); | ||||
if (!cmpPosition) | if (!cmpPosition) | ||||
return false; | return false; | ||||
Done Inline ActionsIf there is no visibleGarrisonPoint given, it will try to match to "", with will return false always, IIRC. Freagarach: If there is no `visibleGarrisonPoint` given, it will try to match to `""`, with will return… | |||||
Done Inline ActionsIt's not a fallback, since template.List is checked also in the case allowedClasses are specified. elexis: It's not a fallback, since template.List is checked also in the case allowedClasses are… | |||||
if (!this.PerformGarrison(entity)) | if (!this.PerformGarrison(entity)) | ||||
Done Inline ActionsYou call MT_GarrisonedUnitsChanged in here with visible[entity] = false Silier: You call MT_GarrisonedUnitsChanged in here with visible[entity] = false | |||||
return false; | return false; | ||||
let visibleGarrisonPoint = vgpEntity; | let visibleGarrisonPoint = vgpEntity; | ||||
if (!vgpEntity || !this.AllowedToVisibleGarrisoning(entity, vgpEntity)) | |||||
Done Inline ActionsvgpEntity -> visibleGarrisonPoint !visibleGarrisonPoint -> visibleGarrisonPoint = undefined this is not needed to do Silier: vgpEntity -> visibleGarrisonPoint
`!visibleGarrisonPoint` -> `visibleGarrisonPoint =… | |||||
Done Inline Actions!!vgpEntity -> vgpEntity elexis: !!vgpEntity -> vgpEntity | |||||
Done Inline Actions!! unneeded elexis: !! unneeded | |||||
visibleGarrisonPoint = undefined; | |||||
Done Inline Actionsreturn cmpIdentity && ...? Freagarach: `return cmpIdentity && ...`? | |||||
if (!visibleGarrisonPoint) | if (!visibleGarrisonPoint) | ||||
Done Inline ActionsPerhaps: let visibleGarrisonPoint; if (vgpEntity && this.AllowedToVisibleGarrisoning(entity, vgpEntity)) visibleGarrisonPoint = vgpEntity; Seems more logical than first setting, then resetting. Freagarach: Perhaps:
```lang="js"
let visibleGarrisonPoint;
if (vgpEntity && this. | |||||
for (let vgp of this.visibleGarrisonPoints) | this.visibleGarrisonPoints.find(vgp => !vgp.entity && this.AllowedToVisibleGarrisoning(entity, vgp)); | ||||
Done Inline ActionsNot necessary? Freagarach: Not necessary? | |||||
FreagarachUnsubmitted Done Inline ActionsYou forgot something here ;) Freagarach: You forgot something here ;) | |||||
{ | |||||
if (vgp.entity) | |||||
continue; | |||||
visibleGarrisonPoint = vgp; | |||||
break; | |||||
} | |||||
Done Inline ActionsCan be merged with the above? Freagarach: Can be merged with the above? | |||||
if (visibleGarrisonPoint) | if (visibleGarrisonPoint) | ||||
Done Inline Actionsthis.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity) looks redudant considering L230, I would move it before L224 and if false, make visibleGarrisonPoint invalid to find new Silier: this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity) looks redudant considering L230… | |||||
{ | { | ||||
visibleGarrisonPoint.entity = entity; | visibleGarrisonPoint.entity = entity; | ||||
// Angle of turrets: | // Angle of turrets: | ||||
// Renamed entities (vgpEntity != undefined) should keep their angle. | // Renamed entities (vgpEntity != undefined) should keep their angle. | ||||
// Otherwise if an angle is given in the visibleGarrisonPoint, use it. | // Otherwise if an angle is given in the visibleGarrisonPoint, use it. | ||||
// If no such angle given (usually walls for which outside/inside not well defined), we keep | // If no such angle given (usually walls for which outside/inside not well defined), we keep | ||||
// the current angle as it was used for garrisoning and thus quite often was from inside to | // the current angle as it was used for garrisoning and thus quite often was from inside to | ||||
// outside, except when garrisoning from outWorld where we take as default PI. | // outside, except when garrisoning from outWorld where we take as default PI. | ||||
let cmpTurretPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpTurretPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
if (!vgpEntity && visibleGarrisonPoint.angle != null) | if (!vgpEntity && visibleGarrisonPoint.angle != null) | ||||
cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + visibleGarrisonPoint.angle); | cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + visibleGarrisonPoint.angle); | ||||
else if (!vgpEntity && !cmpPosition.IsInWorld()) | else if (!vgpEntity && !cmpPosition.IsInWorld()) | ||||
cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + Math.PI); | cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + Math.PI); | ||||
let cmpUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); | let cmpUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); | ||||
if (cmpUnitMotion) | if (cmpUnitMotion) | ||||
cmpUnitMotion.SetFacePointAfterMove(false); | cmpUnitMotion.SetFacePointAfterMove(false); | ||||
cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); | cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); | ||||
let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); | let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); | ||||
if (cmpUnitAI) | if (cmpUnitAI) | ||||
cmpUnitAI.SetTurretStance(); | cmpUnitAI.SetTurretStance(); | ||||
} | } | ||||
else | else | ||||
cmpPosition.MoveOutOfWorld(); | cmpPosition.MoveOutOfWorld(); | ||||
// Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet. | |||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { | |||||
Done Inline ActionsInline below? Freagarach: Inline below? | |||||
Done Inline ActionsDon't think that's possible: Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [entity], "removed": [], "visible": { entity: this.IsVisiblyGarrisoned(entity) // Looks broken. } }); Stan: Don't think that's possible:
```lang=js
Engine.PostMessage(this.entity… | |||||
Done Inline Actions"visible": { [entity]: this.IsVisiblyGarrisoned(entity) } ? (https://stackoverflow.com/questions/11508463/javascript-set-object-key-by-variable#11508490) Freagarach: ```
"visible": {
[entity]: this.IsVisiblyGarrisoned(entity)
}
```
? (https://stackoverflow. | |||||
Done Inline ActionsFunction calls (even member ones) are slower than calling the thing directly. Which is why I nuked the function above :) Stan: Function calls (even member ones) are slower than calling the thing directly. Which is why I… | |||||
"added": [entity], | |||||
"removed": [], | |||||
"visible": { | |||||
[entity] : this.IsVisiblyGarrisoned(entity), | |||||
Done Inline ActionsOne could make this (whether it was garrisoned visibly) a variable (around L230) and save a function call here, but is not necessary I guess. Freagarach: One could make this (whether it was garrisoned visibly) a variable (around L230) and save a… | |||||
} | |||||
Done Inline Actionsbut here it is visible[entity] = true, and also you are adding that entity twice refering to L220 Silier: but here it is visible[entity] = true, and also you are adding that entity twice refering to… | |||||
}); | |||||
Done Inline Actions\n? Freagarach: `\n`? | |||||
return true; | return true; | ||||
}; | }; | ||||
/** | /** | ||||
* @return {boolean} Whether the entity was garrisonned. | * @return {boolean} Whether the entity was garrisonned. | ||||
*/ | */ | ||||
GarrisonHolder.prototype.PerformGarrison = function(entity) | GarrisonHolder.prototype.PerformGarrison = function(entity) | ||||
{ | { | ||||
Show All 24 Lines | GarrisonHolder.prototype.PerformGarrison = function(entity) | ||||
let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue); | let cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue); | ||||
if (cmpProductionQueue) | if (cmpProductionQueue) | ||||
cmpProductionQueue.PauseProduction(); | cmpProductionQueue.PauseProduction(); | ||||
let cmpAura = Engine.QueryInterface(entity, IID_Auras); | let cmpAura = Engine.QueryInterface(entity, IID_Auras); | ||||
if (cmpAura && cmpAura.HasGarrisonAura()) | if (cmpAura && cmpAura.HasGarrisonAura()) | ||||
cmpAura.ApplyGarrisonAura(this.entity); | cmpAura.ApplyGarrisonAura(this.entity); | ||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [entity], "removed": [] }); | |||||
return true; | return true; | ||||
Done Inline Actionsas mentioned before, this will be always false before entity is does not have its spot yet Silier: as mentioned before, this will be always false before entity is does not have its spot yet | |||||
}; | }; | ||||
/** | /** | ||||
* Simply eject the unit from the garrisoning entity without moving it | * Simply eject the unit from the garrisoning entity without moving it | ||||
* @param {number} entity - Id of the entity to be ejected. | * @param {number} entity - Id of the entity to be ejected. | ||||
* @param {boolean} forced - Whether eject is forced (i.e. if building is destroyed). | * @param {boolean} forced - Whether eject is forced (i.e. if building is destroyed). | ||||
* @return {boolean} Whether the entity was ejected. | * @return {boolean} Whether the entity was ejected. | ||||
*/ | */ | ||||
Show All 27 Lines | if (pos.y < 0) | ||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
pos = cmpPosition.GetPosition(); | pos = cmpPosition.GetPosition(); | ||||
} | } | ||||
this.entities.splice(entityIndex, 1); | this.entities.splice(entityIndex, 1); | ||||
let cmpEntPosition = Engine.QueryInterface(entity, IID_Position); | let cmpEntPosition = Engine.QueryInterface(entity, IID_Position); | ||||
let cmpEntUnitAI = Engine.QueryInterface(entity, IID_UnitAI); | let cmpEntUnitAI = Engine.QueryInterface(entity, IID_UnitAI); | ||||
// Needs to be called before the visible garrison points are cleared. | |||||
Done Inline Actionsmaybe Needs to be set ... Silier: maybe `Needs to be set ...` | |||||
let visible = { | |||||
[entity] : this.IsVisiblyGarrisoned(entity) | |||||
}; | |||||
Done Inline Actionssee L404 comment Silier: see L404 comment
yes cache visible[entity] here and use later | |||||
for (let vgp of this.visibleGarrisonPoints) | for (let vgp of this.visibleGarrisonPoints) | ||||
{ | { | ||||
if (vgp.entity != entity) | if (vgp.entity != entity) | ||||
continue; | continue; | ||||
cmpEntPosition.SetTurretParent(INVALID_ENTITY, new Vector3D()); | cmpEntPosition.SetTurretParent(INVALID_ENTITY, new Vector3D()); | ||||
let cmpEntUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); | let cmpEntUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); | ||||
if (cmpEntUnitMotion) | if (cmpEntUnitMotion) | ||||
cmpEntUnitMotion.SetFacePointAfterMove(true); | cmpEntUnitMotion.SetFacePointAfterMove(true); | ||||
Show All 16 Lines | GarrisonHolder.prototype.Eject = function(entity, forced) | ||||
cmpEntPosition.JumpTo(pos.x, pos.z); | cmpEntPosition.JumpTo(pos.x, pos.z); | ||||
cmpEntPosition.SetHeightOffset(0); | cmpEntPosition.SetHeightOffset(0); | ||||
let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); | ||||
if (cmpPosition) | if (cmpPosition) | ||||
cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos)); | cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos)); | ||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [entity] }); | Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { | ||||
"added": [], | |||||
"removed": [entity], | |||||
Done Inline Actionsremoving entity second time ? here is visible[entity] = false even if it would be true few lines before Silier: removing entity second time ? here is visible[entity] = false even if it would be true few… | |||||
"visible": visible | |||||
}); | |||||
Done Inline ActionsRegards L360 I guess? Freagarach: Regards L360 I guess? | |||||
Done Inline ActionsMight want to keep the comment, but then at L357 I guess, I often have to look twice to see why it is there and not later ;) (Which is not bad per se, but still.) Freagarach: Might want to keep the comment, but then at L357 I guess, I often have to look twice to see why… | |||||
return true; | return true; | ||||
}; | }; | ||||
/** | /** | ||||
* Ejects units and orders them to move to the rally point. If an ejection | * Ejects units and orders them to move to the rally point. If an ejection | ||||
* with a given obstruction radius has failed, we won't try anymore to eject | * with a given obstruction radius has failed, we won't try anymore to eject | ||||
* entities with a bigger obstruction as that is compelled to also fail. | * entities with a bigger obstruction as that is compelled to also fail. | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg) | ||||
let entityIndex = this.entities.indexOf(msg.entity); | let entityIndex = this.entities.indexOf(msg.entity); | ||||
if (entityIndex != -1) | if (entityIndex != -1) | ||||
{ | { | ||||
// If the entity is dead, remove it directly instead of ejecting the corpse | // If the entity is dead, remove it directly instead of ejecting the corpse | ||||
let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health); | let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health); | ||||
if (cmpHealth && cmpHealth.GetHitpoints() == 0) | if (cmpHealth && cmpHealth.GetHitpoints() == 0) | ||||
{ | { | ||||
this.entities.splice(entityIndex, 1); | this.entities.splice(entityIndex, 1); | ||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [msg.entity] }); | Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { | ||||
"added": [], | |||||
Done Inline ActionsInline below? Freagarach: Inline below? | |||||
Done Inline ActionsSee the other one. Stan: See the other one. | |||||
"removed": [msg.entity], | |||||
"visible": { | |||||
[msg.entity]: this.IsVisiblyGarrisoned(msg.entity) | |||||
} | |||||
}); | |||||
this.UpdateGarrisonFlag(); | this.UpdateGarrisonFlag(); | ||||
for (let point of this.visibleGarrisonPoints) | for (let point of this.visibleGarrisonPoints) | ||||
if (point.entity == msg.entity) | if (point.entity == msg.entity) | ||||
point.entity = null; | point.entity = null; | ||||
} | } | ||||
else if (msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity)) | else if (msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity)) | ||||
this.EjectOrKill([msg.entity]); | this.EjectOrKill([msg.entity]); | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* Update list of garrisoned entities if one gets renamed (e.g. by promotion). | * Update list of garrisoned entities if one gets renamed (e.g. by promotion). | ||||
*/ | */ | ||||
GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) | GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) | ||||
Done Inline ActionsNot sure whether this is the right place for the comment? Freagarach: Not sure whether this is the right place for the comment? | |||||
{ | { | ||||
let entityIndex = this.entities.indexOf(msg.entity); | let entityIndex = this.entities.indexOf(msg.entity); | ||||
if (entityIndex != -1) | if (entityIndex != -1) | ||||
{ | { | ||||
let vgpRenamed; | let vgpRenamed; | ||||
for (let vgp of this.visibleGarrisonPoints) | for (let vgp of this.visibleGarrisonPoints) | ||||
{ | { | ||||
if (vgp.entity != msg.entity) | if (vgp.entity != msg.entity) | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | for (let entity of entities) | ||||
let cmpHealth = Engine.QueryInterface(entity, IID_Health); | let cmpHealth = Engine.QueryInterface(entity, IID_Health); | ||||
if (cmpHealth) | if (cmpHealth) | ||||
cmpHealth.Kill(); | cmpHealth.Kill(); | ||||
this.entities.splice(entityIndex, 1); | this.entities.splice(entityIndex, 1); | ||||
killedEntities.push(entity); | killedEntities.push(entity); | ||||
} | } | ||||
if (killedEntities.length) | if (killedEntities.length) | ||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": killedEntities }); | { | ||||
let visibleEntitiesIds = {}; | |||||
for (let ent of killedEntities) | |||||
visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent); | |||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { | |||||
"added": [], | |||||
"removed": killedEntities, | |||||
"visible": visibleEntitiesIds | |||||
}); | |||||
} | |||||
this.UpdateGarrisonFlag(); | this.UpdateGarrisonFlag(); | ||||
}; | }; | ||||
/** | /** | ||||
* Gives insight about the unit type of garrisoning. | |||||
* @param {number} entity - the entity's id. | |||||
* @return {boolean} - Whether the unit is visible on the structure. | |||||
Done Inline ActionsSwitch? Freagarach: Switch? | |||||
FreagarachUnsubmitted Done Inline Actionsstructure -> entity Freagarach: `structure` -> `entity` | |||||
*/ | |||||
GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) | |||||
{ | |||||
return this.visibleGarrisonPoints.some(point => point.entity == entity); | |||||
}; | |||||
/** | |||||
* Whether an entity is ejectable. | * Whether an entity is ejectable. | ||||
* @param {number} entity - The entity-ID to be tested. | * @param {number} entity - The entity-ID to be tested. | ||||
Done Inline ActionsT Freagarach: `T` | |||||
* @return {boolean} - Whether the entity is ejectable. | * @return {boolean} - Whether the entity is ejectable. | ||||
Done Inline ActionsWhether the entity is visible on the garrison holder. Or something alike, but now the entities don't match ;) Freagarach: `Whether the entity is visible on the garrison holder.` Or something alike, but now the… | |||||
*/ | */ | ||||
Done Inline ActionsIndentation. Freagarach: Indentation. | |||||
GarrisonHolder.prototype.IsEjectable = function(entity) | GarrisonHolder.prototype.IsEjectable = function(entity) | ||||
{ | { | ||||
if (!this.entities.find(ent => ent == entity)) | if (!this.entities.find(ent => ent == entity)) | ||||
return false; | return false; | ||||
let ejectableClasses = this.template.EjectClassesOnDestroy._string; | let ejectableClasses = this.template.EjectClassesOnDestroy._string; | ||||
let entityClasses = Engine.QueryInterface(entity, IID_Identity).GetClassesList(); | let entityClasses = Engine.QueryInterface(entity, IID_Identity).GetClassesList(); | ||||
Show All 40 Lines |
-inside?