Beispiel #1
0
	def end(self):
		self.log.debug("Ending session")
		self.is_alive = False

		LastActivePlayerSettlementManager().remove()
		LastActivePlayerSettlementManager.destroy_instance()

		self.gui.session = None

		Scheduler().rem_all_classinst_calls(self)
		ExtScheduler().rem_all_classinst_calls(self)

		if horizons.main.fife.get_fife_setting("PlaySounds"):
			for emitter in horizons.main.fife.sound.emitter['ambient'][:]:
				emitter.stop()
				horizons.main.fife.sound.emitter['ambient'].remove(emitter)
			horizons.main.fife.sound.emitter['effects'].stop()
			horizons.main.fife.sound.emitter['speech'].stop()
		if hasattr(self, "cursor"): # the line below would crash uglily on ^C
			self.cursor.remove()
		self.cursor = None
		self.world = None
		self.keylistener = None
		self.ingame_gui = None
		self.view = None
		self.manager = None
		self.timer = None
		self.scenario_eventhandler = None
		Scheduler.destroy_instance()


		self.selected_instances = None
		self.selection_groups = None
Beispiel #2
0
	def end(self):
		self.mainhud.mapEvents({
			'zoomIn': None,
			'zoomOut': None,
			'rotateRight': None,
			'rotateLeft': None,
			'gameMenuButton': None
		})
		self.mainhud.hide()
		self.mainhud = None
		self._settings_tab.hide()
		self._settings_tab = None

		self.windows.close_all()
		self.minimap = None
		self.keylistener = None
		LastActivePlayerSettlementManager().remove()
		LastActivePlayerSettlementManager.destroy_instance()
		ZoomChanged.unsubscribe(self._update_zoom)

		if self.cursor:
			self.cursor.remove()
			self.cursor.end()
			self.cursor = None

		super(IngameGui, self).end()
Beispiel #3
0
	def end(self):
		self.log.debug("Ending session")
		self.is_alive = False

		self.gui.session = None

		# Has to be done here, cause the manager uses Scheduler!
		self.end_production_finished_icon_manager()
		Scheduler().rem_all_classinst_calls(self)
		ExtScheduler().rem_all_classinst_calls(self)

		if horizons.globals.fife.get_fife_setting("PlaySounds"):
			for emitter in horizons.globals.fife.sound.emitter['ambient'][:]:
				emitter.stop()
				horizons.globals.fife.sound.emitter['ambient'].remove(emitter)
			horizons.globals.fife.sound.emitter['effects'].stop()
			horizons.globals.fife.sound.emitter['speech'].stop()
		if hasattr(self, "cursor"): # the line below would crash uglily on ^C
			self.cursor.remove()

		if hasattr(self, 'cursor') and self.cursor is not None:
			self.cursor.end()
		# these will call end() if the attribute still exists by the LivingObject magic
		self.ingame_gui = None # keep this before world

		LastActivePlayerSettlementManager().remove() # keep after ingame_gui
		LastActivePlayerSettlementManager.destroy_instance()

		self.cursor = None
		self.world.end() # must be called before the world ref is gone
		self.world = None
		self.keylistener = None
		self.view = None
		self.manager = None
		self.timer = None
		self.scenario_eventhandler = None

		Scheduler().end()
		Scheduler.destroy_instance()

		self.selected_instances = None
		self.selection_groups = None

		self.status_icon_manager.end()
		self.status_icon_manager = None

		horizons.main._modules.session = None
		self._clear_caches()

		# subscriptions shouldn't survive listeners (except the main Gui)
		self.gui.unsubscribe()
		AutosaveIntervalChanged.unsubscribe(self._on_autosave_interval_changed)
		MessageBus().reset()
		self.gui.subscribe()
Beispiel #4
0
	def end(self):
		self.log.debug("Ending session")
		self.is_alive = False

		self.gui.session = None

		Scheduler().rem_all_classinst_calls(self)
		ExtScheduler().rem_all_classinst_calls(self)

		if horizons.main.fife.get_fife_setting("PlaySounds"):
			for emitter in horizons.main.fife.sound.emitter['ambient'][:]:
				emitter.stop()
				horizons.main.fife.sound.emitter['ambient'].remove(emitter)
			horizons.main.fife.sound.emitter['effects'].stop()
			horizons.main.fife.sound.emitter['speech'].stop()
		if hasattr(self, "cursor"): # the line below would crash uglily on ^C
			self.cursor.remove()

		if hasattr(self, 'cursor') and self.cursor is not None:
			self.cursor.end()
		# these will call end() if the attribute still exists by the LivingObject magic
		self.ingame_gui = None # keep this before world

		LastActivePlayerSettlementManager().remove() # keep after ingame_gui
		LastActivePlayerSettlementManager.destroy_instance()

		self.cursor = None
		try:
			# This is likely to throw when the game state is invalid.
			# Try to continue cleanup afterwards even if this fails.
			# NOTE: This is not a proper solution, separating sessions by design (e.g. single processes) would be.
			self.world.end() # must be called before the world ref is gone
		except Exception:
			import traceback
			traceback.print_exc()
			print 'Exception on world end(), trying to continue to cleanup'
		self.world = None
		self.keylistener = None
		self.view = None
		self.manager = None
		self.timer = None
		self.scenario_eventhandler = None

		Scheduler().end()
		Scheduler.destroy_instance()

		self.selected_instances = None
		self.selection_groups = None

		self.status_icon_manager = None
		self.message_bus = None

		horizons.main._modules.session = None
		self._clear_caches()
Beispiel #5
0
	def end(self):
		# unsubscribe early, to avoid messages coming in while we're shutting down
		SpeedChanged.unsubscribe(self._on_speed_changed)
		NewDisaster.unsubscribe(self._on_new_disaster)
		NewSettlement.unsubscribe(self._on_new_settlement)
		PlayerLevelUpgrade.unsubscribe(self._on_player_level_upgrade)
		MineEmpty.unsubscribe(self._on_mine_empty)
		ZoomChanged.unsubscribe(self._update_zoom)
		GuiAction.unsubscribe(self._on_gui_click_action)
		GuiHover.unsubscribe(self._on_gui_hover_action)
		GuiCancelAction.unsubscribe(self._on_gui_cancel_action)

		self.mainhud.mapEvents({
			'zoomIn' : None,
			'zoomOut' : None,
			'rotateRight' : None,
			'rotateLeft': None,

			'destroy_tool' : None,
			'build' : None,
			'diplomacyButton' : None,
			'gameMenuButton' : None
		})
		self.mainhud.hide()
		self.mainhud = None

		self.windows.close_all()
		self.message_widget = None
		self.minimap = None
		self.resource_overview.end()
		self.resource_overview = None
		self.keylistener = None
		self.cityinfo.end()
		self.cityinfo = None
		self.hide_menu()

		if self.cursor:
			self.cursor.remove()
			self.cursor.end()
			self.cursor = None

		LastActivePlayerSettlementManager().remove()
		LastActivePlayerSettlementManager.destroy_instance()

		self.production_finished_icon_manager.end()
		self.production_finished_icon_manager = None
		self.status_icon_manager.end()
		self.status_icon_manager = None

		super(IngameGui, self).end()
Beispiel #6
0
    def __init__(self, session):
        self.session = session

        self.cursor = None
        self.coordinates_tooltip = None
        self.keylistener = IngameKeyListener(self.session)
        # used by NavigationTool
        LastActivePlayerSettlementManager.create_instance(self.session)

        # Mocks needed to act like the real IngameGui
        self.show_menu = Dummy
        self.hide_menu = Dummy
        # a logbook Dummy is necessary for message_widget to work
        self.logbook = Dummy

        self.mainhud = load_uh_widget("minimap.xml")
        self.mainhud.position_technique = "right+0:top+0"

        icon = self.mainhud.findChild(name="minimap")
        self.minimap = Minimap(
            icon,
            targetrenderer=horizons.globals.fife.targetrenderer,
            imagemanager=horizons.globals.fife.imagemanager,
            session=self.session,
            view=self.session.view,
        )

        self.mainhud.mapEvents(
            {
                "zoomIn": self.session.view.zoom_in,
                "zoomOut": self.session.view.zoom_out,
                "rotateRight": Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right),
                "rotateLeft": Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left),
                "gameMenuButton": self.toggle_pause,
            }
        )

        self.mainhud.show()
        ZoomChanged.subscribe(self._update_zoom)

        # Hide unnecessary buttons in hud
        for widget in ("build", "speedUp", "speedDown", "destroy_tool", "diplomacyButton", "logbook"):
            self.mainhud.findChild(name=widget).hide()

        self.windows = WindowManager()
        self.message_widget = MessageWidget(self.session)
        self.pausemenu = PauseMenu(self.session, self, self.windows, in_editor_mode=True)
        self.help_dialog = HelpDialog(self.windows)
Beispiel #7
0
	def end(self):
		self.log.debug("Ending session")
		self.is_alive = False

		self.gui.session = None

		Scheduler().rem_all_classinst_calls(self)
		ExtScheduler().rem_all_classinst_calls(self)

		if horizons.main.fife.get_fife_setting("PlaySounds"):
			for emitter in horizons.main.fife.sound.emitter['ambient'][:]:
				emitter.stop()
				horizons.main.fife.sound.emitter['ambient'].remove(emitter)
			horizons.main.fife.sound.emitter['effects'].stop()
			horizons.main.fife.sound.emitter['speech'].stop()
		if hasattr(self, "cursor"): # the line below would crash uglily on ^C
			self.cursor.remove()

		if hasattr(self, 'cursor') and self.cursor is not None:
			self.cursor.end()
		# these will call end() if the attribute still exists by the LivingObject magic
		self.ingame_gui = None # keep this before world

		LastActivePlayerSettlementManager().remove() # keep after ingame_gui
		LastActivePlayerSettlementManager.destroy_instance()

		self.cursor = None
		self.world.end() # must be called before the world ref is gone
		self.world = None
		self.keylistener = None
		self.view = None
		self.manager = None
		self.timer = None
		self.scenario_eventhandler = None

		Scheduler().end()
		Scheduler.destroy_instance()

		self.selected_instances = None
		self.selection_groups = None

		self.status_icon_manager = None
		self.message_bus = None

		horizons.main._modules.session = None
		self._clear_caches()
Beispiel #8
0
	def __init__(self, gui, db, rng_seed=None):
		super(Session, self).__init__()
		assert isinstance(db, horizons.util.uhdbaccessor.UhDbAccessor)
		self.log.debug("Initing session")
		self.gui = gui # main gui, not ingame gui
		self.db = db # main db for game data (game.sql)
		# this saves how often the current game has been saved
		self.savecounter = 0
		self.is_alive = True

		self._clear_caches()

		#game
		self.random = self.create_rng(rng_seed)
		assert isinstance(self.random, Random)
		self.timer = self.create_timer()
		Scheduler.create_instance(self.timer)
		self.manager = self.create_manager()
		self.view = View(self)
		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.coordinates_tooltip = None
		self.display_speed()
		LastActivePlayerSettlementManager.create_instance(self)


		self.status_icon_manager = StatusIconManager(
		  renderer=self.view.renderer['GenericRenderer'],
		  layer=self.view.layers[LAYERS.OBJECTS]
		  )
		self.production_finished_icon_manager = None
		self.create_production_finished_icon_manager()


		self.selected_instances = set()
		self.selection_groups = [set() for _ in range(10)]  # List of sets that holds the player assigned unit groups.

		self._old_autosave_interval = None
Beispiel #9
0
    def __init__(self, gui, db, rng_seed=None):
        super(Session, self).__init__()
        assert isinstance(db, horizons.util.uhdbaccessor.UhDbAccessor)
        self.log.debug("Initing session")
        self.gui = gui  # main gui, not ingame gui
        self.db = db  # main db for game data (game.sql)
        # this saves how often the current game has been saved
        self.savecounter = 0
        self.is_alive = True

        self._clear_caches()

        #game
        self.random = self.create_rng(rng_seed)
        assert isinstance(self.random, Random)
        self.timer = self.create_timer()
        Scheduler.create_instance(self.timer)
        self.manager = self.create_manager()
        self.view = View(self)
        Entities.load(self.db)
        self.scenario_eventhandler = ScenarioEventHandler(
            self)  # dummy handler with no events

        #GUI
        self.gui.session = self
        self.ingame_gui = IngameGui(self, self.gui)
        self.keylistener = IngameKeyListener(self)
        self.coordinates_tooltip = None
        self.display_speed()
        LastActivePlayerSettlementManager.create_instance(self)

        self.status_icon_manager = StatusIconManager(
            renderer=self.view.renderer['GenericRenderer'],
            layer=self.view.layers[LAYERS.OBJECTS])
        self.production_finished_icon_manager = None
        self.create_production_finished_icon_manager()

        self.selected_instances = set()
        self.selection_groups = [
            set() for _ in range(10)
        ]  # List of sets that holds the player assigned unit groups.

        self._old_autosave_interval = None
    def load(self, db):
        self.message_widget.load(db)
        self.logbook.load(db)
        self.resource_overview.load(db)

        cur_settlement = LastActivePlayerSettlementManager(
        ).get_current_settlement()
        self._cityinfo_set(HoverSettlementChanged(self, cur_settlement))

        self.minimap.draw()  # update minimap to new world
Beispiel #11
0
    def show(self):
        self.__remove_changelisteners()
        self.__current_settlement = LastActivePlayerSettlementManager().get()
        self.__add_changelisteners()
        self.__class__.last_active_build_tab = self.tabindex
        super(BuildTab, self).show()

        button = self.widget.child_finder("switch_build_menu_config_button")
        self._set_switch_layout_button_image(button)
        button.capture(self._switch_build_menu_config)
Beispiel #12
0
	def __init__(self, gui, db, rng_seed=None):
		super(Session, self).__init__()
		assert isinstance(gui, Gui)
		assert isinstance(db, horizons.util.uhdbaccessor.UhDbAccessor)
		self.log.debug("Initing session")
		self.gui = gui # main gui, not ingame gui
		self.db = db # main db for game data (game.sql)
		# this saves how often the current game has been saved
		self.savecounter = 0
		self.is_alive = True

		self.message_bus = MessageBus()

		# misc
		WorldObject.reset()
		NamedComponent.reset()
		AIPlayer.clear_caches()

		#game
		self.random = self.create_rng(rng_seed)
		assert isinstance(self.random, Random)
		self.timer = self.create_timer()
		Scheduler.create_instance(self.timer)
		self.manager = self.create_manager()
		self.view = View(self)
		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.coordinates_tooltip = None
		self.display_speed()
		LastActivePlayerSettlementManager.create_instance(self)


		self.status_icon_manager = StatusIconManager(self)

		self.selected_instances = set()
		self.selection_groups = [set()] * 10 # List of sets that holds the player assigned unit groups.
Beispiel #13
0
	def end(self):
		self.mainhud.mapEvents({
			'zoomIn': None,
			'zoomOut': None,
			'rotateRight': None,
			'rotateLeft': None,
			'gameMenuButton': None
		})
		self.minimap = None
		self.keylistener = None
		LastActivePlayerSettlementManager().remove()
		LastActivePlayerSettlementManager.destroy_instance()
		self.session.view.remove_change_listener(self._update_zoom)

		if self.cursor:
			self.cursor.remove()
			self.cursor.end()
			self.cursor = None

		super(IngameGui, self).end()
Beispiel #14
0
	def __init__(self, session, main_gui):
		self.session = session
		self.main_gui = main_gui

		self.cursor = None
		self.coordinates_tooltip = None
		self.keylistener = IngameKeyListener(self.session)
		# used by NavigationTool
		LastActivePlayerSettlementManager.create_instance(self.session)

		# Mocks needed to act like the real IngameGui
		self.show_menu = Dummy
		self.hide_menu = Dummy

		self.mainhud = load_uh_widget('minimap.xml')
		self.mainhud.position_technique = "right+0:top+0"

		icon = self.mainhud.findChild(name="minimap")
		self.minimap = Minimap(icon,
		                       targetrenderer=horizons.globals.fife.targetrenderer,
		                       imagemanager=horizons.globals.fife.imagemanager,
		                       session=self.session,
		                       view=self.session.view)

		self.mainhud.mapEvents({
			'zoomIn': self.session.view.zoom_in,
			'zoomOut': self.session.view.zoom_out,
			'rotateRight': Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right),
			'rotateLeft': Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left),
			'gameMenuButton': self.toggle_pause,
		})

		self.mainhud.show()
		self.session.view.add_change_listener(self._update_zoom)

		# Hide unnecessary buttons in hud
		for widget in ("build", "speedUp", "speedDown", "destroy_tool", "diplomacyButton", "logbook"):
			self.mainhud.findChild(name=widget).hide()

		self.save_map_dialog = SaveMapDialog(self.main_gui, self, self.session)
		self.pausemenu = PauseMenu(self.session, self.main_gui, self, in_editor_mode=True)
Beispiel #15
0
	def close_construction_mode(self, update_slots=True):
		"""Return to normal configuration"""
		self.construction_mode = False
		if update_slots: # cleanup
			self._drop_cost_labels()
			self.set_inventory_instance(None)
		#self._update_gold()
		self.gold_gui.show()
		self._update_gold(force=True)

		# reshow last settlement
		self.set_inventory_instance( LastActivePlayerSettlementManager().get(get_current_pos=True) )
Beispiel #16
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()
		NamedComponent.reset()
		AIPlayer.clear_caches()

		# Game
		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.message_bus = MessageBus()
		self.status_icon_manager = StatusIconManager(self)


		# GUI
		self.gui.session = self
		self.ingame_gui = Dummy()
		LastActivePlayerSettlementManager.create_instance(self)

		self.selected_instances = set()
		self.selection_groups = [set()] * 10 # List of sets that holds the player assigned unit groups.

		GAME_SPEED.TICKS_PER_SECOND = 16
	def end(self):
		self.mainhud.mapEvents({
			'zoomIn' : None,
			'zoomOut' : None,
			'rotateRight' : None,
			'rotateLeft': None,

			'destroy_tool' : None,
			'build' : None,
			'diplomacyButton' : None,
			'gameMenuButton' : None
		})

		self.message_widget = None
		self.minimap = None
		self.resource_overview.end()
		self.resource_overview = None
		self.keylistener = None
		self.cityinfo.end()
		self.cityinfo = None
		self.hide_menu()
		SettlerUpdate.unsubscribe(self._on_settler_level_change)
		SpeedChanged.unsubscribe(self._on_speed_changed)
		self.session.view.remove_change_listener(self._update_zoom)

		if self.cursor:
			self.cursor.remove()
			self.cursor.end()
			self.cursor = None

		LastActivePlayerSettlementManager().remove()
		LastActivePlayerSettlementManager.destroy_instance()

		self.production_finished_icon_manager.end()
		self.production_finished_icon_manager = None
		self.status_icon_manager.end()
		self.status_icon_manager = None

		super(IngameGui, self).end()
    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()

        self.load_selection(db)

        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 = "{0!s}".format(a.name)
            player2 = "{0!s}".format(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 mouseMoved(self, evt):
        if not self.session.world.inited:
            return

        self.consumed_by_widgets = evt.isConsumedByWidgets()

        self.tooltip.show_evt(evt)
        # don't overwrite this last_event_pos instance. Due to class
        # hierarchy, it would write to the lowest class (e.g. SelectionTool)
        # and the attribute in NavigationTool would be left unchanged.
        self.__class__.last_event_pos.set(evt.getX(), evt.getY(), 0)
        mousepoint = self.__class__.last_event_pos

        # Status menu update
        current = self.get_exact_world_location(evt)

        distance_ge = lambda a, b, epsilon: abs((a.x - b.x)**2 +
                                                (a.y - b.y)**2) >= epsilon**2

        if distance_ge(current, self.last_exact_world_location,
                       4):  # update every 4 tiles for settlement info
            self.last_exact_world_location = current
            # update res bar with settlement-related info
            LastActivePlayerSettlementManager().update(current)

        # check if instance update is scheduled
        if self.__class__.send_hover_instances_update:
            self._schedule_hover_instance_update()

        # Mouse scrolling
        x, y = 0, 0
        if mousepoint.x < VIEW.AUTOSCROLL_WIDTH:
            x -= VIEW.AUTOSCROLL_WIDTH - mousepoint.x
        elif mousepoint.x > (self.session.view.cam.getViewPort().right() -
                             VIEW.AUTOSCROLL_WIDTH):
            x += VIEW.AUTOSCROLL_WIDTH + mousepoint.x - self.session.view.cam.getViewPort(
            ).right()
        if mousepoint.y < VIEW.AUTOSCROLL_WIDTH:
            y -= VIEW.AUTOSCROLL_WIDTH - mousepoint.y
        elif mousepoint.y > (self.session.view.cam.getViewPort().bottom() -
                             VIEW.AUTOSCROLL_WIDTH):
            y += VIEW.AUTOSCROLL_WIDTH + mousepoint.y - self.session.view.cam.getViewPort(
            ).bottom()
        x *= 10
        y *= 10
        self.session.view.autoscroll(x, y)
Beispiel #20
0
	def load(self, db):
		from horizons.util.worldobject import WorldObject
		for obj in db("SELECT DISTINCT object FROM resource_overview_bar"):
			obj = obj[0]
			l = []
			for pos, res in db("SELECT position, resource FROM resource_overview_bar where object=?", obj):
				l.append( (pos, res) )
			obj = WorldObject.get_object_by_id(obj)
			self.resource_configurations[obj] = [ i[1] for i in sorted(l) ]

		# called when any game (also new ones) start
		# register at player inventory for gold updates
		inv = self.session.world.player.get_component(StorageComponent).inventory
		inv.add_change_listener(self._update_gold, call_listener_now=True)
		self.gold_gui.show()
		self._update_gold() # call once more to make pychan happy

		self.set_inventory_instance(
		  LastActivePlayerSettlementManager().get(get_current_pos=True))
Beispiel #21
0
    def load(self, options):
        """Loads a map. Key method for starting a game."""
        """
		TUTORIAL: Here you see how the vital game elements (and some random things that are also required)
		are initialised.
		"""
        if options.is_scenario:
            # game_identifier is a yaml file, that contains reference to actual map file
            self.scenario_eventhandler = ScenarioEventHandler(
                self, options.game_identifier)
            # scenario maps can be normal maps or scenario maps:
            map_filename = self.scenario_eventhandler.get_map_file()
            options.game_identifier = os.path.join(
                SavegameManager.scenario_maps_dir, map_filename)
            if not os.path.exists(options.game_identifier):
                options.game_identifier = os.path.join(
                    SavegameManager.maps_dir, map_filename)
            options.is_map = True

        self.log.debug("Session: Loading from %s", options.game_identifier)
        savegame_db = SavegameAccessor(
            options.game_identifier, options.is_map)  # Initialize new dbreader
        savegame_data = SavegameManager.get_metadata(savegame_db.db_path)
        self.view.resize_layers(savegame_db)

        # load how often the game has been saved (used to know the difference between
        # a loaded and a new game)
        self.savecounter = savegame_data.get('savecounter', 0)

        if savegame_data.get('rng_state', None):
            rng_state_list = json.loads(savegame_data['rng_state'])

            # json treats tuples as lists, but we need tuples here, so convert back
            def rec_list_to_tuple(x):
                if isinstance(x, list):
                    return tuple(rec_list_to_tuple(i) for i in x)
                else:
                    return x

            rng_state_tuple = rec_list_to_tuple(rng_state_list)
            # changing the rng is safe for mp, as all players have to have the same map
            self.random.setstate(rng_state_tuple)

        self.world = World(
            self
        )  # Load horizons.world module (check horizons/world/__init__.py)
        self.world._init(savegame_db,
                         options.force_player_id,
                         disasters_enabled=options.disasters_enabled)
        self.view.load(savegame_db)  # load view
        if not self.is_game_loaded():
            options.init_new_world(self)
        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.world.init_fish_indexer()  # now the fish should exist
        if self.is_game_loaded():
            LastActivePlayerSettlementManager().load(
                savegame_db)  # before ingamegui
        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.get_component(SelectableComponent).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.current_cursor = 'default'
        self.cursor = SelectionTool(self)
        # Set cursor correctly, menus might need to be opened.
        # Open menus later; they may need unit data not yet inited
        self.cursor.apply_select()

        Scheduler().before_ticking()
        savegame_db.close()

        assert hasattr(self.world, "player"), 'Error: there is no human player'
        """
	def __init__(self, session):
		super(IngameGui, self).__init__()
		self.session = session
		assert isinstance(self.session, horizons.session.Session)
		self.settlement = None
		self._old_menu = None

		self.cursor = None
		self.coordinates_tooltip = None

		self.keylistener = IngameKeyListener(self.session)

		self.cityinfo = CityInfo(self)
		LastActivePlayerSettlementManager.create_instance(self.session)

		self.message_widget = MessageWidget(self.session)

		# Windows
		self.windows = WindowManager()
		self.show_popup = self.windows.show_popup
		self.show_error_popup = self.windows.show_error_popup

		self.logbook = LogBook(self.session, self.windows)
		self.players_overview = PlayersOverview(self.session)
		self.players_settlements = PlayersSettlements(self.session)
		self.players_ships = PlayersShips(self.session)

		self.chat_dialog = ChatDialog(self.windows, self.session)
		self.change_name_dialog = ChangeNameDialog(self.windows, self.session)
		self.pausemenu = PauseMenu(self.session, self, self.windows, in_editor_mode=False)
		self.help_dialog = HelpDialog(self.windows, session=self.session)

		# Icon manager
		self.status_icon_manager = StatusIconManager(
			renderer=self.session.view.renderer['GenericRenderer'],
			layer=self.session.view.layers[LAYERS.OBJECTS]
		)
		self.production_finished_icon_manager = ProductionFinishedIconManager(
			renderer=self.session.view.renderer['GenericRenderer'],
			layer=self.session.view.layers[LAYERS.OBJECTS]
		)

		# 'minimap' is the guichan gui around the actual minimap, which is saved
		# in self.minimap
		self.mainhud = load_uh_widget('minimap.xml')
		self.mainhud.position_technique = "right:top"

		icon = self.mainhud.findChild(name="minimap")
		self.minimap = Minimap(icon,
		                       targetrenderer=horizons.globals.fife.targetrenderer,
		                       imagemanager=horizons.globals.fife.imagemanager,
		                       session=self.session,
		                       view=self.session.view)

		def speed_up():
			SpeedUpCommand().execute(self.session)

		def speed_down():
			SpeedDownCommand().execute(self.session)

		self.mainhud.mapEvents({
			'zoomIn' : self.session.view.zoom_in,
			'zoomOut' : self.session.view.zoom_out,
			'rotateRight' : Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right),
			'rotateLeft' : Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left),
			'speedUp' : speed_up,
			'speedDown' : speed_down,
			'destroy_tool' : self.toggle_destroy_tool,
			'build' : self.show_build_menu,
			'diplomacyButton' : self.show_diplomacy_menu,
			'gameMenuButton' : self.toggle_pause,
			'logbook' : lambda: self.windows.toggle(self.logbook)
		})
		self.mainhud.show()

		hotkey_replacements = {
			'rotateRight': 'ROTATE_RIGHT',
			'rotateLeft': 'ROTATE_LEFT',
			'speedUp': 'SPEED_UP',
			'speedDown': 'SPEED_DOWN',
			'destroy_tool': 'DESTROY_TOOL',
			'build': 'BUILD_TOOL',
			'gameMenuButton': 'ESCAPE',
			'logbook': 'LOGBOOK',
		}
		for (widgetname, action) in hotkey_replacements.iteritems():
			widget = self.mainhud.findChild(name=widgetname)
			keys = horizons.globals.fife.get_keys_for_action(action)
			# No `.upper()` here: "Pause" looks better than "PAUSE".
			keyname = HOTKEYS.DISPLAY_KEY.get(keys[0], keys[0].capitalize())
			widget.helptext = widget.helptext.format(key=keyname)

		self.resource_overview = ResourceOverviewBar(self.session)

		# Register for messages
		SpeedChanged.subscribe(self._on_speed_changed)
		NewDisaster.subscribe(self._on_new_disaster)
		NewSettlement.subscribe(self._on_new_settlement)
		PlayerLevelUpgrade.subscribe(self._on_player_level_upgrade)
		MineEmpty.subscribe(self._on_mine_empty)
		ZoomChanged.subscribe(self._update_zoom)

		self._display_speed(self.session.timer.ticks_per_second)
	def __init__(self, session, gui):
		super(IngameGui, self).__init__()
		self.session = session
		assert isinstance(self.session, horizons.session.Session)
		self.main_gui = gui
		self.settlement = None
		self._old_menu = None

		self.cursor = None
		self.coordinates_tooltip = None

		self.keylistener = IngameKeyListener(self.session)

		self.cityinfo = CityInfo(self)
		LastActivePlayerSettlementManager.create_instance(self.session)

		self.message_widget = MessageWidget(self.session)

		# Windows
		self.windows = WindowManager()

		self.logbook = LogBook(self.session, self.windows)
		self.players_overview = PlayersOverview(self.session)
		self.players_settlements = PlayersSettlements(self.session)
		self.players_ships = PlayersShips(self.session)

		self.chat_dialog = ChatDialog(self.windows, self.session)
		self.change_name_dialog = ChangeNameDialog(self.windows, self.session)
		self.pausemenu = PauseMenu(self.session, self, self.windows, in_editor_mode=False)
		self.help_dialog = HelpDialog(self.windows, session=self.session)

		# Icon manager
		self.status_icon_manager = StatusIconManager(
			renderer=self.session.view.renderer['GenericRenderer'],
			layer=self.session.view.layers[LAYERS.OBJECTS]
		)
		self.production_finished_icon_manager = ProductionFinishedIconManager(
			renderer=self.session.view.renderer['GenericRenderer'],
			layer=self.session.view.layers[LAYERS.OBJECTS]
		)

		# 'minimap' is the guichan gui around the actual minimap, which is saved
		# in self.minimap
		self.mainhud = load_uh_widget('minimap.xml')
		self.mainhud.position_technique = "right+0:top+0"

		icon = self.mainhud.findChild(name="minimap")
		self.minimap = Minimap(icon,
		                       targetrenderer=horizons.globals.fife.targetrenderer,
		                       imagemanager=horizons.globals.fife.imagemanager,
		                       session=self.session,
		                       view=self.session.view)

		def speed_up():
			SpeedUpCommand().execute(self.session)

		def speed_down():
			SpeedDownCommand().execute(self.session)

		self.mainhud.mapEvents({
			'zoomIn' : self.session.view.zoom_in,
			'zoomOut' : self.session.view.zoom_out,
			'rotateRight' : Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right),
			'rotateLeft' : Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left),
			'speedUp' : speed_up,
			'speedDown' : speed_down,
			'destroy_tool' : self.toggle_destroy_tool,
			'build' : self.show_build_menu,
			'diplomacyButton' : self.show_diplomacy_menu,
			'gameMenuButton' : self.toggle_pause,
			'logbook' : lambda: self.windows.toggle(self.logbook)
		})
		self.mainhud.show()

		self.resource_overview = ResourceOverviewBar(self.session)

		# Register for messages
		SpeedChanged.subscribe(self._on_speed_changed)
		NewDisaster.subscribe(self._on_new_disaster)
		NewSettlement.subscribe(self._on_new_settlement)
		PlayerLevelUpgrade.subscribe(self._on_player_level_upgrade)
		MineEmpty.subscribe(self._on_mine_empty)
		self.session.view.add_change_listener(self._update_zoom)

		self._display_speed(self.session.timer.ticks_per_second)
    def set_construction_mode(self, resource_source_instance, build_costs):
        """Show resources relevant to construction and build costs
		@param resource_source_instance: object with StorageComponent
		@param build_costs: dict, { res : amount }
		"""
        if resource_source_instance is None:
            # Build moved out of settlement. This is usually not sane and an interaction error.
            # Use this heuristically computed settlement to fix preconditions.
            resource_source_instance = LastActivePlayerSettlementManager().get(
            )
        if self.construction_mode and \
           resource_source_instance == self.current_instance() and \
           build_costs == self._last_build_costs:
            return  # now that's not an update

        self._last_build_costs = build_costs

        self.construction_mode = True
        self.set_inventory_instance(resource_source_instance,
                                    keep_construction_mode=True)

        # label background icons
        cost_icon_gold = "content/gui/images/background/widgets/resbar_stats_bottom.png"
        cost_icon_res = "content/gui/images/background/widgets/res_extra_bg.png"

        res_list = self._get_current_resources()

        # remove old one before, avoids duplicates
        self._drop_cost_labels()

        for res, amount in build_costs.items():
            assert res in res_list or res == RES.GOLD

            cost_label = Label(text="-" + str(amount))
            cost_label.stylize(self.__class__.STYLE)
            # add icon below end of background icon
            if res in res_list:
                entry = res_list.index(res)
                cur_gui = self.gui[entry]
                reference_icon = cur_gui.findChild(name="background_icon")
                below = reference_icon.size[1]
                cost_icon = Icon(image=cost_icon_res, position=(0, below))
                cost_label.position = (15, below)  # TODO: centering

                cur_gui.addChild(cost_icon)
                cur_gui.addChild(cost_label)
                cur_gui.cost_gui = [cost_label, cost_icon]

                cur_gui.resizeToContent()  # container needs to be bigger now
            else:  # must be gold
                # there is an icon with scales there, use its positioning
                reference_icon = self.gold_gui.child_finder(
                    "balance_background")
                cost_icon = Icon(image=cost_icon_gold,
                                 position=(reference_icon.x, reference_icon.y))
                cost_label.position = (23, 74)  # TODO: centering

                self.gold_gui.addChild(cost_icon)
                self.gold_gui.addChild(cost_label)
                self.gold_gui.cost_gui = [cost_label, cost_icon]

                self.gold_gui.resizeToContent()
Beispiel #25
0
	def set_content(self):
		"""Parses self.row_definitions and sets the content accordingly"""
		settlement = LastActivePlayerSettlementManager().get()
		def _set_entry(button, icon, building_id):
			"""Configure a single build menu button"""
			if self.unlocking_strategy == self.__class__.unlocking_strategies.single_per_increment and \
			   self.get_building_increments()[building_id] > self.session.world.player.settler_level:
				return

			building = Entities.buildings[building_id]
			button.helptext = self.session.db.get_building_tooltip(building_id)

			enough_res = False # don't show building by default
			if settlement is not None: # settlement is None when the mouse has left the settlement
				res_overview = self.session.ingame_gui.resource_overview
				button.mapEvents({
				  button.name+"/mouseEntered/buildtab" : Callback(res_overview.set_construction_mode, settlement, building.costs),
				  button.name+"/mouseExited/buildtab" : res_overview.close_construction_mode
				  })

				(enough_res, missing_res) = Build.check_resources({}, building.costs, settlement.owner, [settlement])
			#check whether to disable build menu icon (not enough res available)
			if enough_res:
				icon.image = "content/gui/images/buttons/buildmenu_button_bg.png"
				path = "content/gui/icons/buildmenu/{id:03d}{{mode}}.png".format(id=building_id)
				button.down_image = path.format(mode='_h')
				button.hover_image = path.format(mode='_h')
			else:
				icon.image = "content/gui/images/buttons/buildmenu_button_bg_bw.png"
				path = "content/gui/icons/buildmenu/greyscale/{id:03d}{{mode}}.png".format(id=building_id)
				button.down_image = path.format(mode='')
				button.hover_image = path.format(mode='')
			button.up_image = path.format(mode='')

			button.capture(Callback(self.build_callback, building_id))

		MAX_ROWS = 4
		MAX_COLS = 4
		for row_num, row in enumerate(self.row_definitions):
			# we have integers for building types, strings for headlines above slots and None as empty slots
			column = -1 # can't use enumerate, not always incremented
			for entry in row:
				column += 1
				position = (10*column) + (row_num+1) # legacy code, first row is 1, 11, 21
				if entry is None:
					continue
				elif (column + 1) > MAX_COLS: # out of 4x4 bounds
					err = "Invalid entry '%s': column %s does not exist." % (entry, column + 1)
					err += " Max. column amount in current layout is %s." % MAX_COLS
					raise InvalidBuildMenuFileFormat(err)
				elif row_num > MAX_ROWS: # out of 4x4 bounds
					err = "Invalid entry '%s': row %s does not exist." % (entry, row_num)
					err += " Max. row amount in current layout is %s." % MAX_ROWS
					raise InvalidBuildMenuFileFormat(err)
				elif isinstance(entry, basestring):
					column -= 1 # a headline does not take away a slot
					lbl = self.widget.child_finder('label_{position:02d}'.format(position=position))
					lbl.text = _(entry[2:]) if entry.startswith('_ ') else entry
				elif isinstance(entry, int):
					button = self.widget.child_finder('button_{position:02d}'.format(position=position))
					icon = self.widget.child_finder('icon_{position:02d}'.format(position=position))
					_set_entry(button, icon, entry)
				else:
					raise InvalidBuildMenuFileFormat("Invalid entry: %s" % entry)
Beispiel #26
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = _("Failed to create savegame file")
            descr = _(
                "There has been an error while creating your savegame file.")
            advice = _(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.gui.show_error_popup(headline, descr, advice, unicode(e))
            return self.save(
            )  # retry with new savegamename entered by the user
            # this must not happen with quicksave/autosave
        except OSError as e:
            if e.errno == errno.EACCES:
                self.gui.show_error_popup(
                    _("Access is denied"),
                    _("The savegame file could be read-only or locked by another process."
                      ))
                return self.save()
            raise

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            #self.manager.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)
            LastActivePlayerSettlementManager().save(db)

            for instance in self.selected_instances:
                db("INSERT INTO selected(`group`, id) VALUES(NULL, ?)",
                   instance.worldid)
            for group in xrange(len(self.selection_groups)):
                for instance in self.selection_groups[group]:
                    db("INSERT INTO selected(`group`, id) VALUES(?, ?)", group,
                       instance.worldid)

            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)
            # make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except:
            print "Save Exception"
            traceback.print_exc()
            db.close()  # close db before delete
            os.unlink(savegame)  # remove invalid savegamefile
            return False
Beispiel #27
0
 def save(self, db):
     self.message_widget.save(db)
     self.logbook.save(db)
     self.resource_overview.save(db)
     LastActivePlayerSettlementManager().save(db)
Beispiel #28
0
    def set_content(self):
        """Parses self.row_definitions and sets the content accordingly"""
        settlement = LastActivePlayerSettlementManager().get()

        def _set_entry(button, icon, building_id):
            """Configure a single build menu button"""
            if self.unlocking_strategy == self.__class__.unlocking_strategies.single_per_tier and \
               self.get_building_tiers()[building_id] > self.session.world.player.settler_level:
                return

            building = Entities.buildings[building_id]
            button.helptext = building.get_tooltip()

            # Add necessary resources to tooltip text.
            # tooltip.py will then place icons from this information.
            required_resources = ''
            for resource_id, amount_needed in sorted(building.costs.items()):
                required_resources += ' {}:{}'.format(resource_id,
                                                      amount_needed)
            required_text = '[[Buildmenu{}]]'.format(required_resources)
            button.helptext = required_text + button.helptext

            enough_res = False  # don't show building by default
            if settlement is not None:  # settlement is None when the mouse has left the settlement
                res_overview = self.session.ingame_gui.resource_overview
                show_costs = Callback(res_overview.set_construction_mode,
                                      settlement, building.costs)
                button.mapEvents({
                    button.name + "/mouseEntered/buildtab":
                    show_costs,
                    button.name + "/mouseExited/buildtab":
                    res_overview.close_construction_mode
                })

                (enough_res,
                 missing_res) = Build.check_resources({}, building.costs,
                                                      settlement.owner,
                                                      [settlement])
            # Check whether to disable build menu icon (not enough res available).
            if enough_res:
                icon.image = "content/gui/images/buttons/buildmenu_button_bg.png"
                button.path = "icons/buildmenu/{id:03d}".format(id=building_id)
            else:
                icon.image = "content/gui/images/buttons/buildmenu_button_bg_bw.png"
                button.path = "icons/buildmenu/greyscale/{id:03d}".format(
                    id=building_id)

            button.capture(Callback(self.build_callback, building_id))

        for row_num, row in enumerate(self.row_definitions):
            # we have integers for building types, strings for headlines above slots and None as empty slots
            column = -1  # can't use enumerate, not always incremented
            for entry in row:
                column += 1
                position = (10 * column) + (
                    row_num + 1)  # legacy code, first row is 1, 11, 21
                if entry is None:
                    continue
                elif (column + 1) > self.MAX_COLS:
                    # out of 4x4 bounds
                    err = "Invalid entry '{}': column {} does not exist.".format(
                        entry, column + 1)
                    err += " Max. column amount in current layout is {}.".format(
                        self.MAX_COLS)
                    raise InvalidBuildMenuFileFormat(err)
                elif row_num > self.MAX_ROWS:
                    # out of 4x4 bounds
                    err = "Invalid entry '{}': row {} does not exist.".format(
                        entry, row_num)
                    err += " Max. row amount in current layout is {}.".format(
                        self.MAX_ROWS)
                    raise InvalidBuildMenuFileFormat(err)
                elif isinstance(entry, str):
                    column -= 1  # a headline does not take away a slot
                    lbl = self.widget.child_finder(
                        'label_{position:02d}'.format(position=position))
                    lbl.text = T(
                        entry[2:]) if entry.startswith('_ ') else entry
                elif isinstance(entry, int):
                    button = self.widget.child_finder(
                        'button_{position:02d}'.format(position=position))
                    icon = self.widget.child_finder(
                        'icon_{position:02d}'.format(position=position))
                    _set_entry(button, icon, entry)
                else:
                    raise InvalidBuildMenuFileFormat(
                        "Invalid entry: {}".format(entry))
Beispiel #29
0
    def __init__(self, session):
        super(IngameGui, self).__init__()
        self.session = session
        assert isinstance(self.session, horizons.session.Session)
        self.settlement = None
        self._old_menu = None

        self.cursor = None
        self.coordinates_tooltip = None

        self.keylistener = IngameKeyListener(self.session)

        self.cityinfo = CityInfo(self)
        LastActivePlayerSettlementManager.create_instance(self.session)

        self.message_widget = MessageWidget(self.session)

        # Windows
        self.windows = WindowManager()
        self.show_popup = self.windows.show_popup
        self.show_error_popup = self.windows.show_error_popup

        self.logbook = LogBook(self.session, self.windows)
        self.players_overview = PlayersOverview(self.session)
        self.players_settlements = PlayersSettlements(self.session)
        self.players_ships = PlayersShips(self.session)

        self.chat_dialog = ChatDialog(self.windows, self.session)
        self.change_name_dialog = ChangeNameDialog(self.windows, self.session)
        self.pausemenu = PauseMenu(self.session,
                                   self,
                                   self.windows,
                                   in_editor_mode=False)
        self.help_dialog = HelpDialog(self.windows, session=self.session)

        # Icon manager
        self.status_icon_manager = StatusIconManager(
            renderer=self.session.view.renderer['GenericRenderer'],
            layer=self.session.view.layers[LAYERS.OBJECTS])
        self.production_finished_icon_manager = ProductionFinishedIconManager(
            renderer=self.session.view.renderer['GenericRenderer'],
            layer=self.session.view.layers[LAYERS.OBJECTS])

        # 'minimap' is the guichan gui around the actual minimap, which is saved
        # in self.minimap
        self.mainhud = load_uh_widget('minimap.xml')
        self.mainhud.position_technique = "right:top"

        icon = self.mainhud.findChild(name="minimap")
        self.minimap = Minimap(
            icon,
            targetrenderer=horizons.globals.fife.targetrenderer,
            imagemanager=horizons.globals.fife.imagemanager,
            session=self.session,
            view=self.session.view)

        def speed_up():
            SpeedUpCommand().execute(self.session)

        def speed_down():
            SpeedDownCommand().execute(self.session)

        self.mainhud.mapEvents({
            'zoomIn':
            self.session.view.zoom_in,
            'zoomOut':
            self.session.view.zoom_out,
            'rotateRight':
            Callback.ChainedCallbacks(self.session.view.rotate_right,
                                      self.minimap.rotate_right),
            'rotateLeft':
            Callback.ChainedCallbacks(self.session.view.rotate_left,
                                      self.minimap.rotate_left),
            'speedUp':
            speed_up,
            'speedDown':
            speed_down,
            'destroy_tool':
            self.toggle_destroy_tool,
            'build':
            self.show_build_menu,
            'diplomacyButton':
            self.show_diplomacy_menu,
            'gameMenuButton':
            self.toggle_pause,
            'logbook':
            lambda: self.windows.toggle(self.logbook)
        })
        self.mainhud.show()

        self.resource_overview = ResourceOverviewBar(self.session)

        # Register for messages
        SpeedChanged.subscribe(self._on_speed_changed)
        NewDisaster.subscribe(self._on_new_disaster)
        NewSettlement.subscribe(self._on_new_settlement)
        PlayerLevelUpgrade.subscribe(self._on_player_level_upgrade)
        MineEmpty.subscribe(self._on_mine_empty)
        self.session.view.add_change_listener(self._update_zoom)

        self._display_speed(self.session.timer.ticks_per_second)
    def __init__(self, session):
        super(IngameGui, self).__init__()
        self.session = session
        assert isinstance(self.session, horizons.session.Session)
        self.settlement = None
        self._old_menu = None

        self.cursor = None
        self.coordinates_tooltip = None

        self.keylistener = IngameKeyListener(self.session)

        self.cityinfo = CityInfo(self)
        LastActivePlayerSettlementManager.create_instance(self.session)

        self.message_widget = MessageWidget(self.session)

        # Windows
        self.windows = WindowManager()
        self.open_popup = self.windows.open_popup
        self.open_error_popup = self.windows.open_error_popup

        self.logbook = LogBook(self.session, self.windows)
        self.players_overview = PlayersOverview(self.session)
        self.players_settlements = PlayersSettlements(self.session)
        self.players_ships = PlayersShips(self.session)

        self.chat_dialog = ChatDialog(self.windows, self.session)
        self.change_name_dialog = ChangeNameDialog(self.windows, self.session)
        self.pausemenu = PauseMenu(self.session,
                                   self,
                                   self.windows,
                                   in_editor_mode=False)
        self.help_dialog = HelpDialog(self.windows)

        # Icon manager
        self.status_icon_manager = StatusIconManager(
            renderer=self.session.view.renderer['GenericRenderer'],
            layer=self.session.view.layers[LAYERS.OBJECTS])
        self.production_finished_icon_manager = ProductionFinishedIconManager(
            renderer=self.session.view.renderer['GenericRenderer'],
            layer=self.session.view.layers[LAYERS.OBJECTS])

        # 'minimap' is the guichan gui around the actual minimap, which is saved
        # in self.minimap
        self.mainhud = load_uh_widget('minimap.xml')
        self.mainhud.position_technique = "right:top"

        icon = self.mainhud.findChild(name="minimap")
        self.minimap = Minimap(
            icon,
            targetrenderer=horizons.globals.fife.targetrenderer,
            imagemanager=horizons.globals.fife.imagemanager,
            session=self.session,
            view=self.session.view)

        def speed_up():
            SpeedUpCommand().execute(self.session)

        def speed_down():
            SpeedDownCommand().execute(self.session)

        self.mainhud.mapEvents({
            'zoomIn':
            self.session.view.zoom_in,
            'zoomOut':
            self.session.view.zoom_out,
            'rotateRight':
            Callback.ChainedCallbacks(self.session.view.rotate_right,
                                      self.minimap.rotate_right),
            'rotateLeft':
            Callback.ChainedCallbacks(self.session.view.rotate_left,
                                      self.minimap.rotate_left),
            'speedUp':
            speed_up,
            'speedDown':
            speed_down,
            'destroy_tool':
            self.toggle_destroy_tool,
            'build':
            self.show_build_menu,
            'diplomacyButton':
            self.show_diplomacy_menu,
            'gameMenuButton':
            self.toggle_pause,
            'logbook':
            lambda: self.windows.toggle(self.logbook)
        })
        self.mainhud.show()

        hotkey_replacements = {
            'rotateRight': 'ROTATE_RIGHT',
            'rotateLeft': 'ROTATE_LEFT',
            'speedUp': 'SPEED_UP',
            'speedDown': 'SPEED_DOWN',
            'destroy_tool': 'DESTROY_TOOL',
            'build': 'BUILD_TOOL',
            'gameMenuButton': 'ESCAPE',
            'logbook': 'LOGBOOK',
        }
        for (widgetname, action) in hotkey_replacements.iteritems():
            widget = self.mainhud.findChild(name=widgetname)
            keys = horizons.globals.fife.get_keys_for_action(action)
            # No `.upper()` here: "Pause" looks better than "PAUSE".
            keyname = HOTKEYS.DISPLAY_KEY.get(keys[0], keys[0].capitalize())
            widget.helptext = widget.helptext.format(key=keyname)

        self.resource_overview = ResourceOverviewBar(self.session)

        # Register for messages
        SpeedChanged.subscribe(self._on_speed_changed)
        NewDisaster.subscribe(self._on_new_disaster)
        NewSettlement.subscribe(self._on_new_settlement)
        PlayerLevelUpgrade.subscribe(self._on_player_level_upgrade)
        MineEmpty.subscribe(self._on_mine_empty)
        ZoomChanged.subscribe(self._update_zoom)

        self._display_speed(self.session.timer.ticks_per_second)