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