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.14 by root, Thu Sep 14 17:10:25 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.14 2006/09/14 17:10:25 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
242 else 236 else
243 replace_insert_ob_in_map ("burnout", originator); 237 replace_insert_ob_in_map ("burnout", originator);
244 238
245 return; 239 return;
246 } 240 }
241
247 /* The value of 50 is arbitrary. */ 242 /* The value of 50 is arbitrary. */
248 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))
249 { 244 {
250 object *tmp; 245 object *tmp;
251 archetype *at = find_archetype ("icecube"); 246 archetype *at = archetype::find ("icecube");
252 247
253 if (at == NULL) 248 if (at == NULL)
254 return; 249 return;
250
255 op = stop_item (op); 251 op = stop_item (op);
256 if (op == NULL) 252 if (op == NULL)
257 return; 253 return;
254
258 if ((tmp = present_arch (at, op->map, op->x, op->y)) == NULL) 255 if ((tmp = present_arch (at, op->map, op->x, op->y)) == NULL)
259 { 256 {
260 tmp = arch_to_object (at); 257 tmp = arch_to_object (at);
261 tmp->x = op->x, tmp->y = op->y; 258 tmp->x = op->x, tmp->y = op->y;
262 /* This was in the old (pre new movement code) - 259 /* This was in the old (pre new movement code) -
265 */ 262 */
266 tmp->move_slow_penalty = 0; 263 tmp->move_slow_penalty = 0;
267 tmp->move_slow = 0; 264 tmp->move_slow = 0;
268 insert_ob_in_map (tmp, op->map, originator, 0); 265 insert_ob_in_map (tmp, op->map, originator, 0);
269 } 266 }
267
270 if (!QUERY_FLAG (op, FLAG_REMOVED)) 268 if (!QUERY_FLAG (op, FLAG_REMOVED))
271 remove_ob (op); 269 remove_ob (op);
270
272 (void) insert_ob_in_ob (op, tmp); 271 insert_ob_in_ob (op, tmp);
273 return; 272 return;
274 } 273 }
275} 274}
276 275
277/* Object op is hitting the map. 276/* Object op is hitting the map.
283 282
284int 283int
285hit_map (object *op, int dir, int type, int full_hit) 284hit_map (object *op, int dir, int type, int full_hit)
286{ 285{
287 object *tmp, *next; 286 object *tmp, *next;
288 mapstruct *map; 287 maptile *map;
289 sint16 x, y; 288 sint16 x, y;
290 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 */
291 290
292 tag_t op_tag, next_tag = 0;
293
294 if (QUERY_FLAG (op, FLAG_FREED)) 291 if (QUERY_FLAG (op, FLAG_FREED))
295 { 292 {
296 LOG (llevError, "BUG: hit_map(): free object\n"); 293 LOG (llevError, "BUG: hit_map(): free object\n");
297 return 0; 294 return 0;
298 } 295 }
309 return 0; 306 return 0;
310 } 307 }
311 308
312 if (op->head) 309 if (op->head)
313 op = op->head; 310 op = op->head;
314
315 op_tag = op->count;
316 311
317 map = op->map; 312 map = op->map;
318 x = op->x + freearr_x[dir]; 313 x = op->x + freearr_x[dir];
319 y = op->y + freearr_y[dir]; 314 y = op->y + freearr_y[dir];
320 315
348 update_object (op, UP_OBJ_FACE); 343 update_object (op, UP_OBJ_FACE);
349 type &= ~AT_CHAOS; 344 type &= ~AT_CHAOS;
350 } 345 }
351 346
352 next = get_map_ob (map, x, y); 347 next = get_map_ob (map, x, y);
353 if (next)
354 next_tag = next->count;
355 348
356 while (next) 349 while (next)
357 { 350 {
358 if (was_destroyed (next, next_tag)) 351 if (next->destroyed ())
359 { 352 {
360 /* 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
361 * 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
362 * tags into a temporary array before we start processing the first 355 * tags into a temporary array before we start processing the first
363 * object. That's why we just abort. 356 * object. That's why we just abort.
371 } 364 }
372 365
373 tmp = next; 366 tmp = next;
374 next = tmp->above; 367 next = tmp->above;
375 368
376 if (next) 369 if (tmp->destroyed ())
377 next_tag = next->count;
378
379 if (QUERY_FLAG (tmp, FLAG_FREED))
380 { 370 {
381 LOG (llevError, "BUG: hit_map(): found freed object\n"); 371 LOG (llevError, "BUG: hit_map(): found freed object\n");
382 break; 372 break;
383 } 373 }
384 374
391 381
392 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 382 if (QUERY_FLAG (tmp, FLAG_ALIVE))
393 { 383 {
394 hit_player (tmp, op->stats.dam, op, type, full_hit); 384 hit_player (tmp, op->stats.dam, op, type, full_hit);
395 retflag |= 1; 385 retflag |= 1;
396 if (was_destroyed (op, op_tag)) 386 if (op->destroyed ())
397 break; 387 break;
398 } 388 }
399 389
400 /* Here we are potentially destroying an object. If the object has 390 /* Here we are potentially destroying an object. If the object has
401 * 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
405 * destroyed right now. 395 * destroyed right now.
406 */ 396 */
407 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)
408 { 398 {
409 save_throw_object (tmp, type, op); 399 save_throw_object (tmp, type, op);
410 if (was_destroyed (op, op_tag)) 400 if (op->destroyed ())
411 break; 401 break;
412 } 402 }
413 } 403 }
414 404
415 return 0; 405 return 0;
418void 408void
419attack_message (int dam, int type, object *op, object *hitter) 409attack_message (int dam, int type, object *op, object *hitter)
420{ 410{
421 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 411 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
422 int i, found = 0; 412 int i, found = 0;
423 mapstruct *map; 413 maptile *map;
424 object *next, *tmp; 414 object *next, *tmp;
425 415
426 /* 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
427 * a player might have. For example, fire, electric, cold, etc 417 * a player might have. For example, fire, electric, cold, etc
428 * [garbled 20010919] 418 * [garbled 20010919]
755attack_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)
756{ 746{
757 int simple_attack, roll, dam = 0; 747 int simple_attack, roll, dam = 0;
758 uint32 type; 748 uint32 type;
759 shstr op_name; 749 shstr op_name;
760 tag_t op_tag, hitter_tag;
761 750
762 if (get_attack_mode (&op, &hitter, &simple_attack)) 751 if (get_attack_mode (&op, &hitter, &simple_attack))
763 goto error; 752 goto error;
764 753
765 if (hitter->current_weapon) 754 if (hitter->current_weapon)
766 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)))
767 return RESULT_INT (0); 756 return RESULT_INT (0);
768 757
769 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 758 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
770 return RESULT_INT (0); 759 return RESULT_INT (0);
771
772 op_tag = op->count;
773 hitter_tag = hitter->count;
774 760
775 /* 761 /*
776 * 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
777 * to avoid ever being hit by monsters. 763 * to avoid ever being hit by monsters.
778 */ 764 */
783 * which then gets here again. By decreasing the speed before 769 * which then gets here again. By decreasing the speed before
784 * we call process_object, the 'if' statement above will fail. 770 * we call process_object, the 'if' statement above will fail.
785 */ 771 */
786 op->speed_left--; 772 op->speed_left--;
787 process_object (op); 773 process_object (op);
788 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))
789 goto error; 775 goto error;
790 } 776 }
791 777
792 op_name = op->name; 778 op_name = op->name;
793 779
844 * when they hit the victim. For things like thrown daggers, 830 * when they hit the victim. For things like thrown daggers,
845 * this sets 'hitter' to the actual dagger, and not the 831 * this sets 'hitter' to the actual dagger, and not the
846 * wrapper object. 832 * wrapper object.
847 */ 833 */
848 thrown_item_effect (hitter, op); 834 thrown_item_effect (hitter, op);
849 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))
850 goto leave; 836 goto leave;
851 } 837 }
852 838
853 /* 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
854 * to go further and it will cause FPE's below. 840 * to go further and it will cause FPE's below.
855 */ 841 */
856 if (hitdam <= 0) 842 if (hitdam <= 0)
857 hitdam = 1; 843 hitdam = 1;
858 844
859 type = hitter->attacktype; 845 type = hitter->attacktype;
846
860 if (!type) 847 if (!type)
861 type = AT_PHYSICAL; 848 type = AT_PHYSICAL;
849
862 /* Handle monsters that hit back */ 850 /* Handle monsters that hit back */
863 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))
864 { 852 {
865 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 853 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
866 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
867 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
868 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))
869 goto leave; 859 goto leave;
870 } 860 }
871 861
872 /* In the new attack code, it should handle multiple attack 862 /* In the new attack code, it should handle multiple attack
873 * types in its area, so remove it from here. 863 * types in its area, so remove it from here.
874 */ 864 */
875 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
876 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))
877 goto leave; 868 goto leave;
878 } /* end of if hitter hit op */ 869 } /* end of if hitter hit op */
879 /* if we missed, dam=0 */ 870 /* if we missed, dam=0 */
880 871
881 /*attack_message(dam, type, op, hitter); */ 872 /*attack_message(dam, type, op, hitter); */
938object * 929object *
939hit_with_arrow (object *op, object *victim) 930hit_with_arrow (object *op, object *victim)
940{ 931{
941 object *container, *hitter; 932 object *container, *hitter;
942 int hit_something = 0; 933 int hit_something = 0;
943 tag_t victim_tag, hitter_tag;
944 sint16 victim_x, victim_y;
945 934
946 /* Disassemble missile */ 935 /* Disassemble missile */
947 if (op->inv) 936 if (op->inv)
948 { 937 {
949 container = op; 938 container = op;
955 * 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
956 * THROWN_OBJs. */ 945 * THROWN_OBJs. */
957 } 946 }
958 else 947 else
959 { 948 {
960 container = NULL; 949 container = 0;
961 hitter = op; 950 hitter = op;
962 } 951 }
963 952
964 /* Try to hit victim */ 953 /* Try to hit victim */
965 victim_x = victim->x;
966 victim_y = victim->y;
967 victim_tag = victim->count;
968 hitter_tag = hitter->count;
969
970 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);
971 955
972 /* 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
973 * arrow, move_apply() calls this function, arrow sticks in demon, 957 * arrow, move_apply() calls this function, arrow sticks in demon,
974 * 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
975 * 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
976 * other places as well!) 960 * other places as well!)
977 */ 961 */
978 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 962 if (hitter->destroyed () || hitter->env != NULL)
979 { 963 {
980 if (container) 964 if (container)
981 { 965 {
982 remove_ob (container); 966 remove_ob (container);
983 free_object (container); 967 free_object (container);
984 } 968 }
969
985 return NULL; 970 return 0;
986 } 971 }
987 972
988 /* Missile hit victim */ 973 /* Missile hit victim */
989 /* 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
990 * through the target 975 * through the target
991 */ 976 */
992 if (hit_something && op->speed <= 10.0) 977 if (hit_something && op->speed <= 10.0)
993 { 978 {
994 /* Stop arrow */ 979 /* Stop arrow */
995 if (container == NULL) 980 if (!container)
996 { 981 {
997 hitter = fix_stopped_arrow (hitter); 982 hitter = fix_stopped_arrow (hitter);
998 if (hitter == NULL) 983 if (!hitter)
999 return NULL; 984 return 0;
1000 } 985 }
1001 else 986 else
1002 { 987 {
1003 remove_ob (container); 988 remove_ob (container);
1004 free_object (container); 989 free_object (container);
1005 } 990 }
1006 991
1007 /* Try to stick arrow into victim */ 992 /* Try to stick arrow into victim */
1008 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 993 if (!victim->destroyed () && stick_arrow (hitter, victim))
1009 return NULL; 994 return 0;
1010 995
1011 /* Else try to put arrow on victim's map square 996 /* Else try to put arrow on victim's map square
1012 * 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
1013 * space, that is good enough - with the new movement code, 998 * space, that is good enough - with the new movement code,
1014 * there is now the potential for lots of spaces where something 999 * there is now the potential for lots of spaces where something
1015 * 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
1016 * way to handle those otherwise? 1001 * way to handle those otherwise?
1017 */ 1002 */
1018 if (victim_x != hitter->x || victim_y != hitter->y) 1003 if (victim->x != hitter->x || victim->y != hitter->y)
1019 { 1004 {
1020 remove_ob (hitter); 1005 remove_ob (hitter);
1021 hitter->x = victim_x; 1006 hitter->x = victim->x;
1022 hitter->y = victim_y; 1007 hitter->y = victim->y;
1023 insert_ob_in_map (hitter, victim->map, hitter, 0); 1008 insert_ob_in_map (hitter, victim->map, hitter, 0);
1024 } 1009 }
1025 else 1010 else
1026 {
1027 /* Else leave arrow where it is */ 1011 /* Else leave arrow where it is */
1028 merge_ob (hitter, NULL); 1012 merge_ob (hitter, NULL);
1029 } 1013
1030 return NULL; 1014 return 0;
1031 } 1015 }
1032 1016
1033 if (hit_something && op->speed >= 10.0) 1017 if (hit_something && op->speed >= 10.0)
1034 op->speed -= 1.0; 1018 op->speed -= 1.0;
1035 1019
1037 if (container) 1021 if (container)
1038 { 1022 {
1039 remove_ob (hitter); 1023 remove_ob (hitter);
1040 insert_ob_in_ob (hitter, container); 1024 insert_ob_in_ob (hitter, container);
1041 } 1025 }
1026
1042 return op; 1027 return op;
1043} 1028}
1044 1029
1045 1030
1046void 1031void
1461 op->speed = 0.1; 1446 op->speed = 0.1;
1462 update_ob_speed (op); 1447 update_ob_speed (op);
1463 op->speed_left = -0.05; 1448 op->speed_left = -0.05;
1464 return maxdam; 1449 return maxdam;
1465 } 1450 }
1451
1466 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1452 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1467 { 1453 {
1468 remove_friendly_object (op); 1454 remove_friendly_object (op);
1455
1469 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)
1470 {
1471 op->owner->contr->ranges[range_golem] = NULL; 1457 op->owner->contr->ranges[range_golem] = 0;
1472 op->owner->contr->golem_count = 0;
1473 }
1474 1458
1475 remove_ob (op); 1459 remove_ob (op);
1476 free_object (op); 1460 free_object (op);
1477 return maxdam; 1461 return maxdam;
1478 } 1462 }
1479 1463
1480 /* Now lets start dealing with experience we get for killing something */ 1464 /* Now lets start dealing with experience we get for killing something */
1481 1465
1482 owner = get_owner (hitter); 1466 owner = get_owner (hitter);
1483 if (owner == NULL) 1467 if (!owner)
1484 owner = hitter; 1468 owner = hitter;
1485 1469
1486 /* is the victim (op) standing on battleground? */ 1470 /* is the victim (op) standing on battleground? */
1487 if (op_on_battleground (op, NULL, NULL)) 1471 if (op_on_battleground (op, NULL, NULL))
1488 battleg = 1; 1472 battleg = 1;
1518 * probably don't want to see that. 1502 * probably don't want to see that.
1519 */ 1503 */
1520 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1504 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1521 { 1505 {
1522 if (owner != hitter) 1506 if (owner != hitter)
1523 {
1524 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));
1525 }
1526 else 1508 else
1527 {
1528 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));
1529 } 1510
1530 /* Only play sounds for melee kills */ 1511 /* Only play sounds for melee kills */
1531 if (hitter->type == PLAYER) 1512 if (hitter->type == PLAYER)
1532 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);
1533 } 1514 }
1534 1515
1545 1526
1546 /* This code below deals with finding the appropriate skill 1527 /* This code below deals with finding the appropriate skill
1547 * to credit exp to. This is a bit problematic - we should 1528 * to credit exp to. This is a bit problematic - we should
1548 * probably never really have to look at current_weapon->skill 1529 * probably never really have to look at current_weapon->skill
1549 */ 1530 */
1550 skill = NULL; 1531 skill = 0;
1532
1551 if (hitter->skill && hitter->type != PLAYER) 1533 if (hitter->skill && hitter->type != PLAYER)
1552 skill = hitter->skill; 1534 skill = hitter->skill;
1553 else if (owner->chosen_skill) 1535 else if (owner->chosen_skill)
1554 { 1536 {
1555 skill = owner->chosen_skill->skill; 1537 skill = owner->chosen_skill->skill;
1574 break; 1556 break;
1575 } 1557 }
1576 } 1558 }
1577 } /* Was it a player that hit somethign */ 1559 } /* Was it a player that hit somethign */
1578 else 1560 else
1579 {
1580 skill = NULL; 1561 skill = 0;
1581 }
1582 1562
1583 /* Pet (or spell) killed something. */ 1563 /* Pet (or spell) killed something. */
1584 if (owner != hitter) 1564 if (owner != hitter)
1585 {
1586 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1565 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1587 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1566 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1588 }
1589 else 1567 else
1590 {
1591 (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,
1592 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1569 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1593 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1570 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1594 } 1571
1595 /* These may have been set in the player code section above */ 1572 /* These may have been set in the player code section above */
1596 if (!skop) 1573 if (!skop)
1597 skop = hitter->chosen_skill; 1574 skop = hitter->chosen_skill;
1575
1598 if (!skill && skop) 1576 if (!skill && skop)
1599 skill = skop->skill; 1577 skill = skop->skill;
1600 1578
1601 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);
1602 1580
1603
1604 /* If you didn't kill yourself, and your not the wizard */ 1581 /* If you didn't kill yourself, and your not the wizard */
1605 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1582 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1606 { 1583 {
1607 int exp; 1584 int exp;
1608 1585
1609 /* Really don't give much experience for killing other players */ 1586 /* Really don't give much experience for killing other players */
1610 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1587 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1611 if (op->type == PLAYER) 1588 if (op->type == PLAYER)
1612 { 1589 {
1613 if (battleg) 1590 if (battleg)
1614 { 1591 {
1615 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1592 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1633 1610
1634 if (!settings.simple_exp) 1611 if (!settings.simple_exp)
1635 exp = exp / 2; 1612 exp = exp / 2;
1636 1613
1637 if (owner->type != PLAYER || owner->contr->party == NULL) 1614 if (owner->type != PLAYER || owner->contr->party == NULL)
1638 {
1639 change_exp (owner, exp, skill, 0); 1615 change_exp (owner, exp, skill, 0);
1640 }
1641 else 1616 else
1642 { 1617 {
1643 int shares = 0, count = 0; 1618 int shares = 0, count = 0;
1644
1645 player *pl; 1619 player *pl;
1646
1647 partylist *party = owner->contr->party; 1620 partylist *party = owner->contr->party;
1648 1621
1649#ifdef PARTY_KILL_LOG 1622#ifdef PARTY_KILL_LOG
1650 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);
1651#endif 1624#endif
1652 for (pl = first_player; pl != NULL; pl = pl->next) 1625 for (pl = first_player; pl != NULL; pl = pl->next)
1653 {
1654 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))
1655 { 1627 {
1656 count++; 1628 count++;
1657 shares += (pl->ob->level + 4); 1629 shares += (pl->ob->level + 4);
1658 } 1630 }
1659 } 1631
1660 if (count == 1 || shares > exp) 1632 if (count == 1 || shares > exp || !shares)
1661 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1633 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1662 else 1634 else
1663 { 1635 {
1664 int share = exp / shares, given = 0, nexp; 1636 int share = exp / shares, given = 0, nexp;
1665 1637
1666 for (pl = first_player; pl != NULL; pl = pl->next) 1638 for (pl = first_player; pl != NULL; pl = pl->next)
1667 {
1668 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))
1669 { 1640 {
1670 nexp = (pl->ob->level + 4) * share; 1641 nexp = (pl->ob->level + 4) * share;
1671 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1642 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1672 given += nexp; 1643 given += nexp;
1673 } 1644 }
1674 } 1645
1675 exp -= given; 1646 exp -= given;
1676 /* give any remainder to the player */ 1647 /* give any remainder to the player */
1677 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1648 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1678 } 1649 }
1679 } /* else part of a party */ 1650 } /* else part of a party */
1680
1681 } /* end if person didn't kill himself */ 1651 } /* end if person didn't kill himself */
1682 1652
1683 if (op->type != PLAYER) 1653 if (op->type != PLAYER)
1684 { 1654 {
1685 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1655 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1686 { 1656 {
1687 object *owner1 = get_owner (op); 1657 object *owner1 = get_owner (op);
1688 1658
1689 if (owner1 != NULL && owner1->type == PLAYER) 1659 if (owner1 && owner1->type == PLAYER)
1690 { 1660 {
1691 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);
1692 /* Maybe we should include the owner that killed this, maybe not */ 1662 /* Maybe we should include the owner that killed this, maybe not */
1693 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);
1694 } 1664 }
1697 } 1667 }
1698 1668
1699 remove_ob (op); 1669 remove_ob (op);
1700 free_object (op); 1670 free_object (op);
1701 } 1671 }
1702 /* Player has been killed! */
1703 else 1672 else
1704 { 1673 {
1674 /* Player has been killed! */
1705 if (owner->type == PLAYER) 1675 if (owner->type == PLAYER)
1706 {
1707 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);
1708 }
1709 else 1677 else
1710 assign (op->contr->killer, hitter->name); 1678 assign (op->contr->killer, hitter->name);
1711 } 1679 }
1712 1680
1713 /* 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
1768{ 1736{
1769 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1737 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1770 int maxattacktype, attacknum; 1738 int maxattacktype, attacknum;
1771 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? */
1772 int simple_attack; 1740 int simple_attack;
1773 tag_t op_tag, hitter_tag;
1774 int rtn_kill = 0; 1741 int rtn_kill = 0;
1775 int friendlyfire; 1742 int friendlyfire;
1776 1743
1777 if (get_attack_mode (&op, &hitter, &simple_attack)) 1744 if (get_attack_mode (&op, &hitter, &simple_attack))
1778 return 0; 1745 return 0;
1786 { 1753 {
1787 object *owner = get_owner (hitter); 1754 object *owner = get_owner (hitter);
1788 1755
1789 if (!owner) 1756 if (!owner)
1790 owner = hitter; 1757 owner = hitter;
1758
1791 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)
1792 {
1793 return 0; 1760 return 0;
1794 }
1795 } 1761 }
1796#endif 1762#endif
1797
1798 op_tag = op->count;
1799 hitter_tag = hitter->count;
1800 1763
1801 if (body_attack) 1764 if (body_attack)
1802 { 1765 {
1803 /* 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
1804 * return - we still need to process other attacks the spell still 1767 * return - we still need to process other attacks the spell still
1810 * attack so we don't cancel out things like magic bullet. 1773 * attack so we don't cancel out things like magic bullet.
1811 */ 1774 */
1812 if (type & (AT_PARALYZE | AT_SLOW)) 1775 if (type & (AT_PARALYZE | AT_SLOW))
1813 { 1776 {
1814 type &= ~(AT_PARALYZE | AT_SLOW); 1777 type &= ~(AT_PARALYZE | AT_SLOW);
1778
1815 if (!type || type == AT_MAGIC) 1779 if (!type || type == AT_MAGIC)
1816 return 0; 1780 return 0;
1817 } 1781 }
1818 } 1782 }
1819 1783
1823 1787
1824 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1788 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1825 if (tmp->type == RUNE || tmp->type == TRAP) 1789 if (tmp->type == RUNE || tmp->type == TRAP)
1826 { 1790 {
1827 spring_trap (tmp, hitter); 1791 spring_trap (tmp, hitter);
1828 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))
1829 return 0; 1793 return 0;
1830 break; 1794 break;
1831 } 1795 }
1832 } 1796 }
1833 1797
1834 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1798 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1835 { 1799 {
1836 /* 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
1837 * was_destroyed() check above doesn't return, and might get here. 1801 * destroyed() check above doesn't return, and might get here.
1838 */ 1802 */
1839 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);
1840 return 0; 1804 return 0;
1841 } 1805 }
1842 1806
2061 2025
2062 2026
2063void 2027void
2064poison_player (object *op, object *hitter, int dam) 2028poison_player (object *op, object *hitter, int dam)
2065{ 2029{
2066 archetype *at = find_archetype ("poisoning"); 2030 archetype *at = archetype::find ("poisoning");
2067 object *tmp = present_arch_in_ob (at, op); 2031 object *tmp = present_arch_in_ob (at, op);
2068 2032
2069 if (tmp == NULL) 2033 if (tmp == NULL)
2070 { 2034 {
2071 if ((tmp = arch_to_object (at)) == NULL) 2035 if ((tmp = arch_to_object (at)) == NULL)
2117} 2081}
2118 2082
2119void 2083void
2120slow_player (object *op, object *hitter, int dam) 2084slow_player (object *op, object *hitter, int dam)
2121{ 2085{
2122 archetype *at = find_archetype ("slowness"); 2086 archetype *at = archetype::find ("slowness");
2123 object *tmp; 2087 object *tmp;
2124 2088
2125 if (at == NULL) 2089 if (at == NULL)
2126 { 2090 {
2127 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