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.39 by root, Mon Jan 8 01:19:03 2007 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
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
12 7
13 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
22 17
23 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 21
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 22 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 23*/
29#include <assert.h> 24#include <assert.h>
30#include <global.h> 25#include <global.h>
31#include <living.h> 26#include <living.h>
32#include <material.h> 27#include <material.h>
78 esrv_send_item (op->env, op); 73 esrv_send_item (op->env, op);
79 } 74 }
80 } 75 }
81} 76}
82 77
83
84
85/* did_make_save_item just checks to make sure the item actually 78/* 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 79 * made its saving throw based on the tables. It does not take
87 * any further action (like destroying the item). 80 * any further action (like destroying the item).
88 */ 81 */
89
90int 82int
91did_make_save_item (object *op, int type, object *originator) 83did_make_save_item (object *op, int type, object *originator)
92{ 84{
93 int i, roll, saves = 0, attacks = 0, number; 85 int i, roll, saves = 0, attacks = 0, number;
94 materialtype_t *mt; 86 materialtype_t *mt;
95 87
96 if (op->materialname == NULL) 88 if (op->materialname == NULL)
97 { 89 {
98 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) 90 for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next)
99 {
100 if (op->material & mt->material) 91 if (op->material & mt->material)
101 break; 92 break;
102 }
103 } 93 }
104 else 94 else
105 mt = name_to_material (op->materialname); 95 mt = name_to_material (op->materialname);
106 if (mt == NULL) 96 if (mt == NULL)
107 return TRUE; 97 return TRUE;
158{ 148{
159 if (!did_make_save_item (op, type, originator)) 149 if (!did_make_save_item (op, type, originator))
160 { 150 {
161 object *env = op->env; 151 object *env = op->env;
162 int x = op->x, y = op->y; 152 int x = op->x, y = op->y;
163 mapstruct *m = op->map; 153 maptile *m = op->map;
164 154
165 op = stop_item (op); 155 op = stop_item (op);
166 if (op == NULL) 156 if (op == NULL)
167 return; 157 return;
168 158
218 } 208 }
219 else 209 else
220 { 210 {
221 if (op->env) 211 if (op->env)
222 { 212 {
223 object *tmp = is_player_inv (op->env); 213 object *tmp = op->in_player ();
224 214
225 if (tmp) 215 if (tmp)
226 esrv_del_item (tmp->contr, op->count); 216 esrv_del_item (tmp->contr, op->count);
227 } 217 }
228 218
229 if (!QUERY_FLAG (op, FLAG_REMOVED)) 219 op->destroy ();
230 remove_ob (op);
231
232 free_object (op);
233 } 220 }
234 221
235 if (type & (AT_FIRE | AT_ELECTRICITY)) 222 if (type & (AT_FIRE | AT_ELECTRICITY))
236 if (env) 223 if (env)
237 { 224 {
247 234
248 /* The value of 50 is arbitrary. */ 235 /* The value of 50 is arbitrary. */
249 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2)) 236 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2))
250 { 237 {
251 object *tmp; 238 object *tmp;
252 archetype *at = find_archetype ("icecube"); 239 archetype *at = archetype::find ("icecube");
253 240
254 if (at == NULL) 241 if (at == NULL)
255 return; 242 return;
256 243
257 op = stop_item (op); 244 op = stop_item (op);
270 tmp->move_slow = 0; 257 tmp->move_slow = 0;
271 insert_ob_in_map (tmp, op->map, originator, 0); 258 insert_ob_in_map (tmp, op->map, originator, 0);
272 } 259 }
273 260
274 if (!QUERY_FLAG (op, FLAG_REMOVED)) 261 if (!QUERY_FLAG (op, FLAG_REMOVED))
275 remove_ob (op); 262 op->remove ();
276 263
277 insert_ob_in_ob (op, tmp); 264 insert_ob_in_ob (op, tmp);
278 return; 265 return;
279 } 266 }
280} 267}
287 */ 274 */
288 275
289int 276int
290hit_map (object *op, int dir, int type, int full_hit) 277hit_map (object *op, int dir, int type, int full_hit)
291{ 278{
292 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
352 shuffle_attack (op, 1); /*1 flag tells it to change the face */ 334 shuffle_attack (op, 1); /*1 flag tells it to change the face */
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);
358 if (next)
359 next_tag = next->count;
360
361 while (next)
362 {
363 if (was_destroyed (next, next_tag))
364 {
365 /* There may still be objects that were above 'next', but there is no 339 /* 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 340 * simple way to find out short of copying all object references and
367 * tags into a temporary array before we start processing the first 341 * tags into a temporary array before we start processing the first
368 * object. That's why we just abort. 342 * object. That's why we just abort on destroy.
369 * 343 *
370 * This happens whenever attack spells (like fire) hit a pile 344 * This happens whenever attack spells (like fire) hit a pile
371 * of objects. This is not a bug - nor an error. The errormessage 345 * of objects. This is not a bug - nor an error.
372 * below was spamming the logs for absolutely no reason. 346 */
373 */ 347 for (object *next = map->at (x, y).bot; next && !next->destroyed (); )
374 /* LOG (llevDebug, "hit_map(): next object destroyed\n"); */ 348 {
375 break;
376 }
377
378 tmp = next; 349 object *tmp = next;
379 next = tmp->above; 350 next = tmp->above;
380
381 if (next)
382 next_tag = next->count;
383
384 if (QUERY_FLAG (tmp, FLAG_FREED))
385 {
386 LOG (llevError, "BUG: hit_map(): found freed object\n");
387 break;
388 }
389 351
390 /* Something could have happened to 'tmp' while 'tmp->below' was processed. 352 /* Something could have happened to 'tmp' while 'tmp->below' was processed.
391 * For example, 'tmp' was put in an icecube. 353 * For example, 'tmp' was put in an icecube.
392 * This is one of the few cases where on_same_map should not be used. 354 * This is one of the few cases where on_same_map should not be used.
393 */ 355 */
396 358
397 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 359 if (QUERY_FLAG (tmp, FLAG_ALIVE))
398 { 360 {
399 hit_player (tmp, op->stats.dam, op, type, full_hit); 361 hit_player (tmp, op->stats.dam, op, type, full_hit);
400 retflag |= 1; 362 retflag |= 1;
401 if (was_destroyed (op, op_tag)) 363 if (op->destroyed ())
402 break; 364 break;
403 } 365 }
404
405 /* Here we are potentially destroying an object. If the object has 366 /* 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 367 * NO_PASS set, it is also immune - you can't destroy walls. Note
407 * that weak walls have is_alive set, which prevent objects from 368 * that weak walls have is_alive set, which prevent objects from
408 * passing over/through them. We don't care what type of movement 369 * passing over/through them. We don't care what type of movement
409 * the wall blocks - if it blocks any type of movement, can't be 370 * the wall blocks - if it blocks any type of movement, can't be
410 * destroyed right now. 371 * destroyed right now.
411 */ 372 */
412 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 373 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
413 { 374 {
414 save_throw_object (tmp, type, op); 375 save_throw_object (tmp, type, op);
376
415 if (was_destroyed (op, op_tag)) 377 if (op->destroyed ())
416 break; 378 break;
417 } 379 }
418 } 380 }
419 381
420 return 0; 382 return 0;
423void 385void
424attack_message (int dam, int type, object *op, object *hitter) 386attack_message (int dam, int type, object *op, object *hitter)
425{ 387{
426 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF]; 388 char buf[MAX_BUF], buf1[MAX_BUF], buf2[MAX_BUF];
427 int i, found = 0; 389 int i, found = 0;
428 mapstruct *map; 390 maptile *map;
429 object *next, *tmp; 391 object *next, *tmp;
430 392
431 /* put in a few special messages for some of the common attacktypes 393 /* put in a few special messages for some of the common attacktypes
432 * a player might have. For example, fire, electric, cold, etc 394 * a player might have. For example, fire, electric, cold, etc
433 * [garbled 20010919] 395 * [garbled 20010919]
450 sprintf (buf1, "missed %s", &op->name); 412 sprintf (buf1, "missed %s", &op->name);
451 sprintf (buf2, " misses"); 413 sprintf (buf2, " misses");
452 found++; 414 found++;
453 } 415 }
454 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || 416 else if ((hitter->type == DISEASE || hitter->type == SYMPTOM ||
455 hitter->type == POISONING || (type & AT_POISON && IS_LIVE (op))) && !found) 417 hitter->type == POISONING || (type & AT_POISON && op->is_alive ())) && !found)
456 { 418 {
457 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) 419 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++)
458 if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1) 420 if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1)
459 { 421 {
460 sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2); 422 sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2);
472 strcpy (buf2, attack_mess[ATM_DOOR][i].buf3); 434 strcpy (buf2, attack_mess[ATM_DOOR][i].buf3);
473 found++; 435 found++;
474 break; 436 break;
475 } 437 }
476 } 438 }
477 else if (hitter->type == PLAYER && IS_LIVE (op)) 439 else if (hitter->type == PLAYER && op->is_alive ())
478 { 440 {
479 if (USING_SKILL (hitter, SK_KARATE)) 441 if (USING_SKILL (hitter, SK_KARATE))
480 { 442 {
481 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) 443 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++)
482 if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1) 444 if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1)
508 found++; 470 found++;
509 break; 471 break;
510 } 472 }
511 } 473 }
512 } 474 }
475
513 if (found) 476 if (found)
514 { 477 {
515 /* done */ 478 /* done */
516 } 479 }
517 else if (IS_ARROW (hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) 480 else if (hitter->is_arrow () && (type == AT_PHYSICAL || type == AT_MAGIC))
518 { 481 {
519 sprintf (buf1, "hit"); /* just in case */ 482 sprintf (buf1, "hit"); /* just in case */
520 for (i = 0; i < MAXATTACKMESS; i++) 483 for (i = 0; i < MAXATTACKMESS; i++)
521 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1) 484 if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1)
522 { 485 {
523 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3); 486 strcpy (buf2, attack_mess[ATM_ARROW][i].buf3);
524 found++; 487 found++;
525 break; 488 break;
526 } 489 }
527 } 490 }
528 else if (type & AT_DRAIN && IS_LIVE (op)) 491 else if (type & AT_DRAIN && op->is_alive ())
529 { 492 {
530 /* drain is first, because some items have multiple attypes */ 493 /* drain is first, because some items have multiple attypes */
531 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) 494 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++)
532 if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1) 495 if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1)
533 { 496 {
535 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3); 498 strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3);
536 found++; 499 found++;
537 break; 500 break;
538 } 501 }
539 } 502 }
540 else if (type & AT_ELECTRICITY && IS_LIVE (op)) 503 else if (type & AT_ELECTRICITY && op->is_alive ())
541 { 504 {
542 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) 505 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++)
543 if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1) 506 if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1)
544 { 507 {
545 sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2); 508 sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2);
546 strcpy (buf2, attack_mess[ATM_ELEC][i].buf3); 509 strcpy (buf2, attack_mess[ATM_ELEC][i].buf3);
547 found++; 510 found++;
548 break; 511 break;
549 } 512 }
550 } 513 }
551 else if (type & AT_COLD && IS_LIVE (op)) 514 else if (type & AT_COLD && op->is_alive ())
552 { 515 {
553 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) 516 for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++)
554 if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1) 517 if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1)
555 { 518 {
556 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2); 519 sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2);
633 strcpy (buf1, "hit"); 596 strcpy (buf1, "hit");
634 strcpy (buf2, " hits"); 597 strcpy (buf2, " hits");
635 } 598 }
636 599
637 /* bail out if a monster is casting spells */ 600 /* bail out if a monster is casting spells */
638 if (!(hitter->type == PLAYER || (get_owner (hitter) != NULL && hitter->owner->type == PLAYER))) 601 if (!(hitter->type == PLAYER || (hitter->owner != NULL && hitter->owner->type == PLAYER)))
639 return; 602 return;
640 603
641 /* scale down magic considerably. */ 604 /* scale down magic considerably. */
642 if (type & AT_MAGIC && rndm (0, 5)) 605 if (type & AT_MAGIC && rndm (0, 5))
643 return; 606 return;
644 607
645 /* Did a player hurt another player? Inform both! */ 608 /* Did a player hurt another player? Inform both! */
646 if (op->type == PLAYER && (get_owner (hitter) == NULL ? hitter->type : hitter->owner->type) == PLAYER) 609 if (op->type == PLAYER && (hitter->owner == NULL ? hitter->type : hitter->owner->type) == PLAYER)
647 { 610 {
648 if (get_owner (hitter) != NULL) 611 if (hitter->owner != NULL)
649 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); 612 sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2);
650 else 613 else
651 { 614 {
652 sprintf (buf, "%s%s you.", &hitter->name, buf2); 615 sprintf (buf, "%s%s you.", &hitter->name, buf2);
653 if (dam != 0) 616 if (dam != 0)
675 else 638 else
676 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); 639 play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0);
677 } 640 }
678 new_draw_info (NDI_BLACK, 0, hitter, buf); 641 new_draw_info (NDI_BLACK, 0, hitter, buf);
679 } 642 }
680 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 643 else if (hitter->owner != NULL && hitter->owner->type == PLAYER)
681 { 644 {
682 /* look for stacked spells and start reducing the message chances */ 645 /* 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)) 646 if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE))
684 { 647 {
685 i = 4; 648 i = 4;
686 map = hitter->map; 649 map = hitter->map;
687 if (out_of_map (map, hitter->x, hitter->y)) 650 if (out_of_map (map, hitter->x, hitter->y))
688 return; 651 return;
689 next = get_map_ob (map, hitter->x, hitter->y); 652 next = GET_MAP_OB (map, hitter->x, hitter->y);
690 if (next) 653 if (next)
691 while (next) 654 while (next)
692 { 655 {
693 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE)) 656 if (next->type == SPELL_EFFECT && (next->subtype == SP_EXPLOSION || next->subtype == SP_BULLET || next->subtype == SP_CONE))
694 i *= 3; 657 i *= 3;
760attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 723attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
761{ 724{
762 int simple_attack, roll, dam = 0; 725 int simple_attack, roll, dam = 0;
763 uint32 type; 726 uint32 type;
764 shstr op_name; 727 shstr op_name;
765 tag_t op_tag, hitter_tag;
766 728
767 if (get_attack_mode (&op, &hitter, &simple_attack)) 729 if (get_attack_mode (&op, &hitter, &simple_attack))
768 goto error; 730 goto error;
769 731
770 if (hitter->current_weapon) 732 if (hitter->current_weapon)
771 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 733 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
772 return RESULT_INT (0); 734 return RESULT_INT (0);
773 735
774 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 736 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
775 return RESULT_INT (0); 737 return RESULT_INT (0);
776
777 op_tag = op->count;
778 hitter_tag = hitter->count;
779 738
780 /* 739 /*
781 * A little check to make it more difficult to dance forward and back 740 * A little check to make it more difficult to dance forward and back
782 * to avoid ever being hit by monsters. 741 * to avoid ever being hit by monsters.
783 */ 742 */
788 * which then gets here again. By decreasing the speed before 747 * which then gets here again. By decreasing the speed before
789 * we call process_object, the 'if' statement above will fail. 748 * we call process_object, the 'if' statement above will fail.
790 */ 749 */
791 op->speed_left--; 750 op->speed_left--;
792 process_object (op); 751 process_object (op);
752
793 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 753 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
794 goto error; 754 goto error;
795 } 755 }
796 756
797 op_name = op->name; 757 op_name = op->name;
798 758
832 if (QUERY_FLAG (op, FLAG_SLEEP)) 792 if (QUERY_FLAG (op, FLAG_SLEEP))
833 CLEAR_FLAG (op, FLAG_SLEEP); 793 CLEAR_FLAG (op, FLAG_SLEEP);
834 794
835 /* If the victim can't see the attacker, it may alert others 795 /* If the victim can't see the attacker, it may alert others
836 * for help. */ 796 * for help. */
837 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !get_owner (op) && rndm (0, op->stats.Int)) 797 if (op->type != PLAYER && !can_see_enemy (op, hitter) && !op->owner && rndm (0, op->stats.Int))
838 npc_call_help (op); 798 npc_call_help (op);
839 799
840 /* if you were hidden and hit by a creature, you are discovered */ 800 /* if you were hidden and hit by a creature, you are discovered */
841 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) 801 if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE))
842 { 802 {
849 * when they hit the victim. For things like thrown daggers, 809 * when they hit the victim. For things like thrown daggers,
850 * this sets 'hitter' to the actual dagger, and not the 810 * this sets 'hitter' to the actual dagger, and not the
851 * wrapper object. 811 * wrapper object.
852 */ 812 */
853 thrown_item_effect (hitter, op); 813 thrown_item_effect (hitter, op);
814
854 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 815 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
855 goto leave; 816 goto leave;
856 } 817 }
857 818
858 /* Need to do at least 1 damage, otherwise there is no point 819 /* Need to do at least 1 damage, otherwise there is no point
859 * to go further and it will cause FPE's below. 820 * to go further and it will cause FPE's below.
860 */ 821 */
861 if (hitdam <= 0) 822 if (hitdam <= 0)
862 hitdam = 1; 823 hitdam = 1;
863 824
864 type = hitter->attacktype; 825 type = hitter->attacktype;
826
865 if (!type) 827 if (!type)
866 type = AT_PHYSICAL; 828 type = AT_PHYSICAL;
829
867 /* Handle monsters that hit back */ 830 /* Handle monsters that hit back */
868 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 831 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
869 { 832 {
870 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 833 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
871 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 834 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
835
872 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 836 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
837
873 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 838 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
874 goto leave; 839 goto leave;
875 } 840 }
876 841
877 /* In the new attack code, it should handle multiple attack 842 /* In the new attack code, it should handle multiple attack
878 * types in its area, so remove it from here. 843 * types in its area, so remove it from here.
879 */ 844 */
880 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 845 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
846
881 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 847 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
882 goto leave; 848 goto leave;
883 } /* end of if hitter hit op */ 849 } /* end of if hitter hit op */
884 /* if we missed, dam=0 */ 850 /* if we missed, dam=0 */
885 851
886 /*attack_message(dam, type, op, hitter); */ 852 /*attack_message(dam, type, op, hitter); */
920 if (op->weight <= 5000 && tmp->stats.hp >= 0) 886 if (op->weight <= 5000 && tmp->stats.hp >= 0)
921 { 887 {
922 if (tmp->head != NULL) 888 if (tmp->head != NULL)
923 tmp = tmp->head; 889 tmp = tmp->head;
924 890
925 remove_ob (op); 891 op->remove ();
926 op = insert_ob_in_ob (op, tmp); 892 op = insert_ob_in_ob (op, tmp);
927 893
928 if (tmp->type == PLAYER) 894 if (tmp->type == PLAYER)
929 esrv_send_item (tmp, op); 895 esrv_send_item (tmp, op);
930 896
943object * 909object *
944hit_with_arrow (object *op, object *victim) 910hit_with_arrow (object *op, object *victim)
945{ 911{
946 object *container, *hitter; 912 object *container, *hitter;
947 int hit_something = 0; 913 int hit_something = 0;
948 tag_t victim_tag, hitter_tag;
949 sint16 victim_x, victim_y;
950 914
951 /* Disassemble missile */ 915 /* Disassemble missile */
952 if (op->inv) 916 if (op->inv)
953 { 917 {
954 container = op; 918 container = op;
955 hitter = op->inv; 919 hitter = op->inv;
956 remove_ob (hitter); 920 hitter->remove ();
957 insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); 921 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 922 /* 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 923 * 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 924 * removed at the end of this function must be able to deal with empty
961 * THROWN_OBJs. */ 925 * THROWN_OBJs. */
962 } 926 }
963 else 927 else
964 { 928 {
965 container = NULL; 929 container = 0;
966 hitter = op; 930 hitter = op;
967 } 931 }
968 932
969 /* Try to hit victim */ 933 /* 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); 934 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
976 935
977 /* Arrow attacks door, rune of summoning is triggered, demon is put on 936 /* Arrow attacks door, rune of summoning is triggered, demon is put on
978 * arrow, move_apply() calls this function, arrow sticks in demon, 937 * arrow, move_apply() calls this function, arrow sticks in demon,
979 * attack_ob_simple() returns, and we've got an arrow that still exists 938 * 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 939 * but is no longer on the map. Ugh. (Beware: Such things can happen at
981 * other places as well!) 940 * other places as well!)
982 */ 941 */
983 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 942 if (hitter->destroyed () || hitter->env != NULL)
984 { 943 {
985 if (container) 944 if (container)
986 { 945 {
987 remove_ob (container); 946 container->remove ();
988 free_object (container); 947 container->destroy ();
989 } 948 }
949
990 return NULL; 950 return 0;
991 } 951 }
992 952
993 /* Missile hit victim */ 953 /* Missile hit victim */
994 /* if the speed is > 10, then this is a fast moving arrow, we go straight 954 /* if the speed is > 10, then this is a fast moving arrow, we go straight
995 * through the target 955 * through the target
996 */ 956 */
997 if (hit_something && op->speed <= 10.0) 957 if (hit_something && op->speed <= 10.0)
998 { 958 {
999 /* Stop arrow */ 959 /* Stop arrow */
1000 if (container == NULL) 960 if (!container)
1001 { 961 {
1002 hitter = fix_stopped_arrow (hitter); 962 hitter = fix_stopped_arrow (hitter);
1003 if (hitter == NULL) 963 if (!hitter)
1004 return NULL; 964 return 0;
1005 } 965 }
1006 else 966 else
1007 { 967 container->destroy ();
1008 remove_ob (container);
1009 free_object (container);
1010 }
1011 968
1012 /* Try to stick arrow into victim */ 969 /* Try to stick arrow into victim */
1013 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 970 if (!victim->destroyed () && stick_arrow (hitter, victim))
1014 return NULL; 971 return 0;
1015 972
1016 /* Else try to put arrow on victim's map square 973 /* Else try to put arrow on victim's map square
1017 * remove check for P_WALL here. If the arrow got to this 974 * remove check for P_WALL here. If the arrow got to this
1018 * space, that is good enough - with the new movement code, 975 * space, that is good enough - with the new movement code,
1019 * there is now the potential for lots of spaces where something 976 * there is now the potential for lots of spaces where something
1020 * can fly over but not otherwise move over. What is the correct 977 * can fly over but not otherwise move over. What is the correct
1021 * way to handle those otherwise? 978 * way to handle those otherwise?
1022 */ 979 */
1023 if (victim_x != hitter->x || victim_y != hitter->y) 980 if (victim->x != hitter->x || victim->y != hitter->y)
1024 { 981 {
1025 remove_ob (hitter); 982 hitter->remove ();
1026 hitter->x = victim_x; 983 hitter->x = victim->x;
1027 hitter->y = victim_y; 984 hitter->y = victim->y;
1028 insert_ob_in_map (hitter, victim->map, hitter, 0); 985 insert_ob_in_map (hitter, victim->map, hitter, 0);
1029 } 986 }
1030 else 987 else
1031 {
1032 /* Else leave arrow where it is */ 988 /* Else leave arrow where it is */
1033 merge_ob (hitter, NULL); 989 merge_ob (hitter, NULL);
1034 } 990
1035 return NULL; 991 return 0;
1036 } 992 }
1037 993
1038 if (hit_something && op->speed >= 10.0) 994 if (hit_something && op->speed >= 10.0)
1039 op->speed -= 1.0; 995 op->speed -= 1.0;
1040 996
1041 /* Missile missed victim - reassemble missile */ 997 /* Missile missed victim - reassemble missile */
1042 if (container) 998 if (container)
1043 { 999 {
1044 remove_ob (hitter); 1000 hitter->remove ();
1045 insert_ob_in_ob (hitter, container); 1001 insert_ob_in_ob (hitter, container);
1046 } 1002 }
1003
1047 return op; 1004 return op;
1048} 1005}
1049 1006
1050 1007
1051void 1008void
1060 } 1017 }
1061 else if (!GET_ANIM_ID (op)) 1018 else if (!GET_ANIM_ID (op))
1062 { 1019 {
1063 /* Object has been called - no animations, so remove it */ 1020 /* Object has been called - no animations, so remove it */
1064 if (op->stats.hp < 0) 1021 if (op->stats.hp < 0)
1022 op->destroy ();
1065 { 1023
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 */ 1024 return; /* no animations, so nothing more to do */
1072 } 1025 }
1026
1073 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; 1027 perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp;
1028
1074 if (perc >= (int) NUM_ANIMATIONS (op)) 1029 if (perc >= (int) NUM_ANIMATIONS (op))
1075 perc = NUM_ANIMATIONS (op) - 1; 1030 perc = NUM_ANIMATIONS (op) - 1;
1076 else if (perc < 1) 1031 else if (perc < 1)
1077 perc = 1; 1032 perc = 1;
1033
1078 SET_ANIMATION (op, perc); 1034 SET_ANIMATION (op, perc);
1079 update_object (op, UP_OBJ_FACE); 1035 update_object (op, UP_OBJ_FACE);
1036
1080 if (perc == NUM_ANIMATIONS (op) - 1) 1037 if (perc == NUM_ANIMATIONS (op) - 1)
1081 { /* Reached the last animation */ 1038 { /* Reached the last animation */
1082 if (op->face == blank_face) 1039 if (op->face == blank_face)
1083 {
1084 /* If the last face is blank, remove the ob */ 1040 /* If the last face is blank, remove the ob */
1085 remove_ob (op); /* Should update LOS */ 1041 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 1042 else
1093 { /* The last face was not blank, leave an image */ 1043 { /* The last face was not blank, leave an image */
1094 CLEAR_FLAG (op, FLAG_BLOCKSVIEW); 1044 CLEAR_FLAG (op, FLAG_BLOCKSVIEW);
1095 update_all_los (op->map, op->x, op->y); 1045 update_all_los (op->map, op->x, op->y);
1096 op->move_block = 0; 1046 op->move_block = 0;
1100} 1050}
1101 1051
1102void 1052void
1103scare_creature (object *target, object *hitter) 1053scare_creature (object *target, object *hitter)
1104{ 1054{
1105 object *owner = get_owner (hitter); 1055 object *owner = hitter->owner;
1106 1056
1107 if (!owner) 1057 if (!owner)
1108 owner = hitter; 1058 owner = hitter;
1109 1059
1110 SET_FLAG (target, FLAG_SCARED); 1060 SET_FLAG (target, FLAG_SCARED);
1225 else if (attacknum == ATNR_FEAR) 1175 else if (attacknum == ATNR_FEAR)
1226 scare_creature (op, hitter); 1176 scare_creature (op, hitter);
1227 else if (attacknum == ATNR_CANCELLATION) 1177 else if (attacknum == ATNR_CANCELLATION)
1228 cancellation (op); 1178 cancellation (op);
1229 else if (attacknum == ATNR_DEPLETE) 1179 else if (attacknum == ATNR_DEPLETE)
1230 drain_stat (op); 1180 op->drain_stat ();
1231 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR)) 1181 else if (attacknum == ATNR_BLIND && !QUERY_FLAG (op, FLAG_UNDEAD) && !QUERY_FLAG (op, FLAG_GENERATOR))
1232 blind_player (op, hitter, dam); 1182 blind_player (op, hitter, dam);
1233 } 1183 }
1234 dam = 0; /* These are all effects and don't do real damage */ 1184 dam = 0; /* These are all effects and don't do real damage */
1235 } 1185 }
1274 if (op->type == PLAYER) 1224 if (op->type == PLAYER)
1275 esrv_send_item (op, tmp); 1225 esrv_send_item (op, tmp);
1276 } 1226 }
1277 } 1227 }
1278 if (flag) 1228 if (flag)
1279 fix_player (op); /* Something was corroded */ 1229 op->update_stats (); /* Something was corroded */
1280 } 1230 }
1281 } 1231 }
1282 break; 1232 break;
1283 case ATNR_DRAIN: 1233 case ATNR_DRAIN:
1284 { 1234 {
1314 * Try to credit the owner. We try to display player -> player drain 1264 * Try to credit the owner. We try to display player -> player drain
1315 * attacks, hence all the != PLAYER checks. 1265 * attacks, hence all the != PLAYER checks.
1316 */ 1266 */
1317 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1267 if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1318 { 1268 {
1319 object *owner = get_owner (hitter); 1269 object *owner = hitter->owner;
1320 1270
1321 if (owner && owner != hitter) 1271 if (owner && owner != hitter)
1322 { 1272 {
1323 if (op->type != PLAYER || owner->type != PLAYER) 1273 if (op->type != PLAYER || owner->type != PLAYER)
1324 change_exp (owner, op->stats.exp / (rate * 2), 1274 change_exp (owner, op->stats.exp / (rate * 2),
1461 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW)) 1411 if (QUERY_FLAG (op, FLAG_BLOCKSVIEW))
1462 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */ 1412 update_all_los (op->map, op->x, op->y); /* makes sure los will be recalculated */
1463 1413
1464 if (op->type == DOOR) 1414 if (op->type == DOOR)
1465 { 1415 {
1466 op->speed = 0.1; 1416 op->set_speed (0.1);
1467 update_ob_speed (op);
1468 op->speed_left = -0.05; 1417 op->speed_left = -0.05;
1469 return maxdam; 1418 return maxdam;
1470 } 1419 }
1420
1471 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) 1421 if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER)
1472 { 1422 {
1473 remove_friendly_object (op); 1423 remove_friendly_object (op);
1424
1474 if (get_owner (op) != NULL && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) 1425 if (op->owner && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op)
1475 {
1476 op->owner->contr->ranges[range_golem] = NULL; 1426 op->owner->contr->ranges[range_golem] = 0;
1477 op->owner->contr->golem_count = 0;
1478 }
1479 1427
1480 remove_ob (op); 1428 op->destroy ();
1481 free_object (op);
1482 return maxdam; 1429 return maxdam;
1483 } 1430 }
1484 1431
1485 /* Now lets start dealing with experience we get for killing something */ 1432 /* Now lets start dealing with experience we get for killing something */
1486 1433
1487 owner = get_owner (hitter); 1434 owner = hitter->owner;
1488 if (owner == NULL) 1435 if (!owner)
1489 owner = hitter; 1436 owner = hitter;
1490 1437
1491 /* is the victim (op) standing on battleground? */ 1438 /* is the victim (op) standing on battleground? */
1492 if (op_on_battleground (op, NULL, NULL)) 1439 if (op_on_battleground (op, NULL, NULL))
1493 battleg = 1; 1440 battleg = 1;
1513 char buf[256]; 1460 char buf[256];
1514 1461
1515 tmv = localtime (&t); 1462 tmv = localtime (&t);
1516 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv); 1463 strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv);
1517 1464
1518 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->socket.host, query_name (op)); 1465 LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->ns->host, query_name (op));
1519 } 1466 }
1520 1467
1521 /* try to filter some things out - basically, if you are 1468 /* try to filter some things out - basically, if you are
1522 * killing a level 1 creature and your level 20, you 1469 * killing a level 1 creature and your level 20, you
1523 * probably don't want to see that. 1470 * probably don't want to see that.
1524 */ 1471 */
1525 if (owner->level < op->level * 2 || op->stats.exp > 1000) 1472 if (owner->level < op->level * 2 || op->stats.exp > 1000)
1526 { 1473 {
1527 if (owner != hitter) 1474 if (owner != hitter)
1528 {
1529 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter)); 1475 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s with %s.", query_name (op), query_name (hitter));
1530 }
1531 else 1476 else
1532 {
1533 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op)); 1477 new_draw_info_format (NDI_BLACK, 0, owner, "You killed %s.", query_name (op));
1534 } 1478
1535 /* Only play sounds for melee kills */ 1479 /* Only play sounds for melee kills */
1536 if (hitter->type == PLAYER) 1480 if (hitter->type == PLAYER)
1537 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS); 1481 play_sound_map (owner->map, owner->x, owner->y, SOUND_PLAYER_KILLS);
1538 } 1482 }
1539 1483
1544 * player that the object belonged to - so if you killed another player 1488 * player that the object belonged to - so if you killed another player
1545 * with spells, pets, whatever, there was no penalty. 1489 * with spells, pets, whatever, there was no penalty.
1546 * Changed to make luck penalty configurable in settings. 1490 * Changed to make luck penalty configurable in settings.
1547 */ 1491 */
1548 if (op->type == PLAYER && owner != op && !battleg) 1492 if (op->type == PLAYER && owner != op && !battleg)
1549 change_luck (owner, -settings.pk_luck_penalty); 1493 owner->change_luck (-settings.pk_luck_penalty);
1550 1494
1551 /* This code below deals with finding the appropriate skill 1495 /* This code below deals with finding the appropriate skill
1552 * to credit exp to. This is a bit problematic - we should 1496 * to credit exp to. This is a bit problematic - we should
1553 * probably never really have to look at current_weapon->skill 1497 * probably never really have to look at current_weapon->skill
1554 */ 1498 */
1555 skill = NULL; 1499 skill = 0;
1500
1556 if (hitter->skill && hitter->type != PLAYER) 1501 if (hitter->skill && hitter->type != PLAYER)
1557 skill = hitter->skill; 1502 skill = hitter->skill;
1558 else if (owner->chosen_skill) 1503 else if (owner->chosen_skill)
1559 { 1504 {
1560 skill = owner->chosen_skill->skill; 1505 skill = owner->chosen_skill->skill;
1579 break; 1524 break;
1580 } 1525 }
1581 } 1526 }
1582 } /* Was it a player that hit somethign */ 1527 } /* Was it a player that hit somethign */
1583 else 1528 else
1584 {
1585 skill = NULL; 1529 skill = 0;
1586 }
1587 1530
1588 /* Pet (or spell) killed something. */ 1531 /* Pet (or spell) killed something. */
1589 if (owner != hitter) 1532 if (owner != hitter)
1590 {
1591 (void) sprintf (buf, "%s killed %s with %s%s%s.", &owner->name, 1533 sprintf (buf, "%s killed %s with %s%s%s.", &owner->name,
1592 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1534 query_name (op), query_name (hitter), battleg ? " (duel)" : "", pk ? " (pk)" : "");
1593 }
1594 else 1535 else
1595 {
1596 (void) sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name, 1536 sprintf (buf, "%s killed %s%s%s%s.", &hitter->name, &op->name,
1597 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ? 1537 (QUERY_FLAG (hitter, FLAG_MONSTER)) || hitter->type == PLAYER ?
1598 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : ""); 1538 " in hand to hand combat" : "", battleg ? " (duel)" : "", pk ? " (pk)" : "");
1599 } 1539
1600 /* These may have been set in the player code section above */ 1540 /* These may have been set in the player code section above */
1601 if (!skop) 1541 if (!skop)
1602 skop = hitter->chosen_skill; 1542 skop = hitter->chosen_skill;
1543
1603 if (!skill && skop) 1544 if (!skill && skop)
1604 skill = skop->skill; 1545 skill = skop->skill;
1605 1546
1606 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf); 1547 new_draw_info (NDI_ALL, op->type == PLAYER ? 1 : 10, NULL, buf);
1607 1548
1608
1609 /* If you didn't kill yourself, and your not the wizard */ 1549 /* If you didn't kill yourself, and your not the wizard */
1610 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ)) 1550 if (owner != op && !QUERY_FLAG (op, FLAG_WAS_WIZ))
1611 { 1551 {
1612 int exp; 1552 int exp;
1613 1553
1614 /* Really don't give much experience for killing other players */ 1554 /* Really don't give much experience for killing other players */
1615 // schmorp: temporary? reduce the amount of exp gained for pking enourmously 1555 // schmorp: temporarily? reduce the amount of exp gained for pking enourmously
1616 if (op->type == PLAYER) 1556 if (op->type == PLAYER)
1617 { 1557 {
1618 if (battleg) 1558 if (battleg)
1619 { 1559 {
1620 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!"); 1560 new_draw_info (NDI_UNIQUE, 0, owner, "Your foe has fallen!");
1638 1578
1639 if (!settings.simple_exp) 1579 if (!settings.simple_exp)
1640 exp = exp / 2; 1580 exp = exp / 2;
1641 1581
1642 if (owner->type != PLAYER || owner->contr->party == NULL) 1582 if (owner->type != PLAYER || owner->contr->party == NULL)
1643 {
1644 change_exp (owner, exp, skill, 0); 1583 change_exp (owner, exp, skill, 0);
1645 }
1646 else 1584 else
1647 { 1585 {
1648 int shares = 0, count = 0; 1586 int shares = 0, count = 0;
1649
1650 player *pl; 1587 player *pl;
1651
1652 partylist *party = owner->contr->party; 1588 partylist *party = owner->contr->party;
1653 1589
1654#ifdef PARTY_KILL_LOG
1655 add_kill_to_party (party, query_name (owner), query_name (op), exp); 1590 add_kill_to_party (party, query_name (owner), query_name (op), exp);
1656#endif 1591
1657 for (pl = first_player; pl != NULL; pl = pl->next) 1592 for_all_players (pl)
1658 {
1659 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1593 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1660 { 1594 {
1661 count++; 1595 count++;
1662 shares += (pl->ob->level + 4); 1596 shares += (pl->ob->level + 4);
1663 } 1597 }
1664 } 1598
1665 if (count == 1 || shares > exp) 1599 if (count == 1 || shares > exp || !shares)
1666 change_exp (owner, exp, skill, SK_EXP_TOTAL); 1600 change_exp (owner, exp, skill, SK_EXP_TOTAL);
1667 else 1601 else
1668 { 1602 {
1669 int share = exp / shares, given = 0, nexp; 1603 int share = exp / shares, given = 0, nexp;
1670 1604
1671 for (pl = first_player; pl != NULL; pl = pl->next) 1605 for_all_players (pl)
1672 {
1673 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner)) 1606 if (party && pl->ob->contr->party == party && on_same_map (pl->ob, owner))
1674 { 1607 {
1675 nexp = (pl->ob->level + 4) * share; 1608 nexp = (pl->ob->level + 4) * share;
1676 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL); 1609 change_exp (pl->ob, nexp, skill, SK_EXP_TOTAL);
1677 given += nexp; 1610 given += nexp;
1678 } 1611 }
1679 } 1612
1680 exp -= given; 1613 exp -= given;
1681 /* give any remainder to the player */ 1614 /* give any remainder to the player */
1682 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL); 1615 change_exp (owner, exp, skill, SK_EXP_ADD_SKILL);
1683 } 1616 }
1684 } /* else part of a party */ 1617 } /* else part of a party */
1685
1686 } /* end if person didn't kill himself */ 1618 } /* end if person didn't kill himself */
1687 1619
1688 if (op->type != PLAYER) 1620 if (op->type != PLAYER)
1689 { 1621 {
1690 if (QUERY_FLAG (op, FLAG_FRIENDLY)) 1622 if (QUERY_FLAG (op, FLAG_FRIENDLY))
1691 { 1623 {
1692 object *owner1 = get_owner (op); 1624 object *owner1 = op->owner;
1693 1625
1694 if (owner1 != NULL && owner1->type == PLAYER) 1626 if (owner1 && owner1->type == PLAYER)
1695 { 1627 {
1696 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); 1628 play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0);
1697 /* Maybe we should include the owner that killed this, maybe not */ 1629 /* 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); 1630 new_draw_info_format (NDI_UNIQUE, 0, owner1, "Your pet, the %s, is killed by %s.", &op->name, &hitter->name);
1699 } 1631 }
1700 1632
1701 remove_friendly_object (op); 1633 remove_friendly_object (op);
1702 } 1634 }
1703 1635
1704 remove_ob (op); 1636 op->destroy ();
1705 free_object (op);
1706 } 1637 }
1707 /* Player has been killed! */
1708 else 1638 else
1709 { 1639 {
1640 /* Player has been killed! */
1710 if (owner->type == PLAYER) 1641 if (owner->type == PLAYER)
1711 {
1712 snprintf (op->contr->killer, BIG_NAME, "%s the %s", &owner->name, owner->contr->title); 1642 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1713 }
1714 else 1643 else
1715 assign (op->contr->killer, hitter->name); 1644 assign (op->contr->killer, hitter->name);
1716 } 1645 }
1717 1646
1718 /* This was return -1 - that doesn't seem correct - if we return -1, process 1647 /* This was return -1 - that doesn't seem correct - if we return -1, process
1742 return 0; 1671 return 0;
1743 1672
1744 if (hitter->type == PLAYER && hitter->contr->peaceful == 1) 1673 if (hitter->type == PLAYER && hitter->contr->peaceful == 1)
1745 return 1; 1674 return 1;
1746 1675
1747 if ((owner = get_owner (hitter)) != NULL) 1676 if ((owner = hitter->owner) != NULL)
1748 { 1677 {
1749 if (owner->type == PLAYER && owner->contr->peaceful == 1) 1678 if (owner->type == PLAYER && owner->contr->peaceful == 1)
1750 friendlyfire = 2; 1679 friendlyfire = 2;
1751 } 1680 }
1752 1681
1773{ 1702{
1774 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1703 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1775 int maxattacktype, attacknum; 1704 int maxattacktype, attacknum;
1776 int body_attack = op && op->head; /* Did we hit op's head? */ 1705 int body_attack = op && op->head; /* Did we hit op's head? */
1777 int simple_attack; 1706 int simple_attack;
1778 tag_t op_tag, hitter_tag;
1779 int rtn_kill = 0; 1707 int rtn_kill = 0;
1780 int friendlyfire; 1708 int friendlyfire;
1781 1709
1782 if (get_attack_mode (&op, &hitter, &simple_attack)) 1710 if (get_attack_mode (&op, &hitter, &simple_attack))
1783 return 0; 1711 return 0;
1787 return 0; 1715 return 0;
1788 1716
1789#ifdef PROHIBIT_PLAYERKILL 1717#ifdef PROHIBIT_PLAYERKILL
1790 if (op->type == PLAYER) 1718 if (op->type == PLAYER)
1791 { 1719 {
1792 object *owner = get_owner (hitter); 1720 object *owner = hitter->owner;
1793 1721
1794 if (!owner) 1722 if (!owner)
1795 owner = hitter; 1723 owner = hitter;
1724
1796 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1725 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1797 {
1798 return 0; 1726 return 0;
1799 }
1800 } 1727 }
1801#endif 1728#endif
1802
1803 op_tag = op->count;
1804 hitter_tag = hitter->count;
1805 1729
1806 if (body_attack) 1730 if (body_attack)
1807 { 1731 {
1808 /* slow and paralyze must hit the head. But we don't want to just 1732 /* 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 1733 * return - we still need to process other attacks the spell still
1815 * attack so we don't cancel out things like magic bullet. 1739 * attack so we don't cancel out things like magic bullet.
1816 */ 1740 */
1817 if (type & (AT_PARALYZE | AT_SLOW)) 1741 if (type & (AT_PARALYZE | AT_SLOW))
1818 { 1742 {
1819 type &= ~(AT_PARALYZE | AT_SLOW); 1743 type &= ~(AT_PARALYZE | AT_SLOW);
1744
1820 if (!type || type == AT_MAGIC) 1745 if (!type || type == AT_MAGIC)
1821 return 0; 1746 return 0;
1822 } 1747 }
1823 } 1748 }
1824 1749
1828 1753
1829 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1754 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1830 if (tmp->type == RUNE || tmp->type == TRAP) 1755 if (tmp->type == RUNE || tmp->type == TRAP)
1831 { 1756 {
1832 spring_trap (tmp, hitter); 1757 spring_trap (tmp, hitter);
1758
1833 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1759 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1834 return 0; 1760 return 0;
1761
1835 break; 1762 break;
1836 } 1763 }
1837 } 1764 }
1838 1765
1839 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1766 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1840 { 1767 {
1841 /* FIXME: If a player is killed by a rune in a door, the 1768 /* 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. 1769 * destroyed() check above doesn't return, and might get here.
1843 */ 1770 */
1844 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1771 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1845 return 0; 1772 return 0;
1846 } 1773 }
1847 1774
1885 (hitter->title != NULL 1812 (hitter->title != NULL
1886 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL))) 1813 && (god = find_god (determine_god (hitter))) != NULL && god->race != NULL && strstr (god->race, undead_name) != NULL)))
1887 return 0; 1814 return 0;
1888 } 1815 }
1889 1816
1890 maxattacktype = type; /* initialize this to something */ 1817 maxattacktype = type; /* initialise this to something */
1891 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum) 1818 for (attacknum = 0; attacknum < NROFATTACKS; attacknum++, attacktype = 1 << attacknum)
1892 { 1819 {
1893 /* Magic isn't really a true attack type - it gets combined with other 1820 /* Magic isn't really a true attack type - it gets combined with other
1894 * attack types. As such, skip it over. However, if magic is 1821 * attack types. As such, skip it over. However, if magic is
1895 * the only attacktype in the group, then still attack with it 1822 * the only attacktype in the group, then still attack with it
1956 1883
1957#ifdef ATTACK_DEBUG 1884#ifdef ATTACK_DEBUG
1958 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); 1885 LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam);
1959#endif 1886#endif
1960 1887
1961 if (get_owner (hitter)) 1888 if (hitter->owner)
1962 op->enemy = hitter->owner; 1889 op->enemy = hitter->owner;
1963 else if (QUERY_FLAG (hitter, FLAG_ALIVE)) 1890 else if (QUERY_FLAG (hitter, FLAG_ALIVE))
1964 op->enemy = hitter; 1891 op->enemy = hitter;
1965 1892
1966 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) 1893 if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER)
1991 1918
1992 if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) 1919 if (QUERY_FLAG (op, FLAG_TEAR_DOWN))
1993 { 1920 {
1994 if (maxdam) 1921 if (maxdam)
1995 tear_down_wall (op); 1922 tear_down_wall (op);
1923
1996 return maxdam; /* nothing more to do for wall */ 1924 return maxdam; /* nothing more to do for wall */
1997 } 1925 }
1998 1926
1999 /* See if the creature has been killed */ 1927 /* See if the creature has been killed */
2000 rtn_kill = kill_object (op, maxdam, hitter, type); 1928 rtn_kill = kill_object (op, maxdam, hitter, type);
2008 */ 1936 */
2009 if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) 1937 if (QUERY_FLAG (hitter, FLAG_ONE_HIT))
2010 { 1938 {
2011 if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) 1939 if (QUERY_FLAG (hitter, FLAG_FRIENDLY))
2012 remove_friendly_object (hitter); 1940 remove_friendly_object (hitter);
2013 remove_ob (hitter); 1941
2014 free_object (hitter); 1942 hitter->destroy ();
2015 } 1943 }
2016 /* Lets handle creatures that are splitting now */ 1944 /* Lets handle creatures that are splitting now */
2017 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) 1945 else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING))
2018 { 1946 {
2019 int i; 1947 int i;
2020 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); 1948 int friendly = QUERY_FLAG (op, FLAG_FRIENDLY);
2021 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); 1949 int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE);
2022 object *owner = get_owner (op); 1950 object *owner = op->owner;
2023 1951
2024 if (!op->other_arch) 1952 if (!op->other_arch)
2025 { 1953 {
2026 LOG (llevError, "SPLITTING without other_arch error.\n"); 1954 LOG (llevError, "SPLITTING without other_arch error.\n");
2027 return maxdam; 1955 return maxdam;
2028 } 1956 }
1957
2029 remove_ob (op); 1958 op->remove ();
1959
2030 for (i = 0; i < NROFNEWOBJS (op); i++) 1960 for (i = 0; i < NROFNEWOBJS (op); i++)
2031 { /* This doesn't handle op->more yet */ 1961 { /* This doesn't handle op->more yet */
2032 object *tmp = arch_to_object (op->other_arch); 1962 object *tmp = arch_to_object (op->other_arch);
2033 int j; 1963 int j;
2034 1964
2035 tmp->stats.hp = op->stats.hp; 1965 tmp->stats.hp = op->stats.hp;
1966
2036 if (friendly) 1967 if (friendly)
2037 { 1968 {
2038 SET_FLAG (tmp, FLAG_FRIENDLY);
2039 add_friendly_object (tmp); 1969 add_friendly_object (tmp);
2040 tmp->attack_movement = PETMOVE; 1970 tmp->attack_movement = PETMOVE;
1971
2041 if (owner != NULL) 1972 if (owner)
2042 set_owner (tmp, owner); 1973 tmp->set_owner (owner);
2043 } 1974 }
1975
2044 if (unaggressive) 1976 if (unaggressive)
2045 SET_FLAG (tmp, FLAG_UNAGGRESSIVE); 1977 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
1978
2046 j = find_first_free_spot (tmp, op->map, op->x, op->y); 1979 j = find_first_free_spot (tmp, op->map, op->x, op->y);
1980
2047 if (j == -1) /* No spot to put this monster */ 1981 if (j == -1) /* No spot to put this monster */
2048 free_object (tmp); 1982 tmp->destroy ();
2049 else 1983 else
2050 { 1984 {
2051 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; 1985 tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j];
2052 insert_ob_in_map (tmp, op->map, NULL, 0); 1986 insert_ob_in_map (tmp, op->map, NULL, 0);
2053 } 1987 }
2054 } 1988 }
2055 if (friendly) 1989
2056 remove_friendly_object (op); 1990 op->destroy ();
2057 free_object (op);
2058 } 1991 }
2059 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) 1992 else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10)
2060 { 1993 hitter->destroy ();
2061 remove_ob (hitter); 1994
2062 free_object (hitter);
2063 }
2064 return maxdam; 1995 return maxdam;
2065} 1996}
2066 1997
2067 1998
2068void 1999void
2069poison_player (object *op, object *hitter, int dam) 2000poison_player (object *op, object *hitter, int dam)
2070{ 2001{
2071 archetype *at = find_archetype ("poisoning"); 2002 archetype *at = archetype::find ("poisoning");
2072 object *tmp = present_arch_in_ob (at, op); 2003 object *tmp = present_arch_in_ob (at, op);
2073 2004
2074 if (tmp == NULL) 2005 if (tmp == NULL)
2075 { 2006 {
2076 if ((tmp = arch_to_object (at)) == NULL) 2007 if ((tmp = arch_to_object (at)) == NULL)
2089 if (QUERY_FLAG (hitter, FLAG_ALIVE)) 2020 if (QUERY_FLAG (hitter, FLAG_ALIVE))
2090 tmp->stats.dam += hitter->level / 2; 2021 tmp->stats.dam += hitter->level / 2;
2091 else 2022 else
2092 tmp->stats.dam = dam; 2023 tmp->stats.dam = dam;
2093 2024
2094 copy_owner (tmp, hitter); /* so we get credit for poisoning kills */ 2025 tmp->set_owner (hitter); /* so we get credit for poisoning kills */
2095 if (hitter->skill && hitter->skill != tmp->skill) 2026 if (hitter->skill && hitter->skill != tmp->skill)
2096 { 2027 {
2097 tmp->skill = hitter->skill; 2028 tmp->skill = hitter->skill;
2098 } 2029 }
2099 2030
2105 tmp->stats.Con = MAX (-(dam / 4 + 1), -10); 2036 tmp->stats.Con = MAX (-(dam / 4 + 1), -10);
2106 tmp->stats.Str = MAX (-(dam / 3 + 2), -10); 2037 tmp->stats.Str = MAX (-(dam / 3 + 2), -10);
2107 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10); 2038 tmp->stats.Dex = MAX (-(dam / 6 + 1), -10);
2108 tmp->stats.Int = MAX (-dam / 7, -10); 2039 tmp->stats.Int = MAX (-dam / 7, -10);
2109 SET_FLAG (tmp, FLAG_APPLIED); 2040 SET_FLAG (tmp, FLAG_APPLIED);
2110 fix_player (op); 2041 op->update_stats ();
2111 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); 2042 new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill.");
2112 } 2043 }
2113 if (hitter->type == PLAYER) 2044 if (hitter->type == PLAYER)
2114 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); 2045 new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name);
2115 else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) 2046 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); 2047 new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name);
2117 } 2048 }
2118 tmp->speed_left = 0; 2049 tmp->speed_left = 0;
2119 } 2050 }
2120 else 2051 else
2122} 2053}
2123 2054
2124void 2055void
2125slow_player (object *op, object *hitter, int dam) 2056slow_player (object *op, object *hitter, int dam)
2126{ 2057{
2127 archetype *at = find_archetype ("slowness"); 2058 archetype *at = archetype::find ("slowness");
2128 object *tmp; 2059 object *tmp;
2129 2060
2130 if (at == NULL) 2061 if (at == NULL)
2131 { 2062 {
2132 LOG (llevError, "Can't find slowness archetype.\n"); 2063 LOG (llevError, "Can't find slowness archetype.\n");
2139 } 2070 }
2140 else 2071 else
2141 tmp->stats.food++; 2072 tmp->stats.food++;
2142 SET_FLAG (tmp, FLAG_APPLIED); 2073 SET_FLAG (tmp, FLAG_APPLIED);
2143 tmp->speed_left = 0; 2074 tmp->speed_left = 0;
2144 fix_player (op); 2075 op->update_stats ();
2145} 2076}
2146 2077
2147void 2078void
2148confuse_player (object *op, object *hitter, int dam) 2079confuse_player (object *op, object *hitter, int dam)
2149{ 2080{
2193 */ 2124 */
2194 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100; 2125 tmp->speed = tmp->speed * (100.0 - (float) op->resist[ATNR_BLIND]) / 100;
2195 2126
2196 tmp = insert_ob_in_ob (tmp, op); 2127 tmp = insert_ob_in_ob (tmp, op);
2197 change_abil (op, tmp); /* Mostly to display any messages */ 2128 change_abil (op, tmp); /* Mostly to display any messages */
2198 fix_player (op); /* This takes care of some other stuff */ 2129 op->update_stats (); /* This takes care of some other stuff */
2199 2130
2200 if (hitter->owner) 2131 if (hitter->owner)
2201 owner = get_owner (hitter); 2132 owner = hitter->owner;
2202 else 2133 else
2203 owner = hitter; 2134 owner = hitter;
2204 2135
2205 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); 2136 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op));
2206 } 2137 }
2352 } 2283 }
2353 2284
2354 /* aimed missiles use the owning object's sight */ 2285 /* aimed missiles use the owning object's sight */
2355 if (is_aimed_missile (hitter)) 2286 if (is_aimed_missile (hitter))
2356 { 2287 {
2357 if ((attacker = get_owner (hitter)) == NULL) 2288 if ((attacker = hitter->owner) == NULL)
2358 attacker = hitter; 2289 attacker = hitter;
2359 /* A player who saves but hasn't quit still could have objects 2290 /* A player who saves but hasn't quit still could have objects
2360 * owned by him - need to handle that case to avoid crashes. 2291 * owned by him - need to handle that case to avoid crashes.
2361 */ 2292 */
2362 if (QUERY_FLAG (attacker, FLAG_REMOVED)) 2293 if (QUERY_FLAG (attacker, FLAG_REMOVED))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines