1 #ifndef __BT_WORLD_H__
2 #define __BT_WORLD_H__
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 "export_btanks.h"
32 #include "mrt/singleton.h"
33 #include "mrt/serializable.h"
34 
35 #include <set>
36 #include <map>
37 #include <list>
38 
39 #include "math/v2.h"
40 #include "math/matrix.h"
41 #include "object_common.h"
42 
43 #include "object_grid.h"
44 #include "utils.h"
45 #include "sl08/sl08.h"
46 
47 namespace sdlx {
48 class Surface;
49 class Rect;
50 }
51 
52 namespace ai {
53 class Traits;
54 }
55 
56 class Object;
57 
58 class BTANKSAPI IWorld : public mrt::Serializable {
59 public:
60 	DECLARE_SINGLETON(IWorld);
61 
62 	sl08::signal1<void, const Object *> on_object_add;
63 	sl08::signal1<void, const Object *> on_object_update;
64 	sl08::signal1<void, const Object *> on_object_broke;
65 	sl08::signal1<void, const Object *> on_object_delete;
66 	sl08::signal2<void, const Object *, const Object *> on_object_death; //death emitted after collision handler
67 
68 	void clear();
69 	~IWorld();
70 	IWorld();
71 
72 	void setTimeSlice(const float ts);
73 
74 	void addObject(Object *, const v2<float> &pos, const int id = -1);
75 	const bool exists(const int id) const;
76 	const Object *getObjectByID(const int id) const;
77 	Object *getObjectByID(const int id);
78 
79 	void render(sdlx::Surface &surface, const sdlx::Rect &src, const sdlx::Rect &viewport, const int z1 = -10000, const int z2 = 10001, const Object * player = NULL);
80 	void tick(const float dt);
81 
82 	Object * spawn(const Object *src, const std::string &classname, const std::string &animation, const v2<float> &dpos, const v2<float> &vel, const int z = 0);
83 
84 //the nearest objects
85 	const Object* get_nearest_object(const Object *obj, const std::set<std::string> &classnames, const float range, const bool check_shooting_range) const;
86 	const bool get_nearest(const Object *obj, const std::set<std::string> &classnames, const float range, v2<float> &position, v2<float> &velocity, const bool check_shooting_range) const;
87 //end of the nearest
88 
89 	void get_impassability_matrix(Matrix<int> &matrix, const Object *src, const Object *dst) const;
90 
91 	virtual void serialize(mrt::Serializator &s) const;
92 	virtual void deserialize(const mrt::Serializator &s);
93 	void generateUpdate(mrt::Serializator &s, const bool clean_sync_flag, const int first_id = -1);
94 	void applyUpdate(const mrt::Serializator &s, const float dt, const int sync_id = -1);
95 
96 	void serializeObject(mrt::Serializator &, const Object *, const bool force) const;
97 	Object* deserializeObject(const mrt::Serializator &);
98 	void serializeObjectPV(mrt::Serializator &, const Object *) const;
99 	void deserializeObjectPV(const mrt::Serializator &, Object *);
100 
101 	static void interpolateObject(Object *object);
102 	static void interpolateObjects(ObjectMap &objects);
103 
104 	void tick(Object &o, const float dt, const bool do_calculate = true);
105 	void tick(ObjectMap &objects, const float dt, const bool do_calculate = true);
106 	void purge(const float dt);
107 
108 	const float getImpassability(Object *obj, const v2<int> &position, const Object **collided_with = NULL, const bool probe = false, const bool skip_moving = false) const;
109 
110 	const int get_children(const int id, const std::string &classname) const;
111 	void setMode(const std::string &mode, const bool value);
112 
113 	void enumerate_objects(std::set<const Object *> &o_set, const Object *src, const float range, const std::set<std::string> *classfilter);
114 	void sync(const int id);
115 
116 	void teleport(Object *object, const v2<float> &position); //do not use this!
117 
118 	void push(Object *parent, Object *object, const v2<float> &dpos); //and this!
119 	void push(const int id, Object *object, const v2<float> &pos); //and this!
120 	Object * pop(Object *object); //and this :)))
121 
122 protected:
123 	void purge(ObjectMap &objects, const float dt);
124 	friend class Editor;
125 	friend class Command;
126 
127 	const Object *getObjectByXY(const int x, const int y) const;
128 	void move(const Object *object, const int x, const int y);
129 
130 private:
131 	void _tick(Object &o, const float dt, const bool do_calculate = true);
132 	void _tick(ObjectMap &objects, const float dt, const bool do_calculate = true);
133 
134 	sl08::slot0<void, IWorld> init_map_slot;
135 	void initMap();
136 
137 	void updateObject(Object *o);
138 	void deleteObject(Object *o);
139 
140 	struct collision_map_hash_func {
141 		enum { bucket_size = 4, min_buckets = 8 };
operatorcollision_map_hash_func142 		size_t operator() (const std::pair<int, int> & key) const {
143 			return (key.first << 16) | key.second;
144 		}
operatorcollision_map_hash_func145 		bool operator() (const std::pair<int, int> & key, const std::pair<int, int> & key2) const {
146 			return operator()(key) < operator()(key2);
147 		}
148 	};
149 
150 	typedef std::map<const std::pair<int, int>, bool, collision_map_hash_func> CollisionMap;
151 	mutable CollisionMap _collision_map;
152 
153 	typedef std::map<const std::pair<int, int>, ternary<int, int, bool>, collision_map_hash_func > StaticCollisionMap;
154 	mutable StaticCollisionMap _static_collision_map;
155 
156 	const bool collides(Object *obj, const v2<int> &position, Object *other, const bool probe = false) const;
157 
158 	void cropObjects(const std::set<int> &ids);
159 
160 	void setSpeed(const float speed);
161 
162 	sl08::slot4<void, int, int, int, int, IWorld> map_resize_slot;
163 	void onMapResize(int left, int right, int up, int down);
164 
165 	ObjectMap _objects;
166 	struct Command {
167 		enum Type {Push, Pop};
168 		Type type;
169 		int id;
170 		Object *object;
171 
CommandCommand172 		Command(Type type): type(type), id(0), object(NULL) {}
173 	};
174 	typedef std::list<Command> Commands;
175 	Commands _commands;
176 
177 	Grid<Object *> _grid;
178 	int _last_id, _max_id;
179 	bool _safe_mode, _atatat;
180 	float _max_dt;
181 	int _out_of_sync, _out_of_sync_sent, _current_update_id;
182 
183 	const sdlx::Surface *_hp_bar;
184 
185 	IWorld(const IWorld &);
186 	const IWorld& operator=(const IWorld &);
187 };
188 
189 PUBLIC_SINGLETON(BTANKSAPI, World, IWorld);
190 
191 #endif
192