Index: binaries/data/mods/public/gui/session/selection_panels.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels.js
+++ binaries/data/mods/public/gui/session/selection_panels.js
@@ -291,16 +291,13 @@
if (unitEntStates.some(state => !hasClass(state, "Unit")))
return [];
+ if(!canAllEntsUseAnyFormation())
+ return [];
+
if (!g_AvailableFormations.has(unitEntStates[0].player))
g_AvailableFormations.set(unitEntStates[0].player, Engine.GuiInterfaceCall("GetAvailableFormations", unitEntStates[0].player));
- let availableFormations = g_AvailableFormations.get(unitEntStates[0].player);
-
- // Hide the panel if all formations are disabled
- if (availableFormations.some(formation => canMoveSelectionIntoFormation(formation)))
- return availableFormations;
-
- return [];
+ return g_AvailableFormations.get(unitEntStates[0].player);
},
"setupButton": function(data)
{
Index: binaries/data/mods/public/gui/session/selection_panels_helpers.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -17,6 +17,13 @@
return g_canMoveIntoFormation[formationTemplate];
}
+function canAllEntsUseAnyFormation()
+{
+ return Engine.GuiInterfaceCall("CanAllEntsUseAnyFormation", {
+ "ents": g_Selection.toList()
+ });
+}
+
function hasSameRestrictionCategory(templateName1, templateName2)
{
let template1 = GetTemplateData(templateName1);
Index: binaries/data/mods/public/simulation/components/Formation.js
===================================================================
--- binaries/data/mods/public/simulation/components/Formation.js
+++ binaries/data/mods/public/simulation/components/Formation.js
@@ -7,8 +7,12 @@
"" +
"" +
"" +
- "" +
- "" +
+ ""+
+ ""+
+ ""+
+ "2"+
+ ""+
+ ""+
"" +
"" +
"" +
@@ -75,6 +79,7 @@
Formation.prototype.Init = function()
{
+ this.requiredMemberCount = this.template.RequiredMemberCount;
this.formationShape = this.template.FormationShape;
this.sortingClasses = this.template.SortingClasses.split(/\s+/g);
this.sortingOrder = this.template.SortingOrder;
@@ -325,16 +330,16 @@
this.members = this.members.filter(function(e) { return ents.indexOf(e) == -1; });
this.inPosition = this.inPosition.filter(function(e) { return ents.indexOf(e) == -1; });
- for (var ent of ents)
+ for (let ent of ents)
{
- var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
+ let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
cmpUnitAI.UpdateWorkOrders();
cmpUnitAI.SetFormationController(INVALID_ENTITY);
}
- for (var ent of this.formationMembersWithAura)
+ for (let ent of this.formationMembersWithAura)
{
- var cmpAuras = Engine.QueryInterface(ent, IID_Auras);
+ let cmpAuras = Engine.QueryInterface(ent, IID_Auras);
cmpAuras.RemoveFormationBonus(ents);
// the unit with the aura is also removed from the formation
@@ -344,10 +349,9 @@
this.formationMembersWithAura = this.formationMembersWithAura.filter(function(e) { return ents.indexOf(e) == -1; });
- // If there's nobody left, destroy the formation
- if (this.members.length == 0)
+ if (this.members.length < this.requiredMemberCount)
{
- Engine.DestroyEntity(this.entity);
+ this.Disband();
return;
}
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js
+++ binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -714,6 +714,11 @@
return CanMoveEntsIntoFormation(data.ents, data.formationTemplate);
};
+GuiInterface.prototype.CanAllEntsUseAnyFormation = function(player, data)
+{
+ return CanAllEntsUseAnyFormation(data.ents);
+};
+
GuiInterface.prototype.GetFormationInfoFromTemplate = function(player, data)
{
let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
@@ -1926,6 +1931,7 @@
"GetAvailableFormations": 1,
"GetFormationRequirements": 1,
"CanMoveEntsIntoFormation": 1,
+ "CanAllEntsUseAnyFormation": 1,
"IsFormationSelected": 1,
"GetFormationInfoFromTemplate": 1,
"IsStanceSelected": 1,
Index: binaries/data/mods/public/simulation/helpers/Commands.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Commands.js
+++ binaries/data/mods/public/simulation/helpers/Commands.js
@@ -1659,6 +1659,17 @@
return count >= requirements.minCount;
}
+function CanAllEntsUseAnyFormation(ents)
+{
+ for(let ent of ents)
+ {
+ let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
+ if(!cmpIdentity || cmpIdentity.GetFormationsList().length == 0)
+ return false;
+ }
+ return true;
+}
+
/**
* Check if player can control this entity
* returns: true if the entity is valid and owned by the player
@@ -1721,6 +1732,7 @@
Engine.RegisterGlobal("GetFormationRequirements", GetFormationRequirements);
Engine.RegisterGlobal("CanMoveEntsIntoFormation", CanMoveEntsIntoFormation);
+Engine.RegisterGlobal("CanAllEntsUseAnyFormation", CanAllEntsUseAnyFormation);
Engine.RegisterGlobal("GetDockAngle", GetDockAngle);
Engine.RegisterGlobal("ProcessCommand", ProcessCommand);
Engine.RegisterGlobal("g_Commands", g_Commands);
Index: binaries/data/mods/public/simulation/templates/special/formations/null.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/special/formations/null.xml
+++ binaries/data/mods/public/simulation/templates/special/formations/null.xml
@@ -3,5 +3,6 @@
formations/null.png
None
+
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
@@ -22,8 +22,8 @@
-->
- 1
-
+ 2
+ At least 2 units required
1
square
Hero Champion Cavalry Melee Ranged