(svn r13410) [NoAI] -Add: functions to perform town actions (advertising, bribing, building statues, etc).
--- 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);
}