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.13 by root, Thu Sep 14 00:14:51 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.13 2006/09/14 00:14:51 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
1335 break; 1320 break;
1336 case ATNR_TURN_UNDEAD: 1321 case ATNR_TURN_UNDEAD:
1337 { 1322 {
1338 if (QUERY_FLAG (op, FLAG_UNDEAD)) 1323 if (QUERY_FLAG (op, FLAG_UNDEAD))
1339 { 1324 {
1340 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter); 1325 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1341 object *god = find_god (determine_god (owner)); 1326 object *god = find_god (determine_god (owner));
1342 int div = 1; 1327 int div = 1;
1343 1328
1344 /* if undead are not an enemy of your god, you turn them 1329 /* if undead are not an enemy of your god, you turn them
1345 * at half strength */ 1330 * at half strength */
1371 break; 1356 break;
1372 case ATNR_HOLYWORD: 1357 case ATNR_HOLYWORD:
1373 { 1358 {
1374 /* This has already been handled by hit_player, 1359 /* This has already been handled by hit_player,
1375 * no need to check twice -- DAMN */ 1360 * no need to check twice -- DAMN */
1376 1361 object *owner = hitter->owner ? (object *)hitter->owner : hitter;
1377 object *owner = get_owner (hitter) == NULL ? hitter : get_owner (hitter);
1378 1362
1379 /* As with turn undead above, give a bonus on the saving throw */ 1363 /* As with turn undead above, give a bonus on the saving throw */
1380 if ((op->level + (op->resist[ATNR_HOLYWORD] / 100)) < owner->level + turn_bonus[owner->stats.Wis]) 1364 if ((op->level + (op->resist[ATNR_HOLYWORD] / 100)) < owner->level + turn_bonus[owner->stats.Wis])
1381 scare_creature (op, owner); 1365 scare_creature (op, owner);
1382 } 1366 }
1462 op->speed = 0.1; 1446 op->speed = 0.1;
1463 update_ob_speed (op); 1447 update_ob_speed (op);
1464 op->speed_left = -0.05; 1448 op->speed_left = -0.05;
1465 return maxdam; 1449 return maxdam;
1466 } 1450 }
1451
1467 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1452 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1468 { 1453 {
1469 remove_friendly_object (op); 1454 remove_friendly_object (op);
1455
1470 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)
1471 {
1472 op->owner->contr->ranges[range_golem] = NULL; 1457 op->owner->contr->ranges[range_golem] = 0;
1473 op->owner->contr->golem_count = 0;
1474 }
1475 1458
1476 remove_ob (op); 1459 remove_ob (op);
1477 free_object (op); 1460 free_object (op);
1478 return maxdam; 1461 return maxdam;
1479 } 1462 }
1480 1463
1481 /* Now lets start dealing with experience we get for killing something */ 1464 /* Now lets start dealing with experience we get for killing something */
1482 1465
1483 owner = get_owner (hitter); 1466 owner = get_owner (hitter);
1484 if (owner == NULL) 1467 if (!owner)
1485 owner = hitter; 1468 owner = hitter;
1486 1469
1487 /* is the victim (op) standing on battleground? */ 1470 /* is the victim (op) standing on battleground? */
1488 if (op_on_battleground (op, NULL, NULL)) 1471 if (op_on_battleground (op, NULL, NULL))
1489 battleg = 1; 1472 battleg = 1;
1519 * probably don't want to see that. 1502 * probably don't want to see that.
1520 */ 1503 */
1521 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1504 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1522 { 1505 {
1523 if (owner != hitter) 1506 if (owner != hitter)
1524 {
1525 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));
1526 }
1527 else 1508 else
1528 {
1529 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));
1530 } 1510
1531 /* Only play sounds for melee kills */ 1511 /* Only play sounds for melee kills */
1532 if (hitter->type == PLAYER) 1512 if (hitter->type == PLAYER)
1533 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);
1534 } 1514 }
1535 1515
1546 1526
1547 /* This code below deals with finding the appropriate skill 1527 /* This code below deals with finding the appropriate skill
1548 * to credit exp to. This is a bit problematic - we should 1528 * to credit exp to. This is a bit problematic - we should
1549 * probably never really have to look at current_weapon->skill 1529 * probably never really have to look at current_weapon->skill
1550 */ 1530 */
1551 skill = NULL; 1531 skill = 0;
1532
1552 if (hitter->skill && hitter->type != PLAYER) 1533 if (hitter->skill && hitter->type != PLAYER)
1553 skill = hitter->skill; 1534 skill = hitter->skill;
1554 else if (owner->chosen_skill) 1535 else if (owner->chosen_skill)
1555 { 1536 {
1556 skill = owner->chosen_skill->skill; 1537 skill = owner->chosen_skill->skill;
1575 break; 1556 break;
1576 } 1557 }
1577 } 1558 }
1578 } /* Was it a player that hit somethign */ 1559 } /* Was it a player that hit somethign */
1579 else 1560 else
1580 {
1581 skill = NULL; 1561 skill = 0;
1582 }
1583 1562
1584 /* Pet (or spell) killed something. */ 1563 /* Pet (or spell) killed something. */
1585 if (owner != hitter) 1564 if (owner != hitter)
1586 {
1587 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1565 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1588 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1566 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1589 }
1590 else 1567 else
1591 {
1592 (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,
1593 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1569 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1594 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1570 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1595 } 1571
1596 /* These may have been set in the player code section above */ 1572 /* These may have been set in the player code section above */
1597 if (!skop) 1573 if (!skop)
1598 skop = hitter->chosen_skill; 1574 skop = hitter->chosen_skill;
1575
1599 if (!skill && skop) 1576 if (!skill && skop)
1600 skill = skop->skill; 1577 skill = skop->skill;
1601 1578
1602 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);
1603 1580
1604
1605 /* If you didn't kill yourself, and your not the wizard */ 1581 /* If you didn't kill yourself, and your not the wizard */
1606 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1582 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1607 { 1583 {
1608 int exp; 1584 int exp;
1609 1585
1610 /* Really don't give much experience for killing other players */ 1586 /* Really don't give much experience for killing other players */
1611 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1587 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1612 if (op->type == PLAYER) 1588 if (op->type == PLAYER)
1613 { 1589 {
1614 if (battleg) 1590 if (battleg)
1615 { 1591 {
1616 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1592 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1634 1610
1635 if (!settings.simple_exp) 1611 if (!settings.simple_exp)
1636 exp = exp / 2; 1612 exp = exp / 2;
1637 1613
1638 if (owner->type != PLAYER || owner->contr->party == NULL) 1614 if (owner->type != PLAYER || owner->contr->party == NULL)
1639 {
1640 change_exp (owner, exp, skill, 0); 1615 change_exp (owner, exp, skill, 0);
1641 }
1642 else 1616 else
1643 { 1617 {
1644 int shares = 0, count = 0; 1618 int shares = 0, count = 0;
1645
1646 player *pl; 1619 player *pl;
1647
1648 partylist *party = owner->contr->party; 1620 partylist *party = owner->contr->party;
1649 1621
1650#ifdef PARTY_KILL_LOG 1622#ifdef PARTY_KILL_LOG
1651 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);
1652#endif 1624#endif
1653 for (pl = first_player; pl != NULL; pl = pl->next) 1625 for (pl = first_player; pl != NULL; pl = pl->next)
1654 {
1655 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))
1656 { 1627 {
1657 count++; 1628 count++;
1658 shares += (pl->ob->level + 4); 1629 shares += (pl->ob->level + 4);
1659 } 1630 }
1660 } 1631
1661 if (count == 1 || shares > exp) 1632 if (count == 1 || shares > exp || !shares)
1662 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1633 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1663 else 1634 else
1664 { 1635 {
1665 int share = exp / shares, given = 0, nexp; 1636 int share = exp / shares, given = 0, nexp;
1666 1637
1667 for (pl = first_player; pl != NULL; pl = pl->next) 1638 for (pl = first_player; pl != NULL; pl = pl->next)
1668 {
1669 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))
1670 { 1640 {
1671 nexp = (pl->ob->level + 4) * share; 1641 nexp = (pl->ob->level + 4) * share;
1672 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1642 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1673 given += nexp; 1643 given += nexp;
1674 } 1644 }
1675 } 1645
1676 exp -= given; 1646 exp -= given;
1677 /* give any remainder to the player */ 1647 /* give any remainder to the player */
1678 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1648 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1679 } 1649 }
1680 } /* else part of a party */ 1650 } /* else part of a party */
1681
1682 } /* end if person didn't kill himself */ 1651 } /* end if person didn't kill himself */
1683 1652
1684 if (op->type != PLAYER) 1653 if (op->type != PLAYER)
1685 { 1654 {
1686 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1655 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1687 { 1656 {
1688 object *owner1 = get_owner (op); 1657 object *owner1 = get_owner (op);
1689 1658
1690 if (owner1 != NULL && owner1->type == PLAYER) 1659 if (owner1 && owner1->type == PLAYER)
1691 { 1660 {
1692 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);
1693 /* Maybe we should include the owner that killed this, maybe not */ 1662 /* Maybe we should include the owner that killed this, maybe not */
1694 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);
1695 } 1664 }
1698 } 1667 }
1699 1668
1700 remove_ob (op); 1669 remove_ob (op);
1701 free_object (op); 1670 free_object (op);
1702 } 1671 }
1703 /* Player has been killed! */
1704 else 1672 else
1705 { 1673 {
1674 /* Player has been killed! */
1706 if (owner->type == PLAYER) 1675 if (owner->type == PLAYER)
1707 {
1708 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);
1709 }
1710 else 1677 else
1711 assign (op->contr->killer, hitter->name); 1678 assign (op->contr->killer, hitter->name);
1712 } 1679 }
1713 1680
1714 /* 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
1769{ 1736{
1770 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1737 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1771 int maxattacktype, attacknum; 1738 int maxattacktype, attacknum;
1772 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? */
1773 int simple_attack; 1740 int simple_attack;
1774 tag_t op_tag, hitter_tag;
1775 int rtn_kill = 0; 1741 int rtn_kill = 0;
1776 int friendlyfire; 1742 int friendlyfire;
1777 1743
1778 if (get_attack_mode (&op, &hitter, &simple_attack)) 1744 if (get_attack_mode (&op, &hitter, &simple_attack))
1779 return 0; 1745 return 0;
1787 { 1753 {
1788 object *owner = get_owner (hitter); 1754 object *owner = get_owner (hitter);
1789 1755
1790 if (!owner) 1756 if (!owner)
1791 owner = hitter; 1757 owner = hitter;
1758
1792 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)
1793 {
1794 return 0; 1760 return 0;
1795 }
1796 } 1761 }
1797#endif 1762#endif
1798
1799 op_tag = op->count;
1800 hitter_tag = hitter->count;
1801 1763
1802 if (body_attack) 1764 if (body_attack)
1803 { 1765 {
1804 /* 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
1805 * return - we still need to process other attacks the spell still 1767 * return - we still need to process other attacks the spell still
1811 * attack so we don't cancel out things like magic bullet. 1773 * attack so we don't cancel out things like magic bullet.
1812 */ 1774 */
1813 if (type & (AT_PARALYZE | AT_SLOW)) 1775 if (type & (AT_PARALYZE | AT_SLOW))
1814 { 1776 {
1815 type &= ~(AT_PARALYZE | AT_SLOW); 1777 type &= ~(AT_PARALYZE | AT_SLOW);
1778
1816 if (!type || type == AT_MAGIC) 1779 if (!type || type == AT_MAGIC)
1817 return 0; 1780 return 0;
1818 } 1781 }
1819 } 1782 }
1820 1783
1824 1787
1825 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1788 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1826 if (tmp->type == RUNE || tmp->type == TRAP) 1789 if (tmp->type == RUNE || tmp->type == TRAP)
1827 { 1790 {
1828 spring_trap (tmp, hitter); 1791 spring_trap (tmp, hitter);
1829 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))
1830 return 0; 1793 return 0;
1831 break; 1794 break;
1832 } 1795 }
1833 } 1796 }
1834 1797
1835 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1798 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1836 { 1799 {
1837 /* 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
1838 * was_destroyed() check above doesn't return, and might get here. 1801 * destroyed() check above doesn't return, and might get here.
1839 */ 1802 */
1840 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);
1841 return 0; 1804 return 0;
1842 } 1805 }
1843 1806
2062 2025
2063 2026
2064void 2027void
2065poison_player (object *op, object *hitter, int dam) 2028poison_player (object *op, object *hitter, int dam)
2066{ 2029{
2067 archetype *at = find_archetype ("poisoning"); 2030 archetype *at = archetype::find ("poisoning");
2068 object *tmp = present_arch_in_ob (at, op); 2031 object *tmp = present_arch_in_ob (at, op);
2069 2032
2070 if (tmp == NULL) 2033 if (tmp == NULL)
2071 { 2034 {
2072 if ((tmp = arch_to_object (at)) == NULL) 2035 if ((tmp = arch_to_object (at)) == NULL)
2118} 2081}
2119 2082
2120void 2083void
2121slow_player (object *op, object *hitter, int dam) 2084slow_player (object *op, object *hitter, int dam)
2122{ 2085{
2123 archetype *at = find_archetype ("slowness"); 2086 archetype *at = archetype::find ("slowness");
2124 object *tmp; 2087 object *tmp;
2125 2088
2126 if (at == NULL) 2089 if (at == NULL)
2127 { 2090 {
2128 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