version 1.11 | | version 1.12 |
---|
| | |
/* | | /* |
* static char *rcsid_attack_c = | | * static char *rcsid_attack_c = |
* "$Id: attack.c,v 1.11 2000/05/26 12:36:49 jec Exp $"; | | * "$Id: attack.c,v 1.12 2000/06/07 23:46:18 jec Exp $"; |
*/ | | */ |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
} | | } |
| | |
int hit_map(object *op,int dir,int type) { | | int hit_map(object *op,int dir,int type) { |
object *tmp,*next=NULL; | | object *tmp, *next; |
| | mapstruct *map; |
| | sint16 x, y; |
int retflag=0; /* added this flag.. will return 1 if it hits a monster */ | | int retflag=0; /* added this flag.. will return 1 if it hits a monster */ |
tag_t tag; | | tag_t op_tag, next_tag; |
| | |
if (QUERY_FLAG (op, FLAG_FREED)) { | | if (QUERY_FLAG (op, FLAG_FREED)) { |
LOG (llevError, "BUG: hit_map(): free object\n"); | | LOG (llevError, "BUG: hit_map(): free object\n"); |
| | |
| | |
if (op->head) op=op->head; | | if (op->head) op=op->head; |
| | |
tag = op->count; | | op_tag = op->count; |
| | |
if (!op->map) { | | if (!op->map) { |
LOG(llevDebug,"hit_map called, but %s has no map", op->name); | | LOG (llevError,"BUG: hit_map(): %s has no map", op->name); |
return 0; | | return 0; |
} | | } |
if(out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) | | map = op->map; |
| | x = op->x + freearr_x[dir]; |
| | y = op->y + freearr_y[dir]; |
| | if (out_of_map (map, x, y)) |
return 0; | | return 0; |
| | |
/* peterm: a few special cases for special attacktypes --counterspell | | /* peterm: a few special cases for special attacktypes --counterspell |
| | |
type &= ~AT_CHAOS; | | type &= ~AT_CHAOS; |
} | | } |
| | |
for(tmp=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]); | | next = get_map_ob (map, x, y); |
tmp!=NULL;tmp=next) | | if (next) |
| | next_tag = next->count; |
| | while (next) |
{ | | { |
| | if (was_destroyed (next, next_tag)) { |
| | /* There may still be objects that were above 'next', but there is no |
| | * simple way to find out short of copying all object references and |
| | * tags into a temporary array before we start processing the first |
| | * object. That's why we just abort. Doesn't happen very often anyway. |
| | */ |
| | LOG (llevDebug, "hit_map(): next object destroyed\n"); |
| | break; |
| | } |
| | tmp = next; |
next=tmp->above; | | next=tmp->above; |
| | if (next) |
| | next_tag = next->count; |
| | |
/* Since we are traversing a stack, it is possible that the stack | | |
* gets messed up. So do some checks. | | |
*/ | | |
if (QUERY_FLAG(tmp, FLAG_FREED)) { | | if (QUERY_FLAG(tmp, FLAG_FREED)) { |
LOG(llevDebug,"Warning: in hit_map, found free object\n"); | | LOG (llevError, "BUG: hit_map(): found free object\n"); |
break; | | break; |
} | | } |
else if(QUERY_FLAG(tmp,FLAG_ALIVE)) { | | |
| | /* Something could have happened to 'tmp' while 'tmp->below' was processed. |
| | * For example, 'tmp' was put in an icecube. |
| | */ |
| | if (tmp->map != map || tmp->x != x || tmp->y != y) |
| | continue; |
| | |
| | if (QUERY_FLAG (tmp, FLAG_ALIVE)) { |
hit_player(tmp,op->stats.dam,op,type); | | hit_player(tmp,op->stats.dam,op,type); |
retflag |=1; | | retflag |=1; |
if (was_destroyed (op, tag)) | | if (was_destroyed (op, op_tag)) |
break; | | break; |
} /* It is possible the object has been relocated to know longer be | | } else if (tmp->material) { |
* on the map (ie, in an icecube.) If we no longer have a map, | | |
* just ignore. | | |
*/ | | |
else if(tmp->material && tmp->map) | | |
save_throw_object(tmp,type); | | save_throw_object(tmp,type); |
} | | } |
/*if(tmp==NULL) return 0; This doesn't work, of course */ | | } |
#ifdef NO_CONE_PROPOGATE | | #ifdef NO_CONE_PROPOGATE |
return retflag; | | return retflag; |
#else | | #else |