From 07b122fefe4a23d5a841db6dd1197708386a7933 Mon Sep 17 00:00:00 2001
From: Yona-TYT <yonatan.el.amigo@gmail.com>
Date: Sat, 30 Nov 2024 23:08:09 -0400
Subject: [PATCH] Experiment with an allow rule

---
 src/simutrans/dataobj/scenario.cc        | 21 +++++++++++++++++----
 src/simutrans/dataobj/scenario.h         | 15 ++++++++++++---
 src/simutrans/script/api/api_scenario.cc |  2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/simutrans/dataobj/scenario.cc b/src/simutrans/dataobj/scenario.cc
index 06fa5fa5e..c1d3c5d77 100644
--- a/src/simutrans/dataobj/scenario.cc
+++ b/src/simutrans/dataobj/scenario.cc
@@ -402,14 +402,14 @@ void scenario_t::allow_tool(uint8 player_nr, uint16 tool_id)
 
 void scenario_t::forbid_way_tool(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param)
 {
-	forbidden_t *test = new forbidden_t(forbidden_t::forbid_tool, tool_id, wt, param);
+	forbidden_t *test = new forbidden_t(forbidden_t::forbid_tool, false, tool_id, wt, param);
 	call_forbid_tool(test, player_nr, true);
 }
 
 
 void scenario_t::allow_way_tool(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param)
 {
-	forbidden_t *test = new forbidden_t(forbidden_t::forbid_tool, tool_id, wt, param);
+	forbidden_t *test = new forbidden_t(forbidden_t::forbid_tool, false, tool_id, wt, param);
 	call_forbid_tool(test, player_nr, false);
 }
 
@@ -425,8 +425,19 @@ void scenario_t::allow_way_tool_rect(uint8 player_nr, uint16 tool_id, waytype_t
 	allow_way_tool_cube(player_nr, tool_id, wt, param, koord3d(pos_nw, -128), koord3d(pos_se, 127));
 }
 
+void scenario_t::allow_test_way_tool_rect(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord pos_nw, koord pos_se)
+{
+	intern_forbid_way_tool_cube(player_nr, tool_id, wt, param, koord3d(pos_nw, -128), koord3d(pos_se, 127), (plainstring)"", true);
+}
+
+
+void scenario_t::forbid_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord3d pos_nw, koord3d pos_se, plainstring err)
+{
+	intern_forbid_way_tool_cube(player_nr, tool_id, wt, param, pos_nw, pos_se, err, false);
+}
 
-void scenario_t::forbid_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord3d pos_nw_0, koord3d pos_se_0, plainstring err)
+
+void scenario_t::intern_forbid_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord3d pos_nw_0, koord3d pos_se_0, plainstring err, bool allow)
 {
 	koord pos_nw( min(pos_nw_0.x, pos_se_0.x), min(pos_nw_0.y, pos_se_0.y));
 	koord pos_se( max(pos_nw_0.x, pos_se_0.x), max(pos_nw_0.y, pos_se_0.y));
@@ -435,6 +446,7 @@ void scenario_t::forbid_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t
 
 	forbidden_t *test = new forbidden_t(tool_id, wt, param, pos_nw, pos_se, hmin, hmax);
 	test->error = err;
+	test->allow = allow;
 	call_forbid_tool(test, player_nr, true);
 }
 
@@ -451,6 +463,7 @@ void scenario_t::allow_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t
 }
 
 
+
 void scenario_t::clear_rules()
 {
 	for (uint pnr = 0; pnr < MAX_PLAYER_COUNT; pnr++) {
@@ -562,7 +575,7 @@ const char* scenario_t::is_work_allowed_here(const player_t* player, uint16 tool
 								if (err == NULL) {
 									err = "";
 								}
-								return err;
+								return f.allow? NULL : err;
 							}
 						}
 					}
diff --git a/src/simutrans/dataobj/scenario.h b/src/simutrans/dataobj/scenario.h
index fb58d4f09..79a91c7ca 100644
--- a/src/simutrans/dataobj/scenario.h
+++ b/src/simutrans/dataobj/scenario.h
@@ -95,12 +95,16 @@ private:

 		forbid_type type;
 		/// id of tool to be forbidden, as set by constructors of classes derived from
 		/// tool_t, @see tool/simtool.h
+		bool allow;
+
 		uint16 toolnr;
 		/// waytype of tool, @see waytype_t
 		sint16 waytype;
@@ -111,8 +115,8 @@ private:
 		plainstring error;
 
 		/// constructor: forbid tool/etc for a certain player
-		forbidden_t(forbid_type type_=forbid_tool, uint16 toolnr_=0, sint16 waytype_=invalid_wt, const char *param_=NULL) :
-			type(type_), toolnr(toolnr_), waytype(waytype_),
+		forbidden_t(forbid_type type_=forbid_tool, bool allow_ = false, uint16 toolnr_=0, sint16 waytype_=invalid_wt, const char *param_=NULL) :
+			type(type_), allow(allow_), toolnr(toolnr_), waytype(waytype_),
 			pos_nw(koord::invalid), pos_se(koord::invalid), hmin(-128), hmax(127), error()
 		{
 			parameter_hash = string_to_hash(param_);
@@ -163,6 +167,7 @@ private:
 			file->rdwr_byte(hmin);
 			file->rdwr_byte(hmax);
 			file->rdwr_str(error);
+			file->rdwr_bool(allow);
 		}
 
 		void rotate90(const sint16 y_size);
@@ -205,6 +210,8 @@ private:
 	 */
 	void intern_forbid(forbidden_t *test, uint player_nr, bool forbid);
 
+	void intern_forbid_way_tool_cube(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord3d pos_nw, koord3d pos_se, plainstring err, bool allow);
+
 	/**
 	 * Helper function: works on forbidden_tools directly (if not in network-mode)
 	 * or sends information over network (if at server)
@@ -397,6 +404,8 @@ public:
 	 */
 	void allow_way_tool_rect(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord pos_nw, koord pos_se);
 
+	void allow_test_way_tool_rect(uint8 player_nr, uint16 tool_id, waytype_t wt, const char* param, koord pos_nw, koord pos_se);
+
 	/**
 	 * Forbid tool with certain waytype within cubic region on the map.
 	 * @ingroup squirrel-api
diff --git a/src/simutrans/script/api/api_scenario.cc b/src/simutrans/script/api/api_scenario.cc
index 8585b442d..29143a101 100644
--- a/src/simutrans/script/api/api_scenario.cc
+++ b/src/simutrans/script/api/api_scenario.cc
@@ -219,6 +219,8 @@ void export_scenario(HSQUIRRELVM vm)
 	 */
 	STATIC register_method(vm, &scenario_t::allow_way_tool_rect,  "allow_way_tool_rect");
 
+	STATIC register_method(vm, &scenario_t::allow_test_way_tool_rect,  "allow_test_way_tool_rect");
+
 	/**
 	 * Forbid tool with certain waytype within cubic region on the map.
 	 *
-- 
2.47.1

