← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/show-ship-names into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/show-ship-names into lp:widelands.

Commit message:
Added census/statistics strings to ships and ship construction.
Ship states are now an enum class.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/show-ship-names/+merge/289562

I want to see those beautiful ship names :)
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/show-ship-names into lp:widelands.
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc	2016-03-12 21:28:53 +0000
+++ src/ai/defaultai.cc	2016-03-19 13:07:23 +0000
@@ -3633,12 +3633,12 @@
 		// iterating over ships and doing what is needed
 		for (std::list<ShipObserver>::iterator i = allships.begin(); i != allships.end(); ++i) {
 
-			const uint8_t ship_state = i->ship->get_ship_state();
+			const Widelands::Ship::ShipStates ship_state = i->ship->get_ship_state();
 
 			// Here we manage duration of expedition and related variables
-			if (ship_state == Widelands::Ship::EXP_WAITING ||
-			    ship_state == Widelands::Ship::EXP_SCOUTING ||
-				ship_state == Widelands::Ship::EXP_FOUNDPORTSPACE) {
+			if (ship_state == Widelands::Ship::ShipStates::kExpeditionWaiting ||
+				 ship_state == Widelands::Ship::ShipStates::kExpeditionScouting ||
+				ship_state == Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
 
 					// the function below will take care of variables like
 					// - expedition_ship_
@@ -3656,8 +3656,8 @@
 			}
 
 			// only two states need an attention
-			if ((i->ship->get_ship_state() == Widelands::Ship::EXP_WAITING ||
-			     i->ship->get_ship_state() == Widelands::Ship::EXP_FOUNDPORTSPACE) &&
+			if ((i->ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionWaiting ||
+				  i->ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound) &&
 			    !i->waiting_for_command_) {
 				if (gametime - i->last_command_time > 180 * 1000) {
 					i->waiting_for_command_ = true;
@@ -3676,7 +3676,7 @@
 			}
 
 			// Checking utilization
-			if (i->ship->get_ship_state() == Widelands::Ship::TRANSPORT) {
+			if (i->ship->get_ship_state() == Widelands::Ship::ShipStates::kTransport) {
 				// Good utilization is 10 pieces of ware onboard, to track utilization we use range 0-10000
 				// to avoid float or rounding errors if integers in range 0-100
 				const int16_t tmp_util = (i->ship->get_nritems() > 10) ? 10000 : i->ship->get_nritems() * 1000;

=== modified file 'src/economy/fleet.cc'
--- src/economy/fleet.cc	2016-03-12 07:07:12 +0000
+++ src/economy/fleet.cc	2016-03-19 13:07:23 +0000
@@ -696,7 +696,7 @@
 		if (ships_[s]->get_destination(game)) {
 			continue;
 		}
-		if (ships_[s]->get_ship_state() != Ship::TRANSPORT) {
+		if (ships_[s]->get_ship_state() != Ship::ShipStates::kTransport) {
 			continue; // in expedition obviously
 		}
 
@@ -759,7 +759,7 @@
 				continue; // already has destination
 			}
 
-			if (ships_[s]->get_ship_state() != Ship::TRANSPORT) {
+			if (ships_[s]->get_ship_state() != Ship::ShipStates::kTransport) {
 				continue; // in expedition obviously
 			}
 

=== modified file 'src/logic/map_objects/immovable.cc'
--- src/logic/map_objects/immovable.cc	2016-02-20 14:09:12 +0000
+++ src/logic/map_objects/immovable.cc	2016-03-19 13:07:23 +0000
@@ -30,11 +30,8 @@
 #include "base/macros.h"
 #include "base/wexception.h"
 #include "config.h"
-#include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
-#include "graphic/text_constants.h"
-#include "graphic/text_layout.h"
 #include "helper.h"
 #include "io/fileread.h"
 #include "io/filewrite.h"
@@ -515,23 +512,16 @@
 	                   Rect(Point(0, curh - lines), curw, lines));
 
 	// Additionally, if statistics are enabled, draw a progression string
-	if (game.get_ibase()->get_display_flags() & InteractiveBase::dfShowStatistics) {
-		unsigned int percent = (100 * done / total);
-		construct_string_ =
-			(boost::format("<font color=%s>%s</font>")
-			 % UI_FONT_CLR_DARK.hex_value() % (boost::format(_("%i%% built")) % percent).str())
-			 .str();
-		construct_string_ = as_uifont(construct_string_);
-		dst.blit(pos - Point(0, 48),
-				 UI::g_fh1->render(construct_string_),
-				 BlendMode::UseAlpha,
-				 UI::Align::kCenter);
-	}
+	uint32_t const dpyflags = game.get_ibase()->get_display_flags();
+	do_draw_info(dpyflags & InteractiveBase::dfShowCensus, descr().descname(),
+					 dpyflags & InteractiveBase::dfShowStatistics,
+					 (boost::format("<font color=%s>%s</font>")
+					  % UI_FONT_CLR_DARK.hex_value()
+					  % (boost::format(_("%i%% built")) % (100 * done / total)).str()).str(),
+					  dst, pos);
 }
 
 
-
-
 /**
  * Set the current action's data to \p data.
  *

=== modified file 'src/logic/map_objects/immovable.h'
--- src/logic/map_objects/immovable.h	2016-02-10 19:50:13 +0000
+++ src/logic/map_objects/immovable.h	2016-03-19 13:07:23 +0000
@@ -246,7 +246,6 @@
 	uint32_t anim_construction_done_;
 	uint32_t program_step_; ///< time of next step
 #endif
-	std::string construct_string_;
 
 	/**
 	 * Private persistent data for the currently active program action.

=== modified file 'src/logic/map_objects/map_object.cc'
--- src/logic/map_objects/map_object.cc	2016-03-10 13:48:50 +0000
+++ src/logic/map_objects/map_object.cc	2016-03-19 13:07:23 +0000
@@ -28,7 +28,10 @@
 
 #include "base/log.h"
 #include "base/wexception.h"
+#include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
+#include "graphic/rendertarget.h"
+#include "graphic/text_layout.h"
 #include "io/fileread.h"
 #include "io/filewrite.h"
 #include "logic/cmd_queue.h"
@@ -480,6 +483,27 @@
 	egbase.objects().remove(*this);
 }
 
+void MapObject::do_draw_info(bool show_census, const std::string& census,
+									  bool show_statictics, const std::string& statictics,
+									  RenderTarget& dst, const Point& pos) const {
+	if (show_census || show_statictics) {
+		// We always render this so we can have a stable position for the statistics string.
+		const Image* rendered_census_info =
+				UI::g_fh1->render(as_condensed(census, UI::Align::kCenter), 120);
+		const Point census_pos(pos - Point(0, 48));
+
+		if (show_census) {
+			dst.blit(census_pos, rendered_census_info, BlendMode::UseAlpha, UI::Align::kCenter);
+		}
+
+		if (show_statictics && !statictics.empty()) {
+			dst.blit(census_pos + Point(0, rendered_census_info->height() / 2 + 10),
+						UI::g_fh1->render(as_condensed(statictics)),
+						BlendMode::UseAlpha, UI::Align::kCenter);
+		}
+	}
+}
+
 const Image* MapObject::representative_image() const {
 	return descr().representative_image();
 }

=== modified file 'src/logic/map_objects/map_object.h'
--- src/logic/map_objects/map_object.h	2016-02-17 22:13:21 +0000
+++ src/logic/map_objects/map_object.h	2016-03-19 13:07:23 +0000
@@ -380,6 +380,11 @@
 
 	virtual void cleanup(EditorGameBase &);
 
+	/// Draws census and statistics on screen
+	void do_draw_info(bool show_census, const std::string& census,
+							bool show_statictics, const std::string& statictics,
+							RenderTarget& dst, const Point& pos) const;
+
 	void molog(char const * fmt, ...) const
 		__attribute__((format(printf, 2, 3)));
 

=== modified file 'src/logic/map_objects/tribes/building.cc'
--- src/logic/map_objects/tribes/building.cc	2016-03-10 12:40:49 +0000
+++ src/logic/map_objects/tribes/building.cc	2016-03-19 13:07:23 +0000
@@ -31,11 +31,8 @@
 #include "base/wexception.h"
 #include "economy/flag.h"
 #include "economy/request.h"
-#include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
-#include "graphic/text/font_set.h"
-#include "graphic/text_layout.h"
 #include "io/filesystem/filesystem.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "logic/game.h"
@@ -654,7 +651,7 @@
 		//  door animation?
 
 		//  overlay strings (draw when enabled)
-		draw_help(game, dst, coords, pos);
+		draw_info(game, dst, pos);
 	}
 }
 
@@ -664,38 +661,29 @@
 Draw overlay help strings when enabled.
 ===============
 */
-void Building::draw_help
-	(const EditorGameBase& game, RenderTarget& dst, const FCoords&, const Point& pos)
+void Building::draw_info
+	(const EditorGameBase& game, RenderTarget& dst, const Point& pos)
 {
 	const InteractiveGameBase & igbase =
 		dynamic_cast<const InteractiveGameBase&>(*game.get_ibase());
 	uint32_t const dpyflags = igbase.get_display_flags();
 
-	if (dpyflags & InteractiveBase::dfShowCensus || dpyflags & InteractiveBase::dfShowStatistics) {
-		// We always render this so we can have a stable position for the statistics string.
-		const Image* rendered_census_info =
-				UI::g_fh1->render(as_condensed(info_string(InfoStringFormat::kCensus), UI::Align::kCenter),
-										120);
-		const Point census_pos(pos - Point(0, 48));
-
-		if (dpyflags & InteractiveBase::dfShowCensus) {
-			dst.blit(census_pos, rendered_census_info, BlendMode::UseAlpha, UI::Align::kCenter);
-		}
-
-		if (dpyflags & InteractiveBase::dfShowStatistics) {
-			if (upcast(InteractivePlayer const, iplayer, &igbase))
-				if
-					(!iplayer->player().see_all() &&
-					 iplayer->player().is_hostile(*get_owner()))
-					return;
-			const std::string& info = info_string(InfoStringFormat::kStatistics);
-			if (!info.empty()) {
-				dst.blit(census_pos + Point(0, rendered_census_info->height() / 2 + 10),
-							UI::g_fh1->render(as_condensed(info)),
-							BlendMode::UseAlpha, UI::Align::kCenter);
+	bool show_statistics_string = dpyflags & InteractiveBase::dfShowStatistics;
+	if (show_statistics_string) {
+		if (upcast(InteractivePlayer const, iplayer, &igbase)) {
+			if
+				(!iplayer->player().see_all() &&
+				 iplayer->player().is_hostile(*get_owner())) {
+				show_statistics_string = false;
 			}
 		}
 	}
+	const std::string statistics_string =
+			show_statistics_string ? info_string(InfoStringFormat::kStatistics) : "";
+
+	do_draw_info(dpyflags & InteractiveBase::dfShowCensus, info_string(InfoStringFormat::kCensus),
+					 show_statistics_string, statistics_string,
+					 dst, pos);
 }
 
 int32_t Building::get_priority

=== modified file 'src/logic/map_objects/tribes/building.h'
--- src/logic/map_objects/tribes/building.h	2016-02-13 12:15:29 +0000
+++ src/logic/map_objects/tribes/building.h	2016-03-19 13:07:23 +0000
@@ -279,7 +279,7 @@
 	void act(Game &, uint32_t data) override;
 
 	void draw(const EditorGameBase &, RenderTarget &, const FCoords&, const Point&) override;
-	void draw_help(const EditorGameBase &, RenderTarget &, const FCoords&, const Point&);
+	void draw_info(const EditorGameBase &, RenderTarget &, const Point&);
 
 	virtual void create_options_window
 		(InteractiveGameBase &, UI::Window * & registry)

=== modified file 'src/logic/map_objects/tribes/constructionsite.cc'
--- src/logic/map_objects/tribes/constructionsite.cc	2016-03-13 13:22:49 +0000
+++ src/logic/map_objects/tribes/constructionsite.cc	2016-03-19 13:07:23 +0000
@@ -397,7 +397,7 @@
 	dst.blit_animation(pos, anim_idx, tanim, player_color, Rect(Point(0, h - lines), w, lines));
 
 	// Draw help strings
-	draw_help(game, dst, coords, pos);
+	draw_info(game, dst, pos);
 }
 
 }

=== modified file 'src/logic/map_objects/tribes/dismantlesite.cc'
--- src/logic/map_objects/tribes/dismantlesite.cc	2016-03-13 13:22:49 +0000
+++ src/logic/map_objects/tribes/dismantlesite.cc	2016-03-19 13:07:23 +0000
@@ -268,7 +268,7 @@
 	dst.blit_animation(pos, anim_idx, tanim, player_color, Rect(Point(0, lines), w, h - lines));
 
 	// Draw help strings
-	draw_help(game, dst, coords, pos);
+	draw_info(game, dst, pos);
 }
 
 }

=== modified file 'src/logic/map_objects/tribes/ship.cc'
--- src/logic/map_objects/tribes/ship.cc	2016-03-17 07:57:52 +0000
+++ src/logic/map_objects/tribes/ship.cc	2016-03-19 13:07:23 +0000
@@ -31,6 +31,7 @@
 #include "economy/portdock.h"
 #include "economy/wares_queue.h"
 #include "graphic/graphic.h"
+#include "graphic/rendertarget.h"
 #include "io/fileread.h"
 #include "io/filewrite.h"
 #include "logic/findbob.h"
@@ -125,7 +126,7 @@
 }
 
 Ship::Ship(const ShipDescr& gdescr)
-   : Bob(gdescr), window_(nullptr), fleet_(nullptr), economy_(nullptr), ship_state_(TRANSPORT) {
+	: Bob(gdescr), window_(nullptr), fleet_(nullptr), economy_(nullptr), ship_state_(ShipStates::kTransport) {
 }
 
 Ship::~Ship() {
@@ -255,26 +256,26 @@
 	}
 
 	switch (ship_state_) {
-	case TRANSPORT:
+	case ShipStates::kTransport:
 		if (ship_update_transport(game, state))
 			return;
 		break;
-	case EXP_FOUNDPORTSPACE:
-	case EXP_SCOUTING:
-	case EXP_WAITING:
+	case ShipStates::kExpeditionPortspaceFound:
+	case ShipStates::kExpeditionScouting:
+	case ShipStates::kExpeditionWaiting:
 		ship_update_expedition(game, state);
 		break;
-	case EXP_COLONIZING:
+	case ShipStates::kExpeditionColonizing:
 		break;
-	case SINK_REQUEST:
+	case ShipStates::kSinkRequest:
 		if (descr().is_animation_known("sinking")) {
-			ship_state_ = SINK_ANIMATION;
+			ship_state_ = ShipStates::kSinkAnimation;
 			start_task_idle(game, descr().get_animation("sinking"), 3000);
 			return;
 		}
 		log("Oh no... this ship has no sinking animation :(!\n");
 	// fall trough
-	case SINK_ANIMATION:
+	case ShipStates::kSinkAnimation:
 		// The sink animation has been played, so finally remove the ship from the map
 		pop_task(game);
 		remove(game);
@@ -376,7 +377,7 @@
 		   map.get_neighbour(position, dir).field->nodecaps() & MOVECAPS_SWIM;
 	}
 
-	if (ship_state_ == EXP_SCOUTING) {
+	if (ship_state_ == ShipStates::kExpeditionScouting) {
 		// Check surrounding fields for port buildspaces
 		std::vector<Coords> temp_port_buildspaces;
 		MapRegion<Area<Coords>> mr(map, Area<Coords>(position, descr().vision_range()));
@@ -411,7 +412,7 @@
 		} while (mr.advance(map));
 
 		if (new_port_space) {
-			ship_state_ = EXP_FOUNDPORTSPACE;
+			ship_state_ = ShipStates::kExpeditionPortspaceFound;
 			send_message(
 						game,
 						_("Port Space"),
@@ -441,7 +442,7 @@
 	// If we are waiting for the next transport job, check if we should move away from ships and
 	// shores
 	switch (ship_state_) {
-	case TRANSPORT: {
+	case ShipStates::kTransport: {
 		FCoords position = get_position();
 		Map& map = game.map();
 		unsigned int dirs[LAST_DIRECTION + 1];
@@ -515,7 +516,7 @@
 		return;
 	}
 
-	case EXP_SCOUTING: {
+	case ShipStates::kExpeditionScouting: {
 		if (expedition_->island_exploration) {  // Exploration of the island
 			if (exp_close_to_coast()) {
 				if (expedition_->scouting_direction == WalkingDir::IDLE) {
@@ -539,7 +540,7 @@
 									_("Island Circumnavigated"),
 									_("An expedition ship sailed around its island without any events."),
 									"images/wui/ship/ship_explore_island_cw.png");
-						ship_state_ = EXP_WAITING;
+						ship_state_ = ShipStates::kExpeditionWaiting;
 
 						Notifications::publish(
 						   NoteShipMessage(this, NoteShipMessage::Message::kWaitingForCommand));
@@ -582,7 +583,7 @@
 				}
 				// if we are here, it seems something really strange happend.
 				log("WARNING: ship was not able to start exploration. Entering WAIT mode.");
-				ship_state_ = EXP_WAITING;
+				ship_state_ = ShipStates::kExpeditionWaiting;
 				return start_task_idle(game, descr().main_animation(), 1500);
 			}
 		} else {  // scouting towards a specific direction
@@ -593,7 +594,7 @@
 				return;
 			}
 			// coast reached
-			ship_state_ = EXP_WAITING;
+			ship_state_ = ShipStates::kExpeditionWaiting;
 			start_task_idle(game, descr().main_animation(), 1500);
 			// Send a message to the player, that a new coast was reached
 			send_message(
@@ -610,7 +611,7 @@
 			return;
 		}
 	}
-	case EXP_COLONIZING: {
+	case ShipStates::kExpeditionColonizing: {
 		assert(!expedition_->seen_port_buildspaces.empty());
 		BaseImmovable* baim = game.map()[expedition_->seen_port_buildspaces.front()].get_immovable();
 		if (baim) {
@@ -669,7 +670,7 @@
 		}
 
 		if (items_.empty() || !baim) {  // we are done, either way
-			ship_state_ = TRANSPORT;     // That's it, expedition finished
+			ship_state_ = ShipStates::kTransport;     // That's it, expedition finished
 
 			// Bring us back into a fleet and a economy.
 			init_fleet(game);
@@ -808,7 +809,7 @@
 /// Prepare everything for the coming exploration
 void Ship::start_task_expedition(Game& game) {
 	// Now we are waiting
-	ship_state_ = EXP_WAITING;
+	ship_state_ = ShipStates::kExpeditionWaiting;
 	// Initialize a new, yet empty expedition
 	expedition_.reset(new Expedition());
 	expedition_->seen_port_buildspaces.clear();
@@ -852,13 +853,13 @@
 /// @note only called via player command
 void Ship::exp_scouting_direction(Game&, WalkingDir scouting_direction) {
 	assert(expedition_);
-	ship_state_ = EXP_SCOUTING;
+	ship_state_ = ShipStates::kExpeditionScouting;
 	expedition_->scouting_direction = scouting_direction;
 	expedition_->island_exploration = false;
 }
 
 WalkingDir Ship::get_scouting_direction() {
-	if (expedition_ && ship_state_ == EXP_SCOUTING && !expedition_->island_exploration) {
+	if (expedition_ && ship_state_ == ShipStates::kExpeditionScouting && !expedition_->island_exploration) {
 		return expedition_->scouting_direction;
 	}
 	return WalkingDir::IDLE;
@@ -870,21 +871,21 @@
 	assert(expedition_);
 	DescriptionIndex port_idx = get_owner()->tribe().port();
 	get_owner()->force_csite(c, port_idx);
-	ship_state_ = EXP_COLONIZING;
+	ship_state_ = ShipStates::kExpeditionColonizing;
 }
 
 /// Initializes / changes the direction the island exploration in @arg island_explore_direction direction
 /// @note only called via player command
 void Ship::exp_explore_island(Game&, IslandExploreDirection island_explore_direction) {
 	assert(expedition_);
-	ship_state_ = EXP_SCOUTING;
+	ship_state_ = ShipStates::kExpeditionScouting;
 	expedition_->island_explore_direction = island_explore_direction;
 	expedition_->scouting_direction = WalkingDir::IDLE;
 	expedition_->island_exploration = true;
 }
 
 IslandExploreDirection Ship::get_island_explore_direction() {
-	if (expedition_ && ship_state_ == EXP_SCOUTING && expedition_->island_exploration) {
+	if (expedition_ && ship_state_ == ShipStates::kExpeditionScouting && expedition_->island_exploration) {
 		return expedition_->island_explore_direction;
 	}
 	return IslandExploreDirection::kNotSet;
@@ -897,7 +898,7 @@
 	// Running colonization has the highest priority before cancelation
 	// + cancelation only works if an expedition is actually running
 
-	if ((ship_state_ == EXP_COLONIZING) || !state_is_expedition())
+	if ((ship_state_ == ShipStates::kExpeditionColonizing) || !state_is_expedition())
 		return;
 	send_signal(game, "cancel_expedition");
 
@@ -916,7 +917,7 @@
 			worker->start_task_shipping(game, nullptr);
 		}
 	}
-	ship_state_ = TRANSPORT;
+	ship_state_ = ShipStates::kTransport;
 
 	// Bring us back into a fleet and a economy.
 	set_economy(game, nullptr);
@@ -937,12 +938,56 @@
 	// Running colonization has the highest priority + a sink request is only valid once
 	if (!state_is_sinkable())
 		return;
-	ship_state_ = SINK_REQUEST;
+	ship_state_ = ShipStates::kSinkRequest;
 	// Make sure the ship is active and close possible open windows
 	ship_wakeup(game);
 	close_window();
 }
 
+void Ship::draw(const EditorGameBase& game, RenderTarget& dst, const Point& pos) const {
+	Bob::draw(game, dst, pos);
+
+	// Show ship name and current activity
+	uint32_t const dpyflags = game.get_ibase()->get_display_flags();
+	std::string statistics_string = "";
+	if (dpyflags & InteractiveBase::dfShowStatistics) {
+		switch (ship_state_) {
+		case (ShipStates::kTransport):
+			/** TRANSLATORS: This is a ship state */
+			statistics_string = pgettext("ship_state", "Transporting Wares");
+			break;
+		case (ShipStates::kExpeditionWaiting):
+			/** TRANSLATORS: This is a ship state */
+			statistics_string = pgettext("ship_state", "Waiting");
+			break;
+		case (ShipStates::kExpeditionScouting):
+			/** TRANSLATORS: This is a ship state */
+			statistics_string = pgettext("ship_state", "Scouting");
+			break;
+		case (ShipStates::kExpeditionPortspaceFound):
+			/** TRANSLATORS: This is a ship state */
+			statistics_string = pgettext("ship_state", "Port Space Found");
+			break;
+		case (ShipStates::kExpeditionColonizing):
+			/** TRANSLATORS: This is a ship state */
+			statistics_string = pgettext("ship_state", "Unloading");
+			break;
+		case (ShipStates::kSinkRequest):
+		case (ShipStates::kSinkAnimation):
+			break;
+		default:
+			NEVER_HERE();
+		}
+		statistics_string = (boost::format("<font color=%s>%s</font>")
+									% UI_FONT_CLR_OK.hex_value()
+									% statistics_string).str();
+	}
+
+	do_draw_info(dpyflags & InteractiveBase::dfShowCensus, shipname_,
+					 dpyflags & InteractiveBase::dfShowStatistics, statistics_string,
+					 dst, calc_drawpos(game, pos));
+}
+
 void Ship::log_general_info(const EditorGameBase& egbase) {
 	Bob::log_general_info(egbase);
 
@@ -1048,11 +1093,13 @@
 	Bob::Loader::load(fr);
 
 	// The state the ship is in
-	ship_state_ = fr.unsigned_8();
+	ship_state_ = static_cast<ShipStates>(fr.unsigned_8());
 
 	// Expedition specific data
-	if (ship_state_ == EXP_SCOUTING || ship_state_ == EXP_WAITING ||
-		 ship_state_ == EXP_FOUNDPORTSPACE || ship_state_ == EXP_COLONIZING) {
+	if (ship_state_ == ShipStates::kExpeditionScouting ||
+		 ship_state_ == ShipStates::kExpeditionWaiting ||
+		 ship_state_ == ShipStates::kExpeditionPortspaceFound ||
+		 ship_state_ == ShipStates::kExpeditionColonizing) {
 		expedition_.reset(new Expedition());
 		// Currently seen port build spaces
 		expedition_->seen_port_buildspaces.clear();
@@ -1071,7 +1118,7 @@
 		// Whether the exploration is done clockwise or counter clockwise
 		expedition_->island_explore_direction = static_cast<IslandExploreDirection>(fr.unsigned_8());
 	} else {
-		ship_state_ = TRANSPORT;
+		ship_state_ = ShipStates::kTransport;
 	}
 
 	shipname_ = fr.c_string();
@@ -1117,7 +1164,7 @@
 		ship.expedition_->economy.reset(new Economy(*ship.get_owner()));
 		ship.economy_ = ship.expedition_->economy.get();
 	} else
-		assert(ship_state_ == TRANSPORT);
+		assert(ship_state_ == ShipStates::kTransport);
 
 	// Workers load code set their economy to the economy of their location
 	// (which is a PlayerImmovable), that means that workers on ships do not get
@@ -1175,7 +1222,7 @@
 	Bob::save(egbase, mos, fw);
 
 	// state the ship is in
-	fw.unsigned_8(ship_state_);
+	fw.unsigned_8(static_cast<uint8_t>(ship_state_));
 
 	// expedition specific data
 	if (state_is_expedition()) {

=== modified file 'src/logic/map_objects/tribes/ship.h'
--- src/logic/map_objects/tribes/ship.h	2016-02-22 07:36:10 +0000
+++ src/logic/map_objects/tribes/ship.h	2016-03-19 13:07:23 +0000
@@ -124,34 +124,34 @@
 	void close_window();
 	void refresh_window(InteractiveGameBase &);
 
-	// A ship with task expedition can be in four states: EXP_WAITING, EXP_SCOUTING,
-	// EXP_FOUNDPORTSPACE or EXP_COLONIZING in the first states, the owning player of this ship can
-	// give direction change commands to change the direction of the moving ship / send the ship in a
-	// direction. Once the ship is on its way, it is in EXP_SCOUTING state. In the backend, a click
+	// A ship with task expedition can be in four states: kExpeditionWaiting, kExpeditionScouting,
+	// kExpeditionPortspaceFound or kExpeditionColonizing in the first states, the owning player of this ship
+	// can give direction change commands to change the direction of the moving ship / send the ship in a
+	// direction. Once the ship is on its way, it is in kExpeditionScouting state. In the backend, a click
 	// on a direction begins to the movement into that direction until a coast is reached or the user
 	// cancels the direction through a direction change.
 	//
-	// The EXP_WAITING state means, that an event happend and thus the ship stopped and waits for a
-	// new command by the owner. An event leading to a EXP_WAITING state can be:
+	// The kExpeditionWaiting state means, that an event happend and thus the ship stopped and waits for a
+	// new command by the owner. An event leading to a kExpeditionWaiting state can be:
 	// * expedition is ready to start
 	// * new island appeared in vision range (only outer ring of vision range has to be checked due to the
 	//   always ongoing movement).
 	// * island was completely surrounded
 	//
-	// The EXP_FOUNDPORTSPACE state means, that a port build space was found.
+	// The kExpeditionPortspaceFound state means, that a port build space was found.
 	//
-	enum {
-		TRANSPORT          = 0,
-		EXP_WAITING        = 1,
-		EXP_SCOUTING       = 2,
-		EXP_FOUNDPORTSPACE = 3,
-		EXP_COLONIZING     = 4,
-		SINK_REQUEST       = 8,
-		SINK_ANIMATION     = 9
+	enum class ShipStates : uint8_t {
+		kTransport                = 0,
+		kExpeditionWaiting        = 1,
+		kExpeditionScouting       = 2,
+		kExpeditionPortspaceFound = 3,
+		kExpeditionColonizing     = 4,
+		kSinkRequest              = 8,
+		kSinkAnimation            = 9
 	};
 
 	/// \returns the current state the ship is in
-	uint8_t get_ship_state() {return ship_state_;}
+	ShipStates get_ship_state() {return ship_state_;}
 
 	/// \returns the current name of ship
 	const std::string & get_shipname() {return shipname_;}
@@ -159,24 +159,24 @@
 	/// \returns whether the ship is currently on an expedition
 	bool state_is_expedition() {
 		return
-			(ship_state_ == EXP_SCOUTING
-			 ||
-			 ship_state_ == EXP_WAITING
-			 ||
-			 ship_state_ == EXP_FOUNDPORTSPACE
-			 ||
-			 ship_state_ == EXP_COLONIZING);
+			(ship_state_ == ShipStates::kExpeditionScouting
+			 ||
+			 ship_state_ == ShipStates::kExpeditionWaiting
+			 ||
+			 ship_state_ == ShipStates::kExpeditionPortspaceFound
+			 ||
+			 ship_state_ == ShipStates::kExpeditionColonizing);
 	}
 	/// \returns whether the ship is in transport mode
-	bool state_is_transport() {return (ship_state_ == TRANSPORT);}
+	bool state_is_transport() {return (ship_state_ == ShipStates::kTransport);}
 	/// \returns whether a sink request for the ship is currently valid
 	bool state_is_sinkable() {
 		return
-			(ship_state_ != SINK_REQUEST
-			 &&
-			 ship_state_ != SINK_ANIMATION
-			 &&
-			 ship_state_ != EXP_COLONIZING);
+			(ship_state_ != ShipStates::kSinkRequest
+			 &&
+			 ship_state_ != ShipStates::kSinkAnimation
+			 &&
+			 ship_state_ != ShipStates::kExpeditionColonizing);
 	}
 
 	/// \returns (in expedition mode only!) whether the next field in direction \arg dir is swimable
@@ -217,6 +217,9 @@
 	void exp_cancel (Game &);
 	void sink_ship  (Game &);
 
+protected:
+	void draw(const EditorGameBase&, RenderTarget&, const Point&) const override;
+
 private:
 	friend struct Fleet;
 	friend struct ShipWindow;
@@ -248,7 +251,7 @@
 	OPtr<PortDock> lastdock_;
 	OPtr<PortDock> destination_;
 	std::vector<ShippingItem> items_;
-	uint8_t ship_state_;
+	ShipStates ship_state_;
 	std::string shipname_;
 
 	struct Expedition {
@@ -276,7 +279,7 @@
 	private:
 		uint32_t lastdock_;
 		uint32_t destination_;
-		uint8_t  ship_state_;
+		ShipStates  ship_state_;
 		std::string shipname_;
 		std::unique_ptr<Expedition> expedition_;
 		std::vector<ShippingItem::Loader> items_;

=== modified file 'src/logic/playercommand.cc'
--- src/logic/playercommand.cc	2016-03-02 17:13:06 +0000
+++ src/logic/playercommand.cc	2016-03-19 13:07:23 +0000
@@ -814,11 +814,11 @@
 {
 	upcast(Ship, ship, game.objects().get_object(serial));
 	if (ship && ship->get_owner()->player_number() == sender()) {
-		if (!(ship->get_ship_state() == Widelands::Ship::EXP_WAITING ||
-			ship->get_ship_state() == Widelands::Ship::EXP_FOUNDPORTSPACE ||
-			ship->get_ship_state() == Widelands::Ship::EXP_SCOUTING)) {
+		if (!(ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionWaiting ||
+			ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound ||
+			ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionScouting)) {
 			log (" %1d:ship on %3dx%3d received scout command but not in "
-				"EXP_WAITING or PORTSPACE_FOUND or EXP_SCOUTING status "
+				"kExpeditionWaiting or kExpeditionPortspaceFound or kExpeditionScouting status "
 				"(expedition: %s), ignoring...\n",
 				ship->get_owner()->player_number(),
 				ship->get_position().x,
@@ -886,9 +886,9 @@
 {
 	upcast(Ship, ship, game.objects().get_object(serial));
 	if (ship && ship->get_owner()->player_number() == sender()) {
-		if (ship->get_ship_state() != Widelands::Ship::EXP_FOUNDPORTSPACE) {
+		if (ship->get_ship_state() != Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
 			log (" %1d:ship on %3dx%3d received build port command but "
-			"not in PORTSPACE_FOUND status (expedition: %s), ignoring...\n",
+			"not in kExpeditionPortspaceFound status (expedition: %s), ignoring...\n",
 				ship->get_owner()->player_number(),
 				ship->get_position().x,
 				ship->get_position().y,
@@ -955,11 +955,11 @@
 {
 	upcast(Ship, ship, game.objects().get_object(serial));
 	if (ship && ship->get_owner()->player_number() == sender()) {
-		if (!(ship->get_ship_state() == Widelands::Ship::EXP_WAITING ||
-			ship->get_ship_state() == Widelands::Ship::EXP_FOUNDPORTSPACE ||
-			ship->get_ship_state() == Widelands::Ship::EXP_SCOUTING)) {
+		if (!(ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionWaiting ||
+			ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound ||
+			ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionScouting)) {
 			log (" %1d:ship on %3dx%3d received explore island command "
-			"but not in EXP_WAITING or PORTSPACE_FOUND or EXP_SCOUTING "
+			"but not in kExpeditionWaiting or kExpeditionPortspaceFound or kExpeditionScouting "
 			"status (expedition: %s), ignoring...\n",
 				ship->get_owner()->player_number(),
 				ship->get_position().x,

=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc	2016-03-14 19:56:14 +0000
+++ src/scripting/lua_map.cc	2016-03-19 13:07:23 +0000
@@ -4442,25 +4442,25 @@
 	EditorGameBase& egbase = get_egbase(L);
 	if (is_a(Game, &egbase)) {
 		switch (get(L, egbase)->get_ship_state()) {
-			case Ship::TRANSPORT:
+			case Ship::ShipStates::kTransport:
 				lua_pushstring(L, "transport");
 				break;
-			case Ship::EXP_WAITING:
+			case Ship::ShipStates::kExpeditionWaiting:
 				lua_pushstring(L, "exp_waiting");
 				break;
-			case Ship::EXP_SCOUTING:
+			case Ship::ShipStates::kExpeditionScouting:
 				lua_pushstring(L, "exp_scouting");
 				break;
-			case Ship::EXP_FOUNDPORTSPACE:
+			case Ship::ShipStates::kExpeditionPortspaceFound:
 				lua_pushstring(L, "exp_found_port_space");
 				break;
-			case Ship::EXP_COLONIZING:
+			case Ship::ShipStates::kExpeditionColonizing:
 				lua_pushstring(L, "exp_colonizing");
 				break;
-			case Ship::SINK_REQUEST:
+			case Ship::ShipStates::kSinkRequest:
 				lua_pushstring(L, "sink_request");
 				break;
-			case Ship::SINK_ANIMATION:
+			case Ship::ShipStates::kSinkAnimation:
 				lua_pushstring(L, "sink_animation");
 				break;
 			default:
@@ -4655,7 +4655,7 @@
 int LuaShip::build_colonization_port(lua_State* L) {
 	EditorGameBase& egbase = get_egbase(L);
 	Ship* ship =  get(L, egbase);
-	if (ship->get_ship_state() == Widelands::Ship::EXP_FOUNDPORTSPACE) {
+	if (ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
 		if (upcast(Game, game, &egbase)) {
 			game->send_player_ship_construct_port(*ship, ship->exp_port_spaces().front());
 			return 1;

=== modified file 'src/wui/actionconfirm.cc'
--- src/wui/actionconfirm.cc	2016-02-09 21:14:53 +0000
+++ src/wui/actionconfirm.cc	2016-03-19 13:07:23 +0000
@@ -468,9 +468,9 @@
 		 &&
 		 iaplayer().can_act(ship->get_owner()->player_number())
 		 &&
-		 ship->get_ship_state() != Widelands::Ship::TRANSPORT
+		 ship->get_ship_state() != Widelands::Ship::ShipStates::kTransport
 		 &&
-		 ship->get_ship_state() != Widelands::Ship::EXP_COLONIZING)
+		 ship->get_ship_state() != Widelands::Ship::ShipStates::kExpeditionColonizing)
 	{
 		game.send_player_cancel_expedition_ship(*ship);
 	}

=== modified file 'src/wui/shipwindow.cc'
--- src/wui/shipwindow.cc	2016-03-15 20:56:49 +0000
+++ src/wui/shipwindow.cc	2016-03-19 13:07:23 +0000
@@ -250,7 +250,7 @@
 	}
 
 	// Expedition specific buttons
-	uint8_t state = m_ship.get_ship_state();
+	Ship::ShipStates state = m_ship.get_ship_state();
 	if (m_ship.state_is_expedition()) {
 		/* The following rules apply:
 		 * - The "construct port" button is only active, if the ship is waiting for commands and found a port
@@ -260,18 +260,22 @@
 		 * - The "explore island's coast" buttons are only active, if a coast is in vision range (no matter if
 		 *   in waiting or already expedition/scouting mode)
 		 */
-		m_btn_construct_port->set_enabled(can_act && (state == Ship::EXP_FOUNDPORTSPACE));
+		m_btn_construct_port->set_enabled(can_act && (state == Ship::ShipStates::kExpeditionPortspaceFound));
 		bool coast_nearby = false;
 		for (Direction dir = 1; dir <= LAST_DIRECTION; ++dir) {
 			// NOTE buttons are saved in the format DIRECTION - 1
 			m_btn_scout[dir - 1]->set_enabled
-				(can_act && m_ship.exp_dir_swimable(dir) && (state != Ship::EXP_COLONIZING));
+				(can_act && m_ship.exp_dir_swimable(dir) && (state != Ship::ShipStates::kExpeditionColonizing));
 			coast_nearby |= !m_ship.exp_dir_swimable(dir);
 		}
-		m_btn_explore_island_cw ->set_enabled(can_act && coast_nearby && (state != Ship::EXP_COLONIZING));
-		m_btn_explore_island_ccw->set_enabled(can_act && coast_nearby && (state != Ship::EXP_COLONIZING));
-		m_btn_sink              ->set_enabled(can_act && (state != Ship::EXP_COLONIZING));
-		m_btn_cancel_expedition ->set_enabled(can_act && (state != Ship::EXP_COLONIZING));
+		m_btn_explore_island_cw ->set_enabled(can_act && coast_nearby &&
+														  (state != Ship::ShipStates::kExpeditionColonizing));
+		m_btn_explore_island_ccw->set_enabled(can_act && coast_nearby &&
+														  (state != Ship::ShipStates::kExpeditionColonizing));
+		m_btn_sink              ->set_enabled(can_act &&
+														  (state != Ship::ShipStates::kExpeditionColonizing));
+		m_btn_cancel_expedition ->set_enabled(can_act &&
+														  (state != Ship::ShipStates::kExpeditionColonizing));
 	}
 }
 
@@ -370,7 +374,7 @@
 void Ship::show_window(InteractiveGameBase & igb, bool avoid_fastclick)
 {
 	// No window, if ship is sinking
-	if (ship_state_ == SINK_REQUEST || ship_state_ == SINK_ANIMATION)
+	if (ship_state_ == ShipStates::kSinkRequest || ship_state_ == ShipStates::kSinkAnimation)
 		return;
 
 	if (window_) {


Follow ups