Closed imkindaprogrammermyself closed 4 years ago
Unfortunately, that code was removed right after gif was created (that was just a matplotlib graph rendered as .png for each position change + ffmpeg to combine all that png into single .gif).
There is an example of WOT replays player in project sources and you can handle entity position change here: https://github.com/Monstrofil/replays_unpack/blob/master/examples/wot_parser/player.py#L112
You can do same parser for wows using wot example as reference (recomended way), or just fork this project and handle position change here: https://github.com/Monstrofil/replays_unpack/blob/master/replay_unpack/clients/wows/player.py#L102
Alright, I managed to add player position to the dump. Anyway, what's the maximum x and z on a map?
Depends on map. Map consists of chunks, each is 0..100x0..100, so if I remember correctly, you can calculate it as sqrt(number of *.chunk files in spaces/SPACE_NAME) * 100
.
Oh, I found something:
settings_path = os.path.join(self.__spaces_path, space_name, 'space.settings')
with open(settings_path, 'rb') as f:
tree = etree.parse(f)
space_bounds, = tree.xpath('/space.settings/bounds')
if space_bounds.attrib:
minX = int(space_bounds.get('minX'))
minY = int(space_bounds.get('minY'))
maxX = int(space_bounds.get('maxX'))
maxY = int(space_bounds.get('maxY'))
else:
minX = int(space_bounds.xpath('minX/text()')[0])
minY = int(space_bounds.xpath('minY/text()')[0])
maxX = int(space_bounds.xpath('maxX/text()')[0])
maxY = int(space_bounds.xpath('maxY/text()')[0])
chunk_size_elements = tree.xpath('/space.settings/chunkSize')
if chunk_size_elements:
chunk_size = float(chunk_size_elements[0].text)
else:
chunk_size = 100.0
return dict(
spaceSizeX=len(xrange(minX, maxX + 1)) * chunk_size,
spaceSizeY=len(xrange(minY, maxY + 1)) * chunk_size,
mapSizeX=len(xrange(minX, maxX + 1)) * chunk_size - 4 * chunk_size,
mapSizeY=len(xrange(minY, maxY + 1)) * chunk_size - 4 * chunk_size
)```
mapSizeX=len(xrange(minX, maxX + 1)) * chunk_size - 4 * chunk_size,
mapSizeY=len(xrange(minY, maxY + 1)) * chunk_size - 4 * chunk_size
This strange math ^^ needed because wows uses extra chunk each side "outside" the world.
I added this code inside the BattleController
class that will be called if a Position
packet is processed
def process_position(self, entity_id: int):
ent = self._entities[entity_id]
client = ent.properties["client"]
owner = client["owner"]
if owner not in self._movements:
self._movements[client["owner"]] = [(ent.position.x, ent.position.y, ent.position.z)]
else:
self._movements[client["owner"]].append((ent.position.x, ent.position.y, ent.position.z))
I noticed self._movements
length is only 23 after all the packets are processed. The player/owner of the replay isn't included in that list.
I guess this PR may help: https://github.com/Monstrofil/replays_unpack/pull/1 https://github.com/Monstrofil/replays_unpack/pull/1/files#diff-ffa52a5cbf1afd02ee7ae0d63f281ccb
It has a strange logic of linking positions between two entities and I had no time to investigate why and how it works:
if packet.data.entityId2 != (0,):
# This is a link packet
self._bigworld.entities[packet.data.entityId1[0]].position = self._bigworld.entities[packet.data.entityId2[0]].position
elif packet.data.entityId1 != (0,) and packet.data.entityId2 == (0,):
self._bigworld.entities[packet.data.entityId1[0]].position = packet.data.position
self._bigworld.entities[packet.data.entityId1[0]].rotation = packet.data.rotation
The logic of linking position is because you may continue view the game after your ship is sunk. So that game keep sync ship position from ship to player. When you have been sunk and start watching your team mates, it sync position from the ship you are watching.
So @Monstrofil what's the status of integrating that pull request? Or possibly getting a PR made for the player packet code made by @m-freiberg in his Fork since PR #1 is a few years old, but I see that the wows example folder is missing over there. The existing PR does remove a bunch of code for old versions as well, I don't know if that is a cause for hesitation or not? I don't know if there's a suitable workaround in the meantime or not (I haven't found one yet?), but I feel like the player position is relatively important.
@KeithDeRuiter well, I think I can add PlayerPosition support quite fast, it is not implemented just because DeckerCHAN and imkindaprogrammermyself were the only persons who asked about that in a years and I don't need that because my primary parser usage is battle statistics report for https://replayswows.com/.
Kinda same situation with Camera position/direction data... I know where to get it, but don't need that information for my purposes.
Open another issue pls, I'll try to find some time to make couple commits.
Can you add the code for the animated gif as an example?