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, 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 __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 _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 __init__(self, owner): # ptr - pointer to a player ptr_civ_name = pm.pointer(owner.ptr + 0x1AE0) self.owner = owner self.name = pm.string(ptr_civ_name + 4) self.code = Civilization.strings.index(self.name) self.icon = Civilization.icons[self.code]
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 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 __init__(self, udata): super(Armor, self).__init__() cnt = pm.int16(udata.ptr + 0x142) self.displayed = pm.int16(udata.ptr + 0x17C) self.displayed_pierce = pm.int16(udata.ptr + 0x1A4) if cnt != 0: ptr = pm.pointer(udata.ptr + 0x144) big_struct = pm.struct(ptr, "hh" * cnt) iterator = iter(big_struct) self.extend(zip(iterator, iterator))
def __init__(self): super(Game, self).__init__() ptr = pm.pointer(pm.base_address + 0x006E62D8) 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.player = None self.pov = None self.running = False
def create(self): self.length = pm.int16(self.building.ptr + 0x21c) try: ptr = pm.pointer(self.building.ptr + 0x214) except NullAddress: return None while len(self) < self.length: uid, units_amount = pm.struct(ptr, "hh") for i in range(units_amount): try: ptr_icon = self.building.owner.ptr ptr_icon = pm.pointer(ptr_icon + 0x14) ptr_icon = pm.pointer(ptr_icon + 0x4 * uid) icon = pm.int16(ptr_icon + 0x54) except NullAddress: return None self.append((uid, icon)) ptr += 4 return self
def __init__(self, udata): super(Attack, self).__init__() self.range = pm.float(udata.ptr + 0x154) self.reload_time = pm.float(udata.ptr + 0x160) self.accurancy = pm.int16(udata.ptr + 0x166) self.displayed = pm.int16(udata.ptr + 0x17e) cnt = pm.int16(udata.ptr + 0x148) if cnt != 0: ptr = pm.pointer(udata.ptr + 0x14c) big_struct = pm.struct(ptr, "hh" * cnt) iterator = iter(big_struct) self.extend(zip(iterator, iterator))
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.player = None self.pov = None self.running = False
def create(self): try: # load id and time ptr = pm.pointer(self.building.ptr + 0x220) ptr = pm.pointer(ptr + 0x8) ptr = pm.pointer(ptr) self.id = pm.int16(ptr + 0x40) if self.id > 1402: return None time = pm.float(ptr + 0x44) # Load icon and total time ptr = self.building.owner.ptr ptr = pm.pointer(ptr + 0x14) ptr = pm.pointer(ptr + 0x4 * self.id) except NullAddress: return None self.icon = pm.int16(ptr + 0x54) self.total_time = pm.int16(ptr + 0x19e) self.time = 1 if isnan(time) else time self.cooldown = int(self.total_time - self.time) return self
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 _check_garrison_(self): garrison = [] if not self.udata.max_garrison: return garrison try: ptr = pm.pointer(self.ptr + 0x28) ptr, cnt = pm.struct(ptr, "II") if not ptr: return garrison arr = pm.struct(ptr, "I"*cnt) for ptr in arr: udata = UnitData(pm.pointer(ptr + 0xC), self.owner) """ if r is not None: return garrison if udata and udata.superclass == SuperclassData.combatant: # << checks recursion garrison.append(Unit(ptr, self.owner, udata)) # trebuchet shouldnt bug this """ garrison.append(Unit(ptr, self.owner, udata)) # trebuchet shouldnt bug this except NullAddress: return garrison self.garrison.clear() self.garrison.extend(garrison)
def __init__(self, ptr, number=None): super(Player, self).__init__() self.ptr = ptr self.name = "Gaia" if number is None else Player.__get_name__( number, ptr) self.pov = False self.diplomacy = Diplomacy(self) self.resources = Resources(self) self.color = Color(self) self.civ = Civilization(self) self.research = Research(self) #self.map = Map(ptr) self.objects = Objects(pm.pointer(ptr + 0x18), self) self.log = [] #BuildingResearch.log[self] = [] # Better access for researches Objects._all[self] = {} # Dictionary of used objects self.housed = False self.farm_reseeds = 0 self.selected = None
def update(self): """Creates a list of objects.""" self.clear() # sucks but ok ptr_array = pm.pointer(self.ptr + 0x4) length = pm.uint32(self.ptr + 0x8) object_pointers = pm.struct(ptr_array, "I" * length) length = pm.int8(self.owner.ptr + 0x254) Objects.selected_pointers += pm.struct(self.owner.ptr + 0x160, "I" * length) for ptr in object_pointers: r = Objects._create_(ptr, self.owner) if r is not None: r.update() self.append(r) # Appends the object to the list and sets that the object will not be deleted Objects._all[self.owner][ptr] = [r, False] # adds it into selected objects if ptr in Objects.selected_pointers: Objects.selected.append(r)
def _check_idle_(self): ## Checking if unit is idle need to write better way # Load pointer try: pointer = pm.pointer(self.ptr + 0x14) except NullAddress: print("WARNING aoc_object_unit.py in `_check_idle_(self)`: NULL pointer!") self.idle = False return if pointer in Unit.graphics_data: # Is it in look-up table? self.idle = Unit.graphics_data[pointer] else: # Load it inot the lookup table try: splitted_name = pm.string(pointer+0x50).split("_") result = len(splitted_name) > 1 and "FN" in splitted_name[-1] # idle through graphics.. suuucks Unit.graphics_data[pointer] = result self.idle = result except UnicodeDecodeError: print("WARNING aoc_object_unit.py in `_check_idle_(self)`: Couldn't parse SLP filename!") self.idle = False
def create(self): # some kind of constructor.. returns None if none research try: ptr = pm.pointer(self.building.ptr + 0x1f0) ptr = pm.pointer(ptr + 0x8) ptr = pm.pointer(ptr) self.id = pm.int16(ptr + 0x40) if self.id > 800: return None ptr = pm.pointer(self.building.owner.ptr + 0x1ae8) time = pm.float(pm.pointer(ptr) + 16 * self.id) ptr = pm.pointer(pm.pointer(ptr + 8)) except NullAddress: return None self.building.owner.research.add(self.id) self.total_time = pm.int16(ptr + 0x54 * self.id + 0x26) self.icon = pm.int16(ptr + 0x54 * self.id + 0x2C) self.time = self.total_time if isnan(time) else time # NaN occurs in the end of the research self.cooldown = int(self.total_time - self.time) # if ptr not in BuildingResearch.log[self.building.owner]: # BuildingResearch.log[self.building.owner].append(self) return self
def __init__(self, owner): super(Resources, self).__init__() self.owner = owner self.ptr = pm.pointer(owner.ptr + 0x3c) # Pointer should be unchanged self.keys = Resources.keys self.values = pm.struct(self.ptr, Resources.fmt)
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