version 1.60 | | version 1.61 |
---|
| | |
/* | | /* |
* static char *rcsid_spell_effect_c = | | * static char *rcsid_spell_effect_c = |
* "$Id: spell_effect.c,v 1.60 2001/07/14 04:11:18 mwedel Exp $"; | | * "$Id: spell_effect.c,v 1.61 2001/08/29 07:14:16 mwedel Exp $"; |
*/ | | */ |
| | |
| | |
| | |
} | | } |
| | |
int cast_detection(object *op, int type) { | | int cast_detection(object *op, int type) { |
object *tmp; | | object *tmp, *last=NULL; |
int x,y,done_one; | | int x,y,done_one,nx,ny; |
archetype *detect_arch; | | archetype *detect_arch; |
| | mapstruct *m; |
| | |
detect_arch = find_archetype("detect_magic"); | | detect_arch = find_archetype("detect_magic"); |
if (detect_arch == (archetype *) NULL) | | if (detect_arch == (archetype *) NULL) { |
{ | | |
LOG(llevError, "Couldn't find archetype detect_magic.\n"); | | LOG(llevError, "Couldn't find archetype detect_magic.\n"); |
return 0; | | return 0; |
} | | } |
| | |
| | /* this size should really be based on level or spell parameter - |
| | * even if out of the view, the setting of these values can be useful |
| | * simply so that when you come across them they have already been |
| | * set for you. |
| | */ |
for (x = op->x - MAP_CLIENT_X/2; x <= op->x + MAP_CLIENT_X/2; x++) | | for (x = op->x - MAP_CLIENT_X/2; x <= op->x + MAP_CLIENT_X/2; x++) |
for (y = op->y - MAP_CLIENT_Y/2; y <= op->y + MAP_CLIENT_Y/2; y++) { | | for (y = op->y - MAP_CLIENT_Y/2; y <= op->y + MAP_CLIENT_Y/2; y++) { |
| | |
if (out_of_map(op->map, x, y)) | | if (out_of_map(op->map, x, y)) |
continue; | | continue; |
| | |
done_one = 0; | | done_one = 0; |
for (tmp = get_map_ob(op->map, x, y); tmp && | | nx=x; |
(!done_one || type==SP_DETECT_MAGIC || type==SP_DETECT_CURSE); | | ny=y; |
tmp = tmp->above) | | m = get_map_from_coord(op->map, &nx, &ny); |
{ | | |
| | /* Add some logic here to only examine objects above the floor. |
| | * This should not be done for show invis (may want to show |
| | * invisible floor objects) - may be others also. |
| | */ |
| | |
| | if (type==SP_SHOW_INVIS) last = get_map_ob(m, nx, ny); |
| | else { |
| | for (tmp=get_map_ob(m, nx, ny); tmp; tmp=tmp->above) last=tmp; |
| | |
| | for (tmp=last; tmp; tmp=tmp->below) { |
| | if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break; |
| | else last=tmp; |
| | } |
| | |
| | if (tmp) last=tmp->above; |
| | } |
| | |
| | /* detect magic and detect curse need to set flags on all the items. for |
| | * the other detect spells, we only care if there is one of the matching object |
| | * on that face. |
| | */ |
| | for (tmp = last; |
| | tmp && (!done_one || type==SP_DETECT_MAGIC || type==SP_DETECT_CURSE); |
| | tmp=tmp->above) { |
| | |
switch(type) { | | switch(type) { |
| | |
case SP_DETECT_MAGIC: | | case SP_DETECT_MAGIC: |
if (!QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) && !QUERY_FLAG(tmp, FLAG_IDENTIFIED) && | | if (!QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) && !QUERY_FLAG(tmp, FLAG_IDENTIFIED) && |
is_magical(tmp)) { | | is_magical(tmp)) { |
| | |
SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); | | SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); |
if(tmp->type==RUNE) /*peterm: make runes more visible*/ | | /* peterm: make magical runes more visible*/ |
if(tmp->attacktype&AT_MAGIC) /* if they're magic! */ | | if(tmp->type==RUNE && tmp->attacktype&AT_MAGIC) |
tmp->stats.Cha/=4; | | tmp->stats.Cha/=4; |
done_one = 1; | | done_one = 1; |
} | | } |
break; | | break; |
| | |
case SP_DETECT_MONSTER: | | case SP_DETECT_MONSTER: |
if (op->type == PLAYER) | | /* lets not care about who is casting the spell - everyone on the |
done_one = QUERY_FLAG(tmp, FLAG_MONSTER); | | * map sees the results anyways, |
else | | */ |
done_one = (tmp->type == PLAYER); | | if ((QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) { |
| | done_one = 2; |
| | last=tmp; |
| | } |
break; | | break; |
case SP_DETECT_EVIL: { | | |
| | |
| | case SP_DETECT_EVIL: |
done_one = 0; | | done_one = 0; |
if(QUERY_FLAG(tmp,FLAG_MONSTER)&&tmp->race) { | | if(QUERY_FLAG(tmp,FLAG_MONSTER)&&tmp->race) { |
object *god=find_god(determine_god(op)); | | object *god=find_god(determine_god(op)); |
if(god&&god->slaying&&strstr(god->slaying,tmp->race)) | | if(god && god->slaying && strstr(god->slaying,tmp->race)) { |
done_one = 1; | | last=tmp; |
| | done_one = 2; |
} | | } |
break; | | |
} | | } |
| | break; |
| | |
| | |
case SP_SHOW_INVIS: | | case SP_SHOW_INVIS: |
/* Might there be other objects that we can make visibile? */ | | /* Might there be other objects that we can make visibile? */ |
if (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || | | if (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || |
| | |
} | | } |
} | | } |
break; | | break; |
| | |
case SP_DETECT_CURSE: | | case SP_DETECT_CURSE: |
if (!QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && | | if (!QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && |
(QUERY_FLAG(tmp, FLAG_CURSED) || | | (QUERY_FLAG(tmp, FLAG_CURSED) || |
| | |
done_one = 1; | | done_one = 1; |
} | | } |
break; | | break; |
} | | |
| | } /* end of switch statement */ |
} /* Done all the object on this square */ | | } /* Done all the object on this square */ |
| | |
if (done_one) { | | if (done_one) { |
object *detect_ob = arch_to_object(detect_arch); | | object *detect_ob = arch_to_object(detect_arch); |
detect_ob->x = x; | | detect_ob->x = x; |
detect_ob->y = y; | | detect_ob->y = y; |
insert_ob_in_map(detect_ob, op->map, op,0); | | /* if this is set, we want to copy the face */ |
| | if (done_one == 2 && last) { |
| | detect_ob->face = last->face; |
| | detect_ob->animation_id = last->animation_id; |
| | detect_ob->anim_speed = last->anim_speed; |
| | detect_ob->last_anim=0; |
| | /* by default, the detect_ob is already animated */ |
| | if (!QUERY_FLAG(last, FLAG_ANIMATE)) CLEAR_FLAG(detect_ob, FLAG_ANIMATE); |
} | | } |
| | insert_ob_in_map(detect_ob, op->map, op,0); |
} | | } |
if ((type == SP_DETECT_MAGIC || type == SP_DETECT_CURSE) && | | } /* for processing the surrounding spaces */ |
op->type == PLAYER) | | |
{ | | /* Now process objects in the players inventory if detect curse or magic */ |
| | if ((type == SP_DETECT_MAGIC || type == SP_DETECT_CURSE) && op->type == PLAYER) { |
done_one = 0; | | done_one = 0; |
for (tmp = op->inv; tmp; tmp = tmp->below) | | for (tmp = op->inv; tmp; tmp = tmp->below) { |
if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)) | | if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)) |
| | |
switch(type) { | | switch(type) { |
case SP_DETECT_MAGIC: | | case SP_DETECT_MAGIC: |
if (is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) { | | if (is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) { |
| | |
done_one = 1; | | done_one = 1; |
} | | } |
break; | | break; |
| | |
case SP_DETECT_CURSE: | | case SP_DETECT_CURSE: |
if (!QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && | | if (!QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && |
(QUERY_FLAG(tmp, FLAG_CURSED) || | | (QUERY_FLAG(tmp, FLAG_CURSED) || |
| | |
done_one = 1; | | done_one = 1; |
} | | } |
break; | | break; |
} | | } /* end of switch */ |
} | | } /* for the players inventory */ |
| | } /* if detect magic/curse and object is a player */ |
return 1; | | return 1; |
} | | } |
| | |