forked from 0ad/0ad
251 lines
6.1 KiB
JavaScript
251 lines
6.1 KiB
JavaScript
var g_ParsedData = {
|
|
units: {},
|
|
structures: {},
|
|
techs: {},
|
|
phases: {}
|
|
};
|
|
var g_Lists = {};
|
|
var g_CivData = {};
|
|
var g_SelectedCiv = "";
|
|
|
|
|
|
/**
|
|
* Initialize the dropdown containing all the available civs
|
|
*/
|
|
function init()
|
|
{
|
|
g_CivData = loadCivData(true);
|
|
|
|
if (!Object.keys(g_CivData).length)
|
|
return;
|
|
|
|
var civList = [ { "name": civ.Name, "code": civ.Code } for each (civ in g_CivData) ];
|
|
|
|
// Alphabetically sort the list, ignoring case
|
|
civList.sort(sortNameIgnoreCase);
|
|
|
|
var civListNames = [ civ.name for each (civ in civList) ];
|
|
var civListCodes = [ civ.code for each (civ in civList) ];
|
|
|
|
// Set civ control
|
|
var civSelection = Engine.GetGUIObjectByName("civSelection");
|
|
civSelection.list = civListNames;
|
|
civSelection.list_data = civListCodes;
|
|
civSelection.selected = 0;
|
|
}
|
|
|
|
function selectCiv(civCode)
|
|
{
|
|
if (civCode === g_SelectedCiv || !g_CivData[civCode])
|
|
return;
|
|
|
|
g_SelectedCiv = civCode;
|
|
|
|
// If a buildList already exists, then this civ has already been parsed
|
|
if (g_CivData[g_SelectedCiv].buildList)
|
|
{
|
|
draw();
|
|
return;
|
|
}
|
|
|
|
g_Lists.units = [];
|
|
g_Lists.structures = [];
|
|
g_Lists.techs = [];
|
|
|
|
// get initial units
|
|
var startStructs = [];
|
|
for (let entity of g_CivData[civCode].StartEntities)
|
|
{
|
|
if (entity.Template.slice(0, 5) == "units")
|
|
g_Lists.units.push(entity.Template);
|
|
else if (entity.Template.slice(0, 6) == "struct")
|
|
{
|
|
g_Lists.structures.push(entity.Template);
|
|
startStructs.push(entity.Template);
|
|
}
|
|
}
|
|
|
|
// Load units and structures
|
|
var unitCount = 0;
|
|
do
|
|
{
|
|
for (let u of g_Lists.units)
|
|
if (!g_ParsedData.units[u])
|
|
g_ParsedData.units[u] = loadUnit(u);
|
|
|
|
unitCount = g_Lists.units.length;
|
|
|
|
for (let s of g_Lists.structures)
|
|
if (!g_ParsedData.structures[s])
|
|
g_ParsedData.structures[s] = loadStructure(s);
|
|
|
|
} while (unitCount < g_Lists.units.length);
|
|
|
|
// Load technologies
|
|
var techPairs = {};
|
|
for (let techcode of g_Lists.techs)
|
|
{
|
|
let realcode = depath(techcode);
|
|
|
|
if (realcode.slice(0,4) == "pair")
|
|
techPairs[techcode] = loadTechnologyPair(techcode);
|
|
else if (realcode.slice(0,5) == "phase")
|
|
g_ParsedData.phases[techcode] = loadPhase(techcode);
|
|
else
|
|
g_ParsedData.techs[techcode] = loadTechnology(techcode);
|
|
}
|
|
|
|
// Expand tech pairs
|
|
for (let paircode in techPairs)
|
|
{
|
|
let pair = techPairs[paircode];
|
|
for (let techcode of pair.techs)
|
|
{
|
|
let newTech = loadTechnology(techcode);
|
|
|
|
if (pair.req !== "")
|
|
{
|
|
if ("generic" in newTech.reqs)
|
|
newTech.reqs.generic.concat(techPairs[pair.req].techs);
|
|
else
|
|
for (let civkey of Object.keys(newTech.reqs))
|
|
newTech.reqs[civkey].concat(techPairs[pair.req].techs);
|
|
}
|
|
g_ParsedData.techs[techcode] = newTech;
|
|
}
|
|
}
|
|
|
|
// Establish phase order
|
|
g_ParsedData.phaseList = unravelPhases(g_ParsedData.techs);
|
|
for (let phasecode of g_ParsedData.phaseList)
|
|
{
|
|
let phaseInfo = loadTechData(phasecode);
|
|
g_ParsedData.phases[phasecode] = loadPhase(phasecode);
|
|
|
|
if ("requirements" in phaseInfo)
|
|
for (let op in phaseInfo.requirements)
|
|
{
|
|
let val = phaseInfo.requirements[op];
|
|
if (op == "any")
|
|
for (let v of val)
|
|
{
|
|
let k = Object.keys(v);
|
|
k = k[0];
|
|
v = v[k];
|
|
if (k == "tech" && v in g_ParsedData.phases)
|
|
g_ParsedData.phases[v].actualPhase = phasecode;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Group production lists of structures by phase
|
|
for (let structCode of g_Lists.structures)
|
|
{
|
|
let structInfo = g_ParsedData.structures[structCode];
|
|
|
|
// If this building is shared with another civ,
|
|
// it may have already gone through the grouping process already
|
|
if (!Array.isArray(structInfo.production.technology))
|
|
continue;
|
|
|
|
// Expand tech pairs
|
|
for (let prod of structInfo.production.technology)
|
|
if (prod in techPairs)
|
|
structInfo.production.technology.splice(
|
|
structInfo.production.technology.indexOf(prod), 1,
|
|
techPairs[prod].techs[0], techPairs[prod].techs[1]
|
|
);
|
|
|
|
// Sort techs by phase
|
|
let newProdTech = {};
|
|
for (let prod of structInfo.production.technology)
|
|
{
|
|
let phase = "";
|
|
|
|
if (prod.slice(0,5) === "phase")
|
|
{
|
|
phase = g_ParsedData.phaseList.indexOf(g_ParsedData.phases[prod].actualPhase);
|
|
if (phase > 0)
|
|
phase = g_ParsedData.phaseList[phase - 1];
|
|
}
|
|
else if (g_SelectedCiv in g_ParsedData.techs[prod].reqs)
|
|
{
|
|
for (let req of g_ParsedData.techs[prod].reqs[g_SelectedCiv])
|
|
if (depath(req).slice(0,5) === "phase")
|
|
phase = req;
|
|
}
|
|
else if ("generic" in g_ParsedData.techs[prod].reqs)
|
|
{
|
|
for (let req of g_ParsedData.techs[prod].reqs.generic)
|
|
if (depath(req).slice(0,5) === "phase")
|
|
phase = req;
|
|
}
|
|
|
|
if (depath(phase).slice(0,5) !== "phase")
|
|
{
|
|
warn(prod+" doesn't have a specific phase set ("+structCode+")");
|
|
phase = structInfo.phase;
|
|
}
|
|
|
|
if (!(phase in newProdTech))
|
|
newProdTech[phase] = [];
|
|
|
|
newProdTech[phase].push(prod);
|
|
}
|
|
|
|
// Determine phase for units
|
|
let newProdUnits = {};
|
|
for (let prod of structInfo.production.units)
|
|
{
|
|
if (!g_ParsedData.units[prod])
|
|
continue;
|
|
|
|
let unit = g_ParsedData.units[prod];
|
|
let phase = "";
|
|
|
|
if (unit.phase !== false)
|
|
phase = unit.phase;
|
|
else if (unit.required !== undefined)
|
|
{
|
|
let reqs = g_ParsedData.techs[unit.required].reqs;
|
|
if (g_SelectedCiv in reqs)
|
|
phase = reqs[g_SelectedCiv][0];
|
|
else
|
|
phase = reqs.generic[0];
|
|
}
|
|
else if (structInfo.phase !== false)
|
|
phase = structInfo.phase;
|
|
else
|
|
phase = g_ParsedData.phaseList[0];
|
|
|
|
if (!(phase in newProdUnits))
|
|
newProdUnits[phase] = [];
|
|
|
|
newProdUnits[phase].push(prod);
|
|
}
|
|
|
|
g_ParsedData.structures[structCode].production = {
|
|
"technology": newProdTech,
|
|
"units": newProdUnits
|
|
};
|
|
}
|
|
|
|
// Determine the buildList for the civ (grouped by phase)
|
|
var buildList = {};
|
|
for (let pha of g_ParsedData.phaseList)
|
|
buildList[pha] = [];
|
|
for (let structCode of g_Lists.structures)
|
|
{
|
|
if (!g_ParsedData.structures[structCode].phase || startStructs.indexOf(structCode) > -1)
|
|
g_ParsedData.structures[structCode].phase = g_ParsedData.phaseList[0];
|
|
|
|
let myPhase = g_ParsedData.structures[structCode].phase;
|
|
buildList[myPhase].push(structCode);
|
|
}
|
|
|
|
g_CivData[g_SelectedCiv].buildList = buildList;
|
|
|
|
// Draw tree
|
|
draw();
|
|
}
|