1 //
2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 2 of the License, or (at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 // more details.
14 //
15 // You should have received a copy of the GNU General Public License along with
16 // this program; if not, write to the Free Foundation, Inc., 59 Temple Place,
17 // Suite 330, Boston, MA 02111-1307 USA
18 //
19 // Gordon McNutt
20 // gmcnutt@users.sourceforge.net
21 //
22 /* 12/14/2002 Sam Glasby added place_get_terrain()
23  */
24 #ifndef place_hdr
25 #define place_hdr
26 
27 #include "macros.h"
28 
29 BEGIN_DECL
30 
31 #include "terrain_map.h"
32 #include "list.h"
33 #include "node.h"
34 #include "object.h"
35 #include "Party.h"
36 #include "astar.h"
37 #include "common.h"
38 #include "sky.h"
39 #include "sound.h"
40 
41 #include <SDL.h>
42 
43 #define place_w(p) ((p)->terrain_map->w)
44 #define place_h(p) ((p)->terrain_map->h)
45 #define place_index(p,x,y) ((y) * place_w(p) + (x))
46 #define place_name(p) ((p)->name)
47 #define place_is_wilderness(p) ((p)->wilderness)
48 #define place_is_town(p) (!(p)->wilderness)
49 #define place_is_dungeon(p) (! (p)->wilderness)
50 #define place_is_wrapping(p) ((p)->wraps)
51 #define place_get_item(p,x,y) place_get_object((p),(x),(y),item_layer)
52 #define place_get_parent(p) ((p)->location.place)
53 #define place_get_scale(p) ((p)->scale)
54 #define place_get_x(p) ((p)->location.x)
55 #define place_get_y(p) ((p)->location.y)
56 #define place_is_wilderness_combat(p) ((p)->is_wilderness_combat)
57 #define place_lock(p) ((p)->lock++)
58 /* place_unlock() is a function (see below) */
59 #define place_is_locked(p) ((p)->lock)
60 #define place_mark_for_death(p) ((p)->marked_for_death = 1)
61 #define place_is_marked_for_death(p) ((p)->marked_for_death)
62 #define place_max_distance(p) (place_w(p) + place_h(p))
63 #define place_get_all_objects(p) (&(p)->turn_list)
64 #define place_get_terrain_map(p) ((p)->terrain_map)
65 
66 #define PFLAG_HORZ             (1 << 0) /* matches ASTAR_HORZ */
67 #define PFLAG_VERT             (1 << 1) /* matches ASTAR_VERT */
68 #define PFLAG_IGNOREMECHS      (1 << 2)
69 #define PFLAG_IGNOREBEINGS     (1 << 3)
70 #define PFLAG_IGNOREVEHICLES   (1 << 4)
71 #define PFLAG_IGNORECOMPANIONS (1 << 5)
72 #define PFLAG_MOVEATTEMPT      (1 << 6)
73 #define PFLAG_IGNORETERRAIN    (1 << 7) /* used by Object::putOnMap */
74 #define PFLAG_IGNOREHAZARDS    (1 << 8) /* used by Object::putOnMap */
75 #define PFLAG_IGNOREFIELDS     (1 << 9) /* used by Object::putOnMap */
76 #define PFLAG_IGNORETFEAT      (1 << 10)
77 #define PFLAG_IGNORESTEPTRIG   (1 << 11)
78 #define PFLAG_ADJACENTNOTOK    (1 << 12)
79 
80 // Flags for placeDescribe:
81 #define PLACE_DESCRIBE_TERRAIN (1 << 0)
82 #define PLACE_DESCRIBE_OBJECTS (1 << 1)
83 #define PLACE_DESCRIBE_ALL     (~0)
84 
85 struct location;
86 struct place;
87 struct hash;
88 
89 struct location {
90         struct place *place;
91         int x;
92         int y;
93 };
94 
95 #define PLACE_MAGIC PLACE_ID
96 
97 struct place {
98 
99         // 'magic' is used by the loader to type-check a pointer passed in from
100         // the script.
101         int magic;
102 
103         struct node turn_list;   /* list of objects to exec each turn */
104         struct node *turn_elem;  /* iterator over above list */
105 
106         struct location location;
107         struct place *neighbors[NUM_DIRECTIONS];
108         char *tag;
109         char *name;
110         struct sprite *sprite;
111         struct terrain_map *original_terrain_map;
112         struct terrain_map *terrain_map;
113         struct hash *objects;
114         int scale;
115         bool wraps;
116         bool dirty;
117         bool underground;
118         bool is_wilderness_combat;
119         bool wilderness;
120 
121         // Hack: need this so I can remove the tmp wild combat place after
122         // loading it from a game that saved during combat.
123         void *handle;
124 
125         struct list subplaces;      /* list of subplaces */
126         struct list container_link; /* list hook for a subplace */
127         struct list on_entry_hook;  /* on-entry hook */
128 
129         int saved;
130         int lock;
131         int marked_for_death : 1;
132         int saving_now : 1;
133         int started : 1;
134 
135         /* Coordinates used to position the player in a subplace when he enters
136          * from the edge: */
137         int edge_entrance[NUM_PLANAR_DIRECTIONS][2];
138 };
139 
140 extern struct place *Place;
141 
142 extern struct place *place_new(const char *tag,
143                                const char *name,
144                                struct sprite *sprite,
145                                struct terrain_map *terrain_map,
146                                int wraps,
147                                int underground,
148                                int wilderness,
149                                int wilderness_combat
150                                );
151 
152 #ifdef MAP_REGIONS
153 
154 /* The new region api */
155 
156 typedef struct region {
157         char *tag;
158         char *name;
159         struct location loc;
160         struct terrain_map *map;
161         struct list objects;
162         struct list subplaces;
163 } region_t;
164 
165 typedef struct region_map {
166         int w;
167         int h;
168         region_t *map;
169 } region_map_t;
170 
171 extern region_t *region_new(char *tag, char *name, struct terrain_map *map);
172 extern void region_del(region_t*);
173 extern int region_add_object(region_t *, Object *, int x, int y);
174 extern int region_rm_object(region_t *, Object *);
175 extern int region_add_subplace(region_t *, struct place*, int x int y);
176 extern int region_rm_subplace(region_t *, struct place*);
177 extern void region_paste_to_place(region_t*, struct place*, int x, int y);
178 extern void region_copy_from_place(region_t*, struct place*, int x, int y);
179 extern int regions_are_compatible(region_t *a, region_t *b);
180 extern struct place *place_new(char *tag,char *name, struct sprite *sprite,
181                                region_map_t *rmap,
182                                int wraps,
183                                int underground,
184                                int wilderness,
185                                int wilderness_combat);
186 #endif
187 
188 extern void place_del(struct place *place);
189 
190 extern int place_is_passable(struct place *place, int x, int y,
191                              class Object *passer, int flags);
192 
193 extern int place_is_occupied(struct place *place, int x, int y);
194 
195 extern int place_visibility(struct place *place, int x, int y);
196 
197 extern unsigned int place_walking_distance(struct place *place,
198                                            int x0,
199                                            int y0, int x1, int y1);
200 
201 extern int place_flying_distance(struct place *place, int x0, int y0, int x1, int y1);
202 
203 void place_get_direction_vector(struct place *place, int x1, int y1,
204                                 int x2, int y2, int *dx, int *dy);
205 
206 extern class Party *place_get_Party(struct place *place,
207                                     int x, int y);
208 
209 extern class Vehicle *place_get_vehicle(struct place *place,
210                                         int x, int y);
211 
212 extern int place_eval_path(struct place *place,
213                            int x0, int y0, int x1, int y1);
214 
215 extern void place_move_object(struct place *place,
216                               class Object *object, int newx,
217                               int newy);
218 extern int place_add_object(struct place *place, Object * object);
219 
220 extern void place_remove_object(struct place *place, Object * object);
221 
222 extern Object *place_get_object(struct place *place, int x, int y, enum layer layer);
223 
224 extern void place_add_moongate(struct place *place,
225                                class Moongate * moongate);
226 
227 extern class Party *place_search_for_Party(struct place *place,
228                                            int x,
229                                            int y,
230                                            int radius,
231                                            int (*criteria) (class
232                                                             Party
233                                                             *
234                                                             Party));
235 
236 
237 extern struct astar_node *place_find_path(struct place *place,
238                                           struct astar_search_info *info,
239                                           class Object *requestor);
240 
241 extern struct astar_node *place_find_path_to_edge(struct place *place, int x0,
242                                                   int y0, int edgedir,
243                                                   int pflags,
244                                                   class Object *requestor);
245 
246 extern struct terrain_map *place_get_combat_terrain_map(struct place
247                                                         *place, int x,
248                                                         int y);
249 
place_off_map(struct place * place,int x,int y)250 static inline int place_off_map(struct place *place, int x, int y) {
251         if (place->wraps)
252                 return 0;
253         return (x < 0 || x >= place_w(place) || y < 0 ||
254                 y >= place_h(place));
255 }
256 
257 // returns direction location is off map (assumes it *is* off the map- check that first!)
place_off_map_dir(struct place * place,int x,int y)258 static inline int place_off_map_dir(struct place *place, int x, int y)
259 {
260     if (y<0) {
261         if (x<0) {
262             return NORTHWEST;
263         } else if (x >= place_w(place)) {
264             return NORTHEAST;
265         } else {
266             return NORTH;
267         }
268     } else if (y>=place_h(place)) {
269         if (x<0) {
270             return SOUTHWEST;
271         } else if (x >= place_w(place)) {
272             return SOUTHEAST;
273         } else {
274             return SOUTH;
275         }
276     } else if (x >= place_w(place)) {
277         return EAST;
278     } else {
279         assert(x<0);
280         return WEST;
281     }
282 }
283 
284 extern void place_clip_to_map(struct place *place, int *x, int *y);
285 
place_wrap_x(struct place * place,int x)286 static inline int place_wrap_x(struct place *place, int x) {
287         if (place->wraps)
288                 return ((x +
289                          place->terrain_map->w) %
290                         place->terrain_map->w);
291         return x;
292 }
293 
place_wrap_y(struct place * place,int y)294 static inline int place_wrap_y(struct place *place, int y) {
295         if (place->wraps)
296                 return ((y +
297                          place->terrain_map->h) %
298                         place->terrain_map->h);
299         return y;
300 }
301 
302 extern void place_for_each_object(struct place *place, void (*fx) (class Object *, void *data), void *data);
303 extern int place_get_light(struct place *place, int x, int y);
304 extern void place_set_terrain(struct place *place, int x, int y, struct terrain *terrain);
305 extern struct terrain *place_get_terrain(struct place *place, int x, int y);
306 extern Uint32 place_get_color(struct place *place, int x, int y);
307 extern int place_get_movement_cost(struct place *place,
308                                    int to_x, int to_y,
309                                    class Object *obj, int flags);
310 extern int place_get_diagonal_movement_cost(struct place *place, int from_x,
311                                             int from_y,
312                                             int to_x, int to_y,
313                                             class Object *obj, int flags);
314 extern int place_adjust_turn_cost(struct place *place, int turns);
315 extern int place_is_hazardous(struct place *place, int x, int y);
316 extern class Party *place_random_encounter(struct place *);
317 extern void place_paint_objects(struct place *place, int mx, int my, int sx, int sy);
318 extern int place_los_blocked(struct place *place, int ax, int ay, int bx, int by);
319 extern void place_exec(struct place *place);
320 extern int place_contains_hostiles(struct place *place, Being *subject);
321 extern void place_synchronize(struct place *place);
322 extern void place_enter(struct place *place);
323 extern void place_remove_and_destroy_all_objects(struct place *place);
324 extern void place_save(struct save *, void *val);
325 extern void place_start(void *val);
326 extern int place_add_subplace(struct place *place, struct place *subplace,
327                               int x, int y);
328 extern struct place *place_get_subplace(struct place *place, int x, int y);
329 extern void place_remove_subplace(struct place *place, struct place *subplace);
330 extern void place_for_each_object_at(struct place *place, int x, int y, void (*fx)(class Object *, void *), void *);
331 extern void place_exit(struct place *place);
332 extern void place_unlock(struct place *place);
333 extern void place_describe(struct place *place, int x, int y, int flags);
334 extern void place_examine(struct place *place, int x, int y);
335 extern int place_get_edge_entrance(struct place *place, int dir, int *x, int *y);
336 extern int place_set_edge_entrance(struct place *place, int dir, int x, int y);
337 extern class Object *place_get_filtered_object(struct place *place, int x, int y, int (*filter)(class Object*));
338 extern struct place *place_get_neighbor(struct place *place, int dir);
339 extern void place_set_neighbor(struct place *place, int dir, struct place *neighbor);
340 extern int place_in_los(struct place *p1, int x1, int y1,
341                         struct place *p2, int x2, int y2);
342 extern void place_add_on_entry_hook(struct place *place, closure_t *hook_fx);
343 extern void place_set_terrain_map(struct place *place, struct terrain_map *map);
344 int place_move_is_passable(struct place *place, int from_x, int from_y,
345                            int to_x, int to_y,
346                            class Object *subject, int flags);
347 void place_apply_tile_effects(struct place *place, class Object *obj);
348 
349 END_DECL
350 
351 #endif
352