version 1.94 | | version 1.95 |
---|
| | |
/* | | /* |
* static char *rcsid_attack_c = | | * static char *rcsid_attack_c = |
* "$Id: attack.c,v 1.94 2003/10/27 07:24:14 mwedel Exp $"; | | * "$Id: attack.c,v 1.95 2003/12/21 02:13:46 mwedel Exp $"; |
*/ | | */ |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
} | | } |
} | | } |
| | |
| | /* Object op is hitting the map. |
| | * op is going in direction 'dir' |
| | * type is the attacktype of the object. |
| | * returns 1 if it hits something, 0 otherwise. |
| | */ |
| | |
int hit_map(object *op,int dir,int type) { | | int hit_map(object *op,int dir,int type) { |
object *tmp, *next; | | object *tmp, *next; |
mapstruct *map; | | mapstruct *map; |
sint16 x, y; | | 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 op_tag, next_tag=0; | | tag_t op_tag, next_tag=0; |
| | |
if (QUERY_FLAG (op, FLAG_FREED)) { | | if (QUERY_FLAG (op, FLAG_FREED)) { |
| | |
return 0; | | return 0; |
} | | } |
| | |
if (op->head) op=op->head; | | |
| | |
op_tag = op->count; | | |
| | |
if ( ! op->map) { | | if ( ! op->map) { |
LOG (llevError,"BUG: hit_map(): %s has no map", op->name); | | LOG (llevError,"BUG: hit_map(): %s has no map", op->name); |
return 0; | | return 0; |
} | | } |
| | |
| | if (op->head) op=op->head; |
| | |
| | op_tag = op->count; |
| | |
map = op->map; | | map = op->map; |
x = op->x + freearr_x[dir]; | | x = op->x + freearr_x[dir]; |
y = op->y + freearr_y[dir]; | | y = op->y + freearr_y[dir]; |
| | |
return 0; | | return 0; |
| | |
/* peterm: a few special cases for special attacktypes --counterspell | | /* peterm: a few special cases for special attacktypes --counterspell |
must be out here because it strikes things which are not alive*/ | | * must be out here because it strikes things which are not alive |
| | */ |
| | |
if(type&AT_COUNTERSPELL) { | | if(type&AT_COUNTERSPELL) { |
counterspell(op,dir); /* see newspells.c */ | | counterspell(op,dir); /* see spell_effect.c */ |
| | |
| | /* If the only attacktype is counterspell or magic, don't need |
| | * to do any further processing. |
| | */ |
if(!(type & ~(AT_COUNTERSPELL|AT_MAGIC))){ | | if(!(type & ~(AT_COUNTERSPELL|AT_MAGIC))){ |
return 0; /* we're done, no other attacks */ | | return 0; |
} | | } |
type &= ~AT_COUNTERSPELL; | | type &= ~AT_COUNTERSPELL; |
} | | } |
| | |
next = get_map_ob (map, x, y); | | next = get_map_ob (map, x, y); |
if (next) | | if (next) |
next_tag = next->count; | | next_tag = next->count; |
while (next) | | |
{ | | while (next) { |
if (was_destroyed (next, next_tag)) { | | if (was_destroyed (next, next_tag)) { |
/* There may still be objects that were above 'next', but there is no | | /* 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 | | * simple way to find out short of copying all object references and |
| | |
retflag |=1; | | retflag |=1; |
if (was_destroyed (op, op_tag)) | | if (was_destroyed (op, op_tag)) |
break; | | break; |
} else if ((tmp->material || tmp->materialname) && op->stats.dam > 0) { | | } |
| | /* Here we are potentially destroying an object. If the object has |
| | * NO_PASS set, it is also immune - you can't destroy walls. Note |
| | * that weak walls have is_alive set, which prevent objects from |
| | * passing over/through them. |
| | */ |
| | else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && |
| | !QUERY_FLAG(tmp, FLAG_NO_PASS)) { |
save_throw_object(tmp,type,op); | | save_throw_object(tmp,type,op); |
if (was_destroyed (op, op_tag)) | | if (was_destroyed (op, op_tag)) |
break; | | break; |