(svn r9767) [NoAI] -Add: add support for params in the constructor (via C++ templates) noai
authortruelight
Wed, 02 May 2007 12:47:16 +0000
branchnoai
changeset 9609 f0dbf5850145
parent 9608 6082e2e7e7f5
child 9610 5cebcd43a1ec
(svn r9767) [NoAI] -Add: add support for params in the constructor (via C++ templates)
[NoAI] -Update: updated squirrel_export to create template-tag for constructors
[NoAI] -Add: added AITileListCargoAcceptance, to get acceptance of a tile
[NoAI] -Update: updated regression to test AITileListCargoAcceptance
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
src/ai/ai_squirrel.cpp
src/ai/api/ai_abstractlist.hpp.sq
src/ai/api/ai_accounting.hpp.sq
src/ai/api/ai_base.hpp.sq
src/ai/api/ai_cargo.hpp.sq
src/ai/api/ai_company.hpp.sq
src/ai/api/ai_execmode.hpp.sq
src/ai/api/ai_industry.hpp.sq
src/ai/api/ai_list.hpp.sq
src/ai/api/ai_map.hpp.sq
src/ai/api/ai_order.hpp.sq
src/ai/api/ai_road.hpp.sq
src/ai/api/ai_settings.hpp.sq
src/ai/api/ai_sign.hpp.sq
src/ai/api/ai_testmode.hpp.sq
src/ai/api/ai_tilelist.hpp.sq
src/ai/api/ai_tilelist_valuator.cpp
src/ai/api/ai_tilelist_valuator.hpp
src/ai/api/ai_tilelist_valuator.hpp.sq
src/ai/api/ai_town.hpp.sq
src/ai/api/ai_townlist.hpp.sq
src/ai/api/ai_townlist_valuator.hpp.sq
src/ai/api/ai_transactionmode.hpp.sq
src/ai/api/ai_vehicle.hpp.sq
src/ai/api/squirrel_export.awk
src/squirrel_class.hpp
src/squirrel_helper.hpp
--- a/bin/ai/regression/regression.nut	Wed May 02 11:46:05 2007 +0000
+++ b/bin/ai/regression/regression.nut	Wed May 02 12:47:16 2007 +0000
@@ -312,20 +312,37 @@
 	print("  Count():             " + list.Count());
 	list.AddRectangle(41895 - 256 * 2, 256 * 2 + 41895 + 8);
 	print("  Count():             " + list.Count());
+
 	list.Valuate(AITileListBuildable());
 	list.KeepValue(1);
 	print("  Buildable():         done");
-	print("  KeepAboveValue(1):   done");
+	print("  KeepValue(1):        done");
 	print("  Count():             " + list.Count());
+
+	list.Valuate(AITileListCargoAcceptance(0));
+	list.KeepAboveValue(10);
+	print("  CargoAcceptance():   done");
+	print("  KeepAboveValue(10):  done");
+	print("  Count():             " + list.Count());
+	print("  ListDump:");
+	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+		print("    " + i + " => " + list.GetValue(i));
+	}
+
 	list.Valuate(AITileListRoadTile());
 	list.KeepValue(1);
 	print("  RoadTile():          done");
-	print("  KeepAboveValue(1):   done");
+	print("  KeepValue(1):        done");
 	print("  Count():             " + list.Count());
+	print("  ListDump:");
+	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
+		print("    " + i + " => " + list.GetValue(i));
+	}
+
 	list.Valuate(AITileListNeighbourRoad());
 	list.KeepValue(1);
 	print("  NeighbourRoad():     done");
-	print("  KeepAboveValue(1):   done");
+	print("  KeepValue(1):        done");
 	print("  Count():             " + list.Count());
 	print("  ListDump:");
 	for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
--- a/bin/ai/regression/regression.txt	Wed May 02 11:46:05 2007 +0000
+++ b/bin/ai/regression/regression.txt	Wed May 02 12:47:16 2007 +0000
@@ -702,13 +702,45 @@
   Count():             0
   Count():             45
   Buildable():         done
-  KeepAboveValue(1):   done
+  KeepValue(1):        done
   Count():             40
+  CargoAcceptance():   done
+  KeepAboveValue(10):  done
+  Count():             20
+  ListDump:
+    41895 => 43
+    41897 => 41
+    41383 => 40
+    41639 => 37
+    42151 => 35
+    41641 => 35
+    42153 => 33
+    41899 => 29
+    41898 => 29
+    41387 => 29
+    41386 => 29
+    41643 => 26
+    41642 => 26
+    42407 => 24
+    42409 => 22
+    42408 => 22
+    42155 => 21
+    42154 => 21
+    42411 => 13
+    42410 => 13
   RoadTile():          done
-  KeepAboveValue(1):   done
+  KeepValue(1):        done
   Count():             7
+  ListDump:
+    42409 => 1
+    42408 => 1
+    42407 => 1
+    42151 => 1
+    41895 => 1
+    41639 => 1
+    41383 => 1
   NeighbourRoad():     done
-  KeepAboveValue(1):   done
+  KeepValue(1):        done
   Count():             1
   ListDump:
     42409 => 1
--- a/src/ai/ai_squirrel.cpp	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/ai_squirrel.cpp	Wed May 02 12:47:16 2007 +0000
@@ -211,6 +211,7 @@
 	SQAISignRegister(this->engine);
 	SQAITestModeRegister(this->engine);
 	SQAITileListBuildableRegister(this->engine);
+	SQAITileListCargoAcceptanceRegister(this->engine);
 	SQAITileListNeighbourRoadRegister(this->engine);
 	SQAITileListRegister(this->engine);
 	SQAITileListRoadTileRegister(this->engine);
--- a/src/ai/api/ai_abstractlist.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_abstractlist.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -17,7 +17,7 @@
 void SQAIAbstractListRegister(Squirrel *engine) {
 	DefSQClass <AIAbstractList> SQAIAbstractList("AIAbstractList");
 	SQAIAbstractList.PreRegister(engine);
-	SQAIAbstractList.AddConstructor(engine);
+	SQAIAbstractList.AddConstructor<void (AIAbstractList::*)()>(engine);
 
 	SQAIAbstractList.DefSQStaticMethod(engine, &AIAbstractList::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_accounting.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_accounting.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIAccountingRegister(Squirrel *engine) {
 	DefSQClass <AIAccounting> SQAIAccounting("AIAccounting");
 	SQAIAccounting.PreRegister(engine);
-	SQAIAccounting.AddConstructor(engine);
+	SQAIAccounting.AddConstructor<void (AIAccounting::*)()>(engine);
 
 	SQAIAccounting.DefSQStaticMethod(engine, &AIAccounting::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_base.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_base.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIBaseRegister(Squirrel *engine) {
 	DefSQClass <AIBase> SQAIBase("AIBase");
 	SQAIBase.PreRegister(engine);
-	SQAIBase.AddConstructor(engine);
+	SQAIBase.AddConstructor<void (AIBase::*)()>(engine);
 
 	SQAIBase.DefSQStaticMethod(engine, &AIBase::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_cargo.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_cargo.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAICargoRegister(Squirrel *engine) {
 	DefSQClass <AICargo> SQAICargo("AICargo");
 	SQAICargo.PreRegister(engine);
-	SQAICargo.AddConstructor(engine);
+	SQAICargo.AddConstructor<void (AICargo::*)()>(engine);
 
 	SQAICargo.DefSQStaticMethod(engine, &AICargo::GetClassName, "GetClassName", 1, "x");
 	SQAICargo.DefSQStaticMethod(engine, &AICargo::IsValidCargo, "IsValidCargo", 2, "xi");
--- a/src/ai/api/ai_company.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_company.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAICompanyRegister(Squirrel *engine) {
 	DefSQClass <AICompany> SQAICompany("AICompany");
 	SQAICompany.PreRegister(engine);
-	SQAICompany.AddConstructor(engine);
+	SQAICompany.AddConstructor<void (AICompany::*)()>(engine);
 
 	SQAICompany.DefSQStaticMethod(engine, &AICompany::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_execmode.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_execmode.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIExecModeRegister(Squirrel *engine) {
 	DefSQClass <AIExecMode> SQAIExecMode("AIExecMode");
 	SQAIExecMode.PreRegister(engine);
-	SQAIExecMode.AddConstructor(engine);
+	SQAIExecMode.AddConstructor<void (AIExecMode::*)()>(engine);
 
 	SQAIExecMode.DefSQStaticMethod(engine, &AIExecMode::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_industry.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_industry.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIIndustryRegister(Squirrel *engine) {
 	DefSQClass <AIIndustry> SQAIIndustry("AIIndustry");
 	SQAIIndustry.PreRegister(engine);
-	SQAIIndustry.AddConstructor(engine);
+	SQAIIndustry.AddConstructor<void (AIIndustry::*)()>(engine);
 
 	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::GetClassName,    "GetClassName",    1, "x");
 	SQAIIndustry.DefSQStaticMethod(engine, &AIIndustry::IsValidIndustry, "IsValidIndustry", 2, "xi");
--- a/src/ai/api/ai_list.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_list.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIListRegister(Squirrel *engine) {
 	DefSQClass <AIList> SQAIList("AIList");
 	SQAIList.PreRegister(engine, "AIAbstractList");
-	SQAIList.AddConstructor(engine);
+	SQAIList.AddConstructor<void (AIList::*)()>(engine);
 
 	SQAIList.DefSQStaticMethod(engine, &AIList::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_map.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_map.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIMapRegister(Squirrel *engine) {
 	DefSQClass <AIMap> SQAIMap("AIMap");
 	SQAIMap.PreRegister(engine);
-	SQAIMap.AddConstructor(engine);
+	SQAIMap.AddConstructor<void (AIMap::*)()>(engine);
 
 	SQAIMap.DefSQStaticMethod(engine, &AIMap::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_order.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_order.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -15,7 +15,7 @@
 void SQAIOrderRegister(Squirrel *engine) {
 	DefSQClass <AIOrder> SQAIOrder("AIOrder");
 	SQAIOrder.PreRegister(engine);
-	SQAIOrder.AddConstructor(engine);
+	SQAIOrder.AddConstructor<void (AIOrder::*)()>(engine);
 
 	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NONE,              "AIOF_NONE");
 	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_TRANSFER,          "AIOF_TRANSFER");
--- a/src/ai/api/ai_road.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_road.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIRoadRegister(Squirrel *engine) {
 	DefSQClass <AIRoad> SQAIRoad("AIRoad");
 	SQAIRoad.PreRegister(engine);
-	SQAIRoad.AddConstructor(engine);
+	SQAIRoad.AddConstructor<void (AIRoad::*)()>(engine);
 
 	SQAIRoad.DefSQStaticMethod(engine, &AIRoad::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_settings.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_settings.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAISettingsRegister(Squirrel *engine) {
 	DefSQClass <AISettings> SQAISettings("AISettings");
 	SQAISettings.PreRegister(engine);
-	SQAISettings.AddConstructor(engine);
+	SQAISettings.AddConstructor<void (AISettings::*)()>(engine);
 
 	SQAISettings.DefSQStaticMethod(engine, &AISettings::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_sign.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_sign.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAISignRegister(Squirrel *engine) {
 	DefSQClass <AISign> SQAISign("AISign");
 	SQAISign.PreRegister(engine);
-	SQAISign.AddConstructor(engine);
+	SQAISign.AddConstructor<void (AISign::*)()>(engine);
 
 	SQAISign.DefSQStaticMethod(engine, &AISign::GetClassName, "GetClassName", 1, "x");
 	SQAISign.DefSQStaticMethod(engine, &AISign::IsValidSign,  "IsValidSign",  2, "xi");
--- a/src/ai/api/ai_testmode.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_testmode.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITestModeRegister(Squirrel *engine) {
 	DefSQClass <AITestMode> SQAITestMode("AITestMode");
 	SQAITestMode.PreRegister(engine);
-	SQAITestMode.AddConstructor(engine);
+	SQAITestMode.AddConstructor<void (AITestMode::*)()>(engine);
 
 	SQAITestMode.DefSQStaticMethod(engine, &AITestMode::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_tilelist.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_tilelist.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITileListRegister(Squirrel *engine) {
 	DefSQClass <AITileList> SQAITileList("AITileList");
 	SQAITileList.PreRegister(engine, "AIAbstractList");
-	SQAITileList.AddConstructor(engine);
+	SQAITileList.AddConstructor<void (AITileList::*)()>(engine);
 
 	SQAITileList.DefSQStaticMethod(engine, &AITileList::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_tilelist_valuator.cpp	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_tilelist_valuator.cpp	Wed May 02 12:47:16 2007 +0000
@@ -1,6 +1,8 @@
 #include "ai_tilelist_valuator.hpp"
 #include "../../tile.h"
 #include "../../road_map.h"
+#include "../../variables.h"
+#include "../../station.h"
 
 int32 AITileListBuildable::Valuate(int32 tile) const
 {
@@ -34,3 +36,13 @@
 {
 	return ::IsTileType(tile, MP_STREET) && ::GetRoadTileType(tile) != ROAD_TILE_DEPOT;
 }
+
+int32 AITileListCargoAcceptance::Valuate(int32 tile) const
+{
+	/* TODO -- Make it an enum via constructor, for now it assumes RoadVehicle Station */
+	uint rad = 3;
+
+	AcceptedCargo accepts;
+	GetAcceptanceAroundTiles(accepts, tile, 1, 1, _patches.modified_catchment ? rad : 4);
+	return accepts[this->cargo_type];
+}
--- a/src/ai/api/ai_tilelist_valuator.hpp	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_tilelist_valuator.hpp	Wed May 02 12:47:16 2007 +0000
@@ -55,4 +55,31 @@
 	int32 Valuate(int32 tile) const;
 };
 
+/**
+ * Get the amount of estimated accepted cargo for all tiles in AITileList.
+ * If this value is >= 8, it means it will accept this cargo. For passengers
+ *  and mail it is also a good indicator how much cargo would be brought to
+ *  the station.
+ * @post values < 8 means this tile does not accept this cargo.
+ * @note resulting items are of the type int32 (indicating acceptance)
+ * @note the input items are of the type TileIndex
+ */
+class AITileListCargoAcceptance : public AIAbstractList::Valuator {
+public:
+	/**
+	 * The name of the class, needed by several sub-processes.
+	 */
+	static const char *GetClassName() { return "AITileListCargoAcceptance"; }
+
+	/**
+	 * Custom constructor, we want a cargo-type as parameter.
+	 */
+	AITileListCargoAcceptance(CargoID cargo_type) { this->cargo_type = cargo_type; }
+
+private:
+	CargoID cargo_type;
+
+	int32 Valuate(int32 tile) const;
+};
+
 #endif /* AI_TILELIST_VALUATOR_HPP */
--- a/src/ai/api/ai_tilelist_valuator.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_tilelist_valuator.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITileListBuildableRegister(Squirrel *engine) {
 	DefSQClass <AITileListBuildable> SQAITileListBuildable("AITileListBuildable");
 	SQAITileListBuildable.PreRegister(engine);
-	SQAITileListBuildable.AddConstructor(engine);
+	SQAITileListBuildable.AddConstructor<void (AITileListBuildable::*)()>(engine);
 
 	SQAITileListBuildable.DefSQStaticMethod(engine, &AITileListBuildable::GetClassName, "GetClassName", 1, "x");
 
@@ -29,7 +29,7 @@
 void SQAITileListNeighbourRoadRegister(Squirrel *engine) {
 	DefSQClass <AITileListNeighbourRoad> SQAITileListNeighbourRoad("AITileListNeighbourRoad");
 	SQAITileListNeighbourRoad.PreRegister(engine);
-	SQAITileListNeighbourRoad.AddConstructor(engine);
+	SQAITileListNeighbourRoad.AddConstructor<void (AITileListNeighbourRoad::*)()>(engine);
 
 	SQAITileListNeighbourRoad.DefSQStaticMethod(engine, &AITileListNeighbourRoad::GetClassName, "GetClassName", 1, "x");
 
@@ -47,9 +47,27 @@
 void SQAITileListRoadTileRegister(Squirrel *engine) {
 	DefSQClass <AITileListRoadTile> SQAITileListRoadTile("AITileListRoadTile");
 	SQAITileListRoadTile.PreRegister(engine);
-	SQAITileListRoadTile.AddConstructor(engine);
+	SQAITileListRoadTile.AddConstructor<void (AITileListRoadTile::*)()>(engine);
 
 	SQAITileListRoadTile.DefSQStaticMethod(engine, &AITileListRoadTile::GetClassName, "GetClassName", 1, "x");
 
 	SQAITileListRoadTile.PostRegister(engine);
 }
+
+namespace SQConvert {
+	/* Allow AITileListCargoAcceptance to be used as Squirrel parameter */
+	template <> AITileListCargoAcceptance *GetParam(ForceType<AITileListCargoAcceptance *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileListCargoAcceptance *)instance; }
+	template <> AITileListCargoAcceptance &GetParam(ForceType<AITileListCargoAcceptance &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileListCargoAcceptance *)instance; }
+	template <> const AITileListCargoAcceptance *GetParam(ForceType<const AITileListCargoAcceptance *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AITileListCargoAcceptance *)instance; }
+	template <> const AITileListCargoAcceptance &GetParam(ForceType<const AITileListCargoAcceptance &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AITileListCargoAcceptance *)instance; }
+}; // namespace SQConvert
+
+void SQAITileListCargoAcceptanceRegister(Squirrel *engine) {
+	DefSQClass <AITileListCargoAcceptance> SQAITileListCargoAcceptance("AITileListCargoAcceptance");
+	SQAITileListCargoAcceptance.PreRegister(engine);
+	SQAITileListCargoAcceptance.AddConstructor<void (AITileListCargoAcceptance::*)(CargoID cargo_type)>(engine);
+
+	SQAITileListCargoAcceptance.DefSQStaticMethod(engine, &AITileListCargoAcceptance::GetClassName, "GetClassName", 1, "x");
+
+	SQAITileListCargoAcceptance.PostRegister(engine);
+}
--- a/src/ai/api/ai_town.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_town.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITownRegister(Squirrel *engine) {
 	DefSQClass <AITown> SQAITown("AITown");
 	SQAITown.PreRegister(engine);
-	SQAITown.AddConstructor(engine);
+	SQAITown.AddConstructor<void (AITown::*)()>(engine);
 
 	SQAITown.DefSQStaticMethod(engine, &AITown::GetClassName,  "GetClassName",  1, "x");
 	SQAITown.DefSQStaticMethod(engine, &AITown::IsValidTown,   "IsValidTown",   2, "xi");
--- a/src/ai/api/ai_townlist.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_townlist.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITownListRegister(Squirrel *engine) {
 	DefSQClass <AITownList> SQAITownList("AITownList");
 	SQAITownList.PreRegister(engine, "AIAbstractList");
-	SQAITownList.AddConstructor(engine);
+	SQAITownList.AddConstructor<void (AITownList::*)()>(engine);
 
 	SQAITownList.DefSQStaticMethod(engine, &AITownList::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_townlist_valuator.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_townlist_valuator.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITownListGetPopulationRegister(Squirrel *engine) {
 	DefSQClass <AITownListGetPopulation> SQAITownListGetPopulation("AITownListGetPopulation");
 	SQAITownListGetPopulation.PreRegister(engine);
-	SQAITownListGetPopulation.AddConstructor(engine);
+	SQAITownListGetPopulation.AddConstructor<void (AITownListGetPopulation::*)()>(engine);
 
 	SQAITownListGetPopulation.DefSQStaticMethod(engine, &AITownListGetPopulation::GetClassName, "GetClassName", 1, "x");
 
@@ -29,7 +29,7 @@
 void SQAITownListGetLocationRegister(Squirrel *engine) {
 	DefSQClass <AITownListGetLocation> SQAITownListGetLocation("AITownListGetLocation");
 	SQAITownListGetLocation.PreRegister(engine);
-	SQAITownListGetLocation.AddConstructor(engine);
+	SQAITownListGetLocation.AddConstructor<void (AITownListGetLocation::*)()>(engine);
 
 	SQAITownListGetLocation.DefSQStaticMethod(engine, &AITownListGetLocation::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_transactionmode.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_transactionmode.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAITransactionModeRegister(Squirrel *engine) {
 	DefSQClass <AITransactionMode> SQAITransactionMode("AITransactionMode");
 	SQAITransactionMode.PreRegister(engine);
-	SQAITransactionMode.AddConstructor(engine);
+	SQAITransactionMode.AddConstructor<void (AITransactionMode::*)()>(engine);
 
 	SQAITransactionMode.DefSQStaticMethod(engine, &AITransactionMode::GetClassName, "GetClassName", 1, "x");
 
--- a/src/ai/api/ai_vehicle.hpp.sq	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/ai_vehicle.hpp.sq	Wed May 02 12:47:16 2007 +0000
@@ -11,7 +11,7 @@
 void SQAIVehicleRegister(Squirrel *engine) {
 	DefSQClass <AIVehicle> SQAIVehicle("AIVehicle");
 	SQAIVehicle.PreRegister(engine);
-	SQAIVehicle.AddConstructor(engine);
+	SQAIVehicle.AddConstructor<void (AIVehicle::*)()>(engine);
 
 	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::GetClassName,   "GetClassName",   1, "x");
 	SQAIVehicle.DefSQStaticMethod(engine, &AIVehicle::IsValidEngine,  "IsValidEngine",  2, "xi");
--- a/src/ai/api/squirrel_export.awk	Wed May 02 11:46:05 2007 +0000
+++ b/src/ai/api/squirrel_export.awk	Wed May 02 12:47:16 2007 +0000
@@ -51,6 +51,7 @@
 /^(	*)class/     {
 	if (cls_level == 0) {
 		public = "false"
+		cls_params = ""
 		cls = $2
 		if (match($4, "public") || match($4, "protected") || match($4, "private")) {
 			super_cls = $5
@@ -166,7 +167,7 @@
 		} else {
 			print "	SQ" cls ".PreRegister(engine, \"" super_cls "\");"
 		}
-		print "	SQ" cls ".AddConstructor(engine);"
+		print "	SQ" cls ".AddConstructor<void (" cls "::*)(" cls_params ")>(engine);"
 		print ""
 
 		# Enum values
@@ -243,12 +244,17 @@
 	param_s = $0
 	gsub("\\*", "", $0)
 	gsub("\\(.*", "", $0)
-	funcname = $2
-	if (funcname == "") next
 
 	sub(".*\\(", "", param_s)
 	sub("\\).*", "", param_s)
 
+	funcname = $2
+	if ($1 == cls) {
+		cls_params = param_s
+		next
+	}
+	if (funcname == "") next
+
 	split(param_s, params, ",")
 	types = "x"
 	len = 1;
--- a/src/squirrel_class.hpp	Wed May 02 11:46:05 2007 +0000
+++ b/src/squirrel_class.hpp	Wed May 02 12:47:16 2007 +0000
@@ -29,28 +29,6 @@
 	{}
 
 	/**
-	 * The destructor, to delete the real instance.
-	 */
-	static SQInteger Destructor(SQUserPointer p, SQInteger size)
-	{
-		/* Remove the real instance too */
-		if (p != NULL) delete (CL *)p;
-		return 0;
-	}
-
-	/**
-	 * The constructor, to create the real instance.
-	 */
-	static SQInteger Constructor(HSQUIRRELVM vm)
-	{
-		/* Create the real instance */
-		CL *instance = new CL();
-		sq_setinstanceup(vm, -1, instance);
-		sq_setreleasehook(vm, -1, &DefSQClass::Destructor);
-		return 0;
-	}
-
-	/**
 	 * This defines a method inside a class for Squirrel.
 	 */
 	template <typename Func>
@@ -112,9 +90,11 @@
 		engine->AddClassBegin(this->classname, parent_class);
 	}
 
+	template <typename Func>
 	void AddConstructor(Squirrel *engine)
 	{
-		engine->AddMethod("constructor", &DefSQClass::Constructor);
+		using namespace SQConvert;
+		engine->AddMethod("constructor", DefSQConstructorCallback<CL, Func>);
 	}
 
 	void PostRegister(Squirrel *engine)
--- a/src/squirrel_helper.hpp	Wed May 02 11:46:05 2007 +0000
+++ b/src/squirrel_helper.hpp	Wed May 02 12:47:16 2007 +0000
@@ -126,6 +126,11 @@
 			(instance->*func)();
 			return 0;
 		}
+
+		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
+		{
+			return new Tcls();
+		}
 	};
 
 	/**
@@ -180,6 +185,15 @@
 			);
 			return 0;
 		}
+
+		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
+		{
+			Tcls *inst = new Tcls(
+				GetParam(ForceType<Targ1>(), vm, 2)
+			);
+
+			return inst;
+		}
 	};
 
 	/**
@@ -238,6 +252,16 @@
 			);
 			return 0;
 		}
+
+		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
+		{
+			Tcls *inst = new Tcls(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3)
+			);
+
+			return inst;
+		}
 	};
 
 	/**
@@ -300,6 +324,17 @@
 			);
 			return 0;
 		}
+
+		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
+		{
+			Tcls *inst = new Tcls(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4)
+			);
+
+			return inst;
+		}
 	};
 
 	/**
@@ -366,6 +401,18 @@
 			);
 			return 0;
 		}
+
+		static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
+		{
+			Tcls *inst = new Tcls(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4),
+				GetParam(ForceType<Targ4>(), vm, 5)
+			);
+
+			return inst;
+		}
 	};
 
 
@@ -422,6 +469,33 @@
 		return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
 	}
 
+	/**
+	 * A general template for the destructor of SQ instances. This is needed
+	 *  here as it has to be in the same scope as DefSQConstructorCallback.
+	 */
+	template <typename Tcls>
+	static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
+	{
+		/* Remove the real instance too */
+		if (p != NULL) delete (Tcls *)p;
+		return 0;
+	}
+
+	/**
+	 * A general template to handle creating of instance with any amount of
+	 *  params. It creates the instance in C++, and it sets all the needed
+	 *  settings in SQ to register the instance.
+	 */
+	template <typename Tcls, typename Tmethod>
+	inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
+	{
+		/* Create the real instance */
+		Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
+		sq_setinstanceup(vm, -1, instance);
+		sq_setreleasehook(vm, -1, DefSQDestructorCallback<Tcls>);
+		return 0;
+	}
+
 }; // namespace SQConvert
 
 #endif /* SQUIRREL_HELPER_HPP */