re: who selects a loadout -- the pak entry does; the Arsenal pak is stage-scoped
Settled by elimination with two controls. The 15 loadout names appear as a field VALUE nowhere on the disc -- 0 occurrences across every pak -- while the control Arbalest_155KG, which is referenced, appears 150 times as a value in the same pak. They occur only as the field names of the UNITS record. They are not in the executable either; control: WEAPONS (a section key) is, Arbalest_155KG is not. So nothing references a loadout by name. The selection is which pak entry the Hangar loads. GP_HANGAR_ARSENAL.pak has 180 IDXD entries in 10 shapes; 168 carry a UNITS roster = 28 stages x 6 languages, and the other 12 = 2 x 6. Each entry is one stage's whole Hangar config, and its UNITS roster is the flight for that stage -- 5 distinct rosters over 15 / 5 / 5 / 2 / 1 stages, including one where Rhino2-Katana flies alone. Every count is a multiple of 6 and they sum to 28, the disc's stage count by a fourth independent route. Corrects the previous commit: it read the pak with setdefault, so '15 loadouts / 24 allow-lists / STANDARD_ARM1 has 11 entries' is the union of first-seen records, not one table. Contents vary per entry -- PlayerSET_ARM1 has 5 distinct contents, STANDARD_ARM1 3, ExSET_NOSE 4. The chain and both controls (60/60, 70/88) are per-record and unaffected; only the per-list sizes were over-generalised. Not settled: the entry filenames. name_hash probing over 8 templates x 40 indices x 6 languages resolved 0, while the same probe's controls <lang>\weapon.tbl and <lang>\strings.tbl resolved 12/12. Artefact +40 lines / 1 changed heading; the other four regenerate byte-identical.
This commit is contained in:
@@ -43,12 +43,40 @@ def main():
|
||||
elif set(SLOTS) <= set(n): loadouts.setdefault(nm, r)
|
||||
elif set(n) == {'Type'}: allow.setdefault(nm, r)
|
||||
|
||||
idxd = [(h, U.parse(b)) for h, b in pak_entries(ars) if b[:4] == b'IDXD']
|
||||
withu = [(h, r) for h, r in idxd if any(x['squadron'] == 'UNITS' for x in r)]
|
||||
rosters = collections.Counter()
|
||||
for h, recs in withu:
|
||||
for r in recs:
|
||||
if r['squadron'] == 'UNITS':
|
||||
rosters[tuple(sorted(n for t, n, v in r['fields']))] += 1
|
||||
|
||||
print("# The Hangar loadout system")
|
||||
print("# Regenerate: python3 tools/re-capture/hangar_loadouts.py")
|
||||
print("# See docs/re/structures/hangar-loadout-system.md")
|
||||
print("\n## counts")
|
||||
print("\n## the pak is STAGE-SCOPED -- one config entry per stage per language")
|
||||
print(" total pak entries %4d IDXD entries %3d" % (len(pak_entries(ars)), len(idxd)))
|
||||
print(" entries carrying a UNITS roster %3d = %d stages x 6 languages"
|
||||
% (len(withu), len(withu) // 6))
|
||||
print(" entries without one %3d = %d x 6 (the item table + siblings)"
|
||||
% (len(idxd) - len(withu), (len(idxd) - len(withu)) // 6))
|
||||
print(" every roster count is a multiple of 6: %s ; they sum to %d stages"
|
||||
% (all(c % 6 == 0 for c in rosters.values()), sum(c // 6 for c in rosters.values())))
|
||||
print("\n## the %d distinct UNITS rosters -- who is in the flight, per stage" % len(rosters))
|
||||
for t, c in rosters.most_common():
|
||||
print(" %2d stage(s) %d pilots: %s" % (c // 6, len(t), ", ".join(t)))
|
||||
|
||||
print("\n## counts, UNION over all entries (each name first-seen)")
|
||||
print(" arsenal items %3d loadout records %3d per-slot allow-lists %3d"
|
||||
% (len(items), len(loadouts), len(allow)))
|
||||
var = collections.defaultdict(set)
|
||||
for h, recs in idxd:
|
||||
for r in recs:
|
||||
if set(U.named(r)) == {'Type'}:
|
||||
var[r['squadron']].add(tuple(v for t, n, v in r['fields'] if n is None))
|
||||
print("\n## allow-list CONTENT VARIES BY ENTRY -- distinct contents per name")
|
||||
for k in sorted(var):
|
||||
print(" %-18s %d" % (k, len(var[k])))
|
||||
|
||||
print("\n## loadout records")
|
||||
for nm in sorted(loadouts):
|
||||
|
||||
Reference in New Issue
Block a user