1 /*
2  * Copyright (c) 1997 - 2001 Hj. Malthaner
3  *
4  * This file is part of the Simutrans project under the artistic license.
5  * (see license.txt)
6  */
7 
8 #ifndef simobjs_h
9 #define simobjs_h
10 
11 #include "simtypes.h"
12 #include "display/clip_num.h"
13 #include "display/simimg.h"
14 #include "simcolor.h"
15 #include "dataobj/koord3d.h"
16 
17 
18 class cbuffer_t;
19 class karte_ptr_t;
20 class player_t;
21 
22 /**
23  * Base class of all objects on the map, obj == thing
24  * Since everything is a 'obj' on the map, we need to make this as compact and fast as possible.
25  *
26  * @author Hj. Malthaner
27  */
28 class obj_t
29 {
30 public:
31 	// flags
32 	enum flag_values {
33 		no_flags=0,  /// no special properties
34 		dirty=1,        /// mark image dirty when drawing
35 		not_on_map=2,   /// this object is not placed on any tile (e.g. vehicles in a depot)
36 		is_vehicle=4,   /// this object is a vehicle obviously
37 		highlight=8      /// for drawing some highlighted outline
38 	};
39 
40 	// display only outline with player color on owner stuff
41 	static bool show_owner;
42 
43 private:
44 	obj_t(obj_t const&);
45 	obj_t& operator=(obj_t const&);
46 
47 	/**
48 	 * Coordinate of position
49 	 */
50 	koord3d pos;
51 
52 	/**
53 	 * x-offset of the object on the tile
54 	 * used for drawing object image
55 	 * if xoff and yoff are between 0 and OBJECT_OFFSET_STEPS-1 then
56 	 * the top-left corner of the image is within tile boundaries
57 	 */
58 	sint8 xoff;
59 
60 	/**
61 	 * y-offset of the object on the tile
62 	 */
63 	sint8 yoff;
64 
65 	/**
66 	 * Owner of the object (1 - public player, 15 - unowned)
67 	 */
68 	uint8 owner_n:4;
69 
70 	/**
71 	 * @see flag_values
72 	 */
73 	uint8 flags:4;
74 
75 private:
76 	/**
77 	* Used by all constructors to initialize all vars with safe values
78 	* -> single source principle
79 	* @author Hj. Malthaner
80 	*/
81 	void init();
82 
83 protected:
84 	obj_t();
85 
86 	// since we often need access during loading
set_player_nr(uint8 o)87 	void set_player_nr(uint8 o) { owner_n = o; }
88 
89 	/**
90 	* Pointer to the world of this thing. Static to conserve space.
91 	* Change to instance variable once more than one world is available.
92 	* @author Hj. Malthaner
93 	*/
94 	static karte_ptr_t welt;
95 
96 
97 public:
98 	// needed for drawing images
get_player_nr()99 	sint8 get_player_nr() const { return owner_n; }
100 
101 	/**
102 	 * sets owner of object
103 	 */
104 	void set_owner(player_t *player);
105 
106 	/**
107 	 * returns owner of object
108 	 */
109 	player_t * get_owner() const;
110 
111 	/**
112 	 * routines to set, clear, get bit flags
113 	 * @author Hj. Malthaner
114 	 */
set_flag(flag_values flag)115 	inline void set_flag(flag_values flag) {flags |= flag;}
clear_flag(flag_values flag)116 	inline void clear_flag(flag_values flag) {flags &= ~flag;}
get_flag(flag_values flag)117 	inline bool get_flag(flag_values flag) const {return ((flags & flag) != 0);}
118 
119 	/// all the different types of objects
120 	enum typ {
121 		undefined=-1, obj=0, baum=1, zeiger=2,
122 		wolke=3, sync_wolke=4, async_wolke=5,
123 
124 		gebaeude=7,	// animated buildings (6 not used any more)
125 		signal=8,
126 
127 		bruecke=9, tunnel=10,
128 		bahndepot=12, strassendepot=13, schiffdepot = 14,
129 
130 		raucher=15, // obsolete
131 		leitung = 16, pumpe = 17, senke = 18,
132 		roadsign = 19, pillar = 20,
133 
134 		airdepot = 21, monoraildepot=22, tramdepot=23, maglevdepot=24,
135 
136 		wayobj = 25,
137 		way = 26, // since 99.04 ways are normal things and stored in the objliste_t!
138 
139 		label = 27,	// indicates ownership
140 		field = 28,
141 		crossing = 29,
142 		groundobj = 30, // lakes, stones
143 
144 		narrowgaugedepot=31,
145 
146 		// after this only moving stuff
147 		// reserved values for vehicles: 64 to 95
148 		pedestrian=64,
149 		road_user=65,
150 		road_vehicle=66,
151 		rail_vehicle=67,
152 		monorail_vehicle=68,
153 		maglev_vehicle=69,
154 		narrowgauge_vehicle=70,
155 		water_vehicle=80,
156 		air_vehicle=81,
157 		movingobj=82,
158 
159 		// other new objs (obsolete, only used during loading old games
160 		// lagerhaus = 24, (never really used)
161 		// gebaeude_alt=6,	(very, very old?)
162 		old_gebaeudefundament=11,	// wall below buildings, not used any more
163 		old_automobil=32, old_waggon=33,
164 		old_schiff=34, old_aircraft=35, old_monorailwaggon=36,
165 		old_verkehr=41,
166 		old_fussgaenger=42,
167 		old_choosesignal = 95,
168 		old_presignal = 96,
169 		old_roadsign = 97,
170 		old_pillar = 98,
171 		old_airdepot = 99,
172 		old_monoraildepot=100,
173 		old_tramdepot=101,
174 	};
175 
get_xoff()176 	inline sint8 get_xoff() const {return xoff;}
get_yoff()177 	inline sint8 get_yoff() const {return yoff;}
178 
179 	// true for all moving objects
is_moving()180 	inline bool is_moving() const { return flags&is_vehicle; }
181 
182 	// while in principle, this should trigger the dirty, it takes just too much time to do it
183 	// TAKE CARE OF SET IT DIRTY YOURSELF!!!
set_xoff(sint8 xoff)184 	inline void set_xoff(sint8 xoff) {this->xoff = xoff; }
set_yoff(sint8 yoff)185 	inline void set_yoff(sint8 yoff) {this->yoff = yoff; }
186 
187 	/**
188 	 * Constructor to set position of object
189 	 * This does *not* add the object to the tile
190 	 * @author Hj. Malthaner
191 	 */
192 	obj_t(koord3d pos);
193 
194 	/**
195 	 * Destructor: removes object from tile, should close any inspection windows
196 	 * @author Hj. Malthaner
197 	 */
198 	virtual ~obj_t();
199 
200 	/**
201 	 * Routine for cleanup if object is removed (ie book maintenance, cost for removal)
202 	 * @author Hj. Malthaner
203 	 */
cleanup(player_t *)204 	virtual void cleanup(player_t *) {}
205 
206 	/**
207 	 * @returns untranslated name of object
208 	 * @author Hj. Malthaner
209 	 */
get_name()210 	virtual const char *get_name() const {return "Ding";}
211 
212 	/**
213 	 * @return object type
214 	 * @author Hj. Malthaner
215 	 * @see typ
216 	 */
217 	virtual typ get_typ() const = 0;
218 
219 	/**
220 	 * waytype associated with this object
221 	 */
get_waytype()222 	virtual waytype_t get_waytype() const { return invalid_wt; }
223 
224 	/**
225 	 * called whenever the snowline height changes
226 	 * return false and the obj_t will be deleted
227 	 * @author prissi
228 	 */
check_season(const bool)229 	virtual bool check_season(const bool) { return true; }
230 
231 	/**
232 	 * called during map rotation
233 	 * @author priss
234 	 */
235 	virtual void rotate90();
236 
237 	/**
238 	 * Every object needs an image.
239 	 * @return number of current image for that object
240 	 * @author Hj. Malthaner
241 	 */
242 	virtual image_id get_image() const = 0;
243 
244 	/**
245 	 * give image for height > 0 (max. height currently 3)
246 	 * IMG_EMPTY is no images
247 	 * @author Hj. Malthaner
248 	 */
get_image(int)249 	virtual image_id get_image(int /*height*/) const {return IMG_EMPTY;}
250 
251 	/**
252 	 * this image is drawn after all get_image() on this tile
253 	 * Currently only single height is supported for this feature
254 	 */
get_front_image()255 	virtual image_id get_front_image() const {return IMG_EMPTY;}
256 
257 	/**
258 	 * if a function returns a value here with TRANSPARENT_FLAGS set
259 	 * then a transparent outline with the color from the lower 8 bit is drawn
260 	 * @author kierongreen
261 	 */
get_outline_colour()262 	virtual FLAGGED_PIXVAL get_outline_colour() const {return 0;}
263 
264 	/**
265 	 * The image, that will be outlined
266 	 * @author kierongreen
267 	 */
get_outline_image()268 	virtual image_id get_outline_image() const { return IMG_EMPTY; }
269 
270 	/**
271 	 * Save and Load of object data in one routine
272 	 * @author Hj. Malthaner
273 	 */
274 	virtual void rdwr(loadsave_t *file);
275 
276 	/**
277 	 * Called after the world is completely loaded from savegame
278 	 *
279 	 * @author Hj. Malthaner
280 	 */
finish_rd()281 	virtual void finish_rd() {}
282 
283 	/**
284 	 * @return position
285 	 */
get_pos()286 	inline koord3d get_pos() const {return pos;}
287 
288 	/**
289 	 * set position - you would not have guessed it :)
290 	 */
set_pos(koord3d k)291 	inline void set_pos(koord3d k) { if(k!=pos) { set_flag(dirty); pos = k;} }
292 
293 	/**
294 	 * put description of object into the buffer
295 	 * (used for certain windows)
296 	 * @author Hj. Malthaner
297 	 * @see simwin
298 	 */
299 	virtual void info(cbuffer_t & buf) const;
300 
301 	/**
302 	 * Opens a new info window for the object
303 	 * @author Hj. Malthaner
304 	 */
305 	virtual void show_info();
306 
307 	/**
308 	 * @return True if the object lifecycle is managed by another system so cannot be destroyed.
309 	 * False if the object can be destroyed at any time.
310 	 */
311 	virtual bool has_managed_lifecycle() const;
312 
313 	/**
314 	 * @return NULL if OK, otherwise an error message
315 	 * @author Hj. Malthaner
316 	 */
317 	virtual const char *is_deletable(const player_t *player);
318 
319 	/**
320 	 * Draw background image of object
321 	 * (everything that could be potentially behind vehicles)
322 	 */
323 	void display(int xpos, int ypos  CLIP_NUM_DEF) const;
324 
325 	/**
326 	 * Draw foreground image
327 	 * (everything that is in front of vehicles)
328 	 */
329 #ifdef MULTI_THREAD
330 	virtual void display_after(int xpos, int ypos, const sint8 clip_num) const;
331 #else
332 	virtual void display_after(int xpos, int ypos, bool is_global) const;
333 #endif
334 
335 #ifdef MULTI_THREAD
336 	/**
337 	 * Draw overlays
338 	 * (convoi tooltips)
339 	 */
display_overlay(int,int)340 	virtual void display_overlay(int /*xpos*/, int /*ypos*/) const { return; }
341 #endif
342 
343 	/**
344 	* When a vehicle moves or a cloud moves, it needs to mark the old spot as dirty (to copy to screen).
345 	* This routine already takes position, and offsets (x_off, y_off) into account.
346 	* @param yoff extra y-offset, in most cases 0, in pixels.
347 	* @author prissi
348 	*/
349 	void mark_image_dirty(image_id image, sint16 yoff) const;
350 
351 	/**
352 	 * Function for recalculating the image.
353 	 * @author Hj. Malthaner
354 	 */
calc_image()355 	virtual void calc_image() {}
356 };
357 
358 
359 /**
360  * Template to do casting of pointers based on obj_t::typ
361  * as a replacement of the slower dynamic_cast<>
362  */
363 template<typename T> static T* obj_cast(obj_t*);
364 
obj_cast(obj_t const * const d)365 template<typename T> static inline T const* obj_cast(obj_t const* const d)
366 {
367 	return obj_cast<T>(const_cast<obj_t*>(d));
368 }
369 
370 
371 /**
372  * Game objects that do not have description windows (for instance zeiger_t, wolke_t)
373  */
374 class obj_no_info_t : public obj_t
375 {
376 public:
obj_no_info_t(koord3d pos)377 	obj_no_info_t(koord3d pos) : obj_t(pos) {}
378 
show_info()379 	void show_info() OVERRIDE {}
380 
381 protected:
obj_no_info_t()382 	obj_no_info_t() : obj_t() {}
383 };
384 
385 #endif
386