1 #ifndef __BTANKS_ANIMATED_OBJECT__ 2 #define __BTANKS_ANIMATED_OBJECT__ 3 4 /* Battle Tanks Game 5 * Copyright (C) 2006-2009 Battle Tanks team 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (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, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 /* 23 * Additional rights can be granted beyond the GNU General Public License 24 * on the terms provided in the Exception. If you modify this file, 25 * you may extend this exception to your version of the file, 26 * but you are not obligated to do so. If you do not wish to provide this 27 * exception without modification, you must delete this exception statement 28 * from your version and license this file solely under the GPL without exception. 29 */ 30 31 #include <string> 32 #include <map> 33 #include <set> 34 #include <queue> 35 36 #include "export_btanks.h" 37 #include "base_object.h" 38 #include "alarm.h" 39 #include "math/v2.h" 40 #include "math/matrix.h" 41 #include "object_common.h" 42 43 namespace sdlx { 44 class Rect; 45 class Surface; 46 class CollisionMap; 47 } 48 49 namespace clunk { 50 class Object; 51 } 52 53 class AnimationModel; 54 class Animation; 55 class Pose; 56 57 class BTANKSAPI Object : public BaseObject { 58 public: 59 const v2<float> get_relative_position(const Object *obj) const; get_position()60 inline const v2<float> get_position() const { return _parent == NULL? _position: _position + _parent->get_position(); } 61 62 template<typename T> get_position(v2<T> & position)63 inline void get_position(v2<T> &position) const { 64 position = _position.convert<T>(); 65 if (_parent != NULL) { 66 v2<T> ppos; 67 _parent->get_position(ppos); 68 position += ppos; 69 } 70 } 71 get_center_position()72 inline const v2<float> get_center_position() const { return get_position() + size / 2; } 73 template<typename T> get_center_position(v2<T> & position)74 inline void get_center_position(v2<T> &position) const { get_position<T>(position); position += (size / 2).convert<T>(); } 75 76 const std::string registered_name; 77 78 std::string animation; 79 float fadeout_time; 80 81 Object(const std::string &classname); //do not use parent - internal 82 ~Object(); 83 84 void init(const std::string &animation); //do not use it, needed for resman 85 86 virtual Object * clone() const; 87 Object * deep_clone() const; 88 89 bool playing_sound(const std::string &name) const; 90 void play_sound(const std::string &name, const bool loop, const float gain = 1.0); 91 void play_random_sound(const std::string &classname, const bool loop, const float gain = 1.0); 92 void fadeout_sound(const std::string &name); 93 get_direction()94 inline const int get_direction() const { return _direction_idx; } get_directions_number()95 inline const int get_directions_number() const { return _directions_n; } 96 virtual void set_direction(const int dir); 97 void set_directions_number(const int dirs); 98 99 virtual void tick(const float dt); 100 virtual void render(sdlx::Surface &surface, const int x, const int y); 101 const bool collides(const Object *other, const int x, const int y, const bool hidden_by_other = false) const; 102 const bool collides(const sdlx::CollisionMap *other, const int x, const int y, const bool hidden_by_other = false) const; 103 104 // animation: 105 void play(const std::string &id, const bool repeat = false); 106 void play_now(const std::string &id); 107 void cancel(); 108 void cancel_repeatable(); 109 void cancel_all(); get_state()110 inline const std::string& get_state() const { 111 static const std::string empty; 112 if (_events.empty()) 113 return empty; 114 return _events.front().name; 115 } 116 const float get_state_progress() const; 117 //effects 118 void add_effect(const std::string &name, const float ttl = -1); has_effect(const std::string & name)119 inline const bool has_effect(const std::string &name) const { 120 return _effects.find(name) != _effects.end(); 121 } 122 const float get_effect_timer(const std::string &name) const; 123 void remove_effect(const std::string &name); 124 125 virtual void add_damage(Object *from, const int hp, const bool emitDeath = true); 126 void add_damage(Object *from, const bool emitDeath = true); 127 128 virtual void emit(const std::string &event, Object * emitter = NULL); 129 virtual void serialize(mrt::Serializator &s) const; 130 virtual void deserialize(const mrt::Serializator &s); 131 132 void serialize_all(mrt::Serializator &s) const; 133 134 virtual void on_spawn(); 135 rotating()136 inline const bool rotating() const { return _direction_idx != _dst_direction; } 137 138 virtual void calculate(const float dt); 139 140 virtual const std::string getType() const; 141 virtual const int getCount() const; 142 143 const Object *get(const std::string &name) const; 144 const bool has(const std::string &name) const; 145 146 const float getWeaponRange(const std::string &weapon) const; 147 148 const int get_target_position(v2<float> &relative_position, const v2<float> &target, const std::string &weapon) const; 149 const int get_target_position(v2<float> &relative_position, const v2<float> &target, const float range) const; 150 const int get_target_position(v2<float> &relative_position, const std::set<std::string> &targets, const std::string &weapon) const; 151 const int get_target_position(v2<float> &relative_position, const std::set<std::string> &targets, const float range) const; 152 153 void quantize_velocity(); 154 get_way()155 inline const Way& get_way() const { return _way; } 156 void set_way(const Way & way); 157 const bool is_driven() const; 158 159 const std::string get_nearest_waypoint(const std::string &classname) const; 160 161 void set_zbox(const int z); 162 163 virtual const bool detachVehicle(); 164 virtual const bool attachVehicle(Object *vehicle); 165 166 const int get_children(const std::string &classname) const; 167 void enumerate_objects(std::set<const Object *> &o_set, const float range, const std::set<std::string> *classfilter) const; 168 169 static const bool check_distance(const v2<float> &map1, const v2<float>& map2, const int z, const bool use_pierceable_fixes); 170 171 const bool ai_disabled() const; 172 virtual const bool take(const BaseObject *obj, const std::string &type); 173 174 Object * spawn(const std::string &classname, const std::string &animation, const v2<float> &dpos = v2<float>(), const v2<float> &vel = v2<float>(), const int z = 0); 175 invalidate()176 void invalidate() { set_sync(true); } 177 178 //grouped object handling 179 void pick(const std::string &name, Object *object); //picks up object and insert as group one, i.e. ctf-flag 180 Object *drop(const std::string &name, const v2<float> &dpos = v2<float>()); //pops object and inserts into world again 181 182 Object *add(const std::string &name, const std::string &classname, const std::string &animation, const v2<float> &dpos, const GroupType type); 183 Object *get(const std::string &name); 184 void remove(const std::string &name); 185 void group_emit(const std::string &name, const std::string &event); 186 187 const bool get_render_rect(sdlx::Rect &src) const; 188 is_subobject()189 bool is_subobject() const { return _parent != NULL; } 190 get_slot()191 inline const int get_slot() const { return _slot_id; } 192 void set_slot(const int id); 193 194 void update_outline(const bool hidden); 195 get_clunk_object()196 inline clunk::Object * get_clunk_object() { return clunk_object; } get_clunk_object()197 inline clunk::Object * get_clunk_object() const { return clunk_object; } set_clunk_object(clunk::Object * co)198 inline void set_clunk_object(clunk::Object *co) { clunk_object = co; } 199 200 protected: 201 202 //pathfinding 203 204 struct Point { PointPoint205 inline Point() : id(), parent(), g(0), h(0), dir(-1) {} 206 v2<int> id, parent; 207 int g, h, dir; 208 }; 209 210 struct PD { 211 int f; 212 v2<int> id; PDPD213 inline PD(const int f, const v2<int> &id) : f(f), id(id) {} 214 215 inline const bool operator<(const PD &other) const { 216 return f > other.f; 217 } 218 }; 219 220 typedef std::set<v2<int> > CloseList; 221 typedef std::priority_queue<PD> OpenList; 222 typedef std::map<const v2<int>, Point> PointMap; 223 224 225 void find_path(const v2<int> target, const int step); 226 const bool find_path_done(Way &way); calculating_path()227 inline const bool calculating_path() const { return !_open_list.empty(); } 228 229 void calculate_way_velocity(); 230 231 const bool get_nearest(const std::set<std::string> &classnames, const float range, v2<float> &position, v2<float> &velocity, const bool check_shooting_range) const; 232 const Object * get_nearest_object(const std::set<std::string> &classnames, const float range, const bool check_shooting_range) const; 233 234 void limit_rotation(const float dt, const float speed, const bool rotate_even_stopped, const bool allow_backward); 235 236 void check_surface() const; 237 238 virtual const bool skip_rendering() const; 239 240 const sdlx::Surface * get_surface() const; 241 const Matrix<int> &get_impassability_matrix() const; 242 get_animation_model()243 inline const AnimationModel * get_animation_model() const { return _model; } 244 245 Object * _parent; 246 247 private: 248 //pathfinding stuff 249 void close(const v2<int>& vertex); 250 251 OpenList _open_list; 252 PointMap _points; 253 CloseList _close_list; 254 v2<int> _end, _begin; 255 int _step; 256 //end of pathfinding stuff 257 258 struct Event : public mrt::Serializable { 259 std::string name; 260 bool repeat; 261 std::string sound; 262 float gain; 263 bool played; 264 mutable const Pose * cached_pose; 265 266 Event(); 267 Event(const std::string name, const bool repeat, const std::string &sound, const float gain, const Pose * cached_pose = NULL); 268 virtual void serialize(mrt::Serializator &s) const; 269 virtual void deserialize(const mrt::Serializator &s); 270 }; 271 272 void check_animation() const; 273 void get_subobjects(std::set<Object *> &objects); 274 void group_tick(const float dt); 275 276 mutable const Animation *_animation; 277 mutable const AnimationModel *_model; 278 279 mutable const sdlx::Surface *_surface; 280 281 sdlx::Surface *_fadeout_surface; 282 int _fadeout_alpha; 283 const sdlx::CollisionMap *_cmap; 284 285 typedef std::deque<Event> EventQueue; 286 EventQueue _events; 287 288 typedef std::map<const std::string, float> EffectMap; 289 EffectMap _effects; 290 291 int _tw, _th; 292 int _direction_idx, _directions_n; 293 float _pos; 294 295 //waypoints stuff 296 Way _way; 297 v2<float> _next_target, _next_target_rel; 298 299 //rotation stuff 300 float _rotation_time; 301 int _dst_direction; 302 303 //grouped objects stuff 304 typedef std::map<const std::string, Object *> Group; 305 Group _group; 306 307 int _slot_id; 308 309 void set_sync(const bool sync); 310 311 friend class IWorld; 312 friend class ai::Buratino; 313 friend class ai::Waypoints; 314 friend class RotatingObject; 315 using BaseObject::_position; 316 317 318 clunk::Object *clunk_object; 319 }; 320 321 322 323 #endif 324 325