def test_combat_save_load():
    """
	create a savegame with combat units and actual combat, then save/load it
	"""

    session, player = new_session()
    (p0, s0), (p1, s1) = setup_combat(session, UNITS.FRIGATE)

    s0_worldid, s1_worldid = s0.worldid, s1.worldid

    session.run(seconds=1)

    # saveload
    session = saveload(session)

    s0 = WorldObject.get_object_by_id(s0_worldid)
    s1 = WorldObject.get_object_by_id(s1_worldid)

    # fight

    AddEnemyPair(p0, p1).execute(session)

    Attack(s0, s1).execute(session)
    Attack(s1, s0).execute(session)

    session.run(seconds=20)

    # saveload
    session = saveload(session)

    assert one_dead(s0_worldid, s1_worldid)

    session.end()
	def test(session, _):
		"""Let 2 AI players play for four minutes."""
		session.run(seconds = 4 * 60)
		assert session.world.settlements

		# simple test for luck: storages are known to easily break on remove:
		for settlement in session.world.settlements:
			for stor in settlement.get_buildings_by_id(BUILDINGS.STORAGE_CLASS):
				wid = stor.worldid
				Tear(stor)(stor.owner)
				try:
					WorldObject.get_object_by_id(wid)
				except WorldObjectNotFound:
					pass
				else:
					assert False

			session.run(seconds = 4)

		# for the heck of it, tear the rest as well
		for settlement in session.world.settlements:
			for building in settlement.buildings[:]:
				if building.id != BUILDINGS.WAREHOUSE_CLASS:
					Tear(building)(building.owner)
			assert len(settlement.buildings) == 1

		session.run(seconds = 60)
Beispiel #3
0
def test_combat_save_load():
	"""
	create a savegame with combat units and actual combat, then save/load it
	"""

	session, player = new_session()
	(p0, s0), (p1, s1) = setup_combat(session, UNITS.FRIGATE)

	s0_worldid, s1_worldid = s0.worldid, s1.worldid

	session.run(seconds=1)

	# saveload
	session = saveload(session)

	s0 = WorldObject.get_object_by_id(s0_worldid)
	s1 = WorldObject.get_object_by_id(s1_worldid)

	# fight

	AddEnemyPair(p0, p1).execute(session)

	Attack(s0, s1).execute(session)
	Attack(s1, s0).execute(session)

	session.run(seconds=20)

	# saveload
	session = saveload(session)

	assert one_dead(s0_worldid, s1_worldid)

	session.end()
	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._cur_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])
Beispiel #5
0
	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._cur_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 _load(self, db, worldid, success_callback, failure_callback):
        db_result = db(
            "SELECT source_settlement_manager, destination_settlement_manager, ship, state FROM ai_mission_special_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(SpecialDomesticTrade,
              self).load(db, worldid, success_callback, failure_callback,
                         WorldObject.get_object_by_id(db_result[2]))

        if self.state is self.missionStates.moving_to_source_settlement:
            self.ship.add_move_callback(
                Callback(self._reached_source_settlement))
            self.ship.add_blocked_callback(
                Callback(self._move_to_source_settlement))
        elif self.state is self.missionStates.moving_to_destination_settlement:
            self.ship.add_move_callback(
                Callback(self._reached_destination_settlement))
            self.ship.add_blocked_callback(
                Callback(self._move_to_destination_settlement))
        else:
            assert False, 'invalid state'
    def load_selection(self, db):
        # Re-select old selected instance
        for (instance_id,
             ) in db("SELECT id FROM selected WHERE `group` IS NULL"):
            obj = WorldObject.get_object_by_id(instance_id)
            self.session.selected_instances.add(obj)
            obj.get_component(SelectableComponent).select()

        # Re-show old tab (if there was one) or multiselection
        if len(self.session.selected_instances) == 1:
            tabname = db("SELECT value FROM metadata WHERE name = ?",
                         'selected_tab')[0][0]
            # This can still be None due to old savegames not storing the information
            tabclass = None if tabname is None else resolve_tab(tabname)
            obj.get_component(SelectableComponent).show_menu(
                jump_to_tabclass=tabclass)
        elif self.session.selected_instances:
            self.show_multi_select_tab(self.session.selected_instances)

        # Load user defined unit selection groups (Ctrl+number)
        for (num, group) in enumerate(self.session.selection_groups):
            for (instance_id, ) in db(
                    "SELECT id FROM selected WHERE `group` = ?", num):
                obj = WorldObject.get_object_by_id(instance_id)
                group.add(obj)
Beispiel #8
0
    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'
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
0
	def load(self, db):
		self.message_widget.load(db)
		self.logbook.load(db)
		self.resource_overview.load(db)

		if self.session.is_game_loaded():
			LastActivePlayerSettlementManager().load(db)
			cur_settlement = LastActivePlayerSettlementManager().get_current_settlement()
			self.cityinfo.set_settlement(cur_settlement)

		self.minimap.draw() # update minimap to new world

		self.current_cursor = 'default'
		self.cursor = mousetools.SelectionTool(self.session)
		# Set cursor correctly, menus might need to be opened.
		# Open menus later; they may need unit data not yet inited
		self.cursor.apply_select()

		# Re-select old selected instance
		for (instance_id, ) in db("SELECT id FROM selected WHERE `group` IS NULL"):
			obj = WorldObject.get_object_by_id(instance_id)
			self.session.selected_instances.add(obj)
			obj.get_component(SelectableComponent).select()

		# Re-show old tab (if there was one) or multiselection
		if len(self.session.selected_instances) == 1:
			tabname = db("SELECT value FROM metadata WHERE name = ?",
			             'selected_tab')[0][0]
			# This can still be None due to old savegames not storing the information
			tabclass = None if tabname is None else resolve_tab(tabname)
			obj.get_component(SelectableComponent).show_menu(jump_to_tabclass=tabclass)
		elif self.session.selected_instances:
			self.show_multi_select_tab(self.session.selected_instances)

		# Load user defined unit selection groups (Ctrl+number)
		for (num, group) in enumerate(self.session.selection_groups):
			for (instance_id, ) in db("SELECT id FROM selected WHERE `group` = ?", num):
				obj = WorldObject.get_object_by_id(instance_id)
				group.add(obj)

		if not self.session.is_game_loaded():
			# Fire a message for new world creation
			self.message_widget.add('NEW_WORLD')

		# Show message when the relationship between players changed
		def notify_change(caller, old_state, new_state, a, b):
			player1 = u"%s" % a.name
			player2 = u"%s" % b.name

			data = {'player1' : player1, 'player2' : player2}

			string_id = 'DIPLOMACY_STATUS_{old}_{new}'.format(old=old_state.upper(),
			                                                  new=new_state.upper())
			self.message_widget.add(string_id=string_id, message_dict=data)

		self.session.world.diplomacy.add_diplomacy_status_changed_listener(notify_change)
	def _load(self, db, worldid, success_callback, failure_callback):
		db_result = db("SELECT land_manager, ship, x, y, state FROM ai_mission_found_settlement WHERE rowid = ?", worldid)[0]
		self.land_manager = WorldObject.get_object_by_id(db_result[0])
		self.coords = (int(db_result[2]), int(db_result[3]))
		self.warehouse = None
		self.state = self.missionStates[db_result[4]]
		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'
Beispiel #13
0
	def _load(self, db, worldid, success_callback, failure_callback):
		db_result = db("SELECT land_manager, ship, x, y, state FROM ai_mission_found_settlement WHERE rowid = ?", worldid)[0]
		self.land_manager = WorldObject.get_object_by_id(db_result[0])
		self.coords = (int(db_result[2]), int(db_result[3]))
		self.warehouse = None
		self.state = self.missionStates[db_result[4]]
		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'
Beispiel #14
0
	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.warehouse = self.settlement_manager.settlement.warehouse
		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_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 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_warehouse:
			self.ship.add_move_callback(Callback(self._reached_source_warehouse_area))
			self.ship.add_blocked_callback(Callback(self._move_to_source_warehouse_area))
		elif self.state == self.missionStates.moving_to_destination_warehouse:
			self.ship.add_move_callback(Callback(self._reached_destination_warehouse_area))
			self.ship.add_blocked_callback(Callback(self._move_to_destination_warehouse_area))
		else:
			assert False, 'invalid 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 not db_data:
				# 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 suspicious
				self.log.warning('Object %s of type %s does not know when to pay its rent.\n'
					'Disregard this when loading old savegames or on running cost changes.',
					self.worldid, self.id)
				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)
Beispiel #19
0
		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 )
Beispiel #20
0
    def transfer_to_storageholder(self,
                                  amount,
                                  res_id,
                                  transfer_to,
                                  signal_errors=False):
        """Transfers amount of res_id to transfer_to.
		@param transfer_to: worldid or object reference
		@param signal_errors: whether to play an error sound in case the transfer completely failed (no res transferred)
		@return: amount that was actually transferred (NOTE: this is different from the
						 return value of inventory.alter, since here are 2 storages involved)
		"""
        try:
            transfer_to = WorldObject.get_object_by_id(int(transfer_to))
        except TypeError:  # transfer_to not an int, assume already obj
            pass
        # take res from self
        ret = self.get_component(StorageComponent).inventory.alter(
            res_id, -amount)
        # check if we were able to get the planned amount
        ret = amount if amount < abs(ret) else abs(ret)
        # put res to transfer_to
        ret = transfer_to.get_component(StorageComponent).inventory.alter(
            res_id, amount - ret)
        self.get_component(StorageComponent).inventory.alter(
            res_id, ret)  # return resources that did not fit
        actually_transfered = amount - ret
        if signal_errors and actually_transfered == 0:
            AmbientSoundComponent.play_special('error')
        return actually_transfered
Beispiel #21
0
 def load(self, db, worldid):
     super().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(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 load(self, db, worldid):
		super(BuildingInfluencingDisaster, self).load(db, worldid)
		for building_id, ticks in db("SELECT building, remaining_ticks_havoc FROM building_influencing_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))
Beispiel #24
0
	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 fix_job_object():
     # resolve worldid to object later
     if self.job:
         if self.job.object == -1:
             self.job.object = None  # e.g. when hunters have killed their prey
         else:
             self.job.object = WorldObject.get_object_by_id(self.job.object)
Beispiel #26
0
	def __call__(self, issuer):
		"""Execute the command
		@param issuer: the issuer of the command
		"""
		try:
			building = WorldObject.get_object_by_id(self.building)
		except WorldObjectNotFound:
			self.log.debug("Tear: building %s already gone, not tearing it again.", self.building)
			return # invalid command, possibly caused by mp delay
		if building is None or building.fife_instance is None:
			self.log.error("Tear: attempting to tear down a building that shouldn't exist %s", building)
		elif building.id in BUILDINGS.EXPAND_RANGE:
			building_to_destroy = len(self.destroyable_buildings(building.position, building.settlement)[0])
			if building_to_destroy == 0:
				self.log.debug("Tear: tearing down %s", building)
				building.remove()
			elif building_to_destroy == 1:
				title = _("Destroy all buildings")
				msg = _("This will destroy all the buildings that fall outside of the settlement range.\n\n1 additional building will be destroyed")
				should_abandon = building.session.ingame_gui.show_popup(title, msg, show_cancel_button=True)
				if should_abandon:
					self.log.debug("Tear: tearing down %s", building)
					building.remove()
			else:
				title = _("Destroy all buildings")
				msg = _("This will destroy all the buildings that fall outside of the settlement range.\n\n%s additional buildings will be destroyed" %building_to_destroy)
				should_abandon = building.session.ingame_gui.show_popup(title, msg, show_cancel_button=True)
				if should_abandon:
					self.log.debug("Tear: tearing down %s", building)
					building.remove()
		else:
			self.log.debug("Tear: tearing down %s", building)
			building.remove()
Beispiel #27
0
	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().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 not db_data:
				# 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 suspicious
				self.log.warning('Object %s of type %s does not know when to pay its rent.\n'
					'Disregard this when loading old savegames or on running cost changes.',
					self.worldid, self.id)
				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)
Beispiel #28
0
		def fix_job_object():
			# resolve worldid to object later
			if self.job:
				if self.job.object == -1:
					self.job.object = None   # e.g. when hunters have killed their prey
				else:
					self.job.object = WorldObject.get_object_by_id(self.job.object)
    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)
Beispiel #30
0
	def load(self, db, worldid):
		super(BuildingInfluencingDisaster, self).load(db, worldid)
		for building_id, ticks in db("SELECT building, remaining_ticks_havoc FROM building_influencing_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 load(cls, db, worldid, session, island):
		self = cls.__new__(cls)
		self.session = session
		super(Settlement, self).load(db, worldid)

		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 the settlement tile map
		tile_data = db("SELECT data FROM settlement_tiles WHERE rowid = ?", worldid)[0][0]
		coords_list = [tuple(raw_coords) for raw_coords in json.loads(tile_data)] # json saves tuples as list
		for coords in coords_list:
			tile = island.ground_map[coords]
			self.ground_map[coords] = tile
			tile.settlement = self

		# load all buildings in this 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.WAREHOUSE:
				self.warehouse = building

		for res, amount in db("SELECT res, amount FROM settlement_produced_res WHERE settlement = ?", worldid):
			self.produced_res[res] = amount

		return self
Beispiel #32
0
	def __call__(self, issuer):
		"""Execute the command
		@param issuer: the issuer of the command
		"""
		building = WorldObject.get_object_by_id(self.building)
		self.log.debug("Tear: tearing down %s", building)
		building.remove()
Beispiel #33
0
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)

    # Save and reload game
    session = saveload(session)

    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()
Beispiel #34
0
    def __call__(self, issuer):
        """Execute the command
		@param issuer: the issuer of the command
		"""
        building = WorldObject.get_object_by_id(self.building)
        self.log.debug("Tear: tearing down %s", building)
        building.remove()
 def _check_rotation(cls, session, position, rotation):
     """The rotation should be the same as the one of the underlying mountain"""
     tearset = cls._check_buildings(session,
                                    position)  # will raise on problems
     # rotation fix code is only reached when building is buildable
     mountain = WorldObject.get_object_by_id(iter(tearset).next())
     return mountain.rotation
	def load(cls, db, worldid, session, island):
		self = cls.__new__(cls)
		self.session = session
		super(Settlement, self).load(db, worldid)

		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 the settlement tile map
		tile_data = db("SELECT data FROM settlement_tiles WHERE rowid = ?", worldid)[0][0]
		coords_list = [tuple(raw_coords) for raw_coords in json.loads(tile_data)] # json saves tuples as list
		for coords in coords_list:
			tile = island.ground_map[coords]
			self.ground_map[coords] = tile
			tile.settlement = self

		# load all buildings in this 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.WAREHOUSE:
				self.warehouse = building

		for res, amount in db("SELECT res, amount FROM settlement_produced_res WHERE settlement = ?", worldid):
			self.produced_res[res] = amount

		return self
	def user_attack(self, targetid):
		"""
		Called when the user triggeres the attack, executes the user_attack_issued callbacks
		@param targetid: world id of the unit that is to be attacked
		"""
		self.attack(WorldObject.get_object_by_id(targetid))
		self.on_user_attack_issued()
Beispiel #38
0
	def _load(self, worldid, owner, db, destroy_callback):
		super(Fleet, self).load(db, worldid)
		self.owner = owner
		state_id, dest_x, dest_y, radius, ratio = db("SELECT state_id, dest_x, dest_y, radius, ratio FROM fleet WHERE fleet_id = ?", worldid)[0]

		if radius:  # Circle
			self.destination = Circle(Point(dest_x, dest_y), radius)
		elif dest_x and dest_y:  # Point
			self.destination = Point(dest_x, dest_y)
		else:  # No destination
			pass

		if ratio:
			self.ratio = ratio

		ships_states = [(WorldObject.get_object_by_id(ship_id), self.shipStates[ship_state_id])
		                for ship_id, ship_state_id
		                in db("SELECT ship_id, state_id FROM fleet_ship WHERE fleet_id = ?", worldid)]
		ships = [item[0] for item in ships_states]

		self.__init(ships, destroy_callback)
		self.state = self.fleetStates[state_id]

		for ship, state in ships_states:
			self._ships[ship] = state

		if self.state == self.fleetStates.moving:
			for ship in self.get_ships():
				if self._ships[ship] == self.shipStates.moving:
					ship.add_move_callback(Callback(self._ship_reached, ship))

		if destroy_callback:
			self.destroy_callback = destroy_callback
	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()
Beispiel #40
0
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)

	# Save and reload game
	session = saveload(session)

	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 user_attack(self, targetid):
        """
		Called when the user triggeres the attack, executes the user_attack_issued callbacks
		@param targetid: world id of the unit that is to be attacked
		"""
        self.attack(WorldObject.get_object_by_id(targetid))
        self.on_user_attack_issued()
	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 = STORAGE.SHIP_TOTAL_STORAGE
		ship_resource_slots = STORAGE.SHIP_TOTAL_SLOTS_NUMBER

		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].items():
				available_amount = int(min(math.floor(amount), settlement_manager.settlement.get_component(StorageComponent).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_CLASS, 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()
Beispiel #44
0
	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.get_component(StorageComponent).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 _load(self, worldid, owner, db, success_callback, failure_callback):
        super(ChaseShipsAndAttack, self)._load(db, worldid, success_callback, failure_callback, owner)
        (target_ship_id,) = db("SELECT target_ship_id FROM ai_mission_chase_ships_and_attack WHERE rowid = ?", worldid)[
            0
        ]

        target_ship = WorldObject.get_object_by_id(target_ship_id)
        self.__init(target_ship)
Beispiel #46
0
    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)
        unit = Entities.units[self.unit_id](session=owner.session, owner=owner, x=self.x, y=self.y, **self.kwargs)
        unit.initialize()
        return unit
 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)
Beispiel #48
0
	def finish_loading(self, db):
		""" This is called separately because most objects are loaded after the player. """

		# load the ships

		for ship_id, state_id in db("SELECT rowid, state FROM ai_ship WHERE owner = ?", self.worldid):
			ship = WorldObject.get_object_by_id(ship_id)
			self.ships[ship] = self.shipStates[state_id]

		# load unit manager
		self.unit_manager = UnitManager.load(db, self)

		# load combat manager
		self.combat_manager = CombatManager.load(db, self)

		# load strategy manager
		self.strategy_manager = StrategyManager.load(db, self)

		# load BehaviorManager
		self.behavior_manager = BehaviorManager.load(db, self)

		# load the land managers
		for (worldid,) in db("SELECT rowid FROM ai_land_manager WHERE owner = ?", self.worldid):
			land_manager = LandManager.load(db, self, worldid)
			self.islands[land_manager.island.worldid] = land_manager

		# load the settlement managers and settlement foundation missions
		for land_manager in self.islands.itervalues():
			db_result = db("SELECT rowid FROM ai_settlement_manager WHERE land_manager = ?", land_manager.worldid)
			if db_result:
				settlement_manager = SettlementManager.load(db, self, db_result[0][0])
				self.settlement_managers.append(settlement_manager)
				self._settlement_manager_by_settlement_id[settlement_manager.settlement.worldid] = settlement_manager

				# load the foundation ship preparing missions
				db_result = db("SELECT rowid FROM ai_mission_prepare_foundation_ship WHERE settlement_manager = ?",
					settlement_manager.worldid)
				for (mission_id,) in db_result:
					self.missions.add(PrepareFoundationShip.load(db, mission_id, self.report_success, self.report_failure))
			else:
				mission_id = db("SELECT rowid FROM ai_mission_found_settlement WHERE land_manager = ?", land_manager.worldid)[0][0]
				self.missions.add(FoundSettlement.load(db, mission_id, self.report_success, self.report_failure))

		for settlement_manager in self.settlement_managers:
			# load the domestic trade missions
			db_result = db("SELECT rowid FROM ai_mission_domestic_trade WHERE source_settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(DomesticTrade.load(db, mission_id, self.report_success, self.report_failure))

			# load the special domestic trade missions
			db_result = db("SELECT rowid FROM ai_mission_special_domestic_trade WHERE source_settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(SpecialDomesticTrade.load(db, mission_id, self.report_success, self.report_failure))

			# load the international trade missions
			db_result = db("SELECT rowid FROM ai_mission_international_trade WHERE settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(InternationalTrade.load(db, mission_id, self.report_success, self.report_failure))
	def finish_loading(self, db):
		""" This is called separately because most objects are loaded after the player. """

		# load the ships

		for ship_id, state_id in db("SELECT rowid, state FROM ai_ship WHERE owner = ?", self.worldid):
			ship = WorldObject.get_object_by_id(ship_id)
			self.ships[ship] = self.shipStates[state_id]

		# load unit manager
		self.unit_manager = UnitManager.load(db, self)

		# load combat manager
		self.combat_manager = CombatManager.load(db, self)

		# load strategy manager
		self.strategy_manager = StrategyManager.load(db, self)

		# load BehaviorManager
		self.behavior_manager = BehaviorManager.load(db, self)

		# load the land managers
		for (worldid,) in db("SELECT rowid FROM ai_land_manager WHERE owner = ?", self.worldid):
			land_manager = LandManager.load(db, self, worldid)
			self.islands[land_manager.island.worldid] = land_manager

		# load the settlement managers and settlement foundation missions
		for land_manager in self.islands.itervalues():
			db_result = db("SELECT rowid FROM ai_settlement_manager WHERE land_manager = ?", land_manager.worldid)
			if db_result:
				settlement_manager = SettlementManager.load(db, self, db_result[0][0])
				self.settlement_managers.append(settlement_manager)
				self._settlement_manager_by_settlement_id[settlement_manager.settlement.worldid] = settlement_manager

				# load the foundation ship preparing missions
				db_result = db("SELECT rowid FROM ai_mission_prepare_foundation_ship WHERE settlement_manager = ?",
					settlement_manager.worldid)
				for (mission_id,) in db_result:
					self.missions.add(PrepareFoundationShip.load(db, mission_id, self.report_success, self.report_failure))
			else:
				mission_id = db("SELECT rowid FROM ai_mission_found_settlement WHERE land_manager = ?", land_manager.worldid)[0][0]
				self.missions.add(FoundSettlement.load(db, mission_id, self.report_success, self.report_failure))

		for settlement_manager in self.settlement_managers:
			# load the domestic trade missions
			db_result = db("SELECT rowid FROM ai_mission_domestic_trade WHERE source_settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(DomesticTrade.load(db, mission_id, self.report_success, self.report_failure))

			# load the special domestic trade missions
			db_result = db("SELECT rowid FROM ai_mission_special_domestic_trade WHERE source_settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(SpecialDomesticTrade.load(db, mission_id, self.report_success, self.report_failure))

			# load the international trade missions
			db_result = db("SELECT rowid FROM ai_mission_international_trade WHERE settlement_manager = ?", settlement_manager.worldid)
			for (mission_id,) in db_result:
				self.missions.add(InternationalTrade.load(db, mission_id, self.report_success, self.report_failure))
Beispiel #50
0
def test_ticket_1427():
	"""Boatbuilder production progress should be saved properly"""

	session, player = new_session()
	settlement, island = settle(session)

	boat_builder = Build(BUILDINGS.BOATBUILDER_CLASS, 35, 20, island, settlement=settlement)(player)
	worldid = boat_builder.worldid

	# Make sure no boards are available
	settlement.get_component(StorageComponent).inventory.alter(RES.BOARDS_ID, -1000)

	bb_storage = boat_builder.get_component(StorageComponent)

	# Add production to use resources
	bb_producer =  boat_builder.get_component(Producer)
	bb_producer.add_production_by_id(PRODUCTIONLINES.HUKER)
	production = bb_producer._productions[PRODUCTIONLINES.HUKER]

	assert production.progress == 0.0

	bb_storage.inventory.alter(RES.TEXTILE_ID, 10)
	bb_storage.inventory.alter(RES.BOARDS_ID, 6)

	production_line = production._prod_line

	# Make sure the boatbuilder consumes everything in his inventory
	session.run(seconds=10)

	# Check if correctly consumed wood
	assert production_line.consumed_res[RES.BOARDS_ID] == -2

	# Save all production process for later
	expected_consumed_res = production_line.consumed_res
	expected_produced_res = production_line.produced_res
	expected_production = production_line.production
	expected_progress = production.progress

	# Make sure the producer used the boards
	assert bb_storage.inventory[RES.BOARDS_ID] == 0

	fd, filename = tempfile.mkstemp()
	os.close(fd)
	assert session.save(savegamename=filename)
	session.end(keep_map=True)

	# Load game
	session = load_session(filename)
	loadedbb = WorldObject.get_object_by_id(worldid)

	production_loaded = loadedbb.get_component(Producer)._productions[PRODUCTIONLINES.HUKER]
	production_line_loaded = production_loaded._prod_line

	# Make sure everything is loaded correctly
	assert expected_consumed_res == production_line_loaded.consumed_res
	assert expected_produced_res == production_line_loaded.produced_res
	assert expected_production == production_line_loaded.production
	assert expected_progress == production_loaded.progress
Beispiel #51
0
 def transfer_to_storageholder(self, amount, res_id, transfer_to_id):
     transfer_to = WorldObject.get_object_by_id(transfer_to_id)
     # take res from self
     ret = self.inventory.alter(res_id, -amount)
     # check if we were able to get the planed amount
     ret = amount if amount < abs(ret) else abs(ret)
     # put res to transfer_to
     ret = transfer_to.inventory.alter(res_id, amount - ret)
     self.inventory.alter(res_id, ret)  #return resources that did not fit
    def _load(self, worldid, owner, db, success_callback, failure_callback):
        super(ChaseShipsAndAttack, self)._load(db, worldid, success_callback,
                                               failure_callback, owner)
        (target_ship_id, ) = db(
            "SELECT target_ship_id FROM ai_mission_chase_ships_and_attack WHERE rowid = ?",
            worldid)[0]

        target_ship = WorldObject.get_object_by_id(target_ship_id)
        self.__init(target_ship)
 def fife_instance_to_uh_instance(self, instance):
     """Visual fife instance to uh game logic object or None"""
     i_id = instance.getId()
     if i_id == '':
         return None
     try:
         return WorldObject.get_object_by_id(int(i_id))
     except WorldObjectNotFound:
         return None
def test_ticket_1427():
	"""Boatbuilder production progress should be saved properly"""

	session, player = new_session()
	settlement, island = settle(session)

	boat_builder = Build(BUILDINGS.BOAT_BUILDER, 35, 20, island, settlement=settlement)(player)
	worldid = boat_builder.worldid

	# Make sure no boards are available
	settlement.get_component(StorageComponent).inventory.alter(RES.BOARDS, -1000)

	bb_storage = boat_builder.get_component(StorageComponent)

	# Add production to use resources
	bb_producer = boat_builder.get_component(Producer)
	bb_producer.add_production_by_id(PRODUCTIONLINES.HUKER)
	production = bb_producer._productions[PRODUCTIONLINES.HUKER]

	assert production.progress == 0.0

	bb_storage.inventory.alter(RES.TEXTILE, 10)
	bb_storage.inventory.alter(RES.BOARDS, 6)

	production_line = production._prod_line

	# Make sure the boatbuilder consumes everything in its inventory
	session.run(seconds=10)

	# Check if correctly consumed wood
	assert production_line.consumed_res[RES.BOARDS] == -2

	# Save all production process for later
	expected_consumed_res = production_line.consumed_res
	expected_produced_res = production_line.produced_res
	expected_production = production_line.production
	expected_progress = production.progress

	# Make sure the producer used the boards
	assert bb_storage.inventory[RES.BOARDS] == 0

	# Save and reload game
	session = saveload(session)
	loadedbb = WorldObject.get_object_by_id(worldid)

	production_loaded = loadedbb.get_component(Producer)._productions[PRODUCTIONLINES.HUKER]
	production_line_loaded = production_loaded._prod_line

	# Make sure everything is loaded correctly
	assert expected_consumed_res == production_line_loaded.consumed_res
	assert expected_produced_res == production_line_loaded.produced_res
	assert expected_production == production_line_loaded.production
	assert expected_progress == production_loaded.progress

	# if you don't let the session run for a bit then collectors won't be fully initialized and can't be killed => another test will fail in session.end()
	session.run(seconds=1)
	session.end()
	def fife_instance_to_uh_instance(self, instance):
		"""Visual fife instance to uh game logic object or None"""
		i_id = instance.getId()
		if i_id == '':
			return None
		try:
			return WorldObject.get_object_by_id(int(i_id))
		except WorldObjectNotFound:
			return None
Beispiel #56
0
def test_build_tear(s, p):
    """
	Build stuff and tear it later
	"""
    settlement, island = settle(s)
    tree = Build(BUILDINGS.TREE, 30, 35, island, settlement=settlement)(p)

    s.run(seconds=1)

    wid = tree.worldid
    Tear(tree)(p)

    try:
        WorldObject.get_object_by_id(wid)
    except WorldObjectNotFound:
        pass  # should be gone
    else:
        assert False
def test_build_tear(s, p):
	"""
	Build stuff and tear it later
	"""
	settlement, island = settle(s)
	tree = Build(BUILDINGS.TREE, 30, 35, island, settlement=settlement)(p)

	s.run(seconds=1)

	wid = tree.worldid
	Tear(tree)(p)

	try:
		WorldObject.get_object_by_id(wid)
	except WorldObjectNotFound:
		pass # should be gone
	else:
		assert False