← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/bug-1687100-reveal_fields into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1687100-reveal_fields into lp:widelands.

Commit message:
When the hide_completely option is not selected, LuaPlayer::hide_fields no longer hides fields that the player's buildings see. Added a matching option "show_completely" to LuaPlayer::reveal_fields.

Requested reviews:
  GunChleoc (gunchleoc)
  kaputtnik (franku)
Related bugs:
  Bug #1687100 in widelands: "Lua: reveal_fields after hide_fields(fields, hide_completely) does not respect seen fields"
  https://bugs.launchpad.net/widelands/+bug/1687100

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1687100-reveal_fields/+merge/323721

This was actually a long-standing bug - the function wasn't doing what the documentation described in the first place.

Can be tested by hacking the seafaring tutorial:


=== modified file 'data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua	2016-10-23 11:31:25 +0000
+++ data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua	2017-05-07 07:51:04 +0000
@@ -5,6 +5,14 @@
 function introduction()
    additional_port_space.terr = "summer_water" -- disable the port space
    sleep(1000)
+
+plr:reveal_fields(wl.Game().map:get_field(41,43):region(60))
+plr:hide_fields(wl.Game().map:get_field(41,43):region(40),true)
+
+plr:hide_fields(wl.Game().map:get_field(43,52):region(20),true)
+plr:reveal_fields(wl.Game().map:get_field(43,52):region(20))
+sleep(600000)
+
    message_box_objective(plr, intro_south)
    sleep(300)
    message_box_objective(plr, intro_north)


-- 
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/bug-1687100-reveal_fields.
=== modified file 'src/logic/map_objects/tribes/building.cc'
--- src/logic/map_objects/tribes/building.cc	2017-05-09 09:18:14 +0000
+++ src/logic/map_objects/tribes/building.cc	2017-05-20 08:43:36 +0000
@@ -714,6 +714,13 @@
 }
 
 /**
+ * Returns whether this building should see its vision range.
+ */
+bool Building::is_seeing() const {
+	return seeing_ || descr().type() == MapObjectType::WAREHOUSE;
+}
+
+/**
  * Send a message about this building to the owning player.
  *
  * It will have the building's coordinates, and display a picture of the

=== modified file 'src/logic/map_objects/tribes/building.h'
--- src/logic/map_objects/tribes/building.h	2017-05-06 19:21:47 +0000
+++ src/logic/map_objects/tribes/building.h	2017-05-20 08:43:36 +0000
@@ -235,6 +235,8 @@
 	}
 	PositionList get_positions(const EditorGameBase&) const override;
 
+	bool is_seeing() const;
+
 	std::string info_string(const InfoStringFormat& format);
 
 	// Return the overlay string that is displayed on the map view when enabled

=== modified file 'src/logic/player.h'
--- src/logic/player.h	2017-04-23 07:09:25 +0000
+++ src/logic/player.h	2017-05-20 08:43:36 +0000
@@ -150,7 +150,6 @@
 	// For cheating
 	void set_see_all(bool const t) {
 		see_all_ = t;
-		view_changed_ = true;
 	}
 	bool see_all() const {
 		return see_all_;
@@ -428,12 +427,6 @@
 		return (see_all_ ? 2 : 0) + fields_[i].vision;
 	}
 
-	bool has_view_changed() {
-		bool t = view_changed_;
-		view_changed_ = false;
-		return t;
-	}
-
 	/**
 	 * Update this player's information about this node and the surrounding
 	 * triangles and edges.
@@ -458,7 +451,6 @@
 		do {
 			see_node(map, first_map_field, mr.location(), gametime);
 		} while (mr.advance(map));
-		view_changed_ = true;
 	}
 
 	/// Decrement this player's vision for each node in an area.
@@ -470,7 +462,6 @@
 		do
 			unsee_node(mr.location().field - &first_map_field, gametime);
 		while (mr.advance(map));
-		view_changed_ = true;
 	}
 
 	MilitaryInfluence military_influence(MapIndex const i) const {
@@ -628,7 +619,6 @@
 	std::vector<Player*> team_player_;
 	bool team_player_uptodate_;
 	bool see_all_;
-	bool view_changed_;
 	const PlayerNumber player_number_;
 	const TribeDescr& tribe_;  // buildings, wares, workers, sciences
 	uint32_t casualties_, kills_;

=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc	2017-05-09 09:18:14 +0000
+++ src/scripting/lua_game.cc	2017-05-20 08:43:36 +0000
@@ -27,6 +27,7 @@
 #include "economy/flag.h"
 #include "logic/campaign_visibility.h"
 #include "logic/game_controller.h"
+#include "logic/map_objects/tribes/building.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
 #include "logic/message.h"
 #include "logic/objective.h"
@@ -593,6 +594,10 @@
       :arg fields: The fields to show
       :type fields: :class:`array` of :class:`wl.map.Fields`
 
+      :arg show_completely: *Optional*. The fields will be marked as explored as if a building was
+         seeing them. Always use this option if you hid the fields with the option `hide_completely`.
+      :type show_completely: :class:`boolean`
+
       :returns: :const:`nil`
 */
 int LuaPlayer::reveal_fields(lua_State* L) {
@@ -601,11 +606,17 @@
 	Map& m = egbase.map();
 
 	luaL_checktype(L, 2, LUA_TTABLE);
+	const bool bump_vision = (!lua_isnone(L, 3) && luaL_checkboolean(L, 3));
 
 	lua_pushnil(L); /* first key */
 	while (lua_next(L, 2) != 0) {
-		p.see_node(m, m[0], (*get_user_class<LuaField>(L, -1))->fcoords(L), egbase.get_gametime());
+		LuaField* field = *get_user_class<LuaField>(L, -1);
+		p.see_node(m, m[0], field->fcoords(L), egbase.get_gametime());
 		lua_pop(L, 1);
+		// Player should now see what the buildings see
+		if (bump_vision) {
+			p.see_node(m, m[0], field->fcoords(L), egbase.get_gametime());
+		}
 	}
 
 	return 0;
@@ -615,12 +626,13 @@
    .. method:: hide_fields(fields)
 
       Make these fields hidden for the current player if they are not
-      seen by a military building.
+      seen by a building.
 
       :arg fields: The fields to hide
       :type fields: :class:`array` of :class:`wl.map.Fields`
 
-      :arg hide_completely: *Optional*. The fields will be marked as unexplored.
+      :arg hide_completely: *Optional*. The fields will be marked as unexplored and the buildings' vision
+         ignored. When you reveal the fields again, use the option `show_completely`.
       :type hide_completely: :class:`boolean`
 
       :returns: :const:`nil`
@@ -631,16 +643,34 @@
 	Map& m = egbase.map();
 
 	luaL_checktype(L, 2, LUA_TTABLE);
-	const bool mode = !lua_isnone(L, 3) && luaL_checkboolean(L, 3);
+	const Player::UnseeNodeMode mode = (!lua_isnone(L, 3) && luaL_checkboolean(L, 3)) ?
+	                                      Player::UnseeNodeMode::kUnexplore :
+	                                      Player::UnseeNodeMode::kUnsee;
 
 	lua_pushnil(L); /* first key */
 	while (lua_next(L, 2) != 0) {
-		p.unsee_node((*get_user_class<LuaField>(L, -1))->fcoords(L).field - &m[0],
-		             egbase.get_gametime(),
-		             mode ? Player::UnseeNodeMode::kUnexplore : Player::UnseeNodeMode::kUnsee);
+		p.unsee_node(
+		   (*get_user_class<LuaField>(L, -1))->fcoords(L).field - &m[0], egbase.get_gametime(), mode);
 		lua_pop(L, 1);
 	}
 
+	if (mode == Player::UnseeNodeMode::kUnsee) {
+		// Player should still see what the buildings see
+		for (const auto& building_index : p.tribe().buildings()) {
+			const std::vector<Player::BuildingStats>& stats_vector =
+			   p.get_building_statistics(building_index);
+			for (size_t i = 0; i < stats_vector.size(); ++i) {
+				const BaseImmovable* immovable = m[stats_vector[i].pos].get_immovable();
+				if (upcast(const Widelands::Building, building, immovable)) {
+					if (building->is_seeing()) {
+						p.see_area(Area<FCoords>(
+						   m.get_fcoords(building->get_position()), building->descr().vision_range()));
+					}
+				}
+			}
+		}
+	}
+
 	return 0;
 }
 


References