Apply the new ground_level method.
[crawl.git] / crawl-ref / source / dgnevent.cc
blob451813ea6fd4e24718f1f7be9da906934e437523
1 /*
2 * File: dgnevent.cc
3 * Summary: General dungeon events.
4 * Created by: dshaligram on Sat Jul 21 12:17:29 2007 UTC
5 */
7 #include "AppHdr.h"
9 #include "dgnevent.h"
11 #include "coord.h"
12 #include <algorithm>
14 dgn_event_dispatcher dungeon_events;
16 void dgn_event_dispatcher::clear()
18 global_event_mask = 0;
19 listeners.clear();
20 for (int y = 0; y < GYM; ++y)
21 for (int x = 0; x < GXM; ++x)
22 grid_triggers[x][y].reset(NULL);
25 void dgn_event_dispatcher::clear_listeners_at(const coord_def &pos)
27 grid_triggers[pos.x][pos.y].reset(NULL);
30 void dgn_event_dispatcher::move_listeners(
31 const coord_def &from, const coord_def &to)
33 // Any existing listeners at to will be discarded. YHBW.
34 grid_triggers[to.x][to.y] = grid_triggers[from.x][from.y];
37 bool dgn_event_dispatcher::has_listeners_at(const coord_def &pos) const
39 return (grid_triggers[pos.x][pos.y].get());
42 bool dgn_event_dispatcher::fire_vetoable_position_event(
43 dgn_event_type et, const coord_def &pos)
45 const dgn_event event(et, pos);
46 return fire_vetoable_position_event(event, pos);
49 bool dgn_event_dispatcher::fire_vetoable_position_event(
50 const dgn_event &et, const coord_def &pos)
52 dgn_square_alarm *alarm = grid_triggers[pos.x][pos.y].get();
53 if (alarm && (alarm->eventmask & et.type))
55 dgn_square_alarm alcopy(*alarm);
56 for (std::list<dgn_event_listener*>::iterator
57 i = alcopy.listeners.begin();
58 i != alcopy.listeners.end(); ++i)
60 if (!(*i)->notify_dgn_event(et))
61 return (false);
64 return (true);
67 void dgn_event_dispatcher::fire_position_event(
68 dgn_event_type event, const coord_def &pos)
70 const dgn_event et(event, pos);
71 fire_position_event(et, pos);
74 void dgn_event_dispatcher::fire_position_event(
75 const dgn_event &et, const coord_def &pos)
77 dgn_square_alarm *alarm = grid_triggers[pos.x][pos.y].get();
78 if (alarm && (alarm->eventmask & et.type))
80 dgn_square_alarm alcopy = *alarm;
81 for (std::list<dgn_event_listener*>::iterator
82 i = alcopy.listeners.begin();
83 i != alcopy.listeners.end(); ++i)
85 (*i)->notify_dgn_event(et);
90 void dgn_event_dispatcher::fire_event(const dgn_event &e)
92 if (global_event_mask & e.type)
94 std::list<dgn_listener_def> lcopy = listeners;
95 for (std::list<dgn_listener_def>::iterator i = lcopy.begin();
96 i != lcopy.end(); ++i)
98 if (i->eventmask & e.type)
99 i->listener->notify_dgn_event(e);
104 void dgn_event_dispatcher::fire_event(dgn_event_type et)
106 fire_event(dgn_event(et));
109 void dgn_event_dispatcher::register_listener(unsigned mask,
110 dgn_event_listener *listener,
111 const coord_def &pos)
113 if (in_bounds(pos))
114 register_listener_at(mask, pos, listener);
115 else
117 global_event_mask |= mask;
118 for (std::list<dgn_listener_def>::iterator i = listeners.begin();
119 i != listeners.end(); ++i)
121 if (i->listener == listener)
123 i->eventmask |= mask;
124 return;
127 listeners.push_back(dgn_listener_def(mask, listener));
131 void dgn_event_dispatcher::register_listener_at(unsigned mask,
132 const coord_def &c,
133 dgn_event_listener *listener)
135 if (!grid_triggers[c.x][c.y].get())
136 grid_triggers[c.x][c.y].reset(new dgn_square_alarm);
138 dgn_square_alarm *alarm = grid_triggers[c.x][c.y].get();
139 alarm->eventmask |= mask;
140 if (std::find(alarm->listeners.begin(), alarm->listeners.end(),
141 listener) == alarm->listeners.end())
142 alarm->listeners.push_back(listener);
145 void dgn_event_dispatcher::remove_listener(dgn_event_listener *listener,
146 const coord_def &pos)
148 if (in_bounds(pos))
149 remove_listener_at(pos, listener);
150 else
152 for (std::list<dgn_listener_def>::iterator i = listeners.begin();
153 i != listeners.end(); ++i)
155 if (i->listener == listener)
157 listeners.erase(i);
158 return;
164 void dgn_event_dispatcher::remove_listener_at(const coord_def &pos,
165 dgn_event_listener *listener)
167 if (dgn_square_alarm *alarm = grid_triggers[pos.x][pos.y].get())
169 std::list<dgn_event_listener*>::iterator i =
170 std::find(alarm->listeners.begin(), alarm->listeners.end(),
171 listener);
172 if (i != alarm->listeners.end())
173 alarm->listeners.erase(i);
177 /////////////////////////////////////////////////////////////////////////////
178 // dgn_event_listener
180 dgn_event_listener::~dgn_event_listener()