def load(self, db): data = db("SELECT value FROM last_active_settlement WHERE type = \"PLAYER\"") self._last_player_settlement = weakref.ref(WorldObject.get_object_by_id(data[0][0])) if data else None data = db("SELECT value FROM last_active_settlement WHERE type = \"ANY\"") self._last_settlement = weakref.ref(WorldObject.get_object_by_id(data[0][0])) if data else None data = db("SELECT value FROM last_active_settlement WHERE type = \"LAST_NONE_FLAG\"") self._last_player_settlement_hovered_was_none = bool(data[0][0])
def __init__(self, db, rng_seed=None): """ Unfortunately, right now there is no other way to setup Dummy versions of the GUI, View etc., unless we want to patch the references in the session module. """ super(LivingObject, self).__init__() self.gui = Dummy() self.db = db self.savecounter = 0 # this is a new game. self.is_alive = True WorldObject.reset() NamedObject.reset() AIPlayer.clear_caches() # Game self.current_tick = 0 self.random = self.create_rng(rng_seed) self.timer = self.create_timer() Scheduler.create_instance(self.timer) ExtScheduler.create_instance(Dummy) self.manager = self.create_manager() self.view = Dummy() self.view.renderer = Dummy() Entities.load(self.db) self.scenario_eventhandler = Dummy() self.campaign = {} self.selected_instances = [] # GUI self.gui.session = self self.ingame_gui = Dummy() GAME_SPEED.TICKS_PER_SECOND = 16
def __init__(self, gui, db): super(Session, self).__init__() self.log.debug("Initing session") self.gui = gui # main gui, not ingame gui self.db = db # main db for game data (game.sqlite) # this saves how often the current game has been saved self.savecounter = 0 self.is_alive = True WorldObject.reset() NamedObject.reset() #game self.random = self.create_rng() self.timer = Timer() Scheduler.create_instance(self.timer) self.manager = self.create_manager() self.view = View(self, (15, 15)) Entities.load(self.db) self.scenario_eventhandler = ScenarioEventHandler(self) # dummy handler with no events self.campaign = {} #GUI self.gui.session = self self.ingame_gui = IngameGui(self, self.gui) self.keylistener = IngameKeyListener(self) self.display_speed() self.selected_instances = set() self.selection_groups = [set()] * 10 # List of sets that holds the player assigned unit groups.
def _load(self, db, worldid, success_callback, failure_callback): db_result = db( "SELECT settlement_manager, settlement, ship, bought_resource, sold_resource, state FROM ai_mission_international_trade WHERE rowid = ?", worldid, )[0] self.settlement_manager = WorldObject.get_object_by_id(db_result[0]) self.settlement = WorldObject.get_object_by_id(db_result[1]) self.bought_resource = db_result[3] self.sold_resource = db_result[4] self.state = self.missionStates[db_result[5]] super(InternationalTrade, self).load( db, worldid, success_callback, failure_callback, WorldObject.get_object_by_id(db_result[2]) ) if self.state is self.missionStates.moving_to_my_settlement: self.ship.add_move_callback(Callback(self._reached_my_settlement)) self.ship.add_blocked_callback(Callback(self._move_to_my_settlement)) elif self.state is self.missionStates.moving_to_other_settlement: self.ship.add_move_callback(Callback(self._reached_other_settlement)) self.ship.add_blocked_callback(Callback(self._move_to_other_settlement)) elif self.state is self.missionStates.returning_to_my_settlement: self.ship.add_move_callback(Callback(self._returned_to_my_settlement)) self.ship.add_blocked_callback(Callback(self._return_to_my_settlement)) else: assert False, "invalid state"
def one_dead(wid1, wid2): for wid in (wid1, wid2): at_least_one_dead = False try: WorldObject.get_object_by_id(wid) except WorldObjectNotFound: at_least_one_dead = True return at_least_one_dead
def cleanup(cls): """ If a test uses manual session management, we cannot be sure that session.end was called before a crash, leaving the game in an unclean state. This method should return the game to a valid state. """ Scheduler.destroy_instance() ExtScheduler.destroy_instance() WorldObject.reset()
def load(self, savegame, players, is_scenario=False, campaign={}): """Loads a map. @param savegame: path to the savegame database. @param players: iterable of dictionaries containing id, name, color and local @param is_scenario: Bool whether the loaded map is a scenario or not """ if is_scenario: # savegame is a yaml file, that contains reference to actual map file self.scenario_eventhandler = ScenarioEventHandler(self, savegame) savegame = os.path.join(SavegameManager.maps_dir, \ self.scenario_eventhandler.get_map_file()) self.campaign = campaign self.log.debug("Session: Loading from %s", savegame) savegame_db = SavegameAccessor(savegame) # Initialize new dbreader try: # load how often the game has been saved (used to know the difference between # a loaded and a new game) self.savecounter = SavegameManager.get_metadata(savegame)['savecounter'] except KeyError: self.savecounter = 0 self.world = World(self) # Load horizons.world module (check horizons/world/__init__.py) self.world._init(savegame_db) self.view.load(savegame_db) # load view if not self.is_game_loaded(): # NOTE: this must be sorted before iteration, cause there is no defined order for # iterating a dict, and it must happen in the same order for mp games. for i in sorted(players): self.world.setup_player(i['id'], i['name'], i['color'], i['local']) center = self.world.init_new_world() self.view.center(center[0], center[1]) else: # try to load scenario data self.scenario_eventhandler.load(savegame_db) self.manager.load(savegame_db) # load the manager (there might me old scheduled ticks). self.ingame_gui.load(savegame_db) # load the old gui positions and stuff for instance_id in savegame_db("SELECT id FROM selected WHERE `group` IS NULL"): # Set old selected instance obj = WorldObject.get_object_by_id(instance_id[0]) self.selected_instances.add(obj) obj.select() for group in xrange(len(self.selection_groups)): # load user defined unit groups for instance_id in savegame_db("SELECT id FROM selected WHERE `group` = ?", group): self.selection_groups[group].add(WorldObject.get_object_by_id(instance_id[0])) # cursor has to be inited last, else player interacts with a not inited world with it. self.cursor = SelectionTool(self) self.cursor.apply_select() # Set cursor correctly, menus might need to be opened. assert hasattr(self.world, "player"), 'Error: there is no human player' """
def _load(self, db, worldid, success_callback, failure_callback): db_result = db("SELECT land_manager, ship, warehouse_builder, state FROM ai_mission_found_settlement WHERE rowid = ?", worldid)[0] self.land_manager = WorldObject.get_object_by_id(db_result[0]) self.warehouse_location = Builder.load(db, db_result[2], self.land_manager) self.warehouse = None self.state = self.missionStates[db_result[3]] super(FoundSettlement, self).load(db, worldid, success_callback, failure_callback, WorldObject.get_object_by_id(db_result[1])) if self.state == self.missionStates.moving: self.ship.add_move_callback(Callback(self._reached_destination_area)) self.ship.add_blocked_callback(Callback(self._move_to_destination_area)) else: assert False, 'invalid state'
def load_location(self, db, worldid): """ Does not alter self, just gets island and settlement from a savegame. @return: tuple: (island, settlement) """ location_obj = WorldObject.get_object_by_id(db.get_building_location(worldid)) if isinstance(location_obj, Settlement): # workaround: island can't be fetched from world, because it isn't fully constructed island = WorldObject.get_object_by_id(db.get_settlement_island(location_obj.worldid)) settlement = location_obj else: # loc is island island = location_obj settlement = None return (island, settlement)
def _load(self, db, worldid, success_callback, failure_callback): db_result = db("SELECT settlement_manager, ship, feeder_island, state FROM ai_mission_prepare_foundation_ship WHERE rowid = ?", worldid)[0] self.settlement_manager = WorldObject.get_object_by_id(db_result[0]) self.branch_office = self.settlement_manager.settlement.branch_office self.feeder_island = db_result[2] self.state = self.missionStates[db_result[3]] super(PrepareFoundationShip, self).load(db, worldid, success_callback, failure_callback, \ WorldObject.get_object_by_id(db_result[1])) if self.state == self.missionStates.moving: self.ship.add_move_callback(Callback(self._reached_bo_area)) self.ship.add_blocked_callback(Callback(self._move_to_bo_area)) else: assert False, 'invalid state'
def _load(self, db, worldid, success_callback, failure_callback): db_result = db("SELECT source_settlement_manager, destination_settlement_manager, ship, state FROM ai_mission_domestic_trade WHERE rowid = ?", worldid)[0] self.source_settlement_manager = WorldObject.get_object_by_id(db_result[0]) self.destination_settlement_manager = WorldObject.get_object_by_id(db_result[1]) self.state = self.missionStates[db_result[3]] super(DomesticTrade, self).load(db, worldid, success_callback, failure_callback, WorldObject.get_object_by_id(db_result[2])) if self.state == self.missionStates.moving_to_source_bo: self.ship.add_move_callback(Callback(self._reached_source_bo_area)) self.ship.add_blocked_callback(Callback(self._move_to_source_bo_area)) elif self.state == self.missionStates.moving_to_destination_bo: self.ship.add_move_callback(Callback(self._reached_destination_bo_area)) self.ship.add_blocked_callback(Callback(self._move_to_destination_bo_area)) else: assert False, 'invalid state'
def load(self, db): enabled, self.current_waypoint, self.wait_at_load, self.wait_at_unload = \ db("SELECT enabled, current_waypoint, wait_at_load, wait_at_unload " + \ "FROM ship_route WHERE ship_id = ?", self.ship.worldid)[0] query = "SELECT warehouse_id FROM ship_route_waypoint WHERE ship_id = ? ORDER BY waypoint_index" offices_id = db(query, self.ship.worldid) for office_id, in offices_id: warehouse = WorldObject.get_object_by_id(office_id) query = "SELECT res, amount FROM ship_route_resources WHERE ship_id = ? and waypoint_index = ?" resource_list = dict(db(query, self.ship.worldid, len(self.waypoints))) self.waypoints.append({ 'warehouse' : warehouse, 'resource_list' : resource_list }) waiting = False for res, amount in db("SELECT res, amount FROM ship_route_current_transfer WHERE ship_id = ?", self.ship.worldid): waiting = True self.current_transfer[res] = amount Scheduler().add_new_object(self.on_route_warehouse_reached, self, GAME_SPEED.TICKS_PER_SECOND) if enabled and not waiting: self.current_waypoint -= 1 self.enable()
def mousePressed(self, evt): if evt.isConsumedByWidgets(): super(SelectionTool, self).mousePressed(evt) return elif evt.getButton() == fife.MouseEvent.LEFT: selectable = [] instances = self.session.view.cam.getMatchingInstances(\ fife.ScreenPoint(evt.getX(), evt.getY()), self.session.view.layers[LAYERS.OBJECTS]) for i in instances: instance = WorldObject.get_object_by_id(int(i.getId())) if hasattr(instance, 'select'): selectable.append(instance) if len(selectable) > 1: selectable = selectable[0:0] self.select_old = frozenset(self.session.selected_instances) if evt.isControlPressed() else frozenset() selectable = set(self.select_old ^ frozenset(selectable)) for instance in self.session.selected_instances - selectable: instance.deselect() for instance in selectable - self.session.selected_instances: instance.select() self.session.selected_instances = selectable self.select_begin = (evt.getX(), evt.getY()) self.session.ingame_gui.hide_menu() elif evt.getButton() == fife.MouseEvent.RIGHT: target_mapcoord = self.session.view.cam.toMapCoordinates(\ fife.ScreenPoint(evt.getX(), evt.getY()), False) for i in self.session.selected_instances: if i.movable: Act(i, target_mapcoord.x, target_mapcoord.y).execute(self.session) else: super(SelectionTool, self).mousePressed(evt) return evt.consume()
def load_location(self, db, worldid): """ Does not alter self, just gets island and settlement from a savegame. @return: tuple: (island, settlement) """ location_obj = WorldObject.get_object_by_id(db.get_building_location(worldid)) if isinstance(location_obj, Settlement): # workaround: island can't be fetched from world, because it isn't fully constructed island = WorldObject.get_object_by_id(db.get_settlement_island(location_obj.worldid)) # settlement might not have been registered in island, so do it if getter fails settlement = island.get_settlement(self.position.center()) or \ island.add_existing_settlement(self.position, self.radius, location_obj) else: # loc is island island = location_obj settlement = None return (island, settlement)
def buy_resource(self, ship_worldid, resource_id, amount): """ Attempt to buy the given amount of resource from the ship, return the amount bought """ if resource_id not in self.buy_list: return 0 ship = WorldObject.get_object_by_id(ship_worldid) price = int(self.session.db.get_res_value(resource_id) * TRADER.PRICE_MODIFIER_SELL) # price per ton of resource assert price > 0 # can't buy more than the ship has amount = min(amount, ship.inventory[resource_id]) # can't buy more than we can fit in the inventory amount = min(amount, self.inventory.get_free_space_for(resource_id)) # can't buy more than we can afford amount = min(amount, self.owner.inventory[RES.GOLD_ID] // price) # can't buy more than we are trying to buy according to the settings amount = min(amount, self.buy_list[resource_id] - self.inventory[resource_id]) if amount <= 0: return 0 total_price = price * amount assert self.owner.inventory.alter(RES.GOLD_ID, -total_price) == 0 assert ship.owner.inventory.alter(RES.GOLD_ID, total_price) == 0 assert self.inventory.alter(resource_id, amount) == 0 assert ship.inventory.alter(resource_id, -amount) == 0 self.buy_history[Scheduler().cur_tick] = (resource_id, amount, total_price) self.total_expenses += total_price return amount
def sell_resource(self, ship_worldid, resource_id, amount): """ Attempt to sell the given amount of resource to the ship, returns the amount sold """ if resource_id not in self.sell_list: return 0 ship = WorldObject.get_object_by_id(ship_worldid) price = int(self.session.db.get_res_value(resource_id) * TRADER.PRICE_MODIFIER_BUY) # price per ton of resource assert price > 0 # can't sell more than what we have amount = min(amount, self.inventory[resource_id]) # can't sell more than the ship can fit in its inventory amount = min(amount, ship.inventory.get_free_space_for(resource_id)) # can't sell more than the ship's owner can afford amount = min(amount, ship.owner.inventory[RES.GOLD_ID] // price) # can't sell more than we are trying to sell according to the settings amount = min(amount, self.inventory[resource_id] - self.sell_list[resource_id]) if amount <= 0: return 0 total_price = price * amount assert self.owner.inventory.alter(RES.GOLD_ID, total_price) == 0 assert ship.owner.inventory.alter(RES.GOLD_ID, -total_price) == 0 assert self.inventory.alter(resource_id, -amount) == 0 assert ship.inventory.alter(resource_id, amount) == 0 self.sell_history[Scheduler().cur_tick] = (resource_id, amount, total_price) self.total_income += total_price return amount
def load_ship_states(self, db): # load ships one by one from db (ship instances themselves are loaded already, but # we have to use them here) for ship_id, state_id, remaining_ticks in db("SELECT rowid, state, remaining_ticks FROM pirate_ships"): state = self.shipStates[state_id] ship = WorldObject.get_object_by_id(ship_id) self.ships[ship] = state
def load(self, db, worldid): self.island, self.settlement = self.load_location(db, worldid) x, y, location, rotation, level = db.get_building_row(worldid) owner_id = db.get_settlement_owner(location) owner = None if owner_id is None else WorldObject.get_object_by_id(owner_id) # early init before super() call self.__pre_init(owner, rotation, Point(x, y), level=level) super(BasicBuilding, self).load(db, worldid) remaining_ticks_of_month = None if self.has_running_costs: db_data = db("SELECT ticks FROM remaining_ticks_of_month WHERE rowid=?", worldid) if len(db_data) == 0: # this can happen when running costs are set when there were no before # we shouldn't crash because of changes in yaml code, still it's suspicous print 'WARNING: object %s of type %s does not know when to pay its rent.' print 'Disregard this when loading old savegames or on running cost changes.' remaining_ticks_of_month = 1 else: remaining_ticks_of_month = db_data[0][0] self.__init(remaining_ticks_of_month=remaining_ticks_of_month) # island.add_building handles registration of building for island and settlement self.island.add_building(self, self.owner, load=True)
def load(cls, db, worldid, session): self = cls.__new__(cls) owner, tax = db("SELECT owner, tax_setting FROM settlement WHERE rowid = ?", worldid)[0] self.__init(session, WorldObject.get_object_by_id(owner), tax) # load super here cause basic stuff is just set up now super(Settlement, self).load(db, worldid) # load all buildings from this settlement # the buildings will expand the area of the settlement by adding everything, # that is in the radius of the building, to the settlement. from horizons.world import load_building for building_id, building_type in \ db("SELECT rowid, type FROM building WHERE location = ?", worldid): load_building(session, db, building_type, building_id) for res, amount in db("SELECT res, amount FROM settlement_produced_res WHERE settlement = ?", worldid): self.produced_res[res] = amount # load inventory after buildings, since buildings, specifically storages, determine # the size of the settlement's inventory self.inventory.load(db, worldid) return self
def load(self, db, worldid): super(FireDisaster, self).load(db, worldid) for building_id, ticks in db("SELECT building, remaining_ticks_havoc FROM fire_disaster WHERE disaster = ?", worldid): # do half of infect() building = WorldObject.get_object_by_id(building_id) self.log.debug("%s loading disaster %s", self, building) self.infect(building, load=(db, worldid))
def _get_source_settlement_manager(self): """Return the settlement manager of the settlement from which we should pick up resources next or None if none are needed.""" # TODO: find a better way of getting the following constants ship_capacity = 120 ship_resource_slots = 4 options = [] # [(available resource amount, available number of resources, settlement_manager_id), ...] for settlement_manager in self.owner.settlement_managers: if settlement_manager is self.settlement_manager: continue resource_manager = settlement_manager.resource_manager num_resources = 0 total_amount = 0 for resource_id, amount in resource_manager.trade_storage[self.settlement_manager.worldid].iteritems(): available_amount = int(min(math.floor(amount), settlement_manager.settlement.inventory[resource_id])) if available_amount > 0: num_resources += 1 total_amount += available_amount ships_needed = int(max(math.ceil(num_resources / float(ship_resource_slots)), math.ceil(total_amount / float(ship_capacity)))) if ships_needed > self.ships_sent[settlement_manager.worldid]: self.log.info('have %d ships, need %d ships, %d resource types, %d total amount', \ self.ships_sent[settlement_manager.worldid], ships_needed, num_resources, total_amount) options.append((total_amount - ship_capacity * self.ships_sent[settlement_manager.worldid], \ num_resources - ship_resource_slots * self.ships_sent[settlement_manager.worldid], settlement_manager.worldid)) return None if not options else WorldObject.get_object_by_id(max(options)[2])
def test_load_inactive_production(): """ create a savegame with a inactive production, load it """ session, player = new_session() settlement, island = settle(session) lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) # Set lumberjack to inactive lj.get_component(Producer).set_active(active = False) worldid = lj.worldid session.run(seconds=1) fd, filename = tempfile.mkstemp() os.close(fd) assert session.save(savegamename=filename) session.end(keep_map=True) # Load game session = load_session(filename) loadedlj = WorldObject.get_object_by_id(worldid) # Make sure it really is not active producer = loadedlj.get_component(Producer) assert not producer.is_active() # Trigger bug #1359 ToggleActive(producer).execute(session) session.end()
def __call__(self, issuer): """__call__() gets called by the manager. @param issuer: the issuer of the command """ owner = WorldObject.get_object_by_id(self.owner_id) return Entities.units[self.unit_id](session=owner.session, owner=owner, \ x=self.x, y=self.y, **self.kwargs)
def load(self, db, worldid): super(WildAnimal, self).load(db, worldid) # get own properties health, can_reproduce = db.get_wildanimal_row(worldid) # get home island island = WorldObject.get_object_by_id(db.get_unit_owner(worldid)) self.__init(island, bool(can_reproduce), health)
def load(cls, db, worldid, session): self = cls.__new__(cls) owner = db("SELECT owner FROM settlement WHERE rowid = ?", worldid)[0][0] upgrade_permissions = {} tax_settings = {} for level, allowed, tax in db("SELECT level, upgrading_allowed, tax_setting FROM settlement_level_properties WHERE settlement = ?", worldid): upgrade_permissions[level] = allowed tax_settings[level] = tax self.__init(session, WorldObject.get_object_by_id(owner), upgrade_permissions, tax_settings) # load super here cause basic stuff is just set up now super(Settlement, self).load(db, worldid) # load all buildings from this settlement # the buildings will expand the area of the settlement by adding everything, # that is in the radius of the building, to the settlement. from horizons.world import load_building for building_id, building_type in \ db("SELECT rowid, type FROM building WHERE location = ?", worldid): building = load_building(session, db, building_type, building_id) if building_type == BUILDINGS.BRANCH_OFFICE_CLASS: self.branch_office = building for res, amount in db("SELECT res, amount FROM settlement_produced_res WHERE settlement = ?", worldid): self.produced_res[res] = amount return self
def fix_job_object(): # resolve worldid to object later if self.job: if self.job.object == -1: self.job.object = None else: self.job.object = WorldObject.get_object_by_id( self.job.object )
def load(self, db, worldid): self.island, self.settlement = self.load_location(db, worldid) x, y, location, rotation, level = db.get_building_row(worldid) owner_id = db.get_settlement_owner(location) owner = None if owner_id is None else WorldObject.get_object_by_id(owner_id) self.owner = owner # set before super().load(), they need it # HACK set position in advance of loading because it is needed in the # collecting component. The position is set twice because of this, but # it should do no harm. self.__set_position(rotation, Point(x, y)) super(BasicBuilding, self).load(db, worldid) remaining_ticks_of_month = None if self.has_running_costs: db_data = db("SELECT ticks FROM remaining_ticks_of_month WHERE rowid=?", worldid) if len(db_data) == 0: # this can happen when running costs are set when there were no before # we shouldn't crash because of changes in yaml code, still it's suspicous print 'WARNING: object %s of type %s does not know when to pay its rent.' print 'Disregard this when loading old savegames or on running cost changes.' remaining_ticks_of_month = 1 else: remaining_ticks_of_month = db_data[0][0] self.__init(Point(x, y), rotation, level=level, \ remaining_ticks_of_month=remaining_ticks_of_month) # island.add_building handles registration of building for island and settlement self.island.add_building(self, self.owner, load=True)
def _load(self, db, owner, worldid): self.owner = owner super(SettlementManager, self).load(db, worldid) # load the main part land_manager_id = db("SELECT land_manager FROM ai_settlement_manager WHERE rowid = ?", worldid)[0][0] land_manager = WorldObject.get_object_by_id(land_manager_id) # find the settlement for settlement in self.owner.session.world.settlements: if settlement.owner == self.owner and settlement.island == land_manager.island: land_manager.settlement = settlement break assert land_manager.settlement self.resource_manager = ResourceManager.load(db, self) self.trade_manager = TradeManager.load(db, self) self.__init(land_manager) # load the master builders self.village_builder = VillageBuilder.load(db, self) self.production_builder = ProductionBuilder.load(db, self) self.village_builder.display() self.production_builder.display() self.__init_goals() # the add_building events happen before the settlement manager is loaded so they have to be repeated here for building in self.settlement.buildings: self.add_building(building)
def get_hover_instances(self, evt, layers=None): """ Utility method, returns the instances under the cursor @param layers: list of layer ids to search for. Default to OBJECTS """ if layers is None: layers = [LAYERS.OBJECTS] all_instances = [] for layer in layers: instances = self.session.view.cam.getMatchingInstances(\ fife.ScreenPoint(evt.getX(), evt.getY()), self.session.view.layers[layer], False) # False for accurate all_instances.extend(instances) hover_instances = [] for i in all_instances: id = i.getId() # Check id, can be '' if instance is created and clicked on before # actual game representation class is created (network play) if id == '': continue instance = WorldObject.get_object_by_id(int(id)) hover_instances.append(instance) return hover_instances
def load(cls, db, worldid, session): self = cls.__new__(cls) owner, tax = db( "SELECT owner, tax_setting FROM settlement WHERE rowid = ?", worldid)[0] self.__init(session, WorldObject.get_object_by_id(owner), tax) # load super here cause basic stuff is just set up now super(Settlement, self).load(db, worldid) # load all buildings from this settlement # the buildings will expand the area of the settlement by adding everything, # that is in the radius of the building, to the settlement. from horizons.world import load_building for building_id, building_type in \ db("SELECT rowid, type FROM building WHERE location = ?", worldid): load_building(session, db, building_type, building_id) for res, amount in db( "SELECT res, amount FROM settlement_produced_res WHERE settlement = ?", worldid): self.produced_res[res] = amount # load inventory after buildings, since buildings, specifically storages, determine # the size of the settlement's inventory self.inventory.load(db, worldid) return self
def object(self): try: return self._object except AttributeError: try: return WorldObject.get_object_by_id(self._obj_id) except WorldObjectNotFound: return None
def load_ship_states(self, db): # load ships one by one from db (ship instances themselves are loaded already, but # we have to use them here) for ship_id, state_id, remaining_ticks in \ db("SELECT rowid, state, remaining_ticks FROM pirate_ships"): state = self.shipStates[state_id] ship = WorldObject.get_object_by_id(ship_id) self.ships[ship] = state
def load(self, db, worldid): super(WildAnimal, self).load(db, worldid) # get own properties health, can_reproduce = \ db("SELECT health, can_reproduce FROM wildanimal WHERE rowid = ?", worldid)[0] # get home island home_island_id = db("SELECT owner FROM unit WHERE rowid = ?", worldid)[0][0] island = WorldObject.get_object_by_id(home_island_id) self.__init(island, bool(can_reproduce), health)
def load_ship_states(self, db): # load ships one by one from db (ship instances themselves are loaded already, but # we have to use them here) for ship_id, state_id, remaining_ticks, targeted_branch in \ db("SELECT rowid, state, remaining_ticks, targeted_branch FROM trader_ships"): state = self.shipStates[state_id] ship = WorldObject.get_object_by_id(ship_id) self.ships[ship] = state if state == self.shipStates.moving_random: ship.add_move_callback(Callback(self.ship_idle, ship)) elif state == self.shipStates.moving_to_branch: ship.add_move_callback(Callback(self.reached_branch, ship)) assert targeted_branch is not None self.office[ship.worldid] = WorldObject.get_object_by_id(targeted_branch) elif state == self.shipStates.reached_branch: assert remaining_ticks is not None Scheduler().add_new_object( \ Callback(self.ship_idle, ship), self, remaining_ticks)
def load(self, db, worldid): super(Unit, self).load(db, worldid) x, y, health, owner_id = db( "SELECT x, y, health, owner FROM unit WHERE rowid = ?", worldid)[0] if (owner_id == 0): owner = None else: owner = WorldObject.get_object_by_id(owner_id) self.__init(x, y, owner, health) return self
def _load(self, db, worldid): super(Production, self).load(db, worldid) db_data = db.get_production_row(worldid) self.__init(WorldObject.get_object_by_id(db_data[1]).inventory, db_data[2], \ PRODUCTION.STATES[db_data[0]], None if db_data[4] is None else PRODUCTION.STATES[db_data[4]]) if self._state == PRODUCTION.STATES.paused: self._pause_remaining_ticks = db_data[3] elif self._state == PRODUCTION.STATES.producing: Scheduler().add_new_object(self._finished_producing, self, db_data[3]) elif self._state == PRODUCTION.STATES.waiting_for_res or \ self._state == PRODUCTION.STATES.inventory_full: self.inventory.add_change_listener(self._check_inventory)
def load_ship_states(self, db): # load ships one by one from db (ship instances themselves are loaded already, but # we have to use them here) for ship_id, state_id, remaining_ticks in \ db("SELECT rowid, state, remaining_ticks FROM pirate_ships"): state = self.shipStates[state_id] ship = WorldObject.get_object_by_id(ship_id) self.ships[ship] = state assert remaining_ticks is not None Scheduler().add_new_object(Callback(self.lookout, ship), self, remaining_ticks, -1, 8) ship.add_move_callback(Callback(self.ship_idle, ship)) self.calculate_visibility_points(ship)
def tick(self, tick): """Do the tick (execute all commands for this tick) This code may only be reached if we are allowed to tick now (@see can_tick)""" # calculate command packets for this tick command_packets = self.commandsmanager.get_packets_for_tick(tick) command_packets.extend(self.localcommandsmanager.get_packets_for_tick(tick)) # sort by player, so that the packets get executed in the same order in every client # (packets are already in a special order within the packets, so no further sorting is necessary) command_packets.sort(key=operator.attrgetter('player_id')) for command_packet in command_packets: for command in command_packet.commandlist: self.log.debug("MPManager: calling command (tick %s): %s", tick, command) command(WorldObject.get_object_by_id(command_packet.player_id))
def load(self, db, worldid): super(BasicBuilding, self).load(db, worldid) x, y, self.health, location, rotation, level = db.get_building_row(worldid) owner_id = db.get_settlement_owner(location) owner = None if owner_id is None else WorldObject.get_object_by_id(owner_id) remaining_ticks_of_month = None if self.has_running_costs: remaining_ticks_of_month = db("SELECT ticks FROM remaining_ticks_of_month WHERE rowid=?", worldid)[0][0] self.__init(Point(x, y), rotation, owner, level=level, \ remaining_ticks_of_month=remaining_ticks_of_month) self.island, self.settlement = self.load_location(db, worldid) # island.add_building handles registration of building for island and settlement self.island.add_building(self, self.owner)
def mousePressed(self, evt): if evt.isConsumedByWidgets(): super(SelectionTool, self).mousePressed(evt) return elif evt.getButton() == fife.MouseEvent.LEFT: selectable = [] instances = self.session.view.cam.getMatchingInstances(\ fife.ScreenPoint(evt.getX(), evt.getY()), self.session.view.layers[LAYERS.OBJECTS]) for i in instances: # Check id, can be '' if instance is created and clicked on before # actual game representation class is created (network play) id = i.getId() if id == '': continue instance = WorldObject.get_object_by_id(int(id)) if instance.is_selectable: selectable.append(instance) if len(selectable) > 1: selectable = selectable[0:0] self.select_old = frozenset( self.session.selected_instances) if evt.isControlPressed( ) else frozenset() selectable = set(self.select_old ^ frozenset(selectable)) for instance in self.session.selected_instances - selectable: instance.deselect() for instance in selectable - self.session.selected_instances: instance.select() self.session.selected_instances = selectable self.select_begin = (evt.getX(), evt.getY()) self.session.ingame_gui.hide_menu() elif evt.getButton() == fife.MouseEvent.RIGHT: target_mapcoord = self.session.view.cam.toMapCoordinates(\ fife.ScreenPoint(evt.getX(), evt.getY()), False) for i in self.session.selected_instances: if i.movable: Act(i, target_mapcoord.x, target_mapcoord.y).execute(self.session) else: super(SelectionTool, self).mousePressed(evt) return evt.consume()
def load(self, db): enabled, self.current_waypoint = db( "SELECT enabled, current_waypoint FROM ship_route WHERE ship_id = ?", self.ship.worldid)[0] query = "SELECT branch_office_id FROM ship_route_waypoint WHERE ship_id = ? ORDER BY waypoint_index" offices_id = db(query, self.ship.worldid) for office_id, in offices_id: branch_office = WorldObject.get_object_by_id(office_id) query = "SELECT res, amount FROM ship_route_resources WHERE ship_id = ? and waypoint_index = ?" resource_list = dict( db(query, self.ship.worldid, len(self.waypoints))) self.waypoints.append({ 'branch_office': branch_office, 'resource_list': resource_list }) if enabled: self.current_waypoint -= 1 self.enable()
def _get_object(self): return WorldObject.get_object_by_id(self.obj_id)
def mouseDragged(self, evt): if evt.getButton() == fife.MouseEvent.LEFT and hasattr( self, 'select_begin'): do_multi = ((self.select_begin[0] - evt.getX())**2 + (self.select_begin[1] - evt.getY())** 2) >= 10 # ab 3px (3*3 + 1) self.session.view.renderer['GenericRenderer'].removeAll("select") if do_multi: a = fife.Point(min(self.select_begin[0], evt.getX()), \ min(self.select_begin[1], evt.getY())) b = fife.Point(max(self.select_begin[0], evt.getX()), \ min(self.select_begin[1], evt.getY())) c = fife.Point(max(self.select_begin[0], evt.getX()), \ max(self.select_begin[1], evt.getY())) d = fife.Point(min(self.select_begin[0], evt.getX()), \ max(self.select_begin[1], evt.getY())) self.session.view.renderer['GenericRenderer'].addLine("select", \ fife.GenericRendererNode(a), fife.GenericRendererNode(b), 200, 200, 200) self.session.view.renderer['GenericRenderer'].addLine("select", \ fife.GenericRendererNode(b), fife.GenericRendererNode(c), 200, 200, 200) self.session.view.renderer['GenericRenderer'].addLine("select", \ fife.GenericRendererNode(d), fife.GenericRendererNode(c), 200, 200, 200) self.session.view.renderer['GenericRenderer'].addLine("select", \ fife.GenericRendererNode(a), fife.GenericRendererNode(d), 200, 200, 200) selectable = [] instances = self.session.view.cam.getMatchingInstances(\ fife.Rect(min(self.select_begin[0], evt.getX()), \ min(self.select_begin[1], evt.getY()), \ abs(evt.getX() - self.select_begin[0]), \ abs(evt.getY() - self.select_begin[1])) if do_multi else fife.ScreenPoint(evt.getX(), evt.getY()), self.session.view.layers[LAYERS.OBJECTS]) # Only one unit, select anyway if len(instances) == 1: instance = WorldObject.get_object_by_id( int(instances[0].getId())) if instance.is_selectable: selectable.append(instance) else: for i in instances: instance = WorldObject.get_object_by_id(int(i.getId())) if instance.is_selectable and instance.owner == self.session.world.player: selectable.append(instance) if len(selectable) > 1: if do_multi: for instance in selectable[:]: # iterate through copy for safe removal if instance.is_building: selectable.remove(instance) else: selectable = [selectable.pop(0)] if do_multi: selectable = set(self.select_old | frozenset(selectable)) else: selectable = set(self.select_old ^ frozenset(selectable)) for instance in self.session.selected_instances - selectable: instance.deselect() for instance in selectable - self.session.selected_instances: instance.select() self.session.selected_instances = selectable elif (evt.getButton() == fife.MouseEvent.RIGHT): pass else: super(SelectionTool, self).mouseDragged(evt) return evt.consume()
def __call__(self, issuer): # NOTE: special call method, cause production must be saved as id, not as Production obj getattr(self._get_object(), self.method)( None if self._production is None else \ WorldObject.get_object_by_id(self._production) )
def __str__(self): return "packet " + str(self.__class__) + " from player " + str(WorldObject.get_object_by_id(self.player_id)) + " for tick " + str(self.tick)