From fcb34df8b1ad9406ce9093e76bc40b1cd7adfadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 10 Nov 2024 15:36:34 +0100 Subject: [PATCH 01/10] fix: value access attribute error --- src/zenkit/daedalus_script.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index 7c1abfc..edbb795 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -124,13 +124,13 @@ def set_string(self, val: str, i: int = 0, ctx: DaedalusInstance | None = None) ) def get_int(self, i: int = 0, ctx: DaedalusInstance | None = None) -> int: - return DLL.ZkDaedalusSymbol_getInt(self._handle, c_uint16(i), ctx.handle if ctx else None).value + return DLL.ZkDaedalusSymbol_getInt(self._handle, c_uint16(i), ctx.handle if ctx else None) def set_int(self, val: int, i: int = 0, ctx: DaedalusInstance | None = None) -> None: DLL.ZkDaedalusSymbol_setInt(self._handle, c_int32(val), c_uint16(i), ctx.handle if ctx else None) def get_float(self, i: int = 0, ctx: DaedalusInstance | None = None) -> float: - return DLL.ZkDaedalusSymbol_getFloat(self._handle, c_uint16(i), ctx.handle if ctx else None).value + return DLL.ZkDaedalusSymbol_getFloat(self._handle, c_uint16(i), ctx.handle if ctx else None) def set_float(self, val: float, i: int = 0, ctx: DaedalusInstance | None = None) -> None: DLL.ZkDaedalusSymbol_setFloat(self._handle, c_float(val), c_uint16(i), ctx.handle if ctx else None) From cdd726056c40622921c25253e0857f3810550c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 10 Nov 2024 15:44:52 +0100 Subject: [PATCH 02/10] feat: value property for symbol --- src/zenkit/daedalus_script.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index edbb795..3ef4949 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -187,6 +187,16 @@ def index(self) -> int: def return_type(self) -> DaedalusDataType: return DaedalusDataType(DLL.ZkDaedalusSymbol_getReturnType(self._handle)) + @property + def value(self) -> float | int | str | None: + if self.type == DaedalusDataType.FLOAT: + return self.get_float() + if self.type == DaedalusDataType.INT: + return self.get_int() + if self.type == DaedalusDataType.STRING: + return self.get_string() + return None + def __repr__(self) -> str: return f"<{self.__class__.__name__} handle={self._handle} name={self.name!r} type={self.type.name}>" From 8343ded123245a4d952cc26a1cbd193a504f1a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 10 Nov 2024 15:54:36 +0100 Subject: [PATCH 03/10] chore: update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c88fa4f..889eb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /.cache/ /dist/ +/build/ /?venv/ *.egg-info/ From cd4facc55faea601fb3a3b63cc306382aebbb50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Mon, 11 Nov 2024 21:59:32 +0100 Subject: [PATCH 04/10] feat: add get_parent for DaedalusSymbol --- src/zenkit/daedalus_script.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index 3ef4949..afcbc8d 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -135,6 +135,17 @@ def get_float(self, i: int = 0, ctx: DaedalusInstance | None = None) -> float: def set_float(self, val: float, i: int = 0, ctx: DaedalusInstance | None = None) -> None: DLL.ZkDaedalusSymbol_setFloat(self._handle, c_float(val), c_uint16(i), ctx.handle if ctx else None) + def get_parent_as_symbol(self, find_root: bool = False) -> "DaedalusSymbol | None": + if self.parent < 0: + return None + + handle = self._keepalive.get_symbol_by_index(self.parent) + + while find_root and handle and handle.parent >= 0: + handle = self._keepalive.get_symbol_by_index(handle.parent) + + return handle + @property def is_const(self) -> bool: return DLL.ZkDaedalusSymbol_getIsConst(self._handle) != 0 From f342e9c115d1d5804e30884b4cd37113e92e23e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Tue, 12 Nov 2024 00:46:49 +0100 Subject: [PATCH 05/10] feat: add instance as symbol value --- src/zenkit/_core.py | 1 + src/zenkit/daedalus/__init__.py | 9 +++++++++ src/zenkit/daedalus_script.py | 8 +++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/zenkit/_core.py b/src/zenkit/_core.py index c8121b5..00c9c3f 100644 --- a/src/zenkit/_core.py +++ b/src/zenkit/_core.py @@ -54,6 +54,7 @@ DLL: Final[CDLL] = CDLL(str(_PATH)) PathOrFileLike = Union[str, PathLike, "Read", bytes, bytearray, "VfsNode"] +DaedalusSymbolValue = Union[float, int, str, "DaedalusInstance", None] class GameVersion(IntEnum): diff --git a/src/zenkit/daedalus/__init__.py b/src/zenkit/daedalus/__init__.py index 173a95c..47d8637 100644 --- a/src/zenkit/daedalus/__init__.py +++ b/src/zenkit/daedalus/__init__.py @@ -44,3 +44,12 @@ DaedalusInstanceType.SOUND_EFFECT: SoundEffectInstance, DaedalusInstanceType.SOUND_SYSTEM: SoundSystemInstance, } + +_CLASS_TYPES = { + "C_NPC": DaedalusInstanceType.NPC, + "C_MISSION": DaedalusInstanceType.MISSION, + "C_ITEM": DaedalusInstanceType.ITEM, + "C_INFO": DaedalusInstanceType.INFO, + "C_ITEMREACT": DaedalusInstanceType.ITEM_REACT, + "C_FOCUS": DaedalusInstanceType.FOCUS, +} diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index afcbc8d..68404f4 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -20,8 +20,10 @@ from typing import ClassVar from zenkit import _native +from zenkit.daedalus import _CLASS_TYPES from zenkit._core import DLL from zenkit._core import PathOrFileLike +from zenkit._core import DaedalusSymbolValue from zenkit._native import ZkPointer from zenkit._native import ZkString from zenkit.daedalus.base import DaedalusInstance @@ -199,13 +201,17 @@ def return_type(self) -> DaedalusDataType: return DaedalusDataType(DLL.ZkDaedalusSymbol_getReturnType(self._handle)) @property - def value(self) -> float | int | str | None: + def value(self) -> DaedalusSymbolValue: if self.type == DaedalusDataType.FLOAT: return self.get_float() if self.type == DaedalusDataType.INT: return self.get_int() if self.type == DaedalusDataType.STRING: return self.get_string() + if self._keepalive.__class__.__name__ == "DaedalusVm" and self.type == DaedalusDataType.INSTANCE: + class_sym = self.get_parent_as_symbol(find_root=True) + if class_sym: # Instances always have parent symbols, except for .PAR instances in functions... + return self._keepalive.init_instance(self, _CLASS_TYPES[class_sym.name]) return None def __repr__(self) -> str: From 6d0280740a876273954ef8e78e0f5f76f61606cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Tue, 12 Nov 2024 00:47:53 +0100 Subject: [PATCH 06/10] feat: add __str__ for symbol --- src/zenkit/daedalus_script.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index 68404f4..332f1a2 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -217,6 +217,10 @@ def value(self) -> DaedalusSymbolValue: def __repr__(self) -> str: return f"<{self.__class__.__name__} handle={self._handle} name={self.name!r} type={self.type.name}>" + def __str__(self) -> str: + value = self.value + return value.__str__() if value is not None else self.__repr__() + class DaedalusInstruction(Structure): _fields_: ClassVar[tuple[str, Any]] = [ From 76c7ea1b82d0f688cd8f7678eecc405ca25451a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 19 Jan 2025 04:53:05 +0100 Subject: [PATCH 07/10] fix: add class type check --- src/zenkit/daedalus_script.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index 332f1a2..9bc5b9c 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -211,7 +211,9 @@ def value(self) -> DaedalusSymbolValue: if self._keepalive.__class__.__name__ == "DaedalusVm" and self.type == DaedalusDataType.INSTANCE: class_sym = self.get_parent_as_symbol(find_root=True) if class_sym: # Instances always have parent symbols, except for .PAR instances in functions... - return self._keepalive.init_instance(self, _CLASS_TYPES[class_sym.name]) + typ = _CLASS_TYPES.get(class_sym.name) + if typ: # Unknow classes ex. from Ikarus aren't linked to a type + return self._keepalive.init_instance(self, typ) return None def __repr__(self) -> str: From 83b6dd6df3c17020e504693878cb3fa427e06d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 19 Jan 2025 05:07:00 +0100 Subject: [PATCH 08/10] fix: new conditional for instance type value --- src/zenkit/daedalus_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index 9bc5b9c..f3205d7 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -208,7 +208,7 @@ def value(self) -> DaedalusSymbolValue: return self.get_int() if self.type == DaedalusDataType.STRING: return self.get_string() - if self._keepalive.__class__.__name__ == "DaedalusVm" and self.type == DaedalusDataType.INSTANCE: + if self.type == DaedalusDataType.INSTANCE and hasattr(self._keepalive, "init_instance"): class_sym = self.get_parent_as_symbol(find_root=True) if class_sym: # Instances always have parent symbols, except for .PAR instances in functions... typ = _CLASS_TYPES.get(class_sym.name) From 5f65656a02a1c44b8febd699c512472c24631e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sun, 19 Jan 2025 06:02:24 +0100 Subject: [PATCH 09/10] fix: daedalus script symbols as generator --- src/zenkit/daedalus_script.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index f3205d7..eac6edd 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -7,6 +7,7 @@ ] from abc import abstractmethod +from collections.abc import Generator from ctypes import Structure from ctypes import c_float from ctypes import c_int @@ -281,9 +282,9 @@ def load(path_or_file_like: PathOrFileLike) -> "DaedalusScript": return DaedalusScript(_handle=handle, _delete=True) @property - def symbols(self) -> list[DaedalusSymbol]: + def symbols(self) -> Generator[DaedalusSymbol]: count = DLL.ZkDaedalusScript_getSymbolCount(self._handle) - return [self.get_symbol_by_index(i) for i in range(count)] + return (self.get_symbol_by_index(i) for i in range(count)) def get_instruction(self, address: int) -> DaedalusInstruction: return DLL.ZkDaedalusScript_getInstruction(self._handle, c_size_t(address)) From a7f19d9322b28ccb908d1effd559372121428138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Krzy=C5=9Bk=C3=B3w?= Date: Sat, 25 Jan 2025 18:27:07 +0100 Subject: [PATCH 10/10] fix: is_const check before init_instance --- src/zenkit/daedalus_script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zenkit/daedalus_script.py b/src/zenkit/daedalus_script.py index eac6edd..121c8d8 100644 --- a/src/zenkit/daedalus_script.py +++ b/src/zenkit/daedalus_script.py @@ -209,7 +209,7 @@ def value(self) -> DaedalusSymbolValue: return self.get_int() if self.type == DaedalusDataType.STRING: return self.get_string() - if self.type == DaedalusDataType.INSTANCE and hasattr(self._keepalive, "init_instance"): + if self.type == DaedalusDataType.INSTANCE and self.is_const and hasattr(self._keepalive, "init_instance"): class_sym = self.get_parent_as_symbol(find_root=True) if class_sym: # Instances always have parent symbols, except for .PAR instances in functions... typ = _CLASS_TYPES.get(class_sym.name)