Index: ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js @@ -30,26 +30,27 @@ this.targetUnits = []; }; -BuildingAI.prototype.OnGarrisonedUnitsChanged = function(msg) +BuildingAI.prototype.OnGarrisonedUnitsChanged = function() { - let classes = this.template.GarrisonArrowClasses; - - for (let ent of msg.added) - { - if (msg.visible[ent]) - continue; + this.RecalculateProjectileCount(); +}; - let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); - if (!cmpIdentity) - continue; +BuildingAI.prototype.OnTurretsChanged = function() +{ + this.RecalculateProjectileCount(); +}; - if (MatchesClassList(cmpIdentity.GetClassesList(), classes)) - ++this.archersGarrisoned; - } +BuildingAI.prototype.RecalculateProjectileCount = function() +{ + this.archersGarrisoned = 0; + let classes = this.template.GarrisonArrowClasses; - for (let ent of msg.removed) + let cmpTurretHolder = Engine.QueryInterface(this.entity, IID_TurretHolder); + let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); + for (let ent of cmpGarrisonHolder.GetEntities()) { - if (msg.visible[ent]) + // Only count non-visible garrisoned entities towards extra arrows. + if (cmpTurretHolder && cmpTurretHolder.OccupiesTurret(ent)) continue; let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); @@ -57,7 +58,7 @@ continue; if (MatchesClassList(cmpIdentity.GetClassesList(), classes)) - --this.archersGarrisoned; + ++this.archersGarrisoned; } }; Index: ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -31,39 +31,6 @@ "" + "" + "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "tokens" + - "" + - "" + - "" + - ""+ - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + ""; /** @@ -77,22 +44,15 @@ this.entities = []; this.timer = undefined; this.allowGarrisoning = new Map(); - this.visibleGarrisonPoints = []; - if (!this.template.VisibleGarrisonPoints) - return; +}; - let points = this.template.VisibleGarrisonPoints; - for (let point in points) - this.visibleGarrisonPoints.push({ - "offset": { - "x": +points[point].X, - "y": +points[point].Y, - "z": +points[point].Z - }, - "allowedClasses": points[point].AllowedClasses, - "angle": points[point].Angle ? +points[point].Angle * Math.PI / 180 : null, - "entity": null - }); +/** + * @param {number} entity - The entity to verify. + * @return {boolean} - Whether the given entity is garrisoned in this GarrisonHolder. + */ +GarrisonHolder.prototype.IsGarrisoned = function(entity) +{ + return this.entities.indexOf(entity) != -1; }; /** @@ -197,29 +157,12 @@ }; /** - * @param {number} entity - The entity's id. - * @param {Object|undefined} visibleGarrisonPoint - The vgp object. - * @return {boolean} - Whether the unit is allowed be visible on that garrison point. - */ -GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(entity, visibleGarrisonPoint) -{ - if (!visibleGarrisonPoint) - return false; - - if (!visibleGarrisonPoint.allowedClasses) - return true; - - let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); - return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), visibleGarrisonPoint.allowedClasses._string); -}; - -/** - * Garrison a unit inside. The timer for AutoHeal is started here. - * @param {number} vgpEntity - The visual garrison point that will be used. - * If vgpEntity is given, this visualGarrisonPoint will be used for the entity. + * @param {number} entity - The entityID to garrison. + * @param {boolean} renamed - Whether the entity was renamed. + * * @return {boolean} - Whether the entity was garrisoned. */ -GarrisonHolder.prototype.Garrison = function(entity, vgpEntity) +GarrisonHolder.prototype.Garrison = function(entity, renamed = false) { if (!this.IsAllowedToGarrison(entity)) return false; @@ -227,10 +170,6 @@ if (!this.HasEnoughHealth()) return false; - let cmpPosition = Engine.QueryInterface(entity, IID_Position); - if (!cmpPosition) - return false; - if (!this.timer && this.GetHealRate() > 0) { let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); @@ -247,53 +186,14 @@ if (cmpAura && cmpAura.HasGarrisonAura()) cmpAura.ApplyGarrisonAura(this.entity); - let visibleGarrisonPoint; - if (vgpEntity && this.AllowedToVisibleGarrisoning(entity, vgpEntity)) - visibleGarrisonPoint = vgpEntity; - - if (!visibleGarrisonPoint) - visibleGarrisonPoint = this.visibleGarrisonPoints.find(vgp => !vgp.entity && this.AllowedToVisibleGarrisoning(entity, vgp)); - - let isVisiblyGarrisoned = false; - if (visibleGarrisonPoint) - { - visibleGarrisonPoint.entity = entity; - // Angle of turrets: - // Renamed entities (vgpEntity != undefined) should keep their angle. - // 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 - // 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. - let cmpTurretPosition = Engine.QueryInterface(this.entity, IID_Position); - if (!vgpEntity && visibleGarrisonPoint.angle != null) - cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + visibleGarrisonPoint.angle); - else if (!vgpEntity && !cmpPosition.IsInWorld()) - cmpPosition.SetYRotation(cmpTurretPosition.GetRotation().y + Math.PI); - let cmpUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); - if (cmpUnitMotion) - cmpUnitMotion.SetFacePointAfterMove(false); - cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); - let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); - if (cmpUnitAI) - cmpUnitAI.SetTurretStance(); - - // Remove the unit's obstruction to avoid interfering with pathing. - let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction); - if (cmpObstruction) - cmpObstruction.SetActive(false); - - isVisiblyGarrisoned = true; - } - else + let cmpPosition = Engine.QueryInterface(entity, IID_Position); + if (cmpPosition) 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, { "added": [entity], "removed": [], - "visible": { - [entity]: isVisiblyGarrisoned, - } + "renamed": renamed }); return true; @@ -303,9 +203,11 @@ * Simply eject the unit from the garrisoning entity without moving it * @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} renamed - Whether eject was due to entity renaming. + * * @return {boolean} Whether the entity was ejected. */ -GarrisonHolder.prototype.Eject = function(entity, forced) +GarrisonHolder.prototype.Eject = function(entity, forced, renamed = false) { let entityIndex = this.entities.indexOf(entity); // Error: invalid entity ID, usually it's already been ejected @@ -337,33 +239,13 @@ } this.entities.splice(entityIndex, 1); - let cmpEntPosition = Engine.QueryInterface(entity, IID_Position); - let cmpEntUnitAI = Engine.QueryInterface(entity, IID_UnitAI); - - // Needs to be set before the visible garrison points are cleared. - let visible = { - [entity]: this.IsVisiblyGarrisoned(entity) - }; - - for (let vgp of this.visibleGarrisonPoints) - { - if (vgp.entity != entity) - continue; - cmpEntPosition.SetTurretParent(INVALID_ENTITY, new Vector3D()); - let cmpEntUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); - if (cmpEntUnitMotion) - cmpEntUnitMotion.SetFacePointAfterMove(true); - if (cmpEntUnitAI) - cmpEntUnitAI.ResetTurretStance(); - vgp.entity = null; - break; - } // Reset the obstruction flags to template defaults. let cmpObstruction = Engine.QueryInterface(entity, IID_Obstruction); if (cmpObstruction) cmpObstruction.SetActive(true); + let cmpEntUnitAI = Engine.QueryInterface(entity, IID_UnitAI); if (cmpEntUnitAI) cmpEntUnitAI.Ungarrison(); @@ -375,17 +257,21 @@ if (cmpEntAura && cmpEntAura.HasGarrisonAura()) cmpEntAura.RemoveGarrisonAura(this.entity); - cmpEntPosition.JumpTo(pos.x, pos.z); - cmpEntPosition.SetHeightOffset(0); + let cmpEntPosition = Engine.QueryInterface(entity, IID_Position); + if (cmpEntPosition) + { + cmpEntPosition.JumpTo(pos.x, pos.z); + cmpEntPosition.SetHeightOffset(0); - let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (cmpPosition) - cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos)); + let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (cmpPosition) + cmpEntPosition.SetYRotation(cmpPosition.GetPosition().horizAngleTo(pos)); + } Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "removed": [entity], - "visible": visible + "renamed": renamed }); return true; @@ -628,16 +514,9 @@ this.entities.splice(entityIndex, 1); Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], - "removed": [msg.entity], - "visible": { - [msg.entity]: this.IsVisiblyGarrisoned(msg.entity) - } + "removed": [msg.entity] }); this.UpdateGarrisonFlag(); - - for (let point of this.visibleGarrisonPoints) - if (point.entity == msg.entity) - point.entity = null; } else if (msg.to == INVALID_PLAYER || !IsOwnedByMutualAllyOfEntity(this.entity, msg.entity)) this.EjectOrKill([msg.entity]); @@ -652,16 +531,19 @@ let entityIndex = this.entities.indexOf(msg.entity); if (entityIndex != -1) { - let vgpRenamed; - for (let vgp of this.visibleGarrisonPoints) - { - if (vgp.entity != msg.entity) - continue; - vgpRenamed = vgp; - break; - } - this.Eject(msg.entity, true); - this.Garrison(msg.newentity, vgpRenamed); + this.Eject(msg.entity, true, true); + this.Garrison(msg.newentity, true); + + // TurretHolder is not subscribed to GarrisonChanged, so we must inform it explicitly. + // Otherwise a renaming entity may re-occupy another turret instead of its previous one, + // since the message does not know what turret point whas used, which is not wanted. + // Also ensure the TurretHolder receives the message after we process it. + // If it processes it before us we garrison a turret and subsequently + // are hidden by GarrisonHolder again. + // This could be fixed by not requiring a turret to be 'garrisoned'. + let cmpTurretHolder = Engine.QueryInterface(this.entity, IID_TurretHolder); + if (cmpTurretHolder) + cmpTurretHolder.SwapEntities(msg.entity, msg.newentity); } if (!this.initGarrison) @@ -722,26 +604,12 @@ if (killedEntities.length) { - let visibleEntitiesIds = {}; - for (let ent of killedEntities) - visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent); Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], - "removed": killedEntities, - "visible": visibleEntitiesIds + "removed": killedEntities }); + this.UpdateGarrisonFlag(); } - this.UpdateGarrisonFlag(); -}; - -/** - * Gives insight about the unit type of garrisoning. - * @param {number} entity - The entity's id. - * @return {boolean} - Whether the entity is visible on the garrison holder. - */ -GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) -{ - return this.visibleGarrisonPoints.some(point => point.entity == entity); }; /** Index: ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js +++ ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -359,6 +359,12 @@ "garrisonedEntitiesCount": cmpGarrisonHolder.GetGarrisonedEntitiesCount() }; + let cmpTurretHolder = Engine.QueryInterface(ent, IID_TurretHolder); + if (cmpTurretHolder) + ret.turretHolder = { + "turretPoints": cmpTurretHolder.GetTurretPoints() + }; + ret.canGarrison = !!Engine.QueryInterface(ent, IID_Garrisonable); let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); Index: ps/trunk/binaries/data/mods/public/simulation/components/TurretHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/TurretHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/TurretHolder.js @@ -0,0 +1,249 @@ +/** + * This class holds the functions regarding entities being visible on + * another entity, but tied to their parents location. + * Currently renaming and changing ownership are still managed by GarrisonHolder.js, + * but in the future these components should be independent. + */ +class TurretHolder +{ + Init() + { + this.turretPoints = []; + + let points = this.template.TurretPoints; + for (let point in points) + this.turretPoints.push({ + "offset": { + "x": +points[point].X, + "y": +points[point].Y, + "z": +points[point].Z + }, + "allowedClasses": points[point].AllowedClasses, + "angle": points[point].Angle ? +points[point].Angle * Math.PI / 180 : null, + "entity": null + }); + } + + /** + * @return {Object[]} - An array of the turret points this entity has. + */ + GetTurretPoints() + { + return this.turretPoints; + } + + /** + * @param {number} entity - The entity to check for. + * @param {Object} turretPoint - The turret point to use. + * + * @return {boolean} - Whether the entity is allowed to occupy the specified turret point. + */ + AllowedToOccupyTurret(entity, turretPoint) + { + if (!turretPoint || turretPoint.entity) + return false; + + if (!IsOwnedByMutualAllyOfEntity(entity, this.entity)) + return false; + + if (!turretPoint.allowedClasses) + return true; + + let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); + return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), turretPoint.allowedClasses._string); + } + + /** + * Occupy a turret point with the given entity. + * @param {number} entity - The entity to use. + * @param {Object} turretPoint - Optionally the specific turret point to occupy. + * + * @return {boolean} - Whether the occupation was successful. + */ + OccupyTurret(entity, requestedTurretPoint) + { + let cmpPositionOccupant = Engine.QueryInterface(entity, IID_Position); + if (!cmpPositionOccupant) + return false; + + let cmpPositionSelf = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPositionSelf) + return false; + + if (this.OccupiesTurret(entity)) + return false; + + let turretPoint; + if (requestedTurretPoint) + { + if (this.AllowedToOccupyTurret(entity, requestedTurretPoint)) + turretPoint = requestedTurretPoint; + } + else + turretPoint = this.turretPoints.find(turret => !turret.entity && this.AllowedToOccupyTurret(entity, turret)); + + if (!turretPoint) + return false; + + turretPoint.entity = entity; + // Angle of turrets: + // Renamed entities (turretPoint != undefined) should keep their angle. + // Otherwise if an angle is given in the turretPoint, use it. + // 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 + // outside, except when garrisoning from outWorld where we take as default PI. + if (!turretPoint && turretPoint.angle != null) + cmpPositionOccupant.SetYRotation(cmpPositionSelf.GetRotation().y + turretPoint.angle); + else if (!turretPoint && !cmpPosition.IsInWorld()) + cmpPositionOccupant.SetYRotation(cmpPositionSelf.GetRotation().y + Math.PI); + + cmpPositionOccupant.SetTurretParent(this.entity, turretPoint.offset); + + let cmpUnitMotion = Engine.QueryInterface(entity, IID_UnitMotion); + if (cmpUnitMotion) + cmpUnitMotion.SetFacePointAfterMove(false); + + let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); + if (cmpUnitAI) + cmpUnitAI.SetTurretStance(); + + Engine.PostMessage(this.entity, MT_TurretsChanged, { + "added": [entity], + "removed": [] + }); + + return true; + } + + /** + * Remove the entity from a turret. + * @param {number} entity - The specific entity to eject. + * @param {Object} turret - Optionally the turret to abandon. + * + * @return {boolean} - Whether the entity was occupying a/the turret before. + */ + LeaveTurret(entity, requestedTurretPoint) + { + let turretPoint; + if (requestedTurretPoint) + { + if (requestedTurretPoint.entity == entity) + turretPoint = requestedTurretPoint; + } + else + turretPoint = this.turretPoints.find(turret => turret.entity == entity); + + if (!turretPoint) + return false; + + let cmpPositionEntity = Engine.QueryInterface(entity, IID_Position); + cmpPositionEntity.SetTurretParent(INVALID_ENTITY, new Vector3D()); + + let cmpUnitMotionEntity = Engine.QueryInterface(entity, IID_UnitMotion); + if (cmpUnitMotionEntity) + cmpUnitMotionEntity.SetFacePointAfterMove(true); + + let cmpUnitAIEntity = Engine.QueryInterface(entity, IID_UnitAI); + if (cmpUnitAIEntity) + cmpUnitAIEntity.ResetTurretStance(); + + turretPoint.entity = null; + + Engine.PostMessage(this.entity, MT_TurretsChanged, { + "added": [], + "removed": [entity] + }); + + return true; + } + + /** + * @param {number} entity - The entity's id. + * @param {Object} turret - Optionally the turret to check. + * + * @return {boolean} - Whether the entity is positioned on a turret of this entity. + */ + OccupiesTurret(entity, requestedTurretPoint) + { + return requestedTurretPoint ? requestedTurretPoint.entity == entity : + this.turretPoints.some(turretPoint => turretPoint.entity == entity); + } + + /** + * @param {number} entity - The entity's id. + * @return {Object} - The turret this entity is positioned on, if applicable. + */ + GetOccupiedTurret(entity) + { + return this.turretPoints.find(turretPoint => turretPoint.entity == entity); + } + + /** + * We process EntityRenamed here because we need to be sure that we 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. + * + * @param {number} from - The entity to substitute. + * @param {number} to - The entity to subtitute with. + */ + SwapEntities(from, to) + { + let turretPoint = this.GetOccupiedTurret(from); + if (turretPoint) + this.LeaveTurret(from, turretPoint); + + let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); + if (cmpGarrisonHolder && cmpGarrisonHolder.IsGarrisoned(to)) + this.OccupyTurret(to, turretPoint); + } + + OnGarrisonedUnitsChanged(msg) + { + // Ignore renaming for that is handled seperately + // (i.e. called directly from GarrisonHolder.js). + if (msg.renamed) + return; + + for (let entity of msg.removed) + this.LeaveTurret(entity); + for (let entity of msg.added) + this.OccupyTurret(entity); + } +} + +TurretHolder.prototype.Schema = + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "tokens" + + "" + + "" + + "" + + ""+ + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + +Engine.RegisterComponentType(IID_TurretHolder, "TurretHolder", TurretHolder); Index: ps/trunk/binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js @@ -0,0 +1,7 @@ +Engine.RegisterInterface("TurretHolder"); + +/** + * Message of the form { "added": number[], "removed": number[] } + * sent from the TurretHolder component to the current entity whenever the turrets change. + */ +Engine.RegisterMessageType("TurretsChanged"); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GarrisonHolder.js @@ -2,6 +2,7 @@ Engine.LoadHelperScript("Player.js"); Engine.LoadComponentScript("interfaces/GarrisonHolder.js"); Engine.LoadComponentScript("interfaces/Garrisonable.js"); +Engine.LoadComponentScript("interfaces/TurretHolder.js"); Engine.LoadComponentScript("GarrisonHolder.js"); Engine.LoadComponentScript("interfaces/Auras.js"); Engine.LoadComponentScript("interfaces/Health.js"); @@ -73,11 +74,8 @@ "GetHeightOffset": () => 0, "GetPosition": () => new Vector3D(4, 3, 25), "GetRotation": () => new Vector3D(4, 0, 6), - "GetTurretParent": () => INVALID_ENTITY, - "IsInWorld": () => true, "JumpTo": (posX, posZ) => {}, "MoveOutOfWorld": () => {}, - "SetTurretParent": (entity, offset) => {}, "SetHeightOffset": height => {} }); } @@ -94,19 +92,7 @@ "EjectClassesOnDestroy": { "_string": "Infantry" }, "BuffHeal": 1, "LoadingRange": 2.1, - "Pickup": false, - "VisibleGarrisonPoints": { - "archer1": { - "X": 12, - "Y": 5, - "Z": 6 - }, - "archer2": { - "X": 15, - "Y": 5, - "Z": 6 - } - } + "Pickup": false }); let testGarrisonAllowed = function() @@ -182,23 +168,12 @@ "EjectClassesOnDestroy": { "_string": "Infantry" }, "BuffHeal": 1, "LoadingRange": 2.1, - "Pickup": false, - "VisibleGarrisonPoints": { - "archer1": { - "X": 12, - "Y": 5, - "Z": 6 - }, - "archer2": { - "X": 15, - "Y": 5, - "Z": 6 - } - } + "Pickup": false }); testGarrisonAllowed(); +// Test entity renaming. let siegeEngineId = 44; AddMock(siegeEngineId, IID_Identity, { "GetClassesList": () => ["Siege"] @@ -208,7 +183,6 @@ "GetClassesList": () => ["Infantry", "Ranged"] }); -// Test visible garrisoning restrictions. cmpGarrisonHolder = ConstructComponent(garrisonHolderId, "GarrisonHolder", { "Max": 10, "List": { "_string": "Infantry+Ranged Siege Cavalry" }, @@ -216,55 +190,19 @@ "EjectClassesOnDestroy": { "_string": "Infantry" }, "BuffHeal": 1, "LoadingRange": 2.1, - "Pickup": false, - "VisibleGarrisonPoints": { - "archer1": { - "X": 12, - "Y": 5, - "Z": 6 - }, - "archer2": { - "X": 15, - "Y": 5, - "Z": 6, - "AllowedClasses": { "_string": "Siege Trader" } - }, - "archer3": { - "X": 15, - "Y": 5, - "Z": 6, - "AllowedClasses": { "_string": "Siege Infantry+Ranged Infantry+Cavalry" } - } - } + "Pickup": false }); AddMock(32, IID_Identity, { "GetClassesList": () => ["Trader"] }); -TS_ASSERT_EQUALS(cmpGarrisonHolder.Garrison(32), false); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(siegeEngineId, cmpGarrisonHolder.visibleGarrisonPoints[0]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(siegeEngineId, cmpGarrisonHolder.visibleGarrisonPoints[1]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(siegeEngineId, cmpGarrisonHolder.visibleGarrisonPoints[2]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(archerId, cmpGarrisonHolder.visibleGarrisonPoints[0]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(archerId, cmpGarrisonHolder.visibleGarrisonPoints[1]), false); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(archerId, cmpGarrisonHolder.visibleGarrisonPoints[2]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(33, cmpGarrisonHolder.visibleGarrisonPoints[0]), true); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(33, cmpGarrisonHolder.visibleGarrisonPoints[1]), false); -TS_ASSERT_EQUALS(cmpGarrisonHolder.AllowedToVisibleGarrisoning(33, cmpGarrisonHolder.visibleGarrisonPoints[2]), true); - -// If an entity gets renamed (e.g. promotion, upgrade) -// and is no longer able to be visibly garrisoned it -// should be garisoned instead or ejected. AddMock(siegeEngineId, IID_Position, { "GetHeightOffset": () => 0, "GetPosition": () => new Vector3D(4, 3, 25), "GetRotation": () => new Vector3D(4, 0, 6), - "GetTurretParent": () => INVALID_ENTITY, - "IsInWorld": () => true, "JumpTo": (posX, posZ) => {}, "MoveOutOfWorld": () => {}, - "SetTurretParent": (entity, offset) => {}, "SetHeightOffset": height => {} }); let currentSiegePlayer = player; @@ -280,11 +218,8 @@ "GetHeightOffset": () => 0, "GetPosition": () => new Vector3D(4, 3, 25), "GetRotation": () => new Vector3D(4, 0, 6), - "GetTurretParent": () => INVALID_ENTITY, - "IsInWorld": () => true, "JumpTo": (posX, posZ) => {}, "MoveOutOfWorld": () => {}, - "SetTurretParent": (entity, offset) => {}, "SetHeightOffset": height => {} }); @@ -295,14 +230,11 @@ AddMock(cavalryId, IID_Garrisonable, {}); TS_ASSERT(cmpGarrisonHolder.Garrison(siegeEngineId)); TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 1); -TS_ASSERT(cmpGarrisonHolder.IsVisiblyGarrisoned(siegeEngineId)); cmpGarrisonHolder.OnGlobalEntityRenamed({ "entity": siegeEngineId, "newentity": cavalryId }); TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 1); -TS_ASSERT(!cmpGarrisonHolder.IsVisiblyGarrisoned(siegeEngineId)); -TS_ASSERT(!cmpGarrisonHolder.IsVisiblyGarrisoned(archerId)); // Eject enemy units. currentCavalryPlayer = enemyPlayer; @@ -311,14 +243,3 @@ "to": enemyPlayer }); TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 0); - -// Visibly garrisoned units should get ejected if they change players. -TS_ASSERT(cmpGarrisonHolder.Garrison(siegeEngineId)); -TS_ASSERT(cmpGarrisonHolder.IsVisiblyGarrisoned(siegeEngineId)); -TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 1); -currentSiegePlayer = enemyPlayer; -cmpGarrisonHolder.OnGlobalOwnershipChanged({ - "entity": siegeEngineId, - "to": enemyPlayer -}); -TS_ASSERT_EQUALS(cmpGarrisonHolder.GetGarrisonedEntitiesCount(), 0); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js @@ -30,6 +30,7 @@ Engine.LoadComponentScript("interfaces/ResourceSupply.js"); Engine.LoadComponentScript("interfaces/TechnologyManager.js"); Engine.LoadComponentScript("interfaces/Trader.js"); +Engine.LoadComponentScript("interfaces/TurretHolder.js"); Engine.LoadComponentScript("interfaces/Timer.js"); Engine.LoadComponentScript("interfaces/StatisticsTracker.js"); Engine.LoadComponentScript("interfaces/StatusEffectsReceiver.js"); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TurretHolder.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TurretHolder.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_TurretHolder.js @@ -0,0 +1,141 @@ +Engine.LoadHelperScript("Player.js"); +Engine.LoadComponentScript("interfaces/TurretHolder.js"); +Engine.LoadComponentScript("interfaces/UnitAI.js"); +Engine.LoadComponentScript("TurretHolder.js"); + +AddMock(SYSTEM_ENTITY, IID_PlayerManager, { + "GetPlayerByID": id => id +}); + +const player = 1; +const enemyPlayer = 2; +const alliedPlayer = 3; +const turretHolderID = 9; +const entitiesToTest = [10, 11, 12, 13]; + +AddMock(turretHolderID, IID_Ownership, { + "GetOwner": () => player +}); +AddMock(turretHolderID, IID_Position, { + "GetPosition": () => new Vector3D(4, 3, 25), + "GetRotation": () => new Vector3D(4, 0, 6), + "IsInWorld": () => true +}); + +for (let entity of entitiesToTest) +{ + AddMock(entity, IID_Position, { + "GetPosition": () => new Vector3D(4, 3, 25), + "GetRotation": () => new Vector3D(4, 0, 6), + "SetTurretParent": (parent, offset) => {}, + "IsInWorld": () => true + }); + + AddMock(entity, IID_Ownership, { + "GetOwner": () => player + }); +} + +AddMock(player, IID_Player, { + "IsAlly": id => id != enemyPlayer, + "IsMutualAlly": id => id != enemyPlayer, + "GetPlayerID": () => player +}); + +AddMock(alliedPlayer, IID_Player, { + "IsAlly": id => true, + "IsMutualAlly": id => true, + "GetPlayerID": () => alliedPlayer +}); + +let cmpTurretHolder = ConstructComponent(turretHolderID, "TurretHolder", { + "TurretPoints": { + "archer1": { + "X": "12.0", + "Y": "5.", + "Z": "6.0" + }, + "archer2": { + "X": "15.0", + "Y": "5.0", + "Z": "6.0", + "AllowedClasses": { "_string": "Siege Trader" } + }, + "archer3": { + "X": "15.0", + "Y": "5.0", + "Z": "6.0", + "AllowedClasses": { "_string": "Siege Infantry+Ranged Infantry+Cavalry" } + } + } +}); + +let siegeEngineID = entitiesToTest[0]; +AddMock(siegeEngineID, IID_Identity, { + "GetClassesList": () => ["Siege"] +}); + +let archerID = entitiesToTest[1]; +AddMock(archerID, IID_Identity, { + "GetClassesList": () => ["Infantry", "Ranged"] +}); + +let cavID = entitiesToTest[2]; +AddMock(cavID, IID_Identity, { + "GetClassesList": () => ["Infantry", "Cavalry"] +}); + +let infID = entitiesToTest[3]; +AddMock(infID, IID_Identity, { + "GetClassesList": () => ["Infantry"] +}); + +// Test visible garrisoning restrictions. +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(siegeEngineID, cmpTurretHolder.turretPoints[0]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(siegeEngineID, cmpTurretHolder.turretPoints[1]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(siegeEngineID, cmpTurretHolder.turretPoints[2]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(archerID, cmpTurretHolder.turretPoints[0]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(archerID, cmpTurretHolder.turretPoints[1]), false); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(archerID, cmpTurretHolder.turretPoints[2]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(cavID, cmpTurretHolder.turretPoints[0]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(cavID, cmpTurretHolder.turretPoints[1]), false); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(cavID, cmpTurretHolder.turretPoints[2]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(infID, cmpTurretHolder.turretPoints[0]), true); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(infID, cmpTurretHolder.turretPoints[1]), false); +TS_ASSERT_EQUALS(cmpTurretHolder.AllowedToOccupyTurret(infID, cmpTurretHolder.turretPoints[2]), false); + +// Test that one cannot leave a turret that is not occupied. +TS_ASSERT(!cmpTurretHolder.LeaveTurret(archerID)); + +// Test occupying a turret. +TS_ASSERT(!cmpTurretHolder.OccupiesTurret(archerID)); +TS_ASSERT(cmpTurretHolder.OccupyTurret(archerID)); +TS_ASSERT(cmpTurretHolder.OccupiesTurret(archerID)); + +// We're not occupying a turret that we can't occupy. +TS_ASSERT(!cmpTurretHolder.OccupiesTurret(archerID, cmpTurretHolder.turretPoints[1])); +TS_ASSERT(!cmpTurretHolder.OccupyTurret(cavID, cmpTurretHolder.turretPoints[1])); +TS_ASSERT(!cmpTurretHolder.OccupyTurret(cavID, cmpTurretHolder.turretPoints[0])); +TS_ASSERT(cmpTurretHolder.OccupyTurret(cavID, cmpTurretHolder.turretPoints[2])); + +// Leave turrets. +TS_ASSERT(cmpTurretHolder.LeaveTurret(archerID)); +TS_ASSERT(!cmpTurretHolder.LeaveTurret(cavID, cmpTurretHolder.turretPoints[1])); +TS_ASSERT(cmpTurretHolder.LeaveTurret(cavID, cmpTurretHolder.turretPoints[2])); + +// Test renaming. +AddMock(turretHolderID, IID_GarrisonHolder, { + "IsGarrisoned": () => true +}); +TS_ASSERT(cmpTurretHolder.OccupyTurret(siegeEngineID, cmpTurretHolder.turretPoints[2])); +cmpTurretHolder.SwapEntities(siegeEngineID, archerID); +TS_ASSERT(!cmpTurretHolder.OccupiesTurret(siegeEngineID)); +TS_ASSERT(cmpTurretHolder.LeaveTurret(archerID)); + +// Renaming into an entity not allowed on the same turret point hides us. +TS_ASSERT(cmpTurretHolder.OccupyTurret(siegeEngineID, cmpTurretHolder.turretPoints[1])); +cmpTurretHolder.SwapEntities(siegeEngineID, archerID); +TS_ASSERT(!cmpTurretHolder.OccupiesTurret(siegeEngineID)); +TS_ASSERT(!cmpTurretHolder.OccupiesTurret(archerID)); + +// ToDo: Ownership changes are handled by GarrisonHolder.js. Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_long.xml @@ -4,8 +4,8 @@ 9.0 - - + + 0 11.5 @@ -31,8 +31,8 @@ 11.5 0 - - + + athen Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/athen_wall_medium.xml @@ -4,8 +4,8 @@ 12.5 - - + + 0 11.5 @@ -21,8 +21,8 @@ 11.5 0 - - + + athen Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_long.xml @@ -4,8 +4,8 @@ 10.3 - - + + 0 9.3 @@ -31,8 +31,8 @@ 9.3 0 - - + + brit Rate Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/brit_wall_medium.xml @@ -4,8 +4,8 @@ 10.3 - - + + 0 9.3 @@ -21,8 +21,8 @@ 9.3 0 - - + + brit Rate Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_long.xml @@ -4,8 +4,8 @@ 13 - - + + 0 12 @@ -31,8 +31,8 @@ 12 0 - - + + cart Homah Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/cart_wall_medium.xml @@ -4,8 +4,8 @@ 13 - - + + 0 12 @@ -21,8 +21,8 @@ 12 0 - - + + cart Homah Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_long.xml @@ -4,8 +4,8 @@ 10.3 - - + + 0 9.3 @@ -31,8 +31,8 @@ 9.3 0 - - + + gaul Rate Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/gaul_wall_medium.xml @@ -4,8 +4,8 @@ 10.3 - - + + 0 9.3 @@ -21,8 +21,8 @@ 9.3 0 - - + + gaul Rate Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_long.xml @@ -4,8 +4,8 @@ 10 - - + + 0 9 @@ -31,8 +31,8 @@ 9 0 - - + + iber Zabal Horma Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber_wall_medium.xml @@ -4,8 +4,8 @@ 10 - - + + 0 9 @@ -21,8 +21,8 @@ 9 0 - - + + iber Zabal Horma Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_long.xml @@ -4,8 +4,8 @@ 12.6 - - + + 0 11.6 @@ -31,8 +31,8 @@ 11.6 0 - - + + kush sbty Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/kush_wall_medium.xml @@ -4,8 +4,8 @@ 12.6 - - + + 0 11.6 @@ -21,8 +21,8 @@ 11.6 0 - - + + kush sbty Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_long.xml @@ -4,8 +4,8 @@ 12.5 - - + + 0 11.5 @@ -31,8 +31,8 @@ 11.5 0 - - + + mace Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/mace_wall_medium.xml @@ -4,8 +4,8 @@ 12.5 - - + + 0 11.5 @@ -21,8 +21,8 @@ 11.5 0 - - + + mace Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_tower_double.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_tower_double.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_tower_double.xml @@ -23,7 +23,9 @@ Infantry+Archer 20 - + + + 212.50 @@ -72,8 +74,8 @@ -2.118.0-2.1 - - + + 1200 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_long.xml @@ -10,8 +10,8 @@ 10.5 - - + + 0 9.5 @@ -37,8 +37,8 @@ 9.5 0 - - + + maur Shilabanda Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur_wall_medium.xml @@ -10,8 +10,8 @@ 10.5 - - + + 0 9.5 @@ -27,8 +27,8 @@ 9.5 0 - - + + maur Shilabanda Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_long.xml @@ -4,8 +4,8 @@ 11.6 - - + + 0 10.6 @@ -31,8 +31,8 @@ 10.6 0 - - + + pers Para Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/pers_wall_medium.xml @@ -4,8 +4,8 @@ 11.6 - - + + 0 10.6 @@ -21,8 +21,8 @@ 10.6 0 - - + + pers Para Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_long.xml @@ -4,8 +4,8 @@ 10.8 - - + + 0 9.8 @@ -31,8 +31,8 @@ 9.8 0 - - + + ptol Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol_wall_medium.xml @@ -4,8 +4,8 @@ 10.8 - - + + 0 9.8 @@ -21,8 +21,8 @@ 9.8 0 - - + + ptol Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_long.xml @@ -23,8 +23,8 @@ 6.7 - - + + 0 5.7 @@ -50,8 +50,8 @@ 5.7 0 - - + + 0.75 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_siege_wall_medium.xml @@ -23,8 +23,8 @@ 6.7 - - + + 0 5.7 @@ -40,8 +40,8 @@ 5.7 0 - - + + 0.75 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_long.xml @@ -4,8 +4,8 @@ 9.9 - - + + 0 8.9 @@ -31,8 +31,8 @@ 8.9 0 - - + + rome Moenia Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome_wall_medium.xml @@ -4,8 +4,8 @@ 9.9 - - + + 0 8.9 @@ -21,8 +21,8 @@ 8.9 0 - - + + rome Moenia Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_long.xml @@ -4,8 +4,8 @@ 11.4 - - + + 0 10.4 @@ -31,8 +31,8 @@ 10.4 0 - - + + sele Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/sele_wall_medium.xml @@ -4,8 +4,8 @@ 11.4 - - + + 0 10.4 @@ -21,8 +21,8 @@ 10.4 0 - - + + sele Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_long.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_long.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_long.xml @@ -4,8 +4,8 @@ 12.5 - - + + 0 11.5 @@ -31,8 +31,8 @@ 11.5 0 - - + + spart Teichos Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_medium.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_medium.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/spart_wall_medium.xml @@ -4,8 +4,8 @@ 12.5 - - + + 0 11.5 @@ -21,8 +21,8 @@ 11.5 0 - - + + spart Teichos