From d30e8f3d487d33832da943fc04b08c14d5ce33fa Mon Sep 17 00:00:00 2001 From: b3brodie <70666939+b3brodie@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:35:12 -0700 Subject: [PATCH] Mod Compatibility: Only load files within "mod_interactions" if requisite mod is loaded (#76632) * Add feature programatically * adjust existing folders to meet new styling * move interaction files to load after main mod loading * Force mod_interaction files to load after normal mod files * Refactor code to remove disgusting tuple logic * Add astyling and comments * Delete data/mods/Aftershock/mod_interactions/Defense_Mode directory uncapitalizing directories is difficult * Delete data/mods/Defense_Mode/mod_interactions/Aftershock directory * Delete data/mods/Defense_Mode/mod_interactions/Magiclysm directory * Delete data/mods/Defense_Mode/mod_interactions/Megafauna directory * Delete data/mods/Defense_Mode/mod_interactions/MindOverMatter directory * Delete data/mods/Defense_Mode/mod_interactions/Xedra_Evolved directory * Delete data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm directory * Delete data/mods/Magiclysm/mod_interactions/Defense_Mode directory * Delete data/mods/Megafauna/mod_interactions/Defense_Mode directory * Delete data/mods/Xedra_Evolved/mod_interactions/Defense_Mode directory * restart tests phase 1 * restart tests phase 2 * make for loop var const * extra fix for const for loop * add doc * Update doc/MOD_COMPATABILITY.md --------- Co-authored-by: Maleclypse <54345792+Maleclypse@users.noreply.github.com> --- .../monstergroups.json | 0 .../monsters.json | 0 .../species.json | 0 .../{Mythos => Mythos-Creatures}/eocs.json | 0 .../{Aftershock => aftershock}/eocs.json | 0 .../perkdata/money_maker.json | 0 .../perkdata/mysterious_stranger.json | 0 .../perkdata/troubleseeker.json | 0 .../perkmenu.json | 0 .../perks.json | 0 .../{Magiclysm => magiclysm}/eocs.json | 0 .../{Megafauna => megafauna}/eocs.json | 0 .../eocs.json | 0 .../species.json | 0 .../eocs.json | 0 .../eocs.json | 0 .../mindovermatter}/vitakinesis_eoc.json | 0 .../perkdata/caster_level_up_animist.json | 0 .../perkdata/caster_level_up_biomancer.json | 0 .../perkdata/caster_level_up_druid.json | 0 .../perkdata/caster_level_up_earthshaper.json | 0 .../perkdata/caster_level_up_kelvinist.json | 0 .../perkdata/caster_level_up_magus.json | 0 .../perkdata/caster_level_up_stormshaper.json | 0 .../caster_level_up_technomancer.json | 0 .../perkmenu.json | 0 .../perks.json | 0 .../monster_corpse.json | 0 .../monstergroups.json | 0 .../monsters.json | 0 .../overmap_specials.json | 0 .../scenarios.json | 0 .../species.json | 0 .../monstergroups.json | 0 .../monsters.json | 0 .../defense_mode}/monstergroups.json | 0 .../defense_mode}/monsters.json | 0 .../defense_mode}/overmap_specials.json | 0 .../defense_mode}/premonition_instances.json | 0 .../defense_mode}/scenarios.json | 0 .../defense_mode}/monstergroups.json | 0 .../defense_mode}/monsters.json | 0 .../defense_mode}/species.json | 0 .../defense_mode}/monstergroups.json | 0 .../defense_mode}/monsters.json | 0 .../defense_mode}/species.json | 0 .../perks/perk_data/Alchemy1.json | 0 .../perks/perk_menu.json | 0 .../perks/perks.json | 0 .../main_menu.json | 0 .../monster_corpses.json | 0 .../monstergroups.json | 0 .../monsters.json | 0 .../{Defense_Mode => defense_mode}/npcs.json | 0 .../overmap_specials.json | 0 .../scenarios.json | 0 .../species.json | 0 .../updates.json | 0 doc/MOD_COMPATABILITY.md | 33 ++++++++ src/filesystem.cpp | 82 +++++++++++++++++-- src/filesystem.h | 27 ++++++ src/game.cpp | 22 ++++- src/game.h | 4 + src/init.cpp | 73 +++++++++++++++++ src/init.h | 19 +++++ 65 files changed, 249 insertions(+), 11 deletions(-) rename data/mods/Aftershock/mod_interactions/{Defense_Mode => defense_mode}/monstergroups.json (100%) rename data/mods/Aftershock/mod_interactions/{Defense_Mode => defense_mode}/monsters.json (100%) rename data/mods/Aftershock/mod_interactions/{Defense_Mode => defense_mode}/species.json (100%) rename data/mods/Defense_Mode/mod_interactions/{Mythos => Mythos-Creatures}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{Aftershock => aftershock}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/money_maker.json (100%) rename data/mods/Defense_Mode/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/mysterious_stranger.json (100%) rename data/mods/Defense_Mode/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/troubleseeker.json (100%) rename data/mods/Defense_Mode/mod_interactions/{BombasticPerks => bombastic_perks}/perkmenu.json (100%) rename data/mods/Defense_Mode/mod_interactions/{BombasticPerks => bombastic_perks}/perks.json (100%) rename data/mods/Defense_Mode/mod_interactions/{Magiclysm => magiclysm}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{Megafauna => megafauna}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{MindOverMatter => mindovermatter}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{MindOverMatter => mindovermatter}/species.json (100%) rename data/mods/Defense_Mode/mod_interactions/{My_Sweet_Cataclysm => my_sweet_cataclysm}/eocs.json (100%) rename data/mods/Defense_Mode/mod_interactions/{Xedra_Evolved => xedra_evolved}/eocs.json (100%) rename data/mods/Limb_WIP/{mod_integration => mod_interactions/mindovermatter}/vitakinesis_eoc.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_animist.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_biomancer.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_druid.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_earthshaper.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_kelvinist.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_magus.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_stormshaper.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkdata/caster_level_up_technomancer.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perkmenu.json (100%) rename data/mods/Magiclysm/mod_interactions/{BombasticPerks => bombastic_perks}/perks.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/monster_corpse.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/monstergroups.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/monsters.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/overmap_specials.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/scenarios.json (100%) rename data/mods/Magiclysm/mod_interactions/{Defense_Mode => defense_mode}/species.json (100%) rename data/mods/Megafauna/mod_interactions/{Defense_Mode => defense_mode}/monstergroups.json (100%) rename data/mods/Megafauna/mod_interactions/{Defense_Mode => defense_mode}/monsters.json (100%) rename data/mods/MindOverMatter/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monstergroups.json (100%) rename data/mods/MindOverMatter/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monsters.json (100%) rename data/mods/MindOverMatter/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/overmap_specials.json (100%) rename data/mods/MindOverMatter/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/premonition_instances.json (100%) rename data/mods/MindOverMatter/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/scenarios.json (100%) rename data/mods/My_Sweet_Cataclysm/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monstergroups.json (100%) rename data/mods/My_Sweet_Cataclysm/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monsters.json (100%) rename data/mods/My_Sweet_Cataclysm/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/species.json (100%) rename data/mods/Mythos-Creatures/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monstergroups.json (100%) rename data/mods/Mythos-Creatures/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/monsters.json (100%) rename data/mods/Mythos-Creatures/{modinteractions/Defense_Mode => mod_interactions/defense_mode}/species.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{BombasticPerks => bombastic_perks}/perks/perk_data/Alchemy1.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{BombasticPerks => bombastic_perks}/perks/perk_menu.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{BombasticPerks => bombastic_perks}/perks/perks.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/main_menu.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/monster_corpses.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/monstergroups.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/monsters.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/npcs.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/overmap_specials.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/scenarios.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/species.json (100%) rename data/mods/Xedra_Evolved/mod_interactions/{Defense_Mode => defense_mode}/updates.json (100%) create mode 100644 doc/MOD_COMPATABILITY.md diff --git a/data/mods/Aftershock/mod_interactions/Defense_Mode/monstergroups.json b/data/mods/Aftershock/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/Aftershock/mod_interactions/Defense_Mode/monstergroups.json rename to data/mods/Aftershock/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/Aftershock/mod_interactions/Defense_Mode/monsters.json b/data/mods/Aftershock/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/Aftershock/mod_interactions/Defense_Mode/monsters.json rename to data/mods/Aftershock/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/Aftershock/mod_interactions/Defense_Mode/species.json b/data/mods/Aftershock/mod_interactions/defense_mode/species.json similarity index 100% rename from data/mods/Aftershock/mod_interactions/Defense_Mode/species.json rename to data/mods/Aftershock/mod_interactions/defense_mode/species.json diff --git a/data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json b/data/mods/Defense_Mode/mod_interactions/Mythos-Creatures/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json rename to data/mods/Defense_Mode/mod_interactions/Mythos-Creatures/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json b/data/mods/Defense_Mode/mod_interactions/aftershock/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json rename to data/mods/Defense_Mode/mod_interactions/aftershock/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/money_maker.json b/data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/money_maker.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/money_maker.json rename to data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/money_maker.json diff --git a/data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/mysterious_stranger.json b/data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/mysterious_stranger.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/mysterious_stranger.json rename to data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/mysterious_stranger.json diff --git a/data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/troubleseeker.json b/data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/troubleseeker.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkdata/troubleseeker.json rename to data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkdata/troubleseeker.json diff --git a/data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkmenu.json b/data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkmenu.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/BombasticPerks/perkmenu.json rename to data/mods/Defense_Mode/mod_interactions/bombastic_perks/perkmenu.json diff --git a/data/mods/Defense_Mode/mod_interactions/BombasticPerks/perks.json b/data/mods/Defense_Mode/mod_interactions/bombastic_perks/perks.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/BombasticPerks/perks.json rename to data/mods/Defense_Mode/mod_interactions/bombastic_perks/perks.json diff --git a/data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json b/data/mods/Defense_Mode/mod_interactions/magiclysm/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json rename to data/mods/Defense_Mode/mod_interactions/magiclysm/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json b/data/mods/Defense_Mode/mod_interactions/megafauna/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json rename to data/mods/Defense_Mode/mod_interactions/megafauna/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json b/data/mods/Defense_Mode/mod_interactions/mindovermatter/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json rename to data/mods/Defense_Mode/mod_interactions/mindovermatter/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/MindOverMatter/species.json b/data/mods/Defense_Mode/mod_interactions/mindovermatter/species.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/MindOverMatter/species.json rename to data/mods/Defense_Mode/mod_interactions/mindovermatter/species.json diff --git a/data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json b/data/mods/Defense_Mode/mod_interactions/my_sweet_cataclysm/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json rename to data/mods/Defense_Mode/mod_interactions/my_sweet_cataclysm/eocs.json diff --git a/data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json b/data/mods/Defense_Mode/mod_interactions/xedra_evolved/eocs.json similarity index 100% rename from data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json rename to data/mods/Defense_Mode/mod_interactions/xedra_evolved/eocs.json diff --git a/data/mods/Limb_WIP/mod_integration/vitakinesis_eoc.json b/data/mods/Limb_WIP/mod_interactions/mindovermatter/vitakinesis_eoc.json similarity index 100% rename from data/mods/Limb_WIP/mod_integration/vitakinesis_eoc.json rename to data/mods/Limb_WIP/mod_interactions/mindovermatter/vitakinesis_eoc.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_animist.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_animist.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_animist.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_animist.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_biomancer.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_biomancer.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_biomancer.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_biomancer.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_druid.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_druid.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_druid.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_druid.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_earthshaper.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_earthshaper.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_earthshaper.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_earthshaper.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_kelvinist.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_kelvinist.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_kelvinist.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_kelvinist.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_magus.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_magus.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_magus.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_magus.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_stormshaper.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_stormshaper.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_stormshaper.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_stormshaper.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_technomancer.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_technomancer.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkdata/caster_level_up_technomancer.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkdata/caster_level_up_technomancer.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perkmenu.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perkmenu.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perkmenu.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perkmenu.json diff --git a/data/mods/Magiclysm/mod_interactions/BombasticPerks/perks.json b/data/mods/Magiclysm/mod_interactions/bombastic_perks/perks.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/BombasticPerks/perks.json rename to data/mods/Magiclysm/mod_interactions/bombastic_perks/perks.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/monster_corpse.json b/data/mods/Magiclysm/mod_interactions/defense_mode/monster_corpse.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/monster_corpse.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/monster_corpse.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/monstergroups.json b/data/mods/Magiclysm/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/monstergroups.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/monsters.json b/data/mods/Magiclysm/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/monsters.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/overmap_specials.json b/data/mods/Magiclysm/mod_interactions/defense_mode/overmap_specials.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/overmap_specials.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/overmap_specials.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/scenarios.json b/data/mods/Magiclysm/mod_interactions/defense_mode/scenarios.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/scenarios.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/scenarios.json diff --git a/data/mods/Magiclysm/mod_interactions/Defense_Mode/species.json b/data/mods/Magiclysm/mod_interactions/defense_mode/species.json similarity index 100% rename from data/mods/Magiclysm/mod_interactions/Defense_Mode/species.json rename to data/mods/Magiclysm/mod_interactions/defense_mode/species.json diff --git a/data/mods/Megafauna/mod_interactions/Defense_Mode/monstergroups.json b/data/mods/Megafauna/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/Megafauna/mod_interactions/Defense_Mode/monstergroups.json rename to data/mods/Megafauna/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/Megafauna/mod_interactions/Defense_Mode/monsters.json b/data/mods/Megafauna/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/Megafauna/mod_interactions/Defense_Mode/monsters.json rename to data/mods/Megafauna/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/MindOverMatter/modinteractions/Defense_Mode/monstergroups.json b/data/mods/MindOverMatter/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/MindOverMatter/modinteractions/Defense_Mode/monstergroups.json rename to data/mods/MindOverMatter/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/MindOverMatter/modinteractions/Defense_Mode/monsters.json b/data/mods/MindOverMatter/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/MindOverMatter/modinteractions/Defense_Mode/monsters.json rename to data/mods/MindOverMatter/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/MindOverMatter/modinteractions/Defense_Mode/overmap_specials.json b/data/mods/MindOverMatter/mod_interactions/defense_mode/overmap_specials.json similarity index 100% rename from data/mods/MindOverMatter/modinteractions/Defense_Mode/overmap_specials.json rename to data/mods/MindOverMatter/mod_interactions/defense_mode/overmap_specials.json diff --git a/data/mods/MindOverMatter/modinteractions/Defense_Mode/premonition_instances.json b/data/mods/MindOverMatter/mod_interactions/defense_mode/premonition_instances.json similarity index 100% rename from data/mods/MindOverMatter/modinteractions/Defense_Mode/premonition_instances.json rename to data/mods/MindOverMatter/mod_interactions/defense_mode/premonition_instances.json diff --git a/data/mods/MindOverMatter/modinteractions/Defense_Mode/scenarios.json b/data/mods/MindOverMatter/mod_interactions/defense_mode/scenarios.json similarity index 100% rename from data/mods/MindOverMatter/modinteractions/Defense_Mode/scenarios.json rename to data/mods/MindOverMatter/mod_interactions/defense_mode/scenarios.json diff --git a/data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/monstergroups.json b/data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/monstergroups.json rename to data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/monsters.json b/data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/monsters.json rename to data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/species.json b/data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/species.json similarity index 100% rename from data/mods/My_Sweet_Cataclysm/modinteractions/Defense_Mode/species.json rename to data/mods/My_Sweet_Cataclysm/mod_interactions/defense_mode/species.json diff --git a/data/mods/Mythos-Creatures/modinteractions/Defense_Mode/monstergroups.json b/data/mods/Mythos-Creatures/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/Mythos-Creatures/modinteractions/Defense_Mode/monstergroups.json rename to data/mods/Mythos-Creatures/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/Mythos-Creatures/modinteractions/Defense_Mode/monsters.json b/data/mods/Mythos-Creatures/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/Mythos-Creatures/modinteractions/Defense_Mode/monsters.json rename to data/mods/Mythos-Creatures/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/Mythos-Creatures/modinteractions/Defense_Mode/species.json b/data/mods/Mythos-Creatures/mod_interactions/defense_mode/species.json similarity index 100% rename from data/mods/Mythos-Creatures/modinteractions/Defense_Mode/species.json rename to data/mods/Mythos-Creatures/mod_interactions/defense_mode/species.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perk_data/Alchemy1.json b/data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perk_data/Alchemy1.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perk_data/Alchemy1.json rename to data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perk_data/Alchemy1.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perk_menu.json b/data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perk_menu.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perk_menu.json rename to data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perk_menu.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perks.json b/data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perks.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/BombasticPerks/perks/perks.json rename to data/mods/Xedra_Evolved/mod_interactions/bombastic_perks/perks/perks.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/main_menu.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/main_menu.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/main_menu.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/main_menu.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monster_corpses.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/monster_corpses.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monster_corpses.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/monster_corpses.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monstergroups.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/monstergroups.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monstergroups.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/monstergroups.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monsters.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/monsters.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/monsters.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/monsters.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/npcs.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/npcs.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/npcs.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/npcs.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/overmap_specials.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/overmap_specials.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/overmap_specials.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/overmap_specials.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/scenarios.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/scenarios.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/scenarios.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/scenarios.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/species.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/species.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/species.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/species.json diff --git a/data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/updates.json b/data/mods/Xedra_Evolved/mod_interactions/defense_mode/updates.json similarity index 100% rename from data/mods/Xedra_Evolved/mod_interactions/Defense_Mode/updates.json rename to data/mods/Xedra_Evolved/mod_interactions/defense_mode/updates.json diff --git a/doc/MOD_COMPATABILITY.md b/doc/MOD_COMPATABILITY.md new file mode 100644 index 0000000000000..1f72d23d4bcf3 --- /dev/null +++ b/doc/MOD_COMPATABILITY.md @@ -0,0 +1,33 @@ +# Mod Compatability + +## Summary + +Mods are capable of dynamically loading directories based on if other mods are loaded in the world. This will prevent file contents within the mod_interactions folder from being read unless they are part of a folder named after a loaded mod's id. + +## Guide + +In order to dynamically load mod content, files must be placed within subdirectories named after other mod ids (capitalization is checked) within the mod_interactions folder. + +Example: +Mod 1: Mind Over Matter (id:mindovermatter) +Mod 2: Xedra Evolved (id:xedra_evolved) + +If Xedra wishes to load a file only when Mind Over Matter is active: mom_compat_data.json, it must be located as such: +Xedra_Evolved/mod_interactions/mindovermatter/mom_compat_data.json + +Files located within the mod_interactions folders are always loaded after other mod content for every mod is loaded. + +## Limitations + +Currently, this functionality only loads / unloads files based on if other mods are active for the particular world. It does not suppress any other warnings beyond this function. + +In particular, when designing mod compatability content an author will likely want to redefine certain ids to have new definitions, flags, etc. If attempting to do this within the same overall mod folder, this will throw a duplicate definition error. To get around this, instead of a mod redefining its own content within its own mod_interactions folder, the author should redefine its own content using the other mods mod_interaction folder. + +Example: +Mod 1: Mind Over Matter (id:mindovermatter) +Mod 2: Xedra Evolved (id:xedra_evolved) + +If xedra wants an item to have extra damage while Mind Over Matter is loaded, the author should place the new definition in the following: +MindOverMatter/mod_interactions/xedra_evolved/xedra_compat_data.json + +TODO: remove this limitation entirely by adjusting the check to take into account the mod_interaction id source as well \ No newline at end of file diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 166a0d4c52bcd..9d415bb85bfb0 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -281,9 +281,15 @@ bool is_directory( const fs::directory_entry &entry ) // If at_end is true, returns whether entry's name ends in match. // Otherwise, returns whether entry's name contains match. //-------------------------------------------------------------------------------------------------- -bool name_contains( const fs::directory_entry &entry, const std::string &match, const bool at_end ) -{ - std::string entry_name = entry.path().filename().u8string(); +bool name_contains( const fs::directory_entry &entry, const std::string &match, const bool at_end, + const bool match_path ) +{ + std::string entry_name; + if( match_path ) { + entry_name = entry.path().u8string(); + } else { + entry_name = entry.path().filename().u8string(); + } const size_t len_fname = entry_name.length(); const size_t len_match = match.length(); @@ -421,7 +427,7 @@ std::vector get_files_from_path( const std::string &pattern, { return find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { - return name_contains( entry, pattern, match_extension ); + return name_contains( entry, pattern, match_extension, false ); } ); } std::vector get_files_from_path( const std::string &pattern, @@ -429,7 +435,28 @@ std::vector get_files_from_path( const std::string &pattern, { return find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { - return name_contains( entry, pattern, match_extension ); + return name_contains( entry, pattern, match_extension, false ); + } ); +} + +std::vector get_files_from_path_with_path_exclusion( const std::string &pattern, + const std::string &pattern_clash, + const std::string &root_path, const bool recursive_search, const bool match_extension ) +{ + return find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, + bool ) { + return name_contains( entry, pattern, match_extension, false ) && + !name_contains( entry, pattern_clash, false, true ); + } ); +} +std::vector get_files_from_path_with_path_exclusion( const std::string &pattern, + const std::string &pattern_clash, + const cata_path &root_path, const bool recursive_search, const bool match_extension ) +{ + return find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, + bool ) { + return name_contains( entry, pattern, match_extension, false ) && + !name_contains( entry, pattern_clash, false, true ); } ); } @@ -449,7 +476,7 @@ std::vector get_directories_with( const std::string &pattern, auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { - return name_contains( entry, pattern, true ); + return name_contains( entry, pattern, true, false ); } ); // Chop off the file names. Dir path MUST be splitted by '/' @@ -471,7 +498,7 @@ std::vector get_directories_with( const std::string &pattern, auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { - return name_contains( entry, pattern, true ); + return name_contains( entry, pattern, true, false ); } ); // Chop off the file names. Dir path MUST be splitted by '/' @@ -504,7 +531,7 @@ std::vector get_directories_with( const std::vector &p auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { return std::any_of( ext_beg, ext_end, [&]( const std::string & ext ) { - return name_contains( entry, ext, true ); + return name_contains( entry, ext, true, false ); } ); } ); @@ -532,7 +559,7 @@ std::vector get_directories_with( const std::vector &pat auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, bool ) { return std::any_of( ext_beg, ext_end, [&]( const std::string & ext ) { - return name_contains( entry, ext, true ); + return name_contains( entry, ext, true, false ); } ); } ); @@ -547,6 +574,43 @@ std::vector get_directories_with( const std::vector &pat return files; } +/** + * Finds all directories within given path + * @param root_path Search root. + * @param recursive_search Be recurse or not. + * @return vector or directories without pattern filename at end. + */ +std::vector get_directories( const std::string &root_path, + const bool recursive_search ) +{ + auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, + bool ) { + return dir_exist( entry.path() ); + } ); + + files.erase( std::unique( std::begin( files ), std::end( files ) ), std::end( files ) ); + + return files; +} + +/** + * Finds all directories within given path + * @param root_path Search root. + * @param recursive_search Be recurse or not. + * @return vector or directories without pattern filename at end. + */ +std::vector get_directories( const cata_path &root_path, const bool recursive_search ) +{ + auto files = find_file_if_bfs( root_path, recursive_search, [&]( const fs::directory_entry & entry, + bool ) { + return dir_exist( entry.path() ); + } ); + + files.erase( std::unique( std::begin( files ), std::end( files ) ), std::end( files ) ); + + return files; +} + bool copy_file( const std::string &source_path, const std::string &dest_path ) { std::ifstream source_stream( fs::u8path( source_path ), diff --git a/src/filesystem.h b/src/filesystem.h index cf428da186014..a8ccaa8710857 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -72,6 +72,27 @@ std::vector get_files_from_path( const std::string &pattern, std::vector get_files_from_path( const std::string &pattern, const cata_path &root_path, bool recursive_search = false, bool match_extension = false ); +/** + * Returns a vector of files or directories matching pattern at @p root_path excluding those who's path matches @p pattern_clash. + * + * Searches through the directory tree breadth-first. Directories are searched in lexical + * order. Matching files within in each directory are also ordered lexically. + * + * @param pattern The sub-string to match. + * @param pattern_clash The sub-string to exclude files whose paths match. + * @param root_path The path relative to the current working directory to search; empty means ".". + * @param recursive_search Whether to recursively search sub directories. + * @param match_extension If true, match pattern at the end of file names. Otherwise, match anywhere + * in the file name. + */ +std::vector get_files_from_path_with_path_exclusion( const std::string &pattern, + const std::string &pattern_clash, + const std::string &root_path = "", bool recursive_search = false, + bool match_extension = false ); +std::vector get_files_from_path_with_path_exclusion( const std::string &pattern, + const std::string &pattern_clash, + const cata_path &root_path, bool recursive_search = false, + bool match_extension = false ); //-------------------------------------------------------------------------------------------------- /** @@ -92,6 +113,12 @@ std::vector get_directories_with( const std::vector &pat std::vector get_directories_with( const std::string &pattern, const cata_path &root_path = {}, bool recursive_search = false ); +std::vector get_directories( const std::string &root_path = "", + bool recursive_search = false ); + +std::vector get_directories( const cata_path &root_path = {}, bool recursive_search = + false ); + bool copy_file( const std::string &source_path, const std::string &dest_path ); bool copy_file( const cata_path &source_path, const cata_path &dest_path ); diff --git a/src/game.cpp b/src/game.cpp index 3b2681d3530de..2bc24e0d30967 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -607,6 +607,15 @@ void game::load_data_from_dir( const cata_path &path, const std::string &src ) DynamicDataLoader::get_instance().load_data_from_path( path, src ); } +void game::load_mod_data_from_dir( const cata_path &path, const std::string &src ) +{ + DynamicDataLoader::get_instance().load_mod_data_from_path( path, src ); +} +void game::load_mod_interaction_data_from_dir( const cata_path &path, const std::string &src ) +{ + DynamicDataLoader::get_instance().load_mod_interaction_files_from_path( path, src ); +} + #if defined(TUI) // in ncurses_def.cpp extern void check_encoding(); // NOLINT @@ -3235,7 +3244,9 @@ void game::load_world_modfiles() load_packs( _( "Loading files" ), mods ); // Load additional mods from that world-specific folder - load_data_from_dir( PATH_INFO::world_base_save_path_path() / "mods", "custom" ); + load_mod_data_from_dir( PATH_INFO::world_base_save_path_path() / "mods", "custom" ); + load_mod_interaction_data_from_dir( PATH_INFO::world_base_save_path_path() / "mods" / + "mod_interactions", "custom" ); DynamicDataLoader::get_instance().finalize_loaded_data(); } @@ -3260,9 +3271,16 @@ void game::load_packs( const std::string &msg, const std::vector &packs if( mod.ident.str() == "test_data" ) { check_plural = check_plural_t::none; } - load_data_from_dir( mod.path, mod.ident.str() ); + load_mod_data_from_dir( mod.path, mod.ident.str() ); } + for( const auto &e : available ) { + loading_ui::show( msg, e->name() ); + const MOD_INFORMATION &mod = *e; + load_mod_interaction_data_from_dir( mod.path / "mod_interactions", mod.ident.str() ); + } + + std::unordered_set removed_mods { MOD_INFORMATION_Graphical_Overmap // Removed in 0.I }; diff --git a/src/game.h b/src/game.h index c1aae626bc269..77e7af867e190 100644 --- a/src/game.h +++ b/src/game.h @@ -199,6 +199,10 @@ class game protected: /** Loads dynamic data from the given directory. May throw. */ void load_data_from_dir( const cata_path &path, const std::string &src ); + /** Loads dynamic data from the given directory. Excludes files from 'mod_interactions' sub-directory. May throw. */ + void load_mod_data_from_dir( const cata_path &path, const std::string &src ); + /** Loads dynamic data from the folder if it is part of a subdirectory that is named after a currently loaded mod_id. May throw. */ + void load_mod_interaction_data_from_dir( const cata_path &path, const std::string &src ); public: void setup(); /** Saving and loading functions. */ diff --git a/src/init.cpp b/src/init.cpp index a7116e687aa2a..cafa86d963ad5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -529,6 +529,79 @@ void DynamicDataLoader::load_data_from_path( const cata_path &path, const std::s } } +void DynamicDataLoader::load_mod_data_from_path( const cata_path &path, const std::string &src ) +{ + cata_assert( !finalized && + "Can't load additional data after finalization. Must be unloaded first." ); + // We assume that each folder is consistent in itself, + // and all the previously loaded folders. + // E.g. the core might provide a vpart "frame-x" + // the first loaded mode might provide a vehicle that uses that frame + // But not the other way round. + + std::vector files; + // if give path is a directory + if( dir_exist( path.get_unrelative_path() ) ) { + const std::vector dir_files = get_files_from_path_with_path_exclusion( ".json", + "mod_interactions", path, true, false ); + files.insert( files.end(), dir_files.begin(), dir_files.end() ); + // if given path is an individual file + } else if( file_exist( path.get_unrelative_path() ) ) { + files.emplace_back( path ); + } + + // iterate over each file + for( const cata_path &file : files ) { + try { + // parse it + JsonValue jsin = json_loader::from_path( file ); + load_all_from_json( jsin, src, path, file ); + } catch( const JsonError &err ) { + throw std::runtime_error( err.what() ); + } + } +} + +void DynamicDataLoader::load_mod_interaction_files_from_path( const cata_path &path, + const std::string &src ) +{ + cata_assert( !finalized && + "Can't load additional data after finalization. Must be unloaded first." ); + + std::vector &loaded_mods = world_generator->active_world->active_mod_order; + std::vector files; + + if( dir_exist( path.get_unrelative_path() ) ) { + + // obtain folders within mod_interactions to see if they match loaded mod ids + const std::vector interaction_folders = get_directories( path, false ); + + for( const cata_path &f : interaction_folders ) { + bool is_mod_loaded = false; + for( mod_id id : loaded_mods ) { + if( id.str() == f.get_unrelative_path().filename().string() ) { + is_mod_loaded = true; + } + } + if( is_mod_loaded ) { + const std::vector interaction_files = get_files_from_path( ".json", f, true, true ); + files.insert( files.end(), interaction_files.begin(), interaction_files.end() ); + } + } + } + + // iterate over each file + for( const cata_path &file : files ) { + try { + // parse it + JsonValue jsin = json_loader::from_path( file ); + load_all_from_json( jsin, src, path, file ); + } catch( const JsonError &err ) { + throw std::runtime_error( err.what() ); + } + } +} + void DynamicDataLoader::load_all_from_json( const JsonValue &jsin, const std::string &src, const cata_path &base_path, const cata_path &full_path ) { diff --git a/src/init.h b/src/init.h index 409a54e4f3b23..c7f3d0184e85c 100644 --- a/src/init.h +++ b/src/init.h @@ -140,6 +140,25 @@ class DynamicDataLoader */ /*@{*/ void load_data_from_path( const cata_path &path, const std::string &src ); + /** + * Load all data from json files located in + * the path (recursive) except for those within the mod_interactions folder. + * @param path Either a folder (recursively load all + * files with the extension .json), or a file (load only + * that file, don't check extension). + * @param src String identifier for mod this data comes from. + * @throws std::exception on all kind of errors. + */ + /*@{*/ + void load_mod_data_from_path( const cata_path &path, const std::string &src ); + /** + * Load directories located within the given path if they are named after a currently loaded mod id. + * @param path a folder. + * @param src String identifier for mod this data comes from. + * @throws std::exception on all kind of errors. + */ + /*@{*/ + void load_mod_interaction_files_from_path( const cata_path &path, const std::string &src ); /*@}*/ /** * Deletes and unloads all the data previously loaded with