Ejemplo n.º 1
0
    def init_new_world(self, trader_enabled, pirate_enabled,
                       natural_resource_multiplier):
        """
		This should be called if a new map is loaded (not a savegame, a fresh
		map). In other words, when it is loaded for the first time.

		NOTE: commands for creating the world objects are executed directly,
		      bypassing the manager.
		      This is necessary because else the commands would be transmitted
		      over the wire in network games.

		@return: the coordinates of the players first ship
		"""

        # workaround: the creation of all the objects causes a lot of logging output we don't need.
        #             therefore, reset the levels for now
        loggers_to_silence = {'world.production': None}
        for logger_name in loggers_to_silence:
            logger = logging.getLogger(logger_name)
            loggers_to_silence[logger_name] = logger.getEffectiveLevel()
            logger.setLevel(logging.WARN)

        # add a random number of environmental objects
        if natural_resource_multiplier != 0:
            self._add_nature_objects(natural_resource_multiplier)

        # reset loggers, see above
        for logger_name, level in loggers_to_silence.items():
            logging.getLogger(logger_name).setLevel(level)

        # add free trader
        if trader_enabled:
            self.trader = Trader(self.session, 99999, "Free Trader", Color())

        ret_coords = None
        for player in self.players:
            # Adding ships for the players
            # hack to place the ship on the development map
            point = self.get_random_possible_ship_position()
            # Execute command directly, not via manager, because else it would be transmitted over the
            # network to other players. Those however will do the same thing anyways.
            ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP, point.x,
                              point.y)(issuer=self.session.world.player)
            # give ship basic resources
            for res, amount in self.session.db(
                    "SELECT resource, amount FROM start_resources"):
                ship.get_component(StorageComponent).inventory.alter(
                    res, amount)
            if player is self.player:
                ret_coords = point.to_tuple()

                # HACK: Store starting ship as first unit group, and select it
                def _preselect_player_ship(player_ship):
                    sel_comp = player_ship.get_component(SelectableComponent)
                    sel_comp.select(reset_cam=True)
                    self.session.selected_instances = {player_ship}
                    self.session.ingame_gui.handle_selection_group(1, True)
                    sel_comp.show_menu()

                select_ship = partial(_preselect_player_ship, ship)
                Scheduler().add_new_object(select_ship, ship, run_in=0)

        # load the AI stuff only when we have AI players
        if any(isinstance(player, AIPlayer) for player in self.players):
            AIPlayer.load_abstract_buildings(
                self.session.db)  # TODO: find a better place for this

        # add a pirate ship
        if pirate_enabled:
            self.pirate = Pirate(self.session, 99998, "Captain Blackbeard",
                                 Color())

        assert ret_coords is not None, "Return coords are None. No players loaded?"
        return ret_coords
Ejemplo n.º 2
0
    def init_new_world(self,
                       minclay=2,
                       maxclay=3,
                       minmountains=1,
                       maxmountains=3):
        """
		This should be called if a new map is loaded (not a savegame, a fresh
		map). In other words when it is loaded for the first time.

		NOTE: commands for creating the world objects are executed directly,
		      bypassing the manager
		      This is necessary because else the commands would be transmitted
		      over the wire in network games.

		@return: Returs the coordinates of the players first ship
		"""
        # workaround: the creation of all the objects causes a lot of logging output, we don't need
        #             therefore, reset the levels for now
        loggers_to_silence = {'world.production': None}
        for logger_name in loggers_to_silence:
            logger = logging.getLogger(logger_name)
            loggers_to_silence[logger_name] = logger.getEffectiveLevel()
            logger.setLevel(logging.WARN)

        from horizons.command.building import Build
        from horizons.command.unit import CreateUnit
        # add a random number of environmental objects to the gameworld
        if int(self.properties.get('RandomTrees', 1)) == 1:
            Tree = Entities.buildings[BUILDINGS.TREE_CLASS]
            Clay = Entities.buildings[BUILDINGS.CLAY_DEPOSIT_CLASS]
            Fish = Entities.buildings[BUILDINGS.FISH_DEPOSIT_CLASS]
            Mountain = Entities.buildings[BUILDINGS.MOUNTAIN_CLASS]
            for island in self.islands:
                if maxclay <= minclay:
                    minclay = mayclay - 1
                if maxmountains <= minmountains:
                    minmountains = maxmountains - 1
                max_clay_deposits = self.session.random.randint(
                    minclay, maxclay)
                max_mountains = self.session.random.randint(
                    minmountains, maxmountains)
                num_clay_deposits = 0
                num_mountains = 0
                # TODO: fix this sorted()-call. its slow but orderness of dict-loop isn't guaranteed
                for coords, tile in sorted(island.ground_map.iteritems()):
                    # add tree to every nth tile
                    if self.session.random.randint(0, 2) == 0 and \
                       Tree.check_build(self.session, tile, check_settlement=False):
                        building = Build(Tree,
                                         coords[0],
                                         coords[1],
                                         ownerless=True,
                                         island=island)(issuer=None)
                        building.finish_production_now(
                        )  # make trees big and fill their inventory
                        if self.session.random.randint(
                                0, 40) == 0:  # add animal to every nth tree
                            CreateUnit(island.worldid, UNITS.WILD_ANIMAL_CLASS,
                                       *coords)(issuer=None)
                    elif num_clay_deposits < max_clay_deposits and \
                         self.session.random.randint(0, 40) == 0 and \
                         Clay.check_build(self.session, tile, check_settlement=False):
                        num_clay_deposits += 1
                        Build(Clay,
                              coords[0],
                              coords[1],
                              ownerless=True,
                              island=island)(issuer=None)
                    elif num_mountains < max_mountains and \
                         self.session.random.randint(0, 40) == 0 and \
                         Mountain.check_build(self.session, tile, check_settlement=False):
                        num_mountains += 1
                        Build(Mountain,
                              coords[0],
                              coords[1],
                              ownerless=True,
                              island=island)(issuer=None)
                    if 'coastline' in tile.classes and self.session.random.randint(
                            0, 4) == 0:
                        # try to place fish
                        # from the current position, go to random directions 2 times
                        directions = [(i, j) for i in xrange(-1, 2)
                                      for j in xrange(-1, 2)]
                        for (x_dir, y_dir) in self.session.random.sample(
                                directions, 2):
                            # move a random amount in both directions
                            coord_to_check = (
                                coords[0] +
                                x_dir * self.session.random.randint(3, 9),
                                coords[1] +
                                y_dir * self.session.random.randint(3, 9),
                            )
                            # now we have the location, check if we can build here
                            if coord_to_check in self.ground_map:
                                Build(Fish, coord_to_check[0], coord_to_check[1], ownerless=True, \
                                      island=self)(issuer=None)

        # reset loggers, see above
        for logger_name, level in loggers_to_silence.iteritems():
            logging.getLogger(logger_name).setLevel(level)

        # add free trader
        self.trader = Trader(self.session, 99999, u"Free Trader", Color())
        ret_coords = None
        for player in self.players:
            # Adding ships for the players
            point = self.get_random_possible_ship_position()
            # Execute command directly, not via manager, because else it would be transmitted over the
            # network to other players. Those however will do the same thing anyways.
            ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP_CLASS, point.x,
                              point.y)(issuer=self.session.world.player)
            # give ship basic resources
            for res, amount in self.session.db(
                    "SELECT resource, amount FROM start_resources"):
                ship.inventory.alter(res, amount)
            if player is self.player:
                ret_coords = (point.x, point.y)

        # add a pirate ship
        self.pirate = Pirate(self.session, 99998, "Captain Blackbeard",
                             Color())

        # Fire a message for new world creation
        self.session.ingame_gui.message_widget.add(self.max_x / 2,
                                                   self.max_y / 2, 'NEW_WORLD')
        assert ret_coords is not None, "Return coords are None. No players loaded?"
        return ret_coords