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

# User Rev Content
1 root 1.1 /*
2 root 1.78 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 pippijn 1.53 *
4 root 1.76 * 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 pippijn 1.53 *
8 root 1.78 * 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 pippijn 1.53 *
13 root 1.78 * 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 pippijn 1.53 *
18 root 1.78 * 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 root 1.76 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 pippijn 1.53 */
23 root 1.1
24     /*
25 root 1.21 * The maptile is allocated each time a new map is opened.
26 root 1.1 * It contains pointers (very indirectly) to all objects on the map.
27     */
28    
29     #ifndef MAP_H
30     #define MAP_H
31    
32 root 1.40 #include <tr1/unordered_map>
33    
34 root 1.9 #include "cfperl.h"
35    
36 root 1.1 /* We set this size - this is to make magic map work properly on
37 root 1.34 * tiled maps. There is no requirement that this matches the
38 root 1.1 * 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 root 1.31 #define MAP_LAYERS 3
50 root 1.1
51     /* Values for in_memory below. Should probably be an enumerations */
52 root 1.47 enum {
53     MAP_IN_MEMORY,
54     MAP_SWAPPED,
55     MAP_LOADING,
56     MAP_SAVING,
57     };
58 root 1.1
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 root 1.29 // all those macros are herewith declared legacy
65 root 1.30 #define GET_MAP_FLAGS(M,X,Y) (M)->at((X),(Y)).flags ()
66 root 1.29 #define GET_MAP_LIGHT(M,X,Y) (M)->at((X),(Y)).light
67 root 1.34 #define GET_MAP_OB(M,X,Y) (M)->at((X),(Y)).bot
68 root 1.29 #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 root 1.1
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 root 1.56 #define OUT_OF_REAL_MAP(M,X,Y) (!(IN_RANGE_EXC ((X), 0, (M)->width) && IN_RANGE_EXC ((Y), 0, (M)->height)))
80 root 1.1
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 root 1.20 #define P_NO_MAGIC 0x02 /* Spells (some) can't pass this object */
86 root 1.29 #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 root 1.20 #define P_IS_ALIVE 0x10 /* something alive is on this space */
93     #define P_NO_CLERIC 0x20 /* no clerical spells cast here */
94 root 1.30
95 root 1.45 #define P_UPTODATE 0x80 /* this space is up to date */
96 root 1.20
97 root 1.1 /* 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 root 1.29 #define P_OUT_OF_MAP 0x10000 /* This space is outside the map */
104     #define P_NEW_MAP 0x20000
105 root 1.20 /* Coordinates passed result in a new tiled map */
106 root 1.1
107 root 1.29 /* 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 root 1.1 * 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 root 1.29 struct mapspace
119 root 1.20 {
120 root 1.34 object *bot, *top; /* lowest/highest object on this space */
121 root 1.30 object *faces_obj[MAP_LAYERS];/* face objects for the 3 layers */
122     uint8 flags_; /* flags about this space (see the P_ values above) */
123 root 1.20 sint8 light; /* How much light this space provides */
124 root 1.30 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 root 1.45 if (!(flags_ & P_UPTODATE))
133 root 1.30 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 root 1.31 // 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 root 1.30 if (flags () & P_PLAYER)
149 root 1.31 for (object *op = top; op; op = op->below)
150 root 1.30 if (op->type == PLAYER)
151     return op;
152    
153     return 0;
154     }
155 root 1.65
156 root 1.66 // return the item volume on this mapspace in cm³
157     uint64 volume () const;
158 elmex 1.6 };
159 root 1.1
160 root 1.18 struct shopitems : zero_initialised
161     {
162 root 1.20 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 elmex 1.6 };
169 root 1.1
170 root 1.40 // 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 root 1.1 /* 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 root 1.32 INTERFACE_CLASS (maptile)
186     struct maptile : zero_initialised, attachable
187 root 1.19 {
188 root 1.40 sint32 ACC (RW, width), ACC (RW, height); /* Width and height of map. */
189     struct mapspace *spaces; /* Array of spaces on this map */
190 root 1.60 uint8 *regions; /* region index per mapspace, if != 0 */
191     struct region **regionmap; /* index to region */
192 root 1.40
193     tstamp ACC (RW, last_access); /* last time this map was accessed somehow */
194 root 1.29
195 root 1.40 shstr ACC (RW, name); /* Name of map as given by its creator */
196 root 1.59 struct region *ACC (RW, default_region); /* What jurisdiction in the game world this map is ruled by
197 root 1.20 * points to the struct containing all the properties of
198     * the region */
199 root 1.40 double ACC (RW, reset_time);
200 root 1.19 uint32 ACC (RW, reset_timeout); /* How many seconds must elapse before this map
201 root 1.20 * should be reset
202     */
203 root 1.44 bool ACC (RW, dirty); /* if true, something was inserted or removed */
204 root 1.77 bool ACC (RW, no_reset); // must not reset this map
205 root 1.20 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 root 1.42 sint16 players; /* How many players are on this map right now */
214 root 1.20 uint16 ACC (RW, difficulty); /* What level the player should be to play here */
215    
216 root 1.75 bool ACC (RW, active); // wether this map is active or not
217 root 1.40 bool ACC (RW, per_player);
218     bool ACC (RW, per_party);
219     bool ACC (RW, outdoor); /* True if an outdoor map */
220 root 1.58 bool ACC (RW, nodrop); /* avoid dropping anything on this map */
221 root 1.20 uint8 ACC (RW, darkness); /* indicates level of darkness of map */
222 root 1.40
223 root 1.20 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 root 1.34 int ACC (RW, worldpartx), ACC (RW, worldparty); /*Highly fasten conversion between worldmap and weathermap */
233 root 1.20 struct shopitems *shopitems; /* a semi-colon seperated list of item-types the map's shop will trade in */
234 root 1.40 shstr ACC (RW, shoprace); /* the preffered race of the local shopkeeper */
235 root 1.20 double ACC (RW, shopgreed); /* how much our shopkeeper overcharges */
236 pippijn 1.24 sint64 ACC (RW, shopmin); /* minimum price a shop will trade for */
237 pippijn 1.25 sint64 ACC (RW, shopmax); /* maximum price a shop will offer */
238 root 1.40 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 root 1.66 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 root 1.40
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 root 1.77 MTH void do_decay_objects ();
256 root 1.40 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 root 1.46 // set the given flag on all objects in the map
263     MTH void set_object_flag (int flag, int value = 1);
264    
265 root 1.40 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 root 1.60 MTH struct region *region (int x, int y) const;
272 root 1.59
273 root 1.40 // loas the header pseudo-object
274 root 1.51 bool _load_header (object_thawer &thawer);
275     MTH bool _load_header (const char *path);
276 root 1.40
277     // load objects into the map
278 root 1.51 bool _load_objects (object_thawer &thawer);
279     MTH bool _load_objects (const char *path, bool skip_header = true);
280 root 1.40
281     // save objects into the given file (uses IO_ flags)
282 root 1.51 bool _save_objects (object_freezer &freezer, int flags);
283     MTH bool _save_objects (const char *path, int flags);
284 root 1.40
285     // save the header pseudo object _only_
286 root 1.51 bool _save_header (object_freezer &freezer);
287     MTH bool _save_header (const char *path);
288 root 1.23
289     maptile ();
290 root 1.40 maptile (int w, int h);
291 root 1.32 ~maptile ();
292 root 1.40
293 root 1.32 void do_destroy ();
294     void gather_callbacks (AV *&callbacks, event_type event) const;
295    
296 root 1.36 MTH int size () const { return width * height; }
297 root 1.29
298 root 1.36 MTH object *insert (object *op, int x, int y, object *originator = 0, int flags = 0);
299 root 1.34
300 root 1.46 MTH void touch () { last_access = runtime; }
301    
302 root 1.47 // 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 root 1.40
319 root 1.51 void make_map_floor (char **layout, char *floorstyle, random_map_params *RP);
320     bool generate_random_map (random_map_params *RP);
321    
322 root 1.69 static maptile *find_async (const char *path, maptile *original = 0);//PERL
323 root 1.47 static maptile *find_sync (const char *path, maptile *original = 0);//PERL
324 root 1.69 static maptile *find_style_sync (const char *dir, const char *file = 0);//PERL
325     MTH object *pick_random_object () const;
326 root 1.39
327 root 1.37 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 elmex 1.6 };
330 root 1.1
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 root 1.29 * can be negative. direction is the crossfire direction scheme
336 root 1.1 * 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 root 1.20 struct rv_vector
341     {
342     unsigned int distance;
343     int distance_x;
344     int distance_y;
345     int direction;
346     object *part;
347 elmex 1.6 };
348 root 1.1
349 root 1.52 //TODO: these should be refactored into things like xy_normalise
350     // and so on.
351 root 1.63 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 root 1.52
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 root 1.31 inline mapspace &
371     object::ms () const
372     {
373     return map->at (x, y);
374     }
375    
376 root 1.1 #endif
377 root 1.22