ScummVM API documentation
timed_event.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NUVIE_CORE_TIMED_EVENT_H
23 #define NUVIE_CORE_TIMED_EVENT_H
24 
25 #include "ultima/shared/std/string.h"
26 #include "ultima/nuvie/misc/call_back.h"
27 #include "ultima/nuvie/core/obj_manager.h"
28 
29 namespace Ultima {
30 namespace Nuvie {
31 
32 class Actor;
33 class CallBack;
34 class Events;
35 class GameClock;
36 class MapCoord;
37 class MapWindow;
38 class MsgScroll;
39 class Party;
40 class TimedCallbackTarget;
41 class TimedEvent;
42 
43 /* A queue for our events.
44  */
45 class TimeQueue {
47 public:
48  TimeQueue() : tq() { }
49  ~TimeQueue() {
50  clear();
51  }
52 
53  bool empty() const {
54  return tq.empty();
55  }
56  void clear();
57  void add_timer(TimedEvent *tevent);
58  void remove_timer(TimedEvent *tevent);
59  TimedEvent *pop_timer();
60  bool delete_timer(TimedEvent *tevent);
61 
62  bool call_timer(uint32 now); // activate
63  void call_timers(uint32 now); // activate all
64 };
65 
66 
67 #define TIMER_IMMEDIATE true
68 #define TIMER_DELAYED false
69 #define TIMER_REALTIME true
70 #define TIMER_GAMETIME false
71 
72 /* Events activated by a timer. Add to one of the Events time-queues to start.
73  * (THERE IS ONLY ONE SET) The timed() method is called on activation,
74  * and the timer may be automatically deleted or repeated.
75  */
76 class TimedEvent {
77  friend class TimeQueue;
78  friend class Events;
79 protected:
80  TimeQueue *tq; // the TimeQueue; so we can add ourself
81  uint32 delay, time; // timer delay, and next absolute time to activate
82  sint8 repeat_count; // repeat how many times? (-1=infinite;0=stop)
83  bool ignore_pause; // activates even if game is paused
84  bool real_time; // time and delay is in milliseconds (false=game ticks/turns)
85  bool tq_can_delete; // can TimeQueue delete this TimedEvent when done?
86  bool defunct; // deleted; don't activate (use to stop timers from outside)
87 
88 public:
89  TimedEvent(uint32 reltime, bool immediate = TIMER_DELAYED, bool realtime = TIMER_REALTIME);
90  virtual ~TimedEvent() { }
91  virtual void timed(uint32 evtime) {
92  DEBUG(0, LEVEL_ERROR, "TimedEvent: undefined timer method\n");
93  }
94 
95 protected:
96  // stop repeating, remove from tq if it won't delete it
97  // NOTE: potential for bug here, this doesn't prevent it from being called once more
98  void stop() {
99  repeat_count = 0;
100  if (!tq_can_delete) dequeue();
101  }
102  // repeat once (or for requested count)
103  void repeat(uint32 count = 1) {
104  repeat_count = count;
105  }
106 
107 public:
108  void queue(); // set tq, add to tq
109  void dequeue(); // remove from tq, clear tq
110 
111  void set_time(); // set `time' from `delay'
112  void stop_timer() {
113  stop();
114  defunct = true;
115  }
116 };
117 
118 
119 /* Print to stdout. (timer test)
120  */
121 class TimedMessage : public TimedEvent {
122  Std::string msg;
123 public:
124  TimedMessage(uint32 reltime, const char *m, bool repeating = false)
125  : TimedEvent(reltime), msg(m) {
126  repeat_count = repeating ? -1 : 0;
127  }
128  void timed(uint32 evtime) override {
129  DEBUG(0, LEVEL_NOTIFICATION, "Activate! evtime=%d msg=\"%s\"\n", evtime, msg.c_str());
130  }
131 };
132 
133 
134 /* Move the party to/from a dungeon or ladder or moongate. Characters off-screen
135  * will teleport.
136  */
137 class TimedPartyMove : public TimedEvent, public CallBack {
138 protected:
139  MapWindow *map_window;
140  Party *party; // the party
141  MapCoord *dest; // destination, where all actors walk to and disappear
142  MapCoord *target; // where they reappear at the new plane
143  uint32 moves_left; // walk timeout
144  Obj *moongate; // if using a moongate
145  uint8 wait_for_effect; // waiting for a visual effect to complete if not 0
146  Actor *actor_to_hide; // this actor has reached exit and should be hidden
147  bool falling_in;
148 
149 public:
150  TimedPartyMove(MapCoord *d, MapCoord *t, uint32 step_delay = 500);
151  TimedPartyMove(MapCoord *d, MapCoord *t, Obj *use_obj, uint32 step_delay = 500);
152  TimedPartyMove(uint32 step_delay = 500);
153  ~TimedPartyMove() override;
154  void init(MapCoord *d, MapCoord *t, Obj *use_obj);
155  void timed(uint32 evtime) override;
156 
157  uint16 callback(uint16 msg, CallBack *caller, void *data = nullptr) override;
158 
159 protected:
160  bool move_party();
161  bool fall_in();
162  void hide_actor(Actor *person);
163  void change_location();
164 };
165 
166 
167 /* Move the party into a vehicle and start it when everyone is there.
168  */
170  Obj *ship_obj; // vehicle center
171 public:
172  TimedPartyMoveToVehicle(MapCoord *d, Obj *obj, uint32 step_delay = 125);
173  void timed(uint32 evtime) override;
174 };
175 
176 
177 #if 0
178 class TimedRTC : public TimedEvent {
179 public:
180  TimedRTC() : TimedEvent(1000) {
181  repeat_count = -1;
182  }
183  void timed(uint32 evtime) {
184 // Game::get_game()->get_player()->pass();
185  }
186 };
187 #endif
188 
189 
190 //FIXME: It isnt container search. Its a msgscroll effect to print one line at a time.
191 /* Dump one item at a time out of a container, and print it's name to MsgScroll.
192  */
194  MsgScroll *scroll;
195  UseCode *uc;
196  ObjManager *om;
197  Obj *container_obj;
198  Obj *prev_obj; // removed from container
199 public:
201  void timed(uint32 evtime) override;
202 };
203 
204 
205 /* Send timer message to callback target after `wait_time' is up, passing it
206  * some target-defined data.
207  * new TimedCallback(PowderKeg, (void *)my_powderkeg_data, time_to_explode);
208  */
209 class TimedCallback : public TimedEvent, public CallBack {
210 public:
211  TimedCallback(CallBack *t, void *d, uint32 wait_time,
212  bool repeat = false);
213  ~TimedCallback() override { }
214  void timed(uint32 evtime) override;
215  void clear_target() {
216  set_target(nullptr);
217  }
218 };
219 
220 
222 public:
223  GameTimedCallback(CallBack *t, void *d, uint32 wait_time, bool repeat = false);
224  ~GameTimedCallback() override { }
225 };
226 
227 
228 /* Advance gameclock up to 24hours from start time. The callback is used every
229  * hour from the start time, up to and including the stop time.
230  */
231 class TimedAdvance : public TimedCallback {
232  GameClock *_clock;
233  uint16 advance; // minutes requested
234  uint8 minutes_this_hour;
235 protected:
236  uint16 minutes; // minutes advanced
237  uint16 rate; // rate is minutes-per-second
238  uint32 prev_evtime; // last time the timer was called
239 
240 public:
241  TimedAdvance(uint8 hours, uint16 r = 60);
242  TimedAdvance(Std::string timestring, uint16 r = 60); // "HH:MM"
243  ~TimedAdvance() override { }
244 
245  void init(uint16 min, uint16 r); // start time advance
246 
247  void timed(uint32 evtime) override;
248  bool time_passed() const; // returns true if stop time has passed
249  void get_time_from_string(uint8 &hour, uint8 &minute, Std::string timestring);
250 };
251 
252 
253 /* Camping in the wilderness. Move everyone into a circle and place a campfire
254  * in the center.
255  */
257 public:
258  TimedRestGather(uint16 x, uint16 y);
259 
260  void timed(uint32 evtime) override;
261 
262 protected:
263  bool move_party();
264  void check_campfire();
265 };
266 
267 /* Camping in the wilderness. Do a TimedAdvance until the requested time. The
268  * camp can be broken by nearby foes.
269  */
270 class TimedRest : public TimedAdvance {
271  Party *party;
272  MsgScroll *scroll;
273  Actor *lookout;
274  bool sleeping; // false: mealtime, true: sleeping
275  uint8 print_message; // which message is to be printed next
276  Obj *campfire;
277  uint8 number_that_had_food;
278 public:
279  TimedRest(uint8 hours, Actor *lookout, Obj *campfire_obj);
280  ~TimedRest() override;
281 
282  void timed(uint32 evtime) override;
283  void eat(Actor *actor);
284  void bard_play();
285  void sleep();
286 };
287 
288 } // End of namespace Nuvie
289 } // End of namespace Ultima
290 
291 #endif
Definition: map_window.h:73
Definition: actor.h:178
Definition: msg_scroll.h:93
Definition: obj.h:84
Definition: usecode.h:151
Definition: timed_event.h:137
Definition: timed_event.h:256
Definition: game_clock.h:49
Definition: timed_event.h:221
Definition: events.h:183
Definition: party.h:92
Definition: timed_event.h:209
Definition: detection.h:27
Definition: timed_event.h:45
Definition: timed_event.h:270
Definition: call_back.h:50
Definition: timed_event.h:76
Definition: string.h:30
Definition: timed_event.h:169
Definition: map.h:84
Definition: containers.h:200
Definition: obj_manager.h:75
Definition: timed_event.h:231
Definition: timed_event.h:193
Definition: timed_event.h:121
bool empty() const
Definition: list.h:219