(svn r13410) [NoAI] -Add: functions to perform town actions (advertising, bribing, building statues, etc). noai
authorrubidium
Sun, 08 Jun 2008 10:37:30 +0000
branchnoai
changeset 10859 4c14a8041c0a
parent 10856 c7b29152d594
child 10863 7b31d67e1553
(svn r13410) [NoAI] -Add: functions to perform town actions (advertising, bribing, building statues, etc).
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
src/ai/api/ai_town.cpp
src/ai/api/ai_town.hpp
src/ai/api/ai_town.hpp.sq
--- a/bin/ai/regression/regression.nut	Sat Jun 07 23:30:41 2008 +0000
+++ b/bin/ai/regression/regression.nut	Sun Jun 08 10:37:30 2008 +0000
@@ -1036,10 +1036,21 @@
 	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
 		print("    " + i + " => " + list.GetValue(i));
 	}
+
+	print("  HasStatue():                     " + AITown.HasStatue(list.Begin()));
+	print("  GetRoadReworkDuration():         " + AITown.GetRoadReworkDuration(list.Begin()));
+	print("  GetExclusiveRightsPlayer():      " + AITown.GetExclusiveRightsPlayer(list.Begin()));
+	print("  GetExclusiveRightsDuration():    " + AITown.GetExclusiveRightsDuration(list.Begin()));
+	print("  IsActionAvailable(BUILD_STATUE): " + AITown.IsActionAvailable(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
+	print("  PerformTownAction(BUILD_STATUE): " + AITown.PerformTownAction(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
+	print("  IsActionAvailable(BUILD_STATUE): " + AITown.IsActionAvailable(list.Begin(), AITown.TOWN_ACTION_BUILD_STATUE));
+	print("  HasStatue():                     " + AITown.HasStatue(list.Begin()));
 }
 
 function Regression::Tunnel()
 {
+	print("");
+	print("--Tunnel--");
 	print("  IsTunnelTile():       " + AITunnel.IsTunnelTile(29050));
 	print("  RemoveTunnel():       " + AITunnel.RemoveTunnel(29050));
 	print("  GetOtherTunnelEnd():  " + AITunnel.GetOtherTunnelEnd(29050));
--- a/bin/ai/regression/regression.txt	Sat Jun 07 23:30:41 2008 +0000
+++ b/bin/ai/regression/regression.txt	Sun Jun 08 10:37:30 2008 +0000
@@ -6629,6 +6629,16 @@
     6 => 566
     25 => 548
     0 => 538
+  HasStatue():                     false
+  GetRoadReworkDuration():         0
+  GetExclusiveRightsPlayer():      -1
+  GetExclusiveRightsDuration():    0
+  IsActionAvailable(BUILD_STATUE): true
+  PerformTownAction(BUILD_STATUE): true
+  IsActionAvailable(BUILD_STATUE): false
+  HasStatue():                     true
+
+--Tunnel--
   IsTunnelTile():       false
   RemoveTunnel():       false
   GetOtherTunnelEnd():  28026
@@ -6855,11 +6865,50 @@
         IsValidSubsidy():     true
         IsAwarded():          false
         GetAwardedTo():       -1
+        GetExpireDate():      712619
+        SourceIsTown():       true
+        GetSource():          25
+        DestionationIsTown(): true
+        GetDestionation():    10
+        GetCargoType():       0
+  GetNextEvent:          instance
+    GetEventType:        3
+      EventName:         SubsidyOffer
+      --Subsidy (1) --
+        IsValidSubsidy():     true
+        IsAwarded():          false
+        GetAwardedTo():       -1
+        GetExpireDate():      712647
+        SourceIsTown():       true
+        GetSource():          24
+        DestionationIsTown(): true
+        GetDestionation():    21
+        GetCargoType():       0
+  GetNextEvent:          instance
+    GetEventType:        3
+      EventName:         SubsidyOffer
+      --Subsidy (2) --
+        IsValidSubsidy():     true
+        IsAwarded():          false
+        GetAwardedTo():       -1
+        GetExpireDate():      712739
+        SourceIsTown():       true
+        GetSource():          0
+        DestionationIsTown(): true
+        GetDestionation():    21
+        GetCargoType():       0
+  GetNextEvent:          instance
+    GetEventType:        3
+      EventName:         SubsidyOffer
+      --Subsidy (3) --
+        IsValidSubsidy():     true
+        IsAwarded():          false
+        GetAwardedTo():       -1
         GetExpireDate():      712800
         SourceIsTown():       true
-        GetSource():          6
+        GetSource():          4
         DestionationIsTown(): true
-        GetDestionation():    15
+        GetDestionation():    27
         GetCargoType():       0
   IsEventWaiting:        false
 ERROR: We've got a suicidal AI for player 1
--- a/src/ai/api/ai_town.cpp	Sat Jun 07 23:30:41 2008 +0000
+++ b/src/ai/api/ai_town.cpp	Sun Jun 08 10:37:30 2008 +0000
@@ -5,10 +5,13 @@
 #include "ai_town.hpp"
 #include "ai_map.hpp"
 #include "ai_cargo.hpp"
+#include "ai_error.hpp"
+#include "../../command_type.h"
 #include "../../openttd.h"
 #include "../../town.h"
 #include "../../strings_func.h"
 #include "../../core/alloc_func.hpp"
+#include "../../player_func.h"
 #include "table/strings.h"
 
 /* static */ TownID AITown::GetMaxTownID()
@@ -113,6 +116,53 @@
 
 /* static */ bool AITown::IsWithinTownInfluence(TownID town_id, TileIndex tile)
 {
+	if (!IsValidTown(town_id)) return false;
+
 	const Town *t = ::GetTown(town_id);
 	return ((uint32)GetDistanceSquareToTile(town_id, tile) <= t->squared_town_zone_radius[0]);
 }
+
+/* static */ bool AITown::HasStatue(TownID town_id)
+{
+	if (!IsValidTown(town_id)) return false;
+
+	return ::HasBit(::GetTown(town_id)->statues, _current_player);
+}
+
+/* static */ int AITown::GetRoadReworkDuration(TownID town_id)
+{
+	if (!IsValidTown(town_id)) return -1;
+
+	return ::GetTown(town_id)->road_build_months;
+}
+
+/* static */ AICompany::CompanyID AITown::GetExclusiveRightsPlayer(TownID town_id)
+{
+	if (!IsValidTown(town_id)) return AICompany::INVALID_COMPANY;
+
+	return (AICompany::CompanyID)(int8)::GetTown(town_id)->exclusivity;
+}
+
+/* static */ int32 AITown::GetExclusiveRightsDuration(TownID town_id)
+{
+	if (!IsValidTown(town_id)) return -1;
+
+	return ::GetTown(town_id)->exclusive_counter;
+}
+
+extern uint GetMaskOfTownActions(int *nump, PlayerID pid, const Town *t);
+
+/* static */ bool AITown::IsActionAvailable(TownID town_id, TownAction action)
+{
+	if (!IsValidTown(town_id)) return false;
+
+	return HasBit(::GetMaskOfTownActions(NULL, _current_player, ::GetTown(town_id)), action);
+}
+
+/* static */ bool AITown::PerformTownAction(TownID town_id, TownAction action)
+{
+	EnforcePrecondition(false, IsValidTown(town_id));
+	EnforcePrecondition(false, IsActionAvailable(town_id, action));
+
+	return AIObject::DoCommand(::GetTown(town_id)->xy, town_id, action, CMD_DO_TOWN_ACTION);
+}
--- a/src/ai/api/ai_town.hpp	Sat Jun 07 23:30:41 2008 +0000
+++ b/src/ai/api/ai_town.hpp	Sun Jun 08 10:37:30 2008 +0000
@@ -6,6 +6,7 @@
 #define AI_TOWN_HPP
 
 #include "ai_object.hpp"
+#include "ai_company.hpp"
 
 /**
  * Class that handles all town related functions.
@@ -15,6 +16,57 @@
 	static const char *GetClassName() { return "AITown"; }
 
 	/**
+	 * Actions that one can perform on a town.
+	 */
+	enum TownAction {
+		/**
+		 * The cargo ratings temporary gains 25% of rating (in
+		 * absolute percentage, so 10% becomes 35%, with a max of 99%)
+		 * for all stations within 10 tiles.
+		 */
+		TOWN_ACTION_ADVERTISE_SMALL  = 0,
+
+		/**
+		 * The cargo ratings temporary gains 44% of rating (in
+		 * absolute percentage, so 10% becomes 54%, with a max of 99%)
+		 * for all stations within 15 tiles.
+		 */
+		TOWN_ACTION_ADVERTISE_MEDIUM = 1,
+
+		/**
+		 * The cargo ratings temporary gains 63% of rating (in
+		 * absolute percentage, so 10% becomes 73%, with a max of 99%)
+		 * for all stations within 20 tiles.
+		 */
+		TOWN_ACTION_ADVERTISE_LARGE  = 2,
+
+		/**
+		 * Rebuild the roads of this town for 6 months.
+		 */
+		TOWN_ACTION_ROAD_REBUILD     = 3,
+
+		/**
+		 * Build a statue in this town.
+		 */
+		TOWN_ACTION_BUILD_STATUE     = 4,
+
+		/**
+		 * Fund the creation of extra buildings for 3 months.
+		 */
+		TOWN_ACTION_FUND_BUILDINGS   = 5,
+
+		/**
+		 * Buy exclusive rights for this town for 12 months.
+		 */
+		TOWN_ACTION_BUY_RIGHTS       = 6,
+
+		/**
+		 * Bribe the town in order to get a higher rating.
+		 */
+		TOWN_ACTION_BRIBE            = 7,
+	};
+
+	/**
 	 * Gets the maximum town index; there are no valid towns with a higher index.
 	 * @return The maximum town index.
 	 * @post Return value is always non-negative.
@@ -131,9 +183,65 @@
 	 *  Stations on this tile influence the rating of the town.
 	 * @param town_id The town to check.
 	 * @param tile The tile to check.
+	 * @pre IsValidTown(town_id).
 	 * @return True if the tile is within the rating influence of the town.
 	 */
 	static bool IsWithinTownInfluence(TownID town_id, TileIndex tile);
+
+	/**
+	 * Find out if this town has a statue for the current player.
+	 * @param town_id The town to check.
+	 * @pre IsValidTown(town_id).
+	 * @return True if the town has a statue.
+	 */
+	static bool HasStatue(TownID town_id);
+
+	/**
+	 * Find out how long the town is undergoing road reconstructions.
+	 * @param town_id The town to check.
+	 * @pre IsValidTown(town_id).
+	 * @return The number of months the road reworks are still going to take.
+	 *         The value 0 means that there are currently no road reworks.
+	 */
+	static int GetRoadReworkDuration(TownID town_id);
+
+	/**
+	 * Find out which company currently has the exclusive rights of this town.
+	 * @param town_id The town to check.
+	 * @pre IsValidTown(town_id).
+	 * @return The company that has the exclusive rights. The value
+	 *         AICompany::INVALID_COMPANY means that there are currently no
+	 *         exclusive rights given out to anyone.
+	 */
+	static AICompany::CompanyID GetExclusiveRightsPlayer(TownID town_id);
+
+	/**
+	 * Find out how long the town is under influence of the exclusive rights.
+	 * @param town_id The town to check.
+	 * @pre IsValidTown(town_id).
+	 * @return The number of months the exclusive rights hold.
+	 *         The value 0 means that there are currently no exclusive rights
+	 *         given out to anyone.
+	 */
+	static int32 GetExclusiveRightsDuration(TownID town_id);
+
+	/**
+	 * Find out if an action can currently be performed on the town.
+	 * @param town_id The town to perform the action on.
+	 * @pre IsValidTown(town_id).
+	 * @return True if and only if the action can performed.
+	 */
+	static bool IsActionAvailable(TownID town_id, TownAction action);
+
+	/**
+	 * Perform a town action on this town.
+	 * @param town_id The town to perform the action on.
+	 * @param action The action to perform on the town.
+	 * @pre IsValidTown(town_id).
+	 * @pre IsActionAvailable(town_id, action).
+	 * @return True if the action succeeded.
+	 */
+	static bool PerformTownAction(TownID town_id, TownAction action);
 };
 
 #endif /* AI_TOWN_HPP */
--- a/src/ai/api/ai_town.hpp.sq	Sat Jun 07 23:30:41 2008 +0000
+++ b/src/ai/api/ai_town.hpp.sq	Sun Jun 08 10:37:30 2008 +0000
@@ -4,6 +4,10 @@
 #include "ai_town.hpp"
 
 namespace SQConvert {
+	/* Allow enums to be used as Squirrel parameters */
+	template <> AITown::TownAction GetParam(ForceType<AITown::TownAction>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITown::TownAction)tmp; }
+	template <> int Return<AITown::TownAction>(HSQUIRRELVM vm, AITown::TownAction res) { sq_pushinteger(vm, (int32)res); return 1; }
+
 	/* Allow AITown to be used as Squirrel parameter */
 	template <> AITown *GetParam(ForceType<AITown *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITown *)instance; }
 	template <> AITown &GetParam(ForceType<AITown &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITown *)instance; }
@@ -17,6 +21,15 @@
 	SQAITown.PreRegister(engine);
 	SQAITown.AddConstructor<void (AITown::*)(), 1>(engine, "x");
 
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_SMALL,  "TOWN_ACTION_ADVERTISE_SMALL");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_MEDIUM, "TOWN_ACTION_ADVERTISE_MEDIUM");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ADVERTISE_LARGE,  "TOWN_ACTION_ADVERTISE_LARGE");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_ROAD_REBUILD,     "TOWN_ACTION_ROAD_REBUILD");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BUILD_STATUE,     "TOWN_ACTION_BUILD_STATUE");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_FUND_BUILDINGS,   "TOWN_ACTION_FUND_BUILDINGS");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BUY_RIGHTS,       "TOWN_ACTION_BUY_RIGHTS");
+	SQAITown.DefSQConst(engine, AITown::TOWN_ACTION_BRIBE,            "TOWN_ACTION_BRIBE");
+
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetClassName,               "GetClassName",               1, "x");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetMaxTownID,               "GetMaxTownID",               1, "x");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetTownCount,               "GetTownCount",               1, "x");
@@ -31,6 +44,12 @@
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, "xii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceSquareToTile,    "GetDistanceSquareToTile",    3, "xii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::IsWithinTownInfluence,      "IsWithinTownInfluence",      3, "xii");
+	SQAITown.DefSQStaticMethod(engine, &AITown::HasStatue,                  "HasStatue",                  2, "xi");
+	SQAITown.DefSQStaticMethod(engine, &AITown::GetRoadReworkDuration,      "GetRoadReworkDuration",      2, "xi");
+	SQAITown.DefSQStaticMethod(engine, &AITown::GetExclusiveRightsPlayer,   "GetExclusiveRightsPlayer",   2, "xi");
+	SQAITown.DefSQStaticMethod(engine, &AITown::GetExclusiveRightsDuration, "GetExclusiveRightsDuration", 2, "xi");
+	SQAITown.DefSQStaticMethod(engine, &AITown::IsActionAvailable,          "IsActionAvailable",          3, "xii");
+	SQAITown.DefSQStaticMethod(engine, &AITown::PerformTownAction,          "PerformTownAction",          3, "xii");
 
 	SQAITown.PostRegister(engine);
 }