This was SVN commit r11735.
This commit is contained in:
parent
20afc75657
commit
58836c624a
@ -123,5 +123,20 @@
|
||||
{
|
||||
"Template": "units/athen_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Phalanx",
|
||||
"Syntagma"
|
||||
]
|
||||
}
|
||||
|
@ -93,5 +93,18 @@
|
||||
{
|
||||
"Template": "units/cart_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line"
|
||||
]
|
||||
}
|
||||
|
@ -142,5 +142,18 @@
|
||||
{
|
||||
"Template": "units/celt_cavalry_swordsman_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line"
|
||||
]
|
||||
}
|
||||
|
@ -160,5 +160,20 @@
|
||||
"Template": "units/hele_cavalry_swordsman_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Phalanx",
|
||||
"Syntagma"
|
||||
],
|
||||
"SelectableInGameSetup": false
|
||||
}
|
||||
|
@ -100,5 +100,18 @@
|
||||
{
|
||||
"Template": "units/iber_cavalry_spearman_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line"
|
||||
]
|
||||
}
|
||||
|
@ -109,5 +109,20 @@
|
||||
{
|
||||
"Template": "units/mace_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Phalanx",
|
||||
"Syntagma"
|
||||
]
|
||||
}
|
||||
|
@ -101,5 +101,18 @@
|
||||
{
|
||||
"Template": "units/pers_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line"
|
||||
]
|
||||
}
|
||||
|
@ -106,5 +106,19 @@
|
||||
{
|
||||
"Template": "units/rome_cavalry_spearman_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Testudo"
|
||||
]
|
||||
}
|
||||
|
@ -100,5 +100,20 @@
|
||||
{
|
||||
"Template": "units/spart_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Phalanx",
|
||||
"Syntagma"
|
||||
]
|
||||
}
|
||||
|
@ -101,5 +101,20 @@
|
||||
"Template": "units/spart_cavalry_javelinist_b"
|
||||
}
|
||||
],
|
||||
"Formations":
|
||||
[
|
||||
"Scatter",
|
||||
"Box",
|
||||
"Column Closed",
|
||||
"Line Closed",
|
||||
"Column Open",
|
||||
"Line Open",
|
||||
"Flank",
|
||||
"Skirmish",
|
||||
"Wedge",
|
||||
"Battle Line",
|
||||
"Phalanx",
|
||||
"Syntagma"
|
||||
],
|
||||
"SelectableInGameSetup": false
|
||||
}
|
||||
|
@ -712,7 +712,7 @@ function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, s
|
||||
function (item) { unload(entState.id, groups.getEntsByName(item)); } );
|
||||
}
|
||||
|
||||
var formations = getEntityFormationsList(entState);
|
||||
var formations = Engine.GuiInterfaceCall("GetAvailableFormations");
|
||||
if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && formations.length)
|
||||
{
|
||||
setupUnitPanel(FORMATION, usedPanels, entState, formations,
|
||||
|
@ -121,30 +121,6 @@ function damageTypesToText(dmg)
|
||||
return dmgArray.join("[font=\"serif-12\"], [/font]");
|
||||
}
|
||||
|
||||
function getEntityFormationsList(entState)
|
||||
{
|
||||
var civ = g_Players[entState.player].civ;
|
||||
var formations = getCivFormations(civ);
|
||||
return formations;
|
||||
}
|
||||
|
||||
function getCivFormations(civ)
|
||||
{
|
||||
// TODO: this should come from the civ JSON files instead
|
||||
|
||||
var civFormations = ["Scatter", "Box", "Column Closed", "Line Closed", "Column Open", "Line Open", "Flank", "Skirmish", "Wedge", "Battle Line"];
|
||||
if (civ == "hele")
|
||||
{
|
||||
civFormations.push("Phalanx");
|
||||
civFormations.push("Syntagma");
|
||||
}
|
||||
else if (civ == "rome")
|
||||
{
|
||||
civFormations.push("Testudo");
|
||||
}
|
||||
return civFormations;
|
||||
}
|
||||
|
||||
function getEntityCommandsList(entState)
|
||||
{
|
||||
var commands = [];
|
||||
|
@ -214,17 +214,21 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
|
||||
// Choose a sensible size/shape for the various formations, depending on number of units
|
||||
var cols;
|
||||
if (columnar || this.formationName == "Column Closed")
|
||||
|
||||
if (columnar)
|
||||
this.formationName = "Column Closed";
|
||||
|
||||
switch(this.formationName)
|
||||
{
|
||||
case "Column Closed":
|
||||
// Have at most 3 files
|
||||
if (count <= 3)
|
||||
cols = count;
|
||||
else
|
||||
cols = 3;
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Phalanx")
|
||||
{
|
||||
break;
|
||||
case "Phalanx":
|
||||
// Try to have at least 5 files (so batch training gives a single line),
|
||||
// and at most 8
|
||||
if (count <= 5)
|
||||
@ -238,9 +242,8 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
else
|
||||
cols = Math.ceil(count/6);
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Line Closed")
|
||||
{
|
||||
break;
|
||||
case "Line Closed":
|
||||
if (count <= 3)
|
||||
cols = count;
|
||||
else if (count < 30)
|
||||
@ -248,19 +251,16 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
else
|
||||
cols = Math.ceil(count/3);
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Testudo")
|
||||
{
|
||||
break;
|
||||
case "Testudo":
|
||||
cols = Math.ceil(Math.sqrt(count));
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Column Open")
|
||||
{
|
||||
cols = 2
|
||||
break;
|
||||
case "Column Open":
|
||||
cols = 2;
|
||||
shape = "opensquare";
|
||||
}
|
||||
else if (this.formationName == "Line Open")
|
||||
{
|
||||
break;
|
||||
case "Line Open":
|
||||
if (count <= 5)
|
||||
cols = 3;
|
||||
else if (count <= 11)
|
||||
@ -270,18 +270,16 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
else
|
||||
cols = 6;
|
||||
shape = "opensquare";
|
||||
}
|
||||
else if (this.formationName == "Scatter")
|
||||
{
|
||||
break;
|
||||
case "Scatter":
|
||||
var width = Math.sqrt(count) * separation * 5;
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
offsets.push({"x": Math.random()*width, "z": Math.random()*width});
|
||||
}
|
||||
}
|
||||
else if (this.formationName == "Circle")
|
||||
{
|
||||
break;
|
||||
case "Circle":
|
||||
var depth;
|
||||
var pop;
|
||||
if (count <= 36)
|
||||
@ -291,7 +289,7 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
}
|
||||
else
|
||||
{
|
||||
depth = 3
|
||||
depth = 3;
|
||||
pop = Math.ceil(count / depth);
|
||||
}
|
||||
|
||||
@ -311,9 +309,8 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
left--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.formationName == "Box")
|
||||
{
|
||||
break;
|
||||
case "Box":
|
||||
var root = Math.ceil(Math.sqrt(count));
|
||||
|
||||
var left = count;
|
||||
@ -334,8 +331,10 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
meleeleft -= stodo;
|
||||
}
|
||||
else // compact
|
||||
{
|
||||
stodo = Math.max(0, left - (width-2)*(width-2));
|
||||
}
|
||||
}
|
||||
|
||||
for (var r = -sq; r <= sq && stodo; ++r)
|
||||
{
|
||||
@ -352,14 +351,12 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.formationName == "Skirmish")
|
||||
{
|
||||
break;
|
||||
case "Skirmish":
|
||||
cols = Math.ceil(count/2);
|
||||
shape = "opensquare";
|
||||
}
|
||||
else if (this.formationName == "Wedge")
|
||||
{
|
||||
break;
|
||||
case "Wedge":
|
||||
var depth = Math.ceil(Math.sqrt(count));
|
||||
|
||||
var left = count;
|
||||
@ -387,9 +384,8 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.formationName == "Flank")
|
||||
{
|
||||
break;
|
||||
case "Flank":
|
||||
cols = 3;
|
||||
var leftside = [];
|
||||
leftside[0] = Math.ceil(count/2);
|
||||
@ -412,14 +408,12 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
left -= n;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.formationName == "Syntagma")
|
||||
{
|
||||
var cols = Math.ceil(Math.sqrt(count));
|
||||
break;
|
||||
case "Syntagma":
|
||||
cols = Math.ceil(Math.sqrt(count));
|
||||
shape = "square";
|
||||
}
|
||||
else if (this.formationName == "Battle Line")
|
||||
{
|
||||
break;
|
||||
case "Battle Line":
|
||||
if (count <= 5)
|
||||
cols = count;
|
||||
else if (count <= 10)
|
||||
@ -433,6 +427,10 @@ Formation.prototype.ComputeFormationOffsets = function(active, columnar)
|
||||
shape = "opensquare";
|
||||
separation /= 1.5;
|
||||
ordering = "cavalryOnTheSides";
|
||||
break;
|
||||
default:
|
||||
warn("Unknown formation: " + this.formationName);
|
||||
break;
|
||||
}
|
||||
|
||||
if (shape == "square")
|
||||
|
@ -451,6 +451,13 @@ GuiInterface.prototype.GetNextNotification = function()
|
||||
return "";
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetAvailableFormations = function(player, data)
|
||||
{
|
||||
var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player);
|
||||
return cmpPlayer.GetFormations();
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetFormationRequirements = function(player, data)
|
||||
{
|
||||
return GetFormationRequirements(data.formationName);
|
||||
@ -897,6 +904,7 @@ var exposedFunctions = {
|
||||
"CheckTechnologyRequirements": 1,
|
||||
"GetNextNotification": 1,
|
||||
|
||||
"GetAvailableFormations": 1,
|
||||
"GetFormationRequirements": 1,
|
||||
"CanMoveEntsIntoFormation": 1,
|
||||
"IsFormationSelected": 1,
|
||||
|
@ -25,6 +25,7 @@ Player.prototype.Init = function()
|
||||
this.diplomacy = []; // array of diplomatic stances for this player with respect to other players (including gaia and self)
|
||||
this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class
|
||||
this.phase = "village";
|
||||
this.formations = [];
|
||||
this.startCam = undefined;
|
||||
this.controlAllUnits = false;
|
||||
this.isAI = false;
|
||||
@ -202,7 +203,6 @@ Player.prototype.GetConquestCriticalEntitiesCount = function()
|
||||
return this.conquestCriticalEntitiesCount;
|
||||
};
|
||||
|
||||
|
||||
Player.prototype.GetTeam = function()
|
||||
{
|
||||
return this.team;
|
||||
@ -223,6 +223,16 @@ Player.prototype.SetDiplomacy = function(dipl)
|
||||
this.diplomacy = dipl;
|
||||
};
|
||||
|
||||
Player.prototype.GetFormations = function()
|
||||
{
|
||||
return this.formations;
|
||||
};
|
||||
|
||||
Player.prototype.SetFormations = function(formations)
|
||||
{
|
||||
this.formations = formations;
|
||||
};
|
||||
|
||||
Player.prototype.GetStartingCameraPos = function()
|
||||
{
|
||||
return this.startCam.position;
|
||||
|
@ -1702,7 +1702,7 @@ UnitAI.prototype.Init = function()
|
||||
this.formationController = INVALID_ENTITY; // entity with IID_Formation that we belong to
|
||||
this.isGarrisoned = false;
|
||||
this.isIdle = false;
|
||||
this.lastFormationName = "Line Closed";
|
||||
this.lastFormationName = "";
|
||||
|
||||
this.SetStance(this.template.DefaultStance);
|
||||
};
|
||||
|
@ -453,7 +453,7 @@ function ProcessCommand(player, cmd)
|
||||
|
||||
case "formation":
|
||||
var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
|
||||
GetFormationUnitAIs(entities).forEach(function(cmpUnitAI) {
|
||||
GetFormationUnitAIs(entities, cmd.name).forEach(function(cmpUnitAI) {
|
||||
var cmpFormation = Engine.QueryInterface(cmpUnitAI.entity, IID_Formation);
|
||||
if (!cmpFormation)
|
||||
return;
|
||||
@ -567,7 +567,7 @@ function RemoveFromFormation(ents)
|
||||
* Returns a list of UnitAI components, each belonging either to a
|
||||
* selected unit or to a formation entity for groups of the selected units.
|
||||
*/
|
||||
function GetFormationUnitAIs(ents)
|
||||
function GetFormationUnitAIs(ents, formName)
|
||||
{
|
||||
// If an individual was selected, remove it from any formation
|
||||
// and command it individually
|
||||
@ -594,13 +594,11 @@ function GetFormationUnitAIs(ents)
|
||||
continue;
|
||||
|
||||
var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||
// TODO: Currently we use LineClosed as effectively a boolean flag
|
||||
// to determine whether formations are allowed at all. Instead we
|
||||
// should check specific formation names and do something sensible
|
||||
// (like what?) when some units don't support them.
|
||||
// TODO: We'll also need to fix other formation code to use
|
||||
// "LineClosed" instead of "Line Closed" etc consistently.
|
||||
if (cmpIdentity && cmpIdentity.CanUseFormation("LineClosed"))
|
||||
// TODO: We only check if the formation is usable by some units
|
||||
// if we move them to it. We should check if we can use formations
|
||||
// for the other cases.
|
||||
// We only use "LineClosed" instead of "Line Closed" to access the templates.
|
||||
if (cmpIdentity && cmpIdentity.CanUseFormation(formName === undefined ? "LineClosed" : formName.replace(/\s+/,'')))
|
||||
formedEnts.push(ent);
|
||||
else
|
||||
nonformedUnitAIs.push(cmpUnitAI);
|
||||
@ -738,6 +736,7 @@ function CanMoveEntsIntoFormation(ents, formationName)
|
||||
var count = ents.length;
|
||||
|
||||
// TODO: should check the player's civ is allowed to use this formation
|
||||
// See simulation/components/Player.js GetFormations() for a list of all allowed formations
|
||||
|
||||
var requirements = GetFormationRequirements(formationName);
|
||||
if (!requirements)
|
||||
|
@ -118,6 +118,22 @@ function LoadPlayerSettings(settings, newPlayers)
|
||||
}
|
||||
}
|
||||
|
||||
// If formations explicitly defined, use that; otherwise use civ defaults
|
||||
var formations = getSetting(pData, pDefs, "Formations");
|
||||
if (formations !== undefined)
|
||||
{
|
||||
cmpPlayer.SetFormations(formations);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rawFormations = Engine.ReadCivJSONFile(cmpPlayer.GetCiv()+".json");
|
||||
if (!(rawFormations && rawFormations.Formations))
|
||||
{
|
||||
throw("Player.js: Error reading "+cmpPlayer.GetCiv()+".json");
|
||||
}
|
||||
cmpPlayer.SetFormations(rawFormations.Formations);
|
||||
}
|
||||
|
||||
var startCam = getSetting(pData, pDefs, "StartingCamera");
|
||||
if (startCam !== undefined)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@
|
||||
<History>Women in the ancient world took on a variety of roles - from leadership (Celts) to servant (Greeks). Women are hard workers, the economic backbone of any civilisation. In history, it was typical when all the males (capable of fighting) were killed for the females, children, and elderly to be sold as slaves.</History>
|
||||
<Tooltip>Gather resources, build civic structures, and inspire nearby males to work faster. Bonused at foraging and farming.</Tooltip>
|
||||
<Classes datatype="tokens">Worker Female Citizen</Classes>
|
||||
<Formations disable=""/>
|
||||
</Identity>
|
||||
<ResourceGatherer>
|
||||
<MaxDistance>2.0</MaxDistance>
|
||||
|
@ -81,6 +81,7 @@ CComponentManager::CComponentManager(CSimContext& context, bool skipScriptFuncti
|
||||
m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddLocalEntity> ("AddLocalEntity");
|
||||
m_ScriptInterface.RegisterFunction<void, int, CComponentManager::Script_DestroyEntity> ("DestroyEntity");
|
||||
m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadJSONFile> ("ReadJSONFile");
|
||||
m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadCivJSONFile> ("ReadCivJSONFile");
|
||||
m_ScriptInterface.RegisterFunction<std::vector<std::string>, std::wstring, CComponentManager::Script_FindJSONFiles> ("FindJSONFiles");
|
||||
}
|
||||
|
||||
@ -938,10 +939,20 @@ std::string CComponentManager::GenerateSchema()
|
||||
}
|
||||
|
||||
CScriptVal CComponentManager::Script_ReadJSONFile(void* cbdata, std::wstring fileName)
|
||||
{
|
||||
return ReadJSONFile(cbdata, L"simulation/data", fileName);
|
||||
}
|
||||
|
||||
CScriptVal CComponentManager::Script_ReadCivJSONFile(void* cbdata, std::wstring fileName)
|
||||
{
|
||||
return ReadJSONFile(cbdata, L"civs", fileName);
|
||||
}
|
||||
|
||||
CScriptVal CComponentManager::ReadJSONFile(void* cbdata, std::wstring filePath, std::wstring fileName)
|
||||
{
|
||||
CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
|
||||
|
||||
VfsPath path = VfsPath("simulation/data") / fileName;
|
||||
VfsPath path = VfsPath(filePath) / fileName;
|
||||
|
||||
return componentManager->GetScriptInterface().ReadJSONFile(path).get();
|
||||
}
|
||||
|
@ -233,8 +233,11 @@ private:
|
||||
static int Script_AddLocalEntity(void* cbdata, std::string templateName);
|
||||
static void Script_DestroyEntity(void* cbdata, int ent);
|
||||
static CScriptVal Script_ReadJSONFile(void* cbdata, std::wstring fileName);
|
||||
static CScriptVal Script_ReadCivJSONFile(void* cbdata, std::wstring fileName);
|
||||
static std::vector<std::string> Script_FindJSONFiles(void* cbdata, std::wstring subPath);
|
||||
|
||||
static CScriptVal ReadJSONFile(void *cbdata, std::wstring filePath, std::wstring fileName);
|
||||
|
||||
CMessage* ConstructMessage(int mtid, CScriptVal data);
|
||||
void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user