ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/attack.c
(Generate patch)

Comparing deliantra/server/server/attack.c (file contents):
Revision 1.2 by root, Fri Feb 3 07:25:25 2006 UTC vs.
Revision 1.12 by pippijn, Wed May 3 05:50:06 2006 UTC

1/* 1/*
2 * static char *rcsid_attack_c = 2 * static char *rcsid_attack_c =
3 * "$Id: attack.c,v 1.2 2006/02/03 07:25:25 root Exp $"; 3 * "$Id: attack.c,v 1.12 2006/05/03 05:50:06 pippijn Exp $";
4 */ 4 */
5/* 5/*
6 CrossFire, A Multiplayer game for X-windows 6 CrossFire, A Multiplayer game for X-windows
7 7
8 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 8 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
337 * This is one of the few cases where on_same_map should not be used. 337 * This is one of the few cases where on_same_map should not be used.
338 */ 338 */
339 if (tmp->map != map || tmp->x != x || tmp->y != y) 339 if (tmp->map != map || tmp->x != x || tmp->y != y)
340 continue; 340 continue;
341 341
342 /* Need to hit everyone in the transport with this spell */
343 if (tmp->type == TRANSPORT) {
344 object *pl;
345
346 for (pl=tmp->inv; pl; pl=pl->below) {
347 if (pl->type == PLAYER)
348 hit_player(pl,op->stats.dam,op,type,full_hit);
349 }
350 }
351
342 if (QUERY_FLAG (tmp, FLAG_ALIVE)) { 352 if (QUERY_FLAG (tmp, FLAG_ALIVE)) {
343 hit_player(tmp,op->stats.dam,op,type,full_hit); 353 hit_player(tmp,op->stats.dam,op,type,full_hit);
344 retflag |=1; 354 retflag |=1;
345 if (was_destroyed (op, op_tag)) 355 if (was_destroyed (op, op_tag))
346 break; 356 break;
389 } else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || 399 } else if ((hitter->type == DISEASE || hitter->type == SYMPTOM ||
390 hitter->type == POISONING || 400 hitter->type == POISONING ||
391 (type & AT_POISON && IS_LIVE(op))) && !found) { 401 (type & AT_POISON && IS_LIVE(op))) && !found) {
392 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; 402 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1;
393 i++) 403 i++)
394 if (dam < attack_mess[ATM_SUFFER][i].level) { 404 if (dam < attack_mess[ATM_SUFFER][i].level
405 || attack_mess[ATM_SUFFER][i+1].level == -1) {
395 sprintf(buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, 406 sprintf(buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1,
396 op->name, attack_mess[ATM_SUFFER][i].buf2); 407 op->name, attack_mess[ATM_SUFFER][i].buf2);
397 sprintf(buf2, "%s", attack_mess[ATM_SUFFER][i].buf3); 408 sprintf(buf2, "%s", attack_mess[ATM_SUFFER][i].buf3);
398 found++; 409 found++;
399 break; 410 break;
400 } 411 }
401 } else if (op->type == DOOR && !found) { 412 } else if (op->type == DOOR && !found) {
402 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DOOR][i].level != -1; 413 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DOOR][i].level != -1;
403 i++) 414 i++)
404 if (dam < attack_mess[ATM_DOOR][i].level) { 415 if (dam < attack_mess[ATM_DOOR][i].level
416 || attack_mess[ATM_DOOR][i+1].level == -1) {
405 sprintf(buf1, "%s %s%s", attack_mess[ATM_DOOR][i].buf1, 417 sprintf(buf1, "%s %s%s", attack_mess[ATM_DOOR][i].buf1,
406 op->name, attack_mess[ATM_DOOR][i].buf2); 418 op->name, attack_mess[ATM_DOOR][i].buf2);
407 sprintf(buf2, "%s", attack_mess[ATM_DOOR][i].buf3); 419 sprintf(buf2, "%s", attack_mess[ATM_DOOR][i].buf3);
408 found++; 420 found++;
409 break; 421 break;
410 } 422 }
411 } else if (hitter->type == PLAYER && IS_LIVE(op)) { 423 } else if (hitter->type == PLAYER && IS_LIVE(op)) {
412 if (USING_SKILL(hitter, SK_KARATE)) { 424 if (USING_SKILL(hitter, SK_KARATE)) {
413 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; 425 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1;
414 i++) 426 i++)
415 if (dam < attack_mess[ATM_KARATE][i].level) { 427 if (dam < attack_mess[ATM_KARATE][i].level
428 || attack_mess[ATM_KARATE][i+1].level == -1) {
416 sprintf(buf1, "%s %s%s", attack_mess[ATM_KARATE][i].buf1, 429 sprintf(buf1, "%s %s%s", attack_mess[ATM_KARATE][i].buf1,
417 op->name, attack_mess[ATM_KARATE][i].buf2); 430 op->name, attack_mess[ATM_KARATE][i].buf2);
418 sprintf(buf2, "%s", attack_mess[ATM_KARATE][i].buf3); 431 sprintf(buf2, "%s", attack_mess[ATM_KARATE][i].buf3);
419 found++; 432 found++;
420 break; 433 break;
421 } 434 }
422 } else if (USING_SKILL(hitter, SK_CLAWING)) { 435 } else if (USING_SKILL(hitter, SK_CLAWING)) {
423 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_CLAW][i].level != -1; 436 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_CLAW][i].level != -1;
424 i++) 437 i++)
425 if (dam < attack_mess[ATM_CLAW][i].level) { 438 if (dam < attack_mess[ATM_CLAW][i].level
439 || attack_mess[ATM_CLAW][i+1].level == -1) {
426 sprintf(buf1, "%s %s%s", attack_mess[ATM_CLAW][i].buf1, 440 sprintf(buf1, "%s %s%s", attack_mess[ATM_CLAW][i].buf1,
427 op->name, attack_mess[ATM_CLAW][i].buf2); 441 op->name, attack_mess[ATM_CLAW][i].buf2);
428 sprintf(buf2, "%s", attack_mess[ATM_CLAW][i].buf3); 442 sprintf(buf2, "%s", attack_mess[ATM_CLAW][i].buf3);
429 found++; 443 found++;
430 break; 444 break;
431 } 445 }
432 } else if (USING_SKILL(hitter, SK_PUNCHING)) { 446 } else if (USING_SKILL(hitter, SK_PUNCHING)) {
433 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_PUNCH][i].level != -1; 447 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_PUNCH][i].level != -1;
434 i++) 448 i++)
435 if (dam < attack_mess[ATM_PUNCH][i].level) { 449 if (dam < attack_mess[ATM_PUNCH][i].level
450 || attack_mess[ATM_PUNCH][i+1].level == -1) {
436 sprintf(buf1, "%s %s%s", attack_mess[ATM_PUNCH][i].buf1, 451 sprintf(buf1, "%s %s%s", attack_mess[ATM_PUNCH][i].buf1,
437 op->name, attack_mess[ATM_PUNCH][i].buf2); 452 op->name, attack_mess[ATM_PUNCH][i].buf2);
438 sprintf(buf2, "%s", attack_mess[ATM_PUNCH][i].buf3); 453 sprintf(buf2, "%s", attack_mess[ATM_PUNCH][i].buf3);
439 found++; 454 found++;
440 break; 455 break;
441 } 456 }
442 } 457 }
443 } 458 }
459 if (found) {
460 /* done */
444 if (IS_ARROW(hitter) && (type == AT_PHYSICAL || type == AT_MAGIC) && 461 } else if (IS_ARROW(hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) {
445 !found) {
446 sprintf(buf1, "hit"); /* just in case */ 462 sprintf(buf1, "hit"); /* just in case */
447 for (i=0; i < MAXATTACKMESS; i++) 463 for (i=0; i < MAXATTACKMESS; i++)
448 if (dam < attack_mess[ATM_ARROW][i].level) { 464 if (dam < attack_mess[ATM_ARROW][i].level
465 || attack_mess[ATM_ARROW][i+1].level == -1) {
449 sprintf(buf2, "%s", attack_mess[ATM_ARROW][i].buf3); 466 sprintf(buf2, "%s", attack_mess[ATM_ARROW][i].buf3);
467 found++;
450 break; 468 break;
451 } 469 }
452 } else if (type & AT_DRAIN && IS_LIVE(op) && !found) { 470 } else if (type & AT_DRAIN && IS_LIVE(op)) {
453 /* drain is first, because some items have multiple attypes */ 471 /* drain is first, because some items have multiple attypes */
454 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; 472 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1;
455 i++) 473 i++)
456 if (dam < attack_mess[ATM_DRAIN][i].level) { 474 if (dam < attack_mess[ATM_DRAIN][i].level
475 || attack_mess[ATM_DRAIN][i+1].level == -1) {
457 sprintf(buf1, "%s %s%s", attack_mess[ATM_DRAIN][i].buf1, 476 sprintf(buf1, "%s %s%s", attack_mess[ATM_DRAIN][i].buf1,
458 op->name, attack_mess[ATM_DRAIN][i].buf2); 477 op->name, attack_mess[ATM_DRAIN][i].buf2);
459 sprintf(buf2, "%s", attack_mess[ATM_DRAIN][i].buf3); 478 sprintf(buf2, "%s", attack_mess[ATM_DRAIN][i].buf3);
479 found++;
460 break; 480 break;
461 } 481 }
462 } else if (type & AT_ELECTRICITY && IS_LIVE(op) && !found) { 482 } else if (type & AT_ELECTRICITY && IS_LIVE(op)) {
463 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; 483 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1;
464 i++) 484 i++)
465 if (dam < attack_mess[ATM_ELEC][i].level) { 485 if (dam < attack_mess[ATM_ELEC][i].level
486 || attack_mess[ATM_ELEC][i+1].level == -1) {
466 sprintf(buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, 487 sprintf(buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1,
467 op->name, attack_mess[ATM_ELEC][i].buf2); 488 op->name, attack_mess[ATM_ELEC][i].buf2);
468 sprintf(buf2, "%s", attack_mess[ATM_ELEC][i].buf3); 489 sprintf(buf2, "%s", attack_mess[ATM_ELEC][i].buf3);
490 found++;
469 break; 491 break;
470 } 492 }
471 } else if (type & AT_COLD && IS_LIVE(op) && !found) { 493 } else if (type & AT_COLD && IS_LIVE(op)) {
472 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; 494 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1;
473 i++) 495 i++)
474 if (dam < attack_mess[ATM_COLD][i].level) { 496 if (dam < attack_mess[ATM_COLD][i].level
497 || attack_mess[ATM_COLD][i+1].level == -1) {
475 sprintf(buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, 498 sprintf(buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1,
476 op->name, attack_mess[ATM_COLD][i].buf2); 499 op->name, attack_mess[ATM_COLD][i].buf2);
477 sprintf(buf2, "%s", attack_mess[ATM_COLD][i].buf3); 500 sprintf(buf2, "%s", attack_mess[ATM_COLD][i].buf3);
501 found++;
478 break; 502 break;
479 } 503 }
480 } else if (type & AT_FIRE && !found) { 504 } else if (type & AT_FIRE) {
481 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_FIRE][i].level != -1; 505 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_FIRE][i].level != -1;
482 i++) 506 i++)
483 if (dam < attack_mess[ATM_FIRE][i].level) { 507 if (dam < attack_mess[ATM_FIRE][i].level
508 || attack_mess[ATM_FIRE][i+1].level == -1) {
484 sprintf(buf1, "%s %s%s", attack_mess[ATM_FIRE][i].buf1, 509 sprintf(buf1, "%s %s%s", attack_mess[ATM_FIRE][i].buf1,
485 op->name, attack_mess[ATM_FIRE][i].buf2); 510 op->name, attack_mess[ATM_FIRE][i].buf2);
486 sprintf(buf2, "%s", attack_mess[ATM_FIRE][i].buf3); 511 sprintf(buf2, "%s", attack_mess[ATM_FIRE][i].buf3);
512 found++;
487 break; 513 break;
488 } 514 }
489 } else if (hitter->current_weapon != NULL && !found) { 515 } else if (hitter->current_weapon != NULL) {
490 int mtype; 516 int mtype;
491 switch (hitter->current_weapon->weapontype) { 517 switch (hitter->current_weapon->weapontype) {
492 case WEAP_HIT: mtype = ATM_BASIC; break; 518 case WEAP_HIT: mtype = ATM_BASIC; break;
493 case WEAP_SLASH: mtype = ATM_SLASH; break; 519 case WEAP_SLASH: mtype = ATM_SLASH; break;
494 case WEAP_PIERCE: mtype = ATM_PIERCE; break; 520 case WEAP_PIERCE: mtype = ATM_PIERCE; break;
500 case WEAP_BLUD: mtype = ATM_BLUD; break; 526 case WEAP_BLUD: mtype = ATM_BLUD; break;
501 default: mtype = ATM_BASIC; break; 527 default: mtype = ATM_BASIC; break;
502 } 528 }
503 for (i=0; i < MAXATTACKMESS && attack_mess[mtype][i].level != -1; 529 for (i=0; i < MAXATTACKMESS && attack_mess[mtype][i].level != -1;
504 i++) 530 i++)
505 if (dam < attack_mess[mtype][i].level) { 531 if (dam < attack_mess[mtype][i].level
532 || attack_mess[mtype][i+1].level == -1) {
506 sprintf(buf1, "%s %s%s", attack_mess[mtype][i].buf1, 533 sprintf(buf1, "%s %s%s", attack_mess[mtype][i].buf1,
507 op->name, attack_mess[mtype][i].buf2); 534 op->name, attack_mess[mtype][i].buf2);
508 sprintf(buf2, "%s", attack_mess[mtype][i].buf3); 535 sprintf(buf2, "%s", attack_mess[mtype][i].buf3);
536 found++;
509 break; 537 break;
510 } 538 }
511 } else if (!found){ 539 } else {
512 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_BASIC][i].level != -1; 540 for (i=0; i < MAXATTACKMESS && attack_mess[ATM_BASIC][i].level != -1;
513 i++) 541 i++)
514 if (dam < attack_mess[ATM_BASIC][i].level) { 542 if (dam < attack_mess[ATM_BASIC][i].level
543 || attack_mess[ATM_BASIC][i+1].level == -1) {
515 sprintf(buf1, "%s %s%s", attack_mess[ATM_BASIC][i].buf1, 544 sprintf(buf1, "%s %s%s", attack_mess[ATM_BASIC][i].buf1,
516 op->name, attack_mess[ATM_BASIC][i].buf2); 545 op->name, attack_mess[ATM_BASIC][i].buf2);
517 sprintf(buf2, "%s", attack_mess[ATM_BASIC][i].buf3); 546 sprintf(buf2, "%s", attack_mess[ATM_BASIC][i].buf3);
547 found++;
518 break; 548 break;
519 } 549 }
550 }
551
552 if (!found) {
553 sprintf(buf1, "hit");
554 sprintf(buf2, "hits");
520 } 555 }
521 556
522 /* bail out if a monster is casting spells */ 557 /* bail out if a monster is casting spells */
523 if (!(hitter->type == PLAYER || 558 if (!(hitter->type == PLAYER ||
524 (get_owner(hitter) != NULL && hitter->owner->type == PLAYER))) 559 (get_owner(hitter) != NULL && hitter->owner->type == PLAYER)))
527 /* scale down magic considerably. */ 562 /* scale down magic considerably. */
528 if (type & AT_MAGIC && rndm(0, 5)) 563 if (type & AT_MAGIC && rndm(0, 5))
529 return; 564 return;
530 565
531 /* Did a player hurt another player? Inform both! */ 566 /* Did a player hurt another player? Inform both! */
532 /* only show half the player->player combat messages */
533 if(op->type==PLAYER && rndm(0, 1) && 567 if(op->type==PLAYER &&
534 (get_owner(hitter)==NULL?hitter->type:hitter->owner->type)==PLAYER) { 568 (get_owner(hitter)==NULL?hitter->type:hitter->owner->type)==PLAYER) {
535 if(get_owner(hitter)!=NULL) 569 if(get_owner(hitter)!=NULL)
536 sprintf(buf,"%s's %s %s you.", 570 sprintf(buf,"%s's %s %s you.",
537 hitter->owner->name, hitter->name, buf2); 571 hitter->owner->name, hitter->name, buf2);
538 else { 572 else {
547 } 581 }
548 } 582 }
549 new_draw_info(NDI_BLACK, 0,op,buf); 583 new_draw_info(NDI_BLACK, 0,op,buf);
550 } /* end of player hitting player */ 584 } /* end of player hitting player */
551 585
552 /* scale down these messages too */
553 if(hitter->type==PLAYER && rndm(0, 2) == 0) { 586 if(hitter->type==PLAYER) {
554 sprintf(buf,"You %s.",buf1); 587 sprintf(buf,"You %s.",buf1);
555 if (dam != 0) { 588 if (dam != 0) {
556 if (dam < 10) 589 if (dam < 10)
557 play_sound_player_only(hitter->contr, SOUND_PLAYER_HITS1,0,0); 590 play_sound_player_only(hitter->contr, SOUND_PLAYER_HITS1,0,0);
558 else if (dam < 20) 591 else if (dam < 20)
838 * isn't available anymore. 871 * isn't available anymore.
839 */ 872 */
840object *hit_with_arrow (object *op, object *victim) 873object *hit_with_arrow (object *op, object *victim)
841{ 874{
842 object *container, *hitter; 875 object *container, *hitter;
843 int hit_something; 876 int hit_something = 0;
844 tag_t victim_tag, hitter_tag; 877 tag_t victim_tag, hitter_tag;
845 sint16 victim_x, victim_y; 878 sint16 victim_x, victim_y;
846 879
847 /* Disassemble missile */ 880 /* Disassemble missile */
848 if (op->inv) { 881 if (op->inv) {
1154 * not much is drained, low rate means a lot is drained. 1187 * not much is drained, low rate means a lot is drained.
1155 */ 1188 */
1156 int rate; 1189 int rate;
1157 1190
1158 if(op->resist[ATNR_DRAIN] >= 0) 1191 if(op->resist[ATNR_DRAIN] >= 0)
1159 rate = 50 + op->resist[ATNR_DRAIN] / 2; 1192 rate = 400 + op->resist[ATNR_DRAIN] * 3;
1160 else if(op->resist[ATNR_DRAIN] < 0) 1193 else
1161 rate = 5000 / (100 - op->resist[ATNR_DRAIN]); 1194 rate = 400 * 100 / (100 - op->resist[ATNR_DRAIN]);
1162 1195
1163 /* full protection has no effect. Nothing else in this
1164 * function needs to get done, so just return. */
1165 if(!rate)
1166 return 0;
1167
1168 if(op->stats.exp <= rate) { 1196 if(op->stats.exp <= rate) {
1169 if(op->type == GOLEM) 1197 if(op->type == GOLEM)
1170 dam = 999; /* Its force is "sucked" away. 8) */ 1198 dam = 999; /* Its force is "sucked" away. 8) */
1171 else 1199 else
1172 /* If we can't drain, lets try to do physical damage */ 1200 /* If we can't drain, lets try to do physical damage */
1618 1646
1619 /* very simple: if our target has no_damage 1 set or is wiz, we can't hurt him */ 1647 /* very simple: if our target has no_damage 1 set or is wiz, we can't hurt him */
1620 if (QUERY_FLAG (op, FLAG_WIZ) || QUERY_FLAG (op, FLAG_NO_DAMAGE)) 1648 if (QUERY_FLAG (op, FLAG_WIZ) || QUERY_FLAG (op, FLAG_NO_DAMAGE))
1621 return 0; 1649 return 0;
1622 1650
1651#ifdef PROHIBIT_PLAYERKILL
1652 if (op->type == PLAYER) {
1653 object *owner = get_owner (hitter);
1654 if (!owner) owner = hitter;
1655 if (owner->type == PLAYER
1656 && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful))
1657 && op != owner) {
1658 return 0;
1659 }
1660 }
1661#endif
1662
1623 op_tag = op->count; 1663 op_tag = op->count;
1624 hitter_tag = hitter->count; 1664 hitter_tag = hitter->count;
1625 1665
1626 if (body_attack) { 1666 if (body_attack) {
1627 /* slow and paralyze must hit the head. But we don't want to just 1667 /* slow and paralyze must hit the head. But we don't want to just
1731 * doing damage - otherwise, the +1 in the coe below will make 1771 * doing damage - otherwise, the +1 in the coe below will make
1732 * an attack do damage before when it otherwise didn't 1772 * an attack do damage before when it otherwise didn't
1733 */ 1773 */
1734 friendlyfire = friendly_fire(op, hitter); 1774 friendlyfire = friendly_fire(op, hitter);
1735 if (friendlyfire && maxdam){ 1775 if (friendlyfire && maxdam){
1736 maxdam = ((dam * settings.set_friendly_fire) / 100)+0; 1776 maxdam = ((dam * settings.set_friendly_fire) / 100);
1737 1777#ifndef COZY_SERVER
1778 maxdam++;
1779#endif
1780
1738#ifdef ATTACK_DEBUG 1781#ifdef ATTACK_DEBUG
1739 LOG(llevDebug,"Friendly fire (type:%d setting: %d%) did %d damage dropped to %d\n", 1782 LOG(llevDebug,"Friendly fire (type:%d setting: %d%) did %d damage dropped to %d\n",
1740 friendlyfire, settings.set_friendly_fire, dam, maxdam); 1783 friendlyfire, settings.set_friendly_fire, dam, maxdam);
1741#endif 1784#endif
1742 } 1785 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines