diff options
| author | 2025-11-20 18:38:35 -0500 | |
|---|---|---|
| committer | 2025-11-20 18:38:35 -0500 | |
| commit | 3107bbb97fbb3cdd6db7d4986488576878591b34 (patch) | |
| tree | b729e0c0ddae6555994bacd73883f52e77d8e7df | |
| parent | 10463050906aae3d9d100ddb00bf1bbbd891dc26 (diff) | |
| download | NewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.tar.gz NewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.tar.bz2 NewCamera-3107bbb97fbb3cdd6db7d4986488576878591b34.zip | |
Flesh out ModSlots
Signed-off-by: Andrew Opalach <andrew@akon.city>
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | ModSlots/ArmorIDS.py | 356 | ||||
| -rw-r--r-- | ModSlots/ArmorIDs.py | 50 | ||||
| -rw-r--r-- | ModSlots/ArmorIDs.txt | 154 | ||||
| -rwxr-xr-x | ModSlots/ModSlots.py | 246 | ||||
| -rw-r--r-- | ModSlots/slots.example.txt | 122 | ||||
| -rw-r--r-- | README.txt | 4 |
7 files changed, 449 insertions, 485 deletions
@@ -3,4 +3,4 @@ **/obj/ ModSlots/slots.txt ModSlots/venv/ -Research/working/ +Research/temp/ 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+] @@ -1,5 +1,5 @@ == MHWNewCamera -https://www.nexusmods.com/monsterhunterworld/mods/8300 -https://www.nexusmods.com/monsterhunterworld/mods/8366 +https://www.nexusmods.com/monsterhunterworld/mods/8300 + +https://www.nexusmods.com/monsterhunterworld/mods/8366 + // vim: set ft=asciidoc: |