def new_session(mapgen=create_map, rng_seed=RANDOM_SEED, human_player=True, ai_players=0):
	"""
	Create a new session with a map, add one human player and a trader (it will crash
	otherwise). It returns both session and player to avoid making the function-based
	tests too verbose.
	"""
	session = SPTestSession(rng_seed=rng_seed)
	human_difficulty = DifficultySettings.DEFAULT_LEVEL
	ai_difficulty = DifficultySettings.EASY_LEVEL

	players = []
	if human_player:
		players.append({
			'id': 1,
			'name': 'foobar',
			'color': Color.get(1),
			'local': True,
			'ai': False,
			'difficulty': human_difficulty,
		})

	for i in range(ai_players):
		id = i + human_player + 1
		players.append({
			'id': id,
			'name': ('AI' + str(i)),
			'color': Color.get(id),
			'local': (id == 1),
			'ai': True,
			'difficulty': ai_difficulty,
		})

	session.load(mapgen(), players, ai_players > 0, True)
	return session, session.world.player
Пример #2
0
    def _get_player_list(self):
        if self._player_list is not None:
            return self._player_list

        # for now just make it a bit easier for the AI
        difficulty_level = {
            False: DifficultySettings.DEFAULT_LEVEL,
            True: DifficultySettings.EASY_LEVEL
        }

        players = []
        players.append({
            'id':
            1,
            'name':
            self.player_name,
            'color':
            Color.get(1) if self.player_color is None else self.player_color,
            'local':
            True,
            'ai':
            self.human_ai,
            'difficulty':
            difficulty_level[bool(self.human_ai)],
        })

        cur_locale = horizons.globals.fife.get_locale()

        # add AI players with a distinct color; if none can be found then use black
        for num in range(self.ai_players):
            color = Color.get(
                COLORS.BLACK)  # if none can be found then be black
            for possible_color in Color.get_defaults():
                if possible_color == Color.get(COLORS.BLACK):
                    continue  # black is used by the trader and the pirate
                used = any(possible_color == player['color']
                           for player in players)
                if not used:
                    color = possible_color
                    break

            name = horizons.globals.db.get_random_ai_name(
                cur_locale, [p['name'] for p in players])
            # out of pre-defined names?
            if name is None:
                name = 'AI' + str(num + 1)

            players.append({
                'id': num + 2,
                'name': name,
                'color': color,
                'local': False,
                'ai': True,
                'difficulty': difficulty_level[True],
            })
        return players
Пример #3
0
	def set_color(self, color_id):
		"""Updates the background color of large label where players
		see their currently chosen color.
		@param color_id: int. Gets converted to util.Color object.
		"""
		try:
			self.selected_color = Color.get(color_id)
		except KeyError:
			# For some reason, color_id can be 0 apparently:
			# http://forum.unknown-horizons.org/viewtopic.php?t=6927
			# Reset that setting to 1 if the problem occurs.
			self.selected_color = Color.get(1)
		self.gui.findChild(name='selectedcolor').background_color = self.selected_color
Пример #4
0
def setup_combat(s, ship):
	worldid = 10000000

	p0 = Player(s, worldid, "p1", Color.get(1))
	p1 = Player(s, worldid+1, "p2", Color.get(2))

	for p in (p0, p1):
		p.initialize(None)
		s.world.players.append(p)

	s0 = CreateUnit(p0.worldid, ship, 0, 0)(issuer=p0)
	s1 = CreateUnit(p1.worldid, ship, 3, 3)(issuer=p1)

	return ((p0, s0), (p1, s1))
Пример #5
0
def setup_combat(s, ship):
    worldid = 10000000

    p0 = Player(s, worldid, "p1", Color.get(1))
    p1 = Player(s, worldid + 1, "p2", Color.get(2))

    for p in (p0, p1):
        p.initialize(None)
        s.world.players.append(p)

    s0 = CreateUnit(p0.worldid, ship, 0, 0)(issuer=p0)
    s1 = CreateUnit(p1.worldid, ship, 3, 3)(issuer=p1)

    return ((p0, s0), (p1, s1))
Пример #6
0
    def set_color(self, color_id):
        """Updates the background color of large label where players
		see their currently chosen color.
		@param color_id: int. Gets converted to util.Color object.
		"""
        try:
            self.selected_color = Color.get(color_id)
        except KeyError:
            # For some reason, color_id can be 0 apparently:
            # http://forum.unknown-horizons.org/viewtopic.php?t=6927
            # Reset that setting to 1 if the problem occurs.
            self.selected_color = Color.get(1)
        self.gui.findChild(
            name='selectedcolor').background_color = self.selected_color
    def _get_player_list(self):
        if self._player_list is not None:
            return self._player_list

            # for now just make it a bit easier for the AI
        difficulty_level = {False: DifficultySettings.DEFAULT_LEVEL, True: DifficultySettings.EASY_LEVEL}

        players = []
        players.append(
            {
                "id": 1,
                "name": self.player_name,
                "color": Color.get(1) if self.player_color is None else self.player_color,
                "local": True,
                "ai": self.human_ai,
                "difficulty": difficulty_level[bool(self.human_ai)],
            }
        )

        cur_locale = horizons.globals.fife.get_locale()

        # add AI players with a distinct color; if none can be found then use black
        for num in xrange(self.ai_players):
            color = Color.get(COLORS.BLACK)  # if none can be found then be black
            for possible_color in Color.get_defaults():
                if possible_color == Color.get(COLORS.BLACK):
                    continue  # black is used by the trader and the pirate
                used = any(possible_color == player["color"] for player in players)
                if not used:
                    color = possible_color
                    break

            name = horizons.globals.db.get_random_ai_name(cur_locale, [p["name"] for p in players])
            # out of pre-defined names?
            if name is None:
                name = "AI" + str(num + 1)

            players.append(
                {
                    "id": num + 2,
                    "name": name,
                    "color": color,
                    "local": False,
                    "ai": True,
                    "difficulty": difficulty_level[True],
                }
            )
        return players
Пример #8
0
 def get_player_list(self):
     ret_players = []
     for index, player in enumerate(self.players, start=1):
         # TODO: add support for selecting difficulty levels to the GUI
         status = T('Ready') if player.ready else T('Not Ready')
         ret_players.append({
             'id':
             index,
             'sid':
             player.sid,
             'name':
             player.name,
             'color':
             Color.get(player.color),
             'clientid':
             player.clientid,
             'local':
             self.netif.get_client_name() == player.name,
             'ai':
             False,
             'difficulty':
             DifficultySettings.DEFAULT_LEVEL,
             'status':
             status
         })
     return ret_players
Пример #9
0
	def _show_change_player_details_popup(self, game):
		"""Shows a dialog where the player can change its name and/or color"""

		assigned = [p["color"] for p in NetworkInterface().get_game().get_player_list()
		            if p["name"] != NetworkInterface().get_client_name()]
		unused_colors = set(Color.get_defaults()) - set(assigned)

		playerdata = PlayerDataSelection(color_palette=unused_colors)
		playerdata.set_player_name(NetworkInterface().get_client_name())
		playerdata.set_color(NetworkInterface().get_client_color())

		dialog = load_uh_widget('set_player_details.xml')
		dialog.findChild(name="playerdataselectioncontainer").addChild(playerdata.get_widget())

		def _change_playerdata():
			NetworkInterface().change_name(playerdata.get_player_name())
			NetworkInterface().change_color(playerdata.get_player_color().id)
			dialog.hide()
			self._update_game_details()

		def _cancel():
			dialog.hide()

		dialog.mapEvents({
			OkButton.DEFAULT_NAME: _change_playerdata,
			CancelButton.DEFAULT_NAME: _cancel
		})

		dialog.show()
Пример #10
0
    def _show_change_player_details_popup(self, game):
        """Shows a dialog where the player can change its name and/or color"""

        assigned = [
            p["color"]
            for p in NetworkInterface().get_game().get_player_list()
            if p["name"] != NetworkInterface().get_client_name()
        ]
        unused_colors = set(Color.get_defaults()) - set(assigned)

        playerdata = PlayerDataSelection(color_palette=unused_colors)
        playerdata.set_player_name(NetworkInterface().get_client_name())
        playerdata.set_color(NetworkInterface().get_client_color())

        dialog = load_uh_widget('set_player_details.xml')
        dialog.findChild(name="playerdataselectioncontainer").addChild(
            playerdata.get_widget())

        def _change_playerdata():
            NetworkInterface().change_name(playerdata.get_player_name())
            NetworkInterface().change_color(playerdata.get_player_color().id)
            dialog.hide()
            self._update_game_details()

        def _cancel():
            dialog.hide()

        dialog.mapEvents({
            OkButton.DEFAULT_NAME: _change_playerdata,
            CancelButton.DEFAULT_NAME: _cancel
        })

        dialog.show()
Пример #11
0
	def _load(self, db, worldid):
		"""This function makes it possible to load playerdata into an already allocated
		Player instance, which is used e.g. in Trader.load"""
		super(Player, self).load(db, worldid)

		color, name, client_id, settlerlevel, difficulty_level, max_tier_notification = db(
			"SELECT color, name, client_id, settler_level, difficulty_level, max_tier_notification"
			" FROM player WHERE rowid = ?", worldid)[0]
		self.__init(name, Color.get(color), client_id, difficulty_level, max_tier_notification, settlerlevel = settlerlevel)
Пример #12
0
	def _load(self, db, worldid):
		"""This function makes it possible to load playerdata into an already allocated
		Player instance, which is used e.g. in Trader.load"""
		super(Player, self).load(db, worldid)

		color, name, client_id, settlerlevel, difficulty_level, max_tier_notification = db(
			"SELECT color, name, client_id, settler_level, difficulty_level, max_tier_notification"
			" FROM player WHERE rowid = ?", worldid)[0]
		self.__init(name, Color.get(color), client_id, difficulty_level, max_tier_notification, settlerlevel = settlerlevel)
Пример #13
0
def new_session(mapgen=create_map,
                rng_seed=RANDOM_SEED,
                human_player=True,
                ai_players=0):
    """
	Create a new session with a map, add one human player and a trader (it will crash
	otherwise). It returns both session and player to avoid making the function-based
	tests too verbose.
	"""
    session = SPTestSession(rng_seed=rng_seed)
    human_difficulty = DifficultySettings.DEFAULT_LEVEL
    ai_difficulty = DifficultySettings.EASY_LEVEL

    players = []
    if human_player:
        players.append({
            'id': 1,
            'name': 'foobar',
            'color': Color.get(1),
            'local': True,
            'ai': False,
            'difficulty': human_difficulty,
        })

    for i in xrange(ai_players):
        id = i + human_player + 1
        players.append({
            'id': id,
            'name': ('AI' + str(i)),
            'color': Color.get(id),
            'local': (id == 1),
            'ai': True,
            'difficulty': ai_difficulty,
        })

    session.load(mapgen(), players, ai_players > 0, True)
    return session, session.world.player
	def change_color(self, new_color, save=True):
		new_color %= len(set(Color.get_defaults()))

		if save:
			horizons.globals.fife.set_uh_setting("ColorID", new_color)
			horizons.globals.fife.save_settings()

		try:
			if self._client_data.color == new_color:
				return
			self.log.debug("[CHANGECOLOR] %s", new_color)
			if self._mode is None or self._game is None:
				self._client_data.color = new_color
				return
			self.send_packet(packets.client.cmd_changecolor(new_color))
		except NetworkException as e:
			self._handle_exception(e)
Пример #15
0
	def change_color(self, new_color, save=True):
		new_color %= len(set(Color.get_defaults()))

		if save:
			horizons.globals.fife.set_uh_setting("ColorID", new_color)
			horizons.globals.fife.save_settings()

		try:
			if self._client_data.color == new_color:
				return
			self.log.debug("[CHANGECOLOR] %s" % (new_color))
			if self._mode is None or self._game is None:
				self._client_data.color = new_color
				return
			self.send_packet(packets.client.cmd_changecolor(new_color))
		except NetworkException as e:
			self._handle_exception(e)
	def get_player_list(self):
		ret_players = []
		for index, player in enumerate(self.players, start=1):
			# TODO: add support for selecting difficulty levels to the GUI
			status = T('Ready') if player.ready else T('Not Ready')
			ret_players.append({
				'id':         index,
				'sid':        player.sid,
				'name':       player.name,
				'color':      Color.get(player.color),
				'clientid':   player.clientid,
				'local':      self.netif.get_client_name() == player.name,
				'ai':         False,
				'difficulty': DifficultySettings.DEFAULT_LEVEL,
				'status':     status
				})
		return ret_players
Пример #17
0
    def __init__(self, color_palette=None):
        """
		@param widgets: WidgetsDict
		"""
        self.gui = load_uh_widget('playerdataselection.xml')

        self.colors = self.gui.findChild(name='playercolor')

        colorlabels = []
        events = {}

        # need the id to save it as int in settings file.
        for color in (Color.get_defaults()
                      if color_palette is None else color_palette):
            label = Label(name='{color}'.format(color=color.name),
                          text="    ",
                          max_size=(20, 20),
                          min_size=(20, 20),
                          background_color=color)
            events['{label}/mouseClicked'.format(label=color.name)] = \
                                         Callback(self.set_color, color.id)
            colorlabels.append(label)

        # split into three rows with at max 5 entries in each row
        # right now there are 14 different colors to choose from.
        for i in range(0, len(colorlabels), 5):
            hbox = HBox(name='line_{index}'.format(index=i))
            hbox.addChildren(colorlabels[i:i + 5])
            self.colors.addChild(hbox)

        playertextfield = self.gui.findChild(name='playername')

        def playertextfield_clicked():
            if playertextfield.text == 'Unnamed Traveler':
                playertextfield.text = ""

        playertextfield.capture(playertextfield_clicked,
                                event_name='mouseClicked')

        self.gui.mapEvents(events)
        self.update_data()
Пример #18
0
	def __init__(self, color_palette=None):
		"""
		@param widgets: WidgetsDict
		"""
		self.gui = load_uh_widget('playerdataselection.xml')

		self.colors = self.gui.findChild(name='playercolor')

		colorlabels = []
		events = {}

		# need the id to save it as int in settings file.
		for color in (Color.get_defaults() if color_palette is None else color_palette):
			label = Label(name = u'{color}'.format(color=color.name),
			              text = u"    ",
			              max_size = (20, 20),
			              min_size = (20, 20),
			              background_color = color)
			events['{label}/mouseClicked'.format(label=color.name)] = \
			                             Callback(self.set_color, color.id)
			colorlabels.append(label)

		# split into three rows with at max 5 entries in each row
		# right now there are 14 different colors to choose from.
		for i in xrange(0, len(colorlabels), 5):
			hbox = HBox(name='line_{index}'.format(index=i))
			hbox.addChildren(colorlabels[i:i+5])
			self.colors.addChild(hbox)

		playertextfield = self.gui.findChild(name='playername')
		def playertextfield_clicked():
			if playertextfield.text == 'Unnamed Traveler':
				playertextfield.text = ""
		playertextfield.capture(playertextfield_clicked, event_name='mouseClicked')

		self.gui.mapEvents(events)
		self.update_data()
Пример #19
0
	def test_default_color(self):
		self.assertTrue(Color(0, 0, 0, 255).is_default_color)
		self.assertFalse(Color(1, 2, 3, 255).is_default_color)
def test_indexing():
	assert Color.get(1) == Color(0, 0, 0, 255)
	assert Color.get('black') == Color(0, 0, 0, 255)
Пример #21
0
    def init_new_world(self):
        """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:
                max_clay_deposits = self.session.random.randint(2, 3)
                max_mountains = self.session.random.randint(1, 3)
                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
        # TODO: enable pirate as soon as save/load for it is fixed
        #       currently, it breaks human player selection on load
        #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
Пример #22
0
def test_iter():
    colors = list(Color.get_defaults())
    assert len(colors) == 2
    assert all(c.is_default_color for c in colors)
    assert colors[0] == Color(0, 0, 0, 255)
    assert colors[1] == Color(255, 0, 0, 255)
Пример #23
0
def test_default_color():
    assert Color(0, 0, 0, 255).is_default_color
    assert not Color(1, 2, 3, 255).is_default_color
Пример #24
0
def test_comparison():
    assert Color(0, 0, 0, 255) == Color(0, 0, 0, 255)
    assert Color(0, 0, 0, 255) != Color(1, 2, 3, 255)
Пример #25
0
 def test_indexing(self):
     self.assertEqual(Color.get(1), Color(0, 0, 0, 255))
     self.assertEqual(Color.get('black'), Color(0, 0, 0, 255))
Пример #26
0
	def test_iter(self):
		colors = list(Color)
		self.assertEqual(len(colors), 2)
		self.assertTrue(all(c.is_default_color for c in colors))
		self.assertEqual(colors[0], Color(0, 0, 0, 255))
		self.assertEqual(colors[1], Color(255, 0, 0, 255))
Пример #27
0
def test_indexing():
    assert Color.get(1) == Color(0, 0, 0, 255)
    assert Color.get('black') == Color(0, 0, 0, 255)
def test_iter():
	colors = list(Color.get_defaults())
	assert len(colors) == 2
	assert all(c.is_default_color for c in colors)
	assert colors[0] == Color(0, 0, 0, 255)
	assert colors[1] == Color(255, 0, 0, 255)
Пример #29
0
	def test_comparison(self):
		self.assertEqual(Color(0, 0, 0, 255), Color(0, 0, 0, 255))
		self.assertNotEqual(Color(0, 0, 0, 255), Color(1, 2, 3, 255))
Пример #30
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
Пример #31
0
	def test_indexing(self):
		self.assertEqual(Color[1], Color(0, 0, 0, 255))
		self.assertEqual(Color['black'], Color(0, 0, 0, 255))