ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/map.h
Revision: 1.78
Committed: Sun Jul 1 05:00:18 2007 UTC (16 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.77: +11 -12 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002-2005,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
23
24 /*
25 * The maptile is allocated each time a new map is opened.
26 * It contains pointers (very indirectly) to all objects on the map.
27 */
28
29 #ifndef MAP_H
30 #define MAP_H
31
32 #include <tr1/unordered_map>
33
34 #include "cfperl.h"
35
36 /* We set this size - this is to make magic map work properly on
37 * tiled maps. There is no requirement that this matches the
38 * tiled maps size - it just seemed like a reasonable value.
39 * Magic map code now always starts out putting the player in the
40 * center of the map - this makes the most sense when dealing
41 * with tiled maps.
42 * We also figure out the magicmap color to use as we process the
43 * spaces - this is more efficient as we already have up to date
44 * map pointers.
45 */
46 #define MAGIC_MAP_SIZE 50
47 #define MAGIC_MAP_HALF MAGIC_MAP_SIZE/2
48
49 #define MAP_LAYERS 3
50
51 /* Values for in_memory below. Should probably be an enumerations */
52 enum {
53 MAP_IN_MEMORY,
54 MAP_SWAPPED,
55 MAP_LOADING,
56 MAP_SAVING,
57 };
58
59 /* GET_MAP_FLAGS really shouldn't be used very often - get_map_flags should
60 * really be used, as it is multi tile aware. However, there are some cases
61 * where it is known the map is not tiled or the values are known
62 * consistent (eg, op->map, op->x, op->y)
63 */
64 // all those macros are herewith declared legacy
65 #define GET_MAP_FLAGS(M,X,Y) (M)->at((X),(Y)).flags ()
66 #define GET_MAP_LIGHT(M,X,Y) (M)->at((X),(Y)).light
67 #define GET_MAP_OB(M,X,Y) (M)->at((X),(Y)).bot
68 #define GET_MAP_TOP(M,X,Y) (M)->at((X),(Y)).top
69 #define GET_MAP_FACE_OBJ(M,X,Y,L) (M)->at((X),(Y)).faces_obj[L]
70 #define GET_MAP_MOVE_BLOCK(M,X,Y) (M)->at((X),(Y)).move_block
71 #define GET_MAP_MOVE_SLOW(M,X,Y) (M)->at((X),(Y)).move_slow
72 #define GET_MAP_MOVE_ON(M,X,Y) (M)->at((X),(Y)).move_on
73 #define GET_MAP_MOVE_OFF(M,X,Y) (M)->at((X),(Y)).move_off
74
75 /* You should really know what you are doing before using this - you
76 * should almost always be using out_of_map instead, which takes into account
77 * map tiling.
78 */
79 #define OUT_OF_REAL_MAP(M,X,Y) (!(IN_RANGE_EXC ((X), 0, (M)->width) && IN_RANGE_EXC ((Y), 0, (M)->height)))
80
81 /* These are used in the MapLook flags element. They are not used in
82 * in the object flags structure.
83 */
84 #define P_BLOCKSVIEW 0x01
85 #define P_NO_MAGIC 0x02 /* Spells (some) can't pass this object */
86 #define P_PLAYER 0x04 /* a player (or something seeing these objects) is on this mapspace */
87 #define P_SAFE 0x08 /* If this is set the map tile is a safe space,
88 * that means, nothing harmful can be done,
89 * such as: bombs, potion usage, alchemy, spells
90 * this was introduced to make shops safer
91 * but is useful in other situations */
92 #define P_IS_ALIVE 0x10 /* something alive is on this space */
93 #define P_NO_CLERIC 0x20 /* no clerical spells cast here */
94
95 #define P_UPTODATE 0x80 /* this space is up to date */
96
97 /* The following two values are not stored in the MapLook flags, but instead
98 * used in the get_map_flags value - that function is used to return
99 * the flag value, as well as other conditions - using a more general
100 * function that does more of the work can hopefully be used to replace
101 * lots of duplicate checks currently in the code.
102 */
103 #define P_OUT_OF_MAP 0x10000 /* This space is outside the map */
104 #define P_NEW_MAP 0x20000
105 /* Coordinates passed result in a new tiled map */
106
107 /* P_NO_PASS is used for ob_blocked() return value. It needs
108 * to be here to make sure the bits don't match with anything.
109 */
110 #define P_NO_PASS 0x80000
111
112 /* Instead of having numerous arrays that have information on a
113 * particular space (was map, floor, floor2, map_ob),
114 * have this structure take care of that information.
115 * This puts it all in one place, and should also make it easier
116 * to extend information about a space.
117 */
118 struct mapspace
119 {
120 object *bot, *top; /* lowest/highest object on this space */
121 object *faces_obj[MAP_LAYERS];/* face objects for the 3 layers */
122 uint8 flags_; /* flags about this space (see the P_ values above) */
123 sint8 light; /* How much light this space provides */
124 MoveType move_block; /* What movement types this space blocks */
125 MoveType move_slow; /* What movement types this space slows */
126 MoveType move_on; /* What movement types are activated */
127 MoveType move_off; /* What movement types are activated */
128
129 void update_ ();
130 void update ()
131 {
132 if (!(flags_ & P_UPTODATE))
133 update_ ();
134 }
135
136 uint8 flags ()
137 {
138 update ();
139 return flags_;
140 }
141
142 // maybe only inline quick flags_ checking?
143 object *player ()
144 {
145 // search from the top, because players are usually on top
146 // make usually == always and this non-amortized O(1)
147 // could gte rid of P_PLAYER, too, then
148 if (flags () & P_PLAYER)
149 for (object *op = top; op; op = op->below)
150 if (op->type == PLAYER)
151 return op;
152
153 return 0;
154 }
155
156 // return the item volume on this mapspace in cm³
157 uint64 volume () const;
158 };
159
160 struct shopitems : zero_initialised
161 {
162 const char *name; /* name of the item in question, null if it is the default item */
163 const char *name_pl; /* plural name */
164 int typenum; /* itemtype number we need to match 0 if it is the default price */
165 sint8 strength; /* the degree of specialisation the shop has in this item,
166 * as a percentage from -100 to 100 */
167 int index; /* being the size of the shopitems array. */
168 };
169
170 // map I/O, what to load/save
171 enum {
172 IO_HEADER = 0x01, // the "arch map" pseudo object
173 IO_OBJECTS = 0x02, // the non-unique objects
174 IO_UNIQUES = 0x04, // unique objects
175 };
176
177 /* In general, code should always use the macros
178 * above (or functions in map.c) to access many of the
179 * values in the map structure. Failure to do this will
180 * almost certainly break various features. You may think
181 * it is safe to look at width and height values directly
182 * (or even through the macros), but doing so will completely
183 * break map tiling.
184 */
185 INTERFACE_CLASS (maptile)
186 struct maptile : zero_initialised, attachable
187 {
188 sint32 ACC (RW, width), ACC (RW, height); /* Width and height of map. */
189 struct mapspace *spaces; /* Array of spaces on this map */
190 uint8 *regions; /* region index per mapspace, if != 0 */
191 struct region **regionmap; /* index to region */
192
193 tstamp ACC (RW, last_access); /* last time this map was accessed somehow */
194
195 shstr ACC (RW, name); /* Name of map as given by its creator */
196 struct region *ACC (RW, default_region); /* What jurisdiction in the game world this map is ruled by
197 * points to the struct containing all the properties of
198 * the region */
199 double ACC (RW, reset_time);
200 uint32 ACC (RW, reset_timeout); /* How many seconds must elapse before this map
201 * should be reset
202 */
203 bool ACC (RW, dirty); /* if true, something was inserted or removed */
204 bool ACC (RW, no_reset); // must not reset this map
205 bool ACC (RW, fixed_resettime); /* if true, reset time is not affected by
206 * players entering/exiting map
207 */
208 sint32 ACC (RW, timeout); /* swapout is set to this */
209 sint32 ACC (RW, swap_time); /* When it reaches 0, the map will be swapped out */
210 uint32 ACC (RW, in_memory); /* If not true, the map has been freed and must
211 * be loaded before used. The map,omap and map_ob
212 * arrays will be allocated when the map is loaded */
213 sint16 players; /* How many players are on this map right now */
214 uint16 ACC (RW, difficulty); /* What level the player should be to play here */
215
216 bool ACC (RW, active); // wether this map is active or not
217 bool ACC (RW, per_player);
218 bool ACC (RW, per_party);
219 bool ACC (RW, outdoor); /* True if an outdoor map */
220 bool ACC (RW, nodrop); /* avoid dropping anything on this map */
221 uint8 ACC (RW, darkness); /* indicates level of darkness of map */
222
223 uint16 ACC (RW, enter_x); /* enter_x and enter_y are default entrance location */
224 uint16 ACC (RW, enter_y); /* on the map if none are set in the exit */
225 oblinkpt *buttons; /* Linked list of linked lists of buttons */
226 sint16 ACC (RW, temp); /* base temperature of this tile (F) */
227 sint16 ACC (RW, pressure); /* barometric pressure (mb) */
228 sint8 ACC (RW, humid); /* humitidy of this tile */
229 sint8 ACC (RW, windspeed); /* windspeed of this tile */
230 sint8 ACC (RW, winddir); /* direction of wind */
231 sint8 ACC (RW, sky); /* sky conditions */
232 int ACC (RW, worldpartx), ACC (RW, worldparty); /*Highly fasten conversion between worldmap and weathermap */
233 struct shopitems *shopitems; /* a semi-colon seperated list of item-types the map's shop will trade in */
234 shstr ACC (RW, shoprace); /* the preffered race of the local shopkeeper */
235 double ACC (RW, shopgreed); /* how much our shopkeeper overcharges */
236 sint64 ACC (RW, shopmin); /* minimum price a shop will trade for */
237 sint64 ACC (RW, shopmax); /* maximum price a shop will offer */
238 shstr ACC (RW, msg); /* Message map creator may have left */
239 shstr ACC (RW, maplore); /* Map lore information */
240 shstr ACC (RW, tile_path[4]); /* path to adjoining maps */
241 maptile *ACC (RW, tile_map[4]); /* Next map, linked list */
242 shstr ACC (RW, path); /* Filename of the map */
243 int ACC (RW, max_nrof); // maximum nrof of any single item on a mapspace
244 uint64 ACC (RW, max_volume); // maximum volume for all items on a mapspace
245
246 MTH void activate ();
247 MTH void deactivate ();
248
249 // allocates all (empty) mapspace
250 MTH void alloc ();
251 // deallocates the mapspaces (and destroys all objects)
252 MTH void clear ();
253
254 MTH void fix_auto_apply ();
255 MTH void do_decay_objects ();
256 MTH void update_buttons ();
257 MTH int change_map_light (int change);
258 static void change_all_map_light (int change); //PERL
259 MTH void set_darkness_map ();
260 MTH int estimate_difficulty () const;
261
262 // set the given flag on all objects in the map
263 MTH void set_object_flag (int flag, int value = 1);
264
265 MTH void link_multipart_objects ();
266 MTH void clear_unique_items ();
267
268 MTH void clear_header ();
269 MTH void clear_links_to (maptile *m);
270
271 MTH struct region *region (int x, int y) const;
272
273 // loas the header pseudo-object
274 bool _load_header (object_thawer &thawer);
275 MTH bool _load_header (const char *path);
276
277 // load objects into the map
278 bool _load_objects (object_thawer &thawer);
279 MTH bool _load_objects (const char *path, bool skip_header = true);
280
281 // save objects into the given file (uses IO_ flags)
282 bool _save_objects (object_freezer &freezer, int flags);
283 MTH bool _save_objects (const char *path, int flags);
284
285 // save the header pseudo object _only_
286 bool _save_header (object_freezer &freezer);
287 MTH bool _save_header (const char *path);
288
289 maptile ();
290 maptile (int w, int h);
291 ~maptile ();
292
293 void do_destroy ();
294 void gather_callbacks (AV *&callbacks, event_type event) const;
295
296 MTH int size () const { return width * height; }
297
298 MTH object *insert (object *op, int x, int y, object *originator = 0, int flags = 0);
299
300 MTH void touch () { last_access = runtime; }
301
302 // find the map that is at coordinate x|y relative to this map
303 // TODO: need a better way than passing by reference
304 // TODO: make perl interface
305 maptile *xy_find (sint16 &x, sint16 &y);
306
307 // like xy_find, but also loads the map
308 maptile *xy_load (sint16 &x, sint16 &y);
309
310 void do_load_sync ();//PERL
311
312 // make sure the map is loaded
313 MTH void load_sync ()
314 {
315 if (!spaces)
316 do_load_sync ();
317 }
318
319 void make_map_floor (char **layout, char *floorstyle, random_map_params *RP);
320 bool generate_random_map (random_map_params *RP);
321
322 static maptile *find_async (const char *path, maptile *original = 0);//PERL
323 static maptile *find_sync (const char *path, maptile *original = 0);//PERL
324 static maptile *find_style_sync (const char *dir, const char *file = 0);//PERL
325 MTH object *pick_random_object () const;
326
327 mapspace const &at (uint32 x, uint32 y) const { return spaces [x * height + y]; }
328 mapspace &at (uint32 x, uint32 y) { return spaces [x * height + y]; }
329 };
330
331 /* This is used by get_rangevector to determine where the other
332 * creature is. get_rangevector takes into account map tiling,
333 * so you just can not look the the map coordinates and get the
334 * righte value. distance_x/y are distance away, which
335 * can be negative. direction is the crossfire direction scheme
336 * that the creature should head. part is the part of the
337 * monster that is closest.
338 * Note: distance should be always >=0. I changed it to UINT. MT
339 */
340 struct rv_vector
341 {
342 unsigned int distance;
343 int distance_x;
344 int distance_y;
345 int direction;
346 object *part;
347 };
348
349 //TODO: these should be refactored into things like xy_normalise
350 // and so on.
351 int get_map_flags (maptile *oldmap, maptile **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny);
352 int ob_blocked (const object *ob, maptile *m, sint16 x, sint16 y);
353 int out_of_map (maptile *m, int x, int y);
354 maptile *get_map_from_coord (maptile *m, sint16 *x, sint16 *y);
355 void get_rangevector (object *op1, object *op2, rv_vector *retval, int flags);
356 void get_rangevector_from_mapcoord (const maptile *m, int x, int y, const object *op2, rv_vector *retval, int flags);
357 int on_same_map (const object *op1, const object *op2);
358 int adjacent_map (const maptile *map1, const maptile *map2, int *dx, int *dy);
359
360 // adjust map, x and y for tiled maps and return true if the position is valid at all
361 inline bool
362 xy_normalise (maptile *&map, sint16 &x, sint16 &y)
363 {
364 // when in range, do a quick return, otherwise go the slow route
365 return
366 (IN_RANGE_EXC (x, 0, map->width) && IN_RANGE_EXC (y, 0, map->height))
367 || !(get_map_flags (map, &map, x, y, &x, &y) & P_OUT_OF_MAP);
368 }
369
370 inline mapspace &
371 object::ms () const
372 {
373 return map->at (x, y);
374 }
375
376 #endif
377