This repository has been archived by the owner on Jun 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
aoc_game.py
141 lines (124 loc) · 4.8 KB
/
aoc_game.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" aoc_game.py: parsing aoc game data which are common to all players """
from aoc_object_data import UnitData
from aoc_object_unit import Unit
from aoc_objects import Objects
from aoc_player import *
from aoc_time import GTime
from pymemory import NullAddress
# debug
# from pymemory import print_addr
class Game(object):
"""
Attributes
public
Players
gaia Gaia Player
players List of Player
pov Player of View (PoV)
player PoV
Teams
teams List of teamss
t1 Allies to PoV
t2 Enemies to PoV
Game
screen_position Position in format [float, float]
speed Game speed
running Boolean
Methods:
public
__init__() Constructor
update Get the next iteration of game
private
__get_teams__() Creates teams from diplomacy in the beggining of the game. Called in constructor
__update_teams__() Creates teams DURING the game. Called in `update` method
"""
def __get_teams__(self):
teams = {} # magic
for diplo, value in map(lambda p: (p.diplomacy, p), self.players):
key = map(lambda x: str(x == 4), diplo)
teams.setdefault("".join(key), []).append(value)
return list(teams.values())
def __new__(cls):
# Check if the game is running.
if not pm.int32(pm.base_address + 0x9E0708):
return None
# Stupid way how to reset all CLASS variables (not object)
UnitData.all_names = None
Unit.graphics_data = {}
Objects._all = {}
Objects.selected = []
Objects.selected_pointers = []
GTime.time_delta = 0
GTime.time = 0
return super(Game, cls).__new__(cls)
def __init__(self):
super(Game, self).__init__()
ptr = pm.pointer(
pm.base_address + 0x006FDA30) # three offsets are avaliable here: 006DC7F8, 006DDCA0, 006FDA30 each should point to the same address.. if not remove one You need to check for each address in record game.
ptr_players = pm.pointer(ptr + 0x184)
# Get gaia firstly and calculate total players
self.gaia = Player(pm.pointer(ptr_players))
total_players = len(self.gaia.diplomacy) - 1 # Gaia is considered as player too
# Get the rest of players
self.players = [Player(pm.pointer(ptr_players + i * 0x8), i) for i in range(1, total_players + 1)]
self.teams = self.__get_teams__()
self.t1 = []
self.t2 = []
self.screen_position = None
self.speed = None
self.player = None
self.pov = None
self.running = False
def __update_teams__(self):
self.t1 = []
self.t2 = []
for t in self.teams:
if self.pov in t:
self.t1 += t
else:
self.t2 += t
def update(self):
# Check if the game is running: 0 not running, 1 running
pm.update()
if not pm.int32(pm.base_address + 0x9E0708):
self.running = False
return False
# Second check.
try:
ptr = pm.pointer(
pm.base_address + 0x006FDA30) # three offsets are avaliable here: 006DC7F8, 006DDCA0, 006FDA30 each should point to the same address.. if not remove one You need to check for each address in record game.
pm.pointer(ptr + 0x184)
except NullAddress:
self.running = False
return False
# Third check. Time
if pm.int32(ptr + 0x68) <= 0:
return False
self.running = True
# And get the common stuff
GTime.set(pm.int32(ptr + 0x68))
self.screen_position = pm.struct(ptr + 0xD8, "ff")
self.speed = pm.float(ptr + 0x16C)
self.pov = self.players[pm.int8(ptr + 0x174) - 1] # Must be -1
if self.pov != self.player:
if self.player is not None:
self.player.pov = False
self.player = self.pov # Set the new pov
self.player.pov = True
self.__update_teams__()
market_price = pm.struct(ptr + 0x238, "fff") # Wood, food, stone coeficient see spirit of the law - markets
Objects.selected.clear()
Objects.selected_pointers.clear()
# Update all players data
for player in self.players:
player.update(market_price)
self.gaia.update(market_price)
return True
if __name__ == '__main__':
proc_name = "AoK HD.exe"
pm.load_process(proc_name)
game = Game()
if game is not None:
t = game.update()