def __init__(self, db, rng_seed=None): """ Unfortunately, right now there is no other way to setup Dummy versions of the GUI, View etc., unless we want to patch the references in the session module. """ super(LivingObject, self).__init__() self.gui = Dummy() self.db = db self.savecounter = 0 # this is a new game. self.is_alive = True WorldObject.reset() NamedObject.reset() AIPlayer.clear_caches() # Game self.current_tick = 0 self.random = self.create_rng(rng_seed) self.timer = self.create_timer() Scheduler.create_instance(self.timer) ExtScheduler.create_instance(Dummy) self.manager = self.create_manager() self.view = Dummy() self.view.renderer = Dummy() Entities.load(self.db) self.scenario_eventhandler = Dummy() self.campaign = {} self.selected_instances = [] # GUI self.gui.session = self self.ingame_gui = Dummy() GAME_SPEED.TICKS_PER_SECOND = 16
def 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()
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()
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()
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)
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)
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)
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)
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)
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)
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)
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()
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)
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()
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()
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)
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()
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)
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 __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("")
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
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)
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)
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)
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()
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)
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)
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]
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
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()
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()
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()
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()
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()
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()
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()