diff --git a/binaries/data/mods/public/gui/structree/helper.js b/binaries/data/mods/public/gui/structree/helper.js
index 1349c53..97431bf 100644
a
|
b
|
function GetTemplateData(templateName)
|
106 | 106 | var template = loadTemplate(templateName); |
107 | 107 | return GetTemplateDataHelper(template, null, g_AuraData); |
108 | 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Determines and returns the phase of a given technology. Works |
| 112 | * recursively through the given tech's pre-requisite and superseded |
| 113 | * techs if necessary. |
| 114 | * |
| 115 | * @param techName the Technology's name |
| 116 | * @return The name of the phase the technology belongs to, or false if |
| 117 | * the current civ can't research this tech |
| 118 | */ |
| 119 | function GetPhaseOfTechnology(techName) |
| 120 | { |
| 121 | let phaseIdx = -1; |
| 122 | let techReqs = []; |
| 123 | |
| 124 | if (depath(techName).slice(0, 5) === "phase") |
| 125 | { |
| 126 | phaseIdx = g_ParsedData.phaseList.indexOf(g_ParsedData.phases[techName].actualPhase); |
| 127 | if (phaseIdx > 0) |
| 128 | return g_ParsedData.phaseList[phaseIdx - 1]; |
| 129 | } |
| 130 | else if (g_SelectedCiv in g_ParsedData.techs[techName].reqs) |
| 131 | { |
| 132 | if (g_ParsedData.techs[techName].reqs[g_SelectedCiv] === false) |
| 133 | return false; |
| 134 | techReqs = g_ParsedData.techs[techName].reqs[g_SelectedCiv]; |
| 135 | } |
| 136 | else if ("generic" in g_ParsedData.techs[techName].reqs) |
| 137 | techReqs = g_ParsedData.techs[techName].reqs.generic; |
| 138 | |
| 139 | for (let req of techReqs) |
| 140 | if (depath(req).slice(0, 5) === "phase") |
| 141 | return req; |
| 142 | else |
| 143 | { |
| 144 | let newIdx = g_ParsedData.phaseList.indexOf(GetPhaseOfTechnology(req)); |
| 145 | if (newIdx > phaseIdx) |
| 146 | phaseIdx = newIdx; |
| 147 | } |
| 148 | |
| 149 | return phaseIdx > -1 ? g_ParsedData.phaseList[phaseIdx] : false; |
| 150 | |
| 151 | } |
diff --git a/binaries/data/mods/public/gui/structree/load.js b/binaries/data/mods/public/gui/structree/load.js
index 2864ed4..34a5844 100644
a
|
b
|
function loadTechnology(techName)
|
196 | 196 | |
197 | 197 | if (template.requirements !== undefined) |
198 | 198 | { |
199 | | for (let op in template.requirements) |
200 | | { |
201 | | let val = template.requirements[op]; |
202 | | let req = calcReqs(op, val); |
203 | | |
204 | | switch (op) |
205 | | { |
206 | | case "tech": |
207 | | tech.reqs.generic = req; |
208 | | break; |
209 | | |
210 | | case "civ": |
211 | | tech.reqs[req] = []; |
212 | | break; |
213 | | |
214 | | case "any": |
215 | | if (req[0].length > 0) |
216 | | for (let r of req[0]) |
217 | | { |
218 | | let v = req[0][r]; |
219 | | if (typeof r == "number") |
220 | | tech.reqs[v] = []; |
221 | | else |
222 | | tech.reqs[r] = v; |
223 | | } |
224 | | if (req[1].length > 0) |
225 | | tech.reqs.generic = req[1]; |
226 | | break; |
227 | | |
228 | | case "all": |
229 | | if (!req[0].length) |
230 | | tech.reqs.generic = req[1]; |
231 | | else |
232 | | for (let r of req[0]) |
233 | | tech.reqs[r] = req[1]; |
234 | | break; |
235 | | } |
236 | | } |
| 199 | let op = Object.keys(template.requirements)[0]; |
| 200 | let val = template.requirements[op]; |
| 201 | tech.reqs = calcReqs(op, val); |
237 | 202 | } |
238 | 203 | |
239 | 204 | if (template.supersedes !== undefined) |
240 | 205 | { |
241 | 206 | if (tech.reqs.generic !== undefined) |
242 | 207 | tech.reqs.generic.push(template.supersedes); |
| 208 | else if (Object.keys(tech.reqs).length == 0) |
| 209 | tech.reqs.generic = [template.supersedes]; |
243 | 210 | else |
244 | 211 | for (let ck of Object.keys(tech.reqs)) |
245 | 212 | tech.reqs[ck].push(template.supersedes); |
… |
… |
function loadTechnologyPair(pairCode)
|
274 | 241 | * Calculate the prerequisite requirements of a technology. |
275 | 242 | * Works recursively if needed. |
276 | 243 | * |
277 | | * @param op The base operation. Can be "civ", "tech", "all" or "any". |
278 | | * @param val The value associated with the above operation. |
| 244 | * @param operator The base operation. Can be "civ", "notciv", "tech", "all" or "any". |
| 245 | * @param value The value associated with the above operation. |
279 | 246 | * |
280 | | * @return Sorted requirments. |
| 247 | * @return Object containing the requirements, sorted. |
281 | 248 | */ |
282 | | function calcReqs(op, val) |
| 249 | function calcReqs(operator, value) |
283 | 250 | { |
284 | | switch (op) |
| 251 | let retVal = {}; |
| 252 | |
| 253 | switch (operator) |
285 | 254 | { |
286 | 255 | case "civ": |
287 | | case "class": |
| 256 | retVal[value] = []; |
| 257 | break; |
| 258 | |
288 | 259 | case "notciv": |
| 260 | retVal[value] = false; |
| 261 | break; |
| 262 | |
| 263 | case "class": |
289 | 264 | case "number": |
290 | | // nothing needs doing |
| 265 | // do nothing |
291 | 266 | break; |
292 | 267 | |
293 | 268 | case "tech": |
294 | | if (depath(val).slice(0,4) === "pair") |
295 | | return loadTechnologyPair(val).techs; |
296 | | return [ val ]; |
| 269 | if (depath(value).slice(0,4) === "pair") |
| 270 | return {"generic": loadTechnologyPair(value).techs }; |
| 271 | return {"generic": [ value ]}; |
297 | 272 | |
298 | 273 | case "all": |
299 | | case "any": |
300 | | let t = []; |
301 | | let c = []; |
302 | | for (let nv of val) |
303 | | { |
304 | | for (let o in nv) |
| 274 | let civs = []; |
| 275 | let techs = []; |
| 276 | for (let subvalue of value) |
| 277 | for (let newOper in subvalue) |
305 | 278 | { |
306 | | let v = nv[o]; |
307 | | let r = calcReqs(o, v); |
308 | | switch (o) |
| 279 | let newValue = subvalue[newOper]; |
| 280 | let result = calcReqs(newOper, newValue) |
| 281 | |
| 282 | switch (newOper) |
309 | 283 | { |
310 | 284 | case "civ": |
| 285 | civs.push(Object.keys(result)[0]); |
| 286 | break; |
| 287 | |
311 | 288 | case "notciv": |
312 | | c.push(r); |
| 289 | retVal[Object.keys(result)[0]] = false; |
313 | 290 | break; |
314 | 291 | |
315 | 292 | case "tech": |
316 | | t = t.concat(r); |
| 293 | techs = techs.concat(result.generic); |
317 | 294 | break; |
318 | 295 | |
319 | 296 | case "any": |
320 | | c = c.concat(r[0]); |
321 | | t = t.concat(r[1]); |
| 297 | case "all": |
| 298 | if (result.generic) |
| 299 | techs = techs.concat(result.generic); |
| 300 | else |
| 301 | for (let c of Object.keys(result)) |
| 302 | if (result[c] === false) |
| 303 | retVal[c] = false; |
| 304 | else if (newOper === "any") |
| 305 | civs.push(c); |
| 306 | else |
| 307 | warn("Uncomprehensible technology requirements - "+operator +":"+uneval(value)); |
| 308 | break; |
| 309 | } |
| 310 | } |
| 311 | if (civs.length === 0 && techs.length > 0) |
| 312 | retVal.generic = techs; |
| 313 | else |
| 314 | for (let c of civs) |
| 315 | retVal[c] = techs; |
| 316 | break; |
| 317 | |
| 318 | case "any": |
| 319 | for (let subvalue of value) |
| 320 | for (let newOper in subvalue) |
| 321 | { |
| 322 | let newValue = subvalue[newOper]; |
| 323 | let result = calcReqs(newOper, newValue) |
| 324 | |
| 325 | switch (newOper) |
| 326 | { |
| 327 | case "civ": |
| 328 | retVal[Object.keys(result)[0]] = []; |
| 329 | break; |
| 330 | |
| 331 | case "notciv": |
| 332 | retVal[Object.keys(result)[0]] = false; |
| 333 | break; |
| 334 | |
| 335 | case "tech": |
| 336 | if (!retVal.generic) |
| 337 | retVal.generic = []; |
| 338 | retVal.generic.push(result.generic); |
322 | 339 | break; |
323 | 340 | |
324 | 341 | case "all": |
325 | | for (let ci in r[0]) |
326 | | c[ci] = r[1]; |
327 | | t = t; |
| 342 | for (let c of Object.keys(result)) |
| 343 | retVal[c] = result[c]; |
| 344 | break; |
| 345 | |
| 346 | case "any": |
| 347 | for (let civ of Object.keys(result)) |
| 348 | { |
| 349 | if (!retVal[civ]) |
| 350 | { |
| 351 | warn("Possible any/all req operator problem - "+operator +":"+uneval(value)); |
| 352 | retVal[civ] = []; |
| 353 | } |
| 354 | for (let v of result[civ]) |
| 355 | retVal.generic.push(v); |
| 356 | } |
| 357 | break; |
328 | 358 | } |
329 | 359 | } |
330 | | } |
331 | | return [ c, t ]; |
| 360 | break; |
332 | 361 | |
333 | 362 | default: |
334 | | warn("Unknown reqs operator: "+op); |
| 363 | warn("Unknown requirement operator: "+operator); |
335 | 364 | } |
336 | | return val; |
| 365 | return retVal; |
337 | 366 | } |
338 | 367 | |
339 | 368 | /** |
diff --git a/binaries/data/mods/public/gui/structree/structree.js b/binaries/data/mods/public/gui/structree/structree.js
index 64883f9..b38f9c7 100644
a
|
b
|
function selectCiv(civCode)
|
186 | 186 | let newProdTech = {}; |
187 | 187 | for (let prod of structInfo.production.technology) |
188 | 188 | { |
189 | | let phase = ""; |
| 189 | let phase = GetPhaseOfTechnology(prod); |
190 | 190 | |
191 | | if (depath(prod).slice(0,5) === "phase") |
192 | | { |
193 | | phase = g_ParsedData.phaseList.indexOf(g_ParsedData.phases[prod].actualPhase); |
194 | | if (phase > 0) |
195 | | phase = g_ParsedData.phaseList[phase - 1]; |
196 | | } |
197 | | else if (g_SelectedCiv in g_ParsedData.techs[prod].reqs) |
198 | | { |
199 | | for (let req of g_ParsedData.techs[prod].reqs[g_SelectedCiv]) |
200 | | if (depath(req).slice(0,5) === "phase") |
201 | | phase = req; |
202 | | } |
203 | | else if ("generic" in g_ParsedData.techs[prod].reqs) |
204 | | { |
205 | | for (let req of g_ParsedData.techs[prod].reqs.generic) |
206 | | if (depath(req).slice(0,5) === "phase") |
207 | | phase = req; |
208 | | } |
| 191 | if (phase === false) |
| 192 | continue; |
209 | 193 | |
210 | | if (depath(phase).slice(0,5) !== "phase" || g_ParsedData.phaseList.indexOf(phase) < structPhaseIdx) |
| 194 | if (g_ParsedData.phaseList.indexOf(phase) < structPhaseIdx) |
211 | 195 | if (structInfo.phase !== false) |
212 | 196 | phase = structInfo.phase; |
213 | 197 | else |
… |
… |
function selectCiv(civCode)
|
238 | 222 | } |
239 | 223 | else if (unit.required !== undefined) |
240 | 224 | { |
241 | | if (g_ParsedData.phases[unit.required]) |
242 | | phase = g_ParsedData.phases[unit.required].actualPhase; |
243 | | else if (g_ParsedData.techs[unit.required]) |
244 | | { |
245 | | let reqs = g_ParsedData.techs[unit.required].reqs; |
246 | | if (reqs[g_SelectedCiv]) |
247 | | phase = reqs[g_SelectedCiv][0]; |
248 | | else if (reqs.generic) |
249 | | phase = reqs.generic[0]; |
250 | | else |
251 | | warn("Empty requirements found on technology " + unit.required); |
252 | | } |
253 | | else |
254 | | warn("Technology " + unit.required + " for " + prod + " not found."); |
| 225 | phase = GetPhaseOfTechnology(unit.required); |
| 226 | if (phase === false) |
| 227 | continue; |
255 | 228 | } |
256 | 229 | |
257 | 230 | if (depath(phase).slice(0,5) !== "phase" || g_ParsedData.phaseList.indexOf(phase) < structPhaseIdx) |