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