Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes #20: ensure vanilla_entities are loaded on "Write Entities" file regeneration #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions soulstruct/base/maps/msb/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from soulstruct.games import GameSpecificType
from soulstruct.utilities.binary import BinaryReader
from soulstruct.utilities.maths import Vector3, Matrix3, resolve_rotation
from soulstruct.utilities.files import PACKAGE_PATH

from .msb_entry import MSBEntry

Expand Down Expand Up @@ -434,11 +435,12 @@ def write_entities_module(
area_id: int = None,
block_id: int = None,
# TODO: cc_id and dd_id for Elden Ring
append_to_module: str = ""
include_vanilla_entities: bool = False,
):
"""Generates a '{mXX_YY}_entities.py' file with entity IDs for import into EVS script.

If `append_to_module` text is given, all map entities will be appended to it.

If include_vanilla_entities is true, attempts to append this map's vanilla_entities
content to the generated file.
"""
if module_path is None:
if self.path is None:
Expand Down Expand Up @@ -482,6 +484,21 @@ def sort_key(key_value) -> tuple[str, int]:
module_path = Path(module_path)

game_types_import = f"from soulstruct.{self.GAME.submodule_name}.game_types import *\n"

if include_vanilla_entities:
game_folder = self.GAME.submodule_name
# DS1R vanilla_entities are located in PTDE folder
if game_folder == 'darksouls1r':
game_folder = 'darksouls1ptde'
try:
append_to_module = PACKAGE_PATH(
f"{game_folder}/events/vanilla_entities/{self.path.stem}_entities.py"
).read_text()
except FileNotFoundError:
append_to_module = ""
else:
append_to_module = ""
Comment on lines +488 to +500
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic was previously only here, so this didn't happen when running the function from here.


if append_to_module:
if game_types_import not in append_to_module:
# Add game type start import to module. (Very rare that it wouldn't already be there.)
Expand Down
3 changes: 3 additions & 0 deletions soulstruct/base/project/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def __init__(self, project_path="", with_window: ProjectWindow = None, game_root
self.text_editor_font_size = DEFAULT_TEXT_EDITOR_FONT_SIZE
self.custom_script_directory = Path()
self.entities_in_events_directory = False
self.include_vanila_entities = False
self.prefer_json = False
# TODO: Record last edit time for each file/structure.

Expand Down Expand Up @@ -628,6 +629,7 @@ def load_config(self, with_window: ProjectWindow = None, game_root: Path = None)
self._vanilla_game_root = Path(vanilla_game_root)
self.text_editor_font_size = config.get("TextEditorFontSize", DEFAULT_TEXT_EDITOR_FONT_SIZE)
self.entities_in_events_directory = config.get("EntitiesInEventsDirectory", False)
self.include_vanila_entities = config.get("IncludeVanillaEntities", False)
self.prefer_json = config.get("PreferJSON", False)
except KeyError:
raise SoulstructProjectError(
Expand Down Expand Up @@ -752,6 +754,7 @@ def _build_config_dict(self):
"VanillaGameDirectory": str(self._vanilla_game_root),
"TextEditorFontSize": DEFAULT_TEXT_EDITOR_FONT_SIZE,
"EntitiesInEventsDirectory": self.entities_in_events_directory,
"IncludeVanillaEntities": self.include_vanila_entities,
"PreferJSON": self.prefer_json,
}

Expand Down
7 changes: 6 additions & 1 deletion soulstruct/base/project/editors/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,12 @@ def _write_entities_module(self):

msb = self.get_selected_msb()
try:
msb.write_entities_module(module_path, area_id=game_map.area_id, block_id=game_map.block_id)
msb.write_entities_module(
module_path,
area_id=game_map.area_id,
block_id=game_map.block_id,
include_vanilla_entities=self._project.include_vanila_entities
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MSB class doesn't have access to the project configuration, which is why this boolean needs to be passed in. Luckily, editors have access to the project via the _project attribute.

)
except Exception as ex:
self.CustomDialog(
"Write Failed", f"An error occurred while writing '{{project}}/events/{module_path.name}':\n{ex}"
Expand Down
11 changes: 2 additions & 9 deletions soulstruct/darksouls1r/project/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,11 @@ def offer_entities_export(self, with_window: ProjectWindow = None):
game_map = self.maps.GET_MAP(map_name)

if write_vanilla_entities_result == 0:
try:
vanilla_module = PACKAGE_PATH(
f"darksouls1ptde/events/vanilla_entities/{game_map.emevd_file_stem}_entities.py"
).read_text()
except FileNotFoundError:
vanilla_module = ""
else:
vanilla_module = ""
self.include_vanila_entities = True
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the only logic needed here is setting the project configuration value.

Notably, this boolean can't be changed after project initialization (besides manually editing the config json, which will break a lot of things anyway), but I think this limitation really stems from that once an entity has replaced a hard-coded ID within a map script, there isn't a way to reverse this/update the entity without rolling back the script to use the ID again. Until that behavior changes, I think it's appropriate for this to be a one-time set.


msb.write_entities_module(
self.project_root / f"entities/{game_map.emevd_file_stem}_entities.py",
append_to_module=vanilla_module,
include_vanilla_entities=self.include_vanila_entities
)
return True
else:
Expand Down