summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ai/ai_instance.cpp1
-rw-r--r--src/ai/api/ai_changelog.hpp2
-rw-r--r--src/ai/api/ai_town.cpp30
-rw-r--r--src/ai/api/ai_town.hpp22
-rw-r--r--src/ai/api/ai_town.hpp.sq2
-rw-r--r--src/ai/api/ai_townlist.cpp7
-rw-r--r--src/ai/api/ai_townlist.hpp9
-rw-r--r--src/ai/api/ai_townlist.hpp.sq20
8 files changed, 93 insertions, 0 deletions
diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp
index 45e142c24..8c18951eb 100644
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -249,6 +249,7 @@ void AIInstance::RegisterAPI()
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);
diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp
index 86db27d97..66acb6520 100644
--- 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
diff --git a/src/ai/api/ai_town.cpp b/src/ai/api/ai_town.cpp
index c1efe5ec7..79ce96ec7 100644
--- 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));
diff --git a/src/ai/api/ai_town.hpp b/src/ai/api/ai_town.hpp
index da86d5994..165045f5f 100644
--- a/src/ai/api/ai_town.hpp
+++ b/src/ai/api/ai_town.hpp
@@ -187,6 +187,28 @@ public:
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.
diff --git a/src/ai/api/ai_town.hpp.sq b/src/ai/api/ai_town.hpp.sq
index 7bc1a3a91..0b5e322bf 100644
--- a/src/ai/api/ai_town.hpp.sq
+++ b/src/ai/api/ai_town.hpp.sq
@@ -70,6 +70,8 @@ void SQAITown_Register(Squirrel *engine)
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");
diff --git a/src/ai/api/ai_townlist.cpp b/src/ai/api/ai_townlist.cpp
index 4057698fc..2ae29a725 100644
--- a/src/ai/api/ai_townlist.cpp
+++ b/src/ai/api/ai_townlist.cpp
@@ -20,3 +20,10 @@ AITownList::AITownList()
this->AddItem(t->index);
}
}
+
+AITownEffectList::AITownEffectList()
+{
+ for (int i = TE_BEGIN; i < TE_END; i++) {
+ this->AddItem(i);
+ }
+}
diff --git a/src/ai/api/ai_townlist.hpp b/src/ai/api/ai_townlist.hpp
index f08a116ea..60f9da727 100644
--- a/src/ai/api/ai_townlist.hpp
+++ b/src/ai/api/ai_townlist.hpp
@@ -23,4 +23,13 @@ public:
AITownList();
};
+/**
+ * Creates a list of all TownEffects known in the game.
+ * @ingroup AIList
+ */
+class AITownEffectList : public AIList {
+public:
+ AITownEffectList();
+};
+
#endif /* AI_TOWNLIST_HPP */
diff --git a/src/ai/api/ai_townlist.hpp.sq b/src/ai/api/ai_townlist.hpp.sq
index 574e830ab..88d64edcd 100644
--- a/src/ai/api/ai_townlist.hpp.sq
+++ b/src/ai/api/ai_townlist.hpp.sq
@@ -30,3 +30,23 @@ void SQAITownList_Register(Squirrel *engine)
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);
+}