BTFrstrm: add weapon location spreadsheets (Special1/2 and rear-facing)

This commit is contained in:
2026-07-24 10:18:06 -05:00
parent c3d82d78c9
commit 3f2d79a038
3 changed files with 220 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""Generate special_weapon_locations.csv and rear_facing_weapons.csv from stock mech subsystems."""
import csv
from pathlib import Path
BASE = Path("Gameleap/mw4/Content")
MECH_TABLE = BASE / "Tables" / "MechTable.tbl"
OUT_DIR = Path("BTFrstrm")
def parse_ini(path):
sections, cur_sec, cur_dict = [], None, {}
with open(path, 'r', encoding='latin-1', errors='replace') as f:
for raw in f:
line = raw.strip()
if line.startswith('[') and line.endswith(']'):
if cur_sec is not None:
sections.append((cur_sec, cur_dict))
cur_sec, cur_dict = line[1:-1], {}
elif '=' in line and cur_sec is not None:
k, _, v = line.partition('=')
cur_dict[k.strip()] = v.strip()
if cur_sec is not None:
sections.append((cur_sec, cur_dict))
return sections
def find_dir_ci(parent, name):
"""Case-insensitive directory lookup for Linux."""
exact = parent / name
if exact.exists():
return exact
name_lower = name.lower()
for child in parent.iterdir():
if child.is_dir() and child.name.lower() == name_lower:
return child
return None
def weapon_model(model_path):
return Path(model_path.replace('\\', '/')).stem
# Read chassis list from MechTable.tbl
chassis_list = []
with open(MECH_TABLE, 'r', encoding='latin-1') as f:
for raw in f:
line = raw.strip()
if not line or line.startswith('//') or line.startswith('[') or '=' not in line:
continue
name, _, rel = line.partition('=')
# rel is like "Mechs\Atlas\Atlas.instance"
parts = rel.strip().replace('\\', '/').split('/')
chassis_list.append((name.strip(), parts)) # parts = ['Mechs', 'Atlas', 'Atlas.instance']
print(f"Found {len(chassis_list)} chassis in MechTable.tbl")
HDR = ['Chassis', 'InternalLocation', 'Model', 'Site', 'AmmoCount', 'GroupIndex', 'WeaponFacing']
special_rows, rear_rows, missing = [], [], []
mechs_dir = BASE / "Mechs"
for chassis_name, path_parts in chassis_list:
# path_parts[1] is the mech directory name (e.g. 'Atlas', 'MadCat_MkII', 'Urbanmech')
if len(path_parts) < 2:
missing.append(chassis_name)
continue
mech_dir = find_dir_ci(mechs_dir, path_parts[1])
if not mech_dir:
missing.append(f"{chassis_name} (dir not found: {path_parts[1]})")
continue
subs = [f for f in mech_dir.glob('*.subsystems') if f.suffix == '.subsystems']
if not subs:
missing.append(f"{chassis_name} (no .subsystems in {mech_dir.name})")
continue
subsys_file = subs[0]
sections = parse_ini(subsys_file)
for sec_name, fields in sections:
if 'WeaponSubsystem' not in fields.get('Model', ''):
continue
loc = fields.get('InternalLocation', '')
model = weapon_model(fields.get('Model', ''))
site = fields.get('Site', '')
ammo = fields.get('AmmoCount', '')
group = fields.get('GroupIndex', '')
facing = fields.get('WeaponFacing', '')
if loc in ('Special1', 'Special2'):
special_rows.append([chassis_name, loc, model, site, ammo, group, facing])
if facing and facing != '0':
rear_rows.append([chassis_name, loc, model, site, ammo, group, facing])
# Write CSVs
out1 = OUT_DIR / 'special_weapon_locations.csv'
with open(out1, 'w', newline='') as f:
w = csv.writer(f)
w.writerow(HDR)
w.writerows(special_rows)
out2 = OUT_DIR / 'rear_facing_weapons.csv'
with open(out2, 'w', newline='') as f:
w = csv.writer(f)
w.writerow(HDR)
w.writerows(rear_rows)
print(f"Spreadsheet 1 ? Special1/2 weapon locations: {len(special_rows)} rows -> {out1}")
print(f"Spreadsheet 2 ? Non-forward WeaponFacing: {len(rear_rows)} rows -> {out2}")
if missing:
print(f"\nSkipped: {missing}")
+64
View File
@@ -0,0 +1,64 @@
Chassis,InternalLocation,Model,Site,AmmoCount,GroupIndex,WeaponFacing
Archer,LeftTorso,LRM15,site_ldmissile,24,2,2
Archer,RightTorso,LRM15,site_rdmissile,24,2,2
Ares,Special2,ClanLRM10,site_lmissileport,24,2,2
Ares,Special2,ClanLRM10,site_missileport,24,2,2
Ares,Special2,ClanLRM10,site_rmissileport,24,2,2
AssassinII,Special1,LRM5,site_missileport,24,2,2
Atlas,LeftTorso,LRM20,site_lmissileport,12,2,2
Avatar,LeftTorso,LRM5,site_lmissileport,24,2,2
Avatar,RightTorso,LRM5,site_rmissileport,24,2,2
Avatar,LeftTorso,LRM10,site_lmissileport,24,2,2
Avatar,RightTorso,LRM10,site_rmissileport,24,2,2
Awesome,CenterTorso,LRM5,site_ctorsoport,24,2,2
Battlemaster,RightTorso,MediumLaser,site_rdtorsoport,,1,1
Battlemaster,LeftTorso,MediumLaser,site_ldtorsoport,,1,1
BattlemasterIIC,RightTorso,ClanERMediumLaser,site_rdtorsoport,,1,1
BattlemasterIIC,LeftTorso,ClanERMediumLaser,site_ldtorsoport,,1,1
Black Lanner,Special2,ClanSRM6,site_rmissileport,15,2,2
Black Lanner,Special1,ClanLRM10,site_lmissileport,24,2,2
Bushwacker,Special1,LRM5,site_missileport,24,2,2
Bushwacker,Special1,LRM5,site_missileport,24,2,2
Catapult,LeftArm,LRM20,site_lmissileport,12,2,2
Catapult,RightArm,LRM20,site_rmissileport,12,2,2
Cauldron-Born,Special1,ClanLRM10,site_rmissileport,24,2,2
Cauldron-Born,Special2,ClanLRM10,site_lmissileport,24,2,2
Chimera,RightTorso,LRM5,site_missileport,24,2,2
Chimera,RightTorso,LRM5,site_missileport,24,2,2
Chimera,RightTorso,LRM5,site_missileport,24,2,2
Chimera,RightTorso,LRM5,site_missileport,24,2,2
Cyclops,LeftTorso,LRM10,site_lmissile,24,2,2
Cougar,LeftTorso,ClanLRM10,site_lmissileport,12,2,2
Cougar,RightTorso,ClanLRM10,site_rmissileport,12,2,2
Deimos,Special1,ClanLRM15,site_lmissileport,16,2,2
Deimos,Special2,ClanLRM15,site_rmissileport,16,2,2
Dragon,CenterTorso,LRM10,site_missleport,24,2,2
Flea,LeftTorso,SmallLaser,site_ltorsoport,,1,1
Flea,RightTorso,SmallLaser,site_rtorsoport,,1,1
Grizzly,LeftTorso,CLANLRM10,site_missleport,24,2,2
Hellhound,LeftTorso,ClanLRM10,site_missileport,12,2,2
Mad Cat,Special1,ClanLRM10,site_lmissileport,24,2,2
Mad Cat,Special2,ClanLRM10,site_rmissileport,24,2,2
Mad Cat MKII,Special2,ClanLRM15,site_lmissileport,16,2,2
Mad Cat MKII,Special1,ClanLRM15,site_rmissileport,16,2,2
Masakari,LeftTorso,ClanLRM10,site_lmissleport,24,2,2
Masakari,LeftTorso,ClanLRM10,site_ltorsoport,24,2,2
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
Raven,RightTorso,LRM5,site_rtorsoport,24,2,2
Sunder,LeftTorso,MediumLaser,site_ldtorsoport,,1,1
Sunder,RightTorso,MediumLaser,site_rdtorsoport,,1,1
Templar,LeftTorso,MediumPulseLaser,site_ldrtorsoport,,1,1
Templar,RightTorso,MediumPulseLaser,site_rdrtorsoport,,1,1
Thor,Special1,CLANLRM10,site_missileport,24,2,2
Uziel,Special1,LRM10,site_missileport,24,2,2
Vulture,LeftTorso,ClanLRM5,site_lmissileport,24,2,2
Vulture,RightTorso,ClanLRM5,site_rmissileport,24,2,2
Vulture,LeftTorso,ClanLRM10,site_lmissileport,24,2,2
Vulture,RightTorso,ClanLRM10,site_rmissileport,24,2,2
Wolfhound,CenterTorso,ClanERMediumLaser,site_reartorsoport,,1,1
Zeus,RightTorso,MediumPulseLaser,site_reartorsoport,,1,1
1 Chassis InternalLocation Model Site AmmoCount GroupIndex WeaponFacing
2 Archer LeftTorso LRM15 site_ldmissile 24 2 2
3 Archer RightTorso LRM15 site_rdmissile 24 2 2
4 Ares Special2 ClanLRM10 site_lmissileport 24 2 2
5 Ares Special2 ClanLRM10 site_missileport 24 2 2
6 Ares Special2 ClanLRM10 site_rmissileport 24 2 2
7 AssassinII Special1 LRM5 site_missileport 24 2 2
8 Atlas LeftTorso LRM20 site_lmissileport 12 2 2
9 Avatar LeftTorso LRM5 site_lmissileport 24 2 2
10 Avatar RightTorso LRM5 site_rmissileport 24 2 2
11 Avatar LeftTorso LRM10 site_lmissileport 24 2 2
12 Avatar RightTorso LRM10 site_rmissileport 24 2 2
13 Awesome CenterTorso LRM5 site_ctorsoport 24 2 2
14 Battlemaster RightTorso MediumLaser site_rdtorsoport 1 1
15 Battlemaster LeftTorso MediumLaser site_ldtorsoport 1 1
16 BattlemasterIIC RightTorso ClanERMediumLaser site_rdtorsoport 1 1
17 BattlemasterIIC LeftTorso ClanERMediumLaser site_ldtorsoport 1 1
18 Black Lanner Special2 ClanSRM6 site_rmissileport 15 2 2
19 Black Lanner Special1 ClanLRM10 site_lmissileport 24 2 2
20 Bushwacker Special1 LRM5 site_missileport 24 2 2
21 Bushwacker Special1 LRM5 site_missileport 24 2 2
22 Catapult LeftArm LRM20 site_lmissileport 12 2 2
23 Catapult RightArm LRM20 site_rmissileport 12 2 2
24 Cauldron-Born Special1 ClanLRM10 site_rmissileport 24 2 2
25 Cauldron-Born Special2 ClanLRM10 site_lmissileport 24 2 2
26 Chimera RightTorso LRM5 site_missileport 24 2 2
27 Chimera RightTorso LRM5 site_missileport 24 2 2
28 Chimera RightTorso LRM5 site_missileport 24 2 2
29 Chimera RightTorso LRM5 site_missileport 24 2 2
30 Cyclops LeftTorso LRM10 site_lmissile 24 2 2
31 Cougar LeftTorso ClanLRM10 site_lmissileport 12 2 2
32 Cougar RightTorso ClanLRM10 site_rmissileport 12 2 2
33 Deimos Special1 ClanLRM15 site_lmissileport 16 2 2
34 Deimos Special2 ClanLRM15 site_rmissileport 16 2 2
35 Dragon CenterTorso LRM10 site_missleport 24 2 2
36 Flea LeftTorso SmallLaser site_ltorsoport 1 1
37 Flea RightTorso SmallLaser site_rtorsoport 1 1
38 Grizzly LeftTorso CLANLRM10 site_missleport 24 2 2
39 Hellhound LeftTorso ClanLRM10 site_missileport 12 2 2
40 Mad Cat Special1 ClanLRM10 site_lmissileport 24 2 2
41 Mad Cat Special2 ClanLRM10 site_rmissileport 24 2 2
42 Mad Cat MKII Special2 ClanLRM15 site_lmissileport 16 2 2
43 Mad Cat MKII Special1 ClanLRM15 site_rmissileport 16 2 2
44 Masakari LeftTorso ClanLRM10 site_lmissleport 24 2 2
45 Masakari LeftTorso ClanLRM10 site_ltorsoport 24 2 2
46 Mauler LeftTorso LRM5 site_lmissileport 24 2 2
47 Mauler LeftTorso LRM5 site_lmissileport 24 2 2
48 Mauler LeftTorso LRM5 site_lmissileport 24 2 2
49 Mauler RightTorso LRM5 site_rmissileport 24 2 2
50 Mauler RightTorso LRM5 site_rmissileport 24 2 2
51 Mauler RightTorso LRM5 site_rmissileport 24 2 2
52 Raven RightTorso LRM5 site_rtorsoport 24 2 2
53 Sunder LeftTorso MediumLaser site_ldtorsoport 1 1
54 Sunder RightTorso MediumLaser site_rdtorsoport 1 1
55 Templar LeftTorso MediumPulseLaser site_ldrtorsoport 1 1
56 Templar RightTorso MediumPulseLaser site_rdrtorsoport 1 1
57 Thor Special1 CLANLRM10 site_missileport 24 2 2
58 Uziel Special1 LRM10 site_missileport 24 2 2
59 Vulture LeftTorso ClanLRM5 site_lmissileport 24 2 2
60 Vulture RightTorso ClanLRM5 site_rmissileport 24 2 2
61 Vulture LeftTorso ClanLRM10 site_lmissileport 24 2 2
62 Vulture RightTorso ClanLRM10 site_rmissileport 24 2 2
63 Wolfhound CenterTorso ClanERMediumLaser site_reartorsoport 1 1
64 Zeus RightTorso MediumPulseLaser site_reartorsoport 1 1
+45
View File
@@ -0,0 +1,45 @@
Chassis,InternalLocation,Model,Site,AmmoCount,GroupIndex,WeaponFacing
Ares,Special1,ClanERSmallLaser,site_lgunport,,1,
Ares,Special1,ClanERSmallLaser,site_rgunport,,1,
Ares,Special2,ClanLRM10,site_lmissileport,24,2,2
Ares,Special2,ClanLRM10,site_missileport,24,2,2
Ares,Special2,ClanLRM10,site_rmissileport,24,2,2
AssassinII,Special1,LRM5,site_missileport,24,2,2
Atlas,Special1,AC20,site_rtorsoport,10,1,
Atlas,Special2,SRM6,site_llmissile,15,2,
Avatar,Special1,MachineGun,site_ltorsoport,200,1,
Avatar,Special1,MachineGun,site_rtorsoport,200,1,
Battlemaster,Special2,PPC,site_rdgunport,,1,
Battlemaster,Special1,SRM6,site_missile,15,2,
BattlemasterIIC,Special1,ClanSSRM6,site_missile,15,2,
Behemoth,Special1,LargeLaser,site_ctorsoport,,1,
BehemothII,Special1,LargeLaser,site_ctorsoport,,1,
Black Lanner,Special2,ClanSRM6,site_rmissileport,15,2,2
Black Lanner,Special1,ClanLRM10,site_lmissileport,24,2,2
Brigand,Special2,MediumLaser,site_ltorsoport,,1,
Brigand,Special1,MediumLaser,site_rtorsoport,,1,
Bushwacker,Special1,LRM5,site_missileport,24,2,2
Bushwacker,Special1,LRM5,site_missileport,24,2,2
Cauldron-Born,Special1,ClanLRM10,site_rmissileport,24,2,2
Cauldron-Born,Special2,ClanLRM10,site_lmissileport,24,2,2
Cyclops,Special1,MediumPulseLaser,site_gunport,,1,
Deimos,Special1,ClanLRM15,site_lmissileport,16,2,2
Deimos,Special2,ClanLRM15,site_rmissileport,16,2,2
Hauptmann,Special1,ClanUltraAC20,site_rutorsoport,16,1,
Hellspawn,Special1,SSRM2,site_rmissileport,50,2,
HollanderII,Special2,SmallPulseLaser,site_cltorsoport,,1,
HollanderII,Special2,SmallPulseLaser,site_crtorsoport,,1,
HollanderII,Special1,GaussRifle,site_rtorsoport,16,1,
Hunchback,Special1,AC10,site_rutorsoport,20,1,
Loki,Special1,ClanSSRM6,site_missileport,15,2,
Mad Cat,Special1,ClanLRM10,site_lmissileport,24,2,2
Mad Cat,Special2,ClanLRM10,site_rmissileport,24,2,2
Mad Cat MKII,Special2,ClanLRM15,site_lmissileport,16,2,2
Mad Cat MKII,Special1,ClanLRM15,site_rmissileport,16,2,2
Rifleman,Special1,MediumLaser,site_ltorsoport,,1,
Rifleman,Special1,MediumLaser,site_rtorsoport,,1,
Solitaire,Special1,ClanERLargeLaser,site_rtorsoport,,1,
Thor,Special1,CLANLRM10,site_missileport,24,2,2
Uziel,Special1,LRM10,site_missileport,24,2,2
Vulture,Special1,ClanMachineGun,site_ltorsoport,200,1,
Vulture,Special1,ClanMachineGun,site_rtorsoport,200,1,
1 Chassis InternalLocation Model Site AmmoCount GroupIndex WeaponFacing
2 Ares Special1 ClanERSmallLaser site_lgunport 1
3 Ares Special1 ClanERSmallLaser site_rgunport 1
4 Ares Special2 ClanLRM10 site_lmissileport 24 2 2
5 Ares Special2 ClanLRM10 site_missileport 24 2 2
6 Ares Special2 ClanLRM10 site_rmissileport 24 2 2
7 AssassinII Special1 LRM5 site_missileport 24 2 2
8 Atlas Special1 AC20 site_rtorsoport 10 1
9 Atlas Special2 SRM6 site_llmissile 15 2
10 Avatar Special1 MachineGun site_ltorsoport 200 1
11 Avatar Special1 MachineGun site_rtorsoport 200 1
12 Battlemaster Special2 PPC site_rdgunport 1
13 Battlemaster Special1 SRM6 site_missile 15 2
14 BattlemasterIIC Special1 ClanSSRM6 site_missile 15 2
15 Behemoth Special1 LargeLaser site_ctorsoport 1
16 BehemothII Special1 LargeLaser site_ctorsoport 1
17 Black Lanner Special2 ClanSRM6 site_rmissileport 15 2 2
18 Black Lanner Special1 ClanLRM10 site_lmissileport 24 2 2
19 Brigand Special2 MediumLaser site_ltorsoport 1
20 Brigand Special1 MediumLaser site_rtorsoport 1
21 Bushwacker Special1 LRM5 site_missileport 24 2 2
22 Bushwacker Special1 LRM5 site_missileport 24 2 2
23 Cauldron-Born Special1 ClanLRM10 site_rmissileport 24 2 2
24 Cauldron-Born Special2 ClanLRM10 site_lmissileport 24 2 2
25 Cyclops Special1 MediumPulseLaser site_gunport 1
26 Deimos Special1 ClanLRM15 site_lmissileport 16 2 2
27 Deimos Special2 ClanLRM15 site_rmissileport 16 2 2
28 Hauptmann Special1 ClanUltraAC20 site_rutorsoport 16 1
29 Hellspawn Special1 SSRM2 site_rmissileport 50 2
30 HollanderII Special2 SmallPulseLaser site_cltorsoport 1
31 HollanderII Special2 SmallPulseLaser site_crtorsoport 1
32 HollanderII Special1 GaussRifle site_rtorsoport 16 1
33 Hunchback Special1 AC10 site_rutorsoport 20 1
34 Loki Special1 ClanSSRM6 site_missileport 15 2
35 Mad Cat Special1 ClanLRM10 site_lmissileport 24 2 2
36 Mad Cat Special2 ClanLRM10 site_rmissileport 24 2 2
37 Mad Cat MKII Special2 ClanLRM15 site_lmissileport 16 2 2
38 Mad Cat MKII Special1 ClanLRM15 site_rmissileport 16 2 2
39 Rifleman Special1 MediumLaser site_ltorsoport 1
40 Rifleman Special1 MediumLaser site_rtorsoport 1
41 Solitaire Special1 ClanERLargeLaser site_rtorsoport 1
42 Thor Special1 CLANLRM10 site_missileport 24 2 2
43 Uziel Special1 LRM10 site_missileport 24 2 2
44 Vulture Special1 ClanMachineGun site_ltorsoport 200 1
45 Vulture Special1 ClanMachineGun site_rtorsoport 200 1