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