This repository has been archived by the owner on Jun 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ADD - Enemy data loading assets (#12)
Signed-off-by: RaenonX <[email protected]>
- Loading branch information
Showing
5 changed files
with
356 additions
and
1 deletion.
There are no files selected for viewing
Submodule media
updated
6250 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
"""Classes for handling the dungeon planner asset.""" | ||
from dataclasses import dataclass | ||
from typing import Optional, TextIO, Union | ||
|
||
from dlparse.mono.asset.base import MasterAssetBase, MasterEntryBase, MasterParserBase | ||
|
||
__all__ = ("DungeonPlannerEntry", "DungeonPlannerAsset") | ||
|
||
DUNGEON_VARIATION_COUNT_MAX: int = 5 | ||
|
||
|
||
@dataclass | ||
class DungeonPlannerEntry(MasterEntryBase): | ||
"""Single entry of a dungeon planner data.""" | ||
|
||
bgm_id: str | ||
|
||
enemy_param_ids: list[list[int]] # Index = ``variation_idx`` of the quest data | ||
|
||
@staticmethod | ||
def get_enemy_param_ids(data: dict[str, Union[str, int]]) -> list[list[int]]: | ||
""" | ||
Get the enemy parameter IDs. | ||
The index of the return corresponds to ``variation_idx`` field of the quest data. | ||
""" | ||
param_ids = [] | ||
param_fields = [ | ||
[ | ||
"_BossCameraEnemy0Param", | ||
"_BossCameraEnemy1Param", | ||
"_BossCameraEnemy2Param", | ||
"_BossCameraEnemy3Param", | ||
"_BossCameraEnemy4Param", | ||
"_BossCameraEnemy5Param", | ||
"_BossCameraEnemy6Param", | ||
"_BossCameraEnemy7Param", | ||
"_BossCameraEnemy8Param", | ||
"_BossCameraEnemy9Param" | ||
], | ||
["_BossCameraEnemy0ParamHard"], | ||
["_BossCameraEnemy0ParamVeryhard"], | ||
["_BossCameraEnemy0ParamExtreme"], | ||
["_BossCameraEnemy0ParamHell"], | ||
] | ||
|
||
for variation_fields in param_fields: | ||
param_ids_variation = [] | ||
|
||
for variation_field in variation_fields: | ||
# REMOVE: not with walrus https://github.com/PyCQA/pylint/issues/3249 | ||
# pylint: disable=superfluous-parens | ||
if not (enemy_param_id := data[variation_field]): | ||
continue | ||
|
||
param_ids_variation.append(enemy_param_id) | ||
|
||
param_ids.append(param_ids_variation) | ||
|
||
return param_ids | ||
|
||
@staticmethod | ||
def parse_raw(data: dict[str, Union[str, int]]) -> "DungeonPlannerEntry": | ||
return DungeonPlannerEntry( | ||
id=data["_Area"], | ||
bgm_id=data["_Bgm"], | ||
enemy_param_ids=DungeonPlannerEntry.get_enemy_param_ids(data), | ||
) | ||
|
||
|
||
class DungeonPlannerAsset(MasterAssetBase[DungeonPlannerEntry]): | ||
"""Quest data asset class.""" | ||
|
||
asset_file_name = "DungeonAreaPlannerData.json" | ||
|
||
def __init__( | ||
self, file_location: Optional[str] = None, /, | ||
asset_dir: Optional[str] = None, file_like: Optional[TextIO] = None | ||
): | ||
super().__init__(DungeonPlannerParser, file_location, asset_dir=asset_dir, file_like=file_like) | ||
|
||
|
||
class DungeonPlannerParser(MasterParserBase[DungeonPlannerEntry]): | ||
"""Class to parse the quest data file.""" | ||
|
||
@classmethod | ||
def parse_file(cls, file_like: TextIO) -> dict[int, DungeonPlannerEntry]: | ||
entries = cls.get_entries_dict(file_like) | ||
|
||
return {key: DungeonPlannerEntry.parse_raw(value) for key, value in entries.items()} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
""" | ||
Classes for handling the enemy data asset. | ||
Note that enemy data and enemy param are different things. | ||
""" | ||
from dataclasses import dataclass | ||
from typing import Optional, TextIO, Union | ||
|
||
from dlparse.enums import Element | ||
from dlparse.mono.asset.base import MasterAssetBase, MasterEntryBase, MasterParserBase | ||
|
||
__all__ = ("EnemyDataEntry", "EnemyDataAsset") | ||
|
||
|
||
@dataclass | ||
class EnemyDataEntry(MasterEntryBase): | ||
"""Single entry of an enemy data.""" | ||
|
||
element: Element | ||
|
||
od_atk_rate: float | ||
od_def_rate: float | ||
|
||
bk_duration_sec: int | ||
bk_def_rate: float | ||
|
||
@staticmethod | ||
def parse_raw(data: dict[str, Union[str, int]]) -> "EnemyDataEntry": | ||
return EnemyDataEntry( | ||
id=data["_Id"], | ||
element=Element(data["_ElementalType"]), | ||
od_atk_rate=data["_ObAtkRate"], | ||
od_def_rate=data["_ObDefRate"], | ||
bk_duration_sec=data["_BreakDuration"], | ||
bk_def_rate=data["_BreakDefRate"], | ||
) | ||
|
||
|
||
class EnemyDataAsset(MasterAssetBase[EnemyDataEntry]): | ||
"""Enemy data asset class.""" | ||
|
||
asset_file_name = "EnemyParam.json" | ||
|
||
def __init__( | ||
self, file_location: Optional[str] = None, /, | ||
asset_dir: Optional[str] = None, file_like: Optional[TextIO] = None | ||
): | ||
super().__init__(EnemyDataParser, file_location, asset_dir=asset_dir, file_like=file_like) | ||
|
||
|
||
class EnemyDataParser(MasterParserBase[EnemyDataEntry]): | ||
"""Class to parse the enemy data file.""" | ||
|
||
@classmethod | ||
def parse_file(cls, file_like: TextIO) -> dict[int, EnemyDataEntry]: | ||
entries = cls.get_entries_dict(file_like) | ||
|
||
return {key: EnemyDataEntry.parse_raw(value) for key, value in entries.items()} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
""" | ||
Classes for handling the quest data asset. | ||
Note that enemy data and enemy param are different things. | ||
""" | ||
from dataclasses import dataclass | ||
from typing import Optional, TextIO, Union | ||
|
||
from dlparse.enums import Element, Status | ||
from dlparse.mono.asset.base import MasterAssetBase, MasterEntryBase, MasterParserBase | ||
|
||
__all__ = ("EnemyParamEntry", "EnemyParamAsset") | ||
|
||
|
||
@dataclass | ||
class EnemyParamEntry(MasterEntryBase): | ||
"""Single entry of an enemy param data.""" | ||
|
||
enemy_data_id: int | ||
|
||
ai_name: str | ||
action_set_id: int | ||
action_set_id_on_elem: dict[Element, int] | ||
|
||
ability_ids: list[int] | ||
ability_berserk_id: int | ||
|
||
hp: int | ||
atk: int | ||
defense: int | ||
|
||
base_od: int | ||
base_bk: int | ||
|
||
affliction_resistance_pct: dict[Status, int] | ||
|
||
form_2nd_param_id: int | ||
|
||
child_1_param_id: int | ||
child_1_count: int | ||
child_2_param_id: int | ||
child_2_count: int | ||
child_3_param_id: int | ||
child_3_count: int | ||
|
||
part_1_param_id: int | ||
part_2_param_id: int | ||
part_3_param_id: int | ||
part_4_param_id: int | ||
|
||
appear_voice_id: str | ||
|
||
@staticmethod | ||
def get_affliction_resistance_pct(data: dict[str, Union[str, int]]) -> dict[Status, int]: | ||
""" | ||
Get a dictionary which key is the corresponding abnormal status; value is its corresponding resistance. | ||
Note that the value returning is percentage (%). A value of 100 means absolute resist. | ||
""" | ||
ret = { | ||
Status.POISON: data["_RegistAbnormalRate01"], | ||
Status.BURN: data["_RegistAbnormalRate02"], | ||
Status.FREEZE: data["_RegistAbnormalRate03"], | ||
Status.PARALYZE: data["_RegistAbnormalRate04"], | ||
Status.BLIND: data["_RegistAbnormalRate05"], | ||
Status.STUN: data["_RegistAbnormalRate06"], | ||
Status.CURSE: data["_RegistAbnormalRate07"], | ||
Status.BOG: data["_RegistAbnormalRate08"], | ||
Status.SLEEP: data["_RegistAbnormalRate09"], | ||
Status.FROSTBITE: data["_RegistAbnormalRate10"], | ||
Status.FLASHBURN: data["_RegistAbnormalRate11"], | ||
Status.STORMLASH: data["_RegistAbnormalRate12"], | ||
Status.SHADOWBLIGHT: data["_RegistAbnormalRate13"], | ||
Status.SCORCHREND: data["_RegistAbnormalRate14"], | ||
} | ||
|
||
return ret | ||
|
||
@staticmethod | ||
def parse_raw(data: dict[str, Union[str, int]]) -> "EnemyParamEntry": | ||
action_set_id_elem = { | ||
Element.FLAME: data["_ActionSetFire"], | ||
Element.WATER: data["_ActionSetWater"], | ||
Element.WIND: data["_ActionSetWind"], | ||
Element.LIGHT: data["_ActionSetLight"], | ||
Element.SHADOW: data["_ActionSetDark"], | ||
} | ||
|
||
ability_ids = [ | ||
data["_Ability01"], | ||
data["_Ability02"], | ||
data["_Ability03"], | ||
data["_Ability04"] | ||
] | ||
|
||
return EnemyParamEntry( | ||
id=data["_Id"], | ||
enemy_data_id=data["_DataId"], | ||
ai_name=data["_Ai"], | ||
action_set_id=data["_ActionSet"], | ||
action_set_id_on_elem=action_set_id_elem, | ||
ability_ids=ability_ids, | ||
ability_berserk_id=data["_BerserkAbility"], | ||
hp=data["_HP"], | ||
atk=data["_Atk"], | ||
defense=data["_Def"], | ||
base_od=data["_BaseOD"], | ||
base_bk=data["_BaseBreak"], | ||
affliction_resistance_pct=EnemyParamEntry.get_affliction_resistance_pct(data), | ||
form_2nd_param_id=data["_Form2nd"], | ||
child_1_param_id=data["_Child01Param"], | ||
child_1_count=data["_Child01Num"], | ||
child_2_param_id=data["_Child02Param"], | ||
child_2_count=data["_Child02Num"], | ||
child_3_param_id=data["_Child03Param"], | ||
child_3_count=data["_Child03Num"], | ||
part_1_param_id=data["_PartsA"], | ||
part_2_param_id=data["_PartsB"], | ||
part_3_param_id=data["_PartsC"], | ||
part_4_param_id=data["_PartsD"], | ||
appear_voice_id=data["_BossAppearVoiceId"], | ||
) | ||
|
||
|
||
class EnemyParamAsset(MasterAssetBase[EnemyParamEntry]): | ||
"""Enemy param asset class.""" | ||
|
||
asset_file_name = "EnemyParam.json" | ||
|
||
def __init__( | ||
self, file_location: Optional[str] = None, /, | ||
asset_dir: Optional[str] = None, file_like: Optional[TextIO] = None | ||
): | ||
super().__init__(EnemyParamParser, file_location, asset_dir=asset_dir, file_like=file_like) | ||
|
||
|
||
class EnemyParamParser(MasterParserBase[EnemyParamEntry]): | ||
"""Class to parse the enemy param data file.""" | ||
|
||
@classmethod | ||
def parse_file(cls, file_like: TextIO) -> dict[int, EnemyParamEntry]: | ||
entries = cls.get_entries_dict(file_like) | ||
|
||
return {key: EnemyParamEntry.parse_raw(value) for key, value in entries.items()} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"""Classes for handling the quest data asset.""" | ||
from dataclasses import dataclass | ||
from typing import Optional, TextIO, Union | ||
|
||
from dlparse.enums import Element | ||
from dlparse.mono.asset.base import MasterAssetBase, MasterEntryBase, MasterParserBase | ||
|
||
__all__ = ("QuestDataEntry", "QuestDataAsset") | ||
|
||
|
||
@dataclass | ||
class QuestDataEntry(MasterEntryBase): | ||
"""Single entry of a quest data.""" | ||
|
||
name_view_label: str | ||
|
||
element_1: Element | ||
element_1_limit: Element | ||
element_2: Element | ||
element_2_limit: Element | ||
|
||
max_time_sec: int | ||
max_revive: int | ||
|
||
variation_idx: int | ||
area_1_name: str | ||
|
||
@staticmethod | ||
def parse_raw(data: dict[str, Union[str, int]]) -> "QuestDataEntry": | ||
return QuestDataEntry( | ||
id=data["_Id"], | ||
name_view_label=data["_QuestViewName"], | ||
element_1=Element(data["_Elemental"]), | ||
element_1_limit=Element(data["_LimitedElementalType"]), | ||
element_2=Element(data["_Elemental2"]), | ||
element_2_limit=Element(data["_LimitedElementalType2"]), | ||
max_time_sec=data["_FailedTermsTimeElapsed"], | ||
max_revive=data["_RebornLimit"], | ||
variation_idx=data["_VariationType"], | ||
area_1_name=data["_AreaName01"] | ||
) | ||
|
||
|
||
class QuestDataAsset(MasterAssetBase[QuestDataEntry]): | ||
"""Quest data asset class.""" | ||
|
||
asset_file_name = "QuestData.json" | ||
|
||
def __init__( | ||
self, file_location: Optional[str] = None, /, | ||
asset_dir: Optional[str] = None, file_like: Optional[TextIO] = None | ||
): | ||
super().__init__(QuestDataParser, file_location, asset_dir=asset_dir, file_like=file_like) | ||
|
||
|
||
class QuestDataParser(MasterParserBase[QuestDataEntry]): | ||
"""Class to parse the quest data file.""" | ||
|
||
@classmethod | ||
def parse_file(cls, file_like: TextIO) -> dict[int, QuestDataEntry]: | ||
entries = cls.get_entries_dict(file_like) | ||
|
||
return {key: QuestDataEntry.parse_raw(value) for key, value in entries.items()} |