summaryrefslogtreecommitdiff
path: root/ModSlots
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-11-20 18:38:35 -0500
committerAndrew Opalach <andrew@akon.city> 2025-11-20 18:38:35 -0500
commit3107bbb97fbb3cdd6db7d4986488576878591b34 (patch)
treeb729e0c0ddae6555994bacd73883f52e77d8e7df /ModSlots
parent10463050906aae3d9d100ddb00bf1bbbd891dc26 (diff)
downloadNewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.tar.gz
NewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.tar.bz2
NewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.zip
Flesh out ModSlots
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'ModSlots')
-rw-r--r--ModSlots/ArmorIDS.py356
-rw-r--r--ModSlots/ArmorIDs.py50
-rw-r--r--ModSlots/ArmorIDs.txt154
-rwxr-xr-xModSlots/ModSlots.py246
-rw-r--r--ModSlots/slots.example.txt122
5 files changed, 446 insertions, 482 deletions
diff --git a/ModSlots/ArmorIDS.py b/ModSlots/ArmorIDS.py
deleted file mode 100644
index bc21eca..0000000
--- a/ModSlots/ArmorIDS.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# https://github.com/Ezekial711/MonsterHunterWorldModding/wiki/Armor-IDs
-# Macro reformat, Remove None/Unavailable, sort u
-# Duplicates:
-# I guess this means the list has lots of errors, unless I'm missing something.
-# It would take a while to verify all this.
-'''
- 'pl001_0000': 'Skull',
- 'pl001_0000': 'Bushi "Homare"',
- 'pl001_0000': 'Bushi "Sabi"',
- 'pl001_0000': 'Unavailable',
- 'pl002_0000': 'Hunter',
- 'pl002_0010': 'Hunter',
- 'pl003_0000': 'Bone',
- 'pl004_0000': 'Alloy',
- 'pl005_0000': 'Kestodon',
- 'pl006_0000': 'Gajau',
- 'pl009_0000': 'Kulu',
- 'pl009_0001': 'Kulu+',
- 'pl010_0000': 'Pukei',
- 'pl010_0001': 'Pukei+',
- 'pl010_0010': 'Pukei',
- 'pl011_0000': 'Jyura',
- 'pl011_0001': 'Jyura+',
- 'pl013_0000': 'Kadachi',
- 'pl013_0001': 'Kadachi+',
- 'pl014_0000': 'Chain',
- 'pl015_0000': 'Gastodon',
- 'pl016_0000': 'Barnos',
- 'pl019_0000': 'Butterfly',
- 'pl020_0000': 'Anja',
- 'pl020_0001': 'Anja+',
- 'pl020_0010': 'Anja',
- 'pl020_0011': 'Anja+',
- 'pl022_0000': 'Girros',
- 'pl022_0001': 'Girros+',
- 'pl023_0000': 'Tzitzi',
- 'pl023_0001': 'Tzitzi+',
- 'pl024_0000': 'Lumu',
- 'pl024_0001': 'Lumu+',
- 'pl025_0000': 'High Metal',
- 'pl028_0000': 'Baan',
- 'pl028_0001': 'Baan+',
- 'pl028_0010': 'Baan',
- 'pl031_0000': 'Ingot',
- 'pl037_0000': 'Unavailable',
- 'pl038_0000': 'Zorah',
- 'pl038_0010': 'Zorah',
- 'pl042_0000': 'Bazel',
- 'pl042_0010': 'Bazel',
- 'pl043_0000': 'Damascus',
- 'pl043_0010': 'Damascus',
- 'pl044_0000': 'Dober',
- 'pl045_0000': 'Xeno',
- 'pl045_0010': 'Xeno',
- 'pl045_0020': 'Xeno',
- 'pl049_0000': 'Kulve Taroth',
- 'pl049_0010': 'Kulve Taroth',
- 'pl049_0020': 'Kulve',
- 'pl054_0000': 'Skull',
- 'pl057_0000': 'Butterfly',
- 'pl058_0000': 'Shamos',
- 'pl059_0000': 'Bushi "Homare"',
- 'pl060_0000': 'Strategist',
- 'pl061_0000': 'Dragonking',
- 'pl072_0001': 'Azure Age',
- 'pl091_0000': 'Artian',
- 'pl093_0000': 'Black Belt',
- 'pl095_0000': 'Unavailable',
- 'pl095_0010': 'Unavailable',
- 'pl098_0000': 'Duffel Penguin+',
- 'pl100_0000': 'Sealed Dragon Cloth',
- 'pl101_0000': 'Wyverian Ears',
- 'pl110_0000': 'Beo+',
- 'pl118_0000': 'Geralt',
- 'pl121_0000': 'Guardian',
- 'pl121_0000': 'Guardian+',
- 'pl124_0000': 'Rose',
- 'pl125_0000': 'Passion',
- 'pl126_0000': 'Demonlord',
- 'pl127_0000': 'Oolong',
- 'pl128_0000': 'Astral',
-'''
-
-ArmorIDS = {
- 'pl000_0000': 'Invalid',
- 'pl001_0000': 'Leather',
- 'pl002_0000': 'Hunter\'s',
- 'pl002_0010': 'Hunter\'s',
- 'pl003_0000': 'Bone+',
- 'pl004_0000': 'Alloy+',
- 'pl005_0000': 'Kestodon+',
- 'pl006_0000': 'Gajau+',
- 'pl007_0000': 'Vespoid',
- 'pl007_0001': 'Vespoid+',
- 'pl008_0000': 'Jagras',
- 'pl008_0001': 'Jagras+',
- 'pl009_0000': 'Kulu-Ya-Ku',
- 'pl009_0001': 'Kulu-Ya-Ku+',
- 'pl010_0000': 'Pukei-Pukei',
- 'pl010_0001': 'Pukei-Pukei+',
- 'pl010_0010': 'Pukei-Pukei',
- 'pl010_0101': 'Coral Pukei+',
- 'pl011_0000': 'Jyuratodus',
- 'pl011_0001': 'Jyuratodus+',
- 'pl012_0000': 'Barroth',
- 'pl012_0001': 'Barroth+',
- 'pl013_0000': 'Tobi-Kadachi',
- 'pl013_0001': 'Tobi-Kadachi+',
- 'pl013_0101': 'Viper Kadachi+',
- 'pl014_0000': 'Chainmail',
- 'pl015_0000': 'Gastodon+',
- 'pl016_0000': 'Barnos+',
- 'pl017_0000': 'Hornetaur',
- 'pl017_0001': 'Hornetaur+',
- 'pl018_0000': 'Origin',
- 'pl019_0000': 'King Beetle',
- 'pl020_0000': 'Anjanath',
- 'pl020_0001': 'Anjanath+',
- 'pl020_0010': 'Anjanath',
- 'pl020_0011': 'Anjanath+',
- 'pl020_0101': 'Fulgur Anja+',
- 'pl020_0111': 'Fulgur Anja+',
- 'pl021_0000': 'Rathian',
- 'pl021_0001': 'Rathian+',
- 'pl021_0010': 'Rathian',
- 'pl021_0011': 'Rathian+',
- 'pl021_0100': 'Rath Heart',
- 'pl021_0101': 'Rath Heart+',
- 'pl021_0110': 'Rath Heart',
- 'pl021_0111': 'Rath Heart+',
- 'pl021_0200': 'Golden Lune+',
- 'pl021_0210': 'Golden Lune+',
- 'pl022_0000': 'Great Girros',
- 'pl022_0001': 'Great Girros+',
- 'pl023_0000': 'Tzitzi-Ya-Ku',
- 'pl023_0001': 'Tzitzi-Ya-Ku+',
- 'pl024_0000': 'Paolumu',
- 'pl024_0001': 'Paolumu+',
- 'pl024_0101': 'Lumu Phantasm+',
- 'pl025_0000': 'High Metal+',
- 'pl026_0000': 'Death Stench',
- 'pl027_0000': 'Legiana',
- 'pl027_0001': 'Legiana+',
- 'pl027_0010': 'Legiana',
- 'pl027_0011': 'Legiana+',
- 'pl027_0500': 'Shrieking Legia+',
- 'pl027_0510': 'Shrieking Legia+',
- 'pl028_0000': 'Radobaan',
- 'pl028_0001': 'Radobaan+',
- 'pl028_0010': 'Radobaan',
- 'pl029_0000': 'Odogaron',
- 'pl029_0001': 'Odogaron+',
- 'pl029_0010': 'Odogaron',
- 'pl029_0011': 'Odogaron+',
- 'pl029_0101': 'Death Garon+',
- 'pl029_0111': 'Death Garon+',
- 'pl030_0000': 'Nergigante',
- 'pl030_0010': 'Nergigante',
- 'pl030_0020': 'Nergigante',
- 'pl030_0500': 'Ruiner Nergi+',
- 'pl030_0510': 'Ruiner Nergi+',
- 'pl031_0000': 'Ingot+',
- 'pl032_0000': 'Vaal Hazak',
- 'pl032_0010': 'Vaal Hazak',
- 'pl032_0020': 'Vaal Hazak',
- 'pl032_0500': 'Blackveil Hazak+',
- 'pl032_0510': 'Blackveil Hazak+',
- 'pl033_0000': 'Rathalos',
- 'pl033_0001': 'Rathalos+',
- 'pl033_0010': 'Rathalos',
- 'pl033_0011': 'Rathalos+',
- 'pl033_0100': 'Rath Soul',
- 'pl033_0101': 'Rath Soul+',
- 'pl033_0110': 'Rath Soul',
- 'pl033_0111': 'Rath Soul+',
- 'pl033_0200': 'Silver Sol+',
- 'pl033_0210': 'Silver Sol+',
- 'pl034_0000': 'Diablos',
- 'pl034_0001': 'Diablos+',
- 'pl034_0010': 'Diablos',
- 'pl034_0011': 'Diablos+',
- 'pl034_0100': 'Diablos Nero',
- 'pl034_0101': 'Diablos Nero+',
- 'pl034_0110': 'Diablos Nero',
- 'pl034_0111': 'Diablos Nero+',
- 'pl035_0000': 'Kirin',
- 'pl035_0001': 'Kirin+',
- 'pl035_0010': 'Kirin',
- 'pl035_0011': 'Kirin+',
- 'pl035_0020': 'Kirin',
- 'pl036_0000': 'Brigade',
- 'pl037_0000': 'Pulverizing Feather',
- 'pl038_0000': 'Zorah+',
- 'pl038_0010': 'Zorah+',
- 'pl038_0020': 'Zorah',
- 'pl039_0000': 'Dodogama',
- 'pl039_0001': 'Dodogama+',
- 'pl040_0000': 'Lavasioth',
- 'pl040_0001': 'Lavasioth+',
- 'pl040_0010': 'Lavasioth',
- 'pl041_0000': 'Uragaan',
- 'pl041_0001': 'Uragaan+',
- 'pl041_0010': 'Uragaan',
- 'pl042_0000': 'Bazelgeuse',
- 'pl042_0010': 'Bazelgeuse',
- 'pl042_0500': 'Seething Bazel+',
- 'pl042_0510': 'Seething Bazel+',
- 'pl043_0000': 'Damascus+',
- 'pl043_0010': 'Damascus+',
- 'pl044_0000': 'Dober+',
- 'pl045_0000': 'Xeno\'jiiva',
- 'pl045_0010': 'Xeno\'jiiva',
- 'pl045_0020': 'Xeno\'jiiva',
- 'pl046_0000': 'Teostra',
- 'pl046_0001': 'Teostra+',
- 'pl046_0010': 'Teostra',
- 'pl046_0011': 'Teostra+',
- 'pl046_0020': 'Teostra',
- 'pl047_0000': 'Kushala',
- 'pl047_0001': 'Kushala+',
- 'pl047_0010': 'Kushala',
- 'pl047_0011': 'Kushala+',
- 'pl047_0020': 'Kushala',
- 'pl048_0000': 'Guild Cross',
- 'pl049_0000': 'Kulve',
- 'pl049_0001': 'Kulve Taroth+',
- 'pl049_0010': 'Kulve',
- 'pl049_0011': 'Kulve Taroth+',
- 'pl049_0020': 'Kulve Taroth',
- 'pl050_0000': 'Deviljho',
- 'pl050_0010': 'Deviljho',
- 'pl050_0500': 'Savage Jho+',
- 'pl050_0510': 'Savage Jho+',
- 'pl051_0000': 'Lunastra',
- 'pl051_0001': 'Lunastra+',
- 'pl051_0010': 'Lunastra',
- 'pl051_0011': 'Lunastra+',
- 'pl051_0020': 'Lunastra',
- 'pl052_0000': 'Alatreon+',
- 'pl052_0010': 'Alatreon+',
- 'pl053_0000': 'Commission',
- 'pl054_0000': 'Skull Mask',
- 'pl055_0000': 'Faux Felyne',
- 'pl056_0000': 'Mosswine Mask',
- 'pl057_0000': 'Queen Beetle',
- 'pl057_0010': 'Butterfly',
- 'pl058_0000': 'Shamos+',
- 'pl059_0000': 'Crystal Earring',
- 'pl060_0000': 'Strategist Spectacles',
- 'pl061_0000': 'Dragonking Eyepatch',
- 'pl062_0000': 'Shadow Shades',
- 'pl063_0000': 'Sealed Eyepatch',
- 'pl064_0000': 'Wiggler Head',
- 'pl065_0000': 'Kulu-Ya-Ku Head',
- 'pl066_0000': 'Bushi "Sabi"',
- 'pl066_0010': 'Bushi "Homare"',
- 'pl067_0000': 'Samurai',
- 'pl068_0000': 'HARDUMMY',
- 'pl068_0010': 'HARDUMMY',
- 'pl068_0020': 'HARDUMMY',
- 'pl069_0000': 'Ryu',
- 'pl070_0000': 'Sakura',
- 'pl071_0000': 'Dante',
- 'pl072_0000': 'Azure Starlord',
- 'pl072_0001': 'Azure Age+',
- 'pl073_0000': 'Drachen',
- 'pl074_0000': 'Blossom',
- 'pl075_0000': 'Diver',
- 'pl076_0000': 'Harvest',
- 'pl077_0000': 'Orion',
- 'pl078_0000': 'Gala Suit',
- 'pl080_0000': 'Nargacuga+',
- 'pl080_0010': 'Nargacuga+',
- 'pl081_0000': 'Glavenus+',
- 'pl081_0010': 'Glavenus+',
- 'pl081_0100': 'Acidic Glavenus+',
- 'pl081_0110': 'Acidic Glavenus+',
- 'pl082_0000': 'Brachydios+',
- 'pl082_0010': 'Brachydios+',
- 'pl082_0500': 'Raging Brachy+',
- 'pl082_0510': 'Raging Brachy+',
- 'pl083_0000': 'Tigrex+',
- 'pl083_0010': 'Tigrex+',
- 'pl083_0100': 'Brute Tigrex+',
- 'pl083_0110': 'Brute Tigrex+',
- 'pl084_0000': 'Banbaro+',
- 'pl084_0010': 'Banbaro+',
- 'pl085_0000': 'Velkhana+',
- 'pl085_0010': 'Velkhana+',
- 'pl085_0020': 'Velkhana+',
- 'pl086_0000': 'Namielle+',
- 'pl086_0010': 'Namielle+',
- 'pl086_0020': 'Namielle+',
- 'pl087_0000': 'Safi\'jiiva+',
- 'pl087_0010': 'Safi\'jiiva+',
- 'pl088_0000': 'Shara Ishvalda+',
- 'pl088_0010': 'Shara Ishvalda+',
- 'pl089_0000': 'Barioth+',
- 'pl089_0010': 'Barioth+',
- 'pl089_0500': 'Frostfang Barioth+',
- 'pl089_0510': 'Frostfang Barioth+',
- 'pl091_0000': 'Artian+',
- 'pl092_0000': 'Guildwork+',
- 'pl093_0000': 'Black Belt+',
- 'pl094_0000': 'Guild Palace+',
- 'pl095_0000': 'Acrobat',
- 'pl095_0010': 'Showman',
- 'pl096_0000': 'Faux Kelbi',
- 'pl097_0000': 'Faux Aptonoth',
- 'pl098_0000': 'Duffel Penguin Mask+',
- 'pl099_0000': 'Skull Scarf',
- 'pl100_0000': 'Sealed Dragon Cloth+',
- 'pl101_0000': 'Wyverian Ears+',
- 'pl102_0000': 'Wulg+',
- 'pl103_0000': 'Cortos+',
- 'pl104_0000': 'Clockwork+',
- 'pl105_0000': 'Direwolf+',
- 'pl106_0000': 'Thermae',
- 'pl107_0000': 'Zinogre+',
- 'pl107_0010': 'Zinogre+',
- 'pl107_0100': 'Stygian Zin+',
- 'pl107_0110': 'Stygian Zin+',
- 'pl108_0000': 'Yian Garuga+',
- 'pl108_0010': 'Yian Garuga+',
- 'pl109_0000': 'Rajang+',
- 'pl109_0010': 'Rajang+',
- 'pl109_0500': 'Furious Rajang+',
- 'pl109_0510': 'Furious Rajang+',
- 'pl110_0000': 'Beotodus+',
- 'pl111_0000': 'Hare Band',
- 'pl112_0000': 'Downy Crake',
- 'pl113_0000': 'Pearlspring+',
- 'pl113_0001': 'Goldspring Macaque',
- 'pl114_0000': 'Kadachi Scarf',
- 'pl115_0000': 'Buff Body+',
- 'pl115_0001': 'Buff Body+',
- 'pl116_0000': 'Beetle',
- 'pl117_0000': 'Butterfly',
- 'pl118_0000': 'Geralt of Rivia',
- 'pl119_0000': 'Ciri',
- 'pl120_0000': 'Bayek',
- 'pl121_0000': 'Defender',
- 'pl122_0000': 'Yukumo',
- 'pl123_0000': 'Silver Knight',
- 'pl124_0000': 'Rose+',
- 'pl125_0000': 'Passion+',
- 'pl126_0000': 'Demonlord+',
- 'pl127_0000': 'Oolong+',
- 'pl128_0000': 'Astral+',
- 'pl129_0000': 'Fatalis+',
- 'pl129_0010': 'Fatalis+',
- 'pl130_0000': 'Leon+',
- 'pl131_0000': 'Claire+',
- 'pl500_0000': 'Innerwear',
- 'pl501_0000': 'Innerwear'
-}
diff --git a/ModSlots/ArmorIDs.py b/ModSlots/ArmorIDs.py
new file mode 100644
index 0000000..fc5b831
--- /dev/null
+++ b/ModSlots/ArmorIDs.py
@@ -0,0 +1,50 @@
+ArmorIDs = {
+ 'Leather': ['pl001_0000', 'slg000_0000'],
+ 'Chainmail': ['pl014_0000', 'slg000_0000'],
+ 'Hunter\'s': ['pl0002_0000', 'slg000_0000'],
+ 'Hunter\'s (β)': ['pl002_0010', 'slg000_0000'],
+ 'Bone': ['pl003_0000', 'slg003_0000'],
+ 'Vespoid': ['pl007_0000', 'slg007_000'],
+ 'Vespoid+': ['pl007_0001', 'slg007_0000'],
+ 'Kestodon': ['pl005_0000/arm', 'slg000_0000'],
+ 'Gajau': ['pl006_0000/leg'],
+ 'Jagras': ['pl008_0000', 'slg000_0000'],
+ 'Jagras+': ['pl008_0001', 'slg000_0000'],
+ 'Kulu': ['pl009_0000', 'slg000_0000'],
+ 'Kulu+': ['pl009_0001', 'slg000_0000'],
+ 'Alloy': ['pl004_0000', 'slg001_0000'],
+ 'Pukei': ['pl010_0000', 'slg000_0000'],
+ 'Pukei (β)': ['pl010_0010', 'slg000_0000'],
+ 'Pukei+': ['pl010_0001', 'slg000_0000'],
+ 'Coral Pukei+': ['pl010_0101', 'slg000_0000'],
+ 'Barroth': ['pl012_0000', 'slg012_0000'],
+ 'Barroth+': ['pl012_0001+', 'slg012_0000'],
+ 'Jyura': ['pl011_0000', 'slg011_0000'],
+ 'Jyura+': ['pl011_0001', 'slg011_0000'],
+ 'Kadachi': ['pl013_0000', 'slg001_0000'],
+ 'Kadachi+': ['pl013_0001', 'slg001_0000'],
+ 'Viper Kadachi+': ['pl013_0101', 'slg001_0000'],
+ 'High Metal': ['pl025_0000', 'slg002_0000'],
+ 'Butterfly': ['pl019_0000', 'slg019_0000'],
+ 'Shamos': ['pl058_0000/helm'],
+ 'Hornetaur': ['pl017_0000', 'slg017_0000'],
+ 'Hornetaur+': ['pl017_0001', 'slg017_0001'],
+ 'Anja': ['pl020_0000', 'slg020_0000'],
+ 'Anja (β)': ['pl020_0010', 'slg020_0000'],
+ 'Anja+': ['pl020_0001', 'slg020_0000'],
+ 'Anja+ (β)': ['pl020_0011', 'slg020_0000'],
+ 'Fulgur Anja+': ['pl020_0101', 'slg020_0100'],
+ 'Fulgur Anja+ (β)': ['pl020_0111', 'slg020_0100'],
+ 'Rathian': ['pl021_0000', 'slg021_0000'],
+
+ 'Kirin': ['pl035_0000', 'slg000_0000'],
+ 'Kirin (β)': ['pl035_0010', 'slg000_0000'],
+ 'Kirin (γ)': ['pl035_0020', 'slg000_0000'],
+ 'Kirin+': ['pl035_0001', 'slg000_0000'],
+ 'Kirin+ (β)': ['pl035_0011', 'slg000_0000'],
+
+ 'Lavasioth': ['pl040_0000', 'slg040_0000'],
+ 'Lavasioth (β)': ['pl040_0010', 'slg040_0000'],
+ 'Lavasioth+': ['pl040_0001', 'slg040_0000'],
+ 'Artian+': ['pl091_0000', 'slg091_0000']
+}
diff --git a/ModSlots/ArmorIDs.txt b/ModSlots/ArmorIDs.txt
new file mode 100644
index 0000000..97a0451
--- /dev/null
+++ b/ModSlots/ArmorIDs.txt
@@ -0,0 +1,154 @@
+# Scan for places where armor IDs are stored in memory (looks for f_helm, scroll down a lot to find the rest).
+70 6C 5C 66 5F 65 71 75 69 70 5C 70 6C ?? ?? ??
+5F ?? ?? ?? ?? 5C 68 65 6C 6D 5C 6D 6F 64 5C 66
+5F 68 65 6C 6D ?? ?? ?? 5F ?? ?? ?? ?? 5F 4E 4D
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
+70 6C 5C 66 5F 65 71 75 69 70 5C 70 6C ?? ?? ??
+5F ?? ?? ?? ?? 5C 68 65 6C 6D 5C 6D 6F 64 5C 66
+5F 68 65 6C 6D ?? ?? ?? 5F ?? ?? ?? ?? ?? ?? ??
+
+# One line
+70 6C 5C 66 5F 65 71 75 69 70 5C 70 6C ?? ?? ?? 5F ?? ?? ?? ?? 5C 68 65 6C 6D 5C 6D 6F 64 5C 66 5F 68 65 6C 6D ?? ?? ?? 5F ?? ?? ?? ?? 5F 4E 4D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 70 6C 5C 66 5F 65 71 75 69 70 5C 70 6C ?? ?? ?? 5F ?? ?? ?? ?? 5C 68 65 6C 6D 5C 6D 6F 64 5C 66 5F 68 65 6C 6D ?? ?? ?? 5F ?? ?? ?? ?? ?? ?? ??
+
+# Per-line, if there is no revision like (β) or (+), it means the ID remains the same.
+
+Leather: pl001_0000, slg000_0000
+Chainmail: pl014_0000, slg000_0000
+Hunter's: pl002_0000, slg000_0000, pl002_0010(β)
+Bone: pl003_0000, slg003_0000
+Vespoid: pl007_0000, slg007_0000, pl007_0001(+), slg007_0001(+)
+Kestodon: pl005_0000, slg000_0000 (Arm only)
+Gajau: pl006_0000 (Leg only)
+Jagras: pl008_0000, slg000_0000, pl008_0001(+)
+Kulu: pl009_0000, slg000_0000, pl009_0001(+)
+Alloy: pl004_0000, slg001_0000
+Pukei: pl010_0000, slg000_0000, pl010_0010(β), pl010_0001(+)
+Coral Pukei: pl010_0101(+), slg000_0000(+)
+Barroth: pl012_0000, slg012_0000, pl012_0001(+)
+Jyura: pl011_0000, slg011_0000, pl011_0001(+)
+Kadachi: pl013_0000, slg001_0000, pl013_0001(+)
+Viper Kadachi: pl013_0101(+), slg001_0000(+)
+High Metal: pl025_0000, slg002_0000
+Butterfly: pl019_0000, slg019_0000
+Shamos: pl058_0000 (Head only)
+Hornetaur: pl017_0000, slg017_0000, pl017_0001(+), slg017_0001(+)
+Anja: pl020_0000, slg020_0000, pl020_0010(β), pl020_0001(+), pl020_0011(β+)
+Fulgur Anja: pl020_0101(+), slg020_0100(+), pl020_0111(β+)
+Rathian: pl021_0000, slg021_0000, pl021_0010(β), pl021_0001(+), pl021_0011(β+)
+Rath Heart: pl021_0100, slg021_0100, pl021_0110(β), pl021_0101(+), pl021_0111(β+)
+Golden Lune: pl021_0200(+), pl021_0210(β+), slg021_0200(+)
+Tzitzi: pl023_0000, slg023_0000, pl023_0001(+)
+Lumu: pl024_0000, slg000_0000, pl024_0001(+)
+Lumu Phantasm: pl024_0101(+), slg000_0000(+)
+Girros: pl022_0000, slg000_0000, pl022_0001(+)
+Baan: pl028_0000, slg028_0000, pl028_0010(β), pl028_0001(+)
+Ingot: pl031_0000, slg031_0000
+Death Stench: pl026_0000, slg026_0000
+Brigade: pl036_0000, slg001_0000
+Legiana: pl027_0000, slg027_0000, pl027_0010(β), pl027_0001(+), pl027_0011(β+)
+Shrieking Legia: pl027_0500(+), slg027_0500(+), pl027_0510(β+)
+Odogaron: pl029_0000, slg029_0000, pl029_0010(β), pl029_0001(+), pl029_0011(β+)
+Death Garon: pl029_0101(+), slg029_0100(+), pl029_0111(β+)
+Rathalos: pl033_0000, slg033_0000, pl033_0010(β), pl033_0001(+), pl033_0011(β+)
+Rath Soul: pl033_0100, slg033_0100, pl033_0110(β), pl033_0101(+), pl033_0111(β+)
+Silver Sol: pl033_0200(+), slg033_0200(+), pl033_0210(β+)
+Diablos: pl034_0000, slg034_0000, pl034_0010(β), pl034_0001(+), pl034_0011(β+)
+Diablos Nero: pl034_0100, slg034_0100, pl034_0110(β), pl034_0101(+), pl034_0111(β+)
+Kirin: pl035_0000, slg000_0000, pl035_0010(β), pl035_0020(γ), pl035_0001(+), pl035_0011(β+)
+Blossom: pl074_0000, slg074_0000
+Diver: pl075_0000, slg000_0000
+Harvest: pl076_0000, slg076_0000
+Orion: pl077_0000, slg077_0000
+Gala Suit: pl078_0000, slg078_0000
+-- End of Low Rank, Start of High Rank --
+Mosswine Mask: pl056_0000 (Head only)
+Gastodon: pl015_0000 (Head only)
+Barnos: pl016_0000 (Chest only)
+Dodogama: pl039_0000, slg039_0000, pl039_0001(+)
+Zorah: pl038_0000, slg038_0000, pl038_0010(β), pl038_0020(γ)
+Faux Felyne: pl055_0000 (Head only)
+Strategist/Strategist Spectacles: pl060_0000 (Head only)
+Lavasioth: pl040_0000, slg040_0000, pl040_0010(β), pl040_0001(+)
+Uragaan: pl041_0000, slg041_0000, pl041_0010(β), pl041_0001(+)
+Bazel: pl042_0000, slg002_0000, pl042_0010(β)
+Seething Bazel: pl042_0500(+), slg002_0000(+), pl042_0510(β+)
+Damascus: pl043_0000, slg043_0000, pl043_0010(β)
+Dober: pl044_0000, slg044_0000
+Skull: pl054_0000 (Head only)
+Nergigante: pl030_0000, slg030_0000, pl030_0010(β), pl030_0020(γ), slg030_0020(γ)
+Ruiner Nergi: pl030_0500(+), slg030_0500(+), pl030_0510(β+)
+Teostra: pl046_0000, slg046_0000, pl046_0010(β), pl046_0001(+), pl046_0011(β+)
+Kushala: pl047_0000, slg047_0000, pl047_0010(β), pl047_0020(γ), slg047_0020(γ), pl047_0001(+), pl047_0011(β+)
+Vaal Hazak: pl032_0000, slg032_0000, pl032_0010(β), pl032_0020(γ)
+Blackveil Hazak: pl032_0500(+), slg032_0500(+), pl032_0510(β+)
+Xeno'jiva: pl045_0000, slg045_0000, pl045_0010(β)
+Guild Cross: pl048_0000, slg000_0000
+Dragonking/Dragonking Eyepatch: pl061_0000 (Head only)
+Commission: pl053_0000, slg053_0000
+Deviljho: pl050_0000, slg050_0000, pl050_0010(β)
+Savage Jho: pl050_0500(+), slg050_0500(+), pl050_0510(β+)
+Kulve Taroth: pl049_0000, slg049_0000, pl049_0010(β), pl049_0020(γ)
+Lunastra: pl051_0000, slg051_0000, pl051_0010(β)
+Azure Starlord: pl072_0000, slg072_0000
+Azure Age: pl072_0001(+), slg072_0001(+)
+Drachen: pl073_0000, slg073_0000
+Shadow Shades: pl062_0000 (Head only)
+-- End of High Rank, Start of Master Rank --
+Wulg: pl102_0000(+) (Head only)
+Cortos: pl103_0000(+) (Chest only)
+Beo: pl110_0000(+), slg000_0000(+)
+Banbaro: pl084_0000(+), slg084_0000(+), pl084_0010(β+)
+Artian: pl091_0000(+), slg091_0000(+)
+Clockwork: pl104_0000(+), slg104_0000(+), pl104_0010(β+,Head only)
+Barioth: pl089_0000(+), slg089_0000(+), pl089_0010(β+)
+Nargacuga: pl080_0000(+), slg000_0000(+), pl080_0010(β+)
+Glavenus: pl081_0000(+), slg081_0000(+), pl081_0010(β+)
+Acidic Glavenus: pl081_0100(+), slg081_0100(+), pl081_0110(β+)
+Brachydios: pl082_0000(+), slg082_0000(+), pl082_0010(β+)
+Raging Brachy: pl082_0500(+), slg082_0500(+), pl082_0510(β+)
+Tigrex: pl083_0000(+), slg000_0000(+), pl083_0010(β+)
+Brute Tigrex: pl083_0100(+), slg000_0000(+), pl083_0110(β+)
+Black Belt: pl093_0000(+), slg000_0000
+Velkhana: pl085_0000(+), slg085_0000(+), pl085_0010(β+)
+Namielle: pl086_0000(+), slg086_0000(+), pl086_0010(β+)
+Shara Ishvalda: pl088_0000(+), slg088_0000(+), pl088_0010(β+)
+Yian Garuga: pl108_0000(+), slg108_0000(+), pl108_0010(β+)
+Zinogre: pl107_0000(+), slg107_0000(+), pl107_0010(β+)
+Stygian Zin: pl107_0100(+), slg107_0100(+), pl107_0110(β+)
+Guildwork: pl092_0000(+), slg001_0000(+)
+Rajang: pl109_0000(+), slg109_0000(+), pl109_0010(β+)
+Furious Rajang: pl109_0500(+), slg109_0000(+), pl109_0510(β+)
+Safi'jiva: pl087_0000(+), slg087_0000(+), pl087_0010(β+)
+Alatreon: pl052_0000(+), slg052_0000(+), pl052_0010(β+)
+Fatalis: pl129_0000(+), slg129_0000(+), pl129_0010(β+)
+Oolong: pl127_0000(+), slg127_0000(+)
+Astral: pl128_0000(+), slg128_0000(+)
+Rose: pl124_0000(+), slg124_0000(+)
+Passion: pl125_0000(+), slg125_0000(+)
+Demonlord: pl126_0000(+), slg126_0000(+)
+Buff Body: pl115_0000(+), slg000_0000(+)
+Duffel Penguin Mask: pl098_0000(+) (Head only)
+Wyverian Ears: pl101_0000(+) (Head only)
+-- End of Master Rank, Start of Layered Only ---
+Bushi Kabuto "Sabi": pl066_0000 (Head only)
+Bushi Muneate "Sabi": pl066_0000 (Chest only)
+Bushi Kote "Sabi": pl066_0000, slg066_0000 (Arm only)
+Bushi Koshiate "Sabi": pl066_0000 (Waist only)
+Bushi Suneate "Sabi": pl066_0000 (Leg only)
+Bushi Kabuto "Homare": pl066_0010 (Head only)
+Bushi Muneate "Homare": pl066_0010 (Chest only)
+Bushi Kote "Homare": pl066_0010, slg066_0000 (Arm only)
+Bushi Koshiate "Homare": pl066_0010 (Waist only)
+Bushi Suneate "Homare": pl066_0010 (Leg only)
+Origin: pl018_0000, slg001_0000
+Kulu-Ya-Ku Head: pl065_0000 (Head only)
+Ryu: pl069_0000, slg000_0000 (Male)
+Geralt/Geralt of Rivia: pl118_0000, slg118_0000 (Male)
+Ciri: pl119_0000, slg000_0000
+Thermae: pl106_0000, slg106_0000
+Leon: pl130_0000(+), slg130_0000
+Faux Aptonoth: pl097_0000 (Head only)
+Kadachi Scarf: pl114_0000 (Head only)
+Pearlspring: pl113_0000(+) (Head only)
+Goldspring Macaque: pl113_0001 (Head only)
diff --git a/ModSlots/ModSlots.py b/ModSlots/ModSlots.py
index 36e0778..78e7224 100755
--- a/ModSlots/ModSlots.py
+++ b/ModSlots/ModSlots.py
@@ -2,19 +2,29 @@
import sys
sys.dont_write_bytecode = True
+import os
import os.path
-import hashlib
+import shutil
+import re
from enum import Enum
+from hashlib import sha256
from zipfile import ZipFile
-#from unrardll import extract, names
-#from py7zr import SevenZipFile
-from ArmorIDS import ArmorIDS
-# @TODO:
-# - Detach files (copy instead of symlink, MHWNewCamera.json)
-# - Test example to normal and back
-# - More automatic override for the simplest case
-# - Support invisible weapons (default no-include)
+try:
+ from unrardll import extract, names
+ RAR_SUPPORT = True
+except ImportError:
+ RAR_SUPPORT = False
+
+try:
+ from py7zr import SevenZipFile
+ SEVEN_ZIP_SUPPORT = True
+except ImportError:
+ SEVEN_ZIP_SUPPORT = False
+
+from ArmorIDs import ArmorIDs
+
+NATIVEPC_SUBDIRS = ('ec', 'hm', 'npc', 'pg', 'posteffect', 'sound', 'ui', 'village', 'accessory', 'em', 'light', 'otomo', 'photo', 'quest', 'system', 'unit_resource', 'common', 'event', 'ngword_list', 'pc', 'pl', 'shortcut', 'vfx', 'wp', 'plugins')
USAGE = f'Usage: {sys.argv[0]} <Write/Verify/Delete> <Slots.txt> <Path_to_Mods> <Path_to_Game>'
@@ -49,17 +59,19 @@ if not os.path.isdir(Game_Directory):
print(f'Directory {Game_Directory} doesn\'t exist.')
sys.exit(1)
+if Mode == 'verify' and not os.path.isfile(Hash_Path):
+ print(f'Verification requested but previous hash not found at {Hash_Path}.')
+ sys.exit(1)
+
Error_Messages = []
Error_Index = 1
def Error(msg):
global Error_Messages
global Error_Index
- msg = f'{Error_Index}: ' + msg
+ msg = f'{Error_Index}: {msg}'
Error_Messages.append(msg)
Error_Index += 1
- print(msg + '\n^^^^^^^^^^^^^^^^^^^^^^^')
-
-ArmorIDS_Inverted = { v: k for k, v in ArmorIDS.items() }
+ print(msg + '\n' + '^'*len(msg))
class ArchiveType(Enum):
ZIP = 0
@@ -68,53 +80,47 @@ class ArchiveType(Enum):
class Mod():
def __init__(self, path):
- m = hashlib.sha256()
+ self.name = path.split('/')[-1]
+ m = sha256()
m.update(open(path, 'rb').read())
self.hash = m.hexdigest()
ext = path.split('.')[-1].lower()
+ self.files = []
if ext == 'zip':
self.type = ArchiveType.ZIP
self.obj = ZipFile(path, 'r')
- self.files = []
for file in self.obj.infolist():
if file.filename[-1] == '/':
continue
self.files.append(file.filename)
elif ext == 'rar':
self.type = ArchiveType.RAR
- pass
elif ext == '7z':
self.type = ArchiveType.SEVEN_ZIP
- pass
- self.toplevels = []
+ self.obj = SevenZipFile(path, 'r')
+ for file in self.obj.list():
+ if not file.is_directory:
+ self.files.append(file.filename)
self.roots = []
self.ignored = []
self.overrides = {}
self.map = {}
- def substitute_override_name(self, name):
+ def sub_override_name(self, name, slinger):
if name[0] == '[':
name = name[1:-1]
- if name in ArmorIDS_Inverted.keys():
- name = ArmorIDS_Inverted[name][2:]
+ if name in ArmorIDs.keys():
+ name = ArmorIDs[name][1 if slinger else 0][2:]
else:
return None
return name
def get_id_from_subpath(self, sub):
- for armor_id in ArmorIDS.keys():
- armor_id = armor_id[2:]
- search = sub.find(armor_id)
- if search >= 0:
- return sub[search:search + 8]
- return None
-
- def find_overrides_for_file(self, file):
- for key in self.overrides.keys():
- search = file.find(key)
- if search >= 0:
- return self.overrides[key]
- return None
+ if sub.startswith('nativePC/pl/f_equip/pl'):
+ return sub[22:30], False
+ elif sub.startswith('nativePC/wp/slg/slg'):
+ return sub[18:27], True
+ return None, None
def file_sort_key(self, x):
for i in range(0, len(self.roots)):
@@ -122,57 +128,86 @@ class Mod():
return i
return 0
- def do_map(self, All_Files):
+ # If file is within a defined root, truncate it's path up to nativePC/.
+ def maybe_strip_root(self, file):
+ for root in self.roots:
+ if file.startswith(root):
+ nativePC = file.find('nativePC')
+ if nativePC >= 0:
+ return file[nativePC:], root
+ return file, None
+
+ def do_map(self, All_Files, Global_Overrides):
+ print(self.name)
for file in sorted(self.files, key=self.file_sort_key):
- ignore_this = False
- for ig in self.ignored:
- if file.startswith(ig):
- ignore_this = True
+ base, root = self.maybe_strip_root(file)
+ has_overrides = False
+ for key in self.overrides.keys():
+ if base.startswith(key):
+ has_overrides = True
break
- if ignore_this:
+ if (base.startswith(tuple(self.ignored)) or not base.startswith('nativePC')) and not has_overrides:
continue
- path_in_archive = file
- # If file is within a defined root, truncate it's path up to nativePC/.
- for root in self.roots:
- if file.startswith(root):
- nativePC = file.find('nativePC')
- if nativePC >= 0:
- file = file[nativePC:]
- break
+ has_global_override = False
+ for key in Global_Overrides.values():
+ if base.startswith(key[1]):
+ has_global_override = True
+ break
targets = []
- if file in self.overrides.keys():
- targets.extend(self.overrides[file])
- elif not (file.startswith('nativePC') or file in self.toplevels):
- # If file isn't within nativePC/ and is not explicitly included, ignore it.
- continue
- else:
- overrides = self.find_overrides_for_file(file)
- if not overrides:
- targets.append(file) # Include file as-is.
- else:
- # Substitute armor names, like '[Anjanath]', with their IDs.
+ if base in self.overrides.keys() and len(self.overrides[base]) > 0: # Direct remaps.
+ for target in self.overrides[base]:
+ if len(target.split('/')[-1].split('.')) == 1:
+ print(f'Warning: Possible non-direct path as a direct override: {target}')
+ targets.append(target)
+ elif not has_global_override:
+ targets.append(base)
+ # Substitute armor names, like '[Anja]', with their IDs.
+ for i, target in enumerate(targets):
+ for key, overrides in self.overrides.items():
+ if not target.startswith(key) or key == target:
+ continue
for override in overrides:
- target_id = self.get_id_from_subpath(file)
+ target_id, is_slinger = self.get_id_from_subpath(target)
if not target_id:
- Error(f'Invalid target: {file}.')
+ Error(f'Invalid target: {target}')
continue
- mapped_name = self.substitute_override_name(override)
+ mapped_name = self.sub_override_name(override, is_slinger)
if not mapped_name:
- Error(f'Invalid substitute: {override}.')
+ Error(f'Invalid substitute: {override}')
continue
- targets.append(file.replace(target_id, mapped_name))
- print(path_in_archive)
+ targets[i] = target.replace(target_id, mapped_name)
+ break
+ print(f' {file}')
+ # Apply global overrides.
+ for match, override in Global_Overrides.items():
+ for target in targets:
+ if re.match(match, target):
+ override[0].map[override[1]].append(target)
+ targets.remove(target)
+ print(f' (Globally overwritten by) {override[0].name}:{override[1]}')
+ print(f' -> {target}')
+ All_Files.append((self, target, file))
+ break
+ # Map targets.
unique_targets = []
for target in targets:
- # @TODO: Allow "important" mapping instead of relying on order?
- if target in All_Files:
- print(f' (Overwritten)')
+ overwritten = None
+ for other in All_Files:
+ if other[1] == target:
+ overwritten = other
+ break
+ if overwritten:
+ if overwritten[0] == self:
+ print(f' (Overwritten by) {overwritten[2]}')
+ else:
+ print(f' (Overwritten by) {overwritten[0].name}:{overwritten[2]}')
else:
unique_targets.append(target)
- print(' -> ' + target)
+ print(f' -> {target}')
if len(unique_targets) > 0:
- All_Files.extend(unique_targets)
- self.map[path_in_archive] = unique_targets
+ for target in unique_targets:
+ All_Files.append((self, target, file))
+ self.map[file] = unique_targets
def add_to_hash(self, m):
output = f'{os.path.join(Extract_Directory, self.hash)}'
@@ -180,6 +215,8 @@ class Mod():
os.mkdir(output)
if self.type == ArchiveType.ZIP:
self.obj.extractall(path=output)
+ elif self.type == ArchiveType.SEVEN_ZIP:
+ self.obj.extractall(path=output)
for key in self.map:
m.update(open(os.path.join(output, key), 'rb').read())
@@ -189,6 +226,9 @@ class Mod():
for key in self.map:
targets = self.map[key]
for target in targets:
+ copy = target[0] == '|';
+ if copy:
+ target = target[1:]
if target in old_list:
old_list.remove(target)
l.write(target + '\n')
@@ -201,9 +241,15 @@ class Mod():
if os.path.islink(target):
os.remove(target)
elif os.path.isfile(target) or os.path.isdir(target):
- Error(f'Not deleting non-symlink file: {target}.')
+ if not copy:
+ Error(f'Not replacing/removing non-symlink file: {target}')
continue
- os.symlink(f'{os.path.join(output, key)}', target)
+ file = os.path.join(output, key)
+ if copy:
+ print(f'{file}\n (detached) -> {target}')
+ shutil.copyfile(file, target)
+ else:
+ os.symlink(file, target)
def delete(self):
for key in self.map:
@@ -213,11 +259,13 @@ class Mod():
if os.path.islink(target):
os.remove(target)
elif os.path.isfile(target) or os.path.isdir(target):
- Error(f'Not deleting non-symlink file: {target}.')
+ Error(f'Not deleting non-symlink file: {target}')
def is_armor_override(line):
sp = line.split('/')
- if len(sp) >= 3 and sp[2] == 'slg':
+ if len(sp[-1]) == 10 and sp[-1].startswith('pl'):
+ return True
+ if len(sp[-1]) == 11 and sp[-1].startswith('slg'):
return True
if sp[-1] in ['helm', 'body', 'arm', 'wst', 'leg']:
return True
@@ -226,10 +274,13 @@ def is_armor_override(line):
Mods = []
Current_Mod = None
Current_Override = None
+Global_Overrides = {}
with open(Slots, 'r') as f:
for line in f.read().splitlines():
if len(line) == 0 or line[0] == '#':
continue
+ if line == 'XXX':
+ break
if line[0] == ';':
if Current_Mod:
Mods.append(Current_Mod)
@@ -237,54 +288,67 @@ with open(Slots, 'r') as f:
path = os.path.join(Mods_Directory, line[1:])
if os.path.isfile(path):
Current_Mod = Mod(path)
+ Current_Override = None
else:
Error(f'File not found: {path}')
continue
cmd = ''
- if line[0] == '*':
+ if line[0] == '&':
cmd = 'root'
elif line[0] == '<':
cmd = 'ignore'
+ elif line[0] == '|':
+ cmd = 'detach'
elif line[0] == ':':
cmd = 'override'
elif line[0] == '>':
cmd = 'value'
+ elif line[0] == '*':
+ cmd = 'global'
if cmd:
line = line[1:]
- if line.startswith('pl/'):
- line = 'nativePC/' + line
- if line.startswith('wp/'):
+ if line.startswith(NATIVEPC_SUBDIRS):
line = 'nativePC/' + line
if cmd == 'root' and Current_Mod:
Current_Mod.roots.append(line)
elif cmd == 'ignore' and Current_Mod:
Current_Mod.ignored.append(line)
+ elif cmd == 'detach' and Current_Mod:
+ Current_Mod.ignored.append(line)
+ Current_Mod.map[line] = [f'|{line}']
elif cmd == 'override' and Current_Mod:
if not (is_armor_override(line) or line in Current_Mod.files):
Error(f'File not found: {line}')
- Current_Mod = None
- continue
- Current_Override = line
- Current_Mod.overrides[Current_Override] = []
+ else:
+ Current_Override = line
+ Current_Mod.overrides[Current_Override] = []
+ elif cmd == 'global' and Current_Mod and Current_Override:
+ Current_Mod.map[Current_Override] = []
+ Global_Overrides[line] = (Current_Mod, Current_Override)
elif cmd == 'value' and Current_Mod:
if Current_Override:
Current_Mod.overrides[Current_Override].append(line)
- else:
- Current_Mod.toplevels.append(line)
+ elif line[0] == '[': # Special case guess for armor mods.
+ for file in Current_Mod.files:
+ base, root = Current_Mod.maybe_strip_root(file)
+ if base.startswith('nativePC/pl/f_equip/pl') or base.startswith('nativePC/wp/slg/slg'):
+ override = '/'.join(base.split('/')[0:4])
+ Current_Mod.overrides[override] = [line]
if Current_Mod:
Mods.append(Current_Mod)
Current_Mod = None
All_Files = []
-M = hashlib.sha256()
+M = sha256()
for mod in Mods:
- mod.do_map(All_Files)
+ mod.do_map(All_Files, Global_Overrides)
mod.add_to_hash(M)
with open(List_Path, 'a+') as l:
l.seek(0)
old_list = l.read().splitlines()
- l.truncate(0)
+ if Mode == 'write':
+ l.truncate(0)
if Mode == 'write':
for mod in Mods:
@@ -300,14 +364,14 @@ if Mode == 'verify':
if os.path.isfile(Hash_Path):
with open(Hash_Path, 'r') as f:
if f.read() == M.hexdigest():
- print('Verification passed')
+ print('Verification passed!')
else:
- print('Verification failed')
+ print('Verification failed.')
elif Mode == 'delete':
for mod in Mods:
mod.delete()
if len(Error_Messages) > 0:
- print('-----------------------')
+ print('---------------------------')
for err in Error_Messages:
print(err)
diff --git a/ModSlots/slots.example.txt b/ModSlots/slots.example.txt
index 1e739c9..6e3ff2c 100644
--- a/ModSlots/slots.example.txt
+++ b/ModSlots/slots.example.txt
@@ -1,46 +1,98 @@
+# & = Add root. Cut this prefix out of any file's path so that it starts at nativePC/.
+# < = Ignore. Files beginning with this prefix will not be included unless they have further overrides.
+# | = Detach. Include file directly but copy it into nativePC instead of symlink.
+# : = Define target. Can either be a file to directly include or a file/prefix to be the source of the next override.
+# > = General override. Can be a direct path or an armor to substitute like [Anja], [Barroth+], etc.
+# * = Global override. Supply a Python re module format regex to match any defined target and override it.
+
;Stracker's Loader-1982-4-0-1717679465.zip
->dinput8.dll
->loader.dll
->loader-config.json
+:dinput8.dll
+:loader.dll
+:loader-config.json
;SharpPluginLoader-0.0.7.2-linux.zip
->msvcrt.dll
+:msvcrt.dll
;2024 Patch 15.23 1.25-3473-1-25-1728572867.zip
;MHWI - Hide main menu ad banner-7826-1-0-1728933976.zip
-;MHWNewCamera_2.0.zip
-;Fix_Tent_Animation_Face_Deform.zip
+;MHWNewCamera_3.0.zip
+# Copy MHWNewCamera.json instead of symlink so our edits save to the game directory not the extracted mod folder.
+|plugins/CSharp/MHWNewCamera.json
+
+;Fix_Tent_Animation_Face_Deform_v2.zip
+
+;Invisible Sheathed Weapons-2672-1-6-1607062981.7z
+<wp/
+# Buster Sword I
+:wp/two/two002/mod/two002.evwp
+:wp/two/bs_two002/mod/bs_two002.evwp
+
+;Ver1.01 3D pubes for Highpoly Nude MOD with jiggle animation .zip-3173-1-01-1586996247.zip
+<pl/f_equip/pl002_0000/wst/mod/Shaved1.mod3
+<pl/f_equip/pl002_0000/wst/mod/Shaved2.mod3
+<pl/f_equip/pl002_0000/wst/mod/Hairy.mod3
+:pl/f_equip/pl002_0000/wst/mod/Unshaved.mod3
+>pl/f_equip/pl002_0000/wst/mod/f_wst002_0000.mod3
+
+;Version1.0 Normal Fishnet for Highpoly Nude MOD Version 4-5030-1-0-1610636569.zip
+<pl/f_equip/pl002_0000/body
+:pl/f_equip/pl002_0000/arm
+>[Hornetaur]
+:pl/f_equip/pl002_0000/wst
+>[Hornetaur]
+:pl/f_equip/pl002_0000/leg
+>[Hornetaur]
+
+;Ver1.0 Pantie for Highpoly Nude MOD-3465-1-0-1589948707.zip
+<pl/f_equip/HPNM_KirinPantie/CMM_Normal.tex
+<pl/f_equip/HPNM_KirinPantie/CMM_Stripe.tex
+<pl/f_equip/HPNM_KirinPantie/CMM_PolkaDot.tex
+:Pantie_ColorMaskMap/Translucent/CMM_TransVKS_Pantie_Palico.mrl3
+>pl/f_equip/pl002_0000/wst/mod/f_wst002_0000.mrl3
+:pl/f_equip/pl002_0000/wst
+>[Kirin]
+
+;Ver3.1 SmallTitsVer_Highpoly Nude MOD with jiggle animation (Iceborne Compatible )-1965-3-1-1586846362.zip
+<pl/f_equip/HighPolyNudeModTextures/ColorUnchangeable_Nail_CMM.tex
+<pl/f_equip/HighPolyNudeModTextures/Nail_BML.tex
+<pl/f_equip/HighPolyNudeModTextures/Nail_CMM.tex
+<pl/f_equip/HighPolyNudeModTextures/Nail_Disable_snow_Col_CMM.tex
+<pl/f_equip/HighPolyNudeModTextures/Nail_NM.tex
+<pl/f_equip/HighPolyNudeModTextures/Nail_RMT.tex
+
+#;Atrarch's Namielle For Dytsers Armor's-4490-4-0-1630065481.zip
+#<pl/f_equip/pl
+#:pl/f_equip/pl500_0000/body/mod/f_body500_0000.ctc
+## Regex to match any f_body.ctc and override it for all included mods.
+#*pl/f_equip/pl[0-9]+_[0-9]+/body/mod/f_body[0-9]+_[0-9]+.ctc
+
+;Bikini Collections - Sandals-2891-1-0-1584526839.zip
+<pl/f_equip/pl
+:pl/f_equip/pl002_0000
+>[Barroth]
+
+;Bamboo Shoot.zip
+>[Jyura]
+
+;1st Swimsuit Contest.zip
+>[Chainmail]
+
+;2023 Halloween Costume.zip
+>[Vespoid]
+
+;Sera.zip
+# The uncensored files will be used with this order.
+&02. Sera - Uncensored
+&01. Sera - Main File
+>[Artian+]
-#;Reshade Hook v1.0-7015-1-0-1704129998.zip
-#>amd_ags_x64.dll
-#;MHWNo-HUD-No-EffectsFix-v.0.3-8195-0-3-1752188975.zip
-#>ShaderToggler.addon64
-##>ShaderToggler.ini
+;Christmas Gift.zip
+>[Barroth+]
-#;Skin Glossiness Options.zip
-#:skin_BM_dry.tex
-#>pl/f_equip/mangie/bamboo/skin_BM.tex
-#
-#;4k Skin Textures.zip
-#:4k body texture/skin_NM.tex
-#>pl/f_equip/mangie/bamboo/skin_NM.tex
-#:4k face textures/f_face_edit_NM.tex
-#>pl/f_face/face000/mod/f_face_edit_NM.tex
-#:4k face textures/f_face000_RMT_dry.tex
-#>pl/f_face/face000/mod/f_face000_RMT.tex
+;DOA5LR Kasumi_s Battlesuit.zip
+>[Lavasioth]
-#;Bamboo Shoot.zip
-#:pl/f_equip/pl020_0000/helm
-#>[Jyuratodus]
-#:pl/f_equip/pl020_0000/body
-#>[Jyuratodus]
-#:pl/f_equip/pl020_0000/arm
-#>[Jyuratodus]
-#:pl/f_equip/pl020_0000/wst
-#>[Jyuratodus]
-#:pl/f_equip/pl020_0000/leg
-#>[Jyuratodus]
-#:wp/slg/slg020_0000
-#>[Jyuratodus]
+;DOA6 Tamaki Bikini.zip
+>[Vespoid+]