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

Create TypedDict file for the json schema #279

Open
wants to merge 2 commits into
base: main
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
9 changes: 8 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ repos:
rev: v0.0.291
hooks:
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
args: [ --fix, --exit-non-zero-on-fix ]

- repo: https://github.com/henriquegemignani/jsonschema-to-typeddict
rev: v1.0.1
hooks:
- id: jsonschema-to-typeddict
files: src/open_dread_rando/files/schema.json
args: [ --output-path, src/open_dread_rando/configuration.pyi, --root-name, Configuration ]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ write_to = "src/open_dread_rando/version.py"

[tool.ruff]
line-length = 120
select = ["E", "F", "W", "C90", "I", "UP"]
select = ["E", "F", "W", "C90", "I", "UP", "TCH"]
src = ["src"]

# Version to target for generated code.
Expand Down
215 changes: 215 additions & 0 deletions src/open_dread_rando/configuration.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# This file is generated. Manual changes will be lost
# fmt: off
# ruff: noqa
from __future__ import annotations

import typing


class DefScenarioLuaCallback(typing.TypedDict):
scenario: typing.NotRequired[def_scenario_name]
function: typing.NotRequired[str]
args: typing.NotRequired[int]


def_scenario_lua_callback = DefScenarioLuaCallback


class DefActorReferenceWithLayer(typing.TypedDict):
scenario: typing.Required[def_scenario_name]
layer: typing.NotRequired[str]
actor: typing.Required[str]


def_actor_reference_with_layer = DefActorReferenceWithLayer


class DefActorReference(typing.TypedDict):
scenario: typing.Required[def_scenario_name]
actor: typing.Required[str]


def_actor_reference = DefActorReference
def_scenario_name = str
def_constant_damage_value = float | None
def_item_id = str


class DefItem(typing.TypedDict):
item_id: typing.Required[def_item_id]
quantity: typing.Required[float]


def_item = DefItem


class DefPosition(typing.TypedDict):
x: typing.Required[float]
y: typing.Required[float]
z: typing.Required[float]


def_position = DefPosition


# The root object

class ConfigurationPickupsItemMapIconCustomIconCoords(typing.TypedDict, total=False):
row: typing.Required[int]
col: typing.Required[int]


class ConfigurationPickupsItemMapIconCustomIconExtras(typing.TypedDict, total=False):
pass


class ConfigurationPickupsItemMapIconCustomIcon(typing.TypedDict, total=False):
label: typing.Required[str]
player: typing.NotRequired[str]
base_icon: typing.NotRequired[str]
coords: typing.NotRequired[ConfigurationPickupsItemMapIconCustomIconCoords]
is_global: typing.NotRequired[bool]
full_zoom_scale: typing.NotRequired[bool]
extras: typing.NotRequired[ConfigurationPickupsItemMapIconCustomIconExtras]


class ConfigurationPickupsItemMapIcon(typing.TypedDict, total=False):
original_actor: typing.NotRequired[def_actor_reference_with_layer]
icon_id: typing.NotRequired[str]
custom_icon: typing.NotRequired[ConfigurationPickupsItemMapIconCustomIcon]


class ConfigurationPickupsItem(typing.TypedDict, total=False):
pickup_type: typing.Required[str]
caption: typing.Required[str]
resources: typing.Required[list[list[def_item]]]
pickup_actor: typing.NotRequired[def_actor_reference_with_layer]
model: typing.NotRequired[list[str]]
map_icon: typing.NotRequired[ConfigurationPickupsItemMapIcon]
pickup_lua_callback: typing.NotRequired[def_scenario_lua_callback]
pickup_actordef: typing.NotRequired[str]
pickup_string_key: typing.NotRequired[str]


class ConfigurationElevatorsItem(typing.TypedDict, total=False):
teleporter: typing.Required[def_actor_reference_with_layer]
destination: typing.Required[def_actor_reference]
connection_name: typing.Required[str]


class ConfigurationStartingItems(typing.TypedDict, total=False):
ITEM_LIFE_SHARDS: typing.NotRequired[float]


class ConfigurationHintsItem(typing.TypedDict, total=False):
accesspoint_actor: typing.Required[def_actor_reference_with_layer]
hint_id: typing.Required[str]
text: typing.Required[str]


class ConfigurationTextPatches(typing.TypedDict, total=False):
pass


class ConfigurationCosmeticPatchesConfig(typing.TypedDict, total=False):
pass


class ConfigurationCosmeticPatchesLuaCustomInit(typing.TypedDict):
enable_death_counter: typing.NotRequired[bool]
enable_room_name_display: typing.NotRequired[str]


class ConfigurationCosmeticPatchesLuaCameraNamesDict(typing.TypedDict):
pass


class ConfigurationCosmeticPatchesLua(typing.TypedDict):
custom_init: typing.NotRequired[ConfigurationCosmeticPatchesLuaCustomInit]
camera_names_dict: typing.NotRequired[ConfigurationCosmeticPatchesLuaCameraNamesDict]


class ConfigurationCosmeticPatchesShieldVersions(typing.TypedDict, total=False):
ice_missile: typing.NotRequired[str]
diffusion_beam: typing.NotRequired[str]
storm_missile: typing.NotRequired[str]
bomb: typing.NotRequired[str]
cross_bomb: typing.NotRequired[str]
power_bomb: typing.NotRequired[str]


class ConfigurationCosmeticPatches(typing.TypedDict, total=False):
config: typing.Required[ConfigurationCosmeticPatchesConfig]
lua: typing.Required[ConfigurationCosmeticPatchesLua]
shield_versions: typing.Required[ConfigurationCosmeticPatchesShieldVersions]


class ConfigurationConstantEnvironmentDamage(typing.TypedDict):
heat: typing.NotRequired[def_constant_damage_value]
cold: typing.NotRequired[def_constant_damage_value]
lava: typing.NotRequired[def_constant_damage_value]


class ConfigurationGamePatches(typing.TypedDict):
raven_beak_damage_table_handling: typing.NotRequired[str]
remove_grapple_blocks_hanubia_shortcut: typing.NotRequired[bool]
remove_grapple_block_path_to_itorash: typing.NotRequired[bool]
default_x_released: typing.NotRequired[bool]
enable_experiment_boss: typing.NotRequired[bool]
warp_to_start: typing.NotRequired[bool]
nerf_power_bombs: typing.NotRequired[bool]


class ConfigurationObjective(typing.TypedDict):
required_artifacts: typing.NotRequired[int]
hints: typing.NotRequired[list[str]]


class ConfigurationDoorPatchesItem(typing.TypedDict):
actor: typing.Required[def_actor_reference_with_layer]
door_type: typing.Required[str]


class ConfigurationTileGroupPatchesItem(typing.TypedDict):
actor: typing.Required[def_actor_reference_with_layer]
tiletype: typing.Required[str]


class ConfigurationNewSpawnPointsItem(typing.TypedDict):
new_actor: typing.Required[def_actor_reference]
location: typing.Required[def_position]
collision_camera_name: typing.Required[str]


class ConfigurationSpoilerLog(typing.TypedDict, total=False):
pass


class Configuration(typing.TypedDict):
configuration_identifier: typing.Required[str]
layout_uuid: typing.NotRequired[str]
starting_location: typing.Required[def_actor_reference]
pickups: typing.Required[list[ConfigurationPickupsItem]]
elevators: typing.NotRequired[list[ConfigurationElevatorsItem]]
debug_export_modified_files: typing.NotRequired[bool]
starting_items: typing.Required[ConfigurationStartingItems]
starting_text: typing.NotRequired[list[list[str]]]
energy_per_tank: typing.NotRequired[float]
immediate_energy_parts: typing.NotRequired[bool]
hints: typing.NotRequired[list[ConfigurationHintsItem]]
text_patches: typing.NotRequired[ConfigurationTextPatches]
mod_compatibility: typing.NotRequired[str]
mod_category: typing.NotRequired[str]
cosmetic_patches: typing.NotRequired[ConfigurationCosmeticPatches]
enable_remote_lua: typing.NotRequired[bool]
constant_environment_damage: typing.NotRequired[ConfigurationConstantEnvironmentDamage]
game_patches: typing.NotRequired[ConfigurationGamePatches]
objective: typing.NotRequired[ConfigurationObjective]
show_shields_on_minimap: typing.NotRequired[bool]
door_patches: typing.NotRequired[list[ConfigurationDoorPatchesItem]]
tile_group_patches: typing.NotRequired[list[ConfigurationTileGroupPatchesItem]]
new_spawn_points: typing.NotRequired[list[ConfigurationNewSpawnPointsItem]]
spoiler_log: typing.NotRequired[ConfigurationSpoilerLog]


Configuration = Configuration
13 changes: 9 additions & 4 deletions src/open_dread_rando/cosmetic_patches/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
from typing import Any

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from mercury_engine_data_structures.formats.ini import Ini

from open_dread_rando.patcher_editor import PatcherEditor
if TYPE_CHECKING:
from open_dread_rando.configuration import ConfigurationCosmeticPatches
from open_dread_rando.patcher_editor import PatcherEditor


def apply_cosmetic_patches(editor: PatcherEditor, cosmetic: dict):
def apply_cosmetic_patches(editor: PatcherEditor, cosmetic: ConfigurationCosmeticPatches) -> None:
edit_config(editor, cosmetic["config"])


def edit_config(editor: PatcherEditor, config_patches: dict[str, dict[str, Any]]):
def edit_config(editor: PatcherEditor, config_patches: dict[str, dict[str, Any]]) -> None:
config_file = editor.get_file('config.ini', Ini)

for section, items in config_patches.items():
Expand Down
16 changes: 13 additions & 3 deletions src/open_dread_rando/door_locks/custom_door_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from __future__ import annotations

import dataclasses
import functools
import typing
from enum import Enum

from mercury_engine_data_structures.formats import Bmsad
Expand All @@ -8,7 +11,10 @@
from open_dread_rando.files import templates_path
from open_dread_rando.misc_patches.material_patcher import MaterialData, create_custom_material
from open_dread_rando.misc_patches.model_patcher import ModelData, create_custom_model
from open_dread_rando.patcher_editor import PatcherEditor

if typing.TYPE_CHECKING:
from open_dread_rando.configuration import ConfigurationCosmeticPatchesShieldVersions
from open_dread_rando.patcher_editor import PatcherEditor

MISSILE_MDL = "actors/props/doorshieldmissile/models/doorshieldmissile.bcmdl"
SUPER_MDL = "actors/props/doorshieldsupermissile/models/doorshieldsupermissile.bcmdl"
Expand Down Expand Up @@ -409,6 +415,10 @@ def patch(self, editor: PatcherEditor, version: str = "DEFAULT") -> None:
editor.add_new_asset(self.data.actordef, new_template, [])


def create_all_shield_assets(editor: PatcherEditor, shield_model_config: dict[str, str]) -> None:
for shield_name, shield_type in shield_model_config.items():
def create_all_shield_assets(editor: PatcherEditor, shield_model_config: ConfigurationCosmeticPatchesShieldVersions
) -> None:

# mypy doesn't like iterating over typed dict
model_config = typing.cast(dict[str, str], shield_model_config)
for shield_name, shield_type in model_config.items():
BaseShield(ALL_SHIELD_DATA[shield_name]).patch(editor, shield_type)
18 changes: 13 additions & 5 deletions src/open_dread_rando/door_locks/door_patcher.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
from __future__ import annotations

import copy
from bisect import insort
from collections.abc import Sequence
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING

from construct import Container, ListContainer
from mercury_engine_data_structures.formats import Bmscc

from open_dread_rando.constants import ALL_SCENARIOS
from open_dread_rando.patcher_editor import PatcherEditor

if TYPE_CHECKING:
from collections.abc import Sequence

from open_dread_rando.configuration import DefActorReferenceWithLayer
from open_dread_rando.patcher_editor import PatcherEditor

# copied from existing entity, so we don't have to make a whole shield
_EXAMPLE_SHIELD = {"scenario": "s010_cave", "layer": "default", "actor": "Door003_missileShield"}
Expand Down Expand Up @@ -239,11 +246,12 @@ def door_actor_to_type(self, door: Container, scenario: str) -> DoorType:
else:
raise ValueError(f"Door {door.sName} in scenario {scenario} is not a patchable door!")

def patch_door(self, door_ref: dict, door_type: str):
def patch_door(self, door_ref: DefActorReferenceWithLayer, door_type: str) -> None:
"""
Patches a door given a reference.

@param door: A dictionary representing a requested door patch.
@param door_ref: A dictionary representing a requested door patch.
@param door_type:
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a description to the parameter otherwise the docstring looks like only half done.

Copy link
Member Author

@henriquegemignani henriquegemignani Oct 4, 2023

Choose a reason for hiding this comment

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

I fix the docstring's broken link and you go and ask for me to fix the docstring >:(

"""

scenario = door_ref["scenario"]
Expand All @@ -265,7 +273,7 @@ def patch_door(self, door_ref: dict, door_type: str):
self.door_to_basic(door_actor, door_in_scenario_type, scenario)
self.power_to_door_type(door_actor, door_type, scenario)

def door_to_basic(self, door: Container, door_type: DoorType, scenario: str):
def door_to_basic(self, door: Container, door_type: DoorType, scenario: str) -> None:
"""
Reverts a door to a basic (power) door based on its door_type
"""
Expand Down
Loading