arkparser 0.7.1__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {arkparser-0.7.1 → arkparser-0.7.2}/PKG-INFO +1 -1
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/__init__.py +1 -1
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/export.py +10 -1
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/PKG-INFO +1 -1
- {arkparser-0.7.1 → arkparser-0.7.2}/pyproject.toml +1 -1
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cryopod_export.py +76 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/LICENSE +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/README.md +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/__init__.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/binary_reader.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/exceptions.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/map_config.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/normalization.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/types.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/common/version_detection.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/data_models.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/__init__.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/base.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/cloud_inventory.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/profile.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/tribe.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/files/world_save.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/__init__.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/container.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/game_object.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/game_objects/location.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/__init__.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/base.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/byte_property.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/compound.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/primitives.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/properties/registry.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/__init__.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/base.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/colors.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/misc.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/property_list.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/registry.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser/structs/vectors.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/SOURCES.txt +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/dependency_links.txt +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/requires.txt +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/arkparser.egg-info/top_level.txt +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/setup.cfg +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_asa_header_position.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_asa_name_table.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_ase_cluster_drift.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_binary_reader.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_binary_reader_layouts.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cloud_export.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_cloud_inventory.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_current_stats.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_data_models.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_export.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_game_objects.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_golden_exports.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_lazy_properties.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_profile.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_review_fixes.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_tribe.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_v13_property_layouts.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_version_detection.py +0 -0
- {arkparser-0.7.1 → arkparser-0.7.2}/tests/test_world_save.py +0 -0
|
@@ -1568,7 +1568,7 @@ def _build_item_owner_lookup(save: t.Any, lookup: dict[t.Any, t.Any]) -> dict[t.
|
|
|
1568
1568
|
actor_infos = container._inv_actor_info.items()
|
|
1569
1569
|
else:
|
|
1570
1570
|
actor_infos = _iter_inv_actor_info(save)
|
|
1571
|
-
for
|
|
1571
|
+
for actor_id, (inv_ref, team_raw, tribe_raw, owner_raw) in actor_infos:
|
|
1572
1572
|
inv = _resolve(inv_ref, lookup)
|
|
1573
1573
|
if inv is None:
|
|
1574
1574
|
continue
|
|
@@ -1576,9 +1576,11 @@ def _build_item_owner_lookup(save: t.Any, lookup: dict[t.Any, t.Any]) -> dict[t.
|
|
|
1576
1576
|
refs = _prop(inv, "InventoryItems")
|
|
1577
1577
|
if not isinstance(refs, list) or not refs:
|
|
1578
1578
|
continue
|
|
1579
|
+
owner_obj = lookup.get(actor_id) if actor_id is not None else None
|
|
1579
1580
|
info = {
|
|
1580
1581
|
"TargetingTeam": _int(team_raw),
|
|
1581
1582
|
"TribeName": _str(tribe_raw) or _str(owner_raw),
|
|
1583
|
+
"OwnerLocation": getattr(owner_obj, "location", None),
|
|
1582
1584
|
}
|
|
1583
1585
|
for ref in refs:
|
|
1584
1586
|
item_obj = _resolve(ref, lookup)
|
|
@@ -1667,7 +1669,14 @@ def _export_world_cryopods(
|
|
|
1667
1669
|
summaries[item_id] = _cryo_summary(cryo)
|
|
1668
1670
|
owner_info = owner_lookup.get(item_id) if item_id is not None else None
|
|
1669
1671
|
if owner_info is not None:
|
|
1672
|
+
# Pods stored in inventories carry no actor transform of their
|
|
1673
|
+
# own (always the case on ASA); inherit the owning container's
|
|
1674
|
+
# location so GPS fields don't collapse to 0/0/0.
|
|
1675
|
+
if actor.location is None:
|
|
1676
|
+
actor.location = owner_info.get("OwnerLocation")
|
|
1670
1677
|
for key, val in owner_info.items():
|
|
1678
|
+
if key == "OwnerLocation":
|
|
1679
|
+
continue
|
|
1671
1680
|
if val and not cryo.creature_props.get(key):
|
|
1672
1681
|
cryo.creature_props[key] = val
|
|
1673
1682
|
record = _tamed_dict(actor, status, empty_lookup, map_config, save, stored=True)
|
|
@@ -19,7 +19,11 @@ with ``cryo=True``. Two regressions tested here:
|
|
|
19
19
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
|
+
import typing as t
|
|
23
|
+
|
|
22
24
|
from arkparser.data_models import CryopodCreature
|
|
25
|
+
from arkparser.export import export_tamed
|
|
26
|
+
from arkparser.game_objects.location import LocationData
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def _asa_blob(current: list[float], max_: list[float]) -> dict[str, object]:
|
|
@@ -97,6 +101,78 @@ def test_asa_cryopod_display_name_parses_level_and_species() -> None:
|
|
|
97
101
|
assert cryo.species == "Argentavis"
|
|
98
102
|
|
|
99
103
|
|
|
104
|
+
class FakeObject:
|
|
105
|
+
"""Minimal GameObject stand-in for exporter graph tests."""
|
|
106
|
+
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
obj_id: int,
|
|
110
|
+
class_name: str,
|
|
111
|
+
props: dict[str, t.Any] | None = None,
|
|
112
|
+
location: LocationData | None = None,
|
|
113
|
+
is_item: bool = False,
|
|
114
|
+
) -> None:
|
|
115
|
+
self.id = obj_id
|
|
116
|
+
self.guid = ""
|
|
117
|
+
self.names: list[str] = []
|
|
118
|
+
self.class_name = class_name
|
|
119
|
+
self.location = location
|
|
120
|
+
self.is_item = is_item
|
|
121
|
+
self.properties: list[t.Any] = []
|
|
122
|
+
self.components: dict[str, t.Any] = {}
|
|
123
|
+
self.props = props or {}
|
|
124
|
+
|
|
125
|
+
def get_property_value(self, name: str, default: t.Any = None, index: int | None = None) -> t.Any:
|
|
126
|
+
key = name if not index else f"{name}_{index}"
|
|
127
|
+
val = self.props.get(key)
|
|
128
|
+
return default if val is None else val
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class FakeSave:
|
|
132
|
+
"""Save stand-in exposing just what export_tamed needs."""
|
|
133
|
+
|
|
134
|
+
is_asa = True
|
|
135
|
+
|
|
136
|
+
def __init__(self, objects: list[FakeObject], cryos: list[tuple[FakeObject, CryopodCreature]]) -> None:
|
|
137
|
+
self.objects = objects
|
|
138
|
+
self.cryos = cryos
|
|
139
|
+
|
|
140
|
+
def get_tamed_creatures(self) -> list[FakeObject]:
|
|
141
|
+
return []
|
|
142
|
+
|
|
143
|
+
def iter_cryopod_creatures(self) -> t.Iterator[tuple[FakeObject, CryopodCreature]]:
|
|
144
|
+
yield from self.cryos
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_cryopod_inherits_owning_container_location() -> None:
|
|
148
|
+
"""ASA cryopod items live in inventories, not the world: they carry no
|
|
149
|
+
actor transform, so ``item_obj.location`` is None. The exported record
|
|
150
|
+
must fall back to the owning container's (cryofridge / pawn) location
|
|
151
|
+
instead of emitting 0/0/0."""
|
|
152
|
+
fridge = FakeObject(
|
|
153
|
+
10,
|
|
154
|
+
"CryoFridge_C",
|
|
155
|
+
props={
|
|
156
|
+
"MyInventoryComponent": (None, 11),
|
|
157
|
+
"TargetingTeam": 1500000001,
|
|
158
|
+
"TribeName": "Frisky Dingo",
|
|
159
|
+
},
|
|
160
|
+
location=LocationData(x=10000.0, y=-20000.0, z=300.0),
|
|
161
|
+
)
|
|
162
|
+
inventory = FakeObject(11, "PrimalInventoryBP_C", props={"InventoryItems": [(None, 12)]})
|
|
163
|
+
pod = FakeObject(12, "PrimalItem_WeaponEmptyCryopod_C", is_item=True)
|
|
164
|
+
cryo = CryopodCreature.from_asa_cryopod_data(_asa_blob([0.0] * 11, [0.0] * 11))
|
|
165
|
+
assert cryo is not None
|
|
166
|
+
save = FakeSave([fridge, inventory, pod], [(pod, cryo)])
|
|
167
|
+
|
|
168
|
+
records = export_tamed(save, None)
|
|
169
|
+
assert len(records) == 1
|
|
170
|
+
record = records[0]
|
|
171
|
+
assert record["cryo"] is True
|
|
172
|
+
assert record["tribe"] == "Frisky Dingo"
|
|
173
|
+
assert record["ccc"] == "10000.0 -20000.0 300.0"
|
|
174
|
+
|
|
175
|
+
|
|
100
176
|
def test_ase_cryopod_keeps_twelve_stat_layout() -> None:
|
|
101
177
|
"""ASE cryopod blobs carry 12 current stats + 12 max stats (25 floats).
|
|
102
178
|
The ASA fix must not break the ASE path: walking all 12 names is the
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|