Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/GarrisonHolder.js
+++ binaries/data/mods/public/simulation/components/GarrisonHolder.js
@@ -429,39 +429,11 @@
*/
GarrisonHolder.prototype.EjectOrKill = function(entities)
{
- let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
- // Eject the units which can be ejected (if not in world, it generally means this holder
- // is inside a holder which kills its entities, so do not eject)
- if (cmpPosition && cmpPosition.IsInWorld())
- {
- let ejectables = entities.filter(ent => this.IsEjectable(ent));
- if (ejectables.length)
- this.UnloadEntities(ejectables);
- }
-
- // And destroy all remaining entities
- let killedEntities = [];
for (let entity of entities)
{
- let entityIndex = this.entities.indexOf(entity);
- if (entityIndex == -1)
- continue;
- let cmpHealth = Engine.QueryInterface(entity, IID_Health);
- if (cmpHealth)
- cmpHealth.Kill();
- else
- Engine.DestroyEntity(entity);
- this.entities.splice(entityIndex, 1);
- killedEntities.push(entity);
- }
-
- if (killedEntities.length)
- {
- Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {
- "added": [],
- "removed": killedEntities
- });
- this.UpdateGarrisonFlag();
+ let cmpGarrisonable = Engine.QueryInterface(entity, IID_Garrisonable);
+ if (cmpGarrisonable)
+ cmpGarrisonable.UnGarrisonOrDie();
}
};
Index: binaries/data/mods/public/simulation/components/Garrisonable.js
===================================================================
--- binaries/data/mods/public/simulation/components/Garrisonable.js
+++ binaries/data/mods/public/simulation/components/Garrisonable.js
@@ -144,16 +144,49 @@
return true;
};
+/**
+ * @param {boolean} forced
+ */
+Garrisonable.prototype.UnGarrisonOrDie = function(forced = false)
+{
+ if (this.UnGarrison(forced))
+ return;
+
+ let cmpGarrisonHolder = Engine.QueryInterface(this.holder, IID_GarrisonHolder);
+ if (cmpGarrisonHolder)
+ cmpGarrisonHolder.Eject(this.entity, true);
+ let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
+ if (cmpHealth)
+ cmpHealth.Kill();
+ else
+ Engine.DestroyEntity(this.entity);
+};
+
Garrisonable.prototype.OnEntityRenamed = function(msg)
{
if (!this.holder)
return;
let holder = this.holder;
- this.UnGarrison(true, true);
+ this.UnGarrisonOrDie(true);
let cmpGarrisonable = Engine.QueryInterface(msg.newentity, IID_Garrisonable);
- if (cmpGarrisonable)
- cmpGarrisonable.Garrison(holder, true);
+ if (!cmpGarrisonable || !cmpGarrisonable.Garrison(holder, true))
+ {
+ let cmpPositionSelf = Engine.QueryInterface(this.entity, IID_Position);
+ let cmpPositionNew = Engine.QueryInterface(msg.newentity, IID_Position);
+ if (cmpPositionSelf && cmpPositionNew)
+ {
+ if (cmpPositionSelf.IsInWorld())
+ {
+ let pos = cmpPositionSelf.GetPosition2D();
+ cmpPositionNew.JumpTo(pos.x, pos.y);
+ }
+ let rot = cmpPositionSelf.GetRotation();
+ cmpPositionNew.SetYRotation(rot.y);
+ cmpPositionNew.SetXZRotation(rot.x, rot.z);
+ cmpPositionNew.SetHeightOffset(cmpPositionSelf.GetHeightOffset());
+ }
+ }
};
Engine.RegisterComponentType(IID_Garrisonable, "Garrisonable", Garrisonable);
Index: binaries/data/mods/public/simulation/components/TurretHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/TurretHolder.js
+++ binaries/data/mods/public/simulation/components/TurretHolder.js
@@ -237,25 +237,12 @@
*/
EjectOrKill(entities)
{
- let removedEntities = [];
for (let entity of entities)
{
let cmpTurretable = Engine.QueryInterface(entity, IID_Turretable);
- if (!cmpTurretable || !cmpTurretable.LeaveTurret(true))
- {
- let cmpHealth = Engine.QueryInterface(entity, IID_Health);
- if (cmpHealth)
- cmpHealth.Kill();
- else
- Engine.DestroyEntity(entity);
- removedEntities.push(entity);
- }
+ if (cmpTurretable)
+ cmpTurretable.LeaveTurretOrDie();
}
- if (removedEntities.length)
- Engine.PostMessage(this.entity, MT_TurretsChanged, {
- "added": [],
- "removed": removedEntities
- });
}
/**
Index: binaries/data/mods/public/simulation/components/Turretable.js
===================================================================
--- binaries/data/mods/public/simulation/components/Turretable.js
+++ binaries/data/mods/public/simulation/components/Turretable.js
@@ -134,6 +134,24 @@
return true;
};
+/**
+ * @param {boolean} forced
+ */
+Turretable.prototype.LeaveTurretOrDie = function(forced = false)
+{
+ if (this.LeaveTurret(forced))
+ return;
+
+ let cmpTurretHolder = Engine.QueryInterface(this.holder, IID_TurretHolder);
+ if (cmpTurretHolder)
+ cmpTurretHolder.LeaveTurret(this.entity);
+ let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
+ if (cmpHealth)
+ cmpHealth.Kill();
+ else
+ Engine.DestroyEntity(this.entity);
+};
+
Turretable.prototype.OnEntityRenamed = function(msg)
{
if (!this.holder)
@@ -145,10 +163,25 @@
let holder = this.holder;
let currentPoint = cmpTurretHolder.GetOccupiedTurretName(this.entity);
- this.LeaveTurret(true);
+ this.LeaveTurretOrDie(true);
let cmpTurretableNew = Engine.QueryInterface(msg.newentity, IID_Turretable);
- if (cmpTurretableNew)
- cmpTurretableNew.OccupyTurret(holder, currentPoint);
+ if (!cmpTurretableNew || !cmpTurretableNew.OccupyTurret(holder, currentPoint))
+ {
+ let cmpPositionSelf = Engine.QueryInterface(this.entity, IID_Position);
+ let cmpPositionNew = Engine.QueryInterface(msg.newentity, IID_Position);
+ if (cmpPositionSelf && cmpPositionNew)
+ {
+ if (cmpPositionSelf.IsInWorld())
+ {
+ let pos = cmpPositionSelf.GetPosition2D();
+ cmpPositionNew.JumpTo(pos.x, pos.y);
+ }
+ let rot = cmpPositionSelf.GetRotation();
+ cmpPositionNew.SetYRotation(rot.y);
+ cmpPositionNew.SetXZRotation(rot.x, rot.z);
+ cmpPositionNew.SetHeightOffset(cmpPositionSelf.GetHeightOffset());
+ }
+ }
};
Turretable.prototype.OnOwnershipChanged = function(msg)
@@ -157,7 +190,7 @@
return;
if (msg.to == INVALID_PLAYER)
- this.LeaveTurret(true);
+ this.LeaveTurretOrDie(true);
else if (!IsOwnedByMutualAllyOfEntity(this.entity, this.holder))
this.LeaveTurret();
};
Index: binaries/data/mods/public/simulation/helpers/Transform.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Transform.js
+++ binaries/data/mods/public/simulation/helpers/Transform.js
@@ -58,30 +58,6 @@
if (cmpBuilderList && cmpNewBuilderList)
cmpNewBuilderList.AddBuilders(cmpBuilderList.GetBuilders());
- var cmpUnitAI = Engine.QueryInterface(oldEnt, IID_UnitAI);
- var cmpNewUnitAI = Engine.QueryInterface(newEnt, IID_UnitAI);
- if (cmpUnitAI && cmpNewUnitAI)
- {
- let pos = cmpUnitAI.GetHeldPosition();
- if (pos)
- cmpNewUnitAI.SetHeldPosition(pos.x, pos.z);
- if (cmpUnitAI.GetStanceName())
- cmpNewUnitAI.SwitchToStance(cmpUnitAI.GetStanceName());
- if (cmpUnitAI.GetGarrisonHolder() != INVALID_ENTITY)
- cmpNewUnitAI.SetGarrisoned();
- cmpNewUnitAI.AddOrders(cmpUnitAI.GetOrders());
- if (cmpUnitAI.IsGuardOf())
- {
- let guarded = cmpUnitAI.IsGuardOf();
- let cmpGuard = Engine.QueryInterface(guarded, IID_Guard);
- if (cmpGuard)
- {
- cmpGuard.RenameGuard(oldEnt, newEnt);
- cmpNewUnitAI.SetGuardOf(guarded);
- }
- }
- }
-
let cmpPromotion = Engine.QueryInterface(oldEnt, IID_Promotion);
let cmpNewPromotion = Engine.QueryInterface(newEnt, IID_Promotion);
if (cmpPromotion && cmpNewPromotion)
@@ -133,6 +109,27 @@
Engine.PostMessage(oldEnt, MT_EntityRenamed, { "entity": oldEnt, "newentity": newEnt });
+ // UnitAI generally needs other components to be properly initialised.
+ let cmpUnitAI = Engine.QueryInterface(oldEnt, IID_UnitAI);
+ let cmpNewUnitAI = Engine.QueryInterface(newEnt, IID_UnitAI);
+ if (cmpUnitAI && cmpNewUnitAI)
+ {
+ let pos = cmpUnitAI.GetHeldPosition();
+ if (pos)
+ cmpNewUnitAI.SetHeldPosition(pos.x, pos.z);
+ cmpNewUnitAI.AddOrders(cmpUnitAI.GetOrders());
+ let guarded = cmpUnitAI.IsGuardOf();
+ if (guarded)
+ {
+ let cmpGuarded = Engine.QueryInterface(guarded, IID_Guard);
+ if (cmpGuarded)
+ {
+ cmpGuarded.RenameGuard(oldEnt, newEnt);
+ cmpNewUnitAI.SetGuardOf(guarded);
+ }
+ }
+ }
+
if (cmpPosition && cmpPosition.IsInWorld())
cmpPosition.MoveOutOfWorld();
Engine.DestroyEntity(oldEnt);
Index: binaries/data/mods/public/simulation/templates/units/athen/infantry_slinger_a.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/units/athen/infantry_slinger_a.xml
+++ binaries/data/mods/public/simulation/templates/units/athen/infantry_slinger_a.xml
@@ -3,9 +3,11 @@
Advanced
+
units/athen/infantry_slinger_e
+
units/athenians/infantry_slinger_a.xml