changeset 18458:a21b17172ad7 draft

(svn r23302) -Add: [NoAI] AITown::GetCargoGoal and AITown::GetGrowthRate to query statistics about a town regarding its growing
author truebrain <truebrain@openttd.org>
date Wed, 23 Nov 2011 16:09:46 +0000
parents 51074598e74a
children 610fb049192c
files src/ai/ai_instance.cpp src/ai/api/ai_changelog.hpp src/ai/api/ai_town.cpp src/ai/api/ai_town.hpp src/ai/api/ai_town.hpp.sq src/ai/api/ai_townlist.cpp src/ai/api/ai_townlist.hpp src/ai/api/ai_townlist.hpp.sq
diffstat 8 files changed, 93 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -249,6 +249,7 @@
 	SQAITileList_IndustryProducing_Register(this->engine);
 	SQAITileList_StationType_Register(this->engine);
 	SQAITown_Register(this->engine);
+	SQAITownEffectList_Register(this->engine);
 	SQAITownList_Register(this->engine);
 	SQAITunnel_Register(this->engine);
 	SQAIVehicle_Register(this->engine);
--- a/src/ai/api/ai_changelog.hpp
+++ b/src/ai/api/ai_changelog.hpp
@@ -35,6 +35,8 @@
  * \li AIOrder::GetOrderRefit
  * \li AIOrder::IsRefitOrder
  * \li AIOrder::SetOrderRefit
+ * \li AITown::GetCargoGoal
+ * \li AITown::GetGrowthRate
  * \li AITown::GetLastMonthReceived
  * \li AITown::GetTownAuthority
  * \li AIVehicle::ERR_VEHICLE_TOO_LONG in case vehicle length limit is reached
--- a/src/ai/api/ai_town.cpp
+++ b/src/ai/api/ai_town.cpp
@@ -18,6 +18,7 @@
 #include "../../strings_func.h"
 #include "../../company_func.h"
 #include "../../station_base.h"
+#include "../../landscape.h"
 #include "table/strings.h"
 
 /* static */ int32 AITown::GetTownCount()
@@ -102,6 +103,35 @@
 	return t->received[towneffect_id].old_act;
 }
 
+/* static */ uint32 AITown::GetCargoGoal(TownID town_id, AICargo::TownEffect towneffect_id)
+{
+	if (!IsValidTown(town_id)) return -1;
+	if (!AICargo::IsValidTownEffect(towneffect_id)) return -1;
+
+	const Town *t = ::Town::Get(town_id);
+
+	switch (t->goal[towneffect_id]) {
+		case TOWN_GROWTH_WINTER:
+			if (TileHeight(t->xy) >= GetSnowLine() && t->population > 90) return 1;
+			return 0;
+
+		case TOWN_GROWTH_DESERT:
+			if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->population > 60) return 1;
+			return 0;
+
+		default: return t->goal[towneffect_id];
+	}
+}
+
+/* static */ int32 AITown::GetGrowthRate(TownID town_id)
+{
+	if (!IsValidTown(town_id)) return false;
+
+	const Town *t = ::Town::Get(town_id);
+
+	return (t->growth_rate * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS;
+}
+
 /* static */ int32 AITown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile)
 {
 	return AIMap::DistanceManhattan(tile, GetLocation(town_id));
--- a/src/ai/api/ai_town.hpp
+++ b/src/ai/api/ai_town.hpp
@@ -187,6 +187,28 @@
 	static int32 GetLastMonthReceived(TownID town_id, AICargo::TownEffect towneffect_id);
 
 	/**
+	 * Get the amount of cargo that needs to be delivered (per TownEffect) for a
+	 *  town to grow. All goals need to be reached before a town will grow.
+	 * @param town_id The index of the town.
+	 * @param towneffect_id The index of the towneffect.
+	 * @pre IsValidTown(town_id).
+	 * @pre AICargo::IsValidTownEffect(cargo_id).
+	 * @return The goal of the cargo.
+	 * @note Goals can change over time. For example with a changing snowline, or
+	 *  with a growing town.
+	 */
+	static uint32 GetCargoGoal(TownID town_id, AICargo::TownEffect towneffect_id);
+
+	/**
+	 * Get the amount of days between town growth.
+	 * @param town_id The index of the town.
+	 * @pre IsValidTown(town_id).
+	 * @return True if the action succeeded.
+	 * @note This function does not indicate when it will grow next. It only tells you the time between growths.
+	 */
+	static int32 GetGrowthRate(TownID town_id);
+
+	/**
 	 * Get the manhattan distance from the tile to the AITown::GetLocation()
 	 *  of the town.
 	 * @param town_id The town to get the distance to.
--- a/src/ai/api/ai_town.hpp.sq
+++ b/src/ai/api/ai_town.hpp.sq
@@ -70,6 +70,8 @@
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthSupplied,              "GetLastMonthSupplied",              3, ".ii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthTransportedPercentage, "GetLastMonthTransportedPercentage", 3, ".ii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthReceived,              "GetLastMonthReceived",              3, ".ii");
+	SQAITown.DefSQStaticMethod(engine, &AITown::GetCargoGoal,                      "GetCargoGoal",                      3, ".ii");
+	SQAITown.DefSQStaticMethod(engine, &AITown::GetGrowthRate,                     "GetGrowthRate",                     2, ".i");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceManhattanToTile,        "GetDistanceManhattanToTile",        3, ".ii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceSquareToTile,           "GetDistanceSquareToTile",           3, ".ii");
 	SQAITown.DefSQStaticMethod(engine, &AITown::IsWithinTownInfluence,             "IsWithinTownInfluence",             3, ".ii");
--- a/src/ai/api/ai_townlist.cpp
+++ b/src/ai/api/ai_townlist.cpp
@@ -20,3 +20,10 @@
 		this->AddItem(t->index);
 	}
 }
+
+AITownEffectList::AITownEffectList()
+{
+	for (int i = TE_BEGIN; i < TE_END; i++) {
+		this->AddItem(i);
+	}
+}
--- a/src/ai/api/ai_townlist.hpp
+++ b/src/ai/api/ai_townlist.hpp
@@ -23,4 +23,13 @@
 	AITownList();
 };
 
+/**
+ * Creates a list of all TownEffects known in the game.
+ * @ingroup AIList
+ */
+class AITownEffectList : public AIList {
+public:
+	AITownEffectList();
+};
+
 #endif /* AI_TOWNLIST_HPP */
--- a/src/ai/api/ai_townlist.hpp.sq
+++ b/src/ai/api/ai_townlist.hpp.sq
@@ -30,3 +30,23 @@
 
 	SQAITownList.PostRegister(engine);
 }
+
+namespace SQConvert {
+	/* Allow AITownEffectList to be used as Squirrel parameter */
+	template <> inline AITownEffectList *GetParam(ForceType<AITownEffectList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITownEffectList *)instance; }
+	template <> inline AITownEffectList &GetParam(ForceType<AITownEffectList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITownEffectList *)instance; }
+	template <> inline const AITownEffectList *GetParam(ForceType<const AITownEffectList *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITownEffectList *)instance; }
+	template <> inline const AITownEffectList &GetParam(ForceType<const AITownEffectList &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITownEffectList *)instance; }
+	template <> inline int Return<AITownEffectList *>(HSQUIRRELVM vm, AITownEffectList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AITownEffectList", res, NULL, DefSQDestructorCallback<AITownEffectList>); return 1; }
+} // namespace SQConvert
+
+template <> const char *GetClassName<AITownEffectList>() { return "AITownEffectList"; }
+
+void SQAITownEffectList_Register(Squirrel *engine)
+{
+	DefSQClass <AITownEffectList> SQAITownEffectList("AITownEffectList");
+	SQAITownEffectList.PreRegister(engine, "AIList");
+	SQAITownEffectList.AddConstructor<void (AITownEffectList::*)(), 1>(engine, "x");
+
+	SQAITownEffectList.PostRegister(engine);
+}