forked from 0ad/0ad
Make selected stances and formations more obvious. Patch from leper, fixes #1190.
This was SVN commit r11386.
This commit is contained in:
parent
a957455647
commit
0d385f4112
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/commands.png
(Stored with Git LFS)
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/commands.png
(Stored with Git LFS)
Binary file not shown.
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/formation_nonselect.png
(Stored with Git LFS)
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/formation_nonselect.png
(Stored with Git LFS)
Binary file not shown.
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/formation_select.png
(Stored with Git LFS)
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/formation_select.png
(Stored with Git LFS)
Binary file not shown.
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/stance.dds
(Stored with Git LFS)
BIN
binaries/data/mods/public/art/textures/ui/session/icons/sheets/stance.dds
(Stored with Git LFS)
Binary file not shown.
@ -1,5 +0,0 @@
|
||||
aggress,Aggress,
|
||||
defend,Defend,
|
||||
avoid,Avoid,
|
||||
stand,Stand,
|
||||
hold,Hold,
|
@ -972,95 +972,6 @@
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<!--
|
||||
==========================================
|
||||
SESSION GUI - ICON SHEETS - STANCE
|
||||
==========================================
|
||||
-->
|
||||
|
||||
<sprite name="snIconSheetStance">
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceOver">
|
||||
<effect add_color="42 42 42 0"/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceDisabled">
|
||||
<effect grayscale=""/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite name="snIconSheetStanceButton">
|
||||
<image texture="session/icons/bkg/portrait.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceButtonOver">
|
||||
<effect add_color="42 42 42 0"/>
|
||||
<image texture="session/icons/bkg/portrait.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceButtonDisabled">
|
||||
<effect grayscale=""/>
|
||||
<image texture="session/icons/bkg/portrait.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite name="snIconSheetStanceTabButton">
|
||||
<image texture="session/icons/bkg/tab.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceTabButtonOver">
|
||||
<image texture="session/icons/bkg/tab.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image
|
||||
texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
>
|
||||
<effect add_color="42 42 42 0"/>
|
||||
</image>
|
||||
</sprite>
|
||||
<sprite name="snIconSheetStanceTabButtonDisabled">
|
||||
<effect grayscale=""/>
|
||||
<image texture="session/icons/bkg/tab.dds"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
<image texture="session/icons/sheets/stance.dds"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<!--
|
||||
==========================================
|
||||
SESSION GUI - ICON SHEETS - STATISTIC
|
||||
|
@ -593,10 +593,10 @@
|
||||
<!-- Stats -->
|
||||
<object size="8 36 50%-48 100%" name="statsArea" type="image">
|
||||
<!-- Attack icon -->
|
||||
<object hidden="true" size="0 0 48 48" type="image" name="attackIcon" sprite="snIconSheetStance" cell_id="1" tooltip_style="sessionToolTip"/>
|
||||
|
||||
<object hidden="true" size="0 0 48 48" type="image" name="attackIcon" sprite="stretched:session/icons/single/stance-aggressive.png" tooltip_style="sessionToolTip"/>
|
||||
|
||||
<!-- Armour icon "0 48 48 96"-->
|
||||
<object size="0 0 48 48" type="image" name="armourIcon" sprite="snIconSheetStance" cell_id="3" tooltip_style="sessionToolTip"/>
|
||||
<object size="0 0 48 48" type="image" name="armourIcon" sprite="stretched:session/icons/single/stance-defensive.png" tooltip_style="sessionToolTip"/>
|
||||
|
||||
<!-- Resource carrying icon/counter -->
|
||||
<object size="0 40 48 88" type="image" name="resourceCarryingIcon" style="resourceIcon"/>
|
||||
|
@ -17,33 +17,6 @@
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Unit Command Icons -->
|
||||
<!-- ================================ ================================ -->
|
||||
<sprite name="formation">
|
||||
<image
|
||||
texture="session/icons/sheets/formation_select.png"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite name="formation_disabled">
|
||||
<image
|
||||
texture="session/icons/sheets/formation_nonselect.png"
|
||||
cell_size="64 64"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite name="commands">
|
||||
<image
|
||||
texture="session/icons/sheets/commands.png"
|
||||
cell_size="32 32"
|
||||
size="0 0 100% 100%"
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Menu -->
|
||||
<!-- ================================ ================================ -->
|
||||
|
@ -304,24 +304,47 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
|
||||
// Get icon image
|
||||
if (guiName == "Formation")
|
||||
{
|
||||
icon.cell_id = getFormationCellId(item);
|
||||
var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", {
|
||||
"ents": g_Selection.toList(),
|
||||
"formationName": item
|
||||
});
|
||||
|
||||
icon.enabled = formationOk;
|
||||
button.enabled = formationOk;
|
||||
if (!icon.enabled)
|
||||
{
|
||||
icon.sprite = "formation_disabled";
|
||||
button.tooltip += " (disabled)";
|
||||
}
|
||||
else
|
||||
{
|
||||
icon.sprite = "formation";
|
||||
}
|
||||
}
|
||||
if (!formationOk)
|
||||
{
|
||||
icon.sprite = "stretched:session/icons/formations/formation-"+item.replace(/\s+/,'').toLowerCase()+".png";
|
||||
|
||||
// Display a meaningful tooltip why the formation is disabled
|
||||
var requirements = Engine.GuiInterfaceCall("GetFormationRequirements", {
|
||||
"formationName": item
|
||||
});
|
||||
|
||||
button.tooltip += " (disabled)";
|
||||
if (requirements.count > 1)
|
||||
button.tooltip += "\n" + requirements.count + " units required";
|
||||
if (requirements.classesRequired)
|
||||
{
|
||||
button.tooltip += "\nOnly units of type";
|
||||
for each (var classRequired in requirements.classesRequired)
|
||||
{
|
||||
button.tooltip += " " + classRequired;
|
||||
}
|
||||
button.tooltip += " allowed.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var formationSelected = Engine.GuiInterfaceCall("IsFormationSelected", {
|
||||
"ents": g_Selection.toList(),
|
||||
"formationName": item
|
||||
});
|
||||
|
||||
if (formationSelected)
|
||||
icon.sprite = "stretched:session/icons/formations/formation-"+item.replace(/\s+/,'').toLowerCase()+"-selected.png";
|
||||
else
|
||||
icon.sprite = "stretched:session/icons/formations/formation-"+item.replace(/\s+/,'').toLowerCase()+"-available.png";
|
||||
}
|
||||
}
|
||||
else if (guiName == "Stance")
|
||||
{
|
||||
var stanceSelected = Engine.GuiInterfaceCall("IsStanceSelected", {
|
||||
@ -329,16 +352,13 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
|
||||
"stance": item
|
||||
});
|
||||
|
||||
icon.cell_id = i;
|
||||
if (stanceSelected)
|
||||
icon.sprite = "snIconSheetStanceButton";
|
||||
icon.sprite = "stretched:session/icons/single/stance-"+item+"-select.png";
|
||||
else
|
||||
icon.sprite = "snIconSheetStanceButtonDisabled";
|
||||
icon.sprite = "stretched:session/icons/single/stance-"+item+".png";
|
||||
}
|
||||
else if (guiName == "Command")
|
||||
{
|
||||
//icon.cell_id = i;
|
||||
//icon.cell_id = getCommandCellId(item);
|
||||
icon.sprite = "stretched:session/icons/single/" + item.icon;
|
||||
|
||||
}
|
||||
@ -520,7 +540,7 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
||||
|
||||
// TODO: probably should load the stance list from a data file,
|
||||
// and/or vary depending on what units are selected
|
||||
var stances = ["violent", "aggressive", "passive", "defensive", "stand"];
|
||||
var stances = ["violent", "aggressive", "passive", "defensive", "standground"];
|
||||
if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && stances.length)
|
||||
{
|
||||
setupUnitPanel("Stance", usedPanels, entState, stances,
|
||||
|
@ -121,41 +121,6 @@ function damageTypesToText(dmg)
|
||||
return dmgArray.join("[font=\"serif-12\"], [/font]");
|
||||
}
|
||||
|
||||
function getFormationCellId(formationName)
|
||||
{
|
||||
switch (formationName)
|
||||
{
|
||||
case "Loose":
|
||||
return 0;
|
||||
case "Box":
|
||||
return 1;
|
||||
case "Column Closed":
|
||||
return 2;
|
||||
case "Line Closed":
|
||||
return 3;
|
||||
case "Column Open":
|
||||
return 4;
|
||||
case "Line Open":
|
||||
return 5;
|
||||
case "Flank":
|
||||
return 6;
|
||||
case "Skirmish":
|
||||
return 7;
|
||||
case "Wedge":
|
||||
return 8;
|
||||
case "Testudo":
|
||||
return 9;
|
||||
case "Phalanx":
|
||||
return 10;
|
||||
case "Syntagma":
|
||||
return 11;
|
||||
case "Formation12":
|
||||
return 12;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function getEntityFormationsList(entState)
|
||||
{
|
||||
var civ = g_Players[entState.player].civ;
|
||||
@ -167,7 +132,7 @@ function getCivFormations(civ)
|
||||
{
|
||||
// TODO: this should come from the civ JSON files instead
|
||||
|
||||
var civFormations = ["Loose", "Box", "Column Closed", "Line Closed", "Column Open", "Line Open", "Flank", "Skirmish", "Wedge", "Formation12"];
|
||||
var civFormations = ["Scatter", "Box", "Column Closed", "Line Closed", "Column Open", "Line Open", "Flank", "Skirmish", "Wedge", "Battle Line"];
|
||||
if (civ == "hele")
|
||||
{
|
||||
civFormations.push("Phalanx");
|
||||
|
@ -271,7 +271,7 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
cols = 6;
|
||||
shape = "opensquare";
|
||||
}
|
||||
else if (this.formationName == "Loose")
|
||||
else if (this.formationName == "Scatter")
|
||||
{
|
||||
var width = Math.sqrt(count) * separation * 5;
|
||||
|
||||
@ -418,7 +418,7 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
var cols = Math.ceil(Math.sqrt(count));
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Formation12")
|
||||
else if (this.formationName == "Battle Line")
|
||||
{
|
||||
if (count <= 5)
|
||||
cols = count;
|
||||
|
@ -362,11 +362,32 @@ GuiInterface.prototype.GetNextNotification = function()
|
||||
return "";
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetFormationRequirements = function(player, data)
|
||||
{
|
||||
return GetFormationRequirements(data.formationName);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.CanMoveEntsIntoFormation = function(player, data)
|
||||
{
|
||||
return CanMoveEntsIntoFormation(data.ents, data.formationName);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.IsFormationSelected = function(player, data)
|
||||
{
|
||||
for each (var ent in data.ents)
|
||||
{
|
||||
var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
|
||||
if (cmpUnitAI)
|
||||
{
|
||||
// GetLastFormationName is named in a strange way as it (also) is
|
||||
// the value of the current formation (see Formation.js LoadFormation)
|
||||
if (cmpUnitAI.GetLastFormationName() == data.formationName)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
GuiInterface.prototype.IsStanceSelected = function(player, data)
|
||||
{
|
||||
for each (var ent in data.ents)
|
||||
@ -783,7 +804,9 @@ var exposedFunctions = {
|
||||
"GetTemplateData": 1,
|
||||
"GetNextNotification": 1,
|
||||
|
||||
"GetFormationRequirements": 1,
|
||||
"CanMoveEntsIntoFormation": 1,
|
||||
"IsFormationSelected": 1,
|
||||
"IsStanceSelected": 1,
|
||||
|
||||
"SetSelectionHighlight": 1,
|
||||
|
@ -57,7 +57,7 @@ Identity.prototype.Schema =
|
||||
"</element>" +
|
||||
"</optional>" +
|
||||
"<optional>" +
|
||||
"<element name='Formations' a:help='Optional list of space-separated formations this unit is allowed to use. Choices include: Loose, Box, ColumnClosed, LineClosed, ColumnOpen, LineOpen, Flank, Skirmish, Wedge, Testudo, Phalanx, Syntagma, Formation12'>" +
|
||||
"<element name='Formations' a:help='Optional list of space-separated formations this unit is allowed to use. Choices include: Scatter, Box, ColumnClosed, LineClosed, ColumnOpen, LineOpen, Flank, Skirmish, Wedge, Testudo, Phalanx, Syntagma, BattleLine'>" +
|
||||
"<attribute name='datatype'>" +
|
||||
"<value>tokens</value>" +
|
||||
"</attribute>" +
|
||||
|
@ -9,7 +9,7 @@ UnitAI.prototype.Schema =
|
||||
"<value>aggressive</value>" +
|
||||
"<value>defensive</value>" +
|
||||
"<value>passive</value>" +
|
||||
"<value>stand</value>" +
|
||||
"<value>standground</value>" +
|
||||
"</choice>" +
|
||||
"</element>" +
|
||||
"<element name='FormationController'>" +
|
||||
@ -98,7 +98,7 @@ var g_Stances = {
|
||||
respondStandGround: false,
|
||||
respondHoldGround: false,
|
||||
},
|
||||
"stand": {
|
||||
"standground": {
|
||||
targetVisibleEnemies: true,
|
||||
targetAttackers: true,
|
||||
respondFlee: false,
|
||||
@ -2543,7 +2543,7 @@ UnitAI.prototype.SwitchToStance = function(stance)
|
||||
this.SetStance(stance);
|
||||
// Stop moving if switching to stand ground
|
||||
// TODO: Also stop existing orders in a sensible way
|
||||
if (stance == "stand")
|
||||
if (stance == "standground")
|
||||
this.StopMoving();
|
||||
|
||||
// Reset the range query, since the range depends on stance
|
||||
|
@ -592,92 +592,83 @@ function GetFormationUnitAIs(ents)
|
||||
}
|
||||
else
|
||||
{
|
||||
cmpFormation.LoadFormation("Loose");
|
||||
cmpFormation.LoadFormation("Scatter");
|
||||
}
|
||||
}
|
||||
|
||||
return nonformedUnitAIs.concat(Engine.QueryInterface(formationEnt, IID_UnitAI));
|
||||
}
|
||||
|
||||
function GetFormationRequirements(formationName)
|
||||
{
|
||||
var countRequired = 1;
|
||||
var classesRequired;
|
||||
switch(formationName)
|
||||
{
|
||||
case "Scatter":
|
||||
case "Column Closed":
|
||||
case "Line Closed":
|
||||
case "Column Open":
|
||||
case "Line Open":
|
||||
case "Battle Line":
|
||||
break;
|
||||
case "Box":
|
||||
countRequired = 4;
|
||||
break;
|
||||
case "Flank":
|
||||
countRequired = 8;
|
||||
break;
|
||||
case "Skirmish":
|
||||
classesRequired = ["Ranged"];
|
||||
break;
|
||||
case "Wedge":
|
||||
countRequired = 3;
|
||||
classesRequired = ["Cavalry"];
|
||||
break;
|
||||
case "Phalanx":
|
||||
countRequired = 10;
|
||||
classesRequired = ["Melee", "Infantry"];
|
||||
break;
|
||||
case "Syntagma":
|
||||
countRequired = 9;
|
||||
classesRequired = ["Melee", "Infantry"]; // TODO: pike only
|
||||
break;
|
||||
case "Testudo":
|
||||
countRequired = 9;
|
||||
classesRequired = ["Melee", "Infantry"];
|
||||
break;
|
||||
default:
|
||||
// We encountered a unknown formation -> warn the user
|
||||
warn("Commands.js: GetFormationRequirements: unknown formation: " + formationName);
|
||||
return false;
|
||||
}
|
||||
return { "count": countRequired, "classesRequired": classesRequired };
|
||||
}
|
||||
|
||||
|
||||
function CanMoveEntsIntoFormation(ents, formationName)
|
||||
{
|
||||
var count = ents.length;
|
||||
var classesRequired;
|
||||
|
||||
// TODO: should check the player's civ is allowed to use this formation
|
||||
|
||||
if (formationName == "Loose")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (formationName == "Box")
|
||||
{
|
||||
if (count < 4)
|
||||
return false;
|
||||
}
|
||||
else if (formationName == "Column Closed")
|
||||
{
|
||||
}
|
||||
else if (formationName == "Line Closed")
|
||||
{
|
||||
}
|
||||
else if (formationName == "Column Open")
|
||||
{
|
||||
}
|
||||
else if (formationName == "Line Open")
|
||||
{
|
||||
}
|
||||
else if (formationName == "Flank")
|
||||
{
|
||||
if (count < 8)
|
||||
return false;
|
||||
}
|
||||
else if (formationName == "Skirmish")
|
||||
{
|
||||
classesRequired = ["Ranged"];
|
||||
}
|
||||
else if (formationName == "Wedge")
|
||||
{
|
||||
if (count < 3)
|
||||
return false;
|
||||
classesRequired = ["Cavalry"];
|
||||
}
|
||||
else if (formationName == "Formation12")
|
||||
{
|
||||
}
|
||||
else if (formationName == "Phalanx")
|
||||
{
|
||||
if (count < 10)
|
||||
return false;
|
||||
classesRequired = ["Melee", "Infantry"];
|
||||
}
|
||||
else if (formationName == "Syntagma")
|
||||
{
|
||||
if (count < 9)
|
||||
return false;
|
||||
classesRequired = ["Melee", "Infantry"]; // TODO: pike only
|
||||
}
|
||||
else if (formationName == "Testudo")
|
||||
{
|
||||
if (count < 9)
|
||||
return false;
|
||||
classesRequired = ["Melee", "Infantry"];
|
||||
}
|
||||
else
|
||||
{
|
||||
var requirements = GetFormationRequirements(formationName);
|
||||
if (!requirements)
|
||||
return false;
|
||||
|
||||
if (count < requirements.count)
|
||||
return false;
|
||||
}
|
||||
|
||||
var looseOnlyUnits = true;
|
||||
var scatterOnlyUnits = true;
|
||||
for each (var ent in ents)
|
||||
{
|
||||
var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||
if (cmpIdentity)
|
||||
{
|
||||
var classes = cmpIdentity.GetClassesList();
|
||||
if (looseOnlyUnits && (classes.indexOf("Worker") == -1 || classes.indexOf("Support") == -1))
|
||||
looseOnlyUnits = false;
|
||||
for each (var classRequired in classesRequired)
|
||||
if (scatterOnlyUnits && (classes.indexOf("Worker") == -1 || classes.indexOf("Support") == -1))
|
||||
scatterOnlyUnits = false;
|
||||
for each (var classRequired in requirements.classesRequired)
|
||||
{
|
||||
if (classes.indexOf(classRequired) == -1)
|
||||
{
|
||||
@ -687,7 +678,7 @@ function CanMoveEntsIntoFormation(ents, formationName)
|
||||
}
|
||||
}
|
||||
|
||||
if (looseOnlyUnits)
|
||||
if (scatterOnlyUnits)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -711,5 +702,6 @@ function FilterEntityList(entities, player, controlAll)
|
||||
return entities.filter(function(ent) { return CanControlUnit(ent, player, controlAll);} );
|
||||
}
|
||||
|
||||
Engine.RegisterGlobal("GetFormationRequirements", GetFormationRequirements);
|
||||
Engine.RegisterGlobal("CanMoveEntsIntoFormation", CanMoveEntsIntoFormation);
|
||||
Engine.RegisterGlobal("ProcessCommand", ProcessCommand);
|
||||
|
@ -37,7 +37,7 @@
|
||||
<GenericName>Unit</GenericName>
|
||||
<Classes datatype="tokens">Unit ConquestCritical</Classes>
|
||||
<Formations datatype="tokens">
|
||||
Loose
|
||||
Scatter
|
||||
Box
|
||||
ColumnClosed
|
||||
LineClosed
|
||||
@ -49,7 +49,7 @@
|
||||
Testudo
|
||||
Phalanx
|
||||
Syntagma
|
||||
Formation12
|
||||
BattleLine
|
||||
</Formations>
|
||||
</Identity>
|
||||
<Looter/>
|
||||
|
Loading…
Reference in New Issue
Block a user