Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -24,6 +24,9 @@ "" + "" + "" + + "" + + "" + + "" + "" + "" + "" + @@ -494,7 +497,7 @@ // It's not too bad if we don't arrive at exactly the right position. this.order.data.relaxed = true; - this.SetNextState("INDIVIDUAL.PATROL"); + this.SetNextState("INDIVIDUAL.PATROL.PATROLLING"); }, "Order.Heal": function(msg) { @@ -735,7 +738,7 @@ "Order.Patrol": function(msg) { this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); - this.SetNextState("PATROL"); + this.SetNextState("PATROL.PATROLLING"); }, "Order.Guard": function(msg) { @@ -1000,7 +1003,7 @@ }, "PATROL": { - "enter": function(msg) { + "enter": function() { // Memorize the origin position in case that we want to go back let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); if (!cmpPosition || !cmpPosition.IsInWorld()) @@ -1008,6 +1011,7 @@ this.FinishOrder(); return true; } + if (!this.patrolStartPosOrder) { this.patrolStartPosOrder = cmpPosition.GetPosition(); @@ -1015,49 +1019,77 @@ this.patrolStartPosOrder.allowCapture = this.order.data.allowCapture; } - if (!this.MoveTo(this.order.data)) - { - this.FinishOrder(); - return true; - } - this.StartTimer(0, 1000); + this.SetAnimationVariant("combat"); - let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); - cmpFormation.SetRearrange(true); - cmpFormation.MoveMembersIntoFormation(true, true, "combat"); return false; }, - "Timer": function(msg) { - // Check if there are no enemies to attack - this.FindWalkAndFightTargets(); - }, - - "leave": function(msg) { - this.StopTimer(); - this.StopMoving(); + "leave": function() { delete this.patrolStartPosOrder; + this.SetDefaultAnimationVariant(); }, - "MovementUpdate": function(msg) { - if (!msg.likelyFailure && !this.CheckRange(this.order.data)) - return; - /** - * A-B-A-B-..: - * if the user only commands one patrol order, the patrol will be between - * the last position and the defined waypoint - * A-B-C-..-A-B-..: - * otherwise, the patrol is only between the given patrol commands and the - * last position is not included (last position = the position where the unit - * is located at the time of the first patrol order) - */ - - if (this.orderQueue.length == 1) - this.PushOrder("Patrol", this.patrolStartPosOrder); - - this.PushOrder(this.order.type, this.order.data); - this.FinishOrder(); + "PATROLLING": { + "enter": function() { + let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld() || + !this.MoveTo(this.order.data)) + { + this.FinishOrder(); + return true; + } + + let cmpFormation = Engine.QueryInterface(this.entity, IID_Formation); + cmpFormation.SetRearrange(true); + cmpFormation.MoveMembersIntoFormation(true, true, "combat"); + + this.StartTimer(0, 1000); + return false; + }, + + "leave": function() { + this.StopMoving(); + this.StopTimer(); + }, + + "Timer": function(msg) { + this.FindWalkAndFightTargets(); + }, + + "MovementUpdate": function(msg) { + if (!msg.likelyFailure && !msg.likelySuccess && !this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange)) + return; + + if (this.orderQueue.length == 1) + this.PushOrder("Patrol", this.patrolStartPosOrder); + + this.PushOrder(this.order.type, this.order.data); + this.SetNextState("CHECKINGWAYPOINT"); + }, }, + + "CHECKINGWAYPOINT": { + "enter": function() { + this.StartTimer(0, 1000); + this.stopSurveying = 0; + return false; + }, + + "leave": function() { + this.StopTimer(); + delete this.stopSurveying; + }, + + "Timer": function(msg) { + if (this.stopSurveying >= this.template.PatrolWaitTime) + { + this.FinishOrder(); + return; + } + this.FindWalkAndFightTargets(); + this.stopSurveying++; + } + } }, "GARRISON":{ @@ -1645,8 +1677,7 @@ "enter": function() { // Memorize the origin position in case that we want to go back let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (!cmpPosition || !cmpPosition.IsInWorld() || - !this.MoveTo(this.order.data)) + if (!cmpPosition || !cmpPosition.IsInWorld()) { this.FinishOrder(); return true; @@ -1659,32 +1690,72 @@ this.patrolStartPosOrder.allowCapture = this.order.data.allowCapture; } - this.StartTimer(0, 1000); this.SetAnimationVariant("combat"); + return false; }, "leave": function() { - this.StopMoving(); - this.StopTimer(); delete this.patrolStartPosOrder; this.SetDefaultAnimationVariant(); }, - "Timer": function(msg) { - this.FindWalkAndFightTargets(); - }, + "PATROLLING": { + "enter": function() { + let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld() || + !this.MoveTo(this.order.data)) + { + this.FinishOrder(); + return true; + } + this.StartTimer(0, 1000); + return false; + }, + + "leave": function() { + this.StopMoving(); + this.StopTimer(); + }, + + "Timer": function(msg) { + this.FindWalkAndFightTargets(); + }, - "MovementUpdate": function(msg) { - if (!msg.likelyFailure && !msg.likelySuccess && !this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange)) - return; + "MovementUpdate": function(msg) { + if (!msg.likelyFailure && !msg.likelySuccess && !this.RelaxedMaxRangeCheck(this.order.data, this.DefaultRelaxedMaxRange)) + return; - if (this.orderQueue.length == 1) - this.PushOrder("Patrol", this.patrolStartPosOrder); + if (this.orderQueue.length == 1) + this.PushOrder("Patrol", this.patrolStartPosOrder); - this.PushOrder(this.order.type, this.order.data); - this.FinishOrder(); + this.PushOrder(this.order.type, this.order.data); + this.SetNextState("CHECKINGWAYPOINT"); + }, }, + + "CHECKINGWAYPOINT": { + "enter": function() { + this.StartTimer(0, 1000); + this.stopSurveying = 0; + return false; + }, + + "leave": function() { + this.StopTimer(); + delete this.stopSurveying; + }, + + "Timer": function(msg) { + if (this.stopSurveying >= this.template.PatrolWaitTime) + { + this.FinishOrder(); + return; + } + this.FindWalkAndFightTargets(); + this.stopSurveying++; + } + } }, "GUARD": { Index: binaries/data/mods/public/simulation/templates/template_bird.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_bird.xml +++ binaries/data/mods/public/simulation/templates/template_bird.xml @@ -26,6 +26,7 @@ false false false + 0 1000.0 10.0 10000 Index: binaries/data/mods/public/simulation/templates/template_formation.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_formation.xml +++ binaries/data/mods/public/simulation/templates/template_formation.xml @@ -1,6 +1,5 @@ - 2 Requires at least 2 Soldiers or Siege engines. @@ -65,6 +63,7 @@ 12.0 true true + 2 true Index: binaries/data/mods/public/simulation/templates/template_unit.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit.xml +++ binaries/data/mods/public/simulation/templates/template_unit.xml @@ -126,6 +126,7 @@ false true true + 1 false