def create_inventory(self): """Some buildings don't have an own inventory (e.g. storage building). Those can just overwrite this function to do nothing. see also: save_inventory() and load_inventory()""" db_data = horizons.main.db.cached_query("SELECT resource, size FROM balance.storage WHERE object_id = ?", \ self.id) if len(db_data) == 0: # no db data about inventory. Create default inventory. self.inventory = PositiveSizedSlotStorage( STORAGE.DEFAULT_STORAGE_SIZE) else: # specialised storage; each res and limit is stored in db. self.inventory = PositiveSizedSpecializedStorage() for res, size in db_data: self.inventory.add_resource_slot(res, size)
def setup_storage(self): self.inventory = PositiveSizedSlotStorage(0) self.inventory.add_change_listener(self._changed)
class Settlement(TradePost, NamedObject): """The Settlement class describes a settlement and stores all the necessary information like name, current inhabitants, lists of tiles and houses, etc belonging to the village.""" def __init__(self, session, owner): """ @param owner: Player object that owns the settlement """ self.__init(session, owner) super(Settlement, self).__init__() def __init(self, session, owner, tax_setting=1.0): self.session = session self.owner = owner self.tax_setting = tax_setting self.buildings = [] self.setup_storage() self.ground_map = { } # this is the same as in island.py. it uses hard references to the tiles too self.produced_res = { } # dictionary of all resources, produced at this settlement self.buildings_by_id = {} def set_tax_setting(self, tax): self.tax_setting = tax def _possible_names(self): names = horizons.main.db( "SELECT name FROM data.citynames WHERE for_player = 1") return map(lambda x: x[0], names) @property def inhabitants(self): """Returns number of inhabitants (sum of inhabitants of its buildings)""" return sum([building.inhabitants for building in self.buildings]) @property def cumulative_running_costs(self): """Return sum of running costs of all buildings""" return sum([building.running_costs for building in self.buildings]) @property def cumulative_taxes(self): """Return sum of all taxes payed in this settlement in 1 tax round""" return sum([building.last_tax_payed for building in self.buildings if \ hasattr(building, 'last_tax_payed')]) @property def balance(self): """Returns sum(income) - sum(expenses) for settlement""" return self.cumulative_taxes + self.sell_income \ - self.cumulative_running_costs - self.buy_expenses def level_upgrade(self, lvl): """Upgrades settlement to a new increment. It only delegates the upgrade to its buildings.""" for building in self.buildings: building.level_upgrade(lvl) def setup_storage(self): self.inventory = PositiveSizedSlotStorage(0) self.inventory.add_change_listener(self._changed) def save(self, db, islandid): super(Settlement, self).save(db) db( "INSERT INTO settlement (rowid, island, owner, tax_setting) VALUES(?, ?, ?, ?)", self.worldid, islandid, self.owner.worldid, self.tax_setting) for res, amount in self.produced_res.iteritems(): db("INSERT INTO settlement_produced_res (settlement, res, amount) VALUES(?, ?, ?)", \ self.worldid, res, amount) self.inventory.save(db, self.worldid) @classmethod 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 get_tiles_in_radius(self, location, radius, include_self): """Returns tiles in radius of location. This is a generator. @param location: anything that supports get_radius_coordinates (usually Rect). @param include_self: bool, whether to include the coordinates in location """ for coord in location.get_radius_coordinates(radius, include_self): try: yield self.ground_map[coord] except KeyError: pass def add_building(self, building): """Adds a building to the settlement. This does not set building.settlement, it must be set beforehand. @see Island.add_building """ self.buildings.append(building) if building.id in self.buildings_by_id.keys(): self.buildings_by_id[building.id].append(building) else: self.buildings_by_id[building.id] = [building] if hasattr(building, "add_building_production_finished_listener"): building.add_building_production_finished_listener( self.settlement_building_production_finished) def remove_building(self, building): """Properly removes a building from the settlement""" self.buildings.remove(building) self.buildings_by_id[building.id].remove(building) def get_buildings_by_id(self, id): """Returns all buildings on this island that have the given id""" if id in self.buildings_by_id.keys(): return self.buildings_by_id[id] else: return [] def settlement_building_production_finished(self, building, produced_res): """Callback function for registering the production of resources.""" for res, amount in produced_res.iteritems(): if res in self.produced_res: self.produced_res[res] += amount else: self.produced_res[res] = amount
class Settlement(TradePost, NamedObject): """The Settlement class describes a settlement and stores all the necessary information like name, current inhabitants, lists of tiles and houses, etc belonging to the village.""" def __init__(self, session, owner, island): """ @param owner: Player object that owns the settlement @param island: Island that contains the settlement """ self.__init(session, owner, island) super(Settlement, self).__init__() def __init(self, session, owner, island, tax_setting=1.0): self.session = session self.owner = owner self.tax_setting = tax_setting self.buildings = [] self.setup_storage() self.ground_map = {} # this is the same as in island.py. it uses hard references to the tiles too self.island = island self.tilequadtree = TileQuadTree(island.rect) def set_tax_setting(self, tax): self.tax_setting = tax def _possible_names(self): names = horizons.main.db("SELECT name FROM data.citynames WHERE for_player = 1") return map(lambda x: x[0], names) @property def inhabitants(self): """Returns number of inhabitants (sum of inhabitants of its buildings)""" return sum([building.inhabitants for building in self.buildings]) @property def cumulative_running_costs(self): """Return sum of running costs of all buildings""" return sum([building.running_costs for building in self.buildings]) @property def cumulative_taxes(self): """Return sum of all taxes payed in this settlement in 1 tax round""" return sum([building.last_tax_payed for building in self.buildings if \ hasattr(building, 'last_tax_payed')]) @property def balance(self): """Returns sum(income) - sum(expenses) for settlement""" return self.cumulative_taxes + self.sell_income \ - self.cumulative_running_costs - self.buy_expenses def level_upgrade(self, lvl): """Upgrades settlement to a new increment. It only delegates the upgrade to its buildings.""" for building in self.buildings: building.level_upgrade(lvl) def setup_storage(self): self.inventory = PositiveSizedSlotStorage(0) self.inventory.add_change_listener(self._changed) def save(self, db, islandid): super(Settlement, self).save(db) db("INSERT INTO settlement (rowid, island, owner, tax_setting) VALUES(?, ?, ?, ?)", self.worldid, islandid, self.owner.worldid, self.tax_setting) self.inventory.save(db, self.worldid) @classmethod def load(cls, db, worldid, session, island): 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), island, 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) # load inventory after buildings, since buildings, specifically storages, determine # the size of the settlement's inventory self.inventory.load(db, worldid) return self def get_tiles_in_radius(self, location, radius, include_self): """Returns tiles in radius of location. This is a generator. @param location: anything that supports get_radius_coordinates (usually Rect). @param include_self: bool, whether to include the coordinates in location """ for coord in location.get_radius_coordinates(radius, include_self): try: yield self.ground_map[coord] except KeyError: pass
class Settlement(TradePost, NamedObject): """The Settlement class describes a settlement and stores all the necessary information like name, current inhabitants, lists of tiles and houses, etc belonging to the village.""" def __init__(self, session, owner): """ @param owner: Player object that owns the settlement """ self.__init(session, owner) super(Settlement, self).__init__() def __init(self, session, owner, tax_setting=1.0): self.session = session self.owner = owner self.tax_setting = tax_setting self.buildings = [] self.setup_storage() self.ground_map = {} # this is the same as in island.py. it uses hard references to the tiles too self.produced_res = {} # dictionary of all resources, produced at this settlement self.buildings_by_id = {} def set_tax_setting(self, tax): self.tax_setting = tax def _possible_names(self): names = horizons.main.db("SELECT name FROM data.citynames WHERE for_player = 1") return map(lambda x: x[0], names) @property def inhabitants(self): """Returns number of inhabitants (sum of inhabitants of its buildings)""" return sum([building.inhabitants for building in self.buildings]) @property def cumulative_running_costs(self): """Return sum of running costs of all buildings""" return sum([building.running_costs for building in self.buildings]) @property def cumulative_taxes(self): """Return sum of all taxes payed in this settlement in 1 tax round""" return sum([building.last_tax_payed for building in self.buildings if \ hasattr(building, 'last_tax_payed')]) @property def balance(self): """Returns sum(income) - sum(expenses) for settlement""" return self.cumulative_taxes + self.sell_income \ - self.cumulative_running_costs - self.buy_expenses def level_upgrade(self, lvl): """Upgrades settlement to a new increment. It only delegates the upgrade to its buildings.""" for building in self.buildings: building.level_upgrade(lvl) def setup_storage(self): self.inventory = PositiveSizedSlotStorage(0) self.inventory.add_change_listener(self._changed) def save(self, db, islandid): super(Settlement, self).save(db) db("INSERT INTO settlement (rowid, island, owner, tax_setting) VALUES(?, ?, ?, ?)", self.worldid, islandid, self.owner.worldid, self.tax_setting) for res, amount in self.produced_res.iteritems(): db("INSERT INTO settlement_produced_res (settlement, res, amount) VALUES(?, ?, ?)", \ self.worldid, res, amount) self.inventory.save(db, self.worldid) @classmethod 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 get_tiles_in_radius(self, location, radius, include_self): """Returns tiles in radius of location. This is a generator. @param location: anything that supports get_radius_coordinates (usually Rect). @param include_self: bool, whether to include the coordinates in location """ for coord in location.get_radius_coordinates(radius, include_self): try: yield self.ground_map[coord] except KeyError: pass def add_building(self, building): """Adds a building to the settlement. This does not set building.settlement, it must be set beforehand. @see Island.add_building """ self.buildings.append(building) if building.id in self.buildings_by_id.keys(): self.buildings_by_id[building.id].append(building) else: self.buildings_by_id[building.id] = [building] if hasattr(building, "add_building_production_finished_listener"): building.add_building_production_finished_listener(self.settlement_building_production_finished) def remove_building(self, building): """Properly removes a building from the settlement""" self.buildings.remove(building) self.buildings_by_id[building.id].remove(building) def get_buildings_by_id(self, id): """Returns all buildings on this island that have the given id""" if id in self.buildings_by_id.keys(): return self.buildings_by_id[id] else: return [] def settlement_building_production_finished(self, building, produced_res): """Callback function for registering the production of resources.""" for res, amount in produced_res.iteritems(): if res in self.produced_res: self.produced_res[res] += amount else: self.produced_res[res] = amount