1 | /* |
1 | /* |
2 | * static char *rcsid_attack_c = |
2 | * static char *rcsid_attack_c = |
3 | * "$Id: attack.c,v 1.1 2006/02/03 07:14:27 root Exp $"; |
3 | * "$Id: attack.c,v 1.15 2006/06/14 07:33:03 root 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, 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 | strcpy (buf2, attack_mess[ATM_BASIC][i].buf3); |
|
|
547 | found++; |
518 | break; |
548 | break; |
519 | } |
549 | } |
|
|
550 | } |
|
|
551 | |
|
|
552 | if (!found) { |
|
|
553 | strcpy (buf1, "hit"); |
|
|
554 | strcpy (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 { |
539 | sprintf(buf,"%s%s you.",hitter->name, buf2); |
573 | sprintf(buf,"%s%s you.",hitter->name, buf2); |
540 | if (dam != 0) { |
574 | if (dam != 0) { |
541 | if (dam < 10) |
575 | if (dam < 10) |
… | |
… | |
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 | */ |
840 | object *hit_with_arrow (object *op, object *victim) |
873 | object *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 */ |
… | |
… | |
1343 | if (get_owner (op) != NULL && op->owner->type == PLAYER && |
1371 | if (get_owner (op) != NULL && op->owner->type == PLAYER && |
1344 | op->owner->contr->ranges[range_golem] == op) { |
1372 | op->owner->contr->ranges[range_golem] == op) { |
1345 | op->owner->contr->ranges[range_golem]=NULL; |
1373 | op->owner->contr->ranges[range_golem]=NULL; |
1346 | op->owner->contr->golem_count=0; |
1374 | op->owner->contr->golem_count=0; |
1347 | } |
1375 | } |
1348 | else |
|
|
1349 | LOG (llevError, "BUG: hit_player(): Encountered golem without owner.\n"); |
|
|
1350 | |
1376 | |
1351 | remove_ob(op); |
1377 | remove_ob(op); |
1352 | free_object(op); |
1378 | free_object(op); |
1353 | return maxdam; |
1379 | return maxdam; |
1354 | } |
1380 | } |
… | |
… | |
1469 | |
1495 | |
1470 | /* If you didn't kill yourself, and your not the wizard */ |
1496 | /* If you didn't kill yourself, and your not the wizard */ |
1471 | if(owner!=op && !QUERY_FLAG(op, FLAG_WAS_WIZ)) { |
1497 | if(owner!=op && !QUERY_FLAG(op, FLAG_WAS_WIZ)) { |
1472 | int exp; |
1498 | int exp; |
1473 | |
1499 | |
1474 | exp = calc_skill_exp(owner,op, skop); |
|
|
1475 | |
|
|
1476 | /* Really don't give much experience for killing other players */ |
1500 | /* Really don't give much experience for killing other players */ |
|
|
1501 | // schmorp: temporary? reduce the amount of exp gained for pking enourmously |
1477 | if (op->type==PLAYER) { |
1502 | if (op->type==PLAYER) { |
1478 | if (battleg) { |
1503 | if (battleg) { |
1479 | new_draw_info(NDI_UNIQUE, 0,owner, "Your foe has fallen!"); |
1504 | new_draw_info(NDI_UNIQUE, 0,owner, "Your foe has fallen!"); |
1480 | new_draw_info(NDI_UNIQUE, 0,owner, "VICTORY!!!"); |
1505 | new_draw_info(NDI_UNIQUE, 0,owner, "VICTORY!!!"); |
1481 | } |
1506 | } |
1482 | else |
1507 | else |
1483 | exp = MIN(5000000, MAX(0, exp/10)); |
1508 | exp = op->stats.exp / 1000; |
1484 | } |
1509 | } |
1485 | |
1510 | else |
1486 | /* Don't know why this is set this way - doesn't make |
1511 | exp = calc_skill_exp(owner, op, skop); |
1487 | * sense to just divide everything by two for no reason. |
|
|
1488 | */ |
|
|
1489 | |
|
|
1490 | if (!settings.simple_exp) |
|
|
1491 | exp=exp/2; |
|
|
1492 | |
1512 | |
1493 | /* if op is standing on "battleground" (arena), no way to gain |
1513 | /* if op is standing on "battleground" (arena), no way to gain |
1494 | * exp by killing him |
1514 | * exp by killing him |
1495 | */ |
1515 | */ |
1496 | if (battleg) exp = 0; |
1516 | if (battleg) exp = 0; |
|
|
1517 | |
|
|
1518 | /* Don't know why this is set this way - doesn't make |
|
|
1519 | * sense to just divide everything by two for no reason. |
|
|
1520 | */ |
|
|
1521 | |
|
|
1522 | if (!settings.simple_exp) |
|
|
1523 | exp=exp/2; |
1497 | |
1524 | |
1498 | if(owner->type!=PLAYER || owner->contr->party==NULL) { |
1525 | if(owner->type!=PLAYER || owner->contr->party==NULL) { |
1499 | change_exp(owner,exp, skill, 0); |
1526 | change_exp(owner,exp, skill, 0); |
1500 | } |
1527 | } |
1501 | else { |
1528 | else { |
… | |
… | |
1574 | if (hitter->head) hitter=hitter->head; |
1601 | if (hitter->head) hitter=hitter->head; |
1575 | |
1602 | |
1576 | friendlyfire = 0; |
1603 | friendlyfire = 0; |
1577 | |
1604 | |
1578 | if(op->type == PLAYER) { |
1605 | if(op->type == PLAYER) { |
|
|
1606 | if (op_on_battleground (hitter, 0, 0)) |
|
|
1607 | return 0; |
1579 | |
1608 | |
1580 | if(hitter->type == PLAYER && hitter->contr->peaceful == 1) |
1609 | if(hitter->type == PLAYER && hitter->contr->peaceful == 1) |
1581 | return 1; |
1610 | return 1; |
1582 | |
1611 | |
1583 | if((owner = get_owner(hitter))!=NULL) { |
1612 | if((owner = get_owner(hitter))!=NULL) { |
… | |
… | |
1617 | return 0; |
1646 | return 0; |
1618 | |
1647 | |
1619 | /* very simple: if our target has no_damage 1 set or is wiz, we can't hurt him */ |
1648 | /* 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)) |
1649 | if (QUERY_FLAG (op, FLAG_WIZ) || QUERY_FLAG (op, FLAG_NO_DAMAGE)) |
1621 | return 0; |
1650 | return 0; |
|
|
1651 | |
|
|
1652 | #ifdef PROHIBIT_PLAYERKILL |
|
|
1653 | if (op->type == PLAYER) { |
|
|
1654 | object *owner = get_owner (hitter); |
|
|
1655 | if (!owner) owner = hitter; |
|
|
1656 | if (owner->type == PLAYER |
|
|
1657 | && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) |
|
|
1658 | && op != owner) { |
|
|
1659 | return 0; |
|
|
1660 | } |
|
|
1661 | } |
|
|
1662 | #endif |
1622 | |
1663 | |
1623 | op_tag = op->count; |
1664 | op_tag = op->count; |
1624 | hitter_tag = hitter->count; |
1665 | hitter_tag = hitter->count; |
1625 | |
1666 | |
1626 | if (body_attack) { |
1667 | if (body_attack) { |
… | |
… | |
1726 | } |
1767 | } |
1727 | } |
1768 | } |
1728 | |
1769 | |
1729 | /* if this is friendly fire then do a set % of damage only |
1770 | /* if this is friendly fire then do a set % of damage only |
1730 | * Note - put a check in to make sure this attack is actually |
1771 | * Note - put a check in to make sure this attack is actually |
1731 | * doing damage - otherwise, the +1 in the coe below will make |
1772 | * doing damage - otherwise, the +1 in the code below will make |
1732 | * an attack do damage before when it otherwise didn't |
1773 | * an attack do damage before when it otherwise didn't |
1733 | */ |
1774 | */ |
1734 | friendlyfire = friendly_fire(op, hitter); |
1775 | friendlyfire = friendly_fire(op, hitter); |
1735 | if (friendlyfire && maxdam){ |
1776 | if (friendlyfire && maxdam){ |
1736 | maxdam = ((dam * settings.set_friendly_fire) / 100)+1; |
1777 | maxdam = ((dam * settings.set_friendly_fire) / 100); |
1737 | |
1778 | #ifndef COZY_SERVER |
|
|
1779 | maxdam++; |
|
|
1780 | #endif |
|
|
1781 | |
1738 | #ifdef ATTACK_DEBUG |
1782 | #ifdef ATTACK_DEBUG |
1739 | LOG(llevDebug,"Friendly fire (type:%d setting: %d%) did %d damage dropped to %d\n", |
1783 | LOG(llevDebug,"Friendly fire (type:%d setting: %d%) did %d damage dropped to %d\n", |
1740 | friendlyfire, settings.set_friendly_fire, dam, maxdam); |
1784 | friendlyfire, settings.set_friendly_fire, dam, maxdam); |
1741 | #endif |
1785 | #endif |
1742 | } |
1786 | } |