1 | /* |
1 | /* |
2 | * static char *rcsid_treasure_c = |
2 | * static char *rcsid_treasure_c = |
3 | * "$Id: treasure.C,v 1.1 2006/08/13 17:16:03 elmex Exp $"; |
3 | * "$Id: treasure.C,v 1.3 2006/09/03 00:18:41 root 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 | |
… | |
… | |
57 | |
57 | |
58 | int wall_blocked(mapstruct *m, int x, int y) { |
58 | int wall_blocked(mapstruct *m, int x, int y) { |
59 | int r; |
59 | int r; |
60 | |
60 | |
61 | if(OUT_OF_REAL_MAP(m,x,y)) |
61 | if(OUT_OF_REAL_MAP(m,x,y)) |
62 | return 1; |
62 | return 1; |
63 | r = GET_MAP_MOVE_BLOCK(m,x,y) & ~MOVE_BLOCK_DEFAULT; |
63 | r = GET_MAP_MOVE_BLOCK(m,x,y) & ~MOVE_BLOCK_DEFAULT; |
64 | return r; |
64 | return r; |
65 | } |
65 | } |
66 | |
66 | |
67 | /* place treasures in the map, given the |
67 | /* place treasures in the map, given the |
… | |
… | |
166 | } |
166 | } |
167 | |
167 | |
168 | |
168 | |
169 | |
169 | |
170 | /* put a chest into the map, near x and y, with the treasure style |
170 | /* put a chest into the map, near x and y, with the treasure style |
171 | determined (may be null, or may be a treasure list from lib/treasures, |
171 | determined (may be null, or may be a treasure list from lib/treasures, |
172 | if the global variable "treasurestyle" is set to that treasure list's name */ |
172 | if the global variable "treasurestyle" is set to that treasure list's name */ |
173 | |
173 | |
174 | object * place_chest(int treasureoptions,int x, int y,mapstruct *map, mapstruct *style_map,int n_treasures,RMParms *RP) { |
174 | object * place_chest(int treasureoptions,int x, int y,mapstruct *map, mapstruct *style_map,int n_treasures,RMParms *RP) { |
175 | object *the_chest; |
175 | object *the_chest; |
176 | int i,xl,yl; |
176 | int i,xl,yl; |
177 | |
177 | |
… | |
… | |
235 | there's only 1 treasure....*/ |
235 | there's only 1 treasure....*/ |
236 | |
236 | |
237 | if((treasureoptions & KEYREQUIRED)&&n_treasures>1) { |
237 | if((treasureoptions & KEYREQUIRED)&&n_treasures>1) { |
238 | char keybuf[256]; |
238 | char keybuf[256]; |
239 | sprintf(keybuf,"%d",(int)RANDOM()); |
239 | sprintf(keybuf,"%d",(int)RANDOM()); |
240 | the_chest->slaying = add_string(keybuf); |
240 | the_chest->slaying = keybuf; |
241 | keyplace(map,x,y,keybuf,PASS_DOORS,1,RP); |
241 | keyplace(map,x,y,keybuf,PASS_DOORS,1,RP); |
242 | } |
242 | } |
243 | |
243 | |
244 | /* actually place the chest. */ |
244 | /* actually place the chest. */ |
245 | the_chest->x = xl; the_chest->y = yl; |
245 | the_chest->x = xl; the_chest->y = yl; |
… | |
… | |
247 | return the_chest; |
247 | return the_chest; |
248 | } |
248 | } |
249 | |
249 | |
250 | |
250 | |
251 | /* finds the closest monster and returns him, regardless of doors |
251 | /* finds the closest monster and returns him, regardless of doors |
252 | or walls */ |
252 | or walls */ |
253 | object *find_closest_monster(mapstruct *map,int x,int y,RMParms *RP) { |
253 | object *find_closest_monster(mapstruct *map,int x,int y,RMParms *RP) { |
254 | int i; |
254 | int i; |
255 | for(i=0;i<SIZEOFFREE;i++) { |
255 | for(i=0;i<SIZEOFFREE;i++) { |
256 | int lx,ly; |
256 | int lx,ly; |
257 | lx=x+freearr_x[i]; |
257 | lx=x+freearr_x[i]; |
… | |
… | |
270 | } |
270 | } |
271 | |
271 | |
272 | |
272 | |
273 | |
273 | |
274 | /* places keys in the map, preferably in something alive. |
274 | /* places keys in the map, preferably in something alive. |
275 | keycode is the key's code, |
275 | keycode is the key's code, |
276 | door_flag is either PASS_DOORS or NO_PASS_DOORS. |
276 | door_flag is either PASS_DOORS or NO_PASS_DOORS. |
277 | NO_PASS_DOORS won't cross doors or walls to keyplace, PASS_DOORS will. |
277 | NO_PASS_DOORS won't cross doors or walls to keyplace, PASS_DOORS will. |
278 | if n_keys is 1, it will place 1 key. if n_keys >1, it will place 2-4 keys: |
278 | if n_keys is 1, it will place 1 key. if n_keys >1, it will place 2-4 keys: |
279 | it will place 2-4 keys regardless of what nkeys is provided nkeys > 1. |
279 | it will place 2-4 keys regardless of what nkeys is provided nkeys > 1. |
280 | |
280 | |
281 | The idea is that you call keyplace on x,y where a door is, and it'll make |
281 | The idea is that you call keyplace on x,y where a door is, and it'll make |
282 | sure a key is placed on both sides of the door. |
282 | sure a key is placed on both sides of the door. |
283 | */ |
283 | */ |
284 | |
284 | |
285 | int keyplace(mapstruct *map,int x,int y,char *keycode,int door_flag,int n_keys,RMParms *RP) { |
285 | int keyplace(mapstruct *map,int x,int y,char *keycode,int door_flag,int n_keys,RMParms *RP) { |
286 | int i,j; |
286 | int i,j; |
287 | int kx,ky; |
287 | int kx,ky; |
288 | object *the_keymaster; /* the monster that gets the key. */ |
288 | object *the_keymaster; /* the monster that gets the key. */ |
289 | object *the_key; |
289 | object *the_key; |
290 | |
290 | |
291 | /* get a key and set its keycode */ |
291 | /* get a key and set its keycode */ |
292 | the_key = get_archetype("key2"); |
292 | the_key = get_archetype("key2"); |
293 | the_key->slaying = add_string(keycode); |
293 | the_key->slaying = keycode; |
294 | |
|
|
295 | |
294 | |
296 | if(door_flag==PASS_DOORS) { |
295 | if(door_flag==PASS_DOORS) { |
297 | int tries=0; |
296 | int tries=0; |
298 | the_keymaster=NULL; |
297 | the_keymaster=NULL; |
299 | while(tries<15&&the_keymaster==NULL) { |
298 | while(tries<15&&the_keymaster==NULL) { |
… | |
… | |
306 | if(the_keymaster==NULL) { |
305 | if(the_keymaster==NULL) { |
307 | int freeindex; |
306 | int freeindex; |
308 | |
307 | |
309 | freeindex = -1; |
308 | freeindex = -1; |
310 | for(tries = 0; tries < 15 && freeindex == -1; tries++) { |
309 | for(tries = 0; tries < 15 && freeindex == -1; tries++) { |
311 | kx = (RANDOM()%(RP->Xsize-2))+1; |
310 | kx = (RANDOM()%(RP->Xsize-2))+1; |
312 | ky = (RANDOM()%(RP->Ysize-2))+1; |
311 | ky = (RANDOM()%(RP->Ysize-2))+1; |
313 | freeindex = find_first_free_spot(the_key,map,kx,ky); |
312 | freeindex = find_first_free_spot(the_key,map,kx,ky); |
314 | } |
313 | } |
315 | if(freeindex != -1) { |
314 | if(freeindex != -1) { |
316 | kx += freearr_x[freeindex]; |
315 | kx += freearr_x[freeindex]; |
317 | ky += freearr_y[freeindex]; |
316 | ky += freearr_y[freeindex]; |
318 | } |
317 | } |
319 | } |
318 | } |
320 | } |
319 | } |
321 | else { /* NO_PASS_DOORS --we have to work harder.*/ |
320 | else { /* NO_PASS_DOORS --we have to work harder.*/ |
322 | /* don't try to keyplace if we're sitting on a blocked square and |
321 | /* don't try to keyplace if we're sitting on a blocked square and |
… | |
… | |
494 | free(room_free_spots_y); |
493 | free(room_free_spots_y); |
495 | } |
494 | } |
496 | |
495 | |
497 | |
496 | |
498 | /* searches the map for a spot with walls around it. The more |
497 | /* searches the map for a spot with walls around it. The more |
499 | walls the better, but it'll settle for 1 wall, or even 0, but |
498 | walls the better, but it'll settle for 1 wall, or even 0, but |
500 | it'll return 0 if no FREE spots are found.*/ |
499 | it'll return 0 if no FREE spots are found.*/ |
501 | |
500 | |
502 | void find_enclosed_spot(mapstruct *map, int *cx, int *cy,RMParms *RP) { |
501 | void find_enclosed_spot(mapstruct *map, int *cx, int *cy,RMParms *RP) { |
503 | int x,y; |
502 | int x,y; |
504 | int i; |
503 | int i; |
505 | x = *cx;y=*cy; |
504 | x = *cx;y=*cy; |
… | |
… | |
567 | }; |
566 | }; |
568 | } |
567 | } |
569 | |
568 | |
570 | |
569 | |
571 | /* surrounds the point x,y by doors, so as to enclose something, like |
570 | /* surrounds the point x,y by doors, so as to enclose something, like |
572 | a chest. It only goes as far as the 8 squares surrounding, and |
571 | a chest. It only goes as far as the 8 squares surrounding, and |
573 | it'll remove any monsters it finds.*/ |
572 | it'll remove any monsters it finds.*/ |
574 | |
573 | |
575 | object ** surround_by_doors(mapstruct *map,char **layout,int x,int y,int opts) { |
574 | object ** surround_by_doors(mapstruct *map,char **layout,int x,int y,int opts) { |
576 | int i; |
575 | int i; |
577 | char *doors[2]; |
576 | char *doors[2]; |
578 | object **doorlist; |
577 | object **doorlist; |
… | |
… | |
682 | } |
681 | } |
683 | |
682 | |
684 | |
683 | |
685 | |
684 | |
686 | /* locks and/or hides all the doors in doorlist, or does nothing if |
685 | /* locks and/or hides all the doors in doorlist, or does nothing if |
687 | opts doesn't say to lock/hide doors. */ |
686 | opts doesn't say to lock/hide doors. */ |
688 | |
687 | |
689 | void lock_and_hide_doors(object **doorlist,mapstruct *map,int opts,RMParms *RP) { |
688 | void lock_and_hide_doors(object **doorlist,mapstruct *map,int opts,RMParms *RP) { |
690 | object *door; |
689 | object *door; |
691 | int i; |
690 | int i; |
692 | /* lock the doors and hide the keys. */ |
691 | /* lock the doors and hide the keys. */ |
… | |
… | |
702 | remove_ob(door); |
701 | remove_ob(door); |
703 | free_object(door); |
702 | free_object(door); |
704 | doorlist[i]=new_door; |
703 | doorlist[i]=new_door; |
705 | insert_ob_in_map(new_door,map,NULL,0); |
704 | insert_ob_in_map(new_door,map,NULL,0); |
706 | sprintf(keybuf,"%d",(int)RANDOM()); |
705 | sprintf(keybuf,"%d",(int)RANDOM()); |
707 | new_door->slaying = add_string(keybuf); |
706 | new_door->slaying = keybuf; |
708 | keyplace(map,new_door->x,new_door->y,keybuf,NO_PASS_DOORS,2,RP); |
707 | keyplace(map,new_door->x,new_door->y,keybuf,NO_PASS_DOORS,2,RP); |
709 | } |
708 | } |
710 | } |
709 | } |
711 | |
710 | |
712 | /* change the faces of the doors and surrounding walls to hide them. */ |
711 | /* change the faces of the doors and surrounding walls to hide them. */ |