--- deliantra/server/server/attack.c 2006/02/09 02:11:26 1.3 +++ deliantra/server/server/attack.c 2006/03/30 11:11:35 1.7 @@ -339,6 +339,16 @@ if (tmp->map != map || tmp->x != x || tmp->y != y) continue; + /* Need to hit everyone in the transport with this spell */ + if (tmp->type == TRANSPORT) { + object *pl; + + for (pl=tmp->inv; pl; pl=pl->below) { + if (pl->type == PLAYER) + hit_player(pl,op->stats.dam,op,type,full_hit); + } + } + if (QUERY_FLAG (tmp, FLAG_ALIVE)) { hit_player(tmp,op->stats.dam,op,type,full_hit); retflag |=1; @@ -391,7 +401,8 @@ (type & AT_POISON && IS_LIVE(op))) && !found) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) - if (dam < attack_mess[ATM_SUFFER][i].level) { + if (dam < attack_mess[ATM_SUFFER][i].level + || attack_mess[ATM_SUFFER][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, op->name, attack_mess[ATM_SUFFER][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_SUFFER][i].buf3); @@ -401,7 +412,8 @@ } else if (op->type == DOOR && !found) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DOOR][i].level != -1; i++) - if (dam < attack_mess[ATM_DOOR][i].level) { + if (dam < attack_mess[ATM_DOOR][i].level + || attack_mess[ATM_DOOR][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_DOOR][i].buf1, op->name, attack_mess[ATM_DOOR][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_DOOR][i].buf3); @@ -412,7 +424,8 @@ if (USING_SKILL(hitter, SK_KARATE)) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) - if (dam < attack_mess[ATM_KARATE][i].level) { + if (dam < attack_mess[ATM_KARATE][i].level + || attack_mess[ATM_KARATE][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_KARATE][i].buf1, op->name, attack_mess[ATM_KARATE][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_KARATE][i].buf3); @@ -422,7 +435,8 @@ } else if (USING_SKILL(hitter, SK_CLAWING)) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_CLAW][i].level != -1; i++) - if (dam < attack_mess[ATM_CLAW][i].level) { + if (dam < attack_mess[ATM_CLAW][i].level + || attack_mess[ATM_CLAW][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_CLAW][i].buf1, op->name, attack_mess[ATM_CLAW][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_CLAW][i].buf3); @@ -432,7 +446,8 @@ } else if (USING_SKILL(hitter, SK_PUNCHING)) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_PUNCH][i].level != -1; i++) - if (dam < attack_mess[ATM_PUNCH][i].level) { + if (dam < attack_mess[ATM_PUNCH][i].level + || attack_mess[ATM_PUNCH][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_PUNCH][i].buf1, op->name, attack_mess[ATM_PUNCH][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_PUNCH][i].buf3); @@ -441,52 +456,63 @@ } } } - if (IS_ARROW(hitter) && (type == AT_PHYSICAL || type == AT_MAGIC) && - !found) { + if (found) { + /* done */ + } else if (IS_ARROW(hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) { sprintf(buf1, "hit"); /* just in case */ for (i=0; i < MAXATTACKMESS; i++) - if (dam < attack_mess[ATM_ARROW][i].level) { + if (dam < attack_mess[ATM_ARROW][i].level + || attack_mess[ATM_ARROW][i+1].level == -1) { sprintf(buf2, "%s", attack_mess[ATM_ARROW][i].buf3); + found++; break; } - } else if (type & AT_DRAIN && IS_LIVE(op) && !found) { + } else if (type & AT_DRAIN && IS_LIVE(op)) { /* drain is first, because some items have multiple attypes */ for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) - if (dam < attack_mess[ATM_DRAIN][i].level) { + if (dam < attack_mess[ATM_DRAIN][i].level + || attack_mess[ATM_DRAIN][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_DRAIN][i].buf1, op->name, attack_mess[ATM_DRAIN][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_DRAIN][i].buf3); + found++; break; } - } else if (type & AT_ELECTRICITY && IS_LIVE(op) && !found) { + } else if (type & AT_ELECTRICITY && IS_LIVE(op)) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) - if (dam < attack_mess[ATM_ELEC][i].level) { + if (dam < attack_mess[ATM_ELEC][i].level + || attack_mess[ATM_ELEC][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, op->name, attack_mess[ATM_ELEC][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_ELEC][i].buf3); + found++; break; } - } else if (type & AT_COLD && IS_LIVE(op) && !found) { + } else if (type & AT_COLD && IS_LIVE(op)) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) - if (dam < attack_mess[ATM_COLD][i].level) { + if (dam < attack_mess[ATM_COLD][i].level + || attack_mess[ATM_COLD][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, op->name, attack_mess[ATM_COLD][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_COLD][i].buf3); + found++; break; } - } else if (type & AT_FIRE && !found) { + } else if (type & AT_FIRE) { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_FIRE][i].level != -1; i++) - if (dam < attack_mess[ATM_FIRE][i].level) { + if (dam < attack_mess[ATM_FIRE][i].level + || attack_mess[ATM_FIRE][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_FIRE][i].buf1, op->name, attack_mess[ATM_FIRE][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_FIRE][i].buf3); + found++; break; } - } else if (hitter->current_weapon != NULL && !found) { + } else if (hitter->current_weapon != NULL) { int mtype; switch (hitter->current_weapon->weapontype) { case WEAP_HIT: mtype = ATM_BASIC; break; @@ -502,23 +528,32 @@ } for (i=0; i < MAXATTACKMESS && attack_mess[mtype][i].level != -1; i++) - if (dam < attack_mess[mtype][i].level) { + if (dam < attack_mess[mtype][i].level + || attack_mess[mtype][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[mtype][i].buf1, op->name, attack_mess[mtype][i].buf2); sprintf(buf2, "%s", attack_mess[mtype][i].buf3); + found++; break; } - } else if (!found){ + } else { for (i=0; i < MAXATTACKMESS && attack_mess[ATM_BASIC][i].level != -1; i++) - if (dam < attack_mess[ATM_BASIC][i].level) { + if (dam < attack_mess[ATM_BASIC][i].level + || attack_mess[ATM_BASIC][i+1].level == -1) { sprintf(buf1, "%s %s%s", attack_mess[ATM_BASIC][i].buf1, op->name, attack_mess[ATM_BASIC][i].buf2); sprintf(buf2, "%s", attack_mess[ATM_BASIC][i].buf3); + found++; break; } } + if (!found) { + sprintf(buf1, "hit"); + sprintf(buf2, "hits"); + } + /* bail out if a monster is casting spells */ if (!(hitter->type == PLAYER || (get_owner(hitter) != NULL && hitter->owner->type == PLAYER))) @@ -1157,14 +1192,9 @@ if(op->resist[ATNR_DRAIN] >= 0) rate = 50 + op->resist[ATNR_DRAIN] / 2; - else if(op->resist[ATNR_DRAIN] < 0) + else rate = 5000 / (100 - op->resist[ATNR_DRAIN]); - /* full protection has no effect. Nothing else in this - * function needs to get done, so just return. */ - if(!rate) - return 0; - if(op->stats.exp <= rate) { if(op->type == GOLEM) dam = 999; /* Its force is "sucked" away. 8) */ @@ -1620,6 +1650,18 @@ if (QUERY_FLAG (op, FLAG_WIZ) || QUERY_FLAG (op, FLAG_NO_DAMAGE)) return 0; +#ifdef PROHIBIT_PLAYERKILL + if (op->type == PLAYER) { + object *owner = get_owner (hitter); + if (!owner) owner = hitter; + if (owner->type == PLAYER + && !op_on_battleground (op, 0, 0) + && op != owner) { + return 0; + } + } +#endif + op_tag = op->count; hitter_tag = hitter->count;