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.24 by root, Sat Dec 9 16:11: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);
1455
1474 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)
1475 {
1476 op->owner->contr->ranges[range_golem] = NULL; 1457 op->owner->contr->ranges[range_golem] = 0;
1477 op->owner->contr->golem_count = 0;
1478 }
1479 1458
1480 remove_ob (op); 1459 remove_ob (op);
1481 free_object (op); 1460 free_object (op);
1482 return maxdam; 1461 return maxdam;
1483 } 1462 }
1484 1463
1485 /* Now lets start dealing with experience we get for killing something */ 1464 /* Now lets start dealing with experience we get for killing something */
1486 1465
1487 owner = get_owner (hitter); 1466 owner = get_owner (hitter);
1488 if (owner == NULL) 1467 if (!owner)
1489 owner = hitter; 1468 owner = hitter;
1490 1469
1491 /* is the victim (op) standing on battleground? */ 1470 /* is the victim (op) standing on battleground? */
1492 if (op_on_battleground (op, NULL, NULL)) 1471 if (op_on_battleground (op, NULL, NULL))
1493 battleg = 1; 1472 battleg = 1;
1523 * probably don't want to see that. 1502 * probably don't want to see that.
1524 */ 1503 */
1525 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1504 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1526 { 1505 {
1527 if (owner != hitter) 1506 if (owner != hitter)
1528 {
1529 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));
1530 }
1531 else 1508 else
1532 {
1533 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));
1534 } 1510
1535 /* Only play sounds for melee kills */ 1511 /* Only play sounds for melee kills */
1536 if (hitter->type == PLAYER) 1512 if (hitter->type == PLAYER)
1537 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);
1538 } 1514 }
1539 1515
1550 1526
1551 /* This code below deals with finding the appropriate skill 1527 /* This code below deals with finding the appropriate skill
1552 * to credit exp to. This is a bit problematic - we should 1528 * to credit exp to. This is a bit problematic - we should
1553 * probably never really have to look at current_weapon->skill 1529 * probably never really have to look at current_weapon->skill
1554 */ 1530 */
1555 skill = NULL; 1531 skill = 0;
1532
1556 if (hitter->skill && hitter->type != PLAYER) 1533 if (hitter->skill && hitter->type != PLAYER)
1557 skill = hitter->skill; 1534 skill = hitter->skill;
1558 else if (owner->chosen_skill) 1535 else if (owner->chosen_skill)
1559 { 1536 {
1560 skill = owner->chosen_skill->skill; 1537 skill = owner->chosen_skill->skill;
1579 break; 1556 break;
1580 } 1557 }
1581 } 1558 }
1582 } /* Was it a player that hit somethign */ 1559 } /* Was it a player that hit somethign */
1583 else 1560 else
1584 {
1585 skill = NULL; 1561 skill = 0;
1586 }
1587 1562
1588 /* Pet (or spell) killed something. */ 1563 /* Pet (or spell) killed something. */
1589 if (owner != hitter) 1564 if (owner != hitter)
1590 {
1591 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1565 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1592 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1566 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1593 }
1594 else 1567 else
1595 {
1596 (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,
1597 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1569 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1598 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1570 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1599 } 1571
1600 /* These may have been set in the player code section above */ 1572 /* These may have been set in the player code section above */
1601 if (!skop) 1573 if (!skop)
1602 skop = hitter->chosen_skill; 1574 skop = hitter->chosen_skill;
1575
1603 if (!skill && skop) 1576 if (!skill && skop)
1604 skill = skop->skill; 1577 skill = skop->skill;
1605 1578
1606 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);
1607 1580
1608
1609 /* If you didn't kill yourself, and your not the wizard */ 1581 /* If you didn't kill yourself, and your not the wizard */
1610 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1582 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1611 { 1583 {
1612 int exp; 1584 int exp;
1613 1585
1614 /* Really don't give much experience for killing other players */ 1586 /* Really don't give much experience for killing other players */
1615 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1587 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1616 if (op->type == PLAYER) 1588 if (op->type == PLAYER)
1617 { 1589 {
1618 if (battleg) 1590 if (battleg)
1619 { 1591 {
1620 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1592 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1638 1610
1639 if (!settings.simple_exp) 1611 if (!settings.simple_exp)
1640 exp = exp / 2; 1612 exp = exp / 2;
1641 1613
1642 if (owner->type != PLAYER || owner->contr->party == NULL) 1614 if (owner->type != PLAYER || owner->contr->party == NULL)
1643 {
1644 change_exp (owner, exp, skill, 0); 1615 change_exp (owner, exp, skill, 0);
1645 }
1646 else 1616 else
1647 { 1617 {
1648 int shares = 0, count = 0; 1618 int shares = 0, count = 0;
1649
1650 player *pl; 1619 player *pl;
1651
1652 partylist *party = owner->contr->party; 1620 partylist *party = owner->contr->party;
1653 1621
1654#ifdef PARTY_KILL_LOG 1622#ifdef PARTY_KILL_LOG
1655 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);
1656#endif 1624#endif
1657 for (pl = first_player; pl != NULL; pl = pl->next) 1625 for (pl = first_player; pl != NULL; pl = pl->next)
1658 {
1659 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))
1660 { 1627 {
1661 count++; 1628 count++;
1662 shares += (pl->ob->level + 4); 1629 shares += (pl->ob->level + 4);
1663 } 1630 }
1664 } 1631
1665 if (count == 1 || shares > exp) 1632 if (count == 1 || shares > exp || !shares)
1666 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1633 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1667 else 1634 else
1668 { 1635 {
1669 int share = exp / shares, given = 0, nexp; 1636 int share = exp / shares, given = 0, nexp;
1670 1637
1671 for (pl = first_player; pl != NULL; pl = pl->next) 1638 for (pl = first_player; pl != NULL; pl = pl->next)
1672 {
1673 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))
1674 { 1640 {
1675 nexp = (pl->ob->level + 4) * share; 1641 nexp = (pl->ob->level + 4) * share;
1676 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1642 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1677 given += nexp; 1643 given += nexp;
1678 } 1644 }
1679 } 1645
1680 exp -= given; 1646 exp -= given;
1681 /* give any remainder to the player */ 1647 /* give any remainder to the player */
1682 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1648 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1683 } 1649 }
1684 } /* else part of a party */ 1650 } /* else part of a party */
1685
1686 } /* end if person didn't kill himself */ 1651 } /* end if person didn't kill himself */
1687 1652
1688 if (op->type != PLAYER) 1653 if (op->type != PLAYER)
1689 { 1654 {
1690 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1655 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1691 { 1656 {
1692 object *owner1 = get_owner (op); 1657 object *owner1 = get_owner (op);
1693 1658
1694 if (owner1 != NULL && owner1->type == PLAYER) 1659 if (owner1 && owner1->type == PLAYER)
1695 { 1660 {
1696 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);
1697 /* Maybe we should include the owner that killed this, maybe not */ 1662 /* 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); 1663 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1699 } 1664 }
1702 } 1667 }
1703 1668
1704 remove_ob (op); 1669 remove_ob (op);
1705 free_object (op); 1670 free_object (op);
1706 } 1671 }
1707 /* Player has been killed! */
1708 else 1672 else
1709 { 1673 {
1674 /* Player has been killed! */
1710 if (owner->type == PLAYER) 1675 if (owner->type == PLAYER)
1711 {
1712 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);
1713 }
1714 else 1677 else
1715 assign (op->contr->killer, hitter->name); 1678 assign (op->contr->killer, hitter->name);
1716 } 1679 }
1717 1680
1718 /* 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
1773{ 1736{
1774 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1737 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1775 int maxattacktype, attacknum; 1738 int maxattacktype, attacknum;
1776 int body_attack = op && op->head; /* Did we hit op's head? */ 1739 int body_attack = op && op->head; /* Did we hit op's head? */
1777 int simple_attack; 1740 int simple_attack;
1778 tag_t op_tag, hitter_tag;
1779 int rtn_kill = 0; 1741 int rtn_kill = 0;
1780 int friendlyfire; 1742 int friendlyfire;
1781 1743
1782 if (get_attack_mode (&op, &hitter, &simple_attack)) 1744 if (get_attack_mode (&op, &hitter, &simple_attack))
1783 return 0; 1745 return 0;
1791 { 1753 {
1792 object *owner = get_owner (hitter); 1754 object *owner = get_owner (hitter);
1793 1755
1794 if (!owner) 1756 if (!owner)
1795 owner = hitter; 1757 owner = hitter;
1758
1796 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1759 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1797 {
1798 return 0; 1760 return 0;
1799 }
1800 } 1761 }
1801#endif 1762#endif
1802
1803 op_tag = op->count;
1804 hitter_tag = hitter->count;
1805 1763
1806 if (body_attack) 1764 if (body_attack)
1807 { 1765 {
1808 /* slow and paralyze must hit the head. But we don't want to just 1766 /* 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 1767 * return - we still need to process other attacks the spell still
1815 * attack so we don't cancel out things like magic bullet. 1773 * attack so we don't cancel out things like magic bullet.
1816 */ 1774 */
1817 if (type & (AT_PARALYZE | AT_SLOW)) 1775 if (type & (AT_PARALYZE | AT_SLOW))
1818 { 1776 {
1819 type &= ~(AT_PARALYZE | AT_SLOW); 1777 type &= ~(AT_PARALYZE | AT_SLOW);
1778
1820 if (!type || type == AT_MAGIC) 1779 if (!type || type == AT_MAGIC)
1821 return 0; 1780 return 0;
1822 } 1781 }
1823 } 1782 }
1824 1783
1828 1787
1829 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1788 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1830 if (tmp->type == RUNE || tmp->type == TRAP) 1789 if (tmp->type == RUNE || tmp->type == TRAP)
1831 { 1790 {
1832 spring_trap (tmp, hitter); 1791 spring_trap (tmp, hitter);
1833 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1792 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1834 return 0; 1793 return 0;
1835 break; 1794 break;
1836 } 1795 }
1837 } 1796 }
1838 1797
1839 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1798 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1840 { 1799 {
1841 /* FIXME: If a player is killed by a rune in a door, the 1800 /* 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. 1801 * destroyed() check above doesn't return, and might get here.
1843 */ 1802 */
1844 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1803 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1845 return 0; 1804 return 0;
1846 } 1805 }
1847 1806
2066 2025
2067 2026
2068void 2027void
2069poison_player (object *op, object *hitter, int dam) 2028poison_player (object *op, object *hitter, int dam)
2070{ 2029{
2071 archetype *at = find_archetype ("poisoning"); 2030 archetype *at = archetype::find ("poisoning");
2072 object *tmp = present_arch_in_ob (at, op); 2031 object *tmp = present_arch_in_ob (at, op);
2073 2032
2074 if (tmp == NULL) 2033 if (tmp == NULL)
2075 { 2034 {
2076 if ((tmp = arch_to_object (at)) == NULL) 2035 if ((tmp = arch_to_object (at)) == NULL)
2122} 2081}
2123 2082
2124void 2083void
2125slow_player (object *op, object *hitter, int dam) 2084slow_player (object *op, object *hitter, int dam)
2126{ 2085{
2127 archetype *at = find_archetype ("slowness"); 2086 archetype *at = archetype::find ("slowness");
2128 object *tmp; 2087 object *tmp;
2129 2088
2130 if (at == NULL) 2089 if (at == NULL)
2131 { 2090 {
2132 LOG (llevError, "Can't find slowness archetype.\n"); 2091 LOG (llevError, "Can't find slowness archetype.\n");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines