00001
00002
00003
00004
00005
00006
00007 #ifndef __DGNEVENT_H__
00008 #define __DGNEVENT_H__
00009
00010 #include "externs.h"
00011 #include "player.h"
00012 #include <list>
00013
00014
00015 enum dgn_event_type
00016 {
00017 DET_NONE = 0x0000,
00018
00019 DET_TURN_ELAPSED = 0x0001,
00020 DET_MONSTER_MOVED = 0x0002,
00021 DET_PLAYER_MOVED = 0x0004,
00022 DET_LEAVING_LEVEL = 0x0008,
00023 DET_ENTERING_LEVEL = 0x0010,
00024 DET_ENTERED_LEVEL = 0x0020,
00025 DET_PLAYER_IN_LOS = 0x0040,
00026 DET_PLAYER_CLIMBS = 0x0080,
00027 DET_MONSTER_DIED = 0x0100,
00028 DET_ITEM_PICKUP = 0x0200,
00029 DET_ITEM_MOVED = 0x0400,
00030 DET_FEAT_CHANGE = 0x0800,
00031 DET_WALL_HIT = 0x1000,
00032 DET_DOOR_OPENED = 0x2000,
00033 DET_DOOR_CLOSED = 0x4000,
00034 DET_HP_WARNING = 0x8000,
00035 DET_PRESSURE_PLATE = 0x10000,
00036
00037 DET_GLOBAL_MASK = DET_TURN_ELAPSED | DET_LEAVING_LEVEL
00038 | DET_ENTERING_LEVEL | DET_ENTERED_LEVEL
00039 | DET_MONSTER_DIED | DET_HP_WARNING,
00040
00041 DET_POSITION_MASK = DET_MONSTER_MOVED | DET_PLAYER_MOVED
00042 | DET_PLAYER_IN_LOS | DET_ITEM_PICKUP
00043 | DET_ITEM_MOVED | DET_FEAT_CHANGE | DET_WALL_HIT
00044 | DET_DOOR_OPENED | DET_DOOR_CLOSED
00045 | DET_PRESSURE_PLATE,
00046 };
00047
00048 class dgn_event
00049 {
00050 public:
00051 dgn_event_type type;
00052 coord_def place;
00053 int elapsed_ticks;
00054 int arg1, arg2;
00055 coord_def dest;
00056
00057 public:
00058 dgn_event(dgn_event_type t, const coord_def &p = coord_def(),
00059 int ticks = you.time_taken, int a1 = 0, int a2 = 0,
00060 const coord_def &d = coord_def())
00061 : type(t), place(p), elapsed_ticks(ticks), arg1(a1),
00062 arg2(a2), dest(d)
00063 {
00064 }
00065 };
00066
00067 class dgn_event_listener
00068 {
00069 public:
00070 virtual ~dgn_event_listener();
00071
00072 virtual bool notify_dgn_event(const dgn_event &e) = 0;
00073 };
00074
00075
00076 struct dgn_square_alarm
00077 {
00078 dgn_square_alarm() : eventmask(0), listeners() { }
00079
00080 unsigned eventmask;
00081 std::list<dgn_event_listener*> listeners;
00082 };
00083
00084 struct dgn_listener_def
00085 {
00086 dgn_listener_def(unsigned mask, dgn_event_listener *l)
00087 : eventmask(mask), listener(l)
00088 {
00089 }
00090
00091 unsigned eventmask;
00092 dgn_event_listener *listener;
00093 };
00094
00095
00096
00097
00098 class dgn_event_dispatcher
00099 {
00100 public:
00101 dgn_event_dispatcher() : global_event_mask(0), grid_triggers()
00102 {
00103 }
00104
00105 void clear();
00106 void clear_listeners_at(const coord_def &pos);
00107 bool has_listeners_at(const coord_def &pos) const;
00108 void move_listeners(const coord_def &from, const coord_def &to);
00109
00110
00111 bool fire_vetoable_position_event(const dgn_event &e,
00112 const coord_def &pos);
00113
00114 bool fire_vetoable_position_event(dgn_event_type et,
00115 const coord_def &pos);
00116
00117 void fire_position_event(dgn_event_type et, const coord_def &pos);
00118 void fire_position_event(const dgn_event &e, const coord_def &pos);
00119 void fire_event(dgn_event_type et);
00120 void fire_event(const dgn_event &e);
00121
00122 void register_listener(unsigned evmask, dgn_event_listener *,
00123 const coord_def &pos = coord_def());
00124 void remove_listener(dgn_event_listener *,
00125 const coord_def &pos = coord_def());
00126 private:
00127 void register_listener_at(unsigned mask, const coord_def &pos,
00128 dgn_event_listener *l);
00129 void remove_listener_at(const coord_def &pos, dgn_event_listener *l);
00130
00131 private:
00132 unsigned global_event_mask;
00133 std::auto_ptr<dgn_square_alarm> grid_triggers[GXM][GYM];
00134 std::list<dgn_listener_def> listeners;
00135 };
00136
00137 extern dgn_event_dispatcher dungeon_events;
00138
00139 #endif