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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines