# HG changeset patch # User rubidium # Date 1212921450 0 # Node ID 4c14a8041c0a254031ff863d11962c6376c66129 # Parent c7b29152d594f999bc09d23f2f2f163039ac03b9 (svn r13410) [NoAI] -Add: functions to perform town actions (advertising, bribing, building statues, etc). diff -r c7b29152d594 -r 4c14a8041c0a bin/ai/regression/regression.nut --- 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)); diff -r c7b29152d594 -r 4c14a8041c0a bin/ai/regression/regression.txt --- 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 diff -r c7b29152d594 -r 4c14a8041c0a src/ai/api/ai_town.cpp --- 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); +} diff -r c7b29152d594 -r 4c14a8041c0a src/ai/api/ai_town.hpp --- 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 */ diff -r c7b29152d594 -r 4c14a8041c0a src/ai/api/ai_town.hpp.sq --- 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, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AITown::TownAction)tmp; } + template <> int Return(HSQUIRRELVM vm, AITown::TownAction res) { sq_pushinteger(vm, (int32)res); return 1; } + /* Allow AITown to be used as Squirrel parameter */ template <> AITown *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AITown *)instance; } template <> AITown &GetParam(ForceType, 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(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); }