← Back to team overview

widelands-dev team mailing list archive

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

 

SirVer has proposed merging lp:~widelands-dev/widelands/simplify_coords into lp:widelands.

Commit message:
Simplify widelands_geometry.h.

- Document TCoords and remove inheritance.
- Simplify FCoords
- Remove TriangleIndex::None

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/simplify_coords/+merge/330119
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/simplify_coords into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2017-09-01 18:59:42 +0000
+++ src/editor/editorinteractive.cc	2017-09-02 19:46:13 +0000
@@ -617,9 +617,9 @@
 
 		// Make sure that we will start at coordinates (0,0).
 		map_view()->set_view(MapView::View{Vector2f::zero(), 1.f}, MapView::Transition::Jump);
-		set_sel_pos(Widelands::NodeAndTriangle<>(
+		set_sel_pos(Widelands::NodeAndTriangle<>{
 		   Widelands::Coords(0, 0),
-		   Widelands::TCoords<>(Widelands::Coords(0, 0), Widelands::TriangleIndex::D)));
+		   Widelands::TCoords<>(Widelands::Coords(0, 0), Widelands::TriangleIndex::D)});
 		break;
 
 	case MapWas::kGloballyMutated:

=== modified file 'src/editor/tools/info_tool.cc'
--- src/editor/tools/info_tool.cc	2017-08-30 13:35:37 +0000
+++ src/editor/tools/info_tool.cc	2017-09-02 19:46:13 +0000
@@ -113,7 +113,7 @@
 	// *** Terrain info
 	buf += std::string("\n") + _("Terrain:") + "\n";
 
-	const Widelands::Field& tf = (*map)[center.triangle];
+	const Widelands::Field& tf = (*map)[center.triangle.node];
 	const Widelands::TerrainDescription& ter = world.terrain_descr(
 	   center.triangle.t == Widelands::TriangleIndex::D ? tf.terrain_d() : tf.terrain_r());
 

=== modified file 'src/editor/tools/set_terrain_tool.cc'
--- src/editor/tools/set_terrain_tool.cc	2017-08-31 15:22:21 +0000
+++ src/editor/tools/set_terrain_tool.cc	2017-09-02 19:46:13 +0000
@@ -38,12 +38,12 @@
 		Widelands::MapTriangleRegion<TCoords<Widelands::FCoords>> mr(
 		   *map, Widelands::Area<TCoords<Widelands::FCoords>>(
 		            TCoords<Widelands::FCoords>(
-		               Widelands::FCoords(map->get_fcoords(center.triangle)), center.triangle.t),
+		               Widelands::FCoords(map->get_fcoords(center.triangle.node)), center.triangle.t),
 		            radius));
 		do {
 			args->original_terrain_type.push_back((mr.location().t == Widelands::TriangleIndex::D) ?
-			                                         mr.location().field->terrain_d() :
-			                                         mr.location().field->terrain_r());
+			                                         mr.location().node.field->terrain_d() :
+			                                         mr.location().node.field->terrain_r());
 			args->terrain_type.push_back(get_random_enabled());
 		} while (mr.advance(*map));
 	}
@@ -52,7 +52,7 @@
 		Widelands::MapTriangleRegion<TCoords<Widelands::FCoords>> mr(
 		   *map, Widelands::Area<TCoords<Widelands::FCoords>>(
 		            TCoords<Widelands::FCoords>(
-		               Widelands::FCoords(map->get_fcoords(center.triangle)), center.triangle.t),
+		               Widelands::FCoords(map->get_fcoords(center.triangle.node)), center.triangle.t),
 		            radius));
 		std::list<Widelands::DescriptionIndex>::iterator i = args->terrain_type.begin();
 		do {
@@ -77,7 +77,7 @@
 		Widelands::MapTriangleRegion<TCoords<Widelands::FCoords>> mr(
 		   *map, Widelands::Area<TCoords<Widelands::FCoords>>(
 		            TCoords<Widelands::FCoords>(
-		               Widelands::FCoords(map->get_fcoords(center.triangle)), center.triangle.t),
+		               Widelands::FCoords(map->get_fcoords(center.triangle.node)), center.triangle.t),
 		            radius));
 
 		std::list<Widelands::DescriptionIndex>::iterator i = args->original_terrain_type.begin();

=== modified file 'src/graphic/minimap_renderer.cc'
--- src/graphic/minimap_renderer.cc	2017-08-19 22:22:20 +0000
+++ src/graphic/minimap_renderer.cc	2017-09-02 19:46:13 +0000
@@ -161,10 +161,10 @@
 	const int32_t mapwidth = map.get_width();
 
 	for (uint32_t y = 0; y < surface_h; ++y) {
-		Widelands::FCoords f(
+		Widelands::Coords coords(
 		   Widelands::Coords(top_left.x, top_left.y + ((layers & MiniMapLayer::Zoom2) ? y / 2 : y)));
-		map.normalize_coords(f);
-		f.field = &map[f];
+		map.normalize_coords(coords);
+		Widelands::FCoords f = map.get_fcoords(coords);
 		Widelands::MapIndex i = Widelands::Map::get_index(f, mapwidth);
 		for (uint32_t x = 0; x < surface_w; ++x) {
 			if (x % 2 || !(layers & MiniMapLayer::Zoom2)) {

=== modified file 'src/logic/map.cc'
--- src/logic/map.cc	2017-08-31 15:22:21 +0000
+++ src/logic/map.cc	2017-09-02 19:46:13 +0000
@@ -345,7 +345,7 @@
 	// NOTE because of the triangle design, we have to take special care about cases
 	// NOTE where y is changed by an odd number
 	bool yisodd = (new_origin.y % 2) != 0;
-	for (FCoords c(Coords(0, 0)); c.y < height_; ++c.y) {
+	for (Coords c(Coords(0, 0)); c.y < height_; ++c.y) {
 		bool cyisodd = (c.y % 2) != 0;
 		for (c.x = 0; c.x < width_; ++c.x) {
 			Coords temp;
@@ -1737,63 +1737,64 @@
 
 int32_t
 Map::change_terrain(const World& world, TCoords<FCoords> const c, DescriptionIndex const terrain) {
-	c.field->set_terrain(c.t, terrain);
+	c.node.field->set_terrain(c.t, terrain);
 
 	// remove invalid resources if necessary
 	// check vertex to which the triangle belongs
-	if (!is_resource_valid(world, c, c.field->get_resources())) {
-		clear_resources(c);
+	if (!is_resource_valid(world, c.node, c.node.field->get_resources())) {
+		clear_resources(c.node);
 	}
 
 	// always check south-east vertex
-	Widelands::FCoords f_se(c, c.field);
+	Widelands::FCoords f_se(c.node);
 	get_neighbour(f_se, Widelands::WALK_SE, &f_se);
 	if (!is_resource_valid(world, f_se, f_se.field->get_resources())) {
 		clear_resources(f_se);
 	}
 
 	// check south-west vertex if d-Triangle is changed, check east vertex if r-Triangle is changed
-	Widelands::FCoords f_sw_e(c, c.field);
-	get_neighbour(f_sw_e, c.t == TriangleIndex::D ? Widelands::WALK_SW : Widelands::WALK_E, &f_sw_e);
+	Widelands::FCoords f_sw_e(c.node);
+	get_neighbour(
+	   f_sw_e, c.t == TriangleIndex::D ? Widelands::WALK_SW : Widelands::WALK_E, &f_sw_e);
 	if (!is_resource_valid(world, f_sw_e, f_sw_e.field->get_resources())) {
 		clear_resources(f_sw_e);
 	}
 
-	Notifications::publish(NoteFieldTerrainChanged{c, static_cast<MapIndex>(c.field - &fields_[0])});
+	Notifications::publish(
+	   NoteFieldTerrainChanged{c.node, static_cast<MapIndex>(c.node.field - &fields_[0])});
 
 	// Changing the terrain can affect ports, which can be up to 3 fields away.
 	constexpr int kPotentiallyAffectedNeighbors = 3;
-	recalc_for_field_area(world, Area<FCoords>(c, kPotentiallyAffectedNeighbors));
+	recalc_for_field_area(world, Area<FCoords>(c.node, kPotentiallyAffectedNeighbors));
 	return kPotentiallyAffectedNeighbors;
 }
 
 bool Map::is_resource_valid(const Widelands::World& world,
-                            const TCoords<Widelands::FCoords>& c,
+                            const Widelands::FCoords& c,
                             DescriptionIndex curres) {
 	if (curres == Widelands::kNoResource)
 		return true;
 
-	Widelands::FCoords f(c, c.field);
 	Widelands::FCoords f1;
 
 	int32_t count = 0;
 
 	//  this field
-	count += world.terrain_descr(f.field->terrain_r()).is_resource_valid(curres);
-	count += world.terrain_descr(f.field->terrain_d()).is_resource_valid(curres);
+	count += world.terrain_descr(c.field->terrain_r()).is_resource_valid(curres);
+	count += world.terrain_descr(c.field->terrain_d()).is_resource_valid(curres);
 
 	//  If one of the neighbours is impassable, count its resource stronger.
 	//  top left neigbour
-	get_neighbour(f, Widelands::WALK_NW, &f1);
+	get_neighbour(c, Widelands::WALK_NW, &f1);
 	count += world.terrain_descr(f1.field->terrain_r()).is_resource_valid(curres);
 	count += world.terrain_descr(f1.field->terrain_d()).is_resource_valid(curres);
 
 	//  top right neigbour
-	get_neighbour(f, Widelands::WALK_NE, &f1);
+	get_neighbour(c, Widelands::WALK_NE, &f1);
 	count += world.terrain_descr(f1.field->terrain_d()).is_resource_valid(curres);
 
 	//  left neighbour
-	get_neighbour(f, Widelands::WALK_W, &f1);
+	get_neighbour(c, Widelands::WALK_W, &f1);
 	count += world.terrain_descr(f1.field->terrain_r()).is_resource_valid(curres);
 
 	return count > 1;

=== modified file 'src/logic/map.h'
--- src/logic/map.h	2017-08-28 13:37:51 +0000
+++ src/logic/map.h	2017-09-02 19:46:13 +0000
@@ -427,7 +427,7 @@
 	 * To qualify as valid, resources need to be surrounded by at least two matching terrains.
 	 */
 	bool is_resource_valid(const Widelands::World& world,
-	                       const Widelands::TCoords<Widelands::FCoords>& c,
+	                       const Widelands::FCoords& c,
 	                       DescriptionIndex curres);
 
 	// The objectives that are defined in this map if it is a scenario.

=== modified file 'src/logic/maptriangleregion.cc'
--- src/logic/maptriangleregion.cc	2017-08-30 13:35:37 +0000
+++ src/logic/maptriangleregion.cc	2017-09-02 19:46:13 +0000
@@ -23,20 +23,19 @@
 
 template <>
 MapTriangleRegion<>::MapTriangleRegion(const Map& map, Area<TCoords<>> area)
-   : radius_is_odd_(area.radius & 1) {
-	assert(area.t == TriangleIndex::R || area.t == TriangleIndex::D);
+   : radius_is_odd_(area.radius & 1), location_(area) {
 	const uint16_t radius_plus_1 = area.radius + 1;
 	const uint16_t half_radius_rounded_down = area.radius / 2;
 	row_length_ = radius_plus_1;
 	for (uint32_t i = half_radius_rounded_down; i; --i)
-		map.get_tln(area, &area);
+		map.get_tln(area.node, &area.node);
 	if (area.t == TriangleIndex::R) {
-		left_ = area;
+		left_ = area.node;
 		if (area.radius) {
 			remaining_rows_in_upper_phase_ = half_radius_rounded_down + 1;
 			remaining_rows_in_lower_phase_ = (area.radius - 1) / 2;
 			if (radius_is_odd_) {
-				map.get_trn(area, &area);
+				map.get_trn(area.node, &area.node);
 				phase_ = Top;
 				row_length_ = area.radius + 2;
 				remaining_in_row_ = radius_plus_1 / 2;
@@ -56,13 +55,13 @@
 		remaining_rows_in_upper_phase_ = radius_plus_1 / 2;
 		remaining_rows_in_lower_phase_ = half_radius_rounded_down;
 		if (radius_is_odd_) {
-			map.get_ln(area, &area);
-			left_ = area;
+			map.get_ln(area.node, &area.node);
+			left_ = area.node;
 			phase_ = Upper;
 			remaining_in_row_ = row_length_ = area.radius + 2;
 			area.t = TriangleIndex::R;
 		} else {
-			map.get_bln(area, &left_);
+			map.get_bln(area.node, &left_);
 			phase_ = Top;
 			row_length_ = area.radius + 3;
 			remaining_in_row_ = half_radius_rounded_down + (0 < area.radius);
@@ -80,7 +79,7 @@
 	switch (phase_) {
 	case Top:
 		if (remaining_in_row_)
-			map.get_rn(location_, &location_);
+			map.get_rn(location_.node, &location_.node);
 		else if (remaining_rows_in_upper_phase_) {
 			phase_ = Upper;
 			remaining_in_row_ = row_length_;
@@ -93,7 +92,7 @@
 			if (location_.t == TriangleIndex::D)
 				location_.t = TriangleIndex::R;
 			else
-				location_ = TCoords<>(map.r_n(location_), TriangleIndex::D);
+				location_ = TCoords<>(map.r_n(location_.node), TriangleIndex::D);
 		} else {
 			if (--remaining_rows_in_upper_phase_) {
 				row_length_ += 2;
@@ -119,7 +118,7 @@
 			if (location_.t == TriangleIndex::D)
 				location_.t = TriangleIndex::R;
 			else
-				location_ = TCoords<>(map.r_n(location_), TriangleIndex::D);
+				location_ = TCoords<>(map.r_n(location_.node), TriangleIndex::D);
 		} else {
 			if (--remaining_rows_in_lower_phase_) {
 				assert(row_length_ >= 2);
@@ -135,7 +134,7 @@
 		break;
 	case Bottom:
 		if (remaining_in_row_)
-			map.get_rn(location_, &location_);
+			map.get_rn(location_.node, &location_.node);
 		break;
 	}
 	assert(remaining_in_row_ < 10000);  //  Catch wrapping (integer underflow)
@@ -144,20 +143,20 @@
 
 template <>
 MapTriangleRegion<TCoords<FCoords>>::MapTriangleRegion(const Map& map, Area<TCoords<FCoords>> area)
-   : radius_is_odd_(area.radius & 1) {
+   : radius_is_odd_(area.radius & 1), location_(area) {
 	assert(area.t == TriangleIndex::R || area.t == TriangleIndex::D);
 	const uint16_t radius_plus_1 = area.radius + 1;
 	const uint16_t half_radius_rounded_down = area.radius / 2;
 	row_length_ = radius_plus_1;
 	for (uint32_t i = half_radius_rounded_down; i; --i)
-		map.get_tln(area, &area);
+		map.get_tln(area.node, &area.node);
 	if (area.t == TriangleIndex::R) {
-		left_ = area;
+		left_ = area.node;
 		if (area.radius) {
 			remaining_rows_in_upper_phase_ = half_radius_rounded_down + 1;
 			remaining_rows_in_lower_phase_ = (area.radius - 1) / 2;
 			if (radius_is_odd_) {
-				map.get_trn(area, &area);
+				map.get_trn(area.node, &area.node);
 				phase_ = Top;
 				row_length_ = area.radius + 2;
 				remaining_in_row_ = radius_plus_1 / 2;
@@ -176,13 +175,13 @@
 		remaining_rows_in_upper_phase_ = radius_plus_1 / 2;
 		remaining_rows_in_lower_phase_ = half_radius_rounded_down;
 		if (radius_is_odd_) {
-			map.get_ln(area, &area);
-			left_ = area;
+			map.get_ln(area.node, &area.node);
+			left_ = area.node;
 			phase_ = Upper;
 			remaining_in_row_ = row_length_ = area.radius + 2;
 			area.t = TriangleIndex::R;
 		} else {
-			map.get_bln(area, &left_);
+			map.get_bln(area.node, &left_);
 			phase_ = Top;
 			row_length_ = area.radius + 3;
 			remaining_in_row_ = half_radius_rounded_down + (0 < area.radius);
@@ -201,7 +200,7 @@
 	switch (phase_) {
 	case Top:
 		if (remaining_in_row_)
-			map.get_rn(location_, &location_);
+			map.get_rn(location_.node, &location_.node);
 		else if (remaining_rows_in_upper_phase_) {
 			phase_ = Upper;
 			remaining_in_row_ = row_length_;
@@ -214,7 +213,7 @@
 			if (location_.t == TriangleIndex::D)
 				location_.t = TriangleIndex::R;
 			else
-				location_ = TCoords<FCoords>(map.r_n(location_), TriangleIndex::D);
+				location_ = TCoords<FCoords>(map.r_n(location_.node), TriangleIndex::D);
 		} else {
 			if (--remaining_rows_in_upper_phase_) {
 				row_length_ += 2;
@@ -240,7 +239,7 @@
 			if (location_.t == TriangleIndex::D)
 				location_.t = TriangleIndex::R;
 			else
-				location_ = TCoords<FCoords>(map.r_n(location_), TriangleIndex::D);
+				location_ = TCoords<FCoords>(map.r_n(location_.node), TriangleIndex::D);
 		} else {
 			if (--remaining_rows_in_lower_phase_) {
 				assert(row_length_ >= 2);
@@ -256,7 +255,7 @@
 		break;
 	case Bottom:
 		if (remaining_in_row_)
-			map.get_rn(location_, &location_);
+			map.get_rn(location_.node, &location_.node);
 		break;
 	}
 	assert(remaining_in_row_ < 10000);  //  Catch wrapping (integer underflow)

=== modified file 'src/logic/maptriangleregion.h'
--- src/logic/maptriangleregion.h	2017-08-30 13:35:37 +0000
+++ src/logic/maptriangleregion.h	2017-09-02 19:46:13 +0000
@@ -35,10 +35,6 @@
  * Note that the order in which locations are returned is not guarantueed. (But
  * in fact the triangles are returned row by row from top to bottom and from
  * left to right in each row and I see no reason why that would ever change.)
- *
- * The initial coordinates must refer to a triangle
- * (TriangleIndex::D or TriangleIndex::R). Use MapRegion instead for nodes
- * (TriangleIndex::None).
  */
 template <typename CoordsType = TCoords<>, typename RadiusType = uint16_t>
 struct MapTriangleRegion {
@@ -69,8 +65,8 @@
 	     remaining_in_row_(rowwidth_),
 	     remaining_rows_(area_.radius * 2) {
 		for (uint8_t r = area_.radius; r; --r)
-			map.get_tln(area_, &area_);
-		left_ = area_;
+			map.get_tln(area_.node, &area_.node);
+		left_ = area_.node;
 	}
 
 	const TCoords<FCoords>& location() const {
@@ -83,16 +79,16 @@
 				area_.t = TriangleIndex::R;
 			else {
 				area_.t = TriangleIndex::D;
-				map.get_rn(area_, &area_);
+				map.get_rn(area_.node, &area_.node);
 			}
 		} else if (area_.radius < --remaining_rows_) {
-			map.get_bln(left_, &area_);
-			left_ = area_;
+			map.get_bln(left_, &area_.node);
+			left_ = area_.node;
 			area_.t = TriangleIndex::D;
 			remaining_in_row_ = rowwidth_ += 2;
 		} else if (remaining_rows_) {
-			map.get_brn(left_, &area_);
-			left_ = area_;
+			map.get_brn(left_, &area_.node);
+			left_ = area_.node;
 			area_.t = TriangleIndex::D;
 			remaining_in_row_ = rowwidth_ -= 2;
 		} else

=== modified file 'src/logic/widelands_geometry.h'
--- src/logic/widelands_geometry.h	2017-08-30 13:35:37 +0000
+++ src/logic/widelands_geometry.h	2017-09-02 19:46:13 +0000
@@ -109,54 +109,32 @@
 	}
 	FCoords(const Coords& nc, Field* const nf) : Coords(nc), field(nf) {
 	}
-
-	/**
-	 * Used in RenderTarget::rendermap where this is first called, then the
-	 * coordinates are normalized and after that field is set.
-	 *
-	 * \note You really want to use \ref Map::get_fcoords instead.
-	 */
-	explicit FCoords(const Coords& nc) : Coords(nc), field(nullptr) {
-	}
-
 	Field* field;
 };
 
-enum class TriangleIndex { D, R, None };
+enum class TriangleIndex { D, R };
 
-// TODO(sirver): This should not derive from CoordsType. Replace with NodeAndTriangle.
-template <typename CoordsType = Coords> struct TCoords : public CoordsType {
-	TCoords() : t() {
-	}
-	TCoords(const CoordsType C, const TriangleIndex T = TriangleIndex::None) : CoordsType(C), t(T) {
+// This uniquely indexes a single Triangle on the map. A Triangle is
+// indentified by its owning node and the triangle index (down or right).
+template <typename CoordsType = Coords> struct TCoords {
+	TCoords(const CoordsType C, const TriangleIndex T) : node(C), t(T) {
 	}
 
 	bool operator==(const TCoords& other) const {
-		return CoordsType::operator==(other) && t == other.t;
+		return node == other.node && t == other.t;
 	}
 	bool operator!=(const TCoords& other) const {
-		return CoordsType::operator!=(other) || t != other.t;
+		return !(*this == other);
 	}
 
+	CoordsType node;
 	TriangleIndex t;
 };
 
+// A pair of a coord and a triangle, used to signify which field or triangle
+// the cursor is closest. The triangle might belong to another field.
 template <typename NodeCoordsType = Coords, typename TriangleCoordsType = Coords>
 struct NodeAndTriangle {
-	NodeAndTriangle() {
-	}
-	NodeAndTriangle(const NodeCoordsType Node, const TCoords<TriangleCoordsType>& Triangle)
-
-	   : node(Node), triangle(Triangle) {
-	}
-
-	bool operator==(const NodeAndTriangle<>& other) const {
-		return node == other.node && triangle == other.triangle;
-	}
-	bool operator!=(const NodeAndTriangle<>& other) const {
-		return !(*this == other);
-	}
-
 	NodeCoordsType node;
 	TCoords<TriangleCoordsType> triangle;
 };

=== modified file 'src/scripting/lua_ui.cc'
--- src/scripting/lua_ui.cc	2017-08-19 20:55:57 +0000
+++ src/scripting/lua_ui.cc	2017-09-02 19:46:13 +0000
@@ -578,8 +578,10 @@
 	const auto field = *get_user_class<LuaMaps::LuaField>(L, 2);
 	get()->map_view()->mouse_to_field(field->coords(), MapView::Transition::Jump);
 
-	Widelands::NodeAndTriangle<> node_and_triangle;
-	node_and_triangle.node = field->coords();
+	// We fake the triangle here, since we only support clicking on Nodes from
+	// Lua.
+	Widelands::NodeAndTriangle<> node_and_triangle{
+	   field->coords(), Widelands::TCoords<>(field->coords(), Widelands::TriangleIndex::D)};
 	get()->map_view()->field_clicked(node_and_triangle);
 	return 0;
 }

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2017-09-01 18:59:42 +0000
+++ src/wui/interactive_base.cc	2017-09-02 19:46:13 +0000
@@ -167,7 +167,7 @@
 		Widelands::MapTriangleRegion<> mr(map, Area<TCoords<>>(center.triangle, sel_.radius));
 		do
 			field_overlay_manager_->register_overlay(
-			   mr.location(), sel_.pic, OverlayLevel::kSelection, Vector2i::invalid(), jobid);
+			   mr.location().node, sel_.pic, OverlayLevel::kSelection, Vector2i::invalid(), jobid);
 		while (mr.advance(map));
 	} else {
 		Widelands::MapRegion<> mr(map, Area<>(center.node, sel_.radius));

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2017-09-01 18:59:42 +0000
+++ src/wui/interactive_base.h	2017-09-02 19:46:13 +0000
@@ -224,9 +224,10 @@
 	struct SelData {
 		SelData(const bool Freeze = false,
 		        const bool Triangles = false,
-		        const Widelands::NodeAndTriangle<>& Pos = Widelands::NodeAndTriangle<>(
-		           Widelands::Coords(0, 0),
-		           Widelands::TCoords<>(Widelands::Coords(0, 0), Widelands::TriangleIndex::D)),
+		        const Widelands::NodeAndTriangle<>& Pos =
+		           Widelands::NodeAndTriangle<>{
+		              Widelands::Coords(0, 0),
+		              Widelands::TCoords<>(Widelands::Coords(0, 0), Widelands::TriangleIndex::D)},
 		        const uint32_t Radius = 0,
 		        const Image* Pic = nullptr,
 		        const FieldOverlayManager::OverlayId Jobid = 0)

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2017-09-02 18:28:08 +0000
+++ src/wui/interactive_player.cc	2017-09-02 19:46:13 +0000
@@ -282,9 +282,9 @@
 					//  fieldaction window before entering roadbuilding mode here.
 					fieldaction_.destroy();
 					map_view()->mouse_to_field(flag_to_connect_, MapView::Transition::Jump);
-					set_sel_pos(Widelands::NodeAndTriangle<>(
+					set_sel_pos(Widelands::NodeAndTriangle<>{
 					   flag_to_connect_,
-					   Widelands::TCoords<>(flag_to_connect_, Widelands::TriangleIndex::D)));
+					   Widelands::TCoords<>(flag_to_connect_, Widelands::TriangleIndex::D)});
 					start_build_road(flag_to_connect_, field.get_owned_by());
 				}
 			flag_to_connect_ = Widelands::Coords::null();

=== modified file 'src/wui/mapviewpixelfunctions.cc'
--- src/wui/mapviewpixelfunctions.cc	2017-08-30 13:35:37 +0000
+++ src/wui/mapviewpixelfunctions.cc	2017-09-02 19:46:13 +0000
@@ -118,7 +118,7 @@
 		x -= map_end_screen_x;
 	while (y >= map_end_screen_y)
 		y -= map_end_screen_y;
-	NodeAndTriangle<> result;
+	Coords result_node;
 
 	const uint16_t col_number = x / (kTriangleWidth / 2);
 	uint16_t row_number = y / kTriangleHeight, next_row_number;
@@ -172,11 +172,14 @@
 		}
 		if (upper_screen_dx * upper_screen_dx + upper_screen_dy * upper_screen_dy <
 		    lower_screen_dx * lower_screen_dx + lower_screen_dy * lower_screen_dy)
-			result.node = Coords(upper_x, row_number);
+			result_node = Coords(upper_x, row_number);
 		else
-			result.node = Coords(lower_x, next_row_number);
+			result_node = Coords(lower_x, next_row_number);
 	}
 
+	// This will be overwritten in all cases below.
+	TCoords<> result_triangle(Coords::null(), TriangleIndex::D);
+
 	//  Find out which of the 4 possible triangles (x, y) is in.
 	if (slash) {
 		int32_t Y_a =
@@ -190,14 +193,14 @@
 		assert(pdx > 0);
 		if (pdy * kTriangleWidth > ldy * pdx) {
 			//  (x, y) is in the upper triangle.
-			result.triangle = TCoords<>(
+			result_triangle = TCoords<>(
 			   Coords(left_col, (row_number == 0 ? mapheight : row_number) - 1), TriangleIndex::D);
 		} else {
 			Y_a = screen_y_base - map[Coords(left_col, next_row_number)].get_height() * kHeightFactor;
 			ldy = Y_b - Y_a;
 			if (pdy * (kTriangleWidth / 2) > ldy * pdx) {
 				//  (x, y) is in the second triangle.
-				result.triangle = TCoords<>(
+				result_triangle = TCoords<>(
 				   Coords((right_col == 0 ? mapwidth : right_col) - 1, row_number), TriangleIndex::R);
 			} else {
 				Y_b = screen_y_base -
@@ -209,10 +212,10 @@
 				pdx = (col_number + 2) * (kTriangleWidth / 2) - x;
 				if (pdy * kTriangleWidth > ldy * pdx) {
 					//  (x, y) is in the third triangle.
-					result.triangle = TCoords<>(Coords(right_col, row_number), TriangleIndex::D);
+					result_triangle = TCoords<>(Coords(right_col, row_number), TriangleIndex::D);
 				} else {
 					//  (x, y) is in the lower triangle.
-					result.triangle = TCoords<>(Coords(left_col, next_row_number), TriangleIndex::R);
+					result_triangle = TCoords<>(Coords(left_col, next_row_number), TriangleIndex::R);
 				}
 			}
 		}
@@ -228,7 +231,7 @@
 		assert(pdx > 0);
 		if (pdy * kTriangleWidth > ldy * pdx) {
 			//  (x, y) is in the upper triangle.
-			result.triangle = TCoords<>(
+			result_triangle = TCoords<>(
 			   Coords(right_col, (row_number == 0 ? mapheight : row_number) - 1), TriangleIndex::D);
 		} else {
 			Y_b = screen_y_base - map[Coords(right_col, next_row_number)].get_height() * kHeightFactor;
@@ -237,7 +240,7 @@
 			pdx = (col_number + 1) * (kTriangleWidth / 2) - x;
 			if (pdy * (kTriangleWidth / 2) > ldy * pdx) {
 				//  (x, y) is in the second triangle.
-				result.triangle = TCoords<>(Coords(left_col, row_number), TriangleIndex::R);
+				result_triangle = TCoords<>(Coords(left_col, row_number), TriangleIndex::R);
 			} else {
 				Y_a = screen_y_base -
 				      map[Coords((right_col == 0 ? mapwidth : right_col) - 1, next_row_number)]
@@ -246,18 +249,18 @@
 				ldy = Y_b - Y_a;
 				if (pdy * kTriangleWidth > ldy * pdx) {
 					//  (x, y) is in the third triangle.
-					result.triangle = TCoords<>(Coords(left_col, row_number), TriangleIndex::D);
+					result_triangle = TCoords<>(Coords(left_col, row_number), TriangleIndex::D);
 				} else {
 					//  (x, y) is in the lower triangle.
-					result.triangle =
+					result_triangle =
 					   TCoords<>(Coords((right_col == 0 ? mapwidth : right_col) - 1, next_row_number),
 					             TriangleIndex::R);
 				}
 			}
 		}
 	}
-
-	return result;
+	assert(result_triangle.node != Coords::null());
+	return NodeAndTriangle<>{result_node, result_triangle};
 }
 
 /**


Follow ups