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.27 by root, Wed Dec 13 03:28:42 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>
78 esrv_send_item (op->env, op); 72 esrv_send_item (op->env, op);
79 } 73 }
80 } 74 }
81} 75}
82 76
83
84
85/* did_make_save_item just checks to make sure the item actually 77/* did_make_save_item just checks to make sure the item actually
86 * made its saving throw based on the tables. It does not take 78 * made its saving throw based on the tables. It does not take
87 * any further action (like destroying the item). 79 * any further action (like destroying the item).
88 */ 80 */
89
90int 81int
91did_make_save_item (object *op, int type, object *originator) 82did_make_save_item (object *op, int type, object *originator)
92{ 83{
93 int i, roll, saves = 0, attacks = 0, number; 84 int i, roll, saves = 0, attacks = 0, number;
94 materialtype_t *mt; 85 materialtype_t *mt;
95 86
96 if (op->materialname == NULL) 87 if (op->materialname == NULL)
97 { 88 {
98 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) 89 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next)
99 {
100 if (op->material & mt->material) 90 if (op->material & mt->material)
101 break; 91 break;
102 }
103 } 92 }
104 else 93 else
105 mt = name_to_material (op->materialname); 94 mt = name_to_material (op->materialname);
106 if (mt == NULL) 95 if (mt == NULL)
107 return TRUE; 96 return TRUE;
158{ 147{
159 if (!did_make_save_item (op, type, originator)) 148 if (!did_make_save_item (op, type, originator))
160 { 149 {
161 object *env = op->env; 150 object *env = op->env;
162 int x = op->x, y = op->y; 151 int x = op->x, y = op->y;
163 mapstruct *m = op->map; 152 maptile *m = op->map;
164 153
165 op = stop_item (op); 154 op = stop_item (op);
166 if (op == NULL) 155 if (op == NULL)
167 return; 156 return;
168 157
224 213
225 if (tmp) 214 if (tmp)
226 esrv_del_item (tmp->contr, op->count); 215 esrv_del_item (tmp->contr, op->count);
227 } 216 }
228 217
229 if (!QUERY_FLAG (op, FLAG_REMOVED)) 218 op->destroy ();
230 remove_ob (op);
231
232 free_object (op);
233 } 219 }
234 220
235 if (type & (AT_FIRE | AT_ELECTRICITY)) 221 if (type & (AT_FIRE | AT_ELECTRICITY))
236 if (env) 222 if (env)
237 { 223 {
247 233
248 /* The value of 50 is arbitrary. */ 234 /* The value of 50 is arbitrary. */
249 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2)) 235 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2))
250 { 236 {
251 object *tmp; 237 object *tmp;
252 archetype *at = find_archetype ("icecube"); 238 archetype *at = archetype::find ("icecube");
253 239
254 if (at == NULL) 240 if (at == NULL)
255 return; 241 return;
256 242
257 op = stop_item (op); 243 op = stop_item (op);
270 tmp->move_slow = 0; 256 tmp->move_slow = 0;
271 insert_ob_in_map (tmp, op->map, originator, 0); 257 insert_ob_in_map (tmp, op->map, originator, 0);
272 } 258 }
273 259
274 if (!QUERY_FLAG (op, FLAG_REMOVED)) 260 if (!QUERY_FLAG (op, FLAG_REMOVED))
275 remove_ob (op); 261 op->remove ();
276 262
277 insert_ob_in_ob (op, tmp); 263 insert_ob_in_ob (op, tmp);
278 return; 264 return;
279 } 265 }
280} 266}
288 274
289int 275int
290hit_map (object *op, int dir, int type, int full_hit) 276hit_map (object *op, int dir, int type, int full_hit)
291{ 277{
292 object *tmp, *next; 278 object *tmp, *next;
293 mapstruct *map; 279 maptile *map;
294 sint16 x, y; 280 sint16 x, y;
295 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 281 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
296 282
297 tag_t op_tag, next_tag = 0;
298
299 if (QUERY_FLAG (op, FLAG_FREED)) 283 if (QUERY_FLAG (op, FLAG_FREED))
300 { 284 {
301 LOG (llevError, "BUG: hit_map(): free object\n"); 285 LOG (llevError, "BUG: hit_map(): free object\n");
302 return 0; 286 return 0;
303 } 287 }
314 return 0; 298 return 0;
315 } 299 }
316 300
317 if (op->head) 301 if (op->head)
318 op = op->head; 302 op = op->head;
319
320 op_tag = op->count;
321 303
322 map = op->map; 304 map = op->map;
323 x = op->x + freearr_x[dir]; 305 x = op->x + freearr_x[dir];
324 y = op->y + freearr_y[dir]; 306 y = op->y + freearr_y[dir];
325 307
353 update_object (op, UP_OBJ_FACE); 335 update_object (op, UP_OBJ_FACE);
354 type &= ~AT_CHAOS; 336 type &= ~AT_CHAOS;
355 } 337 }
356 338
357 next = get_map_ob (map, x, y); 339 next = get_map_ob (map, x, y);
358 if (next)
359 next_tag = next->count;
360 340
361 while (next) 341 while (next)
362 { 342 {
363 if (was_destroyed (next, next_tag)) 343 if (next->destroyed ())
364 { 344 {
365 /* There may still be objects that were above 'next', but there is no 345 /* 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 346 * simple way to find out short of copying all object references and
367 * tags into a temporary array before we start processing the first 347 * tags into a temporary array before we start processing the first
368 * object. That's why we just abort. 348 * object. That's why we just abort.
376 } 356 }
377 357
378 tmp = next; 358 tmp = next;
379 next = tmp->above; 359 next = tmp->above;
380 360
381 if (next) 361 if (tmp->destroyed ())
382 next_tag = next->count;
383
384 if (QUERY_FLAG (tmp, FLAG_FREED))
385 { 362 {
386 LOG (llevError, "BUG: hit_map(): found freed object\n"); 363 LOG (llevError, "BUG: hit_map(): found freed object\n");
387 break; 364 break;
388 } 365 }
389 366
396 373
397 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 374 if (QUERY_FLAG (tmp, FLAG_ALIVE))
398 { 375 {
399 hit_player (tmp, op->stats.dam, op, type, full_hit); 376 hit_player (tmp, op->stats.dam, op, type, full_hit);
400 retflag |= 1; 377 retflag |= 1;
401 if (was_destroyed (op, op_tag)) 378 if (op->destroyed ())
402 break; 379 break;
403 } 380 }
404 381
405 /* Here we are potentially destroying an object. If the object has 382 /* 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 383 * NO_PASS set, it is also immune - you can't destroy walls. Note
410 * destroyed right now. 387 * destroyed right now.
411 */ 388 */
412 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 389 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
413 { 390 {
414 save_throw_object (tmp, type, op); 391 save_throw_object (tmp, type, op);
415 if (was_destroyed (op, op_tag)) 392 if (op->destroyed ())
416 break; 393 break;
417 } 394 }
418 } 395 }
419 396
420 return 0; 397 return 0;
423void 400void
424attack_message (int dam, int type, object *op, object *hitter) 401attack_message (int dam, int type, object *op, object *hitter)
425{ 402{
426 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 403 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
427 int i, found = 0; 404 int i, found = 0;
428 mapstruct *map; 405 maptile *map;
429 object *next, *tmp; 406 object *next, *tmp;
430 407
431 /* put in a few special messages for some of the common attacktypes 408 /* put in a few special messages for some of the common attacktypes
432 * a player might have. For example, fire, electric, cold, etc 409 * a player might have. For example, fire, electric, cold, etc
433 * [garbled 20010919] 410 * [garbled 20010919]
633 strcpy (buf1, "hit"); 610 strcpy (buf1, "hit");
634 strcpy (buf2, " hits"); 611 strcpy (buf2, " hits");
635 } 612 }
636 613
637 /* bail out if a monster is casting spells */ 614 /* bail out if a monster is casting spells */
638 if (!(hitter->type == PLAYER || (get_owner (hitter) != NULL && hitter->owner->type == PLAYER))) 615 if (!(hitter->type == PLAYER || (hitter->owner != NULL && hitter->owner->type == PLAYER)))
639 return; 616 return;
640 617
641 /* scale down magic considerably. */ 618 /* scale down magic considerably. */
642 if (type & AT_MAGIC && rndm (0, 5)) 619 if (type & AT_MAGIC && rndm (0, 5))
643 return; 620 return;
644 621
645 /* Did a player hurt another player? Inform both! */ 622 /* Did a player hurt another player? Inform both! */
646 if (op->type == PLAYER && (get_owner (hitter) == NULL ? hitter->type : hitter->owner->type) == PLAYER) 623 if (op->type == PLAYER && (hitter->owner == NULL ? hitter->type : hitter->owner->type) == PLAYER)
647 { 624 {
648 if (get_owner (hitter) != NULL) 625 if (hitter->owner != NULL)
649 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); 626 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2);
650 else 627 else
651 { 628 {
652 sprintf (buf, "%s%s you.", &hitter->name, buf2); 629 sprintf (buf, "%s%s you.", &hitter->name, buf2);
653 if (dam != 0) 630 if (dam != 0)
675 else 652 else
676 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); 653 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0);
677 } 654 }
678 new_draw_info (NDI_BLACK, 0, hitter, buf); 655 new_draw_info (NDI_BLACK, 0, hitter, buf);
679 } 656 }
680 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 657 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
681 { 658 {
682 /* look for stacked spells and start reducing the message chances */ 659 /* look for stacked spells and start reducing the message chances */
683 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE)) 660 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE))
684 { 661 {
685 i = 4; 662 i = 4;
760attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 737attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
761{ 738{
762 int simple_attack, roll, dam = 0; 739 int simple_attack, roll, dam = 0;
763 uint32 type; 740 uint32 type;
764 shstr op_name; 741 shstr op_name;
765 tag_t op_tag, hitter_tag;
766 742
767 if (get_attack_mode (&op, &hitter, &simple_attack)) 743 if (get_attack_mode (&op, &hitter, &simple_attack))
768 goto error; 744 goto error;
769 745
770 if (hitter->current_weapon) 746 if (hitter->current_weapon)
771 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 747 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
772 return RESULT_INT (0); 748 return RESULT_INT (0);
773 749
774 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 750 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
775 return RESULT_INT (0); 751 return RESULT_INT (0);
776
777 op_tag = op->count;
778 hitter_tag = hitter->count;
779 752
780 /* 753 /*
781 * A little check to make it more difficult to dance forward and back 754 * A little check to make it more difficult to dance forward and back
782 * to avoid ever being hit by monsters. 755 * to avoid ever being hit by monsters.
783 */ 756 */
788 * which then gets here again. By decreasing the speed before 761 * which then gets here again. By decreasing the speed before
789 * we call process_object, the 'if' statement above will fail. 762 * we call process_object, the 'if' statement above will fail.
790 */ 763 */
791 op->speed_left--; 764 op->speed_left--;
792 process_object (op); 765 process_object (op);
766
793 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 767 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
794 goto error; 768 goto error;
795 } 769 }
796 770
797 op_name = op->name; 771 op_name = op->name;
798 772
832 if (QUERY_FLAG (op, FLAG_SLEEP)) 806 if (QUERY_FLAG (op, FLAG_SLEEP))
833 CLEAR_FLAG (op, FLAG_SLEEP); 807 CLEAR_FLAG (op, FLAG_SLEEP);
834 808
835 /* If the victim can't see the attacker, it may alert others 809 /* If the victim can't see the attacker, it may alert others
836 * for help. */ 810 * for help. */
837 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !get_owner (op) && rndm (0, op->stats.Int)) 811 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !op->owner && rndm (0, op->stats.Int))
838 npc_call_help (op); 812 npc_call_help (op);
839 813
840 /* if you were hidden and hit by a creature, you are discovered */ 814 /* if you were hidden and hit by a creature, you are discovered */
841 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) 815 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE))
842 { 816 {
849 * when they hit the victim. For things like thrown daggers, 823 * when they hit the victim. For things like thrown daggers,
850 * this sets 'hitter' to the actual dagger, and not the 824 * this sets 'hitter' to the actual dagger, and not the
851 * wrapper object. 825 * wrapper object.
852 */ 826 */
853 thrown_item_effect (hitter, op); 827 thrown_item_effect (hitter, op);
828
854 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 829 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
855 goto leave; 830 goto leave;
856 } 831 }
857 832
858 /* Need to do at least 1 damage, otherwise there is no point 833 /* Need to do at least 1 damage, otherwise there is no point
859 * to go further and it will cause FPE's below. 834 * to go further and it will cause FPE's below.
860 */ 835 */
861 if (hitdam <= 0) 836 if (hitdam <= 0)
862 hitdam = 1; 837 hitdam = 1;
863 838
864 type = hitter->attacktype; 839 type = hitter->attacktype;
840
865 if (!type) 841 if (!type)
866 type = AT_PHYSICAL; 842 type = AT_PHYSICAL;
843
867 /* Handle monsters that hit back */ 844 /* Handle monsters that hit back */
868 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 845 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
869 { 846 {
870 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 847 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
871 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 848 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
849
872 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 850 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
851
873 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 852 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
874 goto leave; 853 goto leave;
875 } 854 }
876 855
877 /* In the new attack code, it should handle multiple attack 856 /* In the new attack code, it should handle multiple attack
878 * types in its area, so remove it from here. 857 * types in its area, so remove it from here.
879 */ 858 */
880 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 859 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
860
881 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 861 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
882 goto leave; 862 goto leave;
883 } /* end of if hitter hit op */ 863 } /* end of if hitter hit op */
884 /* if we missed, dam=0 */ 864 /* if we missed, dam=0 */
885 865
886 /*attack_message(dam, type, op, hitter); */ 866 /*attack_message(dam, type, op, hitter); */
920 if (op->weight <= 5000 && tmp->stats.hp >= 0) 900 if (op->weight <= 5000 && tmp->stats.hp >= 0)
921 { 901 {
922 if (tmp->head != NULL) 902 if (tmp->head != NULL)
923 tmp = tmp->head; 903 tmp = tmp->head;
924 904
925 remove_ob (op); 905 op->remove ();
926 op = insert_ob_in_ob (op, tmp); 906 op = insert_ob_in_ob (op, tmp);
927 907
928 if (tmp->type == PLAYER) 908 if (tmp->type == PLAYER)
929 esrv_send_item (tmp, op); 909 esrv_send_item (tmp, op);
930 910
943object * 923object *
944hit_with_arrow (object *op, object *victim) 924hit_with_arrow (object *op, object *victim)
945{ 925{
946 object *container, *hitter; 926 object *container, *hitter;
947 int hit_something = 0; 927 int hit_something = 0;
948 tag_t victim_tag, hitter_tag;
949 sint16 victim_x, victim_y;
950 928
951 /* Disassemble missile */ 929 /* Disassemble missile */
952 if (op->inv) 930 if (op->inv)
953 { 931 {
954 container = op; 932 container = op;
955 hitter = op->inv; 933 hitter = op->inv;
956 remove_ob (hitter); 934 hitter->remove ();
957 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); 935 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON);
958 /* Note that we now have an empty THROWN_OBJ on the map. Code that 936 /* Note that we now have an empty THROWN_OBJ on the map. Code that
959 * might be called until this THROWN_OBJ is either reassembled or 937 * might be called until this THROWN_OBJ is either reassembled or
960 * removed at the end of this function must be able to deal with empty 938 * removed at the end of this function must be able to deal with empty
961 * THROWN_OBJs. */ 939 * THROWN_OBJs. */
962 } 940 }
963 else 941 else
964 { 942 {
965 container = NULL; 943 container = 0;
966 hitter = op; 944 hitter = op;
967 } 945 }
968 946
969 /* Try to hit victim */ 947 /* 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); 948 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
976 949
977 /* Arrow attacks door, rune of summoning is triggered, demon is put on 950 /* Arrow attacks door, rune of summoning is triggered, demon is put on
978 * arrow, move_apply() calls this function, arrow sticks in demon, 951 * arrow, move_apply() calls this function, arrow sticks in demon,
979 * attack_ob_simple() returns, and we've got an arrow that still exists 952 * 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 953 * but is no longer on the map. Ugh. (Beware: Such things can happen at
981 * other places as well!) 954 * other places as well!)
982 */ 955 */
983 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 956 if (hitter->destroyed () || hitter->env != NULL)
984 { 957 {
985 if (container) 958 if (container)
986 { 959 {
987 remove_ob (container); 960 container->remove ();
988 free_object (container); 961 container->destroy ();
989 } 962 }
963
990 return NULL; 964 return 0;
991 } 965 }
992 966
993 /* Missile hit victim */ 967 /* Missile hit victim */
994 /* if the speed is > 10, then this is a fast moving arrow, we go straight 968 /* if the speed is > 10, then this is a fast moving arrow, we go straight
995 * through the target 969 * through the target
996 */ 970 */
997 if (hit_something && op->speed <= 10.0) 971 if (hit_something && op->speed <= 10.0)
998 { 972 {
999 /* Stop arrow */ 973 /* Stop arrow */
1000 if (container == NULL) 974 if (!container)
1001 { 975 {
1002 hitter = fix_stopped_arrow (hitter); 976 hitter = fix_stopped_arrow (hitter);
1003 if (hitter == NULL) 977 if (!hitter)
1004 return NULL; 978 return 0;
1005 } 979 }
1006 else 980 else
1007 { 981 container->destroy ();
1008 remove_ob (container);
1009 free_object (container);
1010 }
1011 982
1012 /* Try to stick arrow into victim */ 983 /* Try to stick arrow into victim */
1013 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 984 if (!victim->destroyed () && stick_arrow (hitter, victim))
1014 return NULL; 985 return 0;
1015 986
1016 /* Else try to put arrow on victim's map square 987 /* Else try to put arrow on victim's map square
1017 * remove check for P_WALL here. If the arrow got to this 988 * remove check for P_WALL here. If the arrow got to this
1018 * space, that is good enough - with the new movement code, 989 * space, that is good enough - with the new movement code,
1019 * there is now the potential for lots of spaces where something 990 * there is now the potential for lots of spaces where something
1020 * can fly over but not otherwise move over. What is the correct 991 * can fly over but not otherwise move over. What is the correct
1021 * way to handle those otherwise? 992 * way to handle those otherwise?
1022 */ 993 */
1023 if (victim_x != hitter->x || victim_y != hitter->y) 994 if (victim->x != hitter->x || victim->y != hitter->y)
1024 { 995 {
1025 remove_ob (hitter); 996 hitter->remove ();
1026 hitter->x = victim_x; 997 hitter->x = victim->x;
1027 hitter->y = victim_y; 998 hitter->y = victim->y;
1028 insert_ob_in_map (hitter, victim->map, hitter, 0); 999 insert_ob_in_map (hitter, victim->map, hitter, 0);
1029 } 1000 }
1030 else 1001 else
1031 {
1032 /* Else leave arrow where it is */ 1002 /* Else leave arrow where it is */
1033 merge_ob (hitter, NULL); 1003 merge_ob (hitter, NULL);
1034 } 1004
1035 return NULL; 1005 return 0;
1036 } 1006 }
1037 1007
1038 if (hit_something && op->speed >= 10.0) 1008 if (hit_something && op->speed >= 10.0)
1039 op->speed -= 1.0; 1009 op->speed -= 1.0;
1040 1010
1041 /* Missile missed victim - reassemble missile */ 1011 /* Missile missed victim - reassemble missile */
1042 if (container) 1012 if (container)
1043 { 1013 {
1044 remove_ob (hitter); 1014 hitter->remove ();
1045 insert_ob_in_ob (hitter, container); 1015 insert_ob_in_ob (hitter, container);
1046 } 1016 }
1017
1047 return op; 1018 return op;
1048} 1019}
1049 1020
1050 1021
1051void 1022void
1060 } 1031 }
1061 else if (!GET_ANIM_ID (op)) 1032 else if (!GET_ANIM_ID (op))
1062 { 1033 {
1063 /* Object has been called - no animations, so remove it */ 1034 /* Object has been called - no animations, so remove it */
1064 if (op->stats.hp < 0) 1035 if (op->stats.hp < 0)
1036 op->destroy ();
1065 { 1037
1066 remove_ob (op); /* Should update LOS */
1067 free_object (op);
1068 /* Don't know why this is here - remove_ob should do it for us */
1069 /*update_position(m, x, y); */
1070 }
1071 return; /* no animations, so nothing more to do */ 1038 return; /* no animations, so nothing more to do */
1072 } 1039 }
1040
1073 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1041 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp;
1042
1074 if (perc >= (int) NUM_ANIMATIONS (op)) 1043 if (perc >= (int) NUM_ANIMATIONS (op))
1075 perc = NUM_ANIMATIONS (op) - 1; 1044 perc = NUM_ANIMATIONS (op) - 1;
1076 else if (perc < 1) 1045 else if (perc < 1)
1077 perc = 1; 1046 perc = 1;
1047
1078 SET_ANIMATION (op, perc); 1048 SET_ANIMATION (op, perc);
1079 update_object (op, UP_OBJ_FACE); 1049 update_object (op, UP_OBJ_FACE);
1050
1080 if (perc == NUM_ANIMATIONS (op) - 1) 1051 if (perc == NUM_ANIMATIONS (op) - 1)
1081 { /* Reached the last animation */ 1052 { /* Reached the last animation */
1082 if (op->face == blank_face) 1053 if (op->face == blank_face)
1083 {
1084 /* If the last face is blank, remove the ob */ 1054 /* If the last face is blank, remove the ob */
1085 remove_ob (op); /* Should update LOS */ 1055 op->destroy ();
1086 free_object (op);
1087
1088 /* remove_ob should call update_position for us */
1089 /*update_position(m, x, y); */
1090
1091 }
1092 else 1056 else
1093 { /* The last face was not blank, leave an image */ 1057 { /* The last face was not blank, leave an image */
1094 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1058 CLEAR_FLAG (op, FLAG_BLOCKSVIEW);
1095 update_all_los (op->map, op->x, op->y); 1059 update_all_los (op->map, op->x, op->y);
1096 op->move_block = 0; 1060 op->move_block = 0;
1100} 1064}
1101 1065
1102void 1066void
1103scare_creature (object *target, object *hitter) 1067scare_creature (object *target, object *hitter)
1104{ 1068{
1105 object *owner = get_owner (hitter); 1069 object *owner = hitter->owner;
1106 1070
1107 if (!owner) 1071 if (!owner)
1108 owner = hitter; 1072 owner = hitter;
1109 1073
1110 SET_FLAG (target, FLAG_SCARED); 1074 SET_FLAG (target, FLAG_SCARED);
1314 * Try to credit the owner. We try to display player -> player drain 1278 * Try to credit the owner. We try to display player -> player drain
1315 * attacks, hence all the != PLAYER checks. 1279 * attacks, hence all the != PLAYER checks.
1316 */ 1280 */
1317 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1281 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1318 { 1282 {
1319 object *owner = get_owner (hitter); 1283 object *owner = hitter->owner;
1320 1284
1321 if (owner && owner != hitter) 1285 if (owner && owner != hitter)
1322 { 1286 {
1323 if (op->type != PLAYER || owner->type != PLAYER) 1287 if (op->type != PLAYER || owner->type != PLAYER)
1324 change_exp (owner, op->stats.exp / (rate * 2), 1288 change_exp (owner, op->stats.exp / (rate * 2),
1466 op->speed = 0.1; 1430 op->speed = 0.1;
1467 update_ob_speed (op); 1431 update_ob_speed (op);
1468 op->speed_left = -0.05; 1432 op->speed_left = -0.05;
1469 return maxdam; 1433 return maxdam;
1470 } 1434 }
1435
1471 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1436 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1472 { 1437 {
1473 remove_friendly_object (op); 1438 remove_friendly_object (op);
1439
1474 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1440 if (op->owner && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1475 {
1476 op->owner->contr->ranges[range_golem] = NULL; 1441 op->owner->contr->ranges[range_golem] = 0;
1477 op->owner->contr->golem_count = 0;
1478 }
1479 1442
1480 remove_ob (op); 1443 op->destroy ();
1481 free_object (op);
1482 return maxdam; 1444 return maxdam;
1483 } 1445 }
1484 1446
1485 /* Now lets start dealing with experience we get for killing something */ 1447 /* Now lets start dealing with experience we get for killing something */
1486 1448
1487 owner = get_owner (hitter); 1449 owner = hitter->owner;
1488 if (owner == NULL) 1450 if (!owner)
1489 owner = hitter; 1451 owner = hitter;
1490 1452
1491 /* is the victim (op) standing on battleground? */ 1453 /* is the victim (op) standing on battleground? */
1492 if (op_on_battleground (op, NULL, NULL)) 1454 if (op_on_battleground (op, NULL, NULL))
1493 battleg = 1; 1455 battleg = 1;
1523 * probably don't want to see that. 1485 * probably don't want to see that.
1524 */ 1486 */
1525 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1487 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1526 { 1488 {
1527 if (owner != hitter) 1489 if (owner != hitter)
1528 {
1529 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1490 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1530 }
1531 else 1491 else
1532 {
1533 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1492 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1534 } 1493
1535 /* Only play sounds for melee kills */ 1494 /* Only play sounds for melee kills */
1536 if (hitter->type == PLAYER) 1495 if (hitter->type == PLAYER)
1537 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1496 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1538 } 1497 }
1539 1498
1550 1509
1551 /* This code below deals with finding the appropriate skill 1510 /* This code below deals with finding the appropriate skill
1552 * to credit exp to. This is a bit problematic - we should 1511 * to credit exp to. This is a bit problematic - we should
1553 * probably never really have to look at current_weapon->skill 1512 * probably never really have to look at current_weapon->skill
1554 */ 1513 */
1555 skill = NULL; 1514 skill = 0;
1515
1556 if (hitter->skill && hitter->type != PLAYER) 1516 if (hitter->skill && hitter->type != PLAYER)
1557 skill = hitter->skill; 1517 skill = hitter->skill;
1558 else if (owner->chosen_skill) 1518 else if (owner->chosen_skill)
1559 { 1519 {
1560 skill = owner->chosen_skill->skill; 1520 skill = owner->chosen_skill->skill;
1579 break; 1539 break;
1580 } 1540 }
1581 } 1541 }
1582 } /* Was it a player that hit somethign */ 1542 } /* Was it a player that hit somethign */
1583 else 1543 else
1584 {
1585 skill = NULL; 1544 skill = 0;
1586 }
1587 1545
1588 /* Pet (or spell) killed something. */ 1546 /* Pet (or spell) killed something. */
1589 if (owner != hitter) 1547 if (owner != hitter)
1590 {
1591 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1548 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1592 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1549 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1593 }
1594 else 1550 else
1595 {
1596 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1551 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1597 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1552 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1598 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1553 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1599 } 1554
1600 /* These may have been set in the player code section above */ 1555 /* These may have been set in the player code section above */
1601 if (!skop) 1556 if (!skop)
1602 skop = hitter->chosen_skill; 1557 skop = hitter->chosen_skill;
1558
1603 if (!skill && skop) 1559 if (!skill && skop)
1604 skill = skop->skill; 1560 skill = skop->skill;
1605 1561
1606 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1562 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1607 1563
1608
1609 /* If you didn't kill yourself, and your not the wizard */ 1564 /* If you didn't kill yourself, and your not the wizard */
1610 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1565 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1611 { 1566 {
1612 int exp; 1567 int exp;
1613 1568
1614 /* Really don't give much experience for killing other players */ 1569 /* Really don't give much experience for killing other players */
1615 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1570 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1616 if (op->type == PLAYER) 1571 if (op->type == PLAYER)
1617 { 1572 {
1618 if (battleg) 1573 if (battleg)
1619 { 1574 {
1620 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1575 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1638 1593
1639 if (!settings.simple_exp) 1594 if (!settings.simple_exp)
1640 exp = exp / 2; 1595 exp = exp / 2;
1641 1596
1642 if (owner->type != PLAYER || owner->contr->party == NULL) 1597 if (owner->type != PLAYER || owner->contr->party == NULL)
1643 {
1644 change_exp (owner, exp, skill, 0); 1598 change_exp (owner, exp, skill, 0);
1645 }
1646 else 1599 else
1647 { 1600 {
1648 int shares = 0, count = 0; 1601 int shares = 0, count = 0;
1649
1650 player *pl; 1602 player *pl;
1651
1652 partylist *party = owner->contr->party; 1603 partylist *party = owner->contr->party;
1653 1604
1654#ifdef PARTY_KILL_LOG 1605#ifdef PARTY_KILL_LOG
1655 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1606 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1656#endif 1607#endif
1657 for (pl = first_player; pl != NULL; pl = pl->next) 1608 for (pl = first_player; pl != NULL; pl = pl->next)
1658 {
1659 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1609 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1660 { 1610 {
1661 count++; 1611 count++;
1662 shares += (pl->ob->level + 4); 1612 shares += (pl->ob->level + 4);
1663 } 1613 }
1664 } 1614
1665 if (count == 1 || shares > exp) 1615 if (count == 1 || shares > exp || !shares)
1666 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1616 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1667 else 1617 else
1668 { 1618 {
1669 int share = exp / shares, given = 0, nexp; 1619 int share = exp / shares, given = 0, nexp;
1670 1620
1671 for (pl = first_player; pl != NULL; pl = pl->next) 1621 for (pl = first_player; pl != NULL; pl = pl->next)
1672 {
1673 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1622 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1674 { 1623 {
1675 nexp = (pl->ob->level + 4) * share; 1624 nexp = (pl->ob->level + 4) * share;
1676 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1625 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1677 given += nexp; 1626 given += nexp;
1678 } 1627 }
1679 } 1628
1680 exp -= given; 1629 exp -= given;
1681 /* give any remainder to the player */ 1630 /* give any remainder to the player */
1682 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1631 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1683 } 1632 }
1684 } /* else part of a party */ 1633 } /* else part of a party */
1685
1686 } /* end if person didn't kill himself */ 1634 } /* end if person didn't kill himself */
1687 1635
1688 if (op->type != PLAYER) 1636 if (op->type != PLAYER)
1689 { 1637 {
1690 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1638 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1691 { 1639 {
1692 object *owner1 = get_owner (op); 1640 object *owner1 = op->owner;
1693 1641
1694 if (owner1 != NULL && owner1->type == PLAYER) 1642 if (owner1 && owner1->type == PLAYER)
1695 { 1643 {
1696 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1644 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1697 /* Maybe we should include the owner that killed this, maybe not */ 1645 /* 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); 1646 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1699 } 1647 }
1700 1648
1701 remove_friendly_object (op); 1649 remove_friendly_object (op);
1702 } 1650 }
1703 1651
1704 remove_ob (op); 1652 op->destroy ();
1705 free_object (op);
1706 } 1653 }
1707 /* Player has been killed! */
1708 else 1654 else
1709 { 1655 {
1656 /* Player has been killed! */
1710 if (owner->type == PLAYER) 1657 if (owner->type == PLAYER)
1711 {
1712 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1658 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1713 }
1714 else 1659 else
1715 assign (op->contr->killer, hitter->name); 1660 assign (op->contr->killer, hitter->name);
1716 } 1661 }
1717 1662
1718 /* This was return -1 - that doesn't seem correct - if we return -1, process 1663 /* This was return -1 - that doesn't seem correct - if we return -1, process
1742 return 0; 1687 return 0;
1743 1688
1744 if (hitter->type == PLAYER && hitter->contr->peaceful == 1) 1689 if (hitter->type == PLAYER && hitter->contr->peaceful == 1)
1745 return 1; 1690 return 1;
1746 1691
1747 if ((owner = get_owner (hitter)) != NULL) 1692 if ((owner = hitter->owner) != NULL)
1748 { 1693 {
1749 if (owner->type == PLAYER && owner->contr->peaceful == 1) 1694 if (owner->type == PLAYER && owner->contr->peaceful == 1)
1750 friendlyfire = 2; 1695 friendlyfire = 2;
1751 } 1696 }
1752 1697
1773{ 1718{
1774 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1719 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1775 int maxattacktype, attacknum; 1720 int maxattacktype, attacknum;
1776 int body_attack = op && op->head; /* Did we hit op's head? */ 1721 int body_attack = op && op->head; /* Did we hit op's head? */
1777 int simple_attack; 1722 int simple_attack;
1778 tag_t op_tag, hitter_tag;
1779 int rtn_kill = 0; 1723 int rtn_kill = 0;
1780 int friendlyfire; 1724 int friendlyfire;
1781 1725
1782 if (get_attack_mode (&op, &hitter, &simple_attack)) 1726 if (get_attack_mode (&op, &hitter, &simple_attack))
1783 return 0; 1727 return 0;
1787 return 0; 1731 return 0;
1788 1732
1789#ifdef PROHIBIT_PLAYERKILL 1733#ifdef PROHIBIT_PLAYERKILL
1790 if (op->type == PLAYER) 1734 if (op->type == PLAYER)
1791 { 1735 {
1792 object *owner = get_owner (hitter); 1736 object *owner = hitter->owner;
1793 1737
1794 if (!owner) 1738 if (!owner)
1795 owner = hitter; 1739 owner = hitter;
1740
1796 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1741 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1797 {
1798 return 0; 1742 return 0;
1799 }
1800 } 1743 }
1801#endif 1744#endif
1802
1803 op_tag = op->count;
1804 hitter_tag = hitter->count;
1805 1745
1806 if (body_attack) 1746 if (body_attack)
1807 { 1747 {
1808 /* slow and paralyze must hit the head. But we don't want to just 1748 /* 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 1749 * return - we still need to process other attacks the spell still
1815 * attack so we don't cancel out things like magic bullet. 1755 * attack so we don't cancel out things like magic bullet.
1816 */ 1756 */
1817 if (type & (AT_PARALYZE | AT_SLOW)) 1757 if (type & (AT_PARALYZE | AT_SLOW))
1818 { 1758 {
1819 type &= ~(AT_PARALYZE | AT_SLOW); 1759 type &= ~(AT_PARALYZE | AT_SLOW);
1760
1820 if (!type || type == AT_MAGIC) 1761 if (!type || type == AT_MAGIC)
1821 return 0; 1762 return 0;
1822 } 1763 }
1823 } 1764 }
1824 1765
1828 1769
1829 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1770 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1830 if (tmp->type == RUNE || tmp->type == TRAP) 1771 if (tmp->type == RUNE || tmp->type == TRAP)
1831 { 1772 {
1832 spring_trap (tmp, hitter); 1773 spring_trap (tmp, hitter);
1774
1833 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1775 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1834 return 0; 1776 return 0;
1777
1835 break; 1778 break;
1836 } 1779 }
1837 } 1780 }
1838 1781
1839 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1782 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1840 { 1783 {
1841 /* FIXME: If a player is killed by a rune in a door, the 1784 /* 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. 1785 * destroyed() check above doesn't return, and might get here.
1843 */ 1786 */
1844 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1787 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1845 return 0; 1788 return 0;
1846 } 1789 }
1847 1790
1956 1899
1957#ifdef ATTACK_DEBUG 1900#ifdef ATTACK_DEBUG
1958 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); 1901 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam);
1959#endif 1902#endif
1960 1903
1961 if (get_owner (hitter)) 1904 if (hitter->owner)
1962 op->enemy = hitter->owner; 1905 op->enemy = hitter->owner;
1963 else if (QUERY_FLAG (hitter, FLAG_ALIVE)) 1906 else if (QUERY_FLAG (hitter, FLAG_ALIVE))
1964 op->enemy = hitter; 1907 op->enemy = hitter;
1965 1908
1966 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) 1909 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER)
1991 1934
1992 if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) 1935 if (QUERY_FLAG (op, FLAG_TEAR_DOWN))
1993 { 1936 {
1994 if (maxdam) 1937 if (maxdam)
1995 tear_down_wall (op); 1938 tear_down_wall (op);
1939
1996 return maxdam; /* nothing more to do for wall */ 1940 return maxdam; /* nothing more to do for wall */
1997 } 1941 }
1998 1942
1999 /* See if the creature has been killed */ 1943 /* See if the creature has been killed */
2000 rtn_kill = kill_object (op, maxdam, hitter, type); 1944 rtn_kill = kill_object (op, maxdam, hitter, type);
2008 */ 1952 */
2009 if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) 1953 if (QUERY_FLAG (hitter, FLAG_ONE_HIT))
2010 { 1954 {
2011 if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) 1955 if (QUERY_FLAG (hitter, FLAG_FRIENDLY))
2012 remove_friendly_object (hitter); 1956 remove_friendly_object (hitter);
2013 remove_ob (hitter); 1957
2014 free_object (hitter); 1958 hitter->destroy ();
2015 } 1959 }
2016 /* Lets handle creatures that are splitting now */ 1960 /* Lets handle creatures that are splitting now */
2017 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) 1961 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING))
2018 { 1962 {
2019 int i; 1963 int i;
2020 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); 1964 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY);
2021 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); 1965 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE);
2022 object *owner = get_owner (op); 1966 object *owner = op->owner;
2023 1967
2024 if (!op->other_arch) 1968 if (!op->other_arch)
2025 { 1969 {
2026 LOG (llevError, "SPLITTING without other_arch error.\n"); 1970 LOG (llevError, "SPLITTING without other_arch error.\n");
2027 return maxdam; 1971 return maxdam;
2028 } 1972 }
1973
2029 remove_ob (op); 1974 op->remove ();
1975
2030 for (i = 0; i < NROFNEWOBJS (op); i++) 1976 for (i = 0; i < NROFNEWOBJS (op); i++)
2031 { /* This doesn't handle op->more yet */ 1977 { /* This doesn't handle op->more yet */
2032 object *tmp = arch_to_object (op->other_arch); 1978 object *tmp = arch_to_object (op->other_arch);
2033 int j; 1979 int j;
2034 1980
2035 tmp->stats.hp = op->stats.hp; 1981 tmp->stats.hp = op->stats.hp;
1982
2036 if (friendly) 1983 if (friendly)
2037 { 1984 {
2038 SET_FLAG (tmp, FLAG_FRIENDLY); 1985 SET_FLAG (tmp, FLAG_FRIENDLY);
2039 add_friendly_object (tmp); 1986 add_friendly_object (tmp);
2040 tmp->attack_movement = PETMOVE; 1987 tmp->attack_movement = PETMOVE;
2041 if (owner != NULL) 1988 if (owner != NULL)
2042 set_owner (tmp, owner); 1989 tmp->set_owner (owner);
2043 } 1990 }
1991
2044 if (unaggressive) 1992 if (unaggressive)
2045 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 1993 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
1994
2046 j = find_first_free_spot (tmp, op->map, op->x, op->y); 1995 j = find_first_free_spot (tmp, op->map, op->x, op->y);
1996
2047 if (j == -1) /* No spot to put this monster */ 1997 if (j == -1) /* No spot to put this monster */
2048 free_object (tmp); 1998 tmp->destroy ();
2049 else 1999 else
2050 { 2000 {
2051 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 2001 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j];
2052 insert_ob_in_map (tmp, op->map, NULL, 0); 2002 insert_ob_in_map (tmp, op->map, NULL, 0);
2053 } 2003 }
2054 } 2004 }
2055 if (friendly) 2005
2056 remove_friendly_object (op); 2006 op->destroy ();
2057 free_object (op);
2058 } 2007 }
2059 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) 2008 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10)
2060 { 2009 hitter->destroy ();
2061 remove_ob (hitter); 2010
2062 free_object (hitter);
2063 }
2064 return maxdam; 2011 return maxdam;
2065} 2012}
2066 2013
2067 2014
2068void 2015void
2069poison_player (object *op, object *hitter, int dam) 2016poison_player (object *op, object *hitter, int dam)
2070{ 2017{
2071 archetype *at = find_archetype ("poisoning"); 2018 archetype *at = archetype::find ("poisoning");
2072 object *tmp = present_arch_in_ob (at, op); 2019 object *tmp = present_arch_in_ob (at, op);
2073 2020
2074 if (tmp == NULL) 2021 if (tmp == NULL)
2075 { 2022 {
2076 if ((tmp = arch_to_object (at)) == NULL) 2023 if ((tmp = arch_to_object (at)) == NULL)
2089 if (QUERY_FLAG (hitter, FLAG_ALIVE)) 2036 if (QUERY_FLAG (hitter, FLAG_ALIVE))
2090 tmp->stats.dam += hitter->level / 2; 2037 tmp->stats.dam += hitter->level / 2;
2091 else 2038 else
2092 tmp->stats.dam = dam; 2039 tmp->stats.dam = dam;
2093 2040
2094 copy_owner (tmp, hitter); /* so we get credit for poisoning kills */ 2041 tmp->set_owner (hitter); /* so we get credit for poisoning kills */
2095 if (hitter->skill && hitter->skill != tmp->skill) 2042 if (hitter->skill && hitter->skill != tmp->skill)
2096 { 2043 {
2097 tmp->skill = hitter->skill; 2044 tmp->skill = hitter->skill;
2098 } 2045 }
2099 2046
2110 fix_player (op); 2057 fix_player (op);
2111 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); 2058 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill.");
2112 } 2059 }
2113 if (hitter->type == PLAYER) 2060 if (hitter->type == PLAYER)
2114 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); 2061 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name);
2115 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 2062 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
2116 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name); 2063 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name);
2117 } 2064 }
2118 tmp->speed_left = 0; 2065 tmp->speed_left = 0;
2119 } 2066 }
2120 else 2067 else
2122} 2069}
2123 2070
2124void 2071void
2125slow_player (object *op, object *hitter, int dam) 2072slow_player (object *op, object *hitter, int dam)
2126{ 2073{
2127 archetype *at = find_archetype ("slowness"); 2074 archetype *at = archetype::find ("slowness");
2128 object *tmp; 2075 object *tmp;
2129 2076
2130 if (at == NULL) 2077 if (at == NULL)
2131 { 2078 {
2132 LOG (llevError, "Can't find slowness archetype.\n"); 2079 LOG (llevError, "Can't find slowness archetype.\n");
2196 tmp = insert_ob_in_ob (tmp, op); 2143 tmp = insert_ob_in_ob (tmp, op);
2197 change_abil (op, tmp); /* Mostly to display any messages */ 2144 change_abil (op, tmp); /* Mostly to display any messages */
2198 fix_player (op); /* This takes care of some other stuff */ 2145 fix_player (op); /* This takes care of some other stuff */
2199 2146
2200 if (hitter->owner) 2147 if (hitter->owner)
2201 owner = get_owner (hitter); 2148 owner = hitter->owner;
2202 else 2149 else
2203 owner = hitter; 2150 owner = hitter;
2204 2151
2205 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); 2152 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op));
2206 } 2153 }
2352 } 2299 }
2353 2300
2354 /* aimed missiles use the owning object's sight */ 2301 /* aimed missiles use the owning object's sight */
2355 if (is_aimed_missile (hitter)) 2302 if (is_aimed_missile (hitter))
2356 { 2303 {
2357 if ((attacker = get_owner (hitter)) == NULL) 2304 if ((attacker = hitter->owner) == NULL)
2358 attacker = hitter; 2305 attacker = hitter;
2359 /* A player who saves but hasn't quit still could have objects 2306 /* A player who saves but hasn't quit still could have objects
2360 * owned by him - need to handle that case to avoid crashes. 2307 * owned by him - need to handle that case to avoid crashes.
2361 */ 2308 */
2362 if (QUERY_FLAG (attacker, FLAG_REMOVED)) 2309 if (QUERY_FLAG (attacker, FLAG_REMOVED))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines