← Back to team overview

widelands-dev team mailing list archive

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

 

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

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #977980 in widelands: "Fish and mountain ressources cannot be removed when they are on grass"
  https://bugs.launchpad.net/widelands/+bug/977980

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

Fixes bug 977980 - display of overlays. 

I decided on a slightly more involve fix that added some symmetry between resources and terrains to the code and decoupled UI from logic through the use of notifications. 
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/fix_resource_overlay into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2016-01-10 11:36:05 +0000
+++ src/editor/editorinteractive.cc	2016-01-14 22:10:38 +0000
@@ -62,6 +62,27 @@
 	egbase->tribes();
 }
 
+// Updates the resources overlays after a field has changed.
+void update_resource_overlay(const Widelands::NoteFieldResourceChanged& note,
+                             const Widelands::World& world,
+                             FieldOverlayManager* field_overlay_manager) {
+	//  Ok, we're doing something. First remove the current overlays.
+	if (note.old_resource != Widelands::kNoResource) {
+		const std::string str =
+		   world.get_resource(note.old_resource)->get_editor_pic(note.old_amount);
+		const Image* pic = g_gr->images().get(str);
+		field_overlay_manager->remove_overlay(note.fc, pic);
+	}
+
+	const auto amount = note.fc.field->get_resources_amount();
+	if (amount > 0) {
+		const std::string str =
+		   world.get_resource(note.fc.field->get_resources())->get_editor_pic(amount);
+		const Image* pic = g_gr->images().get(str);
+		field_overlay_manager->register_overlay(note.fc, pic, 0);
+	}
+}
+
 }  // namespace
 
 EditorInteractive::EditorInteractive(Widelands::EditorGameBase & e) :
@@ -134,6 +155,13 @@
 #endif
 
 	fieldclicked.connect(boost::bind(&EditorInteractive::map_clicked, this, false));
+
+	// Subscribe to changes of the resource type on a field..
+	field_resource_changed_subscriber_ =
+	   Notifications::subscribe<Widelands::NoteFieldResourceChanged>(
+	      [this](const Widelands::NoteFieldResourceChanged& note) {
+		      update_resource_overlay(note, egbase().world(), mutable_field_overlay_manager());
+		   });
 }
 
 void EditorInteractive::register_overlays() {

=== modified file 'src/editor/editorinteractive.h'
--- src/editor/editorinteractive.h	2016-01-07 12:47:17 +0000
+++ src/editor/editorinteractive.h	2016-01-14 22:10:38 +0000
@@ -20,6 +20,8 @@
 #ifndef WL_EDITOR_EDITORINTERACTIVE_H
 #define WL_EDITOR_EDITORINTERACTIVE_H
 
+#include <memory>
+
 #include "editor/tools/editor_history.h"
 #include "editor/tools/editor_increase_height_tool.h"
 #include "editor/tools/editor_increase_resources_tool.h"
@@ -32,6 +34,8 @@
 #include "editor/tools/editor_set_port_space_tool.h"
 #include "editor/tools/editor_set_starting_pos_tool.h"
 #include "editor/tools/editor_set_terrain_tool.h"
+#include "logic/map.h"
+#include "notifications/notifications.h"
 #include "ui_basic/button.h"
 #include "ui_basic/unique_window.h"
 #include "wui/interactive_base.h"
@@ -140,6 +144,8 @@
 
 	EditorHistory m_history;
 
+	std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldResourceChanged>>
+	   field_resource_changed_subscriber_;
 	UI::UniqueWindow::Registry m_toolmenu;
 
 	UI::UniqueWindow::Registry m_toolsizemenu;

=== modified file 'src/editor/map_generator.cc'
--- src/editor/map_generator.cc	2016-01-06 19:11:20 +0000
+++ src/editor/map_generator.cc	2016-01-14 22:10:38 +0000
@@ -134,8 +134,7 @@
 		res_val *= static_cast<uint8_t>(map_info_.resource_amount) + 1;
 		res_val /= 3;
 		if (map_.is_resource_valid(world, fc, res_idx)) {
-			fc.field->set_resources(res_idx, res_val);
-			fc.field->set_initial_res_amount(res_val);
+			map_.initialize_resources(fc, res_idx, res_val);
 		}
 	};
 

=== modified file 'src/editor/tools/editor_decrease_resources_tool.cc'
--- src/editor/tools/editor_decrease_resources_tool.cc	2016-01-10 11:36:05 +0000
+++ src/editor/tools/editor_decrease_resources_tool.cc	2016-01-14 22:10:38 +0000
@@ -36,7 +36,7 @@
 */
 int32_t EditorDecreaseResourcesTool::handle_click_impl(const Widelands::World& world,
                                                        Widelands::NodeAndTriangle<> const center,
-                                                       EditorInteractive& parent,
+                                                       EditorInteractive& /* parent */,
                                                        EditorActionArgs* args,
                                                        Widelands::Map* map) {
 	Widelands::MapRegion<Widelands::Area<Widelands::FCoords> > mr
@@ -54,8 +54,7 @@
 			map->is_resource_valid(world, mr.location(), args->cur_res)) {
 			args->orgResT.push_back(mr.location().field->get_resources());
 			args->orgRes.push_back(mr.location().field->get_resources_amount());
-			EditorSetResourcesTool::set_res_and_overlay(world, amount, args->cur_res, mr.location(),
-			                                            parent.mutable_field_overlay_manager(), map);
+			map->initialize_resources(mr.location(), args->cur_res, amount);
 		}
 
 	} while (mr.advance(*map));

=== modified file 'src/editor/tools/editor_increase_resources_tool.cc'
--- src/editor/tools/editor_increase_resources_tool.cc	2016-01-10 11:36:05 +0000
+++ src/editor/tools/editor_increase_resources_tool.cc	2016-01-14 22:10:38 +0000
@@ -31,7 +31,7 @@
 
 int32_t EditorIncreaseResourcesTool::handle_click_impl(const Widelands::World& world,
                                                        Widelands::NodeAndTriangle<> const center,
-                                                       EditorInteractive& parent,
+                                                       EditorInteractive& /* parent */,
                                                        EditorActionArgs* args,
                                                        Widelands::Map* map) {
 	Widelands::MapRegion<Widelands::Area<Widelands::FCoords> > mr
@@ -52,8 +52,7 @@
 				map->is_resource_valid(world, mr.location(), args->cur_res)) {
 			args->orgResT.push_back(mr.location().field->get_resources());
 			args->orgRes.push_back(mr.location().field->get_resources_amount());
-			EditorSetResourcesTool::set_res_and_overlay(world, amount, args->cur_res, mr.location(),
-			                                            parent.mutable_field_overlay_manager(), map);
+			map->initialize_resources(mr.location(), args->cur_res, amount);
 		}
 	} while (mr.advance(*map));
 	return mr.radius();

=== modified file 'src/editor/tools/editor_set_resources_tool.cc'
--- src/editor/tools/editor_set_resources_tool.cc	2016-01-10 11:36:05 +0000
+++ src/editor/tools/editor_set_resources_tool.cc	2016-01-14 22:10:38 +0000
@@ -27,11 +27,10 @@
 #include "logic/map_objects/world/resource_description.h"
 #include "logic/map_objects/world/world.h"
 #include "logic/mapregion.h"
-#include "wui/field_overlay_manager.h"
 
 int32_t EditorSetResourcesTool::handle_click_impl(const Widelands::World& world,
                                                   Widelands::NodeAndTriangle<> const center,
-                                                  EditorInteractive& parent,
+                                                  EditorInteractive& /* parent */,
                                                   EditorActionArgs* args,
                                                   Widelands::Map* map) {
 	Widelands::MapRegion<Widelands::Area<Widelands::FCoords> > mr
@@ -50,8 +49,7 @@
 		if (map->is_resource_valid(world, mr.location(), args->cur_res)) {
 			args->orgResT.push_back(mr.location().field->get_resources());
 			args->orgRes.push_back(mr.location().field->get_resources_amount());
-			set_res_and_overlay(world, amount, args->cur_res, mr.location(),
-			                    parent.mutable_field_overlay_manager(), map);
+			map->initialize_resources(mr.location(), args->cur_res, amount);
 		}
 	} while (mr.advance(*map));
 	return mr.radius();
@@ -60,7 +58,7 @@
 int32_t
 EditorSetResourcesTool::handle_undo_impl(const Widelands::World& world,
                                          Widelands::NodeAndTriangle<Widelands::Coords> center,
-                                         EditorInteractive& parent,
+                                         EditorInteractive& /* parent */,
                                          EditorActionArgs* args,
                                          Widelands::Map* map) {
 	Widelands::MapRegion<Widelands::Area<Widelands::FCoords> > mr
@@ -77,9 +75,7 @@
 		if (amount > max_amount)
 			amount = max_amount;
 
-		set_res_and_overlay(
-		   world, amount, *ir, mr.location(), parent.mutable_field_overlay_manager(), map);
-
+		map->initialize_resources(mr.location(), *it, amount);
 		++ir;
 		++it;
 	} while (mr.advance(*map));
@@ -95,33 +91,3 @@
 	a.set_to = m_set_to;
 	return a;
 }
-
-void EditorSetResourcesTool::set_res_and_overlay(const Widelands::World& world,
-											int32_t amount, uint8_t new_res,
-											const Widelands::FCoords& fcoords,
-											FieldOverlayManager* field_overlay_manager,
-											Widelands::Map* map) {
-	int32_t old_res = fcoords.field->get_resources();
-
-
-	//  Ok, we're doing something. First remove the current overlays.
-	if (old_res != Widelands::kNoResource) {
-		std::string str = world.get_resource(old_res)->get_editor_pic(
-				fcoords.field->get_resources_amount());
-		const Image* pic = g_gr->images().get(str);
-		field_overlay_manager->remove_overlay(fcoords, pic);
-	}
-
-	if (!amount) {
-		fcoords.field->set_resources(Widelands::kNoResource, 0);
-		fcoords.field->set_initial_res_amount(0);
-	} else {
-		fcoords.field->set_resources(new_res, amount);
-		fcoords.field->set_initial_res_amount(amount);
-		//  set new overlay
-		std::string str = world.get_resource(new_res)->get_editor_pic(amount);
-		const Image* pic = g_gr->images().get(str);
-		field_overlay_manager->register_overlay(fcoords, pic, 0);
-		map->recalc_for_field_area(world, Widelands::Area<Widelands::FCoords>(fcoords, 0));
-	}
-}

=== modified file 'src/editor/tools/editor_set_resources_tool.h'
--- src/editor/tools/editor_set_resources_tool.h	2016-01-10 11:36:05 +0000
+++ src/editor/tools/editor_set_resources_tool.h	2016-01-14 22:10:38 +0000
@@ -23,7 +23,6 @@
 #include "editor/tools/editor_tool.h"
 #include "logic/mapregion.h"
 #include "logic/widelands.h"
-#include "wui/field_overlay_manager.h"
 
 ///  Decreases the resources of a node by a value.
 struct EditorSetResourcesTool : public EditorTool {
@@ -48,16 +47,6 @@
 
 	EditorActionArgs format_args_impl(EditorInteractive & parent) override;
 
-	/**
-	 * Sets the resource amount and updates the overlay.
-	 */
-	static void set_res_and_overlay(const Widelands::World& world,
-	                                int32_t amount,
-	                                uint8_t resIx,
-	                                const Widelands::FCoords& fcoords,
-	                                FieldOverlayManager* field_overlay_manager,
-	                                Widelands::Map* map);
-
 	char const * get_sel_impl() const override {
 		return "pics/fsel_editor_set_resources.png";
 	}

=== modified file 'src/logic/field.h'
--- src/logic/field.h	2016-01-07 12:47:17 +0000
+++ src/logic/field.h	2016-01-14 22:10:38 +0000
@@ -199,18 +199,10 @@
 		roads |= type << dir;
 	}
 
+	// Resources can be set through Map::set_resources()
 	// TODO(unknown): This should return DescriptionIndex
 	uint8_t get_resources() const {return m_resources;}
 	uint8_t get_resources_amount() const {return m_res_amount;}
-	void set_resources(uint8_t const res, uint8_t const amount) {
-		m_resources  = res;
-		m_res_amount = amount;
-	}
-
-	// TODO(unknown): This should take uint8_t
-	void set_initial_res_amount(int32_t const amount) {
-		m_initial_res_amount = amount;
-	}
 	// TODO(unknown): This should return uint8_t
 	int32_t get_initial_res_amount() const {return m_initial_res_amount;}
 

=== modified file 'src/logic/map.cc'
--- src/logic/map.cc	2016-01-10 11:36:05 +0000
+++ src/logic/map.cc	2016-01-14 22:10:38 +0000
@@ -250,11 +250,9 @@
 			amount /= 6;
 
 			if (res == -1 || !amount) {
-				f.field->set_resources(Widelands::kNoResource, 0);
-				f.field->set_initial_res_amount(0);
+				clear_resources(f);
 			} else {
-				f.field->set_resources(res, amount);
-				f.field->set_initial_res_amount(amount);
+				initialize_resources(f, res, amount);
 			}
 
 		}
@@ -322,12 +320,13 @@
 		Field::Terrains default_terrains;
 		default_terrains.d = default_terrain;
 		default_terrains.r = default_terrain;
-		Field * field = m_fields.get();
-		const Field * const fields_end = field + max_index();
-		for (; field < fields_end; ++field) {
-			field->set_height(10);
-			field->set_terrains(default_terrains);
-			field->set_resources(Widelands::kNoResource, 0);
+		for (int16_t y = 0; y < m_height; ++y) {
+			for (int16_t x = 0; x < m_width; ++x) {
+				auto f = get_fcoords(Coords(x, y));
+				f.field->set_height(10);
+				f.field->set_terrains(default_terrains);
+				clear_resources(f);
+			}
 		}
 	}
 	recalc_whole_map(world);
@@ -1837,24 +1836,25 @@
 	// remove invalid resources if necessary
 	// check vertex to which the triangle belongs
 	if (!is_resource_valid(world, c, c.field->get_resources())){
-		c.field->set_resources(Widelands::kNoResource, 0);
+		clear_resources(c);
 	}
 
 	// always check south-east vertex
 	Widelands::FCoords f_se(c, c.field);
 	get_neighbour(f_se, Widelands::WALK_SE, &f_se);
 	if (!is_resource_valid(world, f_se, f_se.field->get_resources())){
-		f_se.field->set_resources(Widelands::kNoResource, 0);
+		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 == TCoords<FCoords>::D ? Widelands::WALK_SW : Widelands::WALK_E, &f_sw_e);
 	if (!is_resource_valid(world, f_sw_e, f_sw_e.field->get_resources())){
-		f_sw_e.field->set_resources(Widelands::kNoResource, 0);
+		clear_resources(f_sw_e);
 	}
 
-	Notifications::publish(NoteFieldTransformed(c, c.field - &m_fields[0]));
+	Notifications::publish(
+	   NoteFieldTerrainChanged{c, static_cast<MapIndex>(c.field - &m_fields[0])});
 
 	recalc_for_field_area(world, Area<FCoords>(c, 2));
 
@@ -1895,11 +1895,40 @@
 
 void Map::ensure_resource_consistency(const World& world)
 {
-	for (MapIndex i = 0; i < max_index(); ++i)
-		if (!is_resource_valid(world, get_fcoords(m_fields[i]), m_fields[i].get_resources()))
-			m_fields[i].set_resources(Widelands::kNoResource, 0);
-}
-
+	for (MapIndex i = 0; i < max_index(); ++i) {
+		auto fcords = get_fcoords(m_fields[i]);
+		if (!is_resource_valid(world, fcords, fcords.field->get_resources())) {
+			clear_resources(fcords);
+		}
+	}
+}
+
+void Map::initialize_resources(const FCoords& c,
+                               const DescriptionIndex resource_type,
+                               const uint8_t amount) {
+	const auto note = NoteFieldResourceChanged{
+	   c, c.field->m_resources, c.field->m_initial_res_amount, c.field->m_res_amount,
+	};
+
+	c.field->m_resources = resource_type;
+	c.field->m_initial_res_amount = amount;
+	c.field->m_res_amount = amount;
+	Notifications::publish(note);
+}
+
+void Map::set_resources(const FCoords& c, uint8_t amount) {
+	assert(c.field->m_resources != Widelands::kNoResource);
+	assert(amount <= c.field->m_initial_res_amount);
+	const auto note = NoteFieldResourceChanged{
+	   c, c.field->m_resources, c.field->m_initial_res_amount, c.field->m_res_amount,
+	};
+	c.field->m_res_amount = amount;
+	Notifications::publish(note);
+}
+
+void Map::clear_resources(const FCoords& c) {
+	initialize_resources(c, Widelands::kNoResource, 0);
+}
 
 uint32_t Map::set_height(const World& world, const FCoords fc, uint8_t const new_value) {
 	assert(new_value <= MAX_FIELD_HEIGHT);

=== modified file 'src/logic/map.h'
--- src/logic/map.h	2016-01-10 11:36:05 +0000
+++ src/logic/map.h	2016-01-14 22:10:38 +0000
@@ -68,15 +68,21 @@
 struct Path;
 class Immovable;
 
-struct NoteFieldTransformed {
-	CAN_BE_SENT_AS_NOTE(NoteId::FieldTransformed)
+struct NoteFieldTerrainChanged {
+	CAN_BE_SENT_AS_NOTE(NoteId::FieldTerrainChanged)
 
 	FCoords fc;
 	MapIndex map_index;
-
-	NoteFieldTransformed(const FCoords& init_fc, const MapIndex init_map_index)
-	   : fc(init_fc), map_index(init_map_index) {
-	}
+};
+
+/// Send when the resource of a field is changed.
+struct NoteFieldResourceChanged {
+	CAN_BE_SENT_AS_NOTE(NoteId::FieldResourceTypeChanged)
+
+	FCoords fc;
+	DescriptionIndex old_resource;
+	uint8_t old_initial_amount;
+	uint8_t old_amount;
 };
 
 struct ImmovableFound {
@@ -362,6 +368,18 @@
 	/// Changes the height of the nodes in an Area by a difference.
 	uint32_t change_height(const World& world, Area<FCoords>, int16_t difference);
 
+	/// Initializes the initial_resources on 'coords' to the 'resource_type'
+	/// with the given amount.
+	void initialize_resources(const FCoords& coords, DescriptionIndex resource_type, uint8_t amount);
+
+	/// Sets the resource of the field to the current value. The type of the
+	/// resource on this field is not changed.
+	void set_resources(const FCoords& coords, uint8_t amount);
+
+	/// Clears the resources, i.e. the amount will be set to 0 and the type of
+	/// resources will be kNoResource.
+	void clear_resources(const FCoords& coords);
+
 	/**
 	 * Ensures that the height of each node within radius from fc is in
 	 * height_interval. If the height is < height_interval.min, it is changed to

=== modified file 'src/logic/map_objects/tribes/production_program.cc'
--- src/logic/map_objects/tribes/production_program.cc	2016-01-12 21:25:20 +0000
+++ src/logic/map_objects/tribes/production_program.cc	2016-01-14 22:10:38 +0000
@@ -1309,8 +1309,7 @@
 					assert(amount > 0);
 
 					--amount;
-
-					mr.location().field->set_resources(m_resource, amount);
+					map.set_resources(mr.location(), amount);
 					break;
 				}
 			} while (mr.advance(map));

=== modified file 'src/logic/map_objects/tribes/worker.cc'
--- src/logic/map_objects/tribes/worker.cc	2016-01-06 19:11:20 +0000
+++ src/logic/map_objects/tribes/worker.cc	2016-01-14 22:10:38 +0000
@@ -176,7 +176,7 @@
 			assert(amount > 0);
 
 			--amount;
-			mr.location().field->set_resources(res, amount);
+			map.set_resources(mr.location(), amount);
 			break;
 		}
 	} while (mr.advance(map));
@@ -286,9 +286,7 @@
 			assert(amount > 0);
 
 			--amount;
-
-			mr.location().field->set_resources
-				(res, mr.location().field->get_initial_res_amount() - amount);
+			map.set_resources(mr.location(), mr.location().field->get_initial_res_amount() - amount);
 			break;
 		}
 	} while (mr.advance(map));

=== modified file 'src/logic/player.cc'
--- src/logic/player.cc	2016-01-06 19:11:20 +0000
+++ src/logic/player.cc	2016-01-14 22:10:38 +0000
@@ -194,9 +194,9 @@
 			}
 		});
 
-	// Subscribe to NoteFieldTransformed.
-	field_transformed_subscriber_ =
-		Notifications::subscribe<NoteFieldTransformed>([this](const NoteFieldTransformed& note) {
+	// Subscribe to NoteFieldTerrainChanged.
+	field_terrain_changed_subscriber_ =
+		Notifications::subscribe<NoteFieldTerrainChanged>([this](const NoteFieldTerrainChanged& note) {
 			if (vision(note.map_index) > 1) {
 				rediscover_node(egbase().map(), egbase().map()[0], note.fc);
 			}

=== modified file 'src/logic/player.h'
--- src/logic/player.h	2016-01-06 19:11:20 +0000
+++ src/logic/player.h	2016-01-14 22:10:38 +0000
@@ -538,7 +538,8 @@
 	void rediscover_node(const Map&, const Widelands::Field&, FCoords);
 
 	std::unique_ptr<Notifications::Subscriber<NoteImmovable>> immovable_subscriber_;
-	std::unique_ptr<Notifications::Subscriber<NoteFieldTransformed>> field_transformed_subscriber_;
+	std::unique_ptr<Notifications::Subscriber<NoteFieldTerrainChanged>>
+	   field_terrain_changed_subscriber_;
 
 	MessageQueue           m_messages;
 

=== modified file 'src/map_io/map_resources_packet.cc'
--- src/map_io/map_resources_packet.cc	2015-11-28 22:29:26 +0000
+++ src/map_io/map_resources_packet.cc	2016-01-14 22:10:38 +0000
@@ -85,8 +85,7 @@
 
 					if (0xa < set_id)
 						throw "Unknown resource in map file. It is not in world!\n";
-					map[Coords(x, y)].set_resources(set_id, set_amount);
-					map[Coords(x, y)].set_initial_res_amount(set_start_amount);
+					map.initialize_resources(map.get_fcoords(Coords(x, y)), set_id, set_amount);
 				}
 			}
 		} else {

=== modified file 'src/map_io/s2map.cc'
--- src/map_io/s2map.cc	2015-11-29 09:43:15 +0000
+++ src/map_io/s2map.cc	2016-01-14 22:10:38 +0000
@@ -617,19 +617,19 @@
 	if (!section)
 		throw wexception("Section 12 (Resources) not found");
 
-	f = m_map.m_fields.get();
 	pc = section.get();
 	char const * res;
 	int32_t amount = 0;
-	for (uint16_t y = 0; y < mapheight; ++y)
-		for (uint16_t x = 0; x < mapwidth; ++x, ++f, ++pc) {
-			uint8_t c = *pc;
+	for (uint16_t y = 0; y < mapheight; ++y) {
+		for (uint16_t x = 0; x < mapwidth; ++x, ++pc) {
+			auto c = m_map.get_fcoords(Widelands::Coords(x, y));
+			uint8_t value = *pc;
 
-			switch (c & 0xF8) {
-			case 0x40: res = "coal";    amount = c & 7; break;
-			case 0x48: res = "iron";    amount = c & 7; break;
-			case 0x50: res = "gold";    amount = c & 7; break;
-			case 0x59: res = "granite"; amount = c & 7; break;
+			switch (value & 0xF8) {
+			case 0x40: res = "coal";    amount = value & 7; break;
+			case 0x48: res = "iron";    amount = value & 7; break;
+			case 0x50: res = "gold";    amount = value & 7; break;
+			case 0x59: res = "granite"; amount = value & 7; break;
 			default:   res = "";        amount = 0; break;
 			};
 
@@ -644,9 +644,9 @@
 			}
 			const int32_t real_amount = static_cast<int32_t>
 				(2.86 * static_cast<float>(amount));
-			f->set_resources(nres, real_amount);
-			f->set_initial_res_amount(real_amount);
+			m_map.initialize_resources(c, nres, real_amount);
 		}
+	}
 
 
 

=== modified file 'src/notifications/note_ids.h'
--- src/notifications/note_ids.h	2015-05-20 19:17:56 +0000
+++ src/notifications/note_ids.h	2016-01-14 22:10:38 +0000
@@ -30,7 +30,8 @@
 	LogMessage,
 	Immovable,
 	FieldPossession,
-	FieldTransformed,
+	FieldTerrainChanged,
+	FieldResourceTypeChanged,
 	ProductionSiteOutOfResources,
 	TrainingSiteSoldierTrained,
 	ShipMessage,

=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc	2016-01-06 19:11:20 +0000
+++ src/scripting/lua_map.cc	2016-01-14 22:10:38 +0000
@@ -4442,15 +4442,18 @@
 	return 1;
 }
 int LuaField::set_resource(lua_State * L) {
-	Field * field = fcoords(L).field;
+	auto& egbase = get_egbase(L);
 	int32_t res = get_egbase(L).world().get_resource
 		(luaL_checkstring(L, -1));
 
 	if (res == Widelands::INVALID_INDEX)
 		report_error(L, "Illegal resource: '%s'", luaL_checkstring(L, -1));
 
-	field->set_resources(res, field->get_resources_amount());
-
+	auto c = fcoords(L);
+	const auto current_amount = c.field->get_resources_amount();
+	auto& map = egbase.map();
+	map.initialize_resources(c, res, c.field->get_initial_res_amount());
+	map.set_resources(c, current_amount);
 	return 0;
 }
 
@@ -4466,8 +4469,8 @@
 	return 1;
 }
 int LuaField::set_resource_amount(lua_State * L) {
-	Field * field = fcoords(L).field;
-	int32_t res = field->get_resources();
+	auto c  = fcoords(L);
+	int32_t res = c.field->get_resources();
 	int32_t amount = luaL_checkint32(L, -1);
 	const ResourceDescription * resDesc = get_egbase(L).world().get_resource(res);
 	int32_t max_amount = resDesc ? resDesc->max_amount() : 0;
@@ -4475,14 +4478,14 @@
 	if (amount < 0 || amount > max_amount)
 		report_error(L, "Illegal amount: %i, must be >= 0 and <= %i", amount, max_amount);
 
-	field->set_resources(res, amount);
-	//in editor, reset also initial amount
 	EditorGameBase & egbase = get_egbase(L);
-	upcast(Game, game, &egbase);
-	if (!game) {
-		field->set_initial_res_amount(amount);
+	auto& map = egbase.map();
+	if(is_a(Game, &egbase)) {
+		map.set_resources(c, amount);
+	} else {
+		// in editor, reset also initial amount
+		map.initialize_resources(c, res, amount);
 	}
-
 	return 0;
 }
 /* RST


Follow ups