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.15 by root, Thu Sep 14 20:46:10 2006 UTC vs.
Revision 1.22 by root, Fri Sep 29 11:53:09 2006 UTC

1
2/*
3 * static char *rcsid_attack_c =
4 * "$Id: attack.C,v 1.15 2006/09/14 20:46:10 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29#include <assert.h> 23#include <assert.h>
30#include <global.h> 24#include <global.h>
31#include <living.h> 25#include <living.h>
32#include <material.h> 26#include <material.h>
158{ 152{
159 if (!did_make_save_item (op, type, originator)) 153 if (!did_make_save_item (op, type, originator))
160 { 154 {
161 object *env = op->env; 155 object *env = op->env;
162 int x = op->x, y = op->y; 156 int x = op->x, y = op->y;
163 mapstruct *m = op->map; 157 maptile *m = op->map;
164 158
165 op = stop_item (op); 159 op = stop_item (op);
166 if (op == NULL) 160 if (op == NULL)
167 return; 161 return;
168 162
247 241
248 /* The value of 50 is arbitrary. */ 242 /* The value of 50 is arbitrary. */
249 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2)) 243 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2))
250 { 244 {
251 object *tmp; 245 object *tmp;
252 archetype *at = find_archetype ("icecube"); 246 archetype *at = archetype::find ("icecube");
253 247
254 if (at == NULL) 248 if (at == NULL)
255 return; 249 return;
256 250
257 op = stop_item (op); 251 op = stop_item (op);
288 282
289int 283int
290hit_map (object *op, int dir, int type, int full_hit) 284hit_map (object *op, int dir, int type, int full_hit)
291{ 285{
292 object *tmp, *next; 286 object *tmp, *next;
293 mapstruct *map; 287 maptile *map;
294 sint16 x, y; 288 sint16 x, y;
295 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 289 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
296 290
297 tag_t op_tag, next_tag = 0;
298
299 if (QUERY_FLAG (op, FLAG_FREED)) 291 if (QUERY_FLAG (op, FLAG_FREED))
300 { 292 {
301 LOG (llevError, "BUG: hit_map(): free object\n"); 293 LOG (llevError, "BUG: hit_map(): free object\n");
302 return 0; 294 return 0;
303 } 295 }
314 return 0; 306 return 0;
315 } 307 }
316 308
317 if (op->head) 309 if (op->head)
318 op = op->head; 310 op = op->head;
319
320 op_tag = op->count;
321 311
322 map = op->map; 312 map = op->map;
323 x = op->x + freearr_x[dir]; 313 x = op->x + freearr_x[dir];
324 y = op->y + freearr_y[dir]; 314 y = op->y + freearr_y[dir];
325 315
353 update_object (op, UP_OBJ_FACE); 343 update_object (op, UP_OBJ_FACE);
354 type &= ~AT_CHAOS; 344 type &= ~AT_CHAOS;
355 } 345 }
356 346
357 next = get_map_ob (map, x, y); 347 next = get_map_ob (map, x, y);
358 if (next)
359 next_tag = next->count;
360 348
361 while (next) 349 while (next)
362 { 350 {
363 if (was_destroyed (next, next_tag)) 351 if (next->destroyed ())
364 { 352 {
365 /* There may still be objects that were above 'next', but there is no 353 /* There may still be objects that were above 'next', but there is no
366 * simple way to find out short of copying all object references and 354 * simple way to find out short of copying all object references and
367 * tags into a temporary array before we start processing the first 355 * tags into a temporary array before we start processing the first
368 * object. That's why we just abort. 356 * object. That's why we just abort.
376 } 364 }
377 365
378 tmp = next; 366 tmp = next;
379 next = tmp->above; 367 next = tmp->above;
380 368
381 if (next) 369 if (tmp->destroyed ())
382 next_tag = next->count;
383
384 if (QUERY_FLAG (tmp, FLAG_FREED))
385 { 370 {
386 LOG (llevError, "BUG: hit_map(): found freed object\n"); 371 LOG (llevError, "BUG: hit_map(): found freed object\n");
387 break; 372 break;
388 } 373 }
389 374
396 381
397 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 382 if (QUERY_FLAG (tmp, FLAG_ALIVE))
398 { 383 {
399 hit_player (tmp, op->stats.dam, op, type, full_hit); 384 hit_player (tmp, op->stats.dam, op, type, full_hit);
400 retflag |= 1; 385 retflag |= 1;
401 if (was_destroyed (op, op_tag)) 386 if (op->destroyed ())
402 break; 387 break;
403 } 388 }
404 389
405 /* Here we are potentially destroying an object. If the object has 390 /* Here we are potentially destroying an object. If the object has
406 * NO_PASS set, it is also immune - you can't destroy walls. Note 391 * NO_PASS set, it is also immune - you can't destroy walls. Note
410 * destroyed right now. 395 * destroyed right now.
411 */ 396 */
412 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 397 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
413 { 398 {
414 save_throw_object (tmp, type, op); 399 save_throw_object (tmp, type, op);
415 if (was_destroyed (op, op_tag)) 400 if (op->destroyed ())
416 break; 401 break;
417 } 402 }
418 } 403 }
419 404
420 return 0; 405 return 0;
423void 408void
424attack_message (int dam, int type, object *op, object *hitter) 409attack_message (int dam, int type, object *op, object *hitter)
425{ 410{
426 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 411 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
427 int i, found = 0; 412 int i, found = 0;
428 mapstruct *map; 413 maptile *map;
429 object *next, *tmp; 414 object *next, *tmp;
430 415
431 /* put in a few special messages for some of the common attacktypes 416 /* put in a few special messages for some of the common attacktypes
432 * a player might have. For example, fire, electric, cold, etc 417 * a player might have. For example, fire, electric, cold, etc
433 * [garbled 20010919] 418 * [garbled 20010919]
760attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 745attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
761{ 746{
762 int simple_attack, roll, dam = 0; 747 int simple_attack, roll, dam = 0;
763 uint32 type; 748 uint32 type;
764 shstr op_name; 749 shstr op_name;
765 tag_t op_tag, hitter_tag;
766 750
767 if (get_attack_mode (&op, &hitter, &simple_attack)) 751 if (get_attack_mode (&op, &hitter, &simple_attack))
768 goto error; 752 goto error;
769 753
770 if (hitter->current_weapon) 754 if (hitter->current_weapon)
771 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 755 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
772 return RESULT_INT (0); 756 return RESULT_INT (0);
773 757
774 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 758 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
775 return RESULT_INT (0); 759 return RESULT_INT (0);
776
777 op_tag = op->count;
778 hitter_tag = hitter->count;
779 760
780 /* 761 /*
781 * A little check to make it more difficult to dance forward and back 762 * A little check to make it more difficult to dance forward and back
782 * to avoid ever being hit by monsters. 763 * to avoid ever being hit by monsters.
783 */ 764 */
788 * which then gets here again. By decreasing the speed before 769 * which then gets here again. By decreasing the speed before
789 * we call process_object, the 'if' statement above will fail. 770 * we call process_object, the 'if' statement above will fail.
790 */ 771 */
791 op->speed_left--; 772 op->speed_left--;
792 process_object (op); 773 process_object (op);
793 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 774 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
794 goto error; 775 goto error;
795 } 776 }
796 777
797 op_name = op->name; 778 op_name = op->name;
798 779
849 * when they hit the victim. For things like thrown daggers, 830 * when they hit the victim. For things like thrown daggers,
850 * this sets 'hitter' to the actual dagger, and not the 831 * this sets 'hitter' to the actual dagger, and not the
851 * wrapper object. 832 * wrapper object.
852 */ 833 */
853 thrown_item_effect (hitter, op); 834 thrown_item_effect (hitter, op);
854 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 835 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
855 goto leave; 836 goto leave;
856 } 837 }
857 838
858 /* Need to do at least 1 damage, otherwise there is no point 839 /* Need to do at least 1 damage, otherwise there is no point
859 * to go further and it will cause FPE's below. 840 * to go further and it will cause FPE's below.
860 */ 841 */
861 if (hitdam <= 0) 842 if (hitdam <= 0)
862 hitdam = 1; 843 hitdam = 1;
863 844
864 type = hitter->attacktype; 845 type = hitter->attacktype;
846
865 if (!type) 847 if (!type)
866 type = AT_PHYSICAL; 848 type = AT_PHYSICAL;
849
867 /* Handle monsters that hit back */ 850 /* Handle monsters that hit back */
868 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 851 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
869 { 852 {
870 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 853 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
871 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 854 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
855
872 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 856 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
857
873 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 858 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
874 goto leave; 859 goto leave;
875 } 860 }
876 861
877 /* In the new attack code, it should handle multiple attack 862 /* In the new attack code, it should handle multiple attack
878 * types in its area, so remove it from here. 863 * types in its area, so remove it from here.
879 */ 864 */
880 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 865 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
866
881 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 867 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
882 goto leave; 868 goto leave;
883 } /* end of if hitter hit op */ 869 } /* end of if hitter hit op */
884 /* if we missed, dam=0 */ 870 /* if we missed, dam=0 */
885 871
886 /*attack_message(dam, type, op, hitter); */ 872 /*attack_message(dam, type, op, hitter); */
943object * 929object *
944hit_with_arrow (object *op, object *victim) 930hit_with_arrow (object *op, object *victim)
945{ 931{
946 object *container, *hitter; 932 object *container, *hitter;
947 int hit_something = 0; 933 int hit_something = 0;
948 tag_t victim_tag, hitter_tag;
949 sint16 victim_x, victim_y;
950 934
951 /* Disassemble missile */ 935 /* Disassemble missile */
952 if (op->inv) 936 if (op->inv)
953 { 937 {
954 container = op; 938 container = op;
960 * 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
961 * THROWN_OBJs. */ 945 * THROWN_OBJs. */
962 } 946 }
963 else 947 else
964 { 948 {
965 container = NULL; 949 container = 0;
966 hitter = op; 950 hitter = op;
967 } 951 }
968 952
969 /* Try to hit victim */ 953 /* Try to hit victim */
970 victim_x = victim->x;
971 victim_y = victim->y;
972 victim_tag = victim->count;
973 hitter_tag = hitter->count;
974
975 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);
976 955
977 /* 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
978 * arrow, move_apply() calls this function, arrow sticks in demon, 957 * arrow, move_apply() calls this function, arrow sticks in demon,
979 * 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
980 * but is no longer on the map. Ugh. (Beware: Such things can happen at 959 * but is no longer on the map. Ugh. (Beware: Such things can happen at
981 * other places as well!) 960 * other places as well!)
982 */ 961 */
983 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 962 if (hitter->destroyed () || hitter->env != NULL)
984 { 963 {
985 if (container) 964 if (container)
986 { 965 {
987 remove_ob (container); 966 remove_ob (container);
988 free_object (container); 967 free_object (container);
989 } 968 }
969
990 return NULL; 970 return 0;
991 } 971 }
992 972
993 /* Missile hit victim */ 973 /* Missile hit victim */
994 /* 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
995 * through the target 975 * through the target
996 */ 976 */
997 if (hit_something && op->speed <= 10.0) 977 if (hit_something && op->speed <= 10.0)
998 { 978 {
999 /* Stop arrow */ 979 /* Stop arrow */
1000 if (container == NULL) 980 if (!container)
1001 { 981 {
1002 hitter = fix_stopped_arrow (hitter); 982 hitter = fix_stopped_arrow (hitter);
1003 if (hitter == NULL) 983 if (!hitter)
1004 return NULL; 984 return 0;
1005 } 985 }
1006 else 986 else
1007 { 987 {
1008 remove_ob (container); 988 remove_ob (container);
1009 free_object (container); 989 free_object (container);
1010 } 990 }
1011 991
1012 /* Try to stick arrow into victim */ 992 /* Try to stick arrow into victim */
1013 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 993 if (!victim->destroyed () && stick_arrow (hitter, victim))
1014 return NULL; 994 return 0;
1015 995
1016 /* Else try to put arrow on victim's map square 996 /* Else try to put arrow on victim's map square
1017 * 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
1018 * space, that is good enough - with the new movement code, 998 * space, that is good enough - with the new movement code,
1019 * there is now the potential for lots of spaces where something 999 * there is now the potential for lots of spaces where something
1020 * 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
1021 * way to handle those otherwise? 1001 * way to handle those otherwise?
1022 */ 1002 */
1023 if (victim_x != hitter->x || victim_y != hitter->y) 1003 if (victim->x != hitter->x || victim->y != hitter->y)
1024 { 1004 {
1025 remove_ob (hitter); 1005 remove_ob (hitter);
1026 hitter->x = victim_x; 1006 hitter->x = victim->x;
1027 hitter->y = victim_y; 1007 hitter->y = victim->y;
1028 insert_ob_in_map (hitter, victim->map, hitter, 0); 1008 insert_ob_in_map (hitter, victim->map, hitter, 0);
1029 } 1009 }
1030 else 1010 else
1031 {
1032 /* Else leave arrow where it is */ 1011 /* Else leave arrow where it is */
1033 merge_ob (hitter, NULL); 1012 merge_ob (hitter, NULL);
1034 } 1013
1035 return NULL; 1014 return 0;
1036 } 1015 }
1037 1016
1038 if (hit_something && op->speed >= 10.0) 1017 if (hit_something && op->speed >= 10.0)
1039 op->speed -= 1.0; 1018 op->speed -= 1.0;
1040 1019
1042 if (container) 1021 if (container)
1043 { 1022 {
1044 remove_ob (hitter); 1023 remove_ob (hitter);
1045 insert_ob_in_ob (hitter, container); 1024 insert_ob_in_ob (hitter, container);
1046 } 1025 }
1026
1047 return op; 1027 return op;
1048} 1028}
1049 1029
1050 1030
1051void 1031void
1466 op->speed = 0.1; 1446 op->speed = 0.1;
1467 update_ob_speed (op); 1447 update_ob_speed (op);
1468 op->speed_left = -0.05; 1448 op->speed_left = -0.05;
1469 return maxdam; 1449 return maxdam;
1470 } 1450 }
1451
1471 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1452 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1472 { 1453 {
1473 remove_friendly_object (op); 1454 remove_friendly_object (op);
1474 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1455 if (get_owner (op) && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1475 { 1456 {
1476 op->owner->contr->ranges[range_golem] = NULL; 1457 op->owner->contr->ranges[range_golem] = 0;
1477 op->owner->contr->golem_count = 0; 1458 op->owner->contr->golem_count = 0;
1478 } 1459 }
1479 1460
1480 remove_ob (op); 1461 remove_ob (op);
1481 free_object (op); 1462 free_object (op);
1483 } 1464 }
1484 1465
1485 /* Now lets start dealing with experience we get for killing something */ 1466 /* Now lets start dealing with experience we get for killing something */
1486 1467
1487 owner = get_owner (hitter); 1468 owner = get_owner (hitter);
1488 if (owner == NULL) 1469 if (!owner)
1489 owner = hitter; 1470 owner = hitter;
1490 1471
1491 /* is the victim (op) standing on battleground? */ 1472 /* is the victim (op) standing on battleground? */
1492 if (op_on_battleground (op, NULL, NULL)) 1473 if (op_on_battleground (op, NULL, NULL))
1493 battleg = 1; 1474 battleg = 1;
1523 * probably don't want to see that. 1504 * probably don't want to see that.
1524 */ 1505 */
1525 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1506 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1526 { 1507 {
1527 if (owner != hitter) 1508 if (owner != hitter)
1528 {
1529 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1509 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1530 }
1531 else 1510 else
1532 {
1533 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1511 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1534 } 1512
1535 /* Only play sounds for melee kills */ 1513 /* Only play sounds for melee kills */
1536 if (hitter->type == PLAYER) 1514 if (hitter->type == PLAYER)
1537 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1515 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1538 } 1516 }
1539 1517
1550 1528
1551 /* This code below deals with finding the appropriate skill 1529 /* This code below deals with finding the appropriate skill
1552 * to credit exp to. This is a bit problematic - we should 1530 * to credit exp to. This is a bit problematic - we should
1553 * probably never really have to look at current_weapon->skill 1531 * probably never really have to look at current_weapon->skill
1554 */ 1532 */
1555 skill = NULL; 1533 skill = 0;
1534
1556 if (hitter->skill && hitter->type != PLAYER) 1535 if (hitter->skill && hitter->type != PLAYER)
1557 skill = hitter->skill; 1536 skill = hitter->skill;
1558 else if (owner->chosen_skill) 1537 else if (owner->chosen_skill)
1559 { 1538 {
1560 skill = owner->chosen_skill->skill; 1539 skill = owner->chosen_skill->skill;
1579 break; 1558 break;
1580 } 1559 }
1581 } 1560 }
1582 } /* Was it a player that hit somethign */ 1561 } /* Was it a player that hit somethign */
1583 else 1562 else
1584 {
1585 skill = NULL; 1563 skill = 0;
1586 }
1587 1564
1588 /* Pet (or spell) killed something. */ 1565 /* Pet (or spell) killed something. */
1589 if (owner != hitter) 1566 if (owner != hitter)
1590 {
1591 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1567 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1592 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1568 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1593 }
1594 else 1569 else
1595 {
1596 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1570 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1597 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1571 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1598 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1572 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1599 } 1573
1600 /* These may have been set in the player code section above */ 1574 /* These may have been set in the player code section above */
1601 if (!skop) 1575 if (!skop)
1602 skop = hitter->chosen_skill; 1576 skop = hitter->chosen_skill;
1577
1603 if (!skill && skop) 1578 if (!skill && skop)
1604 skill = skop->skill; 1579 skill = skop->skill;
1605 1580
1606 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1581 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1607 1582
1608
1609 /* If you didn't kill yourself, and your not the wizard */ 1583 /* If you didn't kill yourself, and your not the wizard */
1610 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1584 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1611 { 1585 {
1612 int exp; 1586 int exp;
1613 1587
1614 /* Really don't give much experience for killing other players */ 1588 /* Really don't give much experience for killing other players */
1615 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1589 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1616 if (op->type == PLAYER) 1590 if (op->type == PLAYER)
1617 { 1591 {
1618 if (battleg) 1592 if (battleg)
1619 { 1593 {
1620 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1594 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1644 change_exp (owner, exp, skill, 0); 1618 change_exp (owner, exp, skill, 0);
1645 } 1619 }
1646 else 1620 else
1647 { 1621 {
1648 int shares = 0, count = 0; 1622 int shares = 0, count = 0;
1649
1650 player *pl; 1623 player *pl;
1651
1652 partylist *party = owner->contr->party; 1624 partylist *party = owner->contr->party;
1653 1625
1654#ifdef PARTY_KILL_LOG 1626#ifdef PARTY_KILL_LOG
1655 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1627 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1656#endif 1628#endif
1657 for (pl = first_player; pl != NULL; pl = pl->next) 1629 for (pl = first_player; pl != NULL; pl = pl->next)
1658 {
1659 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1630 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1660 { 1631 {
1661 count++; 1632 count++;
1662 shares += (pl->ob->level + 4); 1633 shares += (pl->ob->level + 4);
1663 } 1634 }
1664 } 1635
1665 if (count == 1 || shares > exp) 1636 if (count == 1 || shares > exp)
1666 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1637 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1667 else 1638 else
1668 { 1639 {
1669 int share = exp / shares, given = 0, nexp; 1640 int share = exp / shares, given = 0, nexp;
1670 1641
1671 for (pl = first_player; pl != NULL; pl = pl->next) 1642 for (pl = first_player; pl != NULL; pl = pl->next)
1672 {
1673 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1643 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1674 { 1644 {
1675 nexp = (pl->ob->level + 4) * share; 1645 nexp = (pl->ob->level + 4) * share;
1676 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1646 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1677 given += nexp; 1647 given += nexp;
1678 } 1648 }
1679 } 1649
1680 exp -= given; 1650 exp -= given;
1681 /* give any remainder to the player */ 1651 /* give any remainder to the player */
1682 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1652 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1683 } 1653 }
1684 } /* else part of a party */ 1654 } /* else part of a party */
1685
1686 } /* end if person didn't kill himself */ 1655 } /* end if person didn't kill himself */
1687 1656
1688 if (op->type != PLAYER) 1657 if (op->type != PLAYER)
1689 { 1658 {
1690 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1659 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1691 { 1660 {
1692 object *owner1 = get_owner (op); 1661 object *owner1 = get_owner (op);
1693 1662
1694 if (owner1 != NULL && owner1->type == PLAYER) 1663 if (owner1 && owner1->type == PLAYER)
1695 { 1664 {
1696 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1665 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1697 /* Maybe we should include the owner that killed this, maybe not */ 1666 /* Maybe we should include the owner that killed this, maybe not */
1698 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name); 1667 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1699 } 1668 }
1702 } 1671 }
1703 1672
1704 remove_ob (op); 1673 remove_ob (op);
1705 free_object (op); 1674 free_object (op);
1706 } 1675 }
1707 /* Player has been killed! */
1708 else 1676 else
1709 { 1677 {
1678 /* Player has been killed! */
1710 if (owner->type == PLAYER) 1679 if (owner->type == PLAYER)
1711 {
1712 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1680 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1713 }
1714 else 1681 else
1715 assign (op->contr->killer, hitter->name); 1682 assign (op->contr->killer, hitter->name);
1716 } 1683 }
1717 1684
1718 /* This was return -1 - that doesn't seem correct - if we return -1, process 1685 /* This was return -1 - that doesn't seem correct - if we return -1, process
1773{ 1740{
1774 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1741 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1775 int maxattacktype, attacknum; 1742 int maxattacktype, attacknum;
1776 int body_attack = op && op->head; /* Did we hit op's head? */ 1743 int body_attack = op && op->head; /* Did we hit op's head? */
1777 int simple_attack; 1744 int simple_attack;
1778 tag_t op_tag, hitter_tag;
1779 int rtn_kill = 0; 1745 int rtn_kill = 0;
1780 int friendlyfire; 1746 int friendlyfire;
1781 1747
1782 if (get_attack_mode (&op, &hitter, &simple_attack)) 1748 if (get_attack_mode (&op, &hitter, &simple_attack))
1783 return 0; 1749 return 0;
1791 { 1757 {
1792 object *owner = get_owner (hitter); 1758 object *owner = get_owner (hitter);
1793 1759
1794 if (!owner) 1760 if (!owner)
1795 owner = hitter; 1761 owner = hitter;
1762
1796 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1763 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1797 {
1798 return 0; 1764 return 0;
1799 }
1800 } 1765 }
1801#endif 1766#endif
1802
1803 op_tag = op->count;
1804 hitter_tag = hitter->count;
1805 1767
1806 if (body_attack) 1768 if (body_attack)
1807 { 1769 {
1808 /* slow and paralyze must hit the head. But we don't want to just 1770 /* slow and paralyze must hit the head. But we don't want to just
1809 * return - we still need to process other attacks the spell still 1771 * return - we still need to process other attacks the spell still
1815 * attack so we don't cancel out things like magic bullet. 1777 * attack so we don't cancel out things like magic bullet.
1816 */ 1778 */
1817 if (type & (AT_PARALYZE | AT_SLOW)) 1779 if (type & (AT_PARALYZE | AT_SLOW))
1818 { 1780 {
1819 type &= ~(AT_PARALYZE | AT_SLOW); 1781 type &= ~(AT_PARALYZE | AT_SLOW);
1782
1820 if (!type || type == AT_MAGIC) 1783 if (!type || type == AT_MAGIC)
1821 return 0; 1784 return 0;
1822 } 1785 }
1823 } 1786 }
1824 1787
1828 1791
1829 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1792 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1830 if (tmp->type == RUNE || tmp->type == TRAP) 1793 if (tmp->type == RUNE || tmp->type == TRAP)
1831 { 1794 {
1832 spring_trap (tmp, hitter); 1795 spring_trap (tmp, hitter);
1833 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1796 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1834 return 0; 1797 return 0;
1835 break; 1798 break;
1836 } 1799 }
1837 } 1800 }
1838 1801
1839 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1802 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1840 { 1803 {
1841 /* FIXME: If a player is killed by a rune in a door, the 1804 /* FIXME: If a player is killed by a rune in a door, the
1842 * was_destroyed() check above doesn't return, and might get here. 1805 * destroyed() check above doesn't return, and might get here.
1843 */ 1806 */
1844 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1807 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1845 return 0; 1808 return 0;
1846 } 1809 }
1847 1810
2066 2029
2067 2030
2068void 2031void
2069poison_player (object *op, object *hitter, int dam) 2032poison_player (object *op, object *hitter, int dam)
2070{ 2033{
2071 archetype *at = find_archetype ("poisoning"); 2034 archetype *at = archetype::find ("poisoning");
2072 object *tmp = present_arch_in_ob (at, op); 2035 object *tmp = present_arch_in_ob (at, op);
2073 2036
2074 if (tmp == NULL) 2037 if (tmp == NULL)
2075 { 2038 {
2076 if ((tmp = arch_to_object (at)) == NULL) 2039 if ((tmp = arch_to_object (at)) == NULL)
2122} 2085}
2123 2086
2124void 2087void
2125slow_player (object *op, object *hitter, int dam) 2088slow_player (object *op, object *hitter, int dam)
2126{ 2089{
2127 archetype *at = find_archetype ("slowness"); 2090 archetype *at = archetype::find ("slowness");
2128 object *tmp; 2091 object *tmp;
2129 2092
2130 if (at == NULL) 2093 if (at == NULL)
2131 { 2094 {
2132 LOG (llevError, "Can't find slowness archetype.\n"); 2095 LOG (llevError, "Can't find slowness archetype.\n");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines