(svn r9407) [NoAI] -Add: placing of signs.
--- a/bin/ai/regression/regression.nut Thu Mar 22 09:10:00 2007 +0000
+++ b/bin/ai/regression/regression.nut Thu Mar 22 09:52:12 2007 +0000
@@ -102,7 +102,7 @@
print("--Industry--");
print(" GetMaxIndustryID(): " + industry.GetMaxIndustryID());
print(" GetIndustryCount(): " + industry.GetIndustryCount());
- for (local i = -1; i < industry.GetMaxIndustryID(); i++) {
+ for (local i = -1; i < industry.GetMaxIndustryID() + 1; i++) {
if (industry.IsValidIndustry(i)) j++;
print(" Industry " + i);
print(" IsValidIndustry(): " + industry.IsValidIndustry(i));
@@ -198,6 +198,31 @@
print(" BuildRoadStation(bus-drive): " + road.BuildRoadStation(33416, 33415, true, true));
}
+function Regression::Sign()
+{
+ local sign = AISign();
+ local j = 0;
+
+ print("");
+ print("--Sign--");
+ print(" BuildSign(33410, 'Some Sign'): " + sign.BuildSign(33410, "Some Sign"));
+ local sign_id = sign.BuildSign(33409, "Some other Sign");
+ print(" BuildSign(33409, 'Some other Sign'): " + sign_id);
+ print(" RemoveSign(" + sign_id + "): " + sign.RemoveSign(sign_id));
+ print("");
+ print(" GetMaxSignID(): " + sign.GetMaxSignID());
+ print(" GetSignCount(): " + sign.GetSignCount());
+ for (local i = -1; i < sign.GetMaxSignID() + 1; i++) {
+ if (sign.IsValidSign(i)) j++;
+ print(" Sign " + i);
+ print(" IsValidSign(): " + sign.IsValidSign(i));
+ print(" GetText(): " + sign.GetText(i));
+ print(" GetLocation(): " + sign.GetLocation(i));
+ }
+ print(" Valid Signs: " + j);
+ print(" GetSignCount(): " + sign.GetSignCount());
+}
+
function Regression::Town()
{
local town = AITown();
@@ -207,7 +232,7 @@
print("--Town--");
print(" GetMaxTownID(): " + town.GetMaxTownID());
print(" GetTownCount(): " + town.GetTownCount());
- for (local i = -1; i < town.GetMaxTownID(); i++) {
+ for (local i = -1; i < town.GetMaxTownID() + 1; i++) {
if (town.IsValidTown(i)) j++;
print(" Town " + i);
print(" IsValidTown(): " + town.IsValidTown(i));
@@ -215,7 +240,7 @@
print(" GetPopulation(): " + town.GetPopulation(i));
print(" GetLocation(): " + town.GetLocation(i));
}
- print(" Valid Industries: " + j);
+ print(" Valid Towns: " + j);
print(" GetTownCount(): " + town.GetTownCount());
}
@@ -230,6 +255,7 @@
this.Industry();
this.Map();
this.Road();
+ this.Sign();
this.Town();
}
--- a/bin/ai/regression/regression.txt Thu Mar 22 09:10:00 2007 +0000
+++ b/bin/ai/regression/regression.txt Thu Mar 22 09:52:12 2007 +0000
@@ -450,6 +450,10 @@
IsValidIndustry(): false
GetName(): (null : 0x00000000)
GetLocation(): -1
+ Industry 71
+ IsValidIndustry(): false
+ GetName(): (null : 0x00000000)
+ GetLocation(): -1
Valid Industries: 69
GetIndustryCount(): 69
@@ -522,6 +526,36 @@
BuildRoadStation(truck-drive): true
BuildRoadStation(bus-drive): true
+--Sign--
+ BuildSign(33410, 'Some Sign'): 0
+ BuildSign(33409, 'Some other Sign'): 1
+ RemoveSign(1): true
+
+ GetMaxSignID(): 3
+ GetSignCount(): 1
+ Sign -1
+ IsValidSign(): false
+ GetText(): (null : 0x00000000)
+ GetLocation(): -1
+ Sign 0
+ IsValidSign(): true
+ GetText(): Some Sign
+ GetLocation(): 33410
+ Sign 1
+ IsValidSign(): false
+ GetText(): (null : 0x00000000)
+ GetLocation(): -1
+ Sign 2
+ IsValidSign(): false
+ GetText(): (null : 0x00000000)
+ GetLocation(): -1
+ Sign 3
+ IsValidSign(): false
+ GetText(): (null : 0x00000000)
+ GetLocation(): -1
+ Valid Signs: 1
+ GetSignCount(): 1
+
--Town--
GetMaxTownID(): 31
GetTownCount(): 28
@@ -685,5 +719,10 @@
GetName(): (null : 0x00000000)
GetPopulation(): 0
GetLocation(): -1
- Valid Industries: 28
+ Town 31
+ IsValidTown(): false
+ GetName(): (null : 0x00000000)
+ GetPopulation(): 0
+ GetLocation(): -1
+ Valid Towns: 28
GetTownCount(): 28
--- a/projects/openttd.vcproj Thu Mar 22 09:10:00 2007 +0000
+++ b/projects/openttd.vcproj Thu Mar 22 09:52:12 2007 +0000
@@ -1054,6 +1054,9 @@
RelativePath=".\..\src\ai\api\ai_settings.hpp">
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_sign.hpp">
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_town.hpp">
</File>
<File
@@ -1106,6 +1109,9 @@
RelativePath=".\..\src\ai\api\ai_settings.cpp">
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_sign.cpp">
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_town.cpp">
</File>
<File
--- a/projects/openttd_vs80.vcproj Thu Mar 22 09:10:00 2007 +0000
+++ b/projects/openttd_vs80.vcproj Thu Mar 22 09:52:12 2007 +0000
@@ -1624,6 +1624,10 @@
>
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_sign.hpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_town.hpp"
>
</File>
@@ -1692,6 +1696,10 @@
>
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_sign.cpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_town.cpp"
>
</File>
--- a/source.list Thu Mar 22 09:10:00 2007 +0000
+++ b/source.list Thu Mar 22 09:52:12 2007 +0000
@@ -323,6 +323,7 @@
ai/api/ai_order.hpp
ai/api/ai_road.hpp
ai/api/ai_settings.hpp
+ai/api/ai_sign.hpp
ai/api/ai_town.hpp
ai/api/ai_testmode.hpp
ai/api/ai_transactionmode.hpp
@@ -341,6 +342,7 @@
ai/api/ai_order.cpp
ai/api/ai_road.cpp
ai/api/ai_settings.cpp
+ai/api/ai_sign.cpp
ai/api/ai_town.cpp
ai/api/ai_testmode.cpp
ai/api/ai_transactionmode.cpp
--- a/src/ai/ai_squirrel.cpp Thu Mar 22 09:10:00 2007 +0000
+++ b/src/ai/ai_squirrel.cpp Thu Mar 22 09:52:12 2007 +0000
@@ -31,6 +31,7 @@
#include "api/ai_order.hpp"
#include "api/ai_road.hpp"
#include "api/ai_settings.hpp"
+#include "api/ai_sign.hpp"
#include "api/ai_testmode.hpp"
#include "api/ai_town.hpp"
#include "api/ai_transactionmode.hpp"
@@ -196,6 +197,7 @@
SQAIMapRegister(this->engine);
SQAIOrderRegister(this->engine);
SQAIRoadRegister(this->engine);
+ SQAISignRegister(this->engine);
SQAISettingsRegister(this->engine);
SQAITestModeRegister(this->engine);
SQAITownRegister(this->engine);
--- a/src/ai/api/ai_object.cpp Thu Mar 22 09:10:00 2007 +0000
+++ b/src/ai/api/ai_object.cpp Thu Mar 22 09:52:12 2007 +0000
@@ -5,6 +5,8 @@
#include "ai_object.hpp"
#include "../../command.h"
#include "../../player.h"
+#include "table/strings.h" // for signs.h
+#include "../../signs.h" // for _new_sign_id
#include "../ai.h"
#include "../ai_threads.h"
@@ -60,6 +62,16 @@
return AIObject::GetDoCommandStruct(_current_player)->new_vehicle_id;
}
+void AIObject::SetNewSignID(SignID sign)
+{
+ AIObject::GetDoCommandStruct(_current_player)->new_sign_id = sign;
+}
+
+SignID AIObject::GetNewSignID()
+{
+ return AIObject::GetDoCommandStruct(_current_player)->new_sign_id;
+}
+
AIObject::AIDoCommandStruct *AIObject::GetDoCommandStruct(PlayerID player)
{
/* Storage for data on per-AI level */
@@ -130,6 +142,7 @@
::DoCommandP(tile, p1, p2, NULL, procc);
/* Store some values inside the AIObject static memory */
AIObject::SetNewVehicleID(_new_vehicle_id);
+ AIObject::SetNewSignID(_new_sign_id);
/* Suspend the AI player for 1 tick, so it simulates MultiPlayer */
AI_SuspendPlayer(_current_player, AIObject::GetDoCommandDelay());
--- a/src/ai/api/ai_object.hpp Thu Mar 22 09:10:00 2007 +0000
+++ b/src/ai/api/ai_object.hpp Thu Mar 22 09:52:12 2007 +0000
@@ -27,6 +27,7 @@
uint delay;
int32 costs;
VehicleID new_vehicle_id;
+ SignID new_sign_id;
};
/**
@@ -85,6 +86,11 @@
*/
static VehicleID GetNewVehicleID();
+ /**
+ * Get the latest stored new_sign_id.
+ */
+ static SignID GetNewSignID();
+
public:
/**
* Store a new_vehicle_id per player.
@@ -93,6 +99,12 @@
static void SetNewVehicleID(VehicleID vehicle);
/**
+ * Store a new_sign_id per player.
+ * @note NEVER use this yourself in your AI!
+ */
+ static void SetNewSignID(SignID vehicle);
+
+ /**
* If an AI starts, some internals needs to be resetted. This function
* takes care of that.
* @note NEVER use this yourself in your AI!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_sign.cpp Thu Mar 22 09:52:12 2007 +0000
@@ -0,0 +1,67 @@
+/* $Id$ */
+
+/** @file ai_sign.cpp handles all functions of the AISign class */
+
+#include "ai_sign.hpp"
+#include "table/strings.h"
+#include "../../command.h"
+#include "../../signs.h"
+#include "../../strings.h"
+#include "../../variables.h" /* For SetDParam */
+
+SignID AISign::GetMaxSignID()
+{
+ return ::GetMaxSignIndex();
+}
+
+int32 AISign::GetSignCount()
+{
+ return ::GetNumSigns();
+}
+
+/* static */ bool AISign::IsValidSign(SignID sign_id)
+{
+ return ::IsValidSignID(sign_id);
+}
+
+char *AISign::GetText(SignID sign_id)
+{
+ if (!AISign::IsValidSign(sign_id)) return NULL;
+ static const int len = 64;
+ char *sign_name = MallocT<char>(len);
+
+ ::GetString(sign_name, ::GetSign(sign_id)->str, &sign_name[len - 1]);
+
+ return sign_name;
+}
+
+TileIndex AISign::GetLocation(SignID sign_id)
+{
+ if (!AISign::IsValidSign(sign_id)) return INVALID_TILE;
+ const Sign *sign = ::GetSign(sign_id);
+ return ::TileVirtXY(sign->x, sign->y);
+}
+
+bool AISign::RemoveSign(SignID sign_id)
+{
+ _cmd_text = "";
+ return this->DoCommand(0, sign_id, 0, CMD_RENAME_SIGN);
+}
+
+SignID AISign::BuildSign(TileIndex location, const char *text)
+{
+ if (!::IsValidTile(location)) return INVALID_SIGN;
+
+ AIObject::SetNewSignID(INVALID_SIGN);
+ bool ret = this->DoCommand(location, 0, 0, CMD_PLACE_SIGN);
+ if (!ret) return INVALID_SIGN;
+
+ SignID new_sign_id = AIObject::GetNewSignID();
+ _cmd_text = text;
+ ret = this->DoCommand(0, new_sign_id, 0, CMD_RENAME_SIGN);
+ if (!ret) {
+ this->RemoveSign(new_sign_id);
+ return INVALID_SIGN;
+ }
+ return new_sign_id;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_sign.hpp Thu Mar 22 09:52:12 2007 +0000
@@ -0,0 +1,90 @@
+/* $Id$ */
+
+/** @file ai_sign.hpp Everything to query and build signs */
+
+#ifndef AI_SIGN_HPP
+#define AI_SIGN_HPP
+
+#include "ai_object.hpp"
+
+/**
+ * Class that handles all town related functions.
+ */
+class AISign : public AIObject {
+public:
+ /**
+ * Gets the maximum sign index; there are no valid signs with a higher index.
+ * @return the maximum town index.
+ * @post return value is always non-negative.
+ */
+ SignID GetMaxSignID();
+
+ /**
+ * Gets the number of signs. This is different than GetSignTownID()
+ * because of the way OpenTTD works internally.
+ * @return the number of signs.
+ * @post return value is always non-negative.
+ */
+ int32 GetSignCount();
+
+ /**
+ * Checks whether the given sign index is valid.
+ * @param sign_id the index to check.
+ * @return true if and only if the sign is valid.
+ */
+ static bool IsValidSign(SignID sign_id);
+
+ /**
+ * Get the text on the sign.
+ * @param sign_id the sign to get the text of.
+ * @pre sign_id has to be valid (use IsValidSign()).
+ * @return the text on the sign.
+ * @note the returned name must be free'd (C++ only).
+ */
+ char *GetText(SignID sign_id);
+
+ /**
+ * Gets the location of the sign.
+ * @param sign_id the sign to get the location of.
+ * @pre sign_id has to be valid (use IsValidSign()).
+ * @return the location of the sign.
+ * @post return value is always positive and below AIMap::GetMapSize().
+ */
+ TileIndex GetLocation(SignID sign_id);
+
+ /**
+ * Removes a sign from the map.
+ * @param sign_id the sign to remove.
+ * @pre sign_id has to be valid (use IsValidSign()).
+ * @return true if and only if the sign has been removed.
+ */
+ bool RemoveSign(SignID sign_id);
+
+ /**
+ * Builds a sign on the map.
+ * @param location the place to build the sign.
+ * @param text the text to place on the sign.
+ * @pre location is always positive and below AIMap::GetMapSize()
+ * @pre text is not NULL and non-empty, i.e. length is positive.
+ * @return the SignID of the build sign (use IsValidSign() to check for validity).
+ */
+ SignID BuildSign(TileIndex location, const char *text);
+};
+
+#ifdef DEFINE_SQUIRREL_CLASS
+void SQAISignRegister(Squirrel *engine) {
+ DefSQClass <AISign> SQAISign("AISign");
+ SQAISign.PreRegister(engine);
+ SQAISign.AddConstructor(engine);
+ SQAISign.DefSQFunction(engine, &AISign::GetMaxSignID, "GetMaxSignID");
+ SQAISign.DefSQFunction(engine, &AISign::GetSignCount, "GetSignCount");
+ SQAISign.DefSQFunction(engine, &AISign::IsValidSign, "IsValidSign");
+ SQAISign.DefSQFunction(engine, &AISign::GetText, "GetText");
+ SQAISign.DefSQFunction(engine, &AISign::GetLocation, "GetLocation");
+ SQAISign.DefSQFunction(engine, &AISign::RemoveSign, "RemoveSign");
+ SQAISign.DefSQFunction(engine, &AISign::BuildSign, "BuildSign");
+ SQAISign.PostRegister(engine);
+}
+#endif /* SQUIRREL_CLASS */
+
+#endif /* AI_SIGN_HPP */
--- a/src/signs.cpp Thu Mar 22 09:10:00 2007 +0000
+++ b/src/signs.cpp Thu Mar 22 09:52:12 2007 +0000
@@ -10,7 +10,8 @@
#include "command.h"
#include "variables.h"
-static Sign *_new_sign;
+SignID _new_sign_id;
+uint _total_signs;
/**
* Called if a new block is added to the sign-pool
@@ -132,7 +133,8 @@
MarkSignDirty(si);
InvalidateWindow(WC_SIGN_LIST, 0);
_sign_sort_dirty = true;
- _new_sign = si;
+ _new_sign_id = si->index;
+ _total_signs++;
}
return 0;
@@ -184,6 +186,7 @@
InvalidateWindow(WC_SIGN_LIST, 0);
_sign_sort_dirty = true;
+ _total_signs--;
}
}
@@ -198,7 +201,7 @@
void CcPlaceSign(bool success, TileIndex tile, uint32 p1, uint32 p2)
{
if (success) {
- ShowRenameSignWindow(_new_sign);
+ ShowRenameSignWindow(GetSign(_new_sign_id));
ResetObjectToPlace();
}
}
@@ -221,6 +224,7 @@
*/
void InitializeSigns()
{
+ _total_signs = 0;
CleanPool(&_Sign_pool);
AddBlockToPool(&_Sign_pool);
}
@@ -258,6 +262,7 @@
*/
static void Load_SIGN()
{
+ _total_signs = 0;
int index;
while ((index = SlIterateArray()) != -1) {
Sign *si;
@@ -267,6 +272,8 @@
si = GetSign(index);
SlObject(si, _sign_desc);
+
+ _total_signs++;
}
_sign_sort_dirty = true;
--- a/src/signs.h Thu Mar 22 09:10:00 2007 +0000
+++ b/src/signs.h Thu Mar 22 09:52:12 2007 +0000
@@ -16,6 +16,12 @@
SignID index;
};
+enum {
+ INVALID_SIGN = 0xFFFF,
+};
+
+extern SignID _new_sign_id;
+
DECLARE_OLD_POOL(Sign, Sign, 2, 16000)
static inline SignID GetMaxSignIndex()
@@ -30,7 +36,8 @@
static inline uint GetNumSigns()
{
- return GetSignPoolSize();
+ extern uint _total_signs;
+ return _total_signs;
}
/**