Esempio n. 1
0
	def __init__(self, db, rng_seed=None):
		"""
		Unfortunately, right now there is no other way to setup Dummy versions of the GUI,
		View etc., unless we want to patch the references in the session module.
		"""
		super(LivingObject, self).__init__()
		self.gui = Dummy()
		self.db = db
		self.savecounter = 0	# this is a new game.
		self.is_alive = True

		WorldObject.reset()
		NamedObject.reset()
		AIPlayer.clear_caches()

		# Game
		self.current_tick = 0
		self.random = self.create_rng(rng_seed)
		self.timer = self.create_timer()
		Scheduler.create_instance(self.timer)
		ExtScheduler.create_instance(Dummy)
		self.manager = self.create_manager()
		self.view = Dummy()
		self.view.renderer = Dummy()
		Entities.load(self.db)
		self.scenario_eventhandler = Dummy()
		self.campaign = {}
		self.selected_instances = []

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

		GAME_SPEED.TICKS_PER_SECOND = 16
Esempio n. 2
0
def quit():
	"""Quits the game"""
	global fife
	if _modules.session is not None and _modules.session.is_alive:
		_modules.session.end()
	preload_game_join(preloading)
	ExtScheduler.destroy_instance()
	fife.quit()
Esempio n. 3
0
	def cleanup(cls):
		"""
		If a test uses manual session management, we cannot be sure that session.end was
		called before a crash, leaving the game in an unclean state. This method should
		return the game to a valid state.
		"""
		Scheduler.destroy_instance()
		ExtScheduler.destroy_instance()
		SPSession._clear_caches()
Esempio n. 4
0
    def remove(self):
        if self.__class__.send_hover_instances_update:
            self.session.view.remove_change_listener(
                self._schedule_hover_instance_update)
        if self._hover_instances_update_scheduled:
            ExtScheduler().rem_call(self, self._send_hover_instance_upate)

        horizons.globals.fife.eventmanager.removeCommandListener(self.cmdlist)
        super(NavigationTool, self).remove()
Esempio n. 5
0
    def load(self, db, worldid):
        super(AmbientSoundComponent, self).load(db, worldid)
        self.__init()
        # don't start playing all at once

        interval = (0, self.__class__.AMBIENT_SOUND_INTERVAL +
                    self.__class__.AMBIENT_SOUND_INTERVAL_VARIANCE[1])
        run_in = random.randint(*interval)
        ExtScheduler().add_new_object(self._init_playing, self, run_in=run_in)
Esempio n. 6
0
 def disable_sound(self):
     """Disable all sound outputs."""
     if self.emitter['bgsound'] is not None:
         self.emitter['bgsound'].reset()
     if self.emitter['effects'] is not None:
         self.emitter['effects'].reset()
     if self.emitter['speech'] is not None:
         self.emitter['speech'].reset()
     ExtScheduler().rem_call(self, self.check_music)
	def _show_stats(self):
		"""Show data below gold icon when balance label is clicked"""
		if self.stats_gui is None:
			self._init_stats_gui()

		self._update_stats()
		self.stats_gui.show()

		ExtScheduler().add_new_object(self._update_stats, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
Esempio n. 8
0
	def _apply_layout_hack(self):
		# pychan layouting depends on time, it's usually in a better mood later.
		# this introduces some flickering, but fixes #916
		from horizons.extscheduler import ExtScheduler
		def do_apply_hack():
			# just query widget when executing, since if lazy loading is used, the widget
			# does not exist yet in the outer function
			self.current_tab.widget.adaptLayout()
		ExtScheduler().add_new_object(do_apply_hack, self, run_in=0)
Esempio n. 9
0
    def disable(self):
        """Due to the way the minimap works, there isn't really a show/hide,
		but you can disable it with this and enable again with draw().
		Stops all updates."""
        ExtScheduler().rem_all_classinst_calls(self)
        if self.view is not None:
            self.view.discard_change_listener(self.update_cam)

        if self in self.__class__._instances:
            self.__class__._instances.remove(self)
Esempio n. 10
0
    def draw(self):
        """Recalculates and draws the whole minimap of self.session.world or world.
		The world you specified is reused for every operation until the next draw().
		"""
        if self.world is None and self.session.world is not None:
            self.world = self.session.world  # in case minimap has been constructed before the world
        if not self.world.inited:
            return  # don't draw while loading
        if self.transform is None:
            self.transform = _MinimapTransform(self.world.map_dimensions,
                                               self.location, 0,
                                               self._get_rotation_setting())
            self.update_rotation()

        self.__class__._instances.append(self)

        # update cam when view updates
        if self.view is not None and not self.view.has_change_listener(
                self.update_cam):
            self.view.add_change_listener(self.update_cam)

        if not hasattr(self, "icon"):
            # add to global generic renderer with id specific to this instance
            self.renderer.removeAll("minimap_image" + self._id)
            self.minimap_image.reset()
            # NOTE: this is for the generic renderer interface, the offrenderer has slightly different methods
            node = fife.RendererNode(
                fife.Point(self.location.center.x, self.location.center.y))
            self.renderer.addImage("minimap_image" + self._id, node,
                                   self.minimap_image.image, False)

        else:
            # attach image to pychan icon (recommended)
            self.minimap_image.reset()
            self.icon.image = fife.GuiImage(self.minimap_image.image)

        self.update_cam()
        self._recalculate()
        if not self.preview:
            self._timed_update(force=True)
            ExtScheduler().rem_all_classinst_calls(self)
            ExtScheduler().add_new_object(self._timed_update, self,
                                          self.SHIP_DOT_UPDATE_INTERVAL, -1)
Esempio n. 11
0
 def set_network_port(self, port):
     """Sets a new value for client network port"""
     # port is saved as string due to pychan limitations
     try:
         # 0 is not a valid port, but a valid value here (used for default)
         parse_port(port)
     except ValueError:
         headline = _("Invalid network port")
         descr = _(
             "The port you specified is not valid. It must be a number between 1 and 65535."
         )
         advice = _(
             "Please check the port you entered and make sure it is in the specified range."
         )
         horizons.main._modules.gui.show_error_popup(
             headline, descr, advice)
         # reset value and reshow settings dlg
         self.engine.set_uh_setting("NetworkPort", u"0")
         ExtScheduler().add_new_object(self._setting.onOptionsPress,
                                       self.engine, 0)
     else:
         # port is valid
         try:
             if NetworkInterface() is None:
                 NetworkInterface.create_instance()
             NetworkInterface().network_data_changed()
         except Exception as e:
             headline = _(u"Failed to apply new network settings.")
             descr = _(
                 "Network features could not be initialized with the current configuration."
             )
             advice = _(
                 "Check the settings you specified in the network section.")
             if 0 < parse_port(port) < 1024:
                 #i18n This is advice for players seeing a network error with the current config
                 advice += u" " + \
                  _("Low port numbers sometimes require special access privileges, try 0 or a number greater than 1024.")
             details = unicode(e)
             horizons.main._modules.gui.show_error_popup(
                 headline, descr, advice, details)
             ExtScheduler().add_new_object(self._setting.onOptionsPress,
                                           self.engine, 0)
Esempio n. 12
0
	def _schedule_refresh(self):
		"""Schedule a refresh soon, dropping all other refresh request, that appear until then.
		This saves a lot of CPU time, if you have a huge island, or play on high speed."""
		if not self._refresh_scheduled:
			self._refresh_scheduled = True
			def unset_flag():
				# set the flag here and not in refresh() since we can't be sure whether
				# refresh() of this class will be reached or a subclass will not call super()
				self._refresh_scheduled = False
			ExtScheduler().add_new_object(Callback.ChainedCallbacks(unset_flag, self.refresh),
			                              self, run_in=self.__class__.scheduled_update_delay)
Esempio n. 13
0
    def show_text(self, index):
        """Shows the text for a button.
		@param index: index of button"""
        assert isinstance(index, int)
        ExtScheduler().rem_call(
            self, self.hide_text)  # stop hiding if a new text has been shown
        label = self.text_widget.findChild(name='text')
        label.text = unicode(self.active_messages[self.position +
                                                  index].message)
        label.adaptLayout()
        self.text_widget.show()
Esempio n. 14
0
    def start(self, interval, loops):
        """Starts the animation.
		@param interval: seconds
		@param loops: number of loops or -1 for infininte
		"""
        self.interval = interval
        self._next()
        ExtScheduler().add_new_object(self._next,
                                      self,
                                      run_in=interval,
                                      loops=loops)
Esempio n. 15
0
 def show(self):
     run_in = PLAYER.STATS_UPDATE_FREQUENCY / GAME_SPEED.TICKS_PER_SECOND
     ExtScheduler().add_new_object(Callback(self._refresh_tick),
                                   self,
                                   run_in=run_in,
                                   loops=-1)
     if not self._initialised:
         self._initialised = True
         self._init_gui()
     self.refresh()
     self._gui.show()
Esempio n. 16
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()
Esempio n. 17
0
	def set_settlement(self, settlement):
		"""Sets the city name at top center of screen.

		Show/Hide is handled automatically
		"""
		if self._settlement:
			self._settlement.remove_change_listener(self._update_settlement)

		self._settlement = settlement

		if not settlement:
			# Hide the widget (after some seconds).
			# Delayed to allow players scrolling away to click on the widget.
			# This often happens when moving mouse up from island to reach it.
			ExtScheduler().add_new_object(self.hide, self, run_in=GUI.CITYINFO_UPDATE_DELAY)
		else:
			# Cancel previously scheduled hide if a settlement is hovered again.
			ExtScheduler().rem_call(self, self.hide)

			self._update_settlement()  # This calls show()!
			settlement.add_change_listener(self._update_settlement)
Esempio n. 18
0
 def end(self):
     self._remove_listeners()
     self._remove_building_instances()
     self._remove_coloring()
     self._buildable_tiles = None
     self._modified_objects = None
     self.buildings = None
     if self.gui is not None:
         self.session.view.remove_change_listener(self.draw_gui)
         self.gui.hide()
     ExtScheduler().rem_all_classinst_calls(self)
     super(BuildingTool, self).end()
Esempio n. 19
0
	def end(self):
		self.set_inventory_instance( None, force_update=True )
		self.current_instance = weakref.ref(self)
		ExtScheduler().rem_all_classinst_calls(self)
		self.resource_configurations.clear()
		self.hide()
		self.gold_gui = None
		self.gui = None
		self.stats_gui = None
		self._custom_default_resources = None
		NewPlayerSettlementHovered.unsubscribe(self._on_different_settlement)
		TabWidgetChanged.unsubscribe(self._on_tab_widget_changed)
Esempio n. 20
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
Esempio n. 21
0
    def __init__(self, session):
        from horizons.session import Session
        assert isinstance(session, Session)
        self.session = session

        # special slot because of special properties
        self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE,
                                       style=self.__class__.STYLE)
        self.gold_gui.balance_visible = False
        self.gold_gui.child_finder = PychanChildFinder(self.gold_gui)
        gold_icon = self.gold_gui.child_finder("res_icon")
        gold_icon.image = get_res_icon_path(RES.GOLD)
        gold_icon.max_size = gold_icon.min_size = gold_icon.size = (32, 32)
        self.gold_gui.mapEvents({
            "resbar_gold_container/mouseClicked/stats":
            self._toggle_stats,
        })
        self.gold_gui.helptext = T("Click to show statistics")
        self.stats_gui = None

        self.gui = []  # list of slots
        self.resource_configurations = weakref.WeakKeyDictionary()
        self.current_instance = weakref.ref(self)  # can't weakref to None
        self.construction_mode = False
        self._last_build_costs = None
        self._do_show_dummy = False

        self._update_default_configuration()

        NewPlayerSettlementHovered.subscribe(self._on_different_settlement)
        TabWidgetChanged.subscribe(self._on_tab_widget_changed)

        # set now and then every few sec
        ExtScheduler().add_new_object(self._update_balance_display,
                                      self,
                                      run_in=0)
        ExtScheduler().add_new_object(self._update_balance_display,
                                      self,
                                      run_in=Player.STATS_UPDATE_INTERVAL,
                                      loops=-1)
    def _poll_preview_process(self):
        """This will be called regularly to see if the process ended.

		If the process has not yet finished, schedule a new callback to this function.
		Otherwise use the data to update the minimap.
		"""
        if not self._preview_process:
            return

        self._preview_process.poll()

        if self._preview_process.returncode is None:  # not finished
            ExtScheduler().add_new_object(self._poll_preview_process, self,
                                          0.1)
            return
        elif self._preview_process.returncode != 0:
            self._preview_process = None
            self._set_map_preview_status(
                "An unknown error occurred while generating the map preview")
            return

        with open(self._preview_output, 'r') as f:
            data = f.read()
            # Sometimes the subprocess outputs more then the minimap data, e.g. debug
            # information. Since we just read from its stdout, parse out the data that
            # is relevant to us.
            data = re.findall(r'^DATA (\[\[.*\]\]) ENDDATA$', data,
                              re.MULTILINE)[0]
            data = json.loads(data)

        os.unlink(self._preview_output)
        self._preview_process = None

        if self._map_preview:
            self._map_preview.end()

        self._map_preview = Minimap(
            self._gui.findChild(name='map_preview_minimap'),
            session=None,
            view=None,
            world=None,
            targetrenderer=horizons.globals.fife.targetrenderer,
            imagemanager=horizons.globals.fife.imagemanager,
            cam_border=False,
            use_rotation=False,
            tooltip=T("Click to generate a different random map"),
            on_click=self._on_preview_click,
            preview=True)

        self._map_preview.draw_data(data)
        self._set_map_preview_status("")
Esempio n. 23
0
    def wait_for_task():
        """
		Continuously check whether the thread is done.
		"""
        if thread.is_alive():
            ExtScheduler().add_new_object(wait_for_task, None)
        else:
            if result:
                gui = horizons.main._modules.gui
                window = VersionHint(gui.windows, result)
                gui.windows.open(window)
            else:
                # couldn't retrieve file or nothing relevant in there
                pass
Esempio n. 24
0
	def position_tooltip(self, event):
		if (event.getButton() == fife.MouseEvent.MIDDLE):
			return
		widget_position = self.getAbsolutePos()
		screen_width = horizons.main.fife.engine_settings.getScreenWidth()
		self.gui.y = widget_position[1] + event.getY() + 5
		if (widget_position[0] + event.getX() +self.gui.size[0] + 10) <= screen_width:
			self.gui.x = widget_position[0] + event.getX() + 10
		else:
			self.gui.x = widget_position[0] + event.getX() - self.gui.size[0] - 5
		if not self.tooltip_shown:
			ExtScheduler().add_new_object(self.show_tooltip, self, run_in=0.3, loops=0)
			self.tooltip_shown = True
		else:
			self.gui.show()
	def __init__(self):
		self.__setup_client()
		# cbs means callbacks
		self.cbs_game_details_changed = []
		self.cbs_game_starts = []
		self.cbs_p2p_ready = []
		self.cbs_error = [] # cbs with 1 parameter which is an Exception instance
		self._client.register_callback("lobbygame_join", self._cb_game_details_changed)
		self._client.register_callback("lobbygame_leave", self._cb_game_details_changed)
		self._client.register_callback("lobbygame_starts", self._cb_game_starts)
		self._client.register_callback("p2p_ready", self._cb_p2p_ready)
		self._client.register_callback("p2p_data", self._cb_p2p_data)
		self.received_packets = []

		ExtScheduler().add_new_object(self.ping, self, self.PING_INTERVAL, -1)
Esempio n. 26
0
	def _on_damage(self, caller=None):
		"""Called when health has changed"""
		if not self._instance: # dead
			# it is sometimes hard to avoid this being called after the unit has died,
			# e.g. when it's part of a list of changelisteners, and one of the listeners executed before kills the unit
			return
		health_was_displayed_before = self._health_displayed
		# always update
		self.draw_health()
		if health_was_displayed_before:
			return # don't schedule removal
		# remember that it has been drawn automatically
		self._last_draw_health_call_on_damage = True
		# remove later (but only in case there's no manual interference)
		ExtScheduler().add_new_object(Callback(self.draw_health, auto_remove=True),
		                              self, self.__class__.AUTOMATIC_HEALTH_DISPLAY_TIMEOUT)
    def start_single(self):
        """ Starts a single player horizons. """
        assert self.current is self.widgets['singleplayermenu']
        playername = self.current.playerdata.get_player_name()
        if not playername:
            self.show_popup(_("Invalid player name"),
                            _("You entered an invalid playername."))
            return
        playercolor = self.current.playerdata.get_player_color()
        self._save_player_name()

        if self.current.collectData('random'):
            map_file = self._get_random_map_file()
        else:
            assert self.active_right_side.collectData('maplist') != -1
            map_file = self._get_selected_map()

        is_scenario = bool(self.current.collectData('scenario'))
        if not is_scenario:
            ai_players = int(self.current.aidata.get_ai_players())
            horizons.globals.fife.set_uh_setting("AIPlayers", ai_players)
        horizons.globals.fife.save_settings()

        self.show_loading_screen()
        if is_scenario:
            try:
                options = StartGameOptions.create_start_scenario(map_file)
                options.set_human_data(playername, playercolor)
                horizons.main.start_singleplayer(options)
            except InvalidScenarioFileFormat as e:
                self._show_invalid_scenario_file_popup(e)
                self._select_single(show='scenario')
        else:  # free play/random map
            options = StartGameOptions.create_start_map(map_file)
            options.set_human_data(playername, playercolor)
            options.ai_players = ai_players
            options.trader_enabled = self.widgets['game_settings'].findChild(
                name='free_trader').marked
            options.pirate_enabled = self.widgets['game_settings'].findChild(
                name='pirates').marked
            options.disasters_enabled = self.widgets[
                'game_settings'].findChild(name='disasters').marked
            options.natural_resource_multiplier = self._get_natural_resource_multiplier(
            )
            horizons.main.start_singleplayer(options)

        ExtScheduler().rem_all_classinst_calls(self)
Esempio n. 28
0
    def _show_stats(self):
        """Show data below gold icon when balance label is clicked"""
        if self.stats_gui is None:
            reference_icon = self.gold_gui.child_finder("balance_background")
            self.stats_gui = load_uh_widget(self.__class__.STATS_GUI_FILE)
            self.stats_gui.child_finder = PychanChildFinder(self.stats_gui)
            self.stats_gui.position = (reference_icon.x + self.gold_gui.x,
                                       reference_icon.y + self.gold_gui.y)
            self.stats_gui.mapEvents({
                'resbar_stats_container/mouseClicked/stats':
                self._toggle_stats
            })

            images = [  # these must correspond to the entries in _update_stats
                "content/gui/images/resbar_stats/expense.png",
                "content/gui/images/resbar_stats/income.png",
                "content/gui/images/resbar_stats/buy.png",
                "content/gui/images/resbar_stats/sell.png",
                "content/gui/images/resbar_stats/scales_icon.png",
            ]

            for num, image in enumerate(images):
                # keep in sync with comment there until we can use that data:
                # ./content/gui/xml/ingame/hud/resource_overview_bar_stats.xml
                box = HBox(padding=0,
                           min_size=(70, 0),
                           name="resbar_stats_line_%s" % num)
                box.addChild(Icon(image=image))
                box.addSpacer(Spacer())
                box.addChild(Label(name="resbar_stats_entry_%s" % num))
                # workaround for fife font bug, probably http://fife.trac.cloudforge.com/engine/ticket/666
                box.addChild(Label(text=u" "))

                if num < len(images) - 1:  # regular one
                    self.stats_gui.child_finder("entries_box").addChild(box)
                else:  # last one
                    self.stats_gui.child_finder("bottom_box").addChild(box)
                    self.stats_gui.child_finder("bottom_box").stylize(
                        'resource_bar')

        self._update_stats()
        self.stats_gui.show()

        ExtScheduler().add_new_object(self._update_stats,
                                      self,
                                      run_in=Player.STATS_UPDATE_INTERVAL,
                                      loops=-1)
Esempio n. 29
0
    def position_tooltip(self, event):
        """Calculates a nice position for the tooltip.
		@param event: mouse event from fife or tuple screenpoint
		"""
        # TODO: think about nicer way of handling the polymorphism here,
        # e.g. a position_tooltip_event and a position_tooltip_tuple
        where = event  # fife forces this to be called event, but here it can also be a tuple
        if isinstance(where, tuple):
            x, y = where
        else:
            if where.getButton() == fife.MouseEvent.MIDDLE:
                return

            x, y = where.getX(), where.getY()

        if self.gui is None:
            self.__init_gui()

        widget_position = self.getAbsolutePos()

        # Sometimes, we get invalid events from pychan, it is probably related to changing the
        # gui when the mouse hovers on gui elements.
        # Random tests have given evidence to believe that pychan indicates invalid events
        # by setting the top container's position to 0, 0.
        # Since this position is currently unused, it can serve as invalid flag,
        # and dropping these events seems to lead to the desired placements
        def get_top(w):
            return get_top(w.parent) if w.parent else w

        top_pos = get_top(self).position
        if top_pos == (0, 0):
            return

        screen_width = horizons.globals.fife.engine_settings.getScreenWidth()
        self.gui.y = widget_position[1] + y + 5
        offset = x + 10
        if (widget_position[0] + self.gui.size[0] + offset) > screen_width:
            # right screen edge, position to the left of cursor instead
            offset = x - self.gui.size[0] - 5
        self.gui.x = widget_position[0] + offset
        if not self.tooltip_shown:
            ExtScheduler().add_new_object(self.show_tooltip,
                                          self,
                                          run_in=0.3,
                                          loops=0)
            self.tooltip_shown = True
	def __init__(self, session, x, y):
		super(LivingObject, self).__init__()
		self.session = session
		self.x_pos, self.y_pos = x, y
		self.active_messages = [] # for displayed messages
		self.archive = [] # messages, that aren't displayed any more
		self.widget = load_xml_translated('hud_messages.xml')
		self.widget.position = (
			 5,
			 horizons.main.fife.engine_settings.getScreenHeight()/2 - self.widget.size[1]/2)

		self.text_widget = load_xml_translated('hud_messages_text.xml')
		self.text_widget.position = (self.widget.x + self.widget.width, self.widget.y)
		self.widget.show()
		self.current_tick = 0
		self.position = 0 # number of current message
		ExtScheduler().add_new_object(self.tick, self, loops=-1)
    def show_text(self, index):
        """Shows the text for a button.
		@param index: index of button"""
        assert isinstance(index, int)
        # stop hiding if a new text has been shown
        ExtScheduler().rem_call(self, self.hide_text)

        try:
            text = self.active_messages[index].message
        except IndexError:
            # Something went wrong, try to find out what. Also see #2273.
            self.log.error(
                u'Tried to access message at index %s, only have %s. Messages:',
                index, len(self.active_messages))
            self.log.error(u'\n'.join(
                unicode(m) for m in self.active_messages))
            text = (u'Error trying to access message!\n'
                    u'Please report a bug. Thanks!')

        text = text.replace(r'\n', self.CHARS_PER_LINE * ' ')
        text = text.replace('[br]', self.CHARS_PER_LINE * ' ')
        text = textwrap.fill(text, self.CHARS_PER_LINE)

        self.bg_middle = self.text_widget.findChild(name='msg_bg_middle')
        self.bg_middle.removeAllChildren()

        line_count = len(text.splitlines()) - 1
        for i in xrange(line_count * self.LINE_HEIGHT // self.IMG_HEIGHT):
            middle_icon = Icon(image=self.BG_IMAGE_MIDDLE)
            self.bg_middle.addChild(middle_icon)

        button = self.widget.findChild(name=str(index))
        # y position relative to parent
        button_y = button.position[1]
        # Show text next to corresponding icon
        x, y = self.reference_text_widget_position
        self.text_widget.position = (x, y + button_y)

        message_container = self.text_widget.findChild(name='message')
        message_container.size = (300, 21 + self.IMG_HEIGHT * line_count + 21)

        self.bg_middle.adaptLayout()
        label = self.text_widget.findChild(name='text')
        label.text = text
        label.adaptLayout()
        self.text_widget.show()
Esempio n. 32
0
    def _poll_preview_process(self):
        """This will be called regularly to see if the process ended.

		If the process has not yet finished, schedule a new callback to this function.
		Otherwise use the data to update the minimap.
		"""
        if not self._preview_process:
            return

        self._preview_process.poll()

        if self._preview_process.returncode is None:  # not finished
            ExtScheduler().add_new_object(self._poll_preview_process, self,
                                          0.1)
            return
        elif self._preview_process.returncode != 0:
            self._preview_process = None
            self._set_map_preview_status(
                u"An unknown error occurred while generating the map preview")
            return

        with open(self._preview_output, 'r') as f:
            data = f.read()

        os.unlink(self._preview_output)
        self._preview_process = None

        if self._map_preview:
            self._map_preview.end()

        self._map_preview = Minimap(
            self._gui.findChild(name='map_preview_minimap'),
            session=None,
            view=None,
            world=None,
            targetrenderer=horizons.globals.fife.targetrenderer,
            imagemanager=horizons.globals.fife.imagemanager,
            cam_border=False,
            use_rotation=False,
            tooltip=_("Click to generate a different random map"),
            on_click=self._on_preview_click,
            preview=True)

        self._map_preview.draw_data(data)
        self._set_map_preview_status(u"")
	def _add_message(self, message, sound = None):
		"""Internal function for adding messages. Do not call directly.
		@param message: Message instance
		@param sound: path tosoundfile"""
		self.active_messages.insert(0, message)

		if len(self.active_messages) > self.MAX_MESSAGES:
			self.active_messages.remove(self.active_messages[self.MAX_MESSAGES])

		if sound:
			horizons.main.fife.play_sound('speech', sound)
		else:
			# play default msg sound
			AmbientSound.play_special('message')

		self.draw_widget()
		self.show_text(0)
		ExtScheduler().add_new_object(self.hide_text, self, self.SHOW_NEW_MESSAGE_TEXT)
Esempio n. 34
0
		def high(i=0):
			i += 1
			render_name = self._get_render_name("highlight")+str(tup)
			self.minimap_image.set_drawing_enabled()
			self.minimap_image.rendertarget.removeAll(render_name)
			if i > STEPS:
				if finish_callback:
					finish_callback()
				return
			part = i # grow bigger
			if i > STEPS // 2: # after the first half
				part = STEPS-i  # become smaller

			radius = MIN_RAD + int(( float(part) / (STEPS // 2) ) * (MAX_RAD - MIN_RAD) )

			for x, y in Circle( Point(*tup), radius=radius ).get_border_coordinates():
				self.minimap_image.rendertarget.addPoint(render_name, fife.Point(x, y), *color)

			ExtScheduler().add_new_object(lambda : high(i), self, INTERVAL, loops=1)
Esempio n. 35
0
def start(_command_line_arguments):
	"""Starts the horizons. Will drop you to the main menu.
	@param _command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global debug, preloading, command_line_arguments
	command_line_arguments = _command_line_arguments
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.enable_atlases:
		# check if atlas files are outdated
		if atlases_need_rebuild():
			print "Atlases have to be rebuild."

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if mpieces[2]:
				NETWORK.SERVER_PORT = parse_port(mpieces[2])
		except ValueError:
			print "Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535."
			return False

	if command_line_arguments.generate_minimap: # we've been called as subprocess to generate a map preview
		from horizons.gui.modules.singleplayermenu import MapPreview
		MapPreview.generate_minimap( * json.loads(
		  command_line_arguments.generate_minimap
		  ) )
		sys.exit(0)

	# init fife before mp_bind is parsed, since it's needed there
	horizons.globals.fife = Fife()

	if debug: # also True if a specific module is logged (but not 'fife')
		if not (command_line_arguments.debug_module
		        and 'fife' not in command_line_arguments.debug_module):
			horizons.globals.fife._log.lm.setLogToPrompt(True)
		# After the next FIFE release, we should use this instead which is possible as of r3960:
		# horizons.globals.fife._log.logToPrompt = True

		if command_line_arguments.debug_log_only:
			# This is a workaround to not show fife logs in the shell even if
			# (due to the way the fife logger works) these logs will not be
			# redirected to the UH logfile and instead written to a file fife.log
			# in the current directory. See #1782 for background information.
			horizons.globals.fife._log.lm.setLogToPrompt(False)
			horizons.globals.fife._log.lm.setLogToFile(True)
			# same as above applies here, use property after next FIFE release

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			horizons.globals.fife.set_uh_setting("NetworkPort", parse_port(mpieces[2]))
		except ValueError:
			print "Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535."
			return False

	if command_line_arguments.ai_highlights:
		AI.HIGHLIGHT_PLANS = True
	if command_line_arguments.ai_combat_highlights:
		AI.HIGHLIGHT_COMBAT = True
	if command_line_arguments.human_ai:
		AI.HUMAN_AI = True

	# set MAX_TICKS
	if command_line_arguments.max_ticks:
		GAME.MAX_TICKS = command_line_arguments.max_ticks

	horizons.globals.db = _create_main_db()

	# init game parts

	# Install gui logger, needs to be done before instantiating Gui, otherwise we miss
	# the events of the main menu buttons
	if command_line_arguments.log_gui:
		if command_line_arguments.gui_test:
			raise Exception("Logging gui interactions doesn't work when running tests.")
		try:
			from tests.gui.logger import setup_gui_logger
			setup_gui_logger()
		except ImportError:
			traceback.print_exc()
			print
			print "Gui logging requires code that is only present in the repository and is not being installed."
			return False

	# GUI tests always run with sound disabled and SDL (so they can run under xvfb).
	# Needs to be done before engine is initialized.
	if command_line_arguments.gui_test:
		horizons.globals.fife.engine.getSettings().setRenderBackend('SDL')
		horizons.globals.fife.set_fife_setting('PlaySounds', False)

	ExtScheduler.create_instance(horizons.globals.fife.pump)
	horizons.globals.fife.init()
	_modules.gui = Gui()
	SavegameManager.init()

	from horizons.entities import Entities
	Entities.load(horizons.globals.db, load_now=False) # create all references

	# for preloading game data while in main screen
	preload_lock = threading.Lock()
	preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
	preloading = (preload_thread, preload_lock)

	# Singleplayer seed needs to be changed before startup.
	if command_line_arguments.sp_seed:
		SINGLEPLAYER.SEED = command_line_arguments.sp_seed

	# start something according to commandline parameters
	startup_worked = True
	if command_line_arguments.start_dev_map:
		startup_worked = _start_dev_map(command_line_arguments.ai_players, command_line_arguments.human_ai, command_line_arguments.force_player_id)
	elif command_line_arguments.start_random_map:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_specific_random_map is not None:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai,
			seed=command_line_arguments.start_specific_random_map, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_map is not None:
		startup_worked = _start_map(command_line_arguments.start_map, command_line_arguments.ai_players,
			command_line_arguments.human_ai, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_scenario is not None:
		startup_worked = _start_map(command_line_arguments.start_scenario, 0, False, True, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_campaign is not None:
		startup_worked = _start_campaign(command_line_arguments.start_campaign, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.load_map is not None:
		startup_worked = _load_map(command_line_arguments.load_map, command_line_arguments.ai_players,
			command_line_arguments.human_ai, command_line_arguments.force_player_id)
	elif command_line_arguments.load_quicksave is not None:
		startup_worked = _load_last_quicksave()
	elif command_line_arguments.stringpreview:
		tiny = [ i for i in SavegameManager.get_maps()[0] if 'tiny' in i ]
		if not tiny:
			tiny = SavegameManager.get_map()[0]
		startup_worked = _start_map(tiny[0], ai_players=0, human_ai=False, trader_enabled=False, pirate_enabled=False,
			force_player_id=command_line_arguments.force_player_id)
		from development.stringpreviewwidget import StringPreviewWidget
		__string_previewer = StringPreviewWidget(_modules.session)
		__string_previewer.show()
	elif command_line_arguments.create_mp_game:
		_modules.gui.show_main()
		_modules.gui.show_multi()
		_modules.gui.create_default_mp_game()
	elif command_line_arguments.join_mp_game:
		_modules.gui.show_main()
		_modules.gui.show_multi()
		_modules.gui.join_mp_game()
	else: # no commandline parameter, show main screen

		# initalize update checker
		if not command_line_arguments.gui_test:
			from horizons.util.checkupdates import UpdateInfo, check_for_updates, show_new_version_hint
			update_info = UpdateInfo()
			update_check_thread = threading.Thread(target=check_for_updates, args=(update_info,))
			update_check_thread.start()
			def update_info_handler(info):
				if info.status == UpdateInfo.UNINITIALISED:
					ExtScheduler().add_new_object(Callback(update_info_handler, info), info)
				elif info.status == UpdateInfo.READY:
					show_new_version_hint(_modules.gui, info)
				elif info.status == UpdateInfo.INVALID:
					pass # couldn't retrieve file or nothing relevant in there

			update_info_handler(update_info) # schedules checks by itself

		_modules.gui.show_main()
		if not command_line_arguments.nopreload:
			preloading[0].start()

	if not startup_worked:
		# don't start main loop if startup failed
		return False

	if command_line_arguments.gamespeed is not None:
		if _modules.session is None:
			print "You can only set the speed via command line in combination with a game start parameter such as --start-map, etc."
			return False
		_modules.session.speed_set(GAME_SPEED.TICKS_PER_SECOND*command_line_arguments.gamespeed)

	if command_line_arguments.gui_test:
		from tests.gui import TestRunner
		TestRunner(horizons.globals.fife, command_line_arguments.gui_test)

	if command_line_arguments.interactive_shell:
		from horizons.util import interactive_shell
		interactive_shell.start(horizons.globals.fife)

	horizons.globals.fife.run()
from run_uh import init_environment
init_environment(True)

import horizons.main
from horizons.constants import UNITS, BUILDINGS, TIER
from horizons.scenario.actions import ACTIONS
from horizons.scenario.conditions import CONDITIONS

db = horizons.main._create_main_db()

# we also need to load entities to get access to the yaml data
from horizons.extscheduler import ExtScheduler
from horizons.component.storagecomponent import StorageComponent
from horizons.entities import Entities
from tests.dummy import Dummy
ExtScheduler.create_instance(Dummy()) # sometimes needed by entities in subsequent calls
Entities.load_buildings(db, load_now=True)
Entities.load_units(load_now=True)

building_name_mapping = dict((b.id, b.name) for b in Entities.buildings.itervalues())
unit_name_mapping = dict((u.id, u.name) for u in Entities.units.itervalues())


def get_obj_name(obj):
	global db
	if obj < UNITS.DIFFERENCE_BUILDING_UNIT_ID:
		return db("SELECT name FROM building where id = ?", obj)[0][0]
	else:
		return unit_name_mapping[obj]

Esempio n. 37
0
def start(command_line_arguments):
	"""Starts the horizons.
	@param command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = int(mpieces[2])
				if NETWORK.SERVER_PORT < 1 or NETWORK.SERVER_PORT > 65535:
					raise ValueError
		except ValueError:
			print _("Error: Invalid syntax in --mp-master commandline option. Port must be a number between 0 and 65535.")
			return False

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			NETWORK.CLIENT_PORT = int(mpieces[2])
			if NETWORK.CLIENT_PORT < 1 or NETWORK.CLIENT_PORT  > 65535:
				raise ValueError
		except ValueError:
			print _("Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 0 and 65535.")
			return False

	db = _create_db()

	# init game parts
	fife = Fife()

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		from engine import UH_MODULE
		fife.settings.set(UH_MODULE, "ClientID", client_id)
		fife.settings.saveSettings()

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()
	try:
		NetworkInterface.create_instance()
		NetworkInterface().add_to_extscheduler()
	except RuntimeError, e:
		print "Error during network initialization: %s" % (e)
		return False
Esempio n. 38
0
def start(_command_line_arguments):
	"""Starts the horizons. Will drop you to the main menu.
	@param _command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading, command_line_arguments
	command_line_arguments = _command_line_arguments
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = parse_port(mpieces[2], allow_zero=True)
		except ValueError:
			print "Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535."
			return False

	if command_line_arguments.generate_minimap: # we've been called as subprocess to generate a map preview
		from horizons.gui.modules.singleplayermenu import MapPreview
		MapPreview.generate_minimap( * json.loads(
		  command_line_arguments.generate_minimap
		  ) )
		sys.exit(0)

	# init fife before mp_bind is parsed, since it's needed there
	fife = Fife()

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			fife.set_uh_setting("NetworkPort", parse_port(mpieces[2], allow_zero=True))
		except ValueError:
			print "Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535."
			return False

	if command_line_arguments.ai_highlights:
		AI.HIGHLIGHT_PLANS = True
	if command_line_arguments.human_ai:
		AI.HUMAN_AI = True

	# set singleplayer natural resource seed
	if command_line_arguments.nature_seed:
		SINGLEPLAYER.SEED = command_line_arguments.nature_seed

	# set MAX_TICKS
	if command_line_arguments.max_ticks:
		GAME.MAX_TICKS = command_line_arguments.max_ticks

	db = _create_main_db()

	# init game parts

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		fife.set_uh_setting("ClientID", client_id)
		fife.save_settings()

	# Install gui logger, needs to be done before instanciating Gui, otherwise we miss
	# the events of the main menu buttons
	if command_line_arguments.log_gui:
		if command_line_arguments.gui_test:
			raise Exception("Logging gui interactions doesn't work when running tests.")
		try:
			from tests.gui.logger import setup_gui_logger
			setup_gui_logger()
		except ImportError:
			import traceback
			traceback.print_exc()
			print
			print "Gui logging requires code that is only present in the repository and is not being installed."
			return False

	# GUI tests always run with sound disabled and SDL (so they can run under xvfb).
	# Needs to be done before engine is initialized.
	if command_line_arguments.gui_test:
		fife.engine.getSettings().setRenderBackend('SDL')
		fife.set_fife_setting('PlaySounds', False)

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()

	from horizons.entities import Entities
	Entities.load(db, load_now=False) # create all references

	# for preloading game data while in main screen
	preload_lock = threading.Lock()
	preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
	preloading = (preload_thread, preload_lock)

	# initalize update checker
	from horizons.util.checkupdates import UpdateInfo, check_for_updates, show_new_version_hint
	update_info = UpdateInfo()
	update_check_thread = threading.Thread(target=check_for_updates, args=(update_info,))
	update_check_thread.start()
	def update_info_handler(info):
		if info.status == UpdateInfo.UNINITIALISED:
			ExtScheduler().add_new_object(Callback(update_info_handler, info), info)
		elif info.status == UpdateInfo.READY:
			show_new_version_hint(_modules.gui, info)
		elif info.status == UpdateInfo.INVALID:
			pass # couldn't retrieve file or nothing relevant in there

	update_info_handler(update_info) # schedules checks by itself

	# Singleplayer seed needs to be changed before startup.
	if command_line_arguments.sp_seed:
		SINGLEPLAYER.SEED = command_line_arguments.sp_seed

	# start something according to commandline parameters
	startup_worked = True
	if command_line_arguments.start_dev_map:
		startup_worked = _start_dev_map(command_line_arguments.ai_players, command_line_arguments.human_ai, command_line_arguments.force_player_id)
	elif command_line_arguments.start_random_map:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_specific_random_map is not None:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai, \
			seed=command_line_arguments.start_specific_random_map, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_map is not None:
		startup_worked = _start_map(command_line_arguments.start_map, command_line_arguments.ai_players, \
			command_line_arguments.human_ai, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_scenario is not None:
		startup_worked = _start_map(command_line_arguments.start_scenario, 0, False, True, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_campaign is not None:
		startup_worked = _start_campaign(command_line_arguments.start_campaign, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.load_map is not None:
		startup_worked = _load_map(command_line_arguments.load_map, command_line_arguments.ai_players, \
			command_line_arguments.human_ai, command_line_arguments.force_player_id)
	elif command_line_arguments.load_quicksave is not None:
		startup_worked = _load_last_quicksave()
	elif command_line_arguments.stringpreview:
		tiny = [ i for i in SavegameManager.get_maps()[0] if 'tiny' in i ]
		if not tiny:
			tiny = SavegameManager.get_map()[0]
		startup_worked = _start_map(tiny[0], ai_players=0, human_ai=False, trader_enabled=False, pirate_enabled=False, \
			force_player_id=command_line_arguments.force_player_id)
		from development.stringpreviewwidget import StringPreviewWidget
		__string_previewer = StringPreviewWidget(_modules.session)
		__string_previewer.show()
	elif command_line_arguments.create_mp_game:
		_modules.gui.show_main()
		_modules.gui.show_multi()
		_modules.gui.create_default_mp_game()
	elif command_line_arguments.join_mp_game:
		_modules.gui.show_main()
		_modules.gui.show_multi()
		_modules.gui.join_mp_game()
	else: # no commandline parameter, show main screen
		_modules.gui.show_main()
		if not command_line_arguments.nopreload:
			preloading[0].start()

	if not startup_worked:
		# don't start main loop if startup failed
		return False

	if command_line_arguments.gamespeed is not None:
		_modules.session.speed_set(GAME_SPEED.TICKS_PER_SECOND*command_line_arguments.gamespeed)

	if command_line_arguments.gui_test:
		from tests.gui import TestRunner
		TestRunner(fife, command_line_arguments.gui_test)

	if command_line_arguments.interactive_shell:
		from horizons.util import interactive_shell
		interactive_shell.start(fife)

	fife.run()
Esempio n. 39
0
def start(_command_line_arguments):
	"""Starts the horizons. Will drop you to the main menu.
	@param _command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global debug, preloading, command_line_arguments
	command_line_arguments = _command_line_arguments
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if mpieces[2]:
				NETWORK.SERVER_PORT = parse_port(mpieces[2])
		except ValueError:
			print "Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535."
			return False

	# init fife before mp_bind is parsed, since it's needed there
	horizons.globals.fife = Fife()

	if command_line_arguments.generate_minimap: # we've been called as subprocess to generate a map preview
		from horizons.gui.modules.singleplayermenu import generate_random_minimap
		generate_random_minimap( * json.loads(
		  command_line_arguments.generate_minimap
		  ) )
		sys.exit(0)

	if debug: # also True if a specific module is logged (but not 'fife')
		if not (command_line_arguments.debug_module
		        and 'fife' not in command_line_arguments.debug_module):
			horizons.globals.fife._log.logToPrompt = True

		if command_line_arguments.debug_log_only:
			# This is a workaround to not show fife logs in the shell even if
			# (due to the way the fife logger works) these logs will not be
			# redirected to the UH logfile and instead written to a file fife.log
			# in the current directory. See #1782 for background information.
			horizons.globals.fife._log.logToPrompt = False
			horizons.globals.fife._log.logToFile = True

	if horizons.globals.fife.get_uh_setting("DebugLog"):
		set_debug_log(True, startup=True)

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			horizons.globals.fife.set_uh_setting("NetworkPort", parse_port(mpieces[2]))
		except ValueError:
			print "Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535."
			return False

	if command_line_arguments.ai_highlights:
		AI.HIGHLIGHT_PLANS = True
	if command_line_arguments.ai_combat_highlights:
		AI.HIGHLIGHT_COMBAT = True
	if command_line_arguments.human_ai:
		AI.HUMAN_AI = True

	# set MAX_TICKS
	if command_line_arguments.max_ticks:
		GAME.MAX_TICKS = command_line_arguments.max_ticks

	atlas_generator = None
	horizons_path = os.path.dirname(horizons.__file__)
	if VERSION.IS_DEV_VERSION and horizons.globals.fife.get_uh_setting('AtlasesEnabled') \
	                          and horizons.globals.fife.get_uh_setting('AtlasGenerationEnabled') \
	                          and command_line_arguments.atlas_generation \
	                          and not command_line_arguments.gui_test:
		args = [sys.executable, os.path.join(horizons_path, 'engine', 'generate_atlases.py'),
		        str(horizons.globals.fife.get_uh_setting('MaxAtlasSize'))]
		atlas_generator = subprocess.Popen(args, stdout=None, stderr=subprocess.STDOUT)

	# init game parts

	# Install gui logger, needs to be done before instantiating Gui, otherwise we miss
	# the events of the main menu buttons
	if command_line_arguments.log_gui:
		if command_line_arguments.gui_test:
			raise Exception("Logging gui interactions doesn't work when running tests.")
		try:
			from tests.gui.logger import setup_gui_logger
			setup_gui_logger()
		except ImportError:
			traceback.print_exc()
			print
			print "Gui logging requires code that is only present in the repository and is not being installed."
			return False

	# GUI tests always run with sound disabled and SDL (so they can run under xvfb).
	# Needs to be done before engine is initialized.
	if command_line_arguments.gui_test:
		horizons.globals.fife.engine.getSettings().setRenderBackend('SDL')
		horizons.globals.fife.set_fife_setting('PlaySounds', False)

	ExtScheduler.create_instance(horizons.globals.fife.pump)
	horizons.globals.fife.init()

	if atlas_generator is not None:
		atlas_generator.wait()
		assert atlas_generator.returncode is not None
		if atlas_generator.returncode != 0:
			print 'Atlas generation failed. Continuing without atlas support.'
			print 'This just means that the game will run a bit slower.'
			print 'It will still run fine unless there are other problems.'
			print
			GFX.USE_ATLASES = False
		else:
			GFX.USE_ATLASES = True
			PATHS.DB_FILES = PATHS.DB_FILES + (PATHS.ATLAS_DB_PATH, )
	elif not VERSION.IS_DEV_VERSION and horizons.globals.fife.get_uh_setting('AtlasesEnabled'):
		GFX.USE_ATLASES = True
		PATHS.DB_FILES = PATHS.DB_FILES + (PATHS.ATLAS_DB_PATH, )

	horizons.globals.db = _create_main_db()
	horizons.globals.fife.init_animation_loader(GFX.USE_ATLASES)
	_modules.gui = Gui()
	SavegameManager.init()

	from horizons.entities import Entities
	Entities.load(horizons.globals.db, load_now=False) # create all references

	# for preloading game data while in main screen
	preload_lock = threading.Lock()
	preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
	preloading = (preload_thread, preload_lock)

	# Singleplayer seed needs to be changed before startup.
	if command_line_arguments.sp_seed:
		SINGLEPLAYER.SEED = command_line_arguments.sp_seed
	SINGLEPLAYER.FREEZE_PROTECTION = command_line_arguments.freeze_protection

	# start something according to commandline parameters
	startup_worked = True
	if command_line_arguments.start_dev_map:
		startup_worked = _start_map('development', command_line_arguments.ai_players,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
	elif command_line_arguments.start_random_map:
		startup_worked = _start_random_map(command_line_arguments.ai_players, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_specific_random_map is not None:
		startup_worked = _start_random_map(command_line_arguments.ai_players,
			seed=command_line_arguments.start_specific_random_map, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_map is not None:
		startup_worked = _start_map(command_line_arguments.start_map, command_line_arguments.ai_players,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
	elif command_line_arguments.start_scenario is not None:
		startup_worked = _start_map(command_line_arguments.start_scenario, 0, True, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.load_game is not None:
		startup_worked = _load_cmd_map(command_line_arguments.load_game, command_line_arguments.ai_players,
			command_line_arguments.force_player_id)
	elif command_line_arguments.load_quicksave is not None:
		startup_worked = _load_last_quicksave()
	elif command_line_arguments.edit_map is not None:
		startup_worked = edit_map(command_line_arguments.edit_map)
	elif command_line_arguments.edit_game_map is not None:
		startup_worked = edit_game_map(command_line_arguments.edit_game_map)
	elif command_line_arguments.stringpreview:
		tiny = [ i for i in SavegameManager.get_maps()[0] if 'tiny' in i ]
		if not tiny:
			tiny = SavegameManager.get_map()[0]
		startup_worked = _start_map(tiny[0], ai_players=0, trader_enabled=False, pirate_enabled=False,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
		from development.stringpreviewwidget import StringPreviewWidget
		__string_previewer = StringPreviewWidget(_modules.session)
		__string_previewer.show()
	elif command_line_arguments.create_mp_game:
		_modules.gui.show_main()
		_modules.gui.windows.open(_modules.gui.multiplayermenu)
		_modules.gui.multiplayermenu._create_game()
		_modules.gui.windows._windows[-1].act()
	elif command_line_arguments.join_mp_game:
		_modules.gui.show_main()
		_modules.gui.windows.open(_modules.gui.multiplayermenu)
		_modules.gui.multiplayermenu._join_game()
	else: # no commandline parameter, show main screen

		# initialize update checker
		if not command_line_arguments.gui_test:
			from horizons.util.checkupdates import UpdateInfo, check_for_updates, show_new_version_hint
			update_info = UpdateInfo()
			update_check_thread = threading.Thread(target=check_for_updates, args=(update_info,))
			update_check_thread.start()

			def update_info_handler(info):
				if info.status == UpdateInfo.UNINITIALIZED:
					ExtScheduler().add_new_object(Callback(update_info_handler, info), info)
				elif info.status == UpdateInfo.READY:
					show_new_version_hint(_modules.gui, info)
				elif info.status == UpdateInfo.INVALID:
					pass # couldn't retrieve file or nothing relevant in there

			update_info_handler(update_info) # schedules checks by itself

		_modules.gui.show_main()
		if not command_line_arguments.nopreload:
			preloading[0].start()

	if not startup_worked:
		# don't start main loop if startup failed
		return False

	if command_line_arguments.gamespeed is not None:
		if _modules.session is None:
			print "You can only set the speed via command line in combination with a game start parameter such as --start-map, etc."
			return False
		_modules.session.speed_set(GAME_SPEED.TICKS_PER_SECOND*command_line_arguments.gamespeed)

	if command_line_arguments.gui_test:
		from tests.gui import TestRunner
		TestRunner(horizons.globals.fife, command_line_arguments.gui_test)

	horizons.globals.fife.run()
Esempio n. 40
0
def start(_command_line_arguments):
    """Starts the horizons. Will drop you to the main menu.
	@param _command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
    global debug, preloading, command_line_arguments
    command_line_arguments = _command_line_arguments
    # NOTE: globals are designwise the same thing as singletons. they don't look pretty.
    #       here, we only have globals that are either trivial, or only one instance may ever exist.

    from engine import Fife

    # handle commandline globals
    debug = command_line_arguments.debug

    if command_line_arguments.restore_settings:
        # just delete the file, Settings ctor will create a new one
        os.remove(PATHS.USER_CONFIG_FILE)

    if command_line_arguments.mp_master:
        try:
            mpieces = command_line_arguments.mp_master.partition(":")
            NETWORK.SERVER_ADDRESS = mpieces[0]
            # only change port if port is specified
            if mpieces[2]:
                NETWORK.SERVER_PORT = parse_port(mpieces[2])
        except ValueError:
            print "Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535."
            return False

            # init fife before mp_bind is parsed, since it's needed there
    horizons.globals.fife = Fife()

    if command_line_arguments.generate_minimap:  # we've been called as subprocess to generate a map preview
        from horizons.gui.modules.singleplayermenu import generate_random_minimap

        generate_random_minimap(*json.loads(command_line_arguments.generate_minimap))
        sys.exit(0)

    if debug:  # also True if a specific module is logged (but not 'fife')
        setup_debug_mode(command_line_arguments)

    if horizons.globals.fife.get_uh_setting("DebugLog"):
        set_debug_log(True, startup=True)

    if command_line_arguments.mp_bind:
        try:
            mpieces = command_line_arguments.mp_bind.partition(":")
            NETWORK.CLIENT_ADDRESS = mpieces[0]
            horizons.globals.fife.set_uh_setting("NetworkPort", parse_port(mpieces[2]))
        except ValueError:
            print "Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535."
            return False

    setup_AI_settings(command_line_arguments)

    # set MAX_TICKS
    if command_line_arguments.max_ticks:
        GAME.MAX_TICKS = command_line_arguments.max_ticks

    preload_lock = threading.Lock()

    if (
        command_line_arguments.atlas_generation
        and not command_line_arguments.gui_test
        and VERSION.IS_DEV_VERSION
        and horizons.globals.fife.get_uh_setting("AtlasesEnabled")
        and horizons.globals.fife.get_uh_setting("AtlasGenerationEnabled")
    ):

        atlas_loading_thread = None
        atlas_loading_thread = AtlasLoadingThread(preload_lock)
        atlas_loading_thread.start()

        # show info label about atlas generation
        try:
            import Tkinter
            from PIL import Image, ImageTk
            import time

            try:
                window = Tkinter.Tk()
                # iconify window instead of closing
                window.protocol("WM_DELETE_WINDOW", window.iconify)
                window.wm_withdraw()
                window.attributes("-topmost", 1)
                window.title("Unknown Horizons")
                window.maxsize(300, 150)

                logo = Image.open(horizons.constants.PATHS.UH_LOGO_FILE)
                res_logo = logo.resize((116, 99), Image.ANTIALIAS)
                res_logo_image = ImageTk.PhotoImage(res_logo)
                logo_label = Tkinter.Label(window, image=res_logo_image)
                logo_label.pack(side="left")
                label = Tkinter.Label(window, padx=10, text="Generating atlases!")
                label.pack(side="right")

                # wait a second to give the thread time to check if a generation is necessary at all
                time.sleep(1.0)
                window.deiconify()
                while atlas_loading_thread.is_alive():
                    if not window.state() == "iconic":
                        window.attributes("-topmost", 0)
                        window.update()
                    time.sleep(0.1)
                window.destroy()
            except Tkinter.TclError:
                # catch #2298
                atlas_loading_thread.join()
        except ImportError:
            # tkinter or PIL may be missing
            atlas_loading_thread.join()

            # init game parts

    if not setup_gui_logger(command_line_arguments):
        return False

        # GUI tests always run with sound disabled and SDL (so they can run under xvfb).
        # Needs to be done before engine is initialized.
    if command_line_arguments.gui_test:
        horizons.globals.fife.engine.getSettings().setRenderBackend("SDL")
        horizons.globals.fife.set_fife_setting("PlaySounds", False)

    ExtScheduler.create_instance(horizons.globals.fife.pump)
    horizons.globals.fife.init()

    if not VERSION.IS_DEV_VERSION and horizons.globals.fife.get_uh_setting("AtlasesEnabled"):
        GFX.USE_ATLASES = True
        PATHS.DB_FILES = PATHS.DB_FILES + (PATHS.ATLAS_DB_PATH,)

    horizons.globals.db = _create_main_db()
    _modules.gui = Gui()
    SavegameManager.init()
    horizons.globals.fife.init_animation_loader(GFX.USE_ATLASES)

    from horizons.entities import Entities

    Entities.load(horizons.globals.db, load_now=False)  # create all references

    # for preloading game data while in main screen
    preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
    preloading = (preload_thread, preload_lock)

    # Singleplayer seed needs to be changed before startup.
    if command_line_arguments.sp_seed:
        SINGLEPLAYER.SEED = command_line_arguments.sp_seed
    SINGLEPLAYER.FREEZE_PROTECTION = command_line_arguments.freeze_protection

    # start something according to commandline parameters
    startup_worked = True
    if command_line_arguments.start_dev_map:
        startup_worked = _start_map(
            "development",
            command_line_arguments.ai_players,
            force_player_id=command_line_arguments.force_player_id,
            is_map=True,
        )
    elif command_line_arguments.start_random_map:
        startup_worked = _start_random_map(
            command_line_arguments.ai_players, force_player_id=command_line_arguments.force_player_id
        )
    elif command_line_arguments.start_specific_random_map is not None:
        startup_worked = _start_random_map(
            command_line_arguments.ai_players,
            seed=command_line_arguments.start_specific_random_map,
            force_player_id=command_line_arguments.force_player_id,
        )
    elif command_line_arguments.start_map is not None:
        startup_worked = _start_map(
            command_line_arguments.start_map,
            command_line_arguments.ai_players,
            force_player_id=command_line_arguments.force_player_id,
            is_map=True,
        )
    elif command_line_arguments.start_scenario is not None:
        startup_worked = _start_map(
            command_line_arguments.start_scenario, 0, True, force_player_id=command_line_arguments.force_player_id
        )
    elif command_line_arguments.load_game is not None:
        startup_worked = _load_cmd_map(
            command_line_arguments.load_game, command_line_arguments.ai_players, command_line_arguments.force_player_id
        )
    elif command_line_arguments.load_quicksave is not None:
        startup_worked = _load_last_quicksave()
    elif command_line_arguments.edit_map is not None:
        startup_worked = edit_map(command_line_arguments.edit_map)
    elif command_line_arguments.edit_game_map is not None:
        startup_worked = edit_game_map(command_line_arguments.edit_game_map)
    elif command_line_arguments.stringpreview:
        tiny = [i for i in SavegameManager.get_maps()[0] if "tiny" in i]
        if not tiny:
            tiny = SavegameManager.get_map()[0]
        startup_worked = _start_map(
            tiny[0],
            ai_players=0,
            trader_enabled=False,
            pirate_enabled=False,
            force_player_id=command_line_arguments.force_player_id,
            is_map=True,
        )
        from development.stringpreviewwidget import StringPreviewWidget

        __string_previewer = StringPreviewWidget(_modules.session)
        __string_previewer.show()
    elif command_line_arguments.create_mp_game:
        _modules.gui.show_main()
        _modules.gui.windows.open(_modules.gui.multiplayermenu)
        _modules.gui.multiplayermenu._create_game()
        _modules.gui.windows._windows[-1].act()
    elif command_line_arguments.join_mp_game:
        _modules.gui.show_main()
        _modules.gui.windows.open(_modules.gui.multiplayermenu)
        _modules.gui.multiplayermenu._join_game()
    else:  # no commandline parameter, show main screen

        # initialize update checker
        if not command_line_arguments.gui_test:
            setup_update_check()

        _modules.gui.show_main()
        if not command_line_arguments.nopreload:
            preloading[0].start()

    if not startup_worked:
        # don't start main loop if startup failed
        return False

    if command_line_arguments.gamespeed is not None:
        if _modules.session is None:
            print "You can only set the speed via command line in combination with a game start parameter such as --start-map, etc."
            return False
        _modules.session.speed_set(GAME_SPEED.TICKS_PER_SECOND * command_line_arguments.gamespeed)

    if command_line_arguments.gui_test:
        from tests.gui import TestRunner

        TestRunner(horizons.globals.fife, command_line_arguments.gui_test)

    horizons.globals.fife.run()
Esempio n. 41
0
def start(command_line_arguments):
	"""Starts the horizons.
	@param command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = parse_port(mpieces[2], allow_zero=True)
		except ValueError:
			print _("Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535.")
			return False

	# init fife before mp_bind is parsed, since it's needed there
	fife = Fife()

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			fife.set_uh_setting("NetworkPort", parse_port(mpieces[2], allow_zero=True))
			print 'asdf', fife.get_uh_setting("NetworkPort2")
		except ValueError:
			print _("Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535.")
			return False

	db = _create_db()

	# init game parts

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		from engine import UH_MODULE
		fife.settings.set(UH_MODULE, "ClientID", client_id)
		fife.settings.saveSettings()

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()
	try:
		NetworkInterface.create_instance()
	except RuntimeError, e:
		headline = _(u"Failed to initialize networking.")
		descr = _(u"Networking couldn't be initialised with the current configuration.")
		advice = _(u"Check the data you entered in the Network section in the settings dialogue.")
		_modules.gui.show_error_popup(headline, descr, advice, unicode(e))
	def __init__(self, rng_seed=None):
		ExtScheduler.create_instance(mock.Mock())
		super().__init__(horizons.globals.db, rng_seed, ingame_gui_class=Dummy)
		self.reset_autosave = mock.Mock()
Esempio n. 43
0
def start(command_line_arguments):
	"""Starts the horizons.
	@param command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global fife, db, debug, preloading
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if len(mpieces[2]) > 0:
				NETWORK.SERVER_PORT = parse_port(mpieces[2], allow_zero=True)
		except ValueError:
			print _("Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535.")
			return False

	# init fife before mp_bind is parsed, since it's needed there
	fife = Fife()

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			fife.set_uh_setting("NetworkPort", parse_port(mpieces[2], allow_zero=True))
		except ValueError:
			print _("Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535.")
			return False

	AI.AI_PLAYERS = command_line_arguments.ai_players
	if command_line_arguments.ai_highlights:
		AI.HIGHLIGHT_PLANS = True
	if command_line_arguments.human_ai:
		AI.HUMAN_AI = True

	# set singleplayer natural resource seed
	if command_line_arguments.nature_seed:
		SINGLEPLAYER.SEED = command_line_arguments.nature_seed

	# set MAX_TICKS
	if command_line_arguments.max_ticks:
		GAME.MAX_TICKS = command_line_arguments.max_ticks

	db = _create_db()

	# init game parts

	_init_gettext(fife)

	client_id = fife.get_uh_setting("ClientID")
	if client_id is None or len(client_id) == 0:
		# We need a new client id
		client_id = "".join("-" if c in (8, 13, 18, 23) else \
		                    random.choice("0123456789abcdef") for c in xrange(0, 36))
		from engine import UH_MODULE
		fife.settings.set(UH_MODULE, "ClientID", client_id)
		fife.settings.saveSettings()

	ExtScheduler.create_instance(fife.pump)
	fife.init()
	_modules.gui = Gui()
	SavegameManager.init()

	# for preloading game data while in main screen
	preload_lock = threading.Lock()
	preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
	preloading = (preload_thread, preload_lock)

	# start something according to commandline parameters
	startup_worked = True
	if command_line_arguments.start_dev_map:
		startup_worked = _start_dev_map(command_line_arguments.ai_players, command_line_arguments.human_ai)
	elif command_line_arguments.start_random_map:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai)
	elif command_line_arguments.start_specific_random_map is not None:
		startup_worked = _start_random_map(command_line_arguments.ai_players, command_line_arguments.human_ai, \
			seed=command_line_arguments.start_specific_random_map)
	elif command_line_arguments.start_map is not None:
		startup_worked = _start_map(command_line_arguments.start_map, command_line_arguments.ai_players, \
			command_line_arguments.human_ai)
	elif command_line_arguments.start_scenario is not None:
		startup_worked = _start_map(command_line_arguments.start_scenario, 0, False, True)
	elif command_line_arguments.start_campaign is not None:
		startup_worked = _start_campaign(command_line_arguments.start_campaign)
	elif command_line_arguments.load_map is not None:
		startup_worked = _load_map(command_line_arguments.load_map, command_line_arguments.ai_players, \
			command_line_arguments.human_ai)
	elif command_line_arguments.load_quicksave is not None:
		startup_worked = _load_last_quicksave()
	elif command_line_arguments.stringpreview:
		startup_worked = _start_map("development_no_trees", 0, False)
		from development.stringpreviewwidget import StringPreviewWidget
		StringPreviewWidget().show()
	else: # no commandline parameter, show main screen
		_modules.gui.show_main()
		preloading[0].start()

	if not startup_worked:
		# don't start main loop if startup failed
		return False

	fife.run()
Esempio n. 44
0
def start(_command_line_arguments):
	"""Starts the horizons. Will drop you to the main menu.
	@param _command_line_arguments: options object from optparse.OptionParser. see run_uh.py.
	"""
	global debug, preloading, command_line_arguments
	command_line_arguments = _command_line_arguments
	# NOTE: globals are designwise the same thing as singletons. they don't look pretty.
	#       here, we only have globals that are either trivial, or only one instance may ever exist.

	from engine import Fife

	# handle commandline globals
	debug = command_line_arguments.debug

	if command_line_arguments.restore_settings:
		# just delete the file, Settings ctor will create a new one
		os.remove( PATHS.USER_CONFIG_FILE )

	if command_line_arguments.mp_master:
		try:
			mpieces = command_line_arguments.mp_master.partition(':')
			NETWORK.SERVER_ADDRESS = mpieces[0]
			# only change port if port is specified
			if mpieces[2]:
				NETWORK.SERVER_PORT = parse_port(mpieces[2])
		except ValueError:
			print "Error: Invalid syntax in --mp-master commandline option. Port must be a number between 1 and 65535."
			return False

	# init fife before mp_bind is parsed, since it's needed there
	horizons.globals.fife = Fife()

	if command_line_arguments.generate_minimap: # we've been called as subprocess to generate a map preview
		from horizons.gui.modules.singleplayermenu import generate_random_minimap
		generate_random_minimap( * json.loads(
		  command_line_arguments.generate_minimap
		  ) )
		sys.exit(0)

	if debug: # also True if a specific module is logged (but not 'fife')
		setup_debug_mode(command_line_arguments)

	if horizons.globals.fife.get_uh_setting("DebugLog"):
		set_debug_log(True, startup=True)

	if command_line_arguments.mp_bind:
		try:
			mpieces = command_line_arguments.mp_bind.partition(':')
			NETWORK.CLIENT_ADDRESS = mpieces[0]
			horizons.globals.fife.set_uh_setting("NetworkPort", parse_port(mpieces[2]))
		except ValueError:
			print "Error: Invalid syntax in --mp-bind commandline option. Port must be a number between 1 and 65535."
			return False

	setup_AI_settings(command_line_arguments)

	# set MAX_TICKS
	if command_line_arguments.max_ticks:
		GAME.MAX_TICKS = command_line_arguments.max_ticks

	preload_lock = threading.Lock()
	atlas_loading_thread = None
	atlas_loading_thread = AtlasLoadingThread(preload_lock, command_line_arguments)
	atlas_loading_thread.start()
	atlas_loading_thread.join()

	# init game parts

	if not setup_gui_logger(command_line_arguments):
		return False

	# GUI tests always run with sound disabled and SDL (so they can run under xvfb).
	# Needs to be done before engine is initialized.
	if command_line_arguments.gui_test:
		horizons.globals.fife.engine.getSettings().setRenderBackend('SDL')
		horizons.globals.fife.set_fife_setting('PlaySounds', False)

	ExtScheduler.create_instance(horizons.globals.fife.pump)
	horizons.globals.fife.init()

	if not VERSION.IS_DEV_VERSION and horizons.globals.fife.get_uh_setting('AtlasesEnabled'):
		GFX.USE_ATLASES = True
		PATHS.DB_FILES = PATHS.DB_FILES + (PATHS.ATLAS_DB_PATH, )

	horizons.globals.db = _create_main_db()
	_modules.gui = Gui()
	SavegameManager.init()
	horizons.globals.fife.init_animation_loader(GFX.USE_ATLASES)
	
	from horizons.entities import Entities
	Entities.load(horizons.globals.db, load_now=False) # create all references

	# for preloading game data while in main screen
	preload_thread = threading.Thread(target=preload_game_data, args=(preload_lock,))
	preloading = (preload_thread, preload_lock)

	# Singleplayer seed needs to be changed before startup.
	if command_line_arguments.sp_seed:
		SINGLEPLAYER.SEED = command_line_arguments.sp_seed
	SINGLEPLAYER.FREEZE_PROTECTION = command_line_arguments.freeze_protection

	# start something according to commandline parameters
	startup_worked = True
	if command_line_arguments.start_dev_map:
		startup_worked = _start_map('development', command_line_arguments.ai_players,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
	elif command_line_arguments.start_random_map:
		startup_worked = _start_random_map(command_line_arguments.ai_players, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_specific_random_map is not None:
		startup_worked = _start_random_map(command_line_arguments.ai_players,
			seed=command_line_arguments.start_specific_random_map, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.start_map is not None:
		startup_worked = _start_map(command_line_arguments.start_map, command_line_arguments.ai_players,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
	elif command_line_arguments.start_scenario is not None:
		startup_worked = _start_map(command_line_arguments.start_scenario, 0, True, force_player_id=command_line_arguments.force_player_id)
	elif command_line_arguments.load_game is not None:
		startup_worked = _load_cmd_map(command_line_arguments.load_game, command_line_arguments.ai_players,
			command_line_arguments.force_player_id)
	elif command_line_arguments.load_quicksave is not None:
		startup_worked = _load_last_quicksave()
	elif command_line_arguments.edit_map is not None:
		startup_worked = edit_map(command_line_arguments.edit_map)
	elif command_line_arguments.edit_game_map is not None:
		startup_worked = edit_game_map(command_line_arguments.edit_game_map)
	elif command_line_arguments.stringpreview:
		tiny = [ i for i in SavegameManager.get_maps()[0] if 'tiny' in i ]
		if not tiny:
			tiny = SavegameManager.get_map()[0]
		startup_worked = _start_map(tiny[0], ai_players=0, trader_enabled=False, pirate_enabled=False,
			force_player_id=command_line_arguments.force_player_id, is_map=True)
		from development.stringpreviewwidget import StringPreviewWidget
		__string_previewer = StringPreviewWidget(_modules.session)
		__string_previewer.show()
	elif command_line_arguments.create_mp_game:
		_modules.gui.show_main()
		_modules.gui.windows.open(_modules.gui.multiplayermenu)
		_modules.gui.multiplayermenu._create_game()
		_modules.gui.windows._windows[-1].act()
	elif command_line_arguments.join_mp_game:
		_modules.gui.show_main()
		_modules.gui.windows.open(_modules.gui.multiplayermenu)
		_modules.gui.multiplayermenu._join_game()
	else: # no commandline parameter, show main screen

		# initialize update checker
		if not command_line_arguments.gui_test:
			setup_update_check()

		_modules.gui.show_main()
		if not command_line_arguments.nopreload:
			preloading[0].start()

	if not startup_worked:
		# don't start main loop if startup failed
		return False

	if command_line_arguments.gamespeed is not None:
		if _modules.session is None:
			print "You can only set the speed via command line in combination with a game start parameter such as --start-map, etc."
			return False
		_modules.session.speed_set(GAME_SPEED.TICKS_PER_SECOND*command_line_arguments.gamespeed)

	if command_line_arguments.gui_test:
		from tests.gui import TestRunner
		TestRunner(horizons.globals.fife, command_line_arguments.gui_test)

	horizons.globals.fife.run()
Esempio n. 45
0
	def __init__(self, rng_seed=None):
		ExtScheduler.create_instance(Dummy)
		super(SPTestSession, self).__init__(Dummy, horizons.globals.db, rng_seed)
		self.reset_autosave = mock.Mock()