1 | /* |
1 | /* |
2 | * static char *rcsid_map_c = |
2 | * static char *rcsid_map_c = |
3 | * "$Id: region.c,v 1.1 2006/02/03 07:11:40 root Exp $"; |
3 | * "$Id: region.c,v 1.2 2006/07/09 10:56:01 elmex Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
66 | * Since we won't assume all maps have a region set properly, we need an |
66 | * Since we won't assume all maps have a region set properly, we need an |
67 | * explicit check that it is, this is much nicer here than scattered throughout |
67 | * explicit check that it is, this is much nicer here than scattered throughout |
68 | * the map code. |
68 | * the map code. |
69 | */ |
69 | */ |
70 | |
70 | |
71 | const char *get_name_of_region_for_map(mapstruct *m) { |
71 | const char *get_name_of_region_for_map(const mapstruct *m) { |
72 | region *reg; |
72 | region *reg; |
73 | if (m->region!=NULL) return m->region->name; |
73 | if (m->region!=NULL) return m->region->name; |
74 | for (reg=first_region;reg!=NULL;reg=reg->next) { |
74 | for (reg=first_region;reg!=NULL;reg=reg->next) { |
75 | if (reg->fallback) return reg->name; |
75 | if (reg->fallback) return reg->name; |
76 | } |
76 | } |
… | |
… | |
139 | * returns 1 if the player is in the region reg, or a child region thereof |
139 | * returns 1 if the player is in the region reg, or a child region thereof |
140 | * otherwise returns 0 |
140 | * otherwise returns 0 |
141 | * if passed a NULL region returns -1 |
141 | * if passed a NULL region returns -1 |
142 | */ |
142 | */ |
143 | |
143 | |
144 | int region_is_child_of_region(region *child, region *r) { |
144 | int region_is_child_of_region(const region *child, const region *r) { |
145 | |
145 | |
146 | if (r==NULL) |
146 | if (r==NULL) |
147 | return -1; |
147 | return -1; |
148 | if (child == NULL) |
148 | if (child == NULL) |
149 | return 0; |
149 | return 0; |
… | |
… | |
160 | * 1. check if a longname is set and if so return it. |
160 | * 1. check if a longname is set and if so return it. |
161 | * 2. check if there is a parent and try and call the function against that |
161 | * 2. check if there is a parent and try and call the function against that |
162 | * 3. return a obviously wrong string if we can't get a longname, this should |
162 | * 3. return a obviously wrong string if we can't get a longname, this should |
163 | * never happen. We also log a debug message. |
163 | * never happen. We also log a debug message. |
164 | */ |
164 | */ |
165 | const char *get_region_longname(region *r) { |
165 | const char *get_region_longname(const region *r) { |
166 | |
166 | |
167 | if (r->longname!=NULL) |
167 | if (r->longname!=NULL) |
168 | return r->longname; |
168 | return r->longname; |
169 | else if(r->parent!=NULL) |
169 | else if(r->parent!=NULL) |
170 | return get_region_longname(r->parent); |
170 | return get_region_longname(r->parent); |
… | |
… | |
172 | LOG(llevDebug,"NOTICE region %s has no parent and no longname.\n", r->name); |
172 | LOG(llevDebug,"NOTICE region %s has no parent and no longname.\n", r->name); |
173 | return "no name can be found for the current region"; |
173 | return "no name can be found for the current region"; |
174 | } |
174 | } |
175 | } |
175 | } |
176 | |
176 | |
177 | const char *get_region_msg(region *r) { |
177 | const char *get_region_msg(const region *r) { |
178 | if (r->msg!=NULL) |
178 | if (r->msg!=NULL) |
179 | return r->msg; |
179 | return r->msg; |
180 | else if(r->parent!=NULL) |
180 | else if(r->parent!=NULL) |
181 | return get_region_msg(r->parent); |
181 | return get_region_msg(r->parent); |
182 | else { |
182 | else { |
183 | LOG(llevDebug,"NOTICE region %s has no parent and no msg.\n", r->name); |
183 | LOG(llevDebug,"NOTICE region %s has no parent and no msg.\n", r->name); |
184 | return "no description can be found for the current region"; |
184 | return "no description can be found for the current region"; |
185 | } |
185 | } |
|
|
186 | } |
|
|
187 | |
|
|
188 | /** Returns an object which is an exit through which the player represented by op should be |
|
|
189 | * sent in order to be imprisoned. If there is no suitable place to which an exit can be |
|
|
190 | * constructed, then NULL will be returned. The caller is responsible for freeing the object |
|
|
191 | * created by this function. |
|
|
192 | */ |
|
|
193 | object *get_jail_exit(object *op) { |
|
|
194 | region *reg; |
|
|
195 | object *exit; |
|
|
196 | if (op->type != PLAYER) { |
|
|
197 | LOG(llevError, "region.c: get_jail_exit called against non-player object.\n"); |
|
|
198 | return NULL; |
|
|
199 | } |
|
|
200 | reg=get_region_by_map(op->map); |
|
|
201 | while (reg!=NULL) { |
|
|
202 | if (reg->jailmap) { |
|
|
203 | exit=get_object(); |
|
|
204 | EXIT_PATH(exit)=add_string(reg->jailmap); |
|
|
205 | /* damned exits reset savebed and remove teleports, so the prisoner can't escape */ |
|
|
206 | SET_FLAG(exit, FLAG_DAMNED); |
|
|
207 | EXIT_X(exit) = reg->jailx; |
|
|
208 | EXIT_Y(exit) = reg->jaily; |
|
|
209 | return exit; |
|
|
210 | } |
|
|
211 | else reg=reg->parent; |
|
|
212 | } |
|
|
213 | LOG(llevDebug,"No suitable jailmap for region %s was found.\n", reg->name); |
|
|
214 | return NULL; |
186 | } |
215 | } |
187 | |
216 | |
188 | /* |
217 | /* |
189 | * First initialises the archtype hash-table (init_archetable()). |
218 | * First initialises the archtype hash-table (init_archetable()). |
190 | * Reads and parses the archetype file (with the first and second-pass |
219 | * Reads and parses the archetype file (with the first and second-pass |
… | |
… | |
224 | |
253 | |
225 | new=(region *)CALLOC(1,sizeof(region)); |
254 | new=(region *)CALLOC(1,sizeof(region)); |
226 | if(new==NULL) |
255 | if(new==NULL) |
227 | fatal(OUT_OF_MEMORY); |
256 | fatal(OUT_OF_MEMORY); |
228 | |
257 | |
229 | memset(new, sizeof(region), '\0'); |
258 | memset(new, '\0', sizeof(region)); |
230 | |
259 | |
231 | return new; |
260 | return new; |
232 | } |
261 | } |
233 | |
262 | |
234 | /* |
263 | /* |
235 | * Reads/parses the region file, and copies into a linked list |
264 | * Reads/parses the region file, and copies into a linked list |
… | |
… | |
287 | new->parent_name = strdup_local(value); |
316 | new->parent_name = strdup_local(value); |
288 | } |
317 | } |
289 | else if (!strcmp(key,"longname")) { |
318 | else if (!strcmp(key,"longname")) { |
290 | *end=0; |
319 | *end=0; |
291 | new->longname = strdup_local(value); |
320 | new->longname = strdup_local(value); |
|
|
321 | } |
|
|
322 | else if (!strcmp(key,"jail")) { |
|
|
323 | /* jail entries are of the form: /path/to/map x y */ |
|
|
324 | char path[MAX_BUF]; |
|
|
325 | int x,y; |
|
|
326 | if (sscanf(value, "%[^ ] %d %d\n", path, &x, &y) != 3) { |
|
|
327 | LOG(llevError, "region.c: malformated regions entry: jail %s\n", value); |
|
|
328 | continue; |
|
|
329 | } |
|
|
330 | new->jailmap = strdup_local(path); |
|
|
331 | new->jailx = x; |
|
|
332 | new->jaily = y; |
292 | } |
333 | } |
293 | else if (!strcmp(key,"msg")) { |
334 | else if (!strcmp(key,"msg")) { |
294 | while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { |
335 | while (fgets(buf, HUGE_BUF-1, fp)!=NULL) { |
295 | if (!strcmp(buf,"endmsg\n")) break; |
336 | if (!strcmp(buf,"endmsg\n")) break; |
296 | else { |
337 | else { |