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.19 by root, Sat Sep 16 22:24:13 2006 UTC vs.
Revision 1.24 by root, Sat Dec 9 16:11:09 2006 UTC

929object * 929object *
930hit_with_arrow (object *op, object *victim) 930hit_with_arrow (object *op, object *victim)
931{ 931{
932 object *container, *hitter; 932 object *container, *hitter;
933 int hit_something = 0; 933 int hit_something = 0;
934 sint16 victim_x, victim_y;
935 934
936 /* Disassemble missile */ 935 /* Disassemble missile */
937 if (op->inv) 936 if (op->inv)
938 { 937 {
939 container = op; 938 container = op;
945 * removed at the end of this function must be able to deal with empty 944 * removed at the end of this function must be able to deal with empty
946 * THROWN_OBJs. */ 945 * THROWN_OBJs. */
947 } 946 }
948 else 947 else
949 { 948 {
950 container = NULL; 949 container = 0;
951 hitter = op; 950 hitter = op;
952 } 951 }
953 952
954 /* Try to hit victim */ 953 /* Try to hit victim */
955 victim_x = victim->x;
956 victim_y = victim->y;
957
958 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc); 954 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
959 955
960 /* Arrow attacks door, rune of summoning is triggered, demon is put on 956 /* Arrow attacks door, rune of summoning is triggered, demon is put on
961 * arrow, move_apply() calls this function, arrow sticks in demon, 957 * arrow, move_apply() calls this function, arrow sticks in demon,
962 * attack_ob_simple() returns, and we've got an arrow that still exists 958 * attack_ob_simple() returns, and we've got an arrow that still exists
968 if (container) 964 if (container)
969 { 965 {
970 remove_ob (container); 966 remove_ob (container);
971 free_object (container); 967 free_object (container);
972 } 968 }
969
973 return NULL; 970 return 0;
974 } 971 }
975 972
976 /* Missile hit victim */ 973 /* Missile hit victim */
977 /* if the speed is > 10, then this is a fast moving arrow, we go straight 974 /* if the speed is > 10, then this is a fast moving arrow, we go straight
978 * through the target 975 * through the target
979 */ 976 */
980 if (hit_something && op->speed <= 10.0) 977 if (hit_something && op->speed <= 10.0)
981 { 978 {
982 /* Stop arrow */ 979 /* Stop arrow */
983 if (container == NULL) 980 if (!container)
984 { 981 {
985 hitter = fix_stopped_arrow (hitter); 982 hitter = fix_stopped_arrow (hitter);
986 if (hitter == NULL) 983 if (!hitter)
987 return NULL; 984 return 0;
988 } 985 }
989 else 986 else
990 { 987 {
991 remove_ob (container); 988 remove_ob (container);
992 free_object (container); 989 free_object (container);
993 } 990 }
994 991
995 /* Try to stick arrow into victim */ 992 /* Try to stick arrow into victim */
996 if (!victim->destroyed () && stick_arrow (hitter, victim)) 993 if (!victim->destroyed () && stick_arrow (hitter, victim))
997 return NULL; 994 return 0;
998 995
999 /* Else try to put arrow on victim's map square 996 /* Else try to put arrow on victim's map square
1000 * remove check for P_WALL here. If the arrow got to this 997 * remove check for P_WALL here. If the arrow got to this
1001 * space, that is good enough - with the new movement code, 998 * space, that is good enough - with the new movement code,
1002 * there is now the potential for lots of spaces where something 999 * there is now the potential for lots of spaces where something
1003 * can fly over but not otherwise move over. What is the correct 1000 * can fly over but not otherwise move over. What is the correct
1004 * way to handle those otherwise? 1001 * way to handle those otherwise?
1005 */ 1002 */
1006 if (victim_x != hitter->x || victim_y != hitter->y) 1003 if (victim->x != hitter->x || victim->y != hitter->y)
1007 { 1004 {
1008 remove_ob (hitter); 1005 remove_ob (hitter);
1009 hitter->x = victim_x; 1006 hitter->x = victim->x;
1010 hitter->y = victim_y; 1007 hitter->y = victim->y;
1011 insert_ob_in_map (hitter, victim->map, hitter, 0); 1008 insert_ob_in_map (hitter, victim->map, hitter, 0);
1012 } 1009 }
1013 else 1010 else
1014 {
1015 /* Else leave arrow where it is */ 1011 /* Else leave arrow where it is */
1016 merge_ob (hitter, NULL); 1012 merge_ob (hitter, NULL);
1017 } 1013
1018 return NULL; 1014 return 0;
1019 } 1015 }
1020 1016
1021 if (hit_something && op->speed >= 10.0) 1017 if (hit_something && op->speed >= 10.0)
1022 op->speed -= 1.0; 1018 op->speed -= 1.0;
1023 1019
1025 if (container) 1021 if (container)
1026 { 1022 {
1027 remove_ob (hitter); 1023 remove_ob (hitter);
1028 insert_ob_in_ob (hitter, container); 1024 insert_ob_in_ob (hitter, container);
1029 } 1025 }
1026
1030 return op; 1027 return op;
1031} 1028}
1032 1029
1033 1030
1034void 1031void
1449 op->speed = 0.1; 1446 op->speed = 0.1;
1450 update_ob_speed (op); 1447 update_ob_speed (op);
1451 op->speed_left = -0.05; 1448 op->speed_left = -0.05;
1452 return maxdam; 1449 return maxdam;
1453 } 1450 }
1451
1454 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1452 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1455 { 1453 {
1456 remove_friendly_object (op); 1454 remove_friendly_object (op);
1455
1457 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1456 if (get_owner (op) && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1458 {
1459 op->owner->contr->ranges[range_golem] = NULL; 1457 op->owner->contr->ranges[range_golem] = 0;
1460 op->owner->contr->golem_count = 0;
1461 }
1462 1458
1463 remove_ob (op); 1459 remove_ob (op);
1464 free_object (op); 1460 free_object (op);
1465 return maxdam; 1461 return maxdam;
1466 } 1462 }
1467 1463
1468 /* Now lets start dealing with experience we get for killing something */ 1464 /* Now lets start dealing with experience we get for killing something */
1469 1465
1470 owner = get_owner (hitter); 1466 owner = get_owner (hitter);
1471 if (owner == NULL) 1467 if (!owner)
1472 owner = hitter; 1468 owner = hitter;
1473 1469
1474 /* is the victim (op) standing on battleground? */ 1470 /* is the victim (op) standing on battleground? */
1475 if (op_on_battleground (op, NULL, NULL)) 1471 if (op_on_battleground (op, NULL, NULL))
1476 battleg = 1; 1472 battleg = 1;
1506 * probably don't want to see that. 1502 * probably don't want to see that.
1507 */ 1503 */
1508 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1504 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1509 { 1505 {
1510 if (owner != hitter) 1506 if (owner != hitter)
1511 {
1512 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1507 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1513 }
1514 else 1508 else
1515 {
1516 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1509 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1517 } 1510
1518 /* Only play sounds for melee kills */ 1511 /* Only play sounds for melee kills */
1519 if (hitter->type == PLAYER) 1512 if (hitter->type == PLAYER)
1520 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1513 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1521 } 1514 }
1522 1515
1533 1526
1534 /* This code below deals with finding the appropriate skill 1527 /* This code below deals with finding the appropriate skill
1535 * to credit exp to. This is a bit problematic - we should 1528 * to credit exp to. This is a bit problematic - we should
1536 * probably never really have to look at current_weapon->skill 1529 * probably never really have to look at current_weapon->skill
1537 */ 1530 */
1538 skill = NULL; 1531 skill = 0;
1532
1539 if (hitter->skill && hitter->type != PLAYER) 1533 if (hitter->skill && hitter->type != PLAYER)
1540 skill = hitter->skill; 1534 skill = hitter->skill;
1541 else if (owner->chosen_skill) 1535 else if (owner->chosen_skill)
1542 { 1536 {
1543 skill = owner->chosen_skill->skill; 1537 skill = owner->chosen_skill->skill;
1562 break; 1556 break;
1563 } 1557 }
1564 } 1558 }
1565 } /* Was it a player that hit somethign */ 1559 } /* Was it a player that hit somethign */
1566 else 1560 else
1567 {
1568 skill = NULL; 1561 skill = 0;
1569 }
1570 1562
1571 /* Pet (or spell) killed something. */ 1563 /* Pet (or spell) killed something. */
1572 if (owner != hitter) 1564 if (owner != hitter)
1573 {
1574 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1565 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1575 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1566 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1576 }
1577 else 1567 else
1578 {
1579 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1568 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1580 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1569 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1581 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1570 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1582 } 1571
1583 /* These may have been set in the player code section above */ 1572 /* These may have been set in the player code section above */
1584 if (!skop) 1573 if (!skop)
1585 skop = hitter->chosen_skill; 1574 skop = hitter->chosen_skill;
1575
1586 if (!skill && skop) 1576 if (!skill && skop)
1587 skill = skop->skill; 1577 skill = skop->skill;
1588 1578
1589 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1579 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1590 1580
1591
1592 /* If you didn't kill yourself, and your not the wizard */ 1581 /* If you didn't kill yourself, and your not the wizard */
1593 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1582 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1594 { 1583 {
1595 int exp; 1584 int exp;
1596 1585
1597 /* Really don't give much experience for killing other players */ 1586 /* Really don't give much experience for killing other players */
1598 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1587 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1599 if (op->type == PLAYER) 1588 if (op->type == PLAYER)
1600 { 1589 {
1601 if (battleg) 1590 if (battleg)
1602 { 1591 {
1603 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1592 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1621 1610
1622 if (!settings.simple_exp) 1611 if (!settings.simple_exp)
1623 exp = exp / 2; 1612 exp = exp / 2;
1624 1613
1625 if (owner->type != PLAYER || owner->contr->party == NULL) 1614 if (owner->type != PLAYER || owner->contr->party == NULL)
1626 {
1627 change_exp (owner, exp, skill, 0); 1615 change_exp (owner, exp, skill, 0);
1628 }
1629 else 1616 else
1630 { 1617 {
1631 int shares = 0, count = 0; 1618 int shares = 0, count = 0;
1632
1633 player *pl; 1619 player *pl;
1634
1635 partylist *party = owner->contr->party; 1620 partylist *party = owner->contr->party;
1636 1621
1637#ifdef PARTY_KILL_LOG 1622#ifdef PARTY_KILL_LOG
1638 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1623 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1639#endif 1624#endif
1640 for (pl = first_player; pl != NULL; pl = pl->next) 1625 for (pl = first_player; pl != NULL; pl = pl->next)
1641 {
1642 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1626 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1643 { 1627 {
1644 count++; 1628 count++;
1645 shares += (pl->ob->level + 4); 1629 shares += (pl->ob->level + 4);
1646 } 1630 }
1647 } 1631
1648 if (count == 1 || shares > exp) 1632 if (count == 1 || shares > exp || !shares)
1649 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1633 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1650 else 1634 else
1651 { 1635 {
1652 int share = exp / shares, given = 0, nexp; 1636 int share = exp / shares, given = 0, nexp;
1653 1637
1654 for (pl = first_player; pl != NULL; pl = pl->next) 1638 for (pl = first_player; pl != NULL; pl = pl->next)
1655 {
1656 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1639 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1657 { 1640 {
1658 nexp = (pl->ob->level + 4) * share; 1641 nexp = (pl->ob->level + 4) * share;
1659 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1642 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1660 given += nexp; 1643 given += nexp;
1661 } 1644 }
1662 } 1645
1663 exp -= given; 1646 exp -= given;
1664 /* give any remainder to the player */ 1647 /* give any remainder to the player */
1665 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1648 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1666 } 1649 }
1667 } /* else part of a party */ 1650 } /* else part of a party */
1668
1669 } /* end if person didn't kill himself */ 1651 } /* end if person didn't kill himself */
1670 1652
1671 if (op->type != PLAYER) 1653 if (op->type != PLAYER)
1672 { 1654 {
1673 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1655 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1674 { 1656 {
1675 object *owner1 = get_owner (op); 1657 object *owner1 = get_owner (op);
1676 1658
1677 if (owner1 != NULL && owner1->type == PLAYER) 1659 if (owner1 && owner1->type == PLAYER)
1678 { 1660 {
1679 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1661 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1680 /* Maybe we should include the owner that killed this, maybe not */ 1662 /* Maybe we should include the owner that killed this, maybe not */
1681 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name); 1663 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1682 } 1664 }
1685 } 1667 }
1686 1668
1687 remove_ob (op); 1669 remove_ob (op);
1688 free_object (op); 1670 free_object (op);
1689 } 1671 }
1690 /* Player has been killed! */
1691 else 1672 else
1692 { 1673 {
1674 /* Player has been killed! */
1693 if (owner->type == PLAYER) 1675 if (owner->type == PLAYER)
1694 {
1695 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1676 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1696 }
1697 else 1677 else
1698 assign (op->contr->killer, hitter->name); 1678 assign (op->contr->killer, hitter->name);
1699 } 1679 }
1700 1680
1701 /* This was return -1 - that doesn't seem correct - if we return -1, process 1681 /* This was return -1 - that doesn't seem correct - if we return -1, process

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines