version 1.82 | | version 1.83 |
---|
| | |
/* | | /* |
* static char *rcsid_attack_c = | | * static char *rcsid_attack_c = |
* "$Id: attack.c,v 1.82 2003/01/08 08:39:18 mwedel Exp $"; | | * "$Id: attack.c,v 1.83 2003/01/30 00:07:09 garbled Exp $"; |
*/ | | */ |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
*/ | | */ |
| | |
int did_make_save_item(object *op, int type,object *originator) { | | int did_make_save_item(object *op, int type,object *originator) { |
int i, saves=0,materials=0,number; | | int i, roll, saves=0, attacks=0, number; |
| | materialtype_t *mt; |
| | |
if(type&AT_CANCELLATION) | | if (op->materialname == NULL) { |
number=ATNR_CANCELLATION; | | for (mt = materialt; mt != NULL && mt->next != NULL; mt=mt->next) { |
else if(type&AT_COLD) | | if (op->material & mt->material) |
number=ATNR_COLD; | | break; |
else if(type&AT_ELECTRICITY) | | |
number=ATNR_ELECTRICITY; | | |
else if(type&AT_FIRE) | | |
number=ATNR_FIRE; | | |
else if(type&AT_PHYSICAL) | | |
number=ATNR_PHYSICAL; | | |
/* If we are hite by pure magic, the item can get destroyed. | | |
* But if hit by AT_MAGIC | AT_CONFUSION, it should have no effect. | | |
*/ | | |
else if(type==AT_MAGIC) /* Only pure magic, not paralyze, etc */ | | |
number=ATNR_MAGIC; | | |
else return 1; | | |
| | |
/* If the object is immune, no effect */ | | |
if (op->resist[number]==100) return 1; | | |
| | |
| | |
for(i=0;i<NROFMATERIALS;i++) { | | |
if(op->material&(1<<i)) { | | |
materials++; | | |
if(rndm(1, 20)>=material[i].save[number]-op->magic-op->resist[number]/100) | | |
saves++; | | |
/* if the attack is too weak */ | | |
if((20-material[i].save[number])/3 > originator->stats.dam) saves++; | | |
} | | } |
| | } else |
| | mt = name_to_material(op->materialname); |
| | if (mt == NULL) |
| | return TRUE; |
| | roll = rndm(1, 20); |
| | |
| | /* the attacktypes have no meaning for object saves */ |
| | type = type & ~(AT_CONFUSION|AT_DRAIN|AT_GHOSTHIT|AT_POISON|AT_SLOW| |
| | AT_PARALYZE|AT_TURN_UNDEAD|AT_FEAR|AT_DEPLETE|AT_DEATH| |
| | AT_COUNTERSPELL|AT_HOLYWORD|AT_BLIND|AT_LIFE_STEALING); |
| | |
| | if (type == 0) |
| | return TRUE; |
| | if (roll == 20) |
| | return TRUE; |
| | if (roll == 1) |
| | return FALSE; |
| | |
| | for (number=0; number < NROFATTACKS; i++) { |
| | i = 1<<number; |
| | if (!(i&type)) |
| | continue; |
| | attacks++; |
| | if (op->resist[number] == 100) |
| | saves++; |
| | else if (roll >= mt->save[number] - op->magic - op->resist[number]/100) |
| | saves++; |
| | else if ((20-mt->save[number])/3 > originator->stats.dam) |
| | saves++; |
} | | } |
if (saves==materials || materials==0) return 1; | | |
if ((saves==0) || (rndm(1, materials) > saves)) return 0; | | if (saves==attacks || attacks==0) |
return 1; | | return TRUE; |
| | if ((saves==0) || (rndm(1, attacks) > saves)) |
| | return FALSE; |
| | return TRUE; |
} | | } |
| | |
/* This function calls did_make_save_item. It then performs the | | /* This function calls did_make_save_item. It then performs the |
| | |
retflag |=1; | | retflag |=1; |
if (was_destroyed (op, op_tag)) | | if (was_destroyed (op, op_tag)) |
break; | | break; |
} else if (tmp->material && op->stats.dam > 0) { | | } else if ((tmp->material || tmp->materialname) && op->stats.dam > 0) { |
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; |