From b8ee766cd34e2929cef7c854ac2650f1fe17a115 Mon Sep 17 00:00:00 2001 From: sanderd17 Date: Sun, 5 Jan 2014 17:13:22 +0000 Subject: [PATCH] Remove some hardcoded formation shapes. Some special formations still have a special treatment though. Also implement speed modifiers for formations, so we can have faster and slower formations. This was SVN commit r14516. --- .../public/simulation/components/Formation.js | 220 +++++++++--------- .../templates/formations/battle_line.xml | 5 + .../simulation/templates/formations/box.xml | 1 + .../templates/formations/column_closed.xml | 4 +- .../templates/formations/column_open.xml | 4 + .../simulation/templates/formations/flank.xml | 1 + .../templates/formations/line_closed.xml | 2 + .../templates/formations/line_open.xml | 4 + .../templates/formations/phalanx.xml | 4 + .../templates/formations/scatter.xml | 1 + .../templates/formations/skirmish.xml | 4 + .../simulation/templates/formations/wedge.xml | 1 + .../templates/template_formation.xml | 9 +- 13 files changed, 143 insertions(+), 117 deletions(-) diff --git a/binaries/data/mods/public/simulation/components/Formation.js b/binaries/data/mods/public/simulation/components/Formation.js index 75f0d773df..70e706d9a0 100644 --- a/binaries/data/mods/public/simulation/components/Formation.js +++ b/binaries/data/mods/public/simulation/components/Formation.js @@ -3,12 +3,56 @@ function Formation() {} Formation.prototype.Schema = "" + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + ""; var g_ColumnDistanceThreshold = 128; // distance at which we'll switch between column/box formations Formation.prototype.Init = function() { + this.formationShape = this.template.FormationShape; + this.shiftRows = this.template.ShiftRows == "true"; + this.separationMultiplier = { + "width": +this.template.UnitSeparationWidthMultiplier, + "depth": +this.template.UnitSeparationDepthMultiplier + }; + this.widthDepthRatio = +this.template.WidthDepthRatio; + this.minColumns = +(this.template.MinColumns || 0); + this.maxColumns = +(this.template.MaxColumns || 0); + this.maxRows = +(this.template.MaxRows || 0); + this.members = []; // entity IDs currently belonging to this formation this.inPosition = []; // entities that have reached their final position this.columnar = false; // whether we're travelling in column (vs box) formation @@ -38,6 +82,11 @@ Formation.prototype.GetSize = function() return {"width": this.width, "depth": this.depth}; }; +Formation.prototype.GetSpeedMultiplier = function() +{ + return +this.template.SpeedMultiplier; +}; + Formation.prototype.GetMemberCount = function() { return this.members.length; @@ -456,6 +505,8 @@ Formation.prototype.GetAvgFootprint = function(active) Formation.prototype.ComputeFormationOffsets = function(active, positions, columnar) { var separation = this.GetAvgFootprint(active); + separation.width *= this.separationMultiplier.width; + separation.depth *= this.separationMultiplier.depth; // the entities will be assigned to positions in the formation in // the same order as the types list is ordered @@ -483,14 +534,12 @@ Formation.prototype.ComputeFormationOffsets = function(active, positions, column } } if (!done) - { types["Unknown"].push({"ent": active[i], "pos": positions[i]}); - } } var count = active.length; - var shape = undefined; + var shape = this.formationShape; var ordering = []; var offsets = []; @@ -499,73 +548,30 @@ Formation.prototype.ComputeFormationOffsets = function(active, positions, column var cols; if (columnar) - var formationName = "Column Closed"; - else - var formationName = this.formationName; - - switch(formationName) { - case "Column Closed": - // Have at most 3 files - if (count <= 3) - cols = count; - else - cols = 3; shape = "square"; - break; - case "Phalanx": - // Try to have at least 5 files (so batch training gives a single line), - // and at most 8 - if (count <= 5) - cols = count; - else if (count <= 10) - cols = 5; - else if (count <= 16) - cols = Math.ceil(count/2); - else if (count <= 48) - cols = 8; - else - cols = Math.ceil(count/6); - separation.width *= 0.7; - shape = "square"; - break; - case "Line Closed": - if (count <= 3) - cols = count; - else if (count < 30) - cols = Math.max(Math.ceil(count/2), 3); - else - cols = Math.ceil(count/3); - shape = "square"; - ordering = ["FillFromTheCenter", "FillFromTheFront"]; - break; - case "Testudo": - cols = Math.ceil(Math.sqrt(count)); - shape = "square"; - break; - case "Column Open": - cols = 2; - shape = "opensquare"; - break; - case "Line Open": - if (count <= 5) - cols = 3; - else if (count <= 11) - cols = 4; - else if (count <= 18) - cols = 5; - else - cols = 6; - shape = "opensquare"; - ordering = ["FillFromTheCenter", "FillFromTheFront"]; - break; + cols = Math.min(count,3); + } + else + { + var depth = Math.sqrt(count / this.widthDepthRatio); + if (this.maxRows && depth > this.maxRows) + depth = this.maxRows; + cols = Math.ceil(count / Math.ceil(depth) + (this.shiftRows ? 0.5 : 0)); + if (cols < this.minColumns) + cols = Math.min(count, this.minColumns); + if (this.maxColumns && cols > this.maxColumns && this.maxRows != depth) + cols = this.maxColumns; + } + + // define special formations here + switch(this.formationName) + { case "Scatter": var width = Math.sqrt(count) * (separation.width + separation.depth) * 2.5; for (var i = 0; i < count; ++i) - { offsets.push({"x": Math.random()*width, "z": Math.random()*width}); - } break; case "Box": var root = Math.ceil(Math.sqrt(count)); @@ -609,10 +615,6 @@ Formation.prototype.ComputeFormationOffsets = function(active, positions, column } } break; - case "Skirmish": - cols = Math.ceil(count/2); - shape = "opensquare"; - break; case "Wedge": var depth = Math.ceil(Math.sqrt(count)); @@ -667,63 +669,40 @@ Formation.prototype.ComputeFormationOffsets = function(active, positions, column } ordering.push("FillFromTheCenter"); break; - case "Syntagma": - cols = Math.ceil(Math.sqrt(count)); - shape = "square"; - break; case "Battle Line": - if (count <= 5) - cols = count; - else if (count <= 10) - cols = 5; - else if (count <= 16) - cols = Math.ceil(count/2); - else if (count <= 48) - cols = 8; - else - cols = Math.ceil(count/6); - shape = "opensquare"; - separation.width /= 2; - separation.depth /= 1.5; ordering.push("FillFromTheSides"); break; default: - warn("Unknown formation: " + formationName); break; } if (shape == "square") { - var ranks = Math.ceil(count / cols); + var r = 0; + var left = count; + while (left > 0) + { + var n = cols; + var sign = 1; + if (this.shiftRows) + n -= r%2; + else if (n > left) + n = left; + for (var c = 0; c < n && left > 0; ++c) + { + sign *= -1; + if (n%2 == 0) + var x = sign * (Math.floor(c/2) + 0.5) * separation.width; + else + var x = sign * Math.ceil(c/2) * separation.width; + var z = -r * separation.depth; + offsets.push({"x": x, "z": z}); + left-- + } + ++r; + } + } - var left = count; - for (var r = 0; r < ranks; ++r) - { - var n = Math.min(left, cols); - for (var c = 0; c < n; ++c) - { - var x = ((n-1)/2 - c) * separation.width; - var z = -r * separation.depth; - offsets.push({"x": x, "z": z}); - } - left -= n; - } - } - else if (shape == "opensquare") - { - var left = count; - for (var r = 0; left; ++r) - { - var n = Math.min(left, cols - (r&1?1:0)); - for (var c = 0; c < 2*n; c+=2) - { - var x = (- c - (r&1)) * separation.width; - var z = -r * separation.depth; - offsets.push({"x": x, "z": z}); - } - left -= n; - } - } // make sure the average offset is zero, as the formation is centered around that // calculating offset distances without a zero average makes no sense, as the formation // will jump to a different position any time @@ -870,6 +849,7 @@ Formation.prototype.ComputeMotionParameters = function() if (cmpUnitMotion) minSpeed = Math.min(minSpeed, cmpUnitMotion.GetWalkSpeed()); } + minSpeed *= this.GetSpeedMultiplier(); var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); cmpUnitMotion.SetUnitRadius(maxRadius); @@ -981,6 +961,12 @@ Formation.prototype.DeleteTwinFormations = function() Formation.prototype.LoadFormation = function(formationName) { + if (formationName == this.formationName) + { + var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); + cmpUnitAI.MoveIntoFormation(); + return; + } var members = this.members; this.Disband(); var newFormation = Engine.AddEntity("formations/"+formationName.replace(/\s+/g, "_").toLowerCase()); @@ -990,7 +976,11 @@ Formation.prototype.LoadFormation = function(formationName) var cmpThisUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); var cmpNewUnitAI = Engine.QueryInterface(newFormation, IID_UnitAI); - cmpNewUnitAI.AddOrders(cmpThisUnitAI.GetOrders()); + var orders = cmpThisUnitAI.GetOrders(); + if (orders.length) + cmpNewUnitAI.AddOrders(orders); + else + cmpNewUnitAI.MoveIntoFormation(); }; diff --git a/binaries/data/mods/public/simulation/templates/formations/battle_line.xml b/binaries/data/mods/public/simulation/templates/formations/battle_line.xml index 2714abc80b..27a48da2f4 100644 --- a/binaries/data/mods/public/simulation/templates/formations/battle_line.xml +++ b/binaries/data/mods/public/simulation/templates/formations/battle_line.xml @@ -2,5 +2,10 @@ Battle Line + true + 5 + 8 + 6 + 2 diff --git a/binaries/data/mods/public/simulation/templates/formations/box.xml b/binaries/data/mods/public/simulation/templates/formations/box.xml index 9ab221cefc..8820ffc8cb 100644 --- a/binaries/data/mods/public/simulation/templates/formations/box.xml +++ b/binaries/data/mods/public/simulation/templates/formations/box.xml @@ -2,5 +2,6 @@ Box + special diff --git a/binaries/data/mods/public/simulation/templates/formations/column_closed.xml b/binaries/data/mods/public/simulation/templates/formations/column_closed.xml index 140e711b5d..5aab432c5d 100644 --- a/binaries/data/mods/public/simulation/templates/formations/column_closed.xml +++ b/binaries/data/mods/public/simulation/templates/formations/column_closed.xml @@ -1,6 +1,8 @@ - + Column Closed + 3 + 3 diff --git a/binaries/data/mods/public/simulation/templates/formations/column_open.xml b/binaries/data/mods/public/simulation/templates/formations/column_open.xml index 43611b9d51..ed7327f158 100644 --- a/binaries/data/mods/public/simulation/templates/formations/column_open.xml +++ b/binaries/data/mods/public/simulation/templates/formations/column_open.xml @@ -2,5 +2,9 @@ Column Open + true + 2 + 2 + 2 diff --git a/binaries/data/mods/public/simulation/templates/formations/flank.xml b/binaries/data/mods/public/simulation/templates/formations/flank.xml index 44a028ce65..fecb5c374d 100644 --- a/binaries/data/mods/public/simulation/templates/formations/flank.xml +++ b/binaries/data/mods/public/simulation/templates/formations/flank.xml @@ -2,5 +2,6 @@ Flank + special diff --git a/binaries/data/mods/public/simulation/templates/formations/line_closed.xml b/binaries/data/mods/public/simulation/templates/formations/line_closed.xml index 5f77a2698e..ff48f8e322 100644 --- a/binaries/data/mods/public/simulation/templates/formations/line_closed.xml +++ b/binaries/data/mods/public/simulation/templates/formations/line_closed.xml @@ -2,5 +2,7 @@ Line Closed + 3 + 4 diff --git a/binaries/data/mods/public/simulation/templates/formations/line_open.xml b/binaries/data/mods/public/simulation/templates/formations/line_open.xml index 0968510189..1ba5604a2c 100644 --- a/binaries/data/mods/public/simulation/templates/formations/line_open.xml +++ b/binaries/data/mods/public/simulation/templates/formations/line_open.xml @@ -2,5 +2,9 @@ Line Open + true + 2 + 3 + 3 diff --git a/binaries/data/mods/public/simulation/templates/formations/phalanx.xml b/binaries/data/mods/public/simulation/templates/formations/phalanx.xml index cf0e66a389..84e8c3ad5c 100644 --- a/binaries/data/mods/public/simulation/templates/formations/phalanx.xml +++ b/binaries/data/mods/public/simulation/templates/formations/phalanx.xml @@ -2,5 +2,9 @@ Phalanx + 5 + 8 + 6 + 2 diff --git a/binaries/data/mods/public/simulation/templates/formations/scatter.xml b/binaries/data/mods/public/simulation/templates/formations/scatter.xml index 12e6b1b488..a380ce0468 100644 --- a/binaries/data/mods/public/simulation/templates/formations/scatter.xml +++ b/binaries/data/mods/public/simulation/templates/formations/scatter.xml @@ -2,5 +2,6 @@ Scatter + special diff --git a/binaries/data/mods/public/simulation/templates/formations/skirmish.xml b/binaries/data/mods/public/simulation/templates/formations/skirmish.xml index b55d21daff..f8c723f846 100644 --- a/binaries/data/mods/public/simulation/templates/formations/skirmish.xml +++ b/binaries/data/mods/public/simulation/templates/formations/skirmish.xml @@ -2,5 +2,9 @@ Skirmish + true + 2 + 2 + 3 diff --git a/binaries/data/mods/public/simulation/templates/formations/wedge.xml b/binaries/data/mods/public/simulation/templates/formations/wedge.xml index da9287f0e2..a1ad2aa632 100644 --- a/binaries/data/mods/public/simulation/templates/formations/wedge.xml +++ b/binaries/data/mods/public/simulation/templates/formations/wedge.xml @@ -2,5 +2,6 @@ Wedge + special diff --git a/binaries/data/mods/public/simulation/templates/template_formation.xml b/binaries/data/mods/public/simulation/templates/template_formation.xml index a026182488..deaf33de0c 100644 --- a/binaries/data/mods/public/simulation/templates/template_formation.xml +++ b/binaries/data/mods/public/simulation/templates/template_formation.xml @@ -5,7 +5,14 @@ props/special/common/waypoint_flag.xml --> - + + 1 + square + false + 1 + 1 + 1 + 0