def start_singleplayer(options): """Starts a singleplayer game.""" _modules.gui.show_loading_screen() LoadingProgress.broadcast(None, "load_objects") global preloading preload_game_join(preloading) # remove cursor while loading horizons.globals.fife.cursor.set(fife_module.CURSOR_NONE) horizons.globals.fife.engine.pump() horizons.globals.fife.set_cursor_image("default") # destruct old session (right now, without waiting for gc) if _modules.session is not None and _modules.session.is_alive: _modules.session.end() if options.is_editor: from horizons.editor.session import EditorSession as session_class else: from horizons.spsession import SPSession as session_class # start new session _modules.session = session_class(horizons.globals.db) from horizons.scenario import InvalidScenarioFileFormat # would create import loop at top from horizons.util.savegameaccessor import MapFileNotFound from horizons.util.savegameupgrader import SavegameTooOld try: _modules.session.load(options) _modules.gui.close_all() except InvalidScenarioFileFormat: raise except (MapFileNotFound, SavegameTooOld, Exception): _modules.gui.close_all() # don't catch errors when we should fail fast (used by tests) if os.environ.get("FAIL_FAST", False): raise print "Failed to load", options.game_identifier traceback.print_exc() if _modules.session is not None and _modules.session.is_alive: try: _modules.session.end() except Exception: print traceback.print_exc() print "Additionally to failing when loading, cleanup afterwards also failed" _modules.gui.show_main() headline = _("Failed to start/load the game") descr = ( _("The game you selected could not be started.") + u" " + _("The savegame might be broken or has been saved with an earlier version.") ) _modules.gui.open_error_popup(headline, descr) _modules.gui.load_game() return _modules.session
def start_singleplayer(options): """Starts a singleplayer game.""" global gui, session, preloader gui.show_loading_screen() LoadingProgress.broadcast(None, 'load_objects') preloader.wait_for_finish() # remove cursor while loading horizons.globals.fife.cursor.set(fife_module.CURSOR_NONE) horizons.globals.fife.engine.pump() horizons.globals.fife.set_cursor_image('default') # destruct old session (right now, without waiting for gc) if session is not None and session.is_alive: session.end() if options.is_editor: from horizons.editor.session import EditorSession as session_class else: from horizons.spsession import SPSession as session_class # start new session session = session_class(horizons.globals.db) from horizons.scenario import InvalidScenarioFileFormat # would create import loop at top from horizons.util.savegameaccessor import MapFileNotFound from horizons.util.savegameupgrader import SavegameTooOld try: session.load(options) gui.close_all() except InvalidScenarioFileFormat: raise except (MapFileNotFound, SavegameTooOld, Exception): gui.close_all() # don't catch errors when we should fail fast (used by tests) if os.environ.get('FAIL_FAST', False): raise print("Failed to load", options.game_identifier) traceback.print_exc() if session is not None and session.is_alive: try: session.end() except Exception: print() traceback.print_exc() print( "Additionally to failing when loading, cleanup afterwards also failed" ) gui.show_main() headline = T("Failed to start/load the game") descr = T("The game you selected could not be started.") + " " + \ T("The savegame might be broken or has been saved with an earlier version.") gui.open_error_popup(headline, descr) gui.load_game() return session
def show(self): qotl_type_label = self._widget.findChild(name='qotl_type_label') qotl_label = self._widget.findChild(name='qotl_label') name, quote = get_random_quote() qotl_type_label.text = name qotl_label.text = quote self._widget.show() LoadingProgress.subscribe(self._update)
def show(self): qotl_type_label = self._widget.findChild(name='qotl_type_label') qotl_label = self._widget.findChild(name='qotl_label') quote_type = int(horizons.globals.fife.get_uh_setting("QuotesType")) if quote_type == 2: quote_type = random.randint(0, 1) # choose a random type if quote_type == 0: name = GAMEPLAY_TIPS["name"] items = GAMEPLAY_TIPS["items"] elif quote_type == 1: name = FUN_QUOTES["name"] items = FUN_QUOTES["items"] qotl_type_label.text = unicode(name) qotl_label.text = unicode(random.choice(items)) # choose a random quote / gameplay tip self._widget.show() LoadingProgress.subscribe(self._update)
def load(self, options): """Loads a map. Key method for starting a game.""" """ TUTORIAL: Here you see how the vital game elements (and some random things that are also required) are initialized. """ if options.is_scenario: # game_identifier is a yaml file, that contains reference to actual map file self.scenario_eventhandler = ScenarioEventHandler( self, options.game_identifier) # scenario maps can be normal maps or scenario maps: map_filename = self.scenario_eventhandler.get_map_file() options.game_identifier = os.path.join( SavegameManager.scenario_maps_dir, map_filename) if not os.path.exists(options.game_identifier): options.game_identifier = os.path.join( SavegameManager.maps_dir, map_filename) options.is_map = True self.log.debug("Session: Loading from %s", options.game_identifier) savegame_db = SavegameAccessor(options.game_identifier, options.is_map, options) # Initialize new dbreader savegame_data = SavegameManager.get_metadata(savegame_db.db_path) self.view.resize_layers(savegame_db) # load how often the game has been saved (used to know the difference between # a loaded and a new game) self.savecounter = savegame_data.get('savecounter', 0) if savegame_data.get('rng_state', None): rng_state_list = json.loads(savegame_data['rng_state']) # json treats tuples as lists, but we need tuples here, so convert back def rec_list_to_tuple(x): if isinstance(x, list): return tuple(rec_list_to_tuple(i) for i in x) else: return x rng_state_tuple = rec_list_to_tuple(rng_state_list) # changing the rng is safe for mp, as all players have to have the same map self.random.setstate(rng_state_tuple) LoadingProgress.broadcast(self, 'session_create_world') self.world = World( self ) # Load horizons.world module (check horizons/world/__init__.py) self.world._init(savegame_db, options.force_player_id, disasters_enabled=options.disasters_enabled) self.view.load(savegame_db, self.world) # load view if not self.is_game_loaded(): options.init_new_world(self) else: # try to load scenario data self.scenario_eventhandler.load(savegame_db) self.manager.load( savegame_db ) # load the manager (there might be old scheduled ticks). LoadingProgress.broadcast(self, "session_index_fish") self.world.init_fish_indexer() # now the fish should exist # load the old gui positions and stuff # Do this before loading selections, they need the minimap setup LoadingProgress.broadcast(self, "session_load_gui") self.ingame_gui = self._ingame_gui_class(self) self.ingame_gui.load(savegame_db) Scheduler().before_ticking() savegame_db.close() assert hasattr(self.world, "player"), 'Error: there is no human player' LoadingProgress.broadcast(self, "session_finish") """
def _init(self, savegame_db, force_player_id=None, disasters_enabled=True): """ @param savegame_db: Dbreader with loaded savegame database @param force_player_id: the worldid of the selected human player or default if None (debug option) """ """ All essential and non-essential parts of the world are set up here, you don't need to know everything that happens. """ # load properties self.properties = {} for (name, value) in savegame_db("SELECT name, value FROM map_properties"): self.properties[name] = json.loads(value) if not 'disasters_enabled' in self.properties: # set on first init self.properties['disasters_enabled'] = disasters_enabled # create playerlist self.players = [] self.player = None # player sitting in front of this machine self.trader = None self.pirate = None self._load_players(savegame_db, force_player_id) # all static data LoadingProgress.broadcast(self, 'world_load_map') self.load_raw_map(savegame_db) # load world buildings (e.g. fish) LoadingProgress.broadcast(self, 'world_load_buildings') for (building_worldid, building_typeid) in \ savegame_db("SELECT rowid, type FROM building WHERE location = ?", self.worldid): load_building(self.session, savegame_db, building_typeid, building_worldid) # use a dict because it's directly supported by the pathfinding algo LoadingProgress.broadcast(self, 'world_init_water') self.water = dict((tile, 1.0) for tile in self.ground_map) self._init_water_bodies() self.sea_number = self.water_body[(self.min_x, self.min_y)] for island in self.islands: island.terrain_cache.create_sea_cache() # assemble list of water and coastline for ship, that can drive through shallow water # NOTE: this is rather a temporary fix to make the fisher be able to move # since there are tile between coastline and deep sea, all non-constructible tiles # are added to this list as well, which will contain a few too many self.water_and_coastline = copy.copy(self.water) for island in self.islands: for coord, tile in island.ground_map.iteritems(): if 'coastline' in tile.classes or 'constructible' not in tile.classes: self.water_and_coastline[coord] = 1.0 self._init_shallow_water_bodies() self.shallow_sea_number = self.shallow_water_body[(self.min_x, self.min_y)] # create ship position list. entries: ship_map[(x, y)] = ship self.ship_map = {} self.ground_unit_map = {} # create shiplist, which is currently used for saving ships # and having at least one reference to them self.ships = [] self.ground_units = [] # create bullets list, used for saving bullets in ongoing attacks self.bullets = [] if self.session.is_game_loaded(): # there are 0 or 1 trader AIs so this is safe trader_data = savegame_db("SELECT rowid FROM player WHERE is_trader = 1") if trader_data: self.trader = Trader.load(self.session, savegame_db, trader_data[0][0]) # there are 0 or 1 pirate AIs so this is safe pirate_data = savegame_db("SELECT rowid FROM player WHERE is_pirate = 1") if pirate_data: self.pirate = Pirate.load(self.session, savegame_db, pirate_data[0][0]) # load all units (we do it here cause all buildings are loaded by now) LoadingProgress.broadcast(self, 'world_load_units') for (worldid, typeid) in savegame_db("SELECT rowid, type FROM unit ORDER BY rowid"): Entities.units[typeid].load(self.session, savegame_db, worldid) if self.session.is_game_loaded(): # let trader and pirate command their ships. we have to do this here # because ships have to be initialized for this, and they have # to exist before ships are loaded. if self.trader: self.trader.load_ship_states(savegame_db) if self.pirate: self.pirate.finish_loading(savegame_db) # load the AI stuff only when we have AI players LoadingProgress.broadcast(self, 'world_setup_ai') if any(isinstance(player, AIPlayer) for player in self.players): AIPlayer.load_abstract_buildings(self.session.db) # TODO: find a better place for this # load the AI players # this has to be done here because otherwise the ships and other objects won't exist for player in self.players: if not isinstance(player, HumanPlayer): player.finish_loading(savegame_db) LoadingProgress.broadcast(self, 'world_load_stuff') self._load_combat(savegame_db) self._load_diplomacy(savegame_db) self._load_disasters(savegame_db) self.inited = True """TUTORIAL:
def hide(self): self._current_step = 0 LoadingProgress.discard(self._update) self._widget.hide()
def _init(self, savegame_db, force_player_id=None, disasters_enabled=True): """ @param savegame_db: Dbreader with loaded savegame database @param force_player_id: the worldid of the selected human player or default if None (debug option) """ """ All essential and non-essential parts of the world are set up here, you don't need to know everything that happens. """ # load properties self.properties = {} for (name, value) in savegame_db("SELECT name, value FROM map_properties"): self.properties[name] = json.loads(value) if 'disasters_enabled' not in self.properties: # set on first init self.properties['disasters_enabled'] = disasters_enabled self._load_players(savegame_db, force_player_id) # all static data LoadingProgress.broadcast(self, 'world_load_map') self.load_raw_map(savegame_db) # load world buildings (e.g. fish) LoadingProgress.broadcast(self, 'world_load_buildings') buildings = savegame_db( "SELECT rowid, type FROM building WHERE location = ?", self.worldid) for (building_worldid, building_typeid) in buildings: load_building(self.session, savegame_db, building_typeid, building_worldid) # use a dict because it's directly supported by the pathfinding algo LoadingProgress.broadcast(self, 'world_init_water') self.water = {tile: 1.0 for tile in self.ground_map} self._init_water_bodies() self.sea_number = self.water_body[(self.min_x, self.min_y)] for island in self.islands: island.terrain_cache.create_sea_cache() # assemble list of water and coastline for ship, that can drive through shallow water # NOTE: this is rather a temporary fix to make the fisher be able to move # since there are tile between coastline and deep sea, all non-constructible tiles # are added to this list as well, which will contain a few too many self.water_and_coastline = copy.copy(self.water) for island in self.islands: for coord, tile in island.ground_map.items(): if 'coastline' in tile.classes or 'constructible' not in tile.classes: self.water_and_coastline[coord] = 1.0 self._init_shallow_water_bodies() self.shallow_sea_number = self.shallow_water_body[(self.min_x, self.min_y)] # create ship position list. entries: ship_map[(x, y)] = ship self.ship_map = {} self.ground_unit_map = {} if self.session.is_game_loaded(): # there are 0 or 1 trader AIs so this is safe trader_data = savegame_db( "SELECT rowid FROM player WHERE is_trader = 1") if trader_data: self.trader = Trader.load(self.session, savegame_db, trader_data[0][0]) # there are 0 or 1 pirate AIs so this is safe pirate_data = savegame_db( "SELECT rowid FROM player WHERE is_pirate = 1") if pirate_data: self.pirate = Pirate.load(self.session, savegame_db, pirate_data[0][0]) # load all units (we do it here cause all buildings are loaded by now) LoadingProgress.broadcast(self, 'world_load_units') for (worldid, typeid ) in savegame_db("SELECT rowid, type FROM unit ORDER BY rowid"): Entities.units[typeid].load(self.session, savegame_db, worldid) if self.session.is_game_loaded(): # let trader and pirate command their ships. we have to do this here # because ships have to be initialized for this, and they have # to exist before ships are loaded. if self.trader: self.trader.load_ship_states(savegame_db) if self.pirate: self.pirate.finish_loading(savegame_db) # load the AI stuff only when we have AI players LoadingProgress.broadcast(self, 'world_setup_ai') if any(isinstance(player, AIPlayer) for player in self.players): AIPlayer.load_abstract_buildings( self.session.db) # TODO: find a better place for this # load the AI players # this has to be done here because otherwise the ships and other objects won't exist for player in self.players: if not isinstance(player, HumanPlayer): player.finish_loading(savegame_db) LoadingProgress.broadcast(self, 'world_load_stuff') self._load_combat(savegame_db) self._load_diplomacy(savegame_db) self._load_disasters(savegame_db) self.inited = True """TUTORIAL:
def load(self, options): """Loads a map. Key method for starting a game.""" """ TUTORIAL: Here you see how the vital game elements (and some random things that are also required) are initialized. """ if options.is_scenario: # game_identifier is a yaml file, that contains reference to actual map file self.scenario_eventhandler = ScenarioEventHandler(self, options.game_identifier) # scenario maps can be normal maps or scenario maps: map_filename = self.scenario_eventhandler.get_map_file() options.game_identifier = os.path.join(SavegameManager.scenario_maps_dir, map_filename) if not os.path.exists(options.game_identifier): options.game_identifier = os.path.join(SavegameManager.maps_dir, map_filename) options.is_map = True self.log.debug("Session: Loading from %s", options.game_identifier) savegame_db = SavegameAccessor(options.game_identifier, options.is_map, options) # Initialize new dbreader savegame_data = SavegameManager.get_metadata(savegame_db.db_path) self.view.resize_layers(savegame_db) # load how often the game has been saved (used to know the difference between # a loaded and a new game) self.savecounter = savegame_data.get('savecounter', 0) if savegame_data.get('rng_state', None): rng_state_list = json.loads(savegame_data['rng_state']) # json treats tuples as lists, but we need tuples here, so convert back def rec_list_to_tuple(x): if isinstance(x, list): return tuple(rec_list_to_tuple(i) for i in x) else: return x rng_state_tuple = rec_list_to_tuple(rng_state_list) # changing the rng is safe for mp, as all players have to have the same map self.random.setstate(rng_state_tuple) LoadingProgress.broadcast(self, 'session_create_world') self.world = World(self) # Load horizons.world module (check horizons/world/__init__.py) self.world._init(savegame_db, options.force_player_id, disasters_enabled=options.disasters_enabled) self.view.load(savegame_db, self.world) # load view if not self.is_game_loaded(): options.init_new_world(self) else: # try to load scenario data self.scenario_eventhandler.load(savegame_db) self.manager.load(savegame_db) # load the manager (there might be old scheduled ticks). LoadingProgress.broadcast(self, "session_index_fish") self.world.init_fish_indexer() # now the fish should exist # load the old gui positions and stuff # Do this before loading selections, they need the minimap setup LoadingProgress.broadcast(self, "session_load_gui") self.ingame_gui = self._ingame_gui_class(self) self.ingame_gui.load(savegame_db) Scheduler().before_ticking() savegame_db.close() assert hasattr(self.world, "player"), 'Error: there is no human player' LoadingProgress.broadcast(self, "session_finish") """