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 @@ -186,13 +186,33 @@ let cmpGarrisonable = Engine.QueryInterface(msg.newentity, IID_Garrisonable); if (cmpGarrisonable) cmpGarrisonable.Garrison(this.holder, true); + else + { + 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()); + } + } } // We process EntityRenamed of turrets seperately since we // want to occupy the same position after being renamed. let cmpTurretHolder = Engine.QueryInterface(this.holder, IID_TurretHolder); if (cmpTurretHolder) - cmpTurretHolder.SwapEntities(msg.entity, msg.newentity); + if (Engine.QueryInterface(msg.newentity, IID_Garrisonable)) + cmpTurretHolder.SwapEntities(msg.entity, msg.newentity); + else + cmpTurretHolder.LeaveTurret(msg.entity); delete this.holder; }; 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,28 @@ 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.SwitchToStance(cmpUnitAI.GetStanceName()); + 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); + } + } + } + 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,6 +3,7 @@ Advanced + units/athen/infantry_slinger_e