(svn r9626) [NoAI] -Change: renamed AIList to AIAbstractList and hide 'AddItem' and 'RemoveItem' noai
authortruelight
Sat, 14 Apr 2007 20:17:36 +0000
branchnoai
changeset 9593 012f29f59906
parent 9592 c5c09cfde63a
child 9594 5009a30f320a
(svn r9626) [NoAI] -Change: renamed AIList to AIAbstractList and hide 'AddItem' and 'RemoveItem'
-Add: added AIList to work like the old AIList
projects/openttd.vcproj
projects/openttd_vs80.vcproj
source.list
src/ai/ai_squirrel.cpp
src/ai/api/ai_abstractlist.cpp
src/ai/api/ai_abstractlist.hpp
src/ai/api/ai_list.cpp
src/ai/api/ai_list.hpp
src/ai/api/ai_tilelist.hpp
src/ai/api/ai_tilelist_valuator.hpp
src/ai/api/ai_townlist.hpp
src/ai/api/ai_townlist_valuator.hpp
--- a/projects/openttd.vcproj	Sat Apr 14 20:01:25 2007 +0000
+++ b/projects/openttd.vcproj	Sat Apr 14 20:17:36 2007 +0000
@@ -1027,6 +1027,9 @@
 			Name="AI API"
 			Filter="">
 			<File
+				RelativePath=".\..\src\ai\api\ai_abstractlist.hpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_accounting.hpp">
 			</File>
 			<File
@@ -1097,6 +1100,9 @@
 			Name="AI API Implementation"
 			Filter="">
 			<File
+				RelativePath=".\..\src\ai\api\ai_abstractlist.cpp">
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_accounting.cpp">
 			</File>
 			<File
--- a/projects/openttd_vs80.vcproj	Sat Apr 14 20:01:25 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Sat Apr 14 20:17:36 2007 +0000
@@ -1588,6 +1588,10 @@
 			Name="AI API"
 			>
 			<File
+				RelativePath=".\..\src\ai\api\ai_abstractlist.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_accounting.hpp"
 				>
 			</File>
@@ -1680,6 +1684,10 @@
 			Name="AI API Implementation"
 			>
 			<File
+				RelativePath=".\..\src\ai\api\ai_abstractlist.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\ai\api\ai_accounting.cpp"
 				>
 			</File>
--- a/source.list	Sat Apr 14 20:01:25 2007 +0000
+++ b/source.list	Sat Apr 14 20:17:36 2007 +0000
@@ -314,6 +314,7 @@
 ai/NoAI/NoAI.hpp
 
 # AI API
+ai/api/ai_abstractlist.hpp
 ai/api/ai_accounting.hpp
 ai/api/ai_base.hpp
 ai/api/ai_cargo.hpp
@@ -338,6 +339,7 @@
 ai/api/ai_vehicle.hpp
 
 # AI API Implementation
+ai/api/ai_abstractlist.cpp
 ai/api/ai_accounting.cpp
 ai/api/ai_base.cpp
 ai/api/ai_cargo.cpp
--- a/src/ai/ai_squirrel.cpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/ai_squirrel.cpp	Sat Apr 14 20:17:36 2007 +0000
@@ -195,6 +195,7 @@
 
 	/* Register all classes */
 	squirrel_register_std(this->engine);
+	SQAIAbstractListRegister(this->engine);
 	SQAIAccountingRegister(this->engine);
 	SQAIBaseRegister(this->engine);
 	SQAICargoRegister(this->engine);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_abstractlist.cpp	Sat Apr 14 20:17:36 2007 +0000
@@ -0,0 +1,378 @@
+/* $Id$ */
+
+/** @file ai_abstractlist.cpp Implementation of AIAbstractList */
+
+#include "ai_abstractlist.hpp"
+
+/**
+ * Base class for any AIAbstractList sorter.
+ */
+class AIAbstractListSorter {
+protected:
+	AIAbstractList *list;
+
+public:
+	/**
+	 * Virtual dtor, needed to mute warnings.
+	 */
+	virtual ~AIAbstractListSorter() { }
+
+	/**
+	 * Get the first item of the sorter.
+	 */
+	virtual int32 Begin() = 0;
+
+	/**
+	 * Get the next item of the sorter.
+	 */
+	virtual int32 Next() = 0;
+
+	/**
+	 * See if there is a next item of the sorter.
+	 */
+	virtual bool HasNext() = 0;
+};
+
+/**
+ * Sort by value, ascending.
+ */
+class AIAbstractListSorterValueAscending : public AIAbstractListSorter {
+private:
+	AIAbstractList::AIAbstractListBucket::iterator bucket_iter;
+	AIAbstractList::AIItemList *bucket_list;
+	AIAbstractList::AIItemList::iterator bucket_list_iter;
+
+public:
+	AIAbstractListSorterValueAscending(AIAbstractList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->bucket_iter = this->list->buckets.begin();
+		this->bucket_list = &(*this->bucket_iter).second;
+		this->bucket_list_iter = this->bucket_list->begin();
+		return *bucket_list_iter;
+	}
+
+	int32 Next()
+	{
+		this->bucket_list_iter++;
+		if (this->bucket_list_iter == this->bucket_list->end()) {
+			this->bucket_iter++;
+			if (this->bucket_iter == this->list->buckets.end()) return 0;
+			this->bucket_list = &(*this->bucket_iter).second;
+			this->bucket_list_iter = this->bucket_list->begin();
+		}
+		return *bucket_list_iter;
+	}
+
+	bool HasNext()
+	{
+		return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end();
+	}
+};
+
+/**
+ * Sort by value, descending.
+ */
+class AIAbstractListSorterValueDescending : public AIAbstractListSorter {
+private:
+	AIAbstractList::AIAbstractListBucket::reverse_iterator bucket_iter;
+	AIAbstractList::AIItemList *bucket_list;
+	AIAbstractList::AIItemList::reverse_iterator bucket_list_iter;
+
+public:
+	AIAbstractListSorterValueDescending(AIAbstractList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->bucket_iter = this->list->buckets.rbegin();
+		this->bucket_list = &(*this->bucket_iter).second;
+		this->bucket_list_iter = this->bucket_list->rbegin();
+		return *bucket_list_iter;
+	}
+
+	int32 Next()
+	{
+		this->bucket_list_iter++;
+		if (this->bucket_list_iter == this->bucket_list->rend()) {
+			this->bucket_iter++;
+			if (this->bucket_iter == this->list->buckets.rend()) return 0;
+			this->bucket_list = &(*this->bucket_iter).second;
+			this->bucket_list_iter = this->bucket_list->rbegin();
+		}
+		return *bucket_list_iter;
+	}
+
+	bool HasNext()
+	{
+		return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend();
+	}
+};
+
+/**
+ * Sort by item, ascending.
+ */
+class AIAbstractListSorterItemAscending : public AIAbstractListSorter {
+private:
+	AIAbstractList::AIAbstractListMap::iterator item_iter;
+
+public:
+	AIAbstractListSorterItemAscending(AIAbstractList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->item_iter = this->list->items.begin();
+		return (*this->item_iter).first;
+	}
+
+	int32 Next()
+	{
+		this->item_iter++;
+		return (*this->item_iter).first;
+	}
+
+	bool HasNext()
+	{
+		return this->item_iter != this->list->items.end();
+	}
+};
+
+/**
+ * Sort by item, descending.
+ */
+class AIAbstractListSorterItemDescending : public AIAbstractListSorter {
+private:
+	AIAbstractList::AIAbstractListMap::reverse_iterator item_iter;
+
+public:
+	AIAbstractListSorterItemDescending(AIAbstractList *list)
+	{
+		this->list = list;
+	}
+
+	int32 Begin()
+	{
+		this->item_iter = this->list->items.rbegin();
+		return (*this->item_iter).first;
+	}
+
+	int32 Next()
+	{
+		this->item_iter++;
+		return (*this->item_iter).first;
+	}
+
+	bool HasNext()
+	{
+		return this->item_iter != this->list->items.rend();
+	}
+};
+
+
+
+AIAbstractList::AIAbstractList()
+{
+	/* Default sorter */
+	this->sorter = new AIAbstractListSorterValueDescending(this);
+}
+
+AIAbstractList::~AIAbstractList()
+{
+	delete this->sorter;
+}
+
+bool AIAbstractList::HasItem(int32 item)
+{
+	return this->items.count(item) == 1;
+}
+
+void AIAbstractList::Clear()
+{
+	this->items.clear();
+	this->buckets.clear();
+}
+
+void AIAbstractList::AddItem(int32 item)
+{
+	if (this->HasItem(item)) return;
+
+	this->items[item] = 0;
+	this->buckets[0].insert(item);
+}
+
+void AIAbstractList::RemoveItem(int32 item)
+{
+	if (!this->HasItem(item)) return;
+
+	this->buckets[this->GetValue(item)].erase(item);
+	this->items.erase(item);
+}
+
+int32 AIAbstractList::Begin()
+{
+	return this->sorter->Begin();
+}
+
+int32 AIAbstractList::Next()
+{
+	return this->sorter->Next();
+}
+
+bool AIAbstractList::IsEmpty()
+{
+	return this->items.empty();
+}
+
+bool AIAbstractList::HasNext()
+{
+	return this->sorter->HasNext();
+}
+
+int32 AIAbstractList::Count()
+{
+	return this->items.size();
+}
+
+int32 AIAbstractList::GetValue(int32 item)
+{
+	if (!this->HasItem(item)) return 0;
+
+	return this->items[item];
+}
+
+void AIAbstractList::SortByItem(bool ascending)
+{
+	delete this->sorter;
+	if (ascending) this->sorter = new AIAbstractListSorterItemAscending(this);
+	else           this->sorter = new AIAbstractListSorterItemDescending(this);
+}
+
+void AIAbstractList::SortByValue(bool ascending)
+{
+	delete this->sorter;
+	if (ascending) this->sorter = new AIAbstractListSorterValueAscending(this);
+	else           this->sorter = new AIAbstractListSorterValueDescending(this);
+}
+
+void AIAbstractList::RemoveAboveValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second > value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first > value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::RemoveBelowValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second < value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first < value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::RemoveBetweenValue(int32 start, int32 end)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::RemoveValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second == value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first == value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::KeepAboveValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second <= value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first <= value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::KeepBelowValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second >= value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first >= value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::KeepBetweenValue(int32 start, int32 end)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::KeepValue(int32 value)
+{
+	for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).second != value) this->items.erase(iter);
+	}
+
+	for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
+		next_iter = iter; next_iter++;
+		if ((*iter).first != value) this->buckets.erase(iter);
+	}
+}
+
+void AIAbstractList::Valuate(const AIAbstractList::Valuator &proc)
+{
+	this->buckets.clear();
+	for (AIAbstractListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
+		int32 value = proc.Valuate((*iter).first);
+		(*iter).second = value;
+		this->buckets[value].insert((*iter).first);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_abstractlist.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -0,0 +1,238 @@
+/* $Id$ */
+
+/** @file ai_abstractlist.hpp a linked list which can keep item/value pairs */
+
+#ifndef AI_ABSTRACTLIST_HPP
+#define AI_ABSTRACTLIST_HPP
+
+#include "ai_object.hpp"
+#include <map>
+#include <set>
+
+class AIAbstractListSorter;
+
+/**
+ * Class that creates a linked list which can keep item/value pairs.
+ */
+class AIAbstractList : public AIObject {
+private:
+	AIAbstractListSorter *sorter;
+
+public:
+	typedef std::set<int32> AIItemList;               ///< The list of items inside the bucket
+	typedef std::map<int32, AIItemList> AIAbstractListBucket; ///< The bucket list per value
+	typedef std::map<int32, int32> AIAbstractListMap;         ///< List per item
+
+	AIAbstractListMap items;           ///< The items in the list
+	AIAbstractListBucket buckets;      ///< The items in the list, sorted by value
+
+protected:
+	/**
+	 * Add a single item to the list.
+	 * @param item the item to add. Should be unique, otherwise it is ignored.
+	 * @note the value is set to 0 by default.
+	 */
+	void AddItem(int32 item);
+
+	/**
+	 * Remove a single item from the list.
+	 * @param item the item to remove. If not existing, it is ignored.
+	 */
+	void RemoveItem(int32 item);
+
+public:
+	/**
+	 * The name of the class, needed by several sub-processes.
+	 */
+	static const char *GetClassName() { return "AIAbstractList"; }
+
+	/**
+	 * Constructor of the AIAbstractList.
+	 */
+	AIAbstractList();
+
+	/**
+	 * Destructor of the AIAbstractList.
+	 */
+	~AIAbstractList();
+
+	/**
+	 * Clear the list, making Count() returning 0 and IsEmpty() returning true.
+	 */
+	void Clear();
+
+	/**
+	 * Check if an item is in the list.
+	 * @param item the item to check for.
+	 * @return true if the item is in the list.
+	 */
+	bool HasItem(int32 item);
+
+	/**
+	 * Go to the beginning of the list.
+	 * @return the item value of the first item.
+	 */
+	int32 Begin();
+
+	/**
+	 * Go to the next item in the list.
+	 * @return the item value of the next item.
+	 * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list.
+	 */
+	int32 Next();
+
+	/**
+	 * Check if a list is empty.
+	 * @return true if the list is empty.
+	 **/
+	bool IsEmpty();
+
+	/**
+	 * Check if there is a next element. In other words, if this is true,
+	 *   Next() will return a valid item.
+	 * @return true if there is a next item.
+	 */
+	bool HasNext();
+
+	/**
+	 * Returns the amount of items in the list.
+	 * @return amount of items in the list.
+	 */
+	int32 Count();
+
+	/**
+	 * Get the value that belongs to this item.
+	 * @param item the item to get the value from
+	 * @return the value that belongs to this item.
+	 */
+	int32 GetValue(int32 item);
+
+	/**
+	 * Sort this list by item-value.
+	 * @param ascending if true, lowest value is on top, else at bottom.
+	 * @note the current item stays at the same place.
+	 */
+	void SortByItem(bool ascending);
+
+	/**
+	 * Sort this list by the value of the items.
+	 * @param ascending if true, lowest value is on top, else at bottom.
+	 * @note the current item stays at the same place.
+	 */
+	void SortByValue(bool ascending);
+
+	/**
+	 * Removes all items with a higher value than 'value'.
+	 * @param value the value above which all items are removed.
+	 */
+	void RemoveAboveValue(int32 value);
+
+	/**
+	 * Removes all items with a lower value than 'value'.
+	 * @param value the value below which all items are removed.
+	 */
+	void RemoveBelowValue(int32 value);
+
+	/**
+	 * Removes all items with a value above start and below end.
+	 * @param start the lower bound of the to be removed values (exclusive).
+	 * @param end   the upper bound of the to be removed valuens (exclusive).
+	 */
+	void RemoveBetweenValue(int32 start, int32 end);
+
+	/**
+	 * Remove all items with this value.
+	 * @param value the value to remove.
+	 */
+	void RemoveValue(int32 value);
+
+	/**
+	 * Keep all items with a higher value than 'value'.
+	 * @param value the value above which all items are kept.
+	 */
+	void KeepAboveValue(int32 value);
+
+	/**
+	 * Keep all items with a lower value than 'value'.
+	 * @param value the value below which all items are kept.
+	 */
+	void KeepBelowValue(int32 value);
+
+	/**
+	 * Keep all items with a value above start and below end.
+	 * @param start the lower bound of the to be kept values (exclusive).
+	 * @param end   the upper bound of the to be kept values (exclusive).
+	 */
+	void KeepBetweenValue(int32 start, int32 end);
+
+	/**
+	 * Keep all items with this value.
+	 * @param value the value to keep.
+	 **/
+	void KeepValue(int32 value);
+
+	/**
+	 * The definition how valuators should look.
+	 */
+	class Valuator {
+		/* Make this valuator a friend of AIAbstractList, so we can access the private.
+		 *  Nobody else should ever call Valuate. */
+		friend class AIAbstractList;
+	public:
+		/**
+		 * Virtual destructor, needed to make compilers happy.
+		 */
+		virtual ~Valuator() {}
+
+	private:
+		virtual int32 Valuate(int32 item) const = 0;
+	};
+
+	/**
+	 * Give all items a value defined by the valuator you give.
+	 * @note the valuator should be a valid instance.
+	 */
+	void Valuate(const AIAbstractList::Valuator &proc);
+};
+
+#ifdef DEFINE_SQUIRREL_CLASS
+namespace SQConvert {
+	/* Allow inner classes/structs to be used as Squirrel parameters */
+	template <> const AIAbstractList::Valuator &GetParam(ForceType<const AIAbstractList::Valuator &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIAbstractList::Valuator *)instance; }
+
+	/* Allow AIAbstractList to be used as Squirrel parameter */
+	template <> AIAbstractList *GetParam(ForceType<AIAbstractList *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIAbstractList *)instance; }
+}; // namespace SQConvert
+
+void SQAIAbstractListRegister(Squirrel *engine) {
+	DefSQClass <AIAbstractList> SQAIAbstractList("AIAbstractList");
+	SQAIAbstractList.PreRegister(engine);
+	SQAIAbstractList.AddConstructor(engine);
+
+	SQAIAbstractList.DefSQStaticMethod(engine, &AIAbstractList::GetClassName, "GetClassName", 1, "x");
+
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Clear,              "Clear",              1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasItem,            "HasItem",            2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Begin,              "Begin",              1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Next,               "Next",               1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::IsEmpty,            "IsEmpty",            1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasNext,            "HasNext",            1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Count,              "Count",              1, "x");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::GetValue,           "GetValue",           2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SortByItem,         "SortByItem",         2, "xb");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::SortByValue,        "SortByValue",        2, "xb");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveAboveValue,   "RemoveAboveValue",   2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBelowValue,   "RemoveBelowValue",   2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::RemoveValue,        "RemoveValue",        2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepAboveValue,     "KeepAboveValue",     2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBelowValue,     "KeepBelowValue",     2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepBetweenValue,   "KeepBetweenValue",   3, "xii");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::KeepValue,          "KeepValue",          2, "xi");
+	SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Valuate,            "Valuate",            2, "xx");
+
+	SQAIAbstractList.PostRegister(engine);
+}
+#endif /* DEFINE_SQUIRREL_CLASS */
+
+#endif /* AI_LIST_HPP */
--- a/src/ai/api/ai_list.cpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_list.cpp	Sat Apr 14 20:17:36 2007 +0000
@@ -1,378 +1,11 @@
-/* $Id$ */
-
-/** @file ai_list.cpp Implementation of AIList */
-
 #include "ai_list.hpp"
 
-/**
- * Base class for any AIList sorter.
- */
-class AIListSorter {
-protected:
-	AIList *list;
-
-public:
-	/**
-	 * Virtual dtor, needed to mute warnings.
-	 */
-	virtual ~AIListSorter() { }
-
-	/**
-	 * Get the first item of the sorter.
-	 */
-	virtual int32 Begin() = 0;
-
-	/**
-	 * Get the next item of the sorter.
-	 */
-	virtual int32 Next() = 0;
-
-	/**
-	 * See if there is a next item of the sorter.
-	 */
-	virtual bool HasNext() = 0;
-};
-
-/**
- * Sort by value, ascending.
- */
-class AIListSorterValueAscending : public AIListSorter {
-private:
-	AIList::AIListBucket::iterator bucket_iter;
-	AIList::AIItemList *bucket_list;
-	AIList::AIItemList::iterator bucket_list_iter;
-
-public:
-	AIListSorterValueAscending(AIList *list)
-	{
-		this->list = list;
-	}
-
-	int32 Begin()
-	{
-		this->bucket_iter = this->list->buckets.begin();
-		this->bucket_list = &(*this->bucket_iter).second;
-		this->bucket_list_iter = this->bucket_list->begin();
-		return *bucket_list_iter;
-	}
-
-	int32 Next()
-	{
-		this->bucket_list_iter++;
-		if (this->bucket_list_iter == this->bucket_list->end()) {
-			this->bucket_iter++;
-			if (this->bucket_iter == this->list->buckets.end()) return 0;
-			this->bucket_list = &(*this->bucket_iter).second;
-			this->bucket_list_iter = this->bucket_list->begin();
-		}
-		return *bucket_list_iter;
-	}
-
-	bool HasNext()
-	{
-		return this->bucket_iter != this->list->buckets.end() && this->bucket_list_iter != this->bucket_list->end();
-	}
-};
-
-/**
- * Sort by value, descending.
- */
-class AIListSorterValueDescending : public AIListSorter {
-private:
-	AIList::AIListBucket::reverse_iterator bucket_iter;
-	AIList::AIItemList *bucket_list;
-	AIList::AIItemList::reverse_iterator bucket_list_iter;
-
-public:
-	AIListSorterValueDescending(AIList *list)
-	{
-		this->list = list;
-	}
-
-	int32 Begin()
-	{
-		this->bucket_iter = this->list->buckets.rbegin();
-		this->bucket_list = &(*this->bucket_iter).second;
-		this->bucket_list_iter = this->bucket_list->rbegin();
-		return *bucket_list_iter;
-	}
-
-	int32 Next()
-	{
-		this->bucket_list_iter++;
-		if (this->bucket_list_iter == this->bucket_list->rend()) {
-			this->bucket_iter++;
-			if (this->bucket_iter == this->list->buckets.rend()) return 0;
-			this->bucket_list = &(*this->bucket_iter).second;
-			this->bucket_list_iter = this->bucket_list->rbegin();
-		}
-		return *bucket_list_iter;
-	}
-
-	bool HasNext()
-	{
-		return this->bucket_iter != this->list->buckets.rend() && this->bucket_list_iter != this->bucket_list->rend();
-	}
-};
-
-/**
- * Sort by item, ascending.
- */
-class AIListSorterItemAscending : public AIListSorter {
-private:
-	AIList::AIListMap::iterator item_iter;
-
-public:
-	AIListSorterItemAscending(AIList *list)
-	{
-		this->list = list;
-	}
-
-	int32 Begin()
-	{
-		this->item_iter = this->list->items.begin();
-		return (*this->item_iter).first;
-	}
-
-	int32 Next()
-	{
-		this->item_iter++;
-		return (*this->item_iter).first;
-	}
-
-	bool HasNext()
-	{
-		return this->item_iter != this->list->items.end();
-	}
-};
-
-/**
- * Sort by item, descending.
- */
-class AIListSorterItemDescending : public AIListSorter {
-private:
-	AIList::AIListMap::reverse_iterator item_iter;
-
-public:
-	AIListSorterItemDescending(AIList *list)
-	{
-		this->list = list;
-	}
-
-	int32 Begin()
-	{
-		this->item_iter = this->list->items.rbegin();
-		return (*this->item_iter).first;
-	}
-
-	int32 Next()
-	{
-		this->item_iter++;
-		return (*this->item_iter).first;
-	}
-
-	bool HasNext()
-	{
-		return this->item_iter != this->list->items.rend();
-	}
-};
-
-
-
-AIList::AIList()
-{
-	/* Default sorter */
-	this->sorter = new AIListSorterValueDescending(this);
-}
-
-AIList::~AIList()
-{
-	delete this->sorter;
-}
-
-bool AIList::HasItem(int32 item)
-{
-	return this->items.count(item) == 1;
-}
-
-void AIList::Clear()
-{
-	this->items.clear();
-	this->buckets.clear();
-}
-
 void AIList::AddItem(int32 item)
 {
-	if (this->HasItem(item)) return;
-
-	this->items[item] = 0;
-	this->buckets[0].insert(item);
+	AIAbstractList::AddItem(item);
 }
 
 void AIList::RemoveItem(int32 item)
 {
-	if (!this->HasItem(item)) return;
-
-	this->buckets[this->GetValue(item)].erase(item);
-	this->items.erase(item);
-}
-
-int32 AIList::Begin()
-{
-	return this->sorter->Begin();
-}
-
-int32 AIList::Next()
-{
-	return this->sorter->Next();
-}
-
-bool AIList::IsEmpty()
-{
-	return this->items.empty();
-}
-
-bool AIList::HasNext()
-{
-	return this->sorter->HasNext();
-}
-
-int32 AIList::Count()
-{
-	return this->items.size();
-}
-
-int32 AIList::GetValue(int32 item)
-{
-	if (!this->HasItem(item)) return 0;
-
-	return this->items[item];
-}
-
-void AIList::SortByItem(bool ascending)
-{
-	delete this->sorter;
-	if (ascending) this->sorter = new AIListSorterItemAscending(this);
-	else           this->sorter = new AIListSorterItemDescending(this);
-}
-
-void AIList::SortByValue(bool ascending)
-{
-	delete this->sorter;
-	if (ascending) this->sorter = new AIListSorterValueAscending(this);
-	else           this->sorter = new AIListSorterValueDescending(this);
-}
-
-void AIList::RemoveAboveValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second > value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first > value) this->buckets.erase(iter);
-	}
-}
-
-void AIList::RemoveBelowValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second < value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first < value) this->buckets.erase(iter);
-	}
+	AIAbstractList::RemoveItem(item);
 }
-
-void AIList::RemoveBetweenValue(int32 start, int32 end)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
-	}
-}
-
-void AIList::RemoveValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second == value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first == value) this->buckets.erase(iter);
-	}
-}
-
-void AIList::KeepAboveValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second <= value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first <= value) this->buckets.erase(iter);
-	}
-}
-
-void AIList::KeepBelowValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second >= value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first >= value) this->buckets.erase(iter);
-	}
-}
-
-void AIList::KeepBetweenValue(int32 start, int32 end)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
-	}
-}
-
-void AIList::KeepValue(int32 value)
-{
-	for (AIListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).second != value) this->items.erase(iter);
-	}
-
-	for (AIListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
-		next_iter = iter; next_iter++;
-		if ((*iter).first != value) this->buckets.erase(iter);
-	}
-}
-
-void AIList::Valuate(const AIList::Valuator &proc)
-{
-	this->buckets.clear();
-	for (AIListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) {
-		int32 value = proc.Valuate((*iter).first);
-		(*iter).second = value;
-		this->buckets[value].insert((*iter).first);
-	}
-}
--- a/src/ai/api/ai_list.hpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_list.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -1,237 +1,51 @@
 /* $Id$ */
 
-/** @file ai_list.hpp a linked list which can keep item/value pairs */
+/** @file ai_list.hpp a simple list which you can manipulate */
 
 #ifndef AI_LIST_HPP
 #define AI_LIST_HPP
 
-#include "ai_object.hpp"
-#include <map>
-#include <set>
-
-class AIListSorter;
+#include "ai_abstractlist.hpp"
 
 /**
- * Class that creates a linked list which can keep item/value pairs.
+ * Class that creates a simple list of tiles which you can manipulate.
  */
-class AIList : public AIObject {
-private:
-	AIListSorter *sorter;
-
+class AIList : public AIAbstractList {
 public:
-	typedef std::set<int32> AIItemList;               ///< The list of items inside the bucket
-	typedef std::map<int32, AIItemList> AIListBucket; ///< The bucket list per value
-	typedef std::map<int32, int32> AIListMap;         ///< List per item
-
-	AIListMap items;           ///< The items in the list
-	AIListBucket buckets;      ///< The items in the list, sorted by value
-
-public:
-
 	/**
 	 * The name of the class, needed by several sub-processes.
 	 */
 	static const char *GetClassName() { return "AIList"; }
 
-	/**
-	 * Constructor of the AIList.
-	 */
-	AIList();
-
+public:
 	/**
-	 * Destructor of the AIList.
-	 */
-	~AIList();
-
-	/**
-	 * Clear the list, making Count() returning 0 and IsEmpty() returning true.
-	 */
-	void Clear();
-
-	/**
-	 * Add a single item to the list.
-	 * @param item the item to add. Should be unique, otherwise it is ignored.
-	 * @note the value is set to 0 by default.
+	 * Add an item to the list.
+	 * @param item the item to add.
 	 */
 	void AddItem(int32 item);
 
 	/**
-	 * Remove a single item from the list.
-	 * @param item the item to remove. If not existing, it is ignored.
+	 * Remove the item from the list.
+	 * @param item the item to remove.
 	 */
 	void RemoveItem(int32 item);
-
-	/**
-	 * Check if an item is in the list.
-	 * @param item the item to check for.
-	 * @return true if the item is in the list.
-	 */
-	bool HasItem(int32 item);
-
-	/**
-	 * Go to the beginning of the list.
-	 * @return the item value of the first item.
-	 */
-	int32 Begin();
-
-	/**
-	 * Go to the next item in the list.
-	 * @return the item value of the next item.
-	 * @note returns 0 if beyond end-of-list. Use HasNext() to check for end-of-list.
-	 */
-	int32 Next();
-
-	/**
-	 * Check if a list is empty.
-	 * @return true if the list is empty.
-	 **/
-	bool IsEmpty();
-
-	/**
-	 * Check if there is a next element. In other words, if this is true,
-	 *   Next() will return a valid item.
-	 * @return true if there is a next item.
-	 */
-	bool HasNext();
-
-	/**
-	 * Returns the amount of items in the list.
-	 * @return amount of items in the list.
-	 */
-	int32 Count();
-
-	/**
-	 * Get the value that belongs to this item.
-	 * @param item the item to get the value from
-	 * @return the value that belongs to this item.
-	 */
-	int32 GetValue(int32 item);
-
-	/**
-	 * Sort this list by item-value.
-	 * @param ascending if true, lowest value is on top, else at bottom.
-	 * @note the current item stays at the same place.
-	 */
-	void SortByItem(bool ascending);
-
-	/**
-	 * Sort this list by the value of the items.
-	 * @param ascending if true, lowest value is on top, else at bottom.
-	 * @note the current item stays at the same place.
-	 */
-	void SortByValue(bool ascending);
-
-	/**
-	 * Removes all items with a higher value than 'value'.
-	 * @param value the value above which all items are removed.
-	 */
-	void RemoveAboveValue(int32 value);
-
-	/**
-	 * Removes all items with a lower value than 'value'.
-	 * @param value the value below which all items are removed.
-	 */
-	void RemoveBelowValue(int32 value);
-
-	/**
-	 * Removes all items with a value above start and below end.
-	 * @param start the lower bound of the to be removed values (exclusive).
-	 * @param end   the upper bound of the to be removed valuens (exclusive).
-	 */
-	void RemoveBetweenValue(int32 start, int32 end);
-
-	/**
-	 * Remove all items with this value.
-	 * @param value the value to remove.
-	 */
-	void RemoveValue(int32 value);
-
-	/**
-	 * Keep all items with a higher value than 'value'.
-	 * @param value the value above which all items are kept.
-	 */
-	void KeepAboveValue(int32 value);
-
-	/**
-	 * Keep all items with a lower value than 'value'.
-	 * @param value the value below which all items are kept.
-	 */
-	void KeepBelowValue(int32 value);
-
-	/**
-	 * Keep all items with a value above start and below end.
-	 * @param start the lower bound of the to be kept values (exclusive).
-	 * @param end   the upper bound of the to be kept values (exclusive).
-	 */
-	void KeepBetweenValue(int32 start, int32 end);
-
-	/**
-	 * Keep all items with this value.
-	 * @param value the value to keep.
-	 **/
-	void KeepValue(int32 value);
-
-	/**
-	 * The definition how valuators should look.
-	 */
-	class Valuator {
-		/* Make this valuator a friend of AIList, so we can access the private.
-		 *  Nobody else should ever call Valuate. */
-		friend class AIList;
-	public:
-		/**
-		 * Virtual destructor, needed to make compilers happy.
-		 */
-		virtual ~Valuator() {}
-
-	private:
-		virtual int32 Valuate(int32 item) const = 0;
-	};
-
-	/**
-	 * Give all items a value defined by the valuator you give.
-	 * @note the valuator should be a valid instance.
-	 */
-	void Valuate(const AIList::Valuator &proc);
 };
 
 #ifdef DEFINE_SQUIRREL_CLASS
 namespace SQConvert {
-	/* Allow inner classes/structs to be used as Squirrel parameters */
-	template <> const AIList::Valuator &GetParam(ForceType<const AIList::Valuator &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIList::Valuator *)instance; }
-
 	/* Allow AIList to be used as Squirrel parameter */
 	template <> AIList *GetParam(ForceType<AIList *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIList *)instance; }
 }; // namespace SQConvert
 
 void SQAIListRegister(Squirrel *engine) {
 	DefSQClass <AIList> SQAIList("AIList");
-	SQAIList.PreRegister(engine);
+	SQAIList.PreRegister(engine, "AIAbstractList");
 	SQAIList.AddConstructor(engine);
 
 	SQAIList.DefSQStaticMethod(engine, &AIList::GetClassName, "GetClassName", 1, "x");
 
-	SQAIList.DefSQMethod(engine, &AIList::Clear,              "Clear",              1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::AddItem,            "AddItem",            2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::RemoveItem,         "RemoveItem",         2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::HasItem,            "HasItem",            2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::Begin,              "Begin",              1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::Next,               "Next",               1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::IsEmpty,            "IsEmpty",            1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::HasNext,            "HasNext",            1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::Count,              "Count",              1, "x");
-	SQAIList.DefSQMethod(engine, &AIList::GetValue,           "GetValue",           2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::SortByItem,         "SortByItem",         2, "xb");
-	SQAIList.DefSQMethod(engine, &AIList::SortByValue,        "SortByValue",        2, "xb");
-	SQAIList.DefSQMethod(engine, &AIList::RemoveAboveValue,   "RemoveAboveValue",   2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::RemoveBelowValue,   "RemoveBelowValue",   2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::RemoveBetweenValue, "RemoveBetweenValue", 3, "xii");
-	SQAIList.DefSQMethod(engine, &AIList::RemoveValue,        "RemoveValue",        2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::KeepAboveValue,     "KeepAboveValue",     2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::KeepBelowValue,     "KeepBelowValue",     2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::KeepBetweenValue,   "KeepBetweenValue",   3, "xii");
-	SQAIList.DefSQMethod(engine, &AIList::KeepValue,          "KeepValue",          2, "xi");
-	SQAIList.DefSQMethod(engine, &AIList::Valuate,            "Valuate",            2, "xx");
+	SQAIList.DefSQMethod(engine, &AIList::AddItem,         "AddItem",         2, "xi");
+	SQAIList.DefSQMethod(engine, &AIList::RemoveItem,      "RemoveItem",      2, "xi");
 
 	SQAIList.PostRegister(engine);
 }
--- a/src/ai/api/ai_tilelist.hpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_tilelist.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -5,12 +5,12 @@
 #ifndef AI_TILELIST_HPP
 #define AI_TILELIST_HPP
 
-#include "ai_list.hpp"
+#include "ai_abstractlist.hpp"
 
 /**
  * Class that creates a simple list of tiles which you can manipulate.
  */
-class AITileList : public AIList {
+class AITileList : public AIAbstractList {
 public:
 	/**
 	 * The name of the class, needed by several sub-processes.
@@ -67,7 +67,7 @@
 
 void SQAITileListRegister(Squirrel *engine) {
 	DefSQClass <AITileList> SQAITileList("AITileList");
-	SQAITileList.PreRegister(engine, "AIList");
+	SQAITileList.PreRegister(engine, "AIAbstractList");
 	SQAITileList.AddConstructor(engine);
 
 	SQAITileList.DefSQStaticMethod(engine, &AITileList::GetClassName, "GetClassName", 1, "x");
--- a/src/ai/api/ai_tilelist_valuator.hpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_tilelist_valuator.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -5,14 +5,14 @@
 #ifndef AI_TILELIST_VALUATOR_HPP
 #define AI_TILELIST_VALUATOR_HPP
 
-#include "ai_list.hpp"
+#include "ai_abstractlist.hpp"
 
 /**
  * Check if tiles are buildable for entries in an AITownList instance.
  * @note resulting items are of the type bool (0 = not buildable, 1 = buildable)
  * @note the input items are of the type TileIndex
  */
-class AITileListBuildable : public AIList::Valuator {
+class AITileListBuildable : public AIAbstractList::Valuator {
 public:
 	/**
 	 * The name of the class, needed by several sub-processes.
--- a/src/ai/api/ai_townlist.hpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_townlist.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -5,12 +5,12 @@
 #ifndef AI_TOWNLIST_HPP
 #define AI_TOWNLIST_HPP
 
-#include "ai_list.hpp"
+#include "ai_abstractlist.hpp"
 
 /**
  * Class that creates a list of current towns.
  */
-class AITownList : public AIList {
+class AITownList : public AIAbstractList {
 public:
 	/**
 	 * The name of the class, needed by several sub-processes.
@@ -31,7 +31,7 @@
 
 void SQAITownListRegister(Squirrel *engine) {
 	DefSQClass <AITownList> SQAITownList("AITownList");
-	SQAITownList.PreRegister(engine, "AIList");
+	SQAITownList.PreRegister(engine, "AIAbstractList");
 	SQAITownList.AddConstructor(engine);
 
 	SQAITownList.DefSQStaticMethod(engine, &AITownList::GetClassName, "GetClassName", 1, "x");
--- a/src/ai/api/ai_townlist_valuator.hpp	Sat Apr 14 20:01:25 2007 +0000
+++ b/src/ai/api/ai_townlist_valuator.hpp	Sat Apr 14 20:17:36 2007 +0000
@@ -5,14 +5,14 @@
 #ifndef AI_TOWNLIST_VALUATOR_HPP
 #define AI_TOWNLIST_VALUATOR_HPP
 
-#include "ai_list.hpp"
+#include "ai_abstractlist.hpp"
 
 /**
  * Get the population for entries in an AITownList instance.
  * @note resulting items are of the type int32
  * @note the input items are of the type TownID
  */
-class AITownListGetPopulation : public AIList::Valuator {
+class AITownListGetPopulation : public AIAbstractList::Valuator {
 public:
 	/**
 	 * The name of the class, needed by several sub-processes.
@@ -45,7 +45,7 @@
  * @note resulting items are of the type TileIndex
  * @note the input items are of the type TownID
  */
-class AITownListGetLocation : public AIList::Valuator {
+class AITownListGetLocation : public AIAbstractList::Valuator {
 public:
 	/**
 	 * The name of the class, needed by several sub-processes.