← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/max_players into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/max_players into lp:widelands.

Commit message:
Use playercolor masks for player editor/menu player icons. Increased max players to 16.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/max_players/+merge/309083

Tibor can use this for the AI, so proposing this early.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/max_players into lp:widelands.
=== removed file 'data/images/players/editor_player_01_starting_pos.png'
Binary files data/images/players/editor_player_01_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_01_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_02_starting_pos.png'
Binary files data/images/players/editor_player_02_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_02_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_03_starting_pos.png'
Binary files data/images/players/editor_player_03_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_03_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_04_starting_pos.png'
Binary files data/images/players/editor_player_04_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_04_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_05_starting_pos.png'
Binary files data/images/players/editor_player_05_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_05_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_06_starting_pos.png'
Binary files data/images/players/editor_player_06_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_06_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/editor_player_07_starting_pos.png'
Binary files data/images/players/editor_player_07_starting_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/editor_player_07_starting_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_01_pos.png'
Binary files data/images/players/fsel_editor_set_player_01_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_01_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_02_pos.png'
Binary files data/images/players/fsel_editor_set_player_02_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_02_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_03_pos.png'
Binary files data/images/players/fsel_editor_set_player_03_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_03_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_04_pos.png'
Binary files data/images/players/fsel_editor_set_player_04_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_04_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_05_pos.png'
Binary files data/images/players/fsel_editor_set_player_05_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_05_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_06_pos.png'
Binary files data/images/players/fsel_editor_set_player_06_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_06_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/fsel_editor_set_player_07_pos.png'
Binary files data/images/players/fsel_editor_set_player_07_pos.png	2014-12-02 21:50:09 +0000 and data/images/players/fsel_editor_set_player_07_pos.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_01.png'
Binary files data/images/players/genstats_enable_plr_01.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_01.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_02.png'
Binary files data/images/players/genstats_enable_plr_02.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_02.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_03.png'
Binary files data/images/players/genstats_enable_plr_03.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_03.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_04.png'
Binary files data/images/players/genstats_enable_plr_04.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_04.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_05.png'
Binary files data/images/players/genstats_enable_plr_05.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_05.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_06.png'
Binary files data/images/players/genstats_enable_plr_06.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_06.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/players/genstats_enable_plr_07.png'
Binary files data/images/players/genstats_enable_plr_07.png	2014-12-02 21:50:09 +0000 and data/images/players/genstats_enable_plr_07.png	1970-01-01 00:00:00 +0000 differ
=== renamed file 'data/images/players/genstats_enable_plr_08.png' => 'data/images/players/genstats_player.png'
=== added file 'data/images/players/genstats_player_pc.png'
Binary files data/images/players/genstats_player_pc.png	1970-01-01 00:00:00 +0000 and data/images/players/genstats_player_pc.png	2016-10-22 07:40:34 +0000 differ
=== renamed file 'data/images/players/editor_player_08_starting_pos.png' => 'data/images/players/player_position.png'
=== renamed file 'data/images/players/fsel_editor_set_player_08_pos.png' => 'data/images/players/player_position_menu.png'
=== added file 'data/images/players/player_position_menu_pc.png'
Binary files data/images/players/player_position_menu_pc.png	1970-01-01 00:00:00 +0000 and data/images/players/player_position_menu_pc.png	2016-10-22 07:40:34 +0000 differ
=== added file 'data/images/players/player_position_pc.png'
Binary files data/images/players/player_position_pc.png	1970-01-01 00:00:00 +0000 and data/images/players/player_position_pc.png	2016-10-22 07:40:34 +0000 differ
=== modified file 'data/txts/developers.json'
--- data/txts/developers.json	2016-10-05 04:24:26 +0000
+++ data/txts/developers.json	2016-10-22 07:40:34 +0000
@@ -2,7 +2,7 @@
 	"developers":[
 		{
 			"heading": "Chieftain",
-			"image": "images/players/genstats_enable_plr_01.png",
+			"image": "images/players/genstats_player.png",
 			"entries":[
 				{
 					"members":[
@@ -13,7 +13,7 @@
 		},
 		{
 			"heading": "Elders",
-			"image": "images/players/genstats_enable_plr_04.png",
+			"image": "images/players/genstats_player.png",
 			"entries":[
 				{
 					"subheading": "Graphics",
@@ -329,7 +329,7 @@
 		},
 		{
 			"heading": "Former Elders",
-			"image": "images/players/genstats_enable_plr_04.png",
+			"image": "images/players/genstats_player.png",
 			"entries":[
 				{
 					"subheading": "Graphics",

=== modified file 'data/txts/help/multiplayer_help.lua'
--- data/txts/help/multiplayer_help.lua	2016-03-14 11:37:49 +0000
+++ data/txts/help/multiplayer_help.lua	2016-10-22 07:40:34 +0000
@@ -12,7 +12,7 @@
 
       result = result .. rt(h2(_"Client settings"))
       result = result .. rt(p(_"On the left side is a list of all clients including you. You can set your role with the button following your nickname. Available roles are:"))
-      result = result .. picture_li("images/players/genstats_enable_plr_08.png", _"The player with the color of the flag. If more than one client selected the same color, these share control over the player (‘shared kingdom mode’).")
+      result = result .. picture_li("images/players/genstats_player.png", _"The player with the color of the flag. If more than one client selected the same color, these share control over the player (‘shared kingdom mode’).")
       result = result .. picture_li("images/wui/fieldaction/menu_tab_watch.png", _"Spectator mode, meaning you can see everything, but cannot control any player")
 
       result = result .. rt(h2(_"Player settings"))

=== modified file 'src/editor/CMakeLists.txt'
--- src/editor/CMakeLists.txt	2016-05-11 19:05:05 +0000
+++ src/editor/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -93,6 +93,7 @@
     base_macros
     base_scoped_timer
     graphic
+    graphic_playercolor
     graphic_surface
     io_filesystem
     logic

=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2016-09-25 18:46:29 +0000
+++ src/editor/editorinteractive.cc	2016-10-22 07:40:34 +0000
@@ -38,6 +38,7 @@
 #include "editor/ui_menus/tool_menu.h"
 #include "editor/ui_menus/toolsize_menu.h"
 #include "graphic/graphic.h"
+#include "graphic/playercolor.h"
 #include "logic/map.h"
 #include "logic/map_objects/tribes/tribes.h"
 #include "logic/map_objects/world/resource_description.h"
@@ -55,16 +56,6 @@
 #include "wui/interactive_base.h"
 
 namespace {
-
-static char const* const player_pictures[] = {"images/players/editor_player_01_starting_pos.png",
-                                              "images/players/editor_player_02_starting_pos.png",
-                                              "images/players/editor_player_03_starting_pos.png",
-                                              "images/players/editor_player_04_starting_pos.png",
-                                              "images/players/editor_player_05_starting_pos.png",
-                                              "images/players/editor_player_06_starting_pos.png",
-                                              "images/players/editor_player_07_starting_pos.png",
-                                              "images/players/editor_player_08_starting_pos.png"};
-
 using Widelands::Building;
 
 // Load all tribes from disk.
@@ -167,13 +158,10 @@
 
 	//  Starting locations
 	Widelands::PlayerNumber const nr_players = map.get_nrplayers();
-	assert(nr_players <= MAX_PLAYERS);
+	assert(nr_players <= kMaxPlayers);
 	iterate_player_numbers(p, nr_players) {
 		if (Widelands::Coords const sp = map.get_starting_pos(p)) {
-			const Image* player_image = g_gr->images().get(player_pictures[p - 1]);
-			assert(player_image);
-			mutable_field_overlay_manager()->register_overlay(
-			   sp, player_image, 8, Point(player_image->width() / 2, STARTING_POS_HOTSPOT_Y));
+			tools_->set_starting_pos.set_starting_pos(*this, p, sp, &map);
 		}
 	}
 
@@ -543,10 +531,11 @@
 	tools_->current_pointer = &primary;
 	tools_->use_tool = which;
 
-	if (char const* const sel_pic = primary.get_sel(which))
+	if (const Image* sel_pic = primary.get_sel(which)) {
 		set_sel_picture(sel_pic);
-	else
+	} else {
 		unset_sel_picture();
+	}
 	set_sel_triangles(primary.operates_on_triangles());
 }
 

=== modified file 'src/editor/tools/decrease_height_tool.h'
--- src/editor/tools/decrease_height_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/decrease_height_tool.h	2016-10-22 07:40:34 +0000
@@ -41,8 +41,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor//fsel_editor_decrease_height.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor//fsel_editor_decrease_height.png");
 	}
 
 	int32_t get_change_by() const {

=== modified file 'src/editor/tools/decrease_resources_tool.h'
--- src/editor/tools/decrease_resources_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/decrease_resources_tool.h	2016-10-22 07:40:34 +0000
@@ -41,8 +41,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_decrease_resources.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_decrease_resources.png");
 	}
 
 	int32_t get_change_by() const {

=== modified file 'src/editor/tools/delete_bob_tool.h'
--- src/editor/tools/delete_bob_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/delete_bob_tool.h	2016-10-22 07:40:34 +0000
@@ -41,8 +41,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_delete.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_delete.png");
 	}
 };
 

=== modified file 'src/editor/tools/delete_immovable_tool.h'
--- src/editor/tools/delete_immovable_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/delete_immovable_tool.h	2016-10-22 07:40:34 +0000
@@ -41,8 +41,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_delete.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_delete.png");
 	}
 };
 

=== modified file 'src/editor/tools/draw_tool.h'
--- src/editor/tools/draw_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/draw_tool.h	2016-10-22 07:40:34 +0000
@@ -43,8 +43,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "EDITOR_DRAW_TOOL";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/novalue.png");
 	}
 
 	void add_action(EditorToolAction ac, EditorActionArgs& args);

=== modified file 'src/editor/tools/history.cc'
--- src/editor/tools/history.cc	2016-08-04 15:49:05 +0000
+++ src/editor/tools/history.cc	2016-10-22 07:40:34 +0000
@@ -94,7 +94,7 @@
 	   tool, static_cast<uint32_t>(ind), map, center, parent, tool.format_args(ind, parent));
 	if (draw && tool.is_undoable()) {
 		if (undo_stack_.empty() ||
-		    undo_stack_.front().tool.get_sel_impl() != std::string(draw_tool_.get_sel_impl())) {
+		    undo_stack_.front().tool.get_sel_impl() != draw_tool_.get_sel_impl()) {
 			EditorToolAction da(draw_tool_, EditorTool::First, map, center, parent,
 			                    draw_tool_.format_args(EditorTool::First, parent));
 

=== modified file 'src/editor/tools/increase_height_tool.h'
--- src/editor/tools/increase_height_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/increase_height_tool.h	2016-10-22 07:40:34 +0000
@@ -47,8 +47,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_increase_height.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_increase_height.png");
 	}
 
 	int32_t get_change_by() const {

=== modified file 'src/editor/tools/increase_resources_tool.h'
--- src/editor/tools/increase_resources_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/increase_resources_tool.h	2016-10-22 07:40:34 +0000
@@ -53,8 +53,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_increase_resources.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_increase_resources.png");
 	}
 
 	int32_t get_change_by() const {

=== modified file 'src/editor/tools/info_tool.h'
--- src/editor/tools/info_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/info_tool.h	2016-10-22 07:40:34 +0000
@@ -33,8 +33,8 @@
 	                          EditorActionArgs* args,
 	                          Widelands::Map* map) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_info.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_info.png");
 	}
 
 	bool has_size_one() const override {

=== modified file 'src/editor/tools/make_infrastructure_tool.h'
--- src/editor/tools/make_infrastructure_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/make_infrastructure_tool.h	2016-10-22 07:40:34 +0000
@@ -48,8 +48,8 @@
 	                          EditorActionArgs* args,
 	                          Widelands::Map* map) override;
 
-	const char* get_sel_impl() const override {
-		return "images/ui_basic/fsel.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/ui_basic/fsel.png");
 	}  //  Standard sel icon, most complex tool of all
 
 private:

=== modified file 'src/editor/tools/noise_height_tool.h'
--- src/editor/tools/noise_height_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/noise_height_tool.h	2016-10-22 07:40:34 +0000
@@ -44,8 +44,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_noise_height.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_noise_height.png");
 	}
 
 	Widelands::HeightInterval get_interval() const {

=== modified file 'src/editor/tools/place_bob_tool.h'
--- src/editor/tools/place_bob_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/place_bob_tool.h	2016-10-22 07:40:34 +0000
@@ -42,8 +42,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_place_bob.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_place_bob.png");
 	}
 };
 

=== modified file 'src/editor/tools/place_immovable_tool.h'
--- src/editor/tools/place_immovable_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/place_immovable_tool.h	2016-10-22 07:40:34 +0000
@@ -44,8 +44,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_place_immovable.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_place_immovable.png");
 	}
 };
 

=== modified file 'src/editor/tools/set_height_tool.h'
--- src/editor/tools/set_height_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_height_tool.h	2016-10-22 07:40:34 +0000
@@ -43,8 +43,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_set_height.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_set_height.png");
 	}
 
 	Widelands::HeightInterval get_interval() const {

=== modified file 'src/editor/tools/set_origin_tool.h'
--- src/editor/tools/set_origin_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_origin_tool.h	2016-10-22 07:40:34 +0000
@@ -42,8 +42,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/ui_basic/fsel.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/ui_basic/fsel.png");
 	}
 
 	bool has_size_one() const override {

=== modified file 'src/editor/tools/set_port_space_tool.h'
--- src/editor/tools/set_port_space_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_port_space_tool.h	2016-10-22 07:40:34 +0000
@@ -43,8 +43,8 @@
 	                         EditorActionArgs* args,
 	                         Widelands::Map* map) override;
 
-	char const* get_sel_impl() const override {
-		return FSEL_EUPS_FILENAME;
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get(FSEL_EUPS_FILENAME);
 	}
 };
 
@@ -65,8 +65,8 @@
 	                         EditorActionArgs* args,
 	                         Widelands::Map* map) override;
 
-	char const* get_sel_impl() const override {
-		return FSEL_ESPS_FILENAME;
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get(FSEL_ESPS_FILENAME);
 	}
 };
 

=== modified file 'src/editor/tools/set_resources_tool.h'
--- src/editor/tools/set_resources_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_resources_tool.h	2016-10-22 07:40:34 +0000
@@ -46,8 +46,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/wui/editor/fsel_editor_set_resources.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/wui/editor/fsel_editor_set_resources.png");
 	}
 
 	Widelands::ResourceAmount get_set_to() const {

=== modified file 'src/editor/tools/set_starting_pos_tool.cc'
--- src/editor/tools/set_starting_pos_tool.cc	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_starting_pos_tool.cc	2016-10-22 07:40:34 +0000
@@ -22,28 +22,8 @@
 #include "editor/editorinteractive.h"
 #include "editor/tools/tool.h"
 #include "graphic/graphic.h"
+#include "graphic/playercolor.h"
 #include "logic/map.h"
-#include "wui/field_overlay_manager.h"
-
-namespace {
-static char const* const player_pictures[] = {"images/players/editor_player_01_starting_pos.png",
-                                              "images/players/editor_player_02_starting_pos.png",
-                                              "images/players/editor_player_03_starting_pos.png",
-                                              "images/players/editor_player_04_starting_pos.png",
-                                              "images/players/editor_player_05_starting_pos.png",
-                                              "images/players/editor_player_06_starting_pos.png",
-                                              "images/players/editor_player_07_starting_pos.png",
-                                              "images/players/editor_player_08_starting_pos.png"};
-static char const* const player_pictures_small[] = {
-   "images/players/fsel_editor_set_player_01_pos.png",
-   "images/players/fsel_editor_set_player_02_pos.png",
-   "images/players/fsel_editor_set_player_03_pos.png",
-   "images/players/fsel_editor_set_player_04_pos.png",
-   "images/players/fsel_editor_set_player_05_pos.png",
-   "images/players/fsel_editor_set_player_06_pos.png",
-   "images/players/fsel_editor_set_player_07_pos.png",
-   "images/players/fsel_editor_set_player_08_pos.png"};
-}  // namespace
 
 // global variable to pass data from callback to class
 static int32_t current_player_;
@@ -77,9 +57,8 @@
 }
 
 EditorSetStartingPosTool::EditorSetStartingPosTool()
-   : EditorTool(*this, *this, false), current_sel_pic_(nullptr) {
+   : EditorTool(*this, *this, false), overlay_ids_(kMaxPlayers, 0) {
 	current_player_ = 1;
-	fsel_picsname_ = "images/players/fsel_editor_set_player_01_pos.png";
 }
 
 int32_t EditorSetStartingPosTool::handle_click_impl(const Widelands::World&,
@@ -100,34 +79,42 @@
 			current_player_ = 1;
 		}
 
-		Widelands::Coords const old_sp = map->get_starting_pos(current_player_);
-
-		const Image* player_image = g_gr->images().get(player_pictures[current_player_ - 1]);
-		assert(player_image);
-
 		//  check if field is valid
 		if (editor_tool_set_starting_pos_callback(map->get_fcoords(center.node), *map)) {
-			FieldOverlayManager* overlay_manager = eia.mutable_field_overlay_manager();
-			//  remove old overlay if any
-			overlay_manager->remove_overlay(old_sp, player_image);
-
-			//  add new overlay
-			overlay_manager->register_overlay(
-			   center.node, player_image, 4, Point(player_image->width() / 2, STARTING_POS_HOTSPOT_Y));
-
-			//  set new player pos
-			map->set_starting_pos(current_player_, center.node);
+			set_starting_pos(eia, current_player_, center.node, map);
 		}
 	}
 	return 1;
 }
 
+void EditorSetStartingPosTool::set_starting_pos(EditorInteractive& eia,
+                                                Widelands::PlayerNumber plnum,
+                                                const Widelands::Coords& c,
+                                                Widelands::Map* map) {
+	FieldOverlayManager* overlay_manager = eia.mutable_field_overlay_manager();
+	//  remove old overlay if any
+	overlay_manager->remove_overlay(overlay_ids_.at(plnum - 1));
+
+	//  add new overlay
+	FieldOverlayManager::OverlayId overlay_id = overlay_manager->next_overlay_id();
+	overlay_ids_[plnum - 1] = overlay_id;
+
+	const Image* player_image =
+	   playercolor_image(plnum - 1, g_gr->images().get("images/players/player_position.png"),
+	                     g_gr->images().get("images/players/player_position_pc.png"));
+	assert(player_image);
+
+	overlay_manager->register_overlay(
+	   c, player_image, 4, Point(player_image->width() / 2, STARTING_POS_HOTSPOT_Y), overlay_id);
+
+	//  set new player pos
+	map->set_starting_pos(plnum, c);
+}
+
 Widelands::PlayerNumber EditorSetStartingPosTool::get_current_player() const {
 	return current_player_;
 }
 
 void EditorSetStartingPosTool::set_current_player(int32_t const i) {
 	current_player_ = i;
-	fsel_picsname_ = player_pictures_small[current_player_ - 1];
-	current_sel_pic_ = fsel_picsname_;
 }

=== modified file 'src/editor/tools/set_starting_pos_tool.h'
--- src/editor/tools/set_starting_pos_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_starting_pos_tool.h	2016-10-22 07:40:34 +0000
@@ -20,8 +20,12 @@
 #ifndef WL_EDITOR_TOOLS_SET_STARTING_POS_TOOL_H
 #define WL_EDITOR_TOOLS_SET_STARTING_POS_TOOL_H
 
+#include <vector>
+
 #include "editor/tools/tool.h"
+#include "graphic/playercolor.h"
 #include "logic/widelands.h"
+#include "wui/field_overlay_manager.h"
 
 // How much place should be left around a player position
 // where no other player can start
@@ -37,8 +41,10 @@
 	                          EditorInteractive&,
 	                          EditorActionArgs*,
 	                          Widelands::Map*) override;
-	char const* get_sel_impl() const override {
-		return current_sel_pic_;
+	const Image* get_sel_impl() const override {
+		return playercolor_image(get_current_player() - 1,
+		                         g_gr->images().get("images/players/player_position_menu.png"),
+		                         g_gr->images().get("images/players/player_position_menu_pc.png"));
 	}
 
 	Widelands::PlayerNumber get_current_player() const;
@@ -46,10 +52,13 @@
 	bool has_size_one() const override {
 		return true;
 	}
+	void set_starting_pos(EditorInteractive& eia,
+	                      Widelands::PlayerNumber plnum,
+	                      const Widelands::Coords& c,
+	                      Widelands::Map* map);
 
 private:
-	char const* fsel_picsname_;
-	char const* current_sel_pic_;
+	std::vector<FieldOverlayManager::OverlayId> overlay_ids_;
 };
 
 int32_t editor_tool_set_starting_pos_callback(const Widelands::TCoords<Widelands::FCoords>& c,

=== modified file 'src/editor/tools/set_terrain_tool.h'
--- src/editor/tools/set_terrain_tool.h	2016-08-04 15:49:05 +0000
+++ src/editor/tools/set_terrain_tool.h	2016-10-22 07:40:34 +0000
@@ -41,8 +41,8 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive& parent) override;
 
-	char const* get_sel_impl() const override {
-		return "images/ui_basic/fsel.png";
+	const Image* get_sel_impl() const override {
+		return g_gr->images().get("images/ui_basic/fsel.png");
 	}
 	bool operates_on_triangles() const override {
 		return true;

=== modified file 'src/editor/tools/tool.h'
--- src/editor/tools/tool.h	2016-09-10 16:50:51 +0000
+++ src/editor/tools/tool.h	2016-10-22 07:40:34 +0000
@@ -23,6 +23,8 @@
 #define MAX_TOOL_AREA 9
 
 #include "base/macros.h"
+#include "graphic/graphic.h"
+#include "graphic/image.h"
 #include "editor/tools/action_args.h"
 #include "logic/widelands_geometry.h"
 
@@ -67,7 +69,7 @@
 		   .handle_undo_impl(world, center, parent, args, map);
 	}
 
-	const char* get_sel(const ToolIndex i) {
+	const Image* get_sel(const ToolIndex i) {
 		return (i == First ? *this : i == Second ? second_ : third_).get_sel_impl();
 	}
 
@@ -96,7 +98,7 @@
 	                                 Widelands::Map*) {
 		return 0;
 	}  // non unduable tools don't need to implement this.
-	virtual const char* get_sel_impl() const = 0;
+	virtual const Image* get_sel_impl() const = 0;
 	virtual bool operates_on_triangles() const {
 		return false;
 	}

=== modified file 'src/editor/ui_menus/main_menu_random_map.cc'
--- src/editor/ui_menus/main_menu_random_map.cc	2016-08-04 15:49:05 +0000
+++ src/editor/ui_menus/main_menu_random_map.cc	2016-10-22 07:40:34 +0000
@@ -33,7 +33,6 @@
 #include "editor/map_generator.h"
 #include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
-#include "logic/constants.h"
 #include "logic/editor_game_base.h"
 #include "logic/map.h"
 #include "logic/map_objects/world/world.h"
@@ -41,6 +40,11 @@
 #include "ui_basic/messagebox.h"
 #include "ui_basic/progresswindow.h"
 
+namespace {
+// The map generator can't find starting positions for too many players
+constexpr uint8_t kMaxMapgenPlayers = 8;
+} // namespace
+
 using namespace Widelands;
 
 MainMenuNewRandomMap::MainMenuNewRandomMap(EditorInteractive& parent)
@@ -406,7 +410,7 @@
 	case ButtonId::kMapSize:
 		// Restrict maximum players according to map size, but allow at least 2 players.
 		max_players_ = std::min(
-		   static_cast<size_t>(MAX_PLAYERS),
+			static_cast<size_t>(kMaxMapgenPlayers),
 		   (find_dimension_index(width_.get_value()) + find_dimension_index(height_.get_value())) /
 		         2 +
 		      2);
@@ -442,7 +446,7 @@
 	case ButtonId::kNone:
 		// Make sure that all conditions are met
 		max_players_ = std::min(
-		   static_cast<size_t>(MAX_PLAYERS),
+			static_cast<size_t>(kMaxMapgenPlayers),
 		   (find_dimension_index(width_.get_value()) + find_dimension_index(height_.get_value())) /
 		         2 +
 		      2);

=== modified file 'src/editor/ui_menus/player_menu.cc'
--- src/editor/ui_menus/player_menu.cc	2016-08-04 15:49:05 +0000
+++ src/editor/ui_menus/player_menu.cc	2016-10-22 07:40:34 +0000
@@ -26,7 +26,6 @@
 #include "editor/editorinteractive.h"
 #include "editor/tools/set_starting_pos_tool.h"
 #include "graphic/graphic.h"
-#include "logic/constants.h"
 #include "logic/map.h"
 #include "logic/map_objects/tribes/tribes.h"
 #include "logic/map_objects/tribes/warehouse.h"
@@ -36,26 +35,6 @@
 #include "ui_basic/textarea.h"
 #include "wui/field_overlay_manager.h"
 
-namespace {
-static char const* const player_pictures[] = {"images/players/editor_player_01_starting_pos.png",
-                                              "images/players/editor_player_02_starting_pos.png",
-                                              "images/players/editor_player_03_starting_pos.png",
-                                              "images/players/editor_player_04_starting_pos.png",
-                                              "images/players/editor_player_05_starting_pos.png",
-                                              "images/players/editor_player_06_starting_pos.png",
-                                              "images/players/editor_player_07_starting_pos.png",
-                                              "images/players/editor_player_08_starting_pos.png"};
-static char const* const player_pictures_small[] = {
-   "images/players/fsel_editor_set_player_01_pos.png",
-   "images/players/fsel_editor_set_player_02_pos.png",
-   "images/players/fsel_editor_set_player_03_pos.png",
-   "images/players/fsel_editor_set_player_04_pos.png",
-   "images/players/fsel_editor_set_player_05_pos.png",
-   "images/players/fsel_editor_set_player_06_pos.png",
-   "images/players/fsel_editor_set_player_07_pos.png",
-   "images/players/fsel_editor_set_player_08_pos.png"};
-}  // namespace
-
 #define UNDEFINED_TRIBE_NAME "<undefined>"
 
 inline EditorInteractive& EditorPlayerMenu::eia() {
@@ -73,7 +52,7 @@
                  g_gr->images().get("images/ui_basic/but1.png"),
                  g_gr->images().get("images/ui_basic/scrollbar_up.png"),
                  _("Add player"),
-                 parent.egbase().map().get_nrplayers() < MAX_PLAYERS),
+                 parent.egbase().map().get_nrplayers() < kMaxPlayers),
      remove_last_player_(this,
                          "remove_last_player",
                          5,
@@ -107,7 +86,7 @@
 
 	posy_ = posy;
 
-	for (Widelands::PlayerNumber i = 0; i < MAX_PLAYERS; ++i) {
+	for (Widelands::PlayerNumber i = 0; i < kMaxPlayers; ++i) {
 		plr_names_[i] = nullptr;
 		plr_set_pos_buts_[i] = nullptr;
 		plr_set_tribes_buts_[i] = nullptr;
@@ -150,7 +129,7 @@
 	}
 
 	//  Now remove all the unneeded stuff.
-	for (Widelands::PlayerNumber i = nr_players; i < MAX_PLAYERS; ++i) {
+	for (Widelands::PlayerNumber i = nr_players; i < kMaxPlayers; ++i) {
 		delete plr_names_[i];
 		plr_names_[i] = nullptr;
 		delete plr_set_pos_buts_[i];
@@ -205,7 +184,9 @@
 			plr_set_pos_buts_[p - 1]->sigclicked.connect(
 			   boost::bind(&EditorPlayerMenu::set_starting_pos_clicked, boost::ref(*this), p));
 		}
-		const Image* player_image = g_gr->images().get(player_pictures_small[p - 1]);
+		const Image* player_image =
+		   playercolor_image(p - 1, g_gr->images().get("images/players/player_position_menu.png"),
+		                     g_gr->images().get("images/players/player_position_menu_pc.png"));
 		assert(player_image);
 
 		plr_set_pos_buts_[p - 1]->set_pic(player_image);
@@ -217,7 +198,7 @@
 void EditorPlayerMenu::clicked_add_player() {
 	Widelands::Map& map = eia().egbase().map();
 	Widelands::PlayerNumber const nr_players = map.get_nrplayers() + 1;
-	assert(nr_players <= MAX_PLAYERS);
+	assert(nr_players <= kMaxPlayers);
 	map.set_nrplayers(nr_players);
 	{                             //  register new default name for this players
 		assert(nr_players <= 99);  //  2 decimal digits
@@ -228,7 +209,7 @@
 	}
 	map.set_scenario_player_tribe(nr_players, tribenames_[0]);
 	eia().set_need_save(true);
-	add_player_.set_enabled(nr_players < MAX_PLAYERS);
+	add_player_.set_enabled(nr_players < kMaxPlayers);
 	remove_last_player_.set_enabled(true);
 	update();
 }
@@ -243,7 +224,9 @@
 	if (!menu.is_player_tribe_referenced(old_nr_players)) {
 		if (const Widelands::Coords sp = map.get_starting_pos(old_nr_players)) {
 			//  Remove starting position marker.
-			const Image* player_image = g_gr->images().get(player_pictures[old_nr_players - 1]);
+			const Image* player_image = playercolor_image(
+			   old_nr_players - 1, g_gr->images().get("images/players/player_position.png"),
+			   g_gr->images().get("images/players/player_position_pc.png"));
 			assert(player_image);
 			menu.mutable_field_overlay_manager()->remove_overlay(sp, player_image);
 		}
@@ -252,7 +235,7 @@
 			set_starting_pos_clicked(nr_players);
 	}
 	map.set_nrplayers(nr_players);
-	add_player_.set_enabled(nr_players < MAX_PLAYERS);
+	add_player_.set_enabled(nr_players < kMaxPlayers);
 	remove_last_player_.set_enabled(1 < nr_players);
 
 	update();
@@ -375,7 +358,9 @@
 
 		// Remove the player overlay from this starting pos.
 		// A HQ is overlay enough
-		const Image* player_image = g_gr->images().get(player_pictures[n - 1]);
+		const Image* player_image =
+		   playercolor_image(n - 1, g_gr->images().get("images/players/player_position.png"),
+		                     g_gr->images().get("images/players/player_position_pc.png"));
 		assert(player_image);
 		overlay_manager->remove_overlay(start_pos, player_image);
 	}

=== modified file 'src/editor/ui_menus/player_menu.h'
--- src/editor/ui_menus/player_menu.h	2016-09-10 16:50:51 +0000
+++ src/editor/ui_menus/player_menu.h	2016-10-22 07:40:34 +0000
@@ -25,7 +25,7 @@
 #include <string>
 #include <vector>
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/widelands.h"
 #include "ui_basic/button.h"
 #include "ui_basic/unique_window.h"
@@ -47,15 +47,15 @@
 	EditorInteractive& eia();
 	UI::UniqueWindow::Registry allow_buildings_menu_;
 	UI::Textarea* nr_of_players_ta_;
-	UI::EditBox* plr_names_[MAX_PLAYERS];
+	UI::EditBox* plr_names_[kMaxPlayers];
 	UI::Button add_player_, remove_last_player_;
-	UI::Button* plr_make_infrastructure_buts_[MAX_PLAYERS], *plr_set_pos_buts_[MAX_PLAYERS],
-	   *plr_set_tribes_buts_[MAX_PLAYERS];
+	UI::Button* plr_make_infrastructure_buts_[kMaxPlayers], *plr_set_pos_buts_[kMaxPlayers],
+	   *plr_set_tribes_buts_[kMaxPlayers];
 
 	std::vector<std::string> tribenames_;
 
 	/// List of the tribes currently selected for all players
-	std::string selected_tribes_[MAX_PLAYERS];
+	std::string selected_tribes_[kMaxPlayers];
 
 	int32_t posy_;
 

=== modified file 'src/game_io/game_player_info_packet.cc'
--- src/game_io/game_player_info_packet.cc	2016-08-04 15:49:05 +0000
+++ src/game_io/game_player_info_packet.cc	2016-10-22 07:40:34 +0000
@@ -21,7 +21,6 @@
 
 #include "io/fileread.h"
 #include "io/filewrite.h"
-#include "logic/constants.h"
 #include "logic/game.h"
 #include "logic/game_data_error.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
@@ -46,9 +45,9 @@
 					bool const see_all = fr.unsigned_8();
 
 					int32_t const plnum = fr.unsigned_8();
-					if (plnum < 1 || MAX_PLAYERS < plnum)
+					if (plnum < 1 || kMaxPlayers < plnum)
 						throw GameDataError(
-						   "player number (%i) is out of range (1 .. %u)", plnum, MAX_PLAYERS);
+						   "player number (%i) is out of range (1 .. %u)", plnum, kMaxPlayers);
 
 					Widelands::TeamNumber team = fr.unsigned_8();
 					char const* const tribe_name = fr.c_string();

=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt	2016-02-19 19:10:44 +0000
+++ src/graphic/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -22,6 +22,15 @@
   USES_SDL2
 )
 
+wl_library(graphic_playercolor
+  SRCS
+    playercolor.cc
+    playercolor.h
+  DEPENDS
+    graphic_color
+    graphic_surface
+)
+
 wl_library(graphic_render_queue
   SRCS
     render_queue.cc
@@ -255,6 +264,7 @@
     graphic_gl_utils
     graphic_image_cache
     graphic_image_io
+    graphic_playercolor
     graphic_render_queue
     graphic_surface
     graphic_text

=== modified file 'src/graphic/animation.cc'
--- src/graphic/animation.cc	2016-08-04 15:49:05 +0000
+++ src/graphic/animation.cc	2016-10-22 07:40:34 +0000
@@ -34,6 +34,7 @@
 #include "graphic/graphic.h"
 #include "graphic/image.h"
 #include "graphic/image_cache.h"
+#include "graphic/playercolor.h"
 #include "graphic/surface.h"
 #include "graphic/texture.h"
 #include "io/filesystem/layered_filesystem.h"
@@ -213,21 +214,18 @@
 
 Image* NonPackedAnimation::representative_image(const RGBColor* clr) const {
 	assert(!image_files_.empty());
-
 	const Image* image = g_gr->images().get(image_files_[0]);
-	int w = image->width();
-	int h = image->height();
 
-	Texture* rv = new Texture(w, h);
 	if (!hasplrclrs_ || clr == nullptr) {
 		// No player color means we simply want an exact copy of the original image.
+		const int w = image->width();
+		const int h = image->height();
+		Texture* rv = new Texture(w, h);
 		rv->blit(Rect(Point(0, 0), w, h), *image, Rect(Point(0, 0), w, h), 1., BlendMode::Copy);
+		return rv;
 	} else {
-		rv->fill_rect(Rect(Point(0, 0), w, h), RGBAColor(0, 0, 0, 0));
-		rv->blit_blended(Rect(Point(0, 0), w, h), *image,
-		                 *g_gr->images().get(pc_mask_image_files_[0]), Rect(Point(0, 0), w, h), *clr);
+		return playercolor_image(clr, image, g_gr->images().get(pc_mask_image_files_[0]));
 	}
-	return rv;
 }
 
 const std::string& NonPackedAnimation::representative_image_filename() const {

=== added file 'src/graphic/playercolor.cc'
--- src/graphic/playercolor.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/playercolor.cc	2016-10-22 07:40:34 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "graphic/playercolor.h"
+
+#include "graphic/texture.h"
+
+Image* playercolor_image(const RGBColor* clr, const Image* image, const Image* color_mask) {
+	int w = image->width();
+	int h = image->height();
+	Texture* rv = new Texture(w, h);
+	rv->fill_rect(Rect(Point(0, 0), w, h), RGBAColor(0, 0, 0, 0));
+	rv->blit_blended(Rect(Point(0, 0), w, h), *image, *color_mask, Rect(Point(0, 0), w, h), *clr);
+	return rv;
+}
+
+Image* playercolor_image(int player_number, const Image* image, const Image* color_mask) {
+	return playercolor_image(&kPlayerColors[player_number], image, color_mask);
+}

=== added file 'src/graphic/playercolor.h'
--- src/graphic/playercolor.h	1970-01-01 00:00:00 +0000
+++ src/graphic/playercolor.h	2016-10-22 07:40:34 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef WL_LOGIC_PLAYER_COLOR_H
+#define WL_LOGIC_PLAYER_COLOR_H
+
+#include "graphic/color.h"
+#include "graphic/image.h"
+
+/// Maximum numbers of players in a game. The game logic code reserves 5 bits
+/// for player numbers, so it can keep track of 32 different player numbers, of
+/// which the value 0 means neutral and the values 1 .. 31 can be used as the
+/// numbers for actual players. So the upper limit of this value is 31.
+constexpr uint8_t kMaxPlayers = 16;
+
+// Hard coded player colors
+const RGBColor kPlayerColors[kMaxPlayers] = {
+   RGBColor(2, 2, 198),      // blue
+   RGBColor(255, 41, 0),     // red
+   RGBColor(255, 232, 0),    // yellow
+   RGBColor(59, 223, 3),     // green
+   RGBColor(57, 57, 57),     // black/dark gray
+   RGBColor(255, 172, 0),    // orange
+   RGBColor(215, 0, 218),    // purple
+   RGBColor(255, 255, 255),  // white
+   RGBColor(0, 120, 255),    // sky blue
+   RGBColor(104, 0, 40),     // dark red
+   RGBColor(120, 108, 0),    // dark yellow
+   RGBColor(0, 112, 0),      // dark green
+   RGBColor(255, 120, 160),  // rose
+   RGBColor(148, 56, 0),     // brown
+   RGBColor(96, 0, 84),      // dark purple
+   RGBColor(144, 144, 144),  // light gray
+};
+
+Image* playercolor_image(const RGBColor* clr, const Image* image, const Image* color_mask);
+Image* playercolor_image(int player_number, const Image* image, const Image* color_mask);
+
+#endif  // end of include guard: WL_LOGIC_PLAYER_COLOR_H

=== modified file 'src/logic/CMakeLists.txt'
--- src/logic/CMakeLists.txt	2016-05-14 07:35:39 +0000
+++ src/logic/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -44,6 +44,11 @@
     profile
 )
 
+wl_library(logic_constants
+  SRCS
+    constants.h
+)
+
 wl_library(logic
   SRCS
     backtrace.cc
@@ -60,7 +65,6 @@
     cmd_luascript.h
     cmd_queue.cc
     cmd_queue.h
-    constants.h
     cookie_priority_queue.h
     description_maintainer.h
     editor_game_base.cc
@@ -219,12 +223,14 @@
     graphic
     graphic_color
     graphic_image_io
+    graphic_playercolor
     graphic_surface
     graphic_text_layout
     helper
     io_fileread
     io_filesystem
     io_stream
+    logic_constants
     logic_game_controller
     logic_game_settings
     logic_widelands_geometry

=== modified file 'src/logic/constants.h'
--- src/logic/constants.h	2016-05-19 07:51:43 +0000
+++ src/logic/constants.h	2016-10-22 07:40:34 +0000
@@ -22,12 +22,6 @@
 
 #include <cstdint>
 
-/// Maximum numbers of players in a game. The game logic code reserves 5 bits
-/// for player numbers, so it can keep track of 32 different player numbers, of
-/// which the value 0 means neutral and the values 1 .. 31 can be used as the
-/// numbers for actual players. So the upper limit of this value is 31.
-#define MAX_PLAYERS 8
-
 /// How often are statistics to be sampled.
 constexpr uint32_t kStatisticsSampleTime = 30000;
 

=== modified file 'src/logic/editor_game_base.cc'
--- src/logic/editor_game_base.cc	2016-08-04 15:49:05 +0000
+++ src/logic/editor_game_base.cc	2016-10-22 07:40:34 +0000
@@ -31,7 +31,6 @@
 #include "economy/road.h"
 #include "graphic/color.h"
 #include "graphic/graphic.h"
-#include "logic/constants.h"
 #include "logic/findimmovable.h"
 #include "logic/game.h"
 #include "logic/game_data_error.h"
@@ -174,7 +173,7 @@
 
 void EditorGameBase::inform_players_about_ownership(MapIndex const i,
                                                     PlayerNumber const new_owner) {
-	iterate_players_existing_const(plnum, MAX_PLAYERS, *this, p) {
+	iterate_players_existing_const(plnum, kMaxPlayers, *this, p) {
 		Player::Field& player_field = p->fields_[i];
 		if (1 < player_field.vision) {
 			player_field.owner = new_owner;
@@ -184,7 +183,7 @@
 void EditorGameBase::inform_players_about_immovable(MapIndex const i,
                                                     MapObjectDescr const* const descr) {
 	if (!Road::is_road_descr(descr))
-		iterate_players_existing_const(plnum, MAX_PLAYERS, *this, p) {
+		iterate_players_existing_const(plnum, kMaxPlayers, *this, p) {
 			Player::Field& player_field = p->fields_[i];
 			if (1 < player_field.vision) {
 				player_field.map_object_descr[TCoords<>::None] = descr;
@@ -206,7 +205,7 @@
 }
 
 void EditorGameBase::allocate_player_maps() {
-	iterate_players_existing(plnum, MAX_PLAYERS, *this, p) {
+	iterate_players_existing(plnum, kMaxPlayers, *this, p) {
 		p->allocate_map();
 	}
 }
@@ -483,7 +482,7 @@
 	uint8_t const road = f.field->get_roads() & mask;
 	MapIndex const i = f.field - &first_field;
 	MapIndex const neighbour_i = neighbour.field - &first_field;
-	iterate_players_existing_const(plnum, MAX_PLAYERS, *this, p) {
+	iterate_players_existing_const(plnum, kMaxPlayers, *this, p) {
 		Player::Field& first_player_field = *p->fields_;
 		Player::Field& player_field = (&first_player_field)[i];
 		if (1 < player_field.vision || 1 < (&first_player_field)[neighbour_i].vision) {

=== modified file 'src/logic/field.h'
--- src/logic/field.h	2016-08-04 15:49:05 +0000
+++ src/logic/field.h	2016-10-22 07:40:34 +0000
@@ -23,7 +23,7 @@
 #include <cassert>
 #include <limits>
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/nodecaps.h"
 #include "logic/roadtype.h"
 #include "logic/widelands.h"
@@ -145,12 +145,12 @@
 	 * be done separately.
 	 */
 	void set_owned_by(const PlayerNumber n) {
-		assert(n <= MAX_PLAYERS);
+		assert(n <= kMaxPlayers);
 		owner_info_and_selections = n | (owner_info_and_selections & ~Player_Number_Bitmask);
 	}
 
 	PlayerNumber get_owned_by() const {
-		assert((owner_info_and_selections & Player_Number_Bitmask) <= MAX_PLAYERS);
+		assert((owner_info_and_selections & Player_Number_Bitmask) <= kMaxPlayers);
 		return owner_info_and_selections & Player_Number_Bitmask;
 	}
 	bool is_border() const {
@@ -229,7 +229,7 @@
 	static const OwnerInfoAndSelectionsType Player_Number_Bitmask = Border_Bitmask - 1;
 	static const OwnerInfoAndSelectionsType Owner_Info_Bitmask =
 	   Player_Number_Bitmask + Border_Bitmask;
-	static_assert(MAX_PLAYERS <= Player_Number_Bitmask, "Bitmask is too big.");
+	static_assert(kMaxPlayers <= Player_Number_Bitmask, "Bitmask is too big.");
 
 	// Data Members
 	/** linked list, \sa Bob::linknext_ */

=== modified file 'src/logic/map_objects/immovable.cc'
--- src/logic/map_objects/immovable.cc	2016-08-04 15:49:05 +0000
+++ src/logic/map_objects/immovable.cc	2016-10-22 07:40:34 +0000
@@ -35,7 +35,6 @@
 #include "helper.h"
 #include "io/fileread.h"
 #include "io/filewrite.h"
-#include "logic/constants.h"
 #include "logic/editor_game_base.h"
 #include "logic/field.h"
 #include "logic/game.h"
@@ -527,7 +526,7 @@
 
 	if (packet_version >= 5) {
 		PlayerNumber pn = fr.unsigned_8();
-		if (pn && pn <= MAX_PLAYERS) {
+		if (pn && pn <= kMaxPlayers) {
 			Player* plr = egbase().get_player(pn);
 			if (!plr)
 				throw GameDataError("Immovable::load: player %u does not exist", pn);

=== modified file 'src/logic/player.cc'
--- src/logic/player.cc	2016-08-04 15:49:05 +0000
+++ src/logic/player.cc	2016-10-22 07:40:34 +0000
@@ -36,7 +36,6 @@
 #include "io/filewrite.h"
 #include "logic/cmd_delete_message.h"
 #include "logic/cmd_luacoroutine.h"
-#include "logic/constants.h"
 #include "logic/findimmovable.h"
 #include "logic/game.h"
 #include "logic/game_data_error.h"
@@ -88,17 +87,6 @@
 
 namespace Widelands {
 
-const RGBColor Player::Colors[MAX_PLAYERS] = {
-   RGBColor(2, 2, 198),      // blue
-   RGBColor(255, 41, 0),     // red
-   RGBColor(255, 232, 0),    // yellow
-   RGBColor(59, 223, 3),     // green
-   RGBColor(57, 57, 57),     // black/dark gray
-   RGBColor(255, 172, 0),    // orange
-   RGBColor(215, 0, 218),    // purple
-   RGBColor(255, 255, 255),  // white
-};
-
 /**
  * Find the longest possible enhancement chain leading to the given
  * building descr. The FormerBuildings given in reference must be empty and will be
@@ -272,7 +260,7 @@
 	if (!team_number_)
 		return;
 
-	for (PlayerNumber i = 1; i <= MAX_PLAYERS; ++i) {
+	for (PlayerNumber i = 1; i <= kMaxPlayers; ++i) {
 		Player* other = egbase().get_player(i);
 		if (!other)
 			continue;

=== modified file 'src/logic/player.h'
--- src/logic/player.h	2016-08-04 15:49:05 +0000
+++ src/logic/player.h	2016-10-22 07:40:34 +0000
@@ -25,7 +25,7 @@
 
 #include "base/macros.h"
 #include "graphic/color.h"
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/editor_game_base.h"
 #include "logic/map_objects/tribes/building.h"
 #include "logic/map_objects/tribes/constructionsite.h"
@@ -64,9 +64,6 @@
  */
 class Player {
 public:
-	// hard-coded playercolors
-	static const RGBColor Colors[MAX_PLAYERS];
-
 	struct BuildingStats {
 		bool is_constructionsite;
 		Coords pos;
@@ -130,7 +127,7 @@
 		return team_number_;
 	}
 	const RGBColor& get_playercolor() const {
-		return Colors[player_number_ - 1];
+		return kPlayerColors[player_number_ - 1];
 	}
 	const TribeDescr& tribe() const {
 		return tribe_;

=== modified file 'src/logic/playersmanager.cc'
--- src/logic/playersmanager.cc	2016-08-04 15:49:05 +0000
+++ src/logic/playersmanager.cc	2016-10-22 07:40:34 +0000
@@ -22,7 +22,6 @@
 #include <cstring>
 
 #include "base/wexception.h"
-#include "logic/constants.h"
 #include "logic/editor_game_base.h"
 #include "logic/game_settings.h"
 #include "logic/player.h"
@@ -39,7 +38,7 @@
 }
 
 void PlayersManager::cleanup() {
-	const Player* const* const players_end = players_ + MAX_PLAYERS;
+	const Player* const* const players_end = players_ + kMaxPlayers;
 	for (Player** p = players_; p < players_end; ++p) {
 		delete *p;
 		*p = nullptr;
@@ -49,7 +48,7 @@
 
 void PlayersManager::remove_player(PlayerNumber plnum) {
 	assert(1 <= plnum);
-	assert(plnum <= MAX_PLAYERS);
+	assert(plnum <= kMaxPlayers);
 
 	Player*& p = players_[plnum - 1];
 	if (p) {
@@ -67,7 +66,7 @@
                                    const std::string& name,
                                    TeamNumber team) {
 	assert(1 <= player_number);
-	assert(player_number <= MAX_PLAYERS);
+	assert(player_number <= kMaxPlayers);
 
 	Player*& p = players_[player_number - 1];
 	if (p) {

=== modified file 'src/logic/playersmanager.h'
--- src/logic/playersmanager.h	2016-08-04 15:49:05 +0000
+++ src/logic/playersmanager.h	2016-10-22 07:40:34 +0000
@@ -23,7 +23,7 @@
 #include <string>
 #include <vector>
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/widelands.h"
 
 namespace Widelands {
@@ -76,12 +76,12 @@
 	                   TeamNumber team = 0);
 	Player* get_player(int32_t n) const {
 		assert(1 <= n);
-		assert(n <= MAX_PLAYERS);
+		assert(n <= kMaxPlayers);
 		return players_[n - 1];
 	}
 	Player& player(int32_t n) const {
 		assert(1 <= n);
-		assert(n <= MAX_PLAYERS);
+		assert(n <= kMaxPlayers);
 		return *players_[n - 1];
 	}
 
@@ -107,7 +107,7 @@
 	void set_player_end_status(const PlayerEndStatus& status);
 
 private:
-	Player* players_[MAX_PLAYERS];
+	Player* players_[kMaxPlayers];
 	EditorGameBase& egbase_;
 	uint8_t number_of_players_;
 	std::vector<PlayerEndStatus> players_end_status_;

=== modified file 'src/logic/widelands.h'
--- src/logic/widelands.h	2016-08-04 15:49:05 +0000
+++ src/logic/widelands.h	2016-10-22 07:40:34 +0000
@@ -33,7 +33,9 @@
 //  Type definitions for the game logic.
 using MilitaryInfluence = uint16_t;
 
-using PlayerNumber = uint8_t;  /// 5 bits used, so 0 .. 31
+/// 5 bits used, so 0 .. 31
+/// Data type must match kMaxPlayers in graphics/playercolor.h
+using PlayerNumber = uint8_t;
 inline PlayerNumber neutral() {
 	return 0;
 }

=== modified file 'src/map_io/CMakeLists.txt'
--- src/map_io/CMakeLists.txt	2016-02-20 11:29:55 +0000
+++ src/map_io/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -96,6 +96,7 @@
     graphic
     graphic_image_io
     graphic_minimap_renderer
+    graphic_playercolor
     graphic_surface
     helper
     io_fileread

=== modified file 'src/map_io/map_elemental_packet.cc'
--- src/map_io/map_elemental_packet.cc	2016-08-04 15:49:05 +0000
+++ src/map_io/map_elemental_packet.cc	2016-10-22 07:40:34 +0000
@@ -85,7 +85,7 @@
 
 					for (const std::string& player : players_string) {
 						PlayerNumber player_number = static_cast<PlayerNumber>(atoi(player.c_str()));
-						assert(player_number < MAX_PLAYERS);
+						assert(player_number < kMaxPlayers);
 						team.push_back(player_number);
 					}
 

=== modified file 'src/map_io/map_exploration_packet.cc'
--- src/map_io/map_exploration_packet.cc	2016-08-04 15:49:05 +0000
+++ src/map_io/map_exploration_packet.cc	2016-10-22 07:40:34 +0000
@@ -22,7 +22,6 @@
 #include "base/log.h"
 #include "io/fileread.h"
 #include "io/filewrite.h"
-#include "logic/constants.h"
 #include "logic/editor_game_base.h"
 #include "logic/game_data_error.h"
 #include "logic/map.h"
@@ -50,7 +49,7 @@
 		}
 	}
 
-	static_assert(MAX_PLAYERS < 32, "assert(MAX_PLAYERS < 32) failed.");
+	static_assert(kMaxPlayers < 32, "assert(MAX_PLAYERS < 32) failed.");
 	Map& map = egbase.map();
 	PlayerNumber const nr_players = map.get_nrplayers();
 	MapIndex const max_index = map.max_index();
@@ -82,7 +81,7 @@
 
 	fw.unsigned_16(kCurrentPacketVersion);
 
-	static_assert(MAX_PLAYERS < 32, "assert(MAX_PLAYERS < 32) failed.");
+	static_assert(kMaxPlayers < 32, "assert(MAX_PLAYERS < 32) failed.");
 	Map& map = egbase.map();
 	PlayerNumber const nr_players = map.get_nrplayers();
 	MapIndex const max_index = map.max_index();

=== modified file 'src/map_io/map_object_saver.h'
--- src/map_io/map_object_saver.h	2016-08-04 15:49:05 +0000
+++ src/map_io/map_object_saver.h	2016-10-22 07:40:34 +0000
@@ -23,7 +23,7 @@
 #include <map>
 #include <string>
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/widelands.h"
 #include "map_io/map_message_saver.h"
 
@@ -76,7 +76,7 @@
 	bool is_object_saved(const MapObject&);
 
 	/// \note Indexed by player number - 1.
-	MapMessageSaver message_savers[MAX_PLAYERS];
+	MapMessageSaver message_savers[kMaxPlayers];
 
 private:
 	struct MapObjectRec {

=== modified file 'src/network/CMakeLists.txt'
--- src/network/CMakeLists.txt	2016-02-06 11:11:24 +0000
+++ src/network/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -31,6 +31,7 @@
     build_info
     chat
     game_io
+    graphic_playercolor
     helper
     io_fileread
     io_filesystem

=== modified file 'src/network/network_player_settings_backend.h'
--- src/network/network_player_settings_backend.h	2016-08-04 15:49:05 +0000
+++ src/network/network_player_settings_backend.h	2016-10-22 07:40:34 +0000
@@ -20,13 +20,13 @@
 #ifndef WL_NETWORK_NETWORK_PLAYER_SETTINGS_BACKEND_H
 #define WL_NETWORK_NETWORK_PLAYER_SETTINGS_BACKEND_H
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "logic/game_settings.h"
 
 struct NetworkPlayerSettingsBackend {
 
 	NetworkPlayerSettingsBackend(GameSettingsProvider* const settings) : s(settings) {
-		for (uint8_t i = 0; i < MAX_PLAYERS; ++i)
+		for (uint8_t i = 0; i < kMaxPlayers; ++i)
 			shared_in_tribe[i] = std::string();
 	}
 
@@ -37,7 +37,7 @@
 	void refresh(uint8_t id);
 
 	GameSettingsProvider* const s;
-	std::string shared_in_tribe[MAX_PLAYERS];
+	std::string shared_in_tribe[kMaxPlayers];
 };
 
 #endif  // end of include guard: WL_NETWORK_NETWORK_PLAYER_SETTINGS_BACKEND_H

=== modified file 'src/scripting/lua_bases.cc'
--- src/scripting/lua_bases.cc	2016-08-04 15:49:05 +0000
+++ src/scripting/lua_bases.cc	2016-10-22 07:40:34 +0000
@@ -22,7 +22,6 @@
 #include <boost/format.hpp>
 
 #include "economy/economy.h"
-#include "logic/constants.h"
 #include "logic/map_objects/checkstep.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
 #include "logic/map_objects/tribes/tribes.h"
@@ -132,7 +131,7 @@
 	lua_newtable(L);
 
 	uint32_t idx = 1;
-	for (PlayerNumber i = 1; i <= MAX_PLAYERS; i++) {
+	for (PlayerNumber i = 1; i <= kMaxPlayers; i++) {
 		Player* rv = egbase.get_player(i);
 		if (!rv)
 			continue;
@@ -695,7 +694,7 @@
  ==========================================================
  */
 Player& LuaPlayerBase::get(lua_State* L, Widelands::EditorGameBase& egbase) {
-	if (player_number_ > MAX_PLAYERS)
+	if (player_number_ > kMaxPlayers)
 		report_error(L, "Illegal player number %i", player_number_);
 	Player* rv = egbase.get_player(player_number_);
 	if (!rv)

=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc	2016-08-07 20:39:44 +0000
+++ src/scripting/lua_game.cc	2016-10-22 07:40:34 +0000
@@ -26,7 +26,6 @@
 #include "economy/economy.h"
 #include "economy/flag.h"
 #include "logic/campaign_visibility.h"
-#include "logic/constants.h"
 #include "logic/game_controller.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
 #include "logic/message.h"
@@ -1250,7 +1249,7 @@
  ==========================================================
  */
 Player& LuaMessage::get_plr(lua_State* L, Widelands::Game& game) {
-	if (player_number_ > MAX_PLAYERS)
+	if (player_number_ > kMaxPlayers)
 		report_error(L, "Illegal player number %i", player_number_);
 	Player* rv = game.get_player(player_number_);
 	if (!rv)

=== modified file 'src/ui_fsmenu/CMakeLists.txt'
--- src/ui_fsmenu/CMakeLists.txt	2016-03-10 12:57:08 +0000
+++ src/ui_fsmenu/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -44,6 +44,7 @@
     game_io
     graphic
     graphic_image_io
+    graphic_playercolor
     graphic_surface
     graphic_text
     graphic_text_layout

=== modified file 'src/ui_fsmenu/launch_mpg.cc'
--- src/ui_fsmenu/launch_mpg.cc	2016-08-04 15:49:05 +0000
+++ src/ui_fsmenu/launch_mpg.cc	2016-10-22 07:40:34 +0000
@@ -26,9 +26,9 @@
 #include "base/i18n.h"
 #include "base/warning.h"
 #include "graphic/graphic.h"
+#include "graphic/playercolor.h"
 #include "graphic/text_constants.h"
 #include "io/filesystem/layered_filesystem.h"
-#include "logic/constants.h"
 #include "logic/game.h"
 #include "logic/game_controller.h"
 #include "logic/game_settings.h"
@@ -227,7 +227,7 @@
 	map_info_.set_text(_("The host has not yet selected a map or saved game."));
 
 	mpsg_ = new MultiPlayerSetupGroup(
-	   this, get_w() / 50, get_h() / 8, get_w() * 57 / 80, get_h() / 2, settings, butw_, buth_);
+	   this, get_w() / 50, get_h() / 8, get_w() * 57 / 80, get_h(), settings, butw_, buth_);
 
 	// If we are the host, open the map or save selection menu at startup
 	if (settings_->settings().usernum == 0 && settings_->settings().mapname.empty()) {
@@ -494,7 +494,7 @@
 	} else {
 		// Write client infos
 		std::string client_info =
-		   (settings.playernum >= 0) && (settings.playernum < MAX_PLAYERS) ?
+		   (settings.playernum >= 0) && (settings.playernum < kMaxPlayers) ?
 		      (boost::format(_("You are Player %i.")) % (settings.playernum + 1)).str() :
 		      _("You are a spectator.");
 		client_info_.set_text(client_info);
@@ -551,9 +551,9 @@
 	Profile prof;
 	prof.read("map/player_names", nullptr, *l_fs);
 	std::string infotext = _("Saved players are:");
-	std::string player_save_name[MAX_PLAYERS];
-	std::string player_save_tribe[MAX_PLAYERS];
-	std::string player_save_ai[MAX_PLAYERS];
+	std::string player_save_name[kMaxPlayers];
+	std::string player_save_tribe[kMaxPlayers];
+	std::string player_save_ai[kMaxPlayers];
 
 	uint8_t i = 1;
 	for (; i <= nr_players_; ++i) {

=== modified file 'src/ui_fsmenu/launch_spg.cc'
--- src/ui_fsmenu/launch_spg.cc	2016-08-27 10:15:32 +0000
+++ src/ui_fsmenu/launch_spg.cc	2016-10-22 07:40:34 +0000
@@ -30,7 +30,6 @@
 #include "graphic/text_constants.h"
 #include "helper.h"
 #include "io/filesystem/layered_filesystem.h"
-#include "logic/constants.h"
 #include "logic/game.h"
 #include "logic/game_controller.h"
 #include "logic/game_settings.h"
@@ -44,18 +43,6 @@
 #include "ui_fsmenu/mapselect.h"
 #include "wui/playerdescrgroup.h"
 
-namespace {
-static char const* const player_pictures_small[] = {
-   "images/players/fsel_editor_set_player_01_pos.png",
-   "images/players/fsel_editor_set_player_02_pos.png",
-   "images/players/fsel_editor_set_player_03_pos.png",
-   "images/players/fsel_editor_set_player_04_pos.png",
-   "images/players/fsel_editor_set_player_05_pos.png",
-   "images/players/fsel_editor_set_player_06_pos.png",
-   "images/players/fsel_editor_set_player_07_pos.png",
-   "images/players/fsel_editor_set_player_08_pos.png"};
-}  // namespace
-
 FullscreenMenuLaunchSPG::FullscreenMenuLaunchSPG(GameSettingsProvider* const settings,
                                                  GameController* const ctrl,
                                                  bool /* autolaunch */)
@@ -172,8 +159,10 @@
 	init_.set_fontsize(smaller_fontsize);
 
 	uint32_t y = get_h() * 3 / 10 - buth_;
-	for (uint32_t i = 0; i < MAX_PLAYERS; ++i) {
-		const Image* player_image = g_gr->images().get(player_pictures_small[i]);
+	for (uint32_t i = 0; i < kMaxPlayers; ++i) {
+		const Image* player_image =
+		   playercolor_image(i, g_gr->images().get("images/players/player_position_menu.png"),
+		                     g_gr->images().get("images/players/player_position_menu_pc.png"));
 		assert(player_image);
 
 		pos_[i] =
@@ -346,11 +335,11 @@
 		pos_[i]->set_enabled(!is_scenario_ && (player.state == PlayerSettings::stateOpen ||
 		                                       player.state == PlayerSettings::stateComputer));
 	}
-	for (uint32_t i = nr_players_; i < MAX_PLAYERS; ++i)
+	for (uint32_t i = nr_players_; i < kMaxPlayers; ++i)
 		pos_[i]->set_visible(false);
 
 	// update the player description groups
-	for (uint32_t i = 0; i < MAX_PLAYERS; ++i)
+	for (uint32_t i = 0; i < kMaxPlayers; ++i)
 		players_[i]->refresh();
 
 	win_condition_update();

=== modified file 'src/ui_fsmenu/launch_spg.h'
--- src/ui_fsmenu/launch_spg.h	2016-08-04 15:49:05 +0000
+++ src/ui_fsmenu/launch_spg.h	2016-10-22 07:40:34 +0000
@@ -22,7 +22,7 @@
 
 #include <string>
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "ui_basic/button.h"
 #include "ui_basic/multilinetextarea.h"
 #include "ui_basic/textarea.h"
@@ -75,16 +75,16 @@
 	uint32_t buth_;
 
 	UI::Button select_map_, wincondition_, back_, ok_;
-	UI::Button* pos_[MAX_PLAYERS];
+	UI::Button* pos_[kMaxPlayers];
 	UI::Textarea title_, mapname_;
 	UI::Textarea name_, type_, team_, tribe_, init_, wincondition_type_;
 	GameSettingsProvider* settings_;
 	GameController* ctrl_;  // optional
-	PlayerDescriptionGroup* players_[MAX_PLAYERS];
+	PlayerDescriptionGroup* players_[kMaxPlayers];
 	std::string filename_;
 	std::string filename_proof_;  // local var. to check UI state
-	std::string player_save_name_[MAX_PLAYERS];
-	std::string player_save_tribe_[MAX_PLAYERS];
+	std::string player_save_name_[kMaxPlayers];
+	std::string player_save_tribe_[kMaxPlayers];
 	int8_t nr_players_;
 	bool is_scenario_;
 	std::vector<std::string> win_condition_scripts_;

=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt	2016-04-15 17:23:00 +0000
+++ src/wui/CMakeLists.txt	2016-10-22 07:40:34 +0000
@@ -15,6 +15,7 @@
     chat
     graphic
     graphic_color
+    graphic_playercolor
     graphic_text
     graphic_text_layout
     logic
@@ -72,6 +73,7 @@
     base_i18n
     base_log
     graphic
+    graphic_playercolor
     graphic_text_layout
     io_filesystem
     logic
@@ -193,6 +195,7 @@
     graphic_color
     graphic_game_renderer
     graphic_minimap_renderer
+    graphic_playercolor
     graphic_surface
     graphic_text
     graphic_text_layout

=== modified file 'src/wui/chat_msg_layout.cc'
--- src/wui/chat_msg_layout.cc	2016-08-04 15:49:05 +0000
+++ src/wui/chat_msg_layout.cc	2016-10-22 07:40:34 +0000
@@ -24,15 +24,14 @@
 #include "chat/chat.h"
 #include "graphic/color.h"
 #include "graphic/text_layout.h"
-#include "logic/constants.h"
 #include "logic/player.h"
 
 namespace {
 
 // Returns the hexcolor for the 'player'.
 std::string color(const int16_t playern) {
-	if ((playern >= 0) && playern < MAX_PLAYERS) {
-		const RGBColor& clr = Widelands::Player::Colors[playern];
+	if ((playern >= 0) && playern < kMaxPlayers) {
+		const RGBColor& clr = kPlayerColors[playern];
 		char buf[sizeof("ffffff")];
 		snprintf(buf, sizeof(buf), "%.2x%.2x%.2x", clr.r, clr.g, clr.b);
 		return buf;

=== modified file 'src/wui/game_summary.cc'
--- src/wui/game_summary.cc	2016-08-04 15:49:05 +0000
+++ src/wui/game_summary.cc	2016-10-22 07:40:34 +0000
@@ -24,6 +24,7 @@
 
 #include "base/time_string.h"
 #include "graphic/graphic.h"
+#include "graphic/playercolor.h"
 #include "logic/game.h"
 #include "logic/player.h"
 #include "logic/playersmanager.h"
@@ -36,14 +37,6 @@
 #include "wui/interactive_gamebase.h"
 #include "wui/interactive_player.h"
 
-namespace {
-static char const* const flag_pictures[] = {
-   "images/players/genstats_enable_plr_01.png", "images/players/genstats_enable_plr_02.png",
-   "images/players/genstats_enable_plr_03.png", "images/players/genstats_enable_plr_04.png",
-   "images/players/genstats_enable_plr_05.png", "images/players/genstats_enable_plr_06.png",
-   "images/players/genstats_enable_plr_07.png", "images/players/genstats_enable_plr_08.png"};
-}  // namespace
-
 #define PADDING 4
 
 GameSummaryScreen::GameSummaryScreen(InteractiveGameBase* parent, UI::UniqueWindow::Registry* r)
@@ -153,7 +146,9 @@
 		Widelands::Player* p = game_.get_player(pes.player);
 		UI::Table<uintptr_t const>::EntryRecord& te = players_table_->add(i);
 		// Player name & pic
-		const Image* player_image = g_gr->images().get(flag_pictures[pes.player - 1]);
+		const Image* player_image =
+		   playercolor_image(pes.player - 1, g_gr->images().get("images/players/genstats_player.png"),
+		                     g_gr->images().get("images/players/genstats_player_pc.png"));
 		assert(player_image);
 		te.set_picture(0, player_image, p->get_name());
 		// Team

=== modified file 'src/wui/general_statistics_menu.cc'
--- src/wui/general_statistics_menu.cc	2016-08-04 15:49:05 +0000
+++ src/wui/general_statistics_menu.cc	2016-10-22 07:40:34 +0000
@@ -41,14 +41,6 @@
 #include "ui_basic/textarea.h"
 #include "wui/interactive_player.h"
 
-namespace {
-static char const* const flag_pictures[] = {
-   "images/players/genstats_enable_plr_01.png", "images/players/genstats_enable_plr_02.png",
-   "images/players/genstats_enable_plr_03.png", "images/players/genstats_enable_plr_04.png",
-   "images/players/genstats_enable_plr_05.png", "images/players/genstats_enable_plr_06.png",
-   "images/players/genstats_enable_plr_07.png", "images/players/genstats_enable_plr_08.png"};
-}  // namespace
-
 using namespace Widelands;
 
 #define PLOT_HEIGHT 130
@@ -85,7 +77,7 @@
 	}
 
 	for (Game::GeneralStatsVector::size_type i = 0; i < general_statistics_size; ++i) {
-		const RGBColor& color = Player::Colors[i];
+		const RGBColor& color = kPlayerColors[i];
 		plot_.register_plot_data(i * ndatasets_ + 0, &genstats[i].land_size, color);
 		plot_.register_plot_data(i * ndatasets_ + 1, &genstats[i].nr_workers, color);
 		plot_.register_plot_data(i * ndatasets_ + 2, &genstats[i].nr_buildings, color);
@@ -116,7 +108,9 @@
 	iterate_players_existing_novar(p, nr_players, game)++ plr_in_game;
 
 	iterate_players_existing_const(p, nr_players, game, player) {
-		const Image* player_image = g_gr->images().get(flag_pictures[p - 1]);
+		const Image* player_image =
+		   playercolor_image(p - 1, g_gr->images().get("images/players/genstats_player.png"),
+		                     g_gr->images().get("images/players/genstats_player_pc.png"));
 		assert(player_image);
 		UI::Button& cb = *new UI::Button(hbox1, "playerbutton", 0, 0, 25, 25,
 		                                 g_gr->images().get("images/ui_basic/but4.png"), player_image,

=== modified file 'src/wui/general_statistics_menu.h'
--- src/wui/general_statistics_menu.h	2016-08-04 15:49:05 +0000
+++ src/wui/general_statistics_menu.h	2016-10-22 07:40:34 +0000
@@ -20,7 +20,7 @@
 #ifndef WL_WUI_GENERAL_STATISTICS_MENU_H
 #define WL_WUI_GENERAL_STATISTICS_MENU_H
 
-#include "logic/constants.h"
+#include "graphic/playercolor.h"
 #include "ui_basic/box.h"
 #include "ui_basic/button.h"
 #include "ui_basic/radiobutton.h"
@@ -39,7 +39,7 @@
 		Registry()
 		   : UI::UniqueWindow::Registry(),
 		     selected_information(0),
-		     selected_players(true, MAX_PLAYERS),
+		     selected_players(true, kMaxPlayers),
 		     time(WuiPlotArea::TIME_GAME) {
 		}
 
@@ -57,7 +57,7 @@
 	WuiPlotArea plot_;
 	UI::Radiogroup radiogroup_;
 	int32_t selected_information_;
-	UI::Button* cbs_[MAX_PLAYERS];
+	UI::Button* cbs_[kMaxPlayers];
 	uint32_t ndatasets_;
 
 	void clicked_help();

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2016-09-25 16:45:37 +0000
+++ src/wui/interactive_base.cc	2016-10-22 07:40:34 +0000
@@ -199,12 +199,12 @@
 /*
  * Set/Unset sel picture
  */
-void InteractiveBase::set_sel_picture(const char* const file) {
-	sel_.pic = g_gr->images().get(file);
+void InteractiveBase::set_sel_picture(const Image* image) {
+	sel_.pic = image;
 	set_sel_pos(get_sel_pos());  //  redraw
 }
 void InteractiveBase::unset_sel_picture() {
-	set_sel_picture("images/ui_basic/fsel.png");
+	set_sel_picture(g_gr->images().get("images/ui_basic/fsel.png"));
 }
 
 bool InteractiveBase::buildhelp() const {

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2016-08-04 15:49:05 +0000
+++ src/wui/interactive_base.h	2016-10-22 07:40:34 +0000
@@ -185,7 +185,7 @@
 	bool handle_key(bool down, SDL_Keysym) override;
 
 	void unset_sel_picture();
-	void set_sel_picture(const char* const);
+	void set_sel_picture(const Image* image);
 	void adjust_toolbar_position() {
 		toolbar_.set_pos(Point((get_inner_w() - toolbar_.get_w()) >> 1, get_inner_h() - 34));
 	}

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2016-08-04 15:49:05 +0000
+++ src/wui/interactive_player.cc	2016-10-22 07:40:34 +0000
@@ -31,7 +31,6 @@
 #include "economy/flag.h"
 #include "game_io/game_loader.h"
 #include "logic/cmd_queue.h"
-#include "logic/constants.h"
 #include "logic/map_objects/immovable.h"
 #include "logic/map_objects/tribes/building.h"
 #include "logic/map_objects/tribes/constructionsite.h"
@@ -364,7 +363,7 @@
 	}
 
 	int const n = atoi(args[1].c_str());
-	if (n < 1 || n > MAX_PLAYERS || !game().get_player(n)) {
+	if (n < 1 || n > kMaxPlayers || !game().get_player(n)) {
 		DebugConsole::write(str(boost::format("Player #%1% does not exist.") % n));
 		return;
 	}

=== modified file 'src/wui/multiplayersetupgroup.cc'
--- src/wui/multiplayersetupgroup.cc	2016-08-04 15:49:05 +0000
+++ src/wui/multiplayersetupgroup.cc	2016-10-22 07:40:34 +0000
@@ -28,8 +28,8 @@
 #include "base/log.h"
 #include "base/wexception.h"
 #include "graphic/graphic.h"
+#include "graphic/playercolor.h"
 #include "graphic/text_constants.h"
-#include "logic/constants.h"
 #include "logic/game.h"
 #include "logic/game_settings.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
@@ -40,23 +40,6 @@
 #include "ui_basic/scrollbar.h"
 #include "ui_basic/textarea.h"
 
-namespace {
-static char const* const flag_pictures[] = {
-   "images/players/genstats_enable_plr_01.png", "images/players/genstats_enable_plr_02.png",
-   "images/players/genstats_enable_plr_03.png", "images/players/genstats_enable_plr_04.png",
-   "images/players/genstats_enable_plr_05.png", "images/players/genstats_enable_plr_06.png",
-   "images/players/genstats_enable_plr_07.png", "images/players/genstats_enable_plr_08.png"};
-static char const* const player_pictures_small[] = {
-   "images/players/fsel_editor_set_player_01_pos.png",
-   "images/players/fsel_editor_set_player_02_pos.png",
-   "images/players/fsel_editor_set_player_03_pos.png",
-   "images/players/fsel_editor_set_player_04_pos.png",
-   "images/players/fsel_editor_set_player_05_pos.png",
-   "images/players/fsel_editor_set_player_06_pos.png",
-   "images/players/fsel_editor_set_player_07_pos.png",
-   "images/players/fsel_editor_set_player_08_pos.png"};
-}  // namespace
-
 struct MultiPlayerClientGroup : public UI::Box {
 	MultiPlayerClientGroup(UI::Panel* const parent,
 	                       uint8_t id,
@@ -118,25 +101,27 @@
 		} else {
 			name->set_text(us.name);
 			if (save_ != us.position) {
-				std::string pic;
+				const Image* position_image;
 				std::string temp_tooltip;
 				if (us.position < UserSettings::highest_playernum()) {
-					pic = flag_pictures[us.position];
+					position_image = playercolor_image(
+					   us.position, g_gr->images().get("images/players/genstats_player.png"),
+					   g_gr->images().get("images/players/genstats_player_pc.png"));
 					temp_tooltip =
 					   (boost::format(_("Player %u")) % static_cast<unsigned int>(us.position + 1))
 					      .str();
 				} else {
-					pic = "images/wui/fieldaction/menu_tab_watch.png";
+					position_image = g_gr->images().get("images/wui/fieldaction/menu_tab_watch.png");
 					temp_tooltip = _("Spectator");
 				}
 
 				// Either Button if changeable OR text if not
 				if (id_ == s->settings().usernum) {
-					type->set_pic(g_gr->images().get(pic));
+					type->set_pic(position_image);
 					type->set_tooltip(temp_tooltip);
 					type->set_visible(true);
 				} else {
-					type_icon->set_icon(g_gr->images().get(pic));
+					type_icon->set_icon(position_image);
 					type_icon->set_tooltip(temp_tooltip);
 					type_icon->set_visible(true);
 				}
@@ -175,7 +160,9 @@
 	     tribepics_(tp),
 	     tribenames_(tn) {
 		set_size(w, h);
-		const Image* player_image = g_gr->images().get(player_pictures_small[id]);
+		const Image* player_image =
+		   playercolor_image(id, g_gr->images().get("images/players/player_position_menu.png"),
+		                     g_gr->images().get("images/players/player_position_menu_pc.png"));
 		assert(player_image);
 		player = new UI::Icon(this, 0, 0, h, h, player_image);
 		add(player, UI::Align::kHCenter);
@@ -272,7 +259,9 @@
 			type->set_tooltip(_("Shared in"));
 			type->set_pic(g_gr->images().get("images/ui_fsmenu/shared_in.png"));
 			const Image* player_image =
-			   g_gr->images().get(player_pictures_small[player_setting.shared_in - 1]);
+			   playercolor_image(player_setting.shared_in - 1,
+			                     g_gr->images().get("images/players/player_position_menu.png"),
+			                     g_gr->images().get("images/players/player_position_menu_pc.png"));
 			assert(player_image);
 			tribe->set_pic(player_image);
 			tribe->set_tooltip(
@@ -426,7 +415,7 @@
 	labels.back()->set_fontsize(small_font);
 
 	playerbox.set_size(w * 9 / 15, h - buth);
-	multi_player_player_groups.resize(MAX_PLAYERS);
+	multi_player_player_groups.resize(kMaxPlayers);
 	for (uint8_t i = 0; i < multi_player_player_groups.size(); ++i) {
 		multi_player_player_groups.at(i) = new MultiPlayerPlayerGroup(
 		   &playerbox, i, 0, 0, playerbox.get_w(), buth, s, npsb.get(), tribepics_, tribenames_);
@@ -458,7 +447,7 @@
 	}
 
 	// Update player groups
-	for (uint32_t i = 0; i < MAX_PLAYERS; ++i) {
+	for (uint32_t i = 0; i < kMaxPlayers; ++i) {
 		multi_player_player_groups.at(i)->refresh();
 	}
 }

=== modified file 'src/wui/suggested_teams_box.cc'
--- src/wui/suggested_teams_box.cc	2016-08-04 15:49:05 +0000
+++ src/wui/suggested_teams_box.cc	2016-10-22 07:40:34 +0000
@@ -23,18 +23,7 @@
 #include <string>
 
 #include "graphic/graphic.h"
-
-namespace {
-static char const* const player_pictures_small[] = {
-   "images/players/fsel_editor_set_player_01_pos.png",
-   "images/players/fsel_editor_set_player_02_pos.png",
-   "images/players/fsel_editor_set_player_03_pos.png",
-   "images/players/fsel_editor_set_player_04_pos.png",
-   "images/players/fsel_editor_set_player_05_pos.png",
-   "images/players/fsel_editor_set_player_06_pos.png",
-   "images/players/fsel_editor_set_player_07_pos.png",
-   "images/players/fsel_editor_set_player_08_pos.png"};
-}  // namespace
+#include "graphic/playercolor.h"
 
 namespace UI {
 
@@ -52,10 +41,11 @@
              orientation,
              max_x,
              max_y,
-             g_gr->images().get(player_pictures_small[0])->height()),
+             g_gr->images().get("images/players/player_position_menu.png")->height()),
      padding_(padding),
      indent_(indent),
-     label_height_(g_gr->images().get(player_pictures_small[0])->height() + padding) {
+     label_height_(g_gr->images().get("images/players/player_position_menu.png")->height() +
+                   padding) {
 	player_icons_.clear();
 	suggested_teams_.clear();
 	set_size(max_x, max_y);
@@ -128,8 +118,11 @@
 				is_first = false;
 
 				for (Widelands::PlayerNumber player : team) {
-					assert(player < MAX_PLAYERS);
-					const Image* player_image = g_gr->images().get(player_pictures_small[player]);
+					assert(player < kMaxPlayers);
+					const Image* player_image = playercolor_image(
+					   player, g_gr->images().get("images/players/player_position_menu.png"),
+					   g_gr->images().get("images/players/player_position_menu_pc.png"));
+
 					assert(player_image);
 					player_icon = new UI::Icon(
 					   lineup_box_, 0, 0, player_image->width(), player_image->height(), player_image);


Follow ups