def __init__(self, owner): # Ptr - player pointer super(Color, self).__init__() self.ptr = owner.ptr # ptr must be ptr to a player Should be unchanged self.owner = owner self.unique = pm.int32(pm.pointer(owner.ptr + 0x100) + 0x8) self.color_address = pm.pointer(owner.ptr + 0xFC) self.in_game = pm.int32(self.color_address + 0x8) self.color = self.in_game
def __init__(self, ptr, owner, udata): # ptr - pointer to the object # owner - Player datastructure who has this unit # udata - metadata, see `aoc_object_data.py` super(Primitive, self).__init__() self.ptr = ptr self.owner = owner self.udata = udata # Load data self.id = pm.int32(ptr + 0x8) # Game ID keeps unchanged, no need for update self.hp = pm.float(ptr + 0x34) self.selected = pm.int8(ptr + 0x3a) self.status = pm.int8(ptr + 0x4C) # Load consts self.idle = False self.idle_time = 0 self.idle_total_time = 0 self.busy_time = 0 self.busy_total_time = 0 self.garrison = [] self.research = None self.training = None self.position = None self.prev_hp = None self.queue = None self.construction = None self.group = 0 self.created_time = GTime.time self.resource_amount = 0 self.resource_type = ""
def __init__(self, ptr, owner): super(UnitData, self).__init__() # Save the address self.ptr = ptr self.owner = owner # constants self.__name = None self.name_id = pm.int32(ptr + 0x8) self.icon = pm.int16(ptr + 0x54) self.max_hp = pm.int16(ptr + 0x2a) self.max_garrison = pm.int16(ptr + 0x30) # pointers self.id = pm.int16(ptr + 0x12) self.class_ = pm.int16(ptr + 0x16) self.superclass = pm.int16(ptr + 0x4) # But superclass is different for trebuchet in this script for reasons... if self.class_ in ClassData.trebuchets: self.superclass = SuperclassData.combatant self.armor = Armor(self) self.attack = Attack(self) self.costs = Costs(self) self.speed = 0.0 self.train_time = 0 if self.superclass in [ SuperclassData.building, SuperclassData.combatant ]: self.speed = pm.float(ptr + 0xe8) self.train_time = pm.int16(ptr + 0x19e)
def _create_(ptr_object, owner): """Creates an element of the list. """ # Checks if the pointer is correct OR the object is deleted if ptr_object == 0 or pm.int16(ptr_object + 10) == -1: return None # Load new data try: ptr = pm.uint32(ptr_object + 0xC) udata = UnitData(pm.pointer(ptr_object + 0xC), owner) except: print( f"BEEP - Wrong address obj.udata = {hex(ptr)} (For object: {hex(ptr_object)} Object ID: {(pm.int16(ptr_object+10))})" ) return None if udata is None: return None if ptr_object in Objects._all[owner]: Objects._all[owner][ptr_object][1] = False Objects._all[owner][ptr_object][0].udata = udata # Sometimes it might create a new object with the same address!! if pm.int32(ptr_object + 0x8) == Objects._all[owner][ptr_object][0].id: return Objects._all[owner][ptr_object][0] if udata.superclass == SuperclassData.building: return Building(ptr_object, owner, udata) elif udata.superclass == SuperclassData.combatant: return Unit(ptr_object, owner, udata) else: return Primitive(ptr_object, owner, udata)
def update(self): """ Fills the players list""" self.up = True ptr = pm.pointer(pm.base_address + 0x6Da30C) ptr = pm.pointer(ptr + 0xD54) for i in range(Lobby.SKIP_GAIA, 9): p = ptr + 0x50 + 0x60 * i number = pm.int32(p + 0x48) # Get player number if number == -1: # A resets it self.players[i] = LobbyPlayer() else: # Update player's stuff player = self.players[i] player.number = number player.team = pm.int32(p + 0x0) player.color = pm.int32(p + 0x44) player.ai = False if player.name else True player.name = pm.byte_string( pm.pointer(p + 0xC)) if i > 0 else b"Gaia"
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
def __init__(self, owner): super(Research, self).__init__() self.owner = owner ptr = pm.pointer(owner.ptr + 0x1ae8) self.ptr_times = pm.pointer(ptr) # struct size: 0x10 self.length = pm.int32(ptr + 0x4) self.ptr_researches = pm.pointer(pm.pointer(ptr + 0x8)) # struct size: 0x54 self.id_list = [] self.dictionary = {} self.progression = [] self.done = []
def update(self): # Check if the game is running pm.update() if not pm.int32(pm.base_address + 0x9C8FB0): self.running = False return False # Second check. try: ptr = pm.pointer(pm.base_address + 0x006E62D8) 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
def __new__(cls): if not pm.int32(pm.base_address + 0x9C8FB0): 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 __get_name__(number, ptr_ai): """ Get players name, if AI grabs """ ptr = pm.pointer(pm.base_address + 0x6Da30C) ptr = pm.pointer(ptr + 0xD54) ptr = pm.pointer(ptr + 0xb0 + 0x60 * (number - 1) + 0xC) try: name = pm.string(ptr, 32) except: name = "" name = name if name else f"Player #{number}" if pm.int32(ptr_ai + 0x8) == 3: name += " [AI]" return name
def update(self): """ Fills the players list""" self.up = True ptr = pm.pointer(pm.base_address + 0x006EEFB4) ptr = pm.pointer(ptr + 0x0) ptr = pm.pointer(ptr + 0x60) ptr = pm.pointer(ptr + 0xCE4) if not ptr: # ptr is null if not in the lobby return False self.victory = Lobby.VICTORY_OPTIONS[pm.int32(ptr + 0x50)] self.victory_time_or_score = pm.int32(ptr + 0x54) # Time is in years! self.map_size = Lobby.MAP_SIZE_OPTIONS[pm.int32(ptr + 0x90)] self.reveal_map = Lobby.REVEAL_MAP_OPTIONS[pm.int32(ptr + 0x9c)] self.resources = Lobby.RESOURCES_OPTIONS[pm.int32(ptr + 0xa0)] self.starting_age = Lobby.STARTING_AGE_OPTIONS[pm.int32(ptr + 0xa4)] self.ending_age = Lobby.STARTING_AGE_OPTIONS[pm.int32(ptr + 0xa8)] self.game_speed = pm.float(ptr + 0x3b4 + 8 * 8) self.treaty_length = pm.int32(ptr + 0x3b8 + 8 * 8) self.population_limit = pm.int32(ptr + 0x3bC + 8 * 8) for i in range(Lobby.SKIP_GAIA, 9): p = ptr + 0x48 + 0x68 * i number = pm.int32(p + 0x50) # Get player number if number == -1: # A resets it self.players[i] = LobbyPlayer() else: # Update player's stuff player = self.players[i] player.number = number player.team = pm.int32(p + 0x0) player.deathmatch_rating = pm.int32(p + 0x44) player.rating = pm.int32(p + 0x48) player.color = pm.int32(p + 0x4C) player.name = pm.byte_string( pm.pointer(p + 0xC)) if i > 0 else b"Gaia" player.ai = False if player.name and player.name is not "Gaia" else True player.civ = None self.teams_together = not bool(pm.int8(ptr + 0x3c2 + 8 * 8)) self.all_techs = bool(pm.int8(ptr + 0x3c3 + 8 * 8)) self.lock_teams = bool(pm.int8(ptr + 0x3c5 + 8 * 8)) self.lock_speed = bool(pm.int8(ptr + 0x3c6 + 8 * 8)) self.record_game = bool(pm.int8(ptr + 0x3cc + 8 * 8)) self.allow_cheats = bool(pm.int8(ptr + 0x3cf + 8 * 8)) return True
def update(self): tmp = pm.pointer(self.ptr + 0xFC) if tmp != self.color_address: j = str(self) self.in_game = pm.int32(tmp + 0x8) self.color_address = tmp