ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
qd_game_object_moving.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 QDENGINE_QDCORE_QD_GAME_OBJECT_MOVING_H
23 #define QDENGINE_QDCORE_QD_GAME_OBJECT_MOVING_H
24 
25 #include "qdengine/parser/xml_fwd.h"
26 #include "qdengine/qdcore/qd_game_object_animated.h"
27 
28 namespace QDEngine {
29 
30 class qdInterfaceButton;
31 
32 const int QD_MOVING_OBJ_PATH_LENGTH = 200;
33 
36 public:
40 
41  qdGameObjectMoving &operator = (const qdGameObjectMoving &obj);
42 
43  int named_object_type() const {
44  return QD_NAMED_OBJECT_MOVING_OBJ;
45  }
46 
47  enum movement_mode_t {
48  MOVEMENT_MODE_STOP,
49  MOVEMENT_MODE_TURN,
50  MOVEMENT_MODE_START,
51  MOVEMENT_MODE_MOVE,
52  MOVEMENT_MODE_END,
53  MOVEMENT_MODE_NONE_EARLY
54  };
55 
59  CONTROL_MOUSE = 0x01,
79  // Подходить к точке привязки относительно активного
80  CONTROL_ATTACHMENT_TO_ACTIVE_WITH_MOVING = 0x800,
85  };
86 
92  FOLLOW_DONE = 0x02,
94  FOLLOW_WAIT = 0x03,
99  };
100 
101  bool has_control_type(control_type_t type) const {
102  if (_control_types & type) return true;
103  return false;
104  }
105  void add_control_type(control_type_t type) {
106  _control_types |= type;
107  }
108  void remove_control_type(control_type_t type) {
109  _control_types &= ~type;
110  }
111 
112  int get_control_types() { return _control_types; }
113  int get_movement_mode() { return _movement_mode; }
114 
115  qdGameObjectStateWalk::movement_type_t movement_type() const;
116 
117  bool is_walkable(const Vect3f &pos) const;
118  bool is_walkable(const Vect2s &pos) const;
119 
120  const Vect3f &bound(bool perspective_correction = true) const;
121  Vect3f calc_bound_in_pos(Vect3f pos, bool perspective_correction = true);
122  bool calc_walk_grid(Vect2s &center, Vect2s &size) const;
124  bool calc_cur_and_future_walk_grid(float dt, Vect2s &cen_cur, Vect2s &size_cur,
125  Vect2s &cen_next, Vect2s &size_next);
126  float radius() const;
127 
128  bool adjust_z();
129 
130  bool mouse_handler(int x, int y, mouseDispatcher::mouseEvent ev);
131 
132  float direction_angle() const {
133  return _direction_angle;
134  }
135  float calc_direction_angle(const Vect3f &target) const;
136  float animate_rotation(float dt);
137  float rotation_angle() const {
138  return _rotation_angle;
139  }
140 
141  float rotation_angle_per_quant() const {
142  return _rotation_angle_per_quant;
143  }
144  void set_rotation_angle_per_quant(float ang) {
145  _rotation_angle_per_quant = ang;
146  }
147 
148  bool set_direction(float angle);
149  int get_direction(float angle) const;
150 
151  float default_direction_angle() const {
152  return _default_direction_angle;
153  }
154  void set_default_direction(float ang) {
155  _default_direction_angle = ang;
156  }
157 
158  void set_state(int st);
159  void set_state(qdGameObjectState *p);
160 
161  void set_last_walk_state(qdGameObjectState *p) {
162  _last_walk_state = p;
163  }
164  qdGameObjectState *last_walk_state() {
165  return _last_walk_state;
166  }
167 
168  qdGameObjectState *get_default_state();
169  const qdGameObjectState *get_default_state() const;
170 
171  void merge(qdGameObjectMoving *p);
172  void split(qdGameObjectMoving *p);
173 
174  void set_button(qdInterfaceButton *p) {
175  _button = p;
176  }
177  qdInterfaceButton *button() const {
178  return _button;
179  }
180 
181  bool move(const Vect3f &target, bool lock_target = false);
182  bool move(const Vect3f &target, float angle, bool lock_target = false);
183 
184  bool move2position(const Vect3f target);
185 
186  bool skip_movement();
187  bool stop_movement();
188 
189  bool is_moving() const {
190  return check_flag(QD_OBJ_MOVING_FLAG);
191  }
192 
193  bool can_move() const;
194 
195  bool is_in_position(const Vect3f pos) const;
196  bool is_in_position(const Vect3f pos, float angle) const;
197 
198  bool is_moving2position(const Vect3f pos) const;
199  bool is_moving2position(const Vect3f pos, float angle) const;
200 
203  if (is_moving())
204  return _target_r;
205  else
206  return R();
207  }
208 
211  if (is_moving())
212  return ((_path_length) ? _path[_path_length] : _target_r);
213  else
214  return R();
215  }
216 
217  void set_scale(float sc) {
218  _scale = sc;
219  }
220  float scale() const {
221  return _scale;
222  }
223 
224  bool load_script(const xml::tag *p);
225  bool save_script(Common::WriteStream &fh, int indent = 0) const;
226 
228  bool load_data(Common::SeekableReadStream &fh, int save_version);
230  bool save_data(Common::WriteStream &fh) const;
231 
232  bool load_resources();
233 
235  bool can_change_state(const qdGameObjectState *state = NULL) const;
236 
238  bool init();
239 
240  Vect3f get_future_r(float dt, bool &end_movement, bool real_moving = false);
241  void quant(float dt);
242 
243  void redraw(int offs_x = 0, int offs_y = 0) const;
244  void drawDebugPath() const;
245  void debug_redraw() const;
246  void draw_contour(uint32 color) const;
247  void draw_shadow(int offs_x, int offs_y, uint32 color, int alpha) const;
248 
249  bool get_debug_info(Common::String &buf) const;
250 
251  grScreenRegion screen_region() const;
252 
253  bool hit(int x, int y) const;
254 
255  bool update_screen_pos();
256  Vect2s screen_size() const;
257 
258  void disable_control() {
259  _disable_control = true;
260  }
261  void enable_control() {
262  _disable_control = false;
263  }
264  bool is_control_disabled() const {
265  return _disable_control;
266  }
267 
268  bool keyboard_move();
269 
270  bool set_movement_impulse(float dir_angle);
271 
272  float collision_radius() const {
273  if (_collision_radius > FLT_EPS)
274  return _collision_radius;
275  else
276  return radius();
277  }
278 
279  void set_collision_radius(float r) {
280  _collision_radius = r;
281  }
282 
283  float collision_delay() const {
284  return _collision_delay;
285  }
286  void set_collision_delay(float r) {
287  _collision_delay = r;
288  }
289 
290  float collision_path() const {
291  return _collision_path;
292  }
293  void set_collision_path(float path) {
294  _collision_path = path;
295  }
296 
297  float follow_min_radius() const {
298  return _follow_min_radius;
299  }
300  void set_follow_min_radius(float fmr) {
301  _follow_min_radius = fmr;
302  }
303 
304  float follow_max_radius() const {
305  return _follow_max_radius;
306  }
307  void set_follow_max_radius(float fmr) {
308  _follow_max_radius = fmr;
309  }
310 
311  int follow_condition() const {
312  return _follow_condition;
313  };
314  void set_follow_condition(int cond) {
315  _follow_condition = cond;
316  };
317 
318  const Std::vector<const qdGameObjectMoving *> &const_ref_circuit_objs() const {
319  return _circuit_objs;
320  };
321  Std::vector<const qdGameObjectMoving *> &ref_circuit_objs() {
322  return _circuit_objs;
323  };
324 
325  // Для CONTROL_ATTACHMENT
326  const qdGameObjectMoving *attacher() const {
327  return _attacher;
328  }
329  void set_attacher(const qdGameObjectMoving *mov_obj);
330  const qdNamedObjectReference &attacher_ref() const {
331  return _attacher_ref;
332  }
333  Vect2s attach_shift() const {
334  return _attach_shift;
335  }
336  void set_attach_shift(Vect2s shift) {
337  _attach_shift = shift;
338  }
339 
340  Vect3f last_move_order() const {
341  return _last_move_order;
342  };
343  void set_last_move_order(const Vect3f &pnt) {
344  _last_move_order = pnt;
345  };
346 
347  bool avoid_collision(const qdGameObjectMoving *p);
348  bool move_from_personage_path();
349 
350  bool toggle_grid_zone(bool make_walkable = false);
351  void toggle_selection(bool state) {
352  _is_selected = state;
353  }
354 
355  void set_path_attributes(int attr) const;
356  void clear_path_attributes(int attr) const;
357 
358  static Common::String control2str(int control, bool truncate = false);
359  static Common::String movement2str(int movement, bool truncate = false);
360 
361 protected:
362 
363  bool load_script_body(const xml::tag *p);
364  bool save_script_body(Common::WriteStream &fh, int indent = 0) const;
365 
366 private:
367 
369 
372  float _collision_radius;
374  float _collision_delay;
376  float _collision_path;
377 
379  float _follow_min_radius;
380  float _follow_max_radius;
381 
383  int _follow_condition;
386 
388  const qdGameObjectMoving *_attacher; // Объект, который присоединяет к себе наш объект
389  qdNamedObjectReference _attacher_ref;
390  Vect2s _attach_shift; // Позиция нашего объекта - смещение от центра attacher'а
391 
393  int _control_types;
394 
395  bool _disable_control;
396 
397  bool _impulse_movement_mode;
398  float _impulse_timer;
399  float _impulse_start_timer;
400  float _impulse_direction;
401 
402  movement_mode_t _movement_mode;
403  float _movement_mode_time;
404  float _movement_mode_time_current;
405 
406  float _scale;
407  float _direction_angle;
408  float _rotation_angle;
409  float _rotation_angle_per_quant;
410 
411  float _default_direction_angle;
412 
413  float _speed_delta;
414 
415  Vect3f _last_move_order;
416 
417  Vect3f _target_r;
418  int _path_length;
419  int _cur_path_index;
420  float _target_angle;
421  Vect3f _path[QD_MOVING_OBJ_PATH_LENGTH];
422 
423  Vect2s _walk_grid_size;
424  qdGameObjectState *_last_walk_state;
425 
426  bool _ignore_personages;
427  bool _is_selected;
428 
429  mutable qdInterfaceButton *_button;
430 
431  Vect2s get_nearest_walkable_point(const Vect2s &target) const;
433  Vect2s get_pre_last_walkable_point(const Vect2s &target) const;
434  bool is_path_walkable(int x1, int y1, int x2, int y2) const;
435  bool is_path_walkable(const Vect2i &src, const Vect2i &trg) const {
436  return is_path_walkable(src.x, src.y, trg.x, trg.y);
437  }
438  bool is_path_walkable(const Vect3f &src, const Vect3f &trg) const;
439  bool enough_far_target(const Vect3f &dest) const;
440 
441  void toggle_ignore_personages(bool state) {
442  _ignore_personages = state;
443  }
444 
445  bool find_path(const Vect3f target, bool lock_target = false);
446 
447  void optimize_path(Std::vector<Vect2i> &path) const;
448 
449  void optimize_path_four_dirs(Std::list<Vect2i> &path) const;
450  // Спрямление четырех точек для пути с восемью направлениями
451  bool four_pts_eight_dir_straight(Std::list<Vect2i> &path,
453  // Удаляем точки, лежащие внутри прямых отрезков пути
454  bool del_coll_pts(Std::list<Vect2i> &path) const;
455  void optimize_path_eight_dirs(Std::list<Vect2i> &path) const;
456  void optimize_path_smooth(Std::list<Vect2i> &path) const;
457  void finalize_path(const Vect3f &from, const Vect3f &to, const Std::vector<Vect2i> &path, Std::vector<Vect3f> &out_path) const;
458 
459  bool adjust_position(Vect3f &pos) const;
460  bool adjust_direction_angle(float &angle);
461 
462  void change_direction_angle(float angle);
463 
464  bool is_direction_allowed(float angle) const;
465  int allowed_directions_count() const;
466 
467  float calc_scale() const {
468  return calc_scale(R());
469  }
470  float calc_scale(const Vect3f &r) const;
471 
472  bool set_walk_animation();
473  bool movement_impulse();
474 
475  float speed();
476  bool get_speed_parameters(float &speed, float &speed_max, float &acceleration);
477 
478  const qdGameObjectStateWalk *current_walk_state() const;
479 
480  bool adjust_position(Vect3f &pos, float dir_angle) const;
481 
482  Vect2s walk_grid_size(const Vect3f &r) const;
483  Vect2s walk_grid_size(const Vect2s &r) const;
484  Vect2s walk_grid_size() const {
485  return walk_grid_size(R());
486  }
487 
488  bool start_auto_move();
489 
491  bool future_pos_correct(float dt);
492 
494  bool is_movement_finished() const;
495 };
496 
497 } // namespace QDEngine
498 
499 #endif // QDENGINE_QDCORE_QD_GAME_OBJECT_MOVING_H
можно толкать другим персонажем
Definition: qd_game_object_moving.h:63
Definition: vector.h:39
автоматически двигаться
Definition: qd_game_object_moving.h:67
Definition: str.h:59
float radius() const
Возвращает радиус объекта.
Definition: stream.h:77
сгонять с пути других персонажей, если блокируют дорогу
Definition: qd_game_object_moving.h:69
Vect3f target_position() const
Точка, к которой движется персонаж.
Definition: qd_game_object_moving.h:210
Все ок
Definition: qd_game_object_moving.h:92
control_type_t
режимы управления персонажем
Definition: qd_game_object_moving.h:57
bool save_data(Common::WriteStream &fh) const
Запись данных в сэйв.
Definition: list.h:41
Definition: list.h:39
Vect3f local_target_position() const
Текущая точка, к которой движется персонаж.
Definition: qd_game_object_moving.h:202
Definition: stream.h:745
можно указывать мышью точки куда идти
Definition: qd_game_object_moving.h:59
Dynamic object.
Definition: qd_game_object_animated.h:37
Режим с анимацией поворота
Definition: qd_game_object_moving.h:84
follow_condition_t
флаги следования
Definition: qd_game_object_moving.h:88
Definition: xmath.h:419
Состояние динамического объекта - базовый класс.
Definition: qd_game_object_state.h:91
автоматически избегать столкновений с другими персонажами
Definition: qd_game_object_moving.h:65
bool check_flag(int fl) const
Возвращает true, если установлен флаг fl.
Definition: qd_named_object.h:99
Интерфейсный элемент - кнопка.
Definition: qd_interface_button.h:33
Definition: qd_named_object_reference.h:35
XML тег.
Definition: xml_tag.h:33
bool can_change_state(const qdGameObjectState *state=NULL) const
Возвращает true, если объект в данный момент может менять состояние.
Базовый класс для игровых ресурсов.
Definition: console.h:28
Definition: xmath.h:268
bool get_debug_info(Common::String &buf) const
Копирует в буфер отладочную информацию для вывода на экран в отладочном режиме.
bool calc_cur_and_future_walk_grid(float dt, Vect2s &cen_cur, Vect2s &size_cur, Vect2s &cen_next, Vect2s &size_next)
Возвращает текущее положение сетки движения, и положение сетки через dt.
int named_object_type() const
Возвращает тип объекта.
Definition: qd_game_object_moving.h:43
Режим реагирования на клик активному персонажу (персонаж бежит туда же)
Definition: qd_game_object_moving.h:82
Персонаж следует
Definition: qd_game_object_moving.h:98
Персонаж.
Definition: qd_game_object_moving.h:35
movement_type_t
режимы передвижения для персонажа
Definition: qd_game_object_state.h:725
Персонаж ждет остановки всех следующих персонажей, чтобы продолжить следование
Definition: qd_game_object_moving.h:96
Жесткая привязка персонажа к заданному персонажу
Definition: qd_game_object_moving.h:75
Состояние динамического объекта - походка.
Definition: qd_game_object_state.h:715
bool init()
Инициализация объекта, вызывается при старте и перезапуске игры.
Персонаж стремится не отходить от активного персонажа более чем на некоторый радиус ...
Definition: qd_game_object_moving.h:71
mouseEvent
События.
Definition: mouse_input.h:41
Definition: xmath.h:533
Прямоугольная область на экране.
Definition: gr_screen_region.h:31
Для персонажа нужно просчитать путь следования
Definition: qd_game_object_moving.h:90
const Vect3f & bound(bool perspective_correction=true) const
Возвращает баунд объекта.
bool load_data(Common::SeekableReadStream &fh, int save_version)
Загрузка данных из сэйва.
можно рулить с клавиатуры
Definition: qd_game_object_moving.h:61
Персонаж пытается двигаться в ту же сторону, что и активный
Definition: qd_game_object_moving.h:73
Персонаж ждет, когда можно будет возобновить попытку следования
Definition: qd_game_object_moving.h:94