summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortruelight <truelight@openttd.org>2005-11-23 15:08:29 +0000
committertruelight <truelight@openttd.org>2005-11-23 15:08:29 +0000
commit8733f49e883249117580bb8457266cde858f6bac (patch)
tree39b2634d00d2ef0c50327795368bd790f4a2d3af
parentb8f8f3869d3e16aa914133c3ba2c4a66a94068bc (diff)
downloadopenttd-8733f49e883249117580bb8457266cde858f6bac.tar.xz
(svn r3232) -Add: implemented the event-system for AIs
-Add: added several hooks (event-callbacks) for road-related-stuff
-rw-r--r--ai/ai.c5
-rw-r--r--ai/ai_event.h58
-rw-r--r--order_cmd.c3
-rw-r--r--road_cmd.c7
-rw-r--r--roadveh_cmd.c4
-rw-r--r--station_cmd.c4
6 files changed, 81 insertions, 0 deletions
diff --git a/ai/ai.c b/ai/ai.c
index 764d06f94..e3fe2d307 100644
--- a/ai/ai.c
+++ b/ai/ai.c
@@ -9,6 +9,11 @@
#include "ai.h"
#include "default/default.h"
+/* Here we define the events */
+#define DEF_EVENTS
+#include "ai_event.h"
+#undef DEF_EVENTS
+
/**
* Dequeues commands put in the queue via AI_PutCommandInQueue.
*/
diff --git a/ai/ai_event.h b/ai/ai_event.h
new file mode 100644
index 000000000..7f96f71b8
--- /dev/null
+++ b/ai/ai_event.h
@@ -0,0 +1,58 @@
+#ifndef AI_EVENT
+#define AI_EVENT
+
+/* Make the ai_event macro set correctly */
+#ifdef GPMI
+# include <gpmi.h>
+# include "ai.h"
+
+/* This is how we call events (with safety-check) to GPMI */
+/* XXX -- This macro (vararg macro) isn't supported on old GCCs, but GPMI
+ * is using them too, so it isn't a real problem, yet */
+# define ai_event(player, params...) \
+ if (player < MAX_PLAYERS && _ai_player[player].module != NULL) \
+ gpmi_event(_ai_player[player].module, params)
+
+#else
+/* If GPMI isn't loaded, don't do a thing with the events (for now at least)
+ * Because old GCCs don't support vararg macros, and OTTD does support those
+ * GCCs, we need something tricky to ignore the events... and this is the solution :)
+ * Ugly, I know, but it works! */
+
+# ifdef DEF_EVENTS
+ void empty_function(PlayerID player, int event, ...) {}
+# else
+ extern void empty_function(PlayerID player, int event, ...);
+# endif
+# define ai_event empty_function
+
+#endif /* GPMI */
+
+/* To make our life a bit easier; you now only have to define new
+ * events here, and automaticly they work in OpenTTD without including
+ * the ottd_event package. Just because of some lovely macro-shit ;) */
+#ifdef DEF_EVENTS
+# define DEF_EVENTS
+# define INITIAL_SET = -1
+#else
+# define DEF_EVENTS extern
+# define INITIAL_SET
+#endif /* DEF_EVENTS */
+
+/* ------------ All available events -------------- */
+DEF_EVENTS int ottd_Event_BuildStation INITIAL_SET; // (station_index, station_tile)
+DEF_EVENTS int ottd_Event_BuildRoadStation INITIAL_SET; // (station_index, station_tile)
+
+DEF_EVENTS int ottd_Event_BuildDepot INITIAL_SET; // (depot_index, depot_tile)
+DEF_EVENTS int ottd_Event_BuildRoadDepot INITIAL_SET; // (depot_index, depot_tile)
+
+DEF_EVENTS int ottd_Event_BuildVehicle INITIAL_SET; // (vehicle_index, depot_tile)
+DEF_EVENTS int ottd_Event_BuildRoadVehicle INITIAL_SET; // (vehicle_index, depot_tile)
+
+DEF_EVENTS int ottd_Event_VehicleEnterDepot INITIAL_SET; // (vehicle_index, depot_tile)
+DEF_EVENTS int ottd_Event_RoadVehicleEnterDepot INITIAL_SET; // (vehicle_index, depot_tile)
+
+DEF_EVENTS int ottd_Event_GiveOrder INITIAL_SET; // (vehicle_index)
+/* ----------------- End of list ------------------ */
+
+#endif /* AI_EVENT */
diff --git a/order_cmd.c b/order_cmd.c
index 64c7878e0..ae32c4184 100644
--- a/order_cmd.c
+++ b/order_cmd.c
@@ -15,6 +15,7 @@
#include "news.h"
#include "saveload.h"
#include "vehicle_gui.h"
+#include "ai/ai_event.h"
enum {
/* Max orders: 64000 (64 * 1000) */
@@ -393,6 +394,8 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
/* Make sure to rebuild the whole list */
RebuildVehicleLists();
+
+ ai_event(_current_player, ottd_Event_GiveOrder, v->index);
}
return 0;
diff --git a/road_cmd.c b/road_cmd.c
index 34382402c..4592bd7a0 100644
--- a/road_cmd.c
+++ b/road_cmd.c
@@ -17,6 +17,7 @@
#include "depot.h"
#include "pbs.h"
#include "debug.h"
+#include "ai/ai_event.h"
/* When true, GetTrackStatus for roads will treat roads under reconstruction
* as normal roads instead of impassable. This is used when detecting whether
@@ -671,6 +672,8 @@ int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
(p1 | 0x20) /* map5 */
);
+ ai_event(_current_player, ottd_Event_BuildDepot, dep->index, tile);
+ ai_event(_current_player, ottd_Event_BuildRoadDepot, dep->index, tile);
}
return cost + _price.build_road_depot;
}
@@ -1156,6 +1159,10 @@ static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
if (v->type == VEH_Road && v->u.road.frame == 11) {
if (_roadveh_enter_depot_unk0[GB(_m[tile].m5, 0, 2)] == v->u.road.state) {
RoadVehEnterDepot(v);
+
+ ai_event(v->owner, ottd_Event_VehicleEnterDepot, v->index, tile);
+ ai_event(v->owner, ottd_Event_RoadVehicleEnterDepot, v->index, tile);
+
return 4;
}
}
diff --git a/roadveh_cmd.c b/roadveh_cmd.c
index 87b52cfa5..0a78127be 100644
--- a/roadveh_cmd.c
+++ b/roadveh_cmd.c
@@ -18,6 +18,7 @@
#include "sound.h"
#include "depot.h"
#include "vehicle_gui.h"
+#include "ai/ai_event.h"
void ShowRoadVehViewWindow(Vehicle *v);
@@ -195,6 +196,9 @@ int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindow(WC_COMPANY, v->owner);
if (IsLocalPlayer())
InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Road); // updates the replace Road window
+
+ ai_event(_current_player, ottd_Event_BuildVehicle, v->index, tile);
+ ai_event(_current_player, ottd_Event_BuildRoadVehicle, v->index, tile);
}
return cost;
diff --git a/station_cmd.c b/station_cmd.c
index 31391d077..631ac9214 100644
--- a/station_cmd.c
+++ b/station_cmd.c
@@ -27,6 +27,7 @@
#include "depot.h"
#include "pbs.h"
#include "train.h"
+#include "ai/ai_event.h"
enum {
/* Max stations: 64000 (64 * 1000) */
@@ -1463,6 +1464,9 @@ int32 CmdBuildRoadStop(int x, int y, uint32 flags, uint32 p1, uint32 p2)
UpdateStationVirtCoordDirty(st);
UpdateStationAcceptance(st, false);
InvalidateWindow(WC_STATION_LIST, st->owner);
+
+ ai_event(_current_player, ottd_Event_BuildStation, st->index, tile);
+ ai_event(_current_player, ottd_Event_BuildRoadStation, st->index, tile);
}
return cost;
}