ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_attack.C
(Generate patch)

Comparing deliantra/server/server/spell_attack.C (file contents):
Revision 1.15 by root, Sat Sep 16 22:24:13 2006 UTC vs.
Revision 1.24 by root, Tue Dec 26 08:55:00 2006 UTC

27 */ 27 */
28 28
29#include <global.h> 29#include <global.h>
30#include <object.h> 30#include <object.h>
31#include <living.h> 31#include <living.h>
32#ifndef __CEXTRACT__
33# include <sproto.h> 32#include <sproto.h>
34#endif
35#include <spells.h> 33#include <spells.h>
36#include <sounds.h> 34#include <sounds.h>
37 35
38/* this function checks to see if a spell pushes objects as well 36/* this function checks to see if a spell pushes objects as well
39 * as flies over and damages them (only used for cones for now) 37 * as flies over and damages them (only used for cones for now)
57 { 55 {
58 weight_move = op->weight + (op->weight * op->level) / 3; 56 weight_move = op->weight + (op->weight * op->level) / 3;
59 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */ 57 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */
60 } 58 }
61 59
62 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 60 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
63 { 61 {
64 int num_sections = 1; 62 int num_sections = 1;
65 63
66 /* don't move DM */ 64 /* don't move DM */
67 if (QUERY_FLAG (tmp, FLAG_WIZ)) 65 if (QUERY_FLAG (tmp, FLAG_WIZ))
140 138
141 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, sx, sy))) 139 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, sx, sy)))
142 return; 140 return;
143 141
144 /* OK, we made a fork */ 142 /* OK, we made a fork */
145 new_bolt = get_object (); 143 new_bolt = tmp->clone ();
146 copy_object (tmp, new_bolt);
147 144
148 /* reduce chances of subsequent forking */ 145 /* reduce chances of subsequent forking */
149 new_bolt->stats.Dex -= 10; 146 new_bolt->stats.Dex -= 10;
150 tmp->stats.Dex -= 10; /* less forks from main bolt too */ 147 tmp->stats.Dex -= 10; /* less forks from main bolt too */
151 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */ 148 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */
174 sint16 x, y; 171 sint16 x, y;
175 maptile *m; 172 maptile *m;
176 173
177 if (--(op->duration) < 0) 174 if (--(op->duration) < 0)
178 { 175 {
179 remove_ob (op); 176 op->destroy ();
180 free_object (op);
181 return; 177 return;
182 } 178 }
183 179
184 hit_map (op, 0, op->attacktype, 1); 180 hit_map (op, 0, op->attacktype, 1);
185 181
250 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */ 246 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */
251 return; 247 return;
252 } 248 }
253 else 249 else
254 { /* Create a copy of this object and put it ahead */ 250 { /* Create a copy of this object and put it ahead */
255 tmp = get_object (); 251 tmp = op->clone ();
256 copy_object (op, tmp); 252
257 tmp->speed_left = -0.1; 253 tmp->speed_left = -0.1;
258 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp); 254 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp);
259 tmp = insert_ob_in_map (tmp, op->map, op, 0); 255 tmp = insert_ob_in_map (tmp, op->map, op, 0);
260 /* To make up for the decrease at the top of the function */ 256 /* To make up for the decrease at the top of the function */
261 tmp->duration++; 257 tmp->duration++;
282 * we remove the magic flag - that can be derived from 278 * we remove the magic flag - that can be derived from
283 * spob->attacktype. 279 * spob->attacktype.
284 * This function sets up the appropriate owner and skill 280 * This function sets up the appropriate owner and skill
285 * pointers. 281 * pointers.
286 */ 282 */
287
288int 283int
289fire_bolt (object *op, object *caster, int dir, object *spob, object *skill) 284fire_bolt (object *op, object *caster, int dir, object *spob, object *skill)
290{ 285{
291 object *tmp = NULL; 286 object *tmp = NULL;
292 int mflags; 287 int mflags;
310 305
311 tmp->direction = dir; 306 tmp->direction = dir;
312 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 307 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
313 SET_ANIMATION (tmp, dir); 308 SET_ANIMATION (tmp, dir);
314 309
315 set_owner (tmp, op); 310 tmp->set_owner (op);
316 set_spell_skill (op, caster, spob, tmp); 311 set_spell_skill (op, caster, spob, tmp);
317 312
318 tmp->x = op->x + DIRX (tmp); 313 tmp->x = op->x + DIRX (tmp);
319 tmp->y = op->y + DIRY (tmp); 314 tmp->y = op->y + DIRY (tmp);
320 tmp->map = op->map; 315 tmp->map = op->map;
321 316
317 maptile *newmap;
322 mflags = get_map_flags (tmp->map, &tmp->map, tmp->x, tmp->y, &tmp->x, &tmp->y); 318 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
323 if (mflags & P_OUT_OF_MAP) 319 if (mflags & P_OUT_OF_MAP)
324 { 320 {
325 free_object (tmp); 321 tmp->destroy ();
326 return 0; 322 return 0;
327 } 323 }
324
325 tmp->map = newmap;
326
328 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 327 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
329 { 328 {
330 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 329 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
331 { 330 {
332 free_object (tmp); 331 tmp->destroy ();
333 return 0; 332 return 0;
334 } 333 }
334
335 tmp->x = op->x; 335 tmp->x = op->x;
336 tmp->y = op->y; 336 tmp->y = op->y;
337 tmp->direction = absdir (tmp->direction + 4); 337 tmp->direction = absdir (tmp->direction + 4);
338 tmp->map = op->map; 338 tmp->map = op->map;
339 } 339 }
340
340 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 341 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL)
341 move_bolt (tmp); 342 move_bolt (tmp);
343
342 return 1; 344 return 1;
343} 345}
344 346
345 347
346 348
361 maptile *m = op->map; 363 maptile *m = op->map;
362 int i; 364 int i;
363 365
364 if (--(op->duration) < 0) 366 if (--(op->duration) < 0)
365 { 367 {
366 remove_ob (op); 368 op->destroy ();
367 free_object (op);
368 return; 369 return;
369 } 370 }
371
370 hit_map (op, 0, op->attacktype, 0); 372 hit_map (op, 0, op->attacktype, 0);
371 373
372 if (op->range > 0) 374 if (op->range > 0)
373 { 375 {
374 for (i = 1; i < 9; i++) 376 for (i = 1; i < 9; i++)
380 /* ok_to_put_more already does things like checks for walls, 382 /* ok_to_put_more already does things like checks for walls,
381 * out of map, etc. 383 * out of map, etc.
382 */ 384 */
383 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype)) 385 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype))
384 { 386 {
385 tmp = get_object (); 387 tmp = op->clone ();
386 copy_object (op, tmp);
387 tmp->state = 0; 388 tmp->state = 0;
388 tmp->speed_left = -0.21; 389 tmp->speed_left = -0.21;
389 tmp->range--; 390 tmp->range--;
390 tmp->value = 0; 391 tmp->value = 0;
391 tmp->x = dx; 392 tmp->x = dx;
407 object *tmp, *owner; 408 object *tmp, *owner;
408 409
409 if (op->other_arch == NULL) 410 if (op->other_arch == NULL)
410 { 411 {
411 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 412 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
412 remove_ob (op); 413 op->destroy ();
413 free_object (op);
414 return; 414 return;
415 } 415 }
416 416
417 if (op->env) 417 if (op->env)
418 { 418 {
420 420
421 env = object_get_env_recursive (op); 421 env = object_get_env_recursive (op);
422 if (env->map == NULL || out_of_map (env->map, env->x, env->y)) 422 if (env->map == NULL || out_of_map (env->map, env->x, env->y))
423 { 423 {
424 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 424 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
425 remove_ob (op); 425 op->destroy ();
426 free_object (op);
427 return; 426 return;
428 } 427 }
428
429 remove_ob (op); 429 op->remove ();
430 op->x = env->x; 430 op->x = env->x;
431 op->y = env->y; 431 op->y = env->y;
432 insert_ob_in_map (op, env->map, op, INS_NO_MERGE | INS_NO_WALK_ON); 432 insert_ob_in_map (op, env->map, op, INS_NO_MERGE | INS_NO_WALK_ON);
433 } 433 }
434 else if (out_of_map (op->map, op->x, op->y)) 434 else if (out_of_map (op->map, op->x, op->y))
435 { 435 {
436 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 436 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
437 remove_ob (op); 437 op->destroy ();
438 free_object (op);
439 return; 438 return;
440 } 439 }
441 440
442 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps 441 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps
443 // NOTE: If this breaks something important: remove this. I can't think of anything 442 // NOTE: If this breaks something important: remove this. I can't think of anything
444 // bad at the moment that might happen from this. 443 // bad at the moment that might happen from this.
445 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 444 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
446 { 445 {
447 remove_ob (op); 446 op->destroy ();
448 free_object (op);
449 return; 447 return;
450 } 448 }
451 449
452 if (op->attacktype) 450 if (op->attacktype)
453 { 451 {
457 } 455 }
458 456
459 /* other_arch contains what this explodes into */ 457 /* other_arch contains what this explodes into */
460 tmp = arch_to_object (op->other_arch); 458 tmp = arch_to_object (op->other_arch);
461 459
462 copy_owner (tmp, op); 460 tmp->set_owner (op);
463 tmp->skill = op->skill; 461 tmp->skill = op->skill;
464 462
465 owner = get_owner (op); 463 owner = op->owner;
466 464
467 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) 465 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner))
468 { 466 {
469 remove_ob (op); 467 op->destroy ();
470 free_object (op);
471 return; 468 return;
472 } 469 }
473 470
474 tmp->x = op->x; 471 tmp->x = op->x;
475 tmp->y = op->y; 472 tmp->y = op->y;
505 502
506 insert_ob_in_map (tmp, op->map, op, 0); 503 insert_ob_in_map (tmp, op->map, op, 0);
507 /* remove the firebullet */ 504 /* remove the firebullet */
508 if (!op->destroyed ()) 505 if (!op->destroyed ())
509 { 506 {
510 remove_ob (op); 507 op->destroy ();
511 free_object (op);
512 } 508 }
513} 509}
514 510
515 511
516 512
540 536
541 /* If nothing alive on this space, no reason to do anything further */ 537 /* If nothing alive on this space, no reason to do anything further */
542 if (!(mflags & P_IS_ALIVE)) 538 if (!(mflags & P_IS_ALIVE))
543 return; 539 return;
544 540
545 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 541 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
546 { 542 {
547 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 543 if (QUERY_FLAG (tmp, FLAG_ALIVE))
548 { 544 {
549 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 545 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
550 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 546 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
551 { 547 {
552 if (!QUERY_FLAG (op, FLAG_REMOVED)) 548 if (!QUERY_FLAG (op, FLAG_REMOVED))
553 { 549 {
554 remove_ob (op); 550 op->destroy ();
555 free_object (op);
556 return; 551 return;
557 } 552 }
558 } 553 }
559 } 554 }
560 } 555 }
561} 556}
562
563 557
564/* Basically, we move 'op' one square, and if it hits something, 558/* Basically, we move 'op' one square, and if it hits something,
565 * call check_bullet. 559 * call check_bullet.
566 * This function is only applicable to bullets, but not to all 560 * This function is only applicable to bullets, but not to all
567 * fired arches (eg, bolts). 561 * fired arches (eg, bolts).
568 */ 562 */
569
570void 563void
571move_bullet (object *op) 564move_bullet (object *op)
572{ 565{
573 sint16 new_x, new_y; 566 sint16 new_x, new_y;
574 int mflags; 567 int mflags;
589 582
590 /* Reached the end of its life - remove it */ 583 /* Reached the end of its life - remove it */
591 if (--op->range <= 0) 584 if (--op->range <= 0)
592 { 585 {
593 if (op->other_arch) 586 if (op->other_arch)
594 {
595 explode_bullet (op); 587 explode_bullet (op);
596 }
597 else 588 else
598 { 589 op->destroy ();
599 remove_ob (op); 590
600 free_object (op);
601 }
602 return; 591 return;
603 } 592 }
604 593
605 new_x = op->x + DIRX (op); 594 new_x = op->x + DIRX (op);
606 new_y = op->y + DIRY (op); 595 new_y = op->y + DIRY (op);
607 m = op->map; 596 m = op->map;
608 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y); 597 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y);
609 598
610 if (mflags & P_OUT_OF_MAP) 599 if (mflags & P_OUT_OF_MAP)
611 { 600 {
612 remove_ob (op); 601 op->destroy ();
613 free_object (op);
614 return; 602 return;
615 } 603 }
616 604
617 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 605 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))
618 { 606 {
619 if (op->other_arch) 607 if (op->other_arch)
620 {
621 explode_bullet (op); 608 explode_bullet (op);
622 }
623 else 609 else
624 { 610 op->destroy ();
625 remove_ob (op); 611
626 free_object (op);
627 }
628 return; 612 return;
629 } 613 }
630 614
631 remove_ob (op); 615 op->remove ();
632 op->x = new_x; 616 op->x = new_x;
633 op->y = new_y; 617 op->y = new_y;
634 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL) 618 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL)
635 return; 619 return;
636 620
638 { 622 {
639 op->direction = absdir (op->direction + 4); 623 op->direction = absdir (op->direction + 4);
640 update_turn_face (op); 624 update_turn_face (op);
641 } 625 }
642 else 626 else
643 {
644 check_bullet (op); 627 check_bullet (op);
645 }
646} 628}
647 629
648 630
649 631
650 632
685 667
686 tmp->direction = dir; 668 tmp->direction = dir;
687 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 669 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
688 SET_ANIMATION (tmp, dir); 670 SET_ANIMATION (tmp, dir);
689 671
690 set_owner (tmp, op); 672 tmp->set_owner (op);
691 set_spell_skill (op, caster, spob, tmp); 673 set_spell_skill (op, caster, spob, tmp);
692 674
693 tmp->x = op->x + freearr_x[dir]; 675 tmp->x = op->x + freearr_x[dir];
694 tmp->y = op->y + freearr_y[dir]; 676 tmp->y = op->y + freearr_y[dir];
695 tmp->map = op->map; 677 tmp->map = op->map;
696 678
679 maptile *newmap;
697 mflags = get_map_flags (tmp->map, &tmp->map, tmp->x, tmp->y, &tmp->x, &tmp->y); 680 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
698 if (mflags & P_OUT_OF_MAP) 681 if (mflags & P_OUT_OF_MAP)
699 { 682 {
700 free_object (tmp); 683 tmp->destroy ();
701 return 0; 684 return 0;
702 } 685 }
686
687 tmp->map = newmap;
688
703 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 689 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
704 { 690 {
705 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 691 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
706 { 692 {
707 free_object (tmp); 693 tmp->destroy ();
708 return 0; 694 return 0;
709 } 695 }
696
710 tmp->x = op->x; 697 tmp->x = op->x;
711 tmp->y = op->y; 698 tmp->y = op->y;
712 tmp->direction = absdir (tmp->direction + 4); 699 tmp->direction = absdir (tmp->direction + 4);
713 tmp->map = op->map; 700 tmp->map = op->map;
714 } 701 }
702
715 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 703 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)))
716 {
717 check_bullet (tmp); 704 check_bullet (tmp);
718 } 705
719 return 1; 706 return 1;
720} 707}
721 708
722 709
723 710
736 object *new_ob = arch_to_object (op->other_arch); 723 object *new_ob = arch_to_object (op->other_arch);
737 724
738 new_ob->x = op->x; 725 new_ob->x = op->x;
739 new_ob->y = op->y; 726 new_ob->y = op->y;
740 new_ob->level = op->level; 727 new_ob->level = op->level;
741 set_owner (new_ob, op->owner); 728 new_ob->set_owner (op->owner);
742 729
743 /* preserve skill ownership */ 730 /* preserve skill ownership */
744 if (op->skill && op->skill != new_ob->skill) 731 if (op->skill && op->skill != new_ob->skill)
745 { 732 {
746 new_ob->skill = op->skill; 733 new_ob->skill = op->skill;
758 745
759 /* if no map then hit_map will crash so just ignore object */ 746 /* if no map then hit_map will crash so just ignore object */
760 if (!op->map) 747 if (!op->map)
761 { 748 {
762 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 749 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
763 op->speed = 0; 750 op->set_speed (0);
764 update_ob_speed (op);
765 return; 751 return;
766 } 752 }
767 753
768 /* lava saves it's life, but not yours :) */ 754 /* lava saves it's life, but not yours :) */
769 if (QUERY_FLAG (op, FLAG_LIFESAVE)) 755 if (QUERY_FLAG (op, FLAG_LIFESAVE))
775#if 0 761#if 0
776 /* Disable this - enabling it makes monsters easier, as 762 /* Disable this - enabling it makes monsters easier, as
777 * when their cone dies when they die. 763 * when their cone dies when they die.
778 */ 764 */
779 /* If no owner left, the spell dies out. */ 765 /* If no owner left, the spell dies out. */
780 if (get_owner (op) == NULL) 766 if (op->owner == NULL)
781 { 767 {
782 remove_ob (op); 768 op->destroy ();
783 free_object (op);
784 return; 769 return;
785 } 770 }
786#endif 771#endif
787 772
788 hit_map (op, 0, op->attacktype, 0); 773 hit_map (op, 0, op->attacktype, 0);
797 if (op->destroyed ()) 782 if (op->destroyed ())
798 return; 783 return;
799 784
800 if ((op->duration--) < 0) 785 if ((op->duration--) < 0)
801 { 786 {
802 remove_ob (op); 787 op->destroy ();
803 free_object (op);
804 return; 788 return;
805 } 789 }
806 /* Object has hit maximum range, so don't have it move 790 /* Object has hit maximum range, so don't have it move
807 * any further. When the duration above expires, 791 * any further. When the duration above expires,
808 * then the object will get removed. 792 * then the object will get removed.
817 { 801 {
818 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)]; 802 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)];
819 803
820 if (ok_to_put_more (op->map, x, y, op, op->attacktype)) 804 if (ok_to_put_more (op->map, x, y, op, op->attacktype))
821 { 805 {
822 object *tmp = get_object (); 806 object *tmp = op->clone ();
823 807
824 copy_object (op, tmp);
825 tmp->x = x; 808 tmp->x = x;
826 tmp->y = y; 809 tmp->y = y;
827 810
828 tmp->duration = op->duration + 1; 811 tmp->duration = op->duration + 1;
829 812
913 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype) 896 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype)
914 continue; 897 continue;
915 898
916 success = 1; 899 success = 1;
917 tmp = arch_to_object (spell->other_arch); 900 tmp = arch_to_object (spell->other_arch);
918 set_owner (tmp, op); 901 tmp->set_owner (op);
919 set_spell_skill (op, caster, spell, tmp); 902 set_spell_skill (op, caster, spell, tmp);
920 tmp->level = caster_level (caster, spell); 903 tmp->level = caster_level (caster, spell);
921 tmp->x = sx; 904 tmp->x = sx;
922 tmp->y = sy; 905 tmp->y = sy;
923 tmp->attacktype = spell->attacktype; 906 tmp->attacktype = spell->attacktype;
1012 return; 995 return;
1013 996
1014 if (env->type == PLAYER) 997 if (env->type == PLAYER)
1015 esrv_del_item (env->contr, op->count); 998 esrv_del_item (env->contr, op->count);
1016 999
1017 remove_ob (op); 1000 op->remove ();
1018 op->x = env->x; 1001 op->x = env->x;
1019 op->y = env->y; 1002 op->y = env->y;
1020 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL) 1003 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL)
1021 return; 1004 return;
1022 } 1005 }
1024 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding 1007 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding
1025 // on a safe map. I don't like this special casing, but it seems to be neccessary 1008 // on a safe map. I don't like this special casing, but it seems to be neccessary
1026 // as bombs can be carried. 1009 // as bombs can be carried.
1027 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 1010 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
1028 { 1011 {
1029 remove_ob (op); 1012 op->destroy ();
1030 free_object (op);
1031 return; 1013 return;
1032 } 1014 }
1033 1015
1034 /* This copies a lot of the code from the fire bullet, 1016 /* This copies a lot of the code from the fire bullet,
1035 * but using the cast_bullet isn't really feasible, 1017 * but using the cast_bullet isn't really feasible,
1046 tmp->direction = i; 1028 tmp->direction = i;
1047 tmp->range = op->range; 1029 tmp->range = op->range;
1048 tmp->stats.dam = op->stats.dam; 1030 tmp->stats.dam = op->stats.dam;
1049 tmp->duration = op->duration; 1031 tmp->duration = op->duration;
1050 tmp->attacktype = op->attacktype; 1032 tmp->attacktype = op->attacktype;
1051 copy_owner (tmp, op); 1033 tmp->set_owner (op);
1052 if (op->skill && op->skill != tmp->skill) 1034 if (op->skill && op->skill != tmp->skill)
1053 { 1035 {
1054 tmp->skill = op->skill; 1036 tmp->skill = op->skill;
1055 } 1037 }
1056 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1038 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1086 tmp->range = spell->range + SP_level_range_adjust (caster, spell); 1068 tmp->range = spell->range + SP_level_range_adjust (caster, spell);
1087 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1069 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1088 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1070 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1089 tmp->attacktype = spell->attacktype; 1071 tmp->attacktype = spell->attacktype;
1090 1072
1091 set_owner (tmp, op); 1073 tmp->set_owner (op);
1092 set_spell_skill (op, caster, spell, tmp); 1074 set_spell_skill (op, caster, spell, tmp);
1093 tmp->x = dx; 1075 tmp->x = dx;
1094 tmp->y = dy; 1076 tmp->y = dy;
1095 insert_ob_in_map (tmp, m, op, 0); 1077 insert_ob_in_map (tmp, m, op, 0);
1096 return 1; 1078 return 1;
1139 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW) 1121 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW)
1140 return NULL; 1122 return NULL;
1141 1123
1142 if (mflags & P_IS_ALIVE) 1124 if (mflags & P_IS_ALIVE)
1143 { 1125 {
1144 for (target = get_map_ob (mp, x, y); target; target = target->above) 1126 for (target = GET_MAP_OB (mp, x, y); target; target = target->above)
1145 { 1127 {
1146 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER)) 1128 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER))
1147 { 1129 {
1148 return target; 1130 return target;
1149 } 1131 }
1216 if (effect->attacktype & AT_DEATH) 1198 if (effect->attacktype & AT_DEATH)
1217 { 1199 {
1218 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1200 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1219 1201
1220 /* casting death spells at undead isn't a good thing */ 1202 /* casting death spells at undead isn't a good thing */
1221 if QUERY_FLAG
1222 (target, FLAG_UNDEAD) 1203 if (QUERY_FLAG (target, FLAG_UNDEAD))
1223 { 1204 {
1224 if (random_roll (0, 2, op, PREFER_LOW)) 1205 if (random_roll (0, 2, op, PREFER_LOW))
1225 { 1206 {
1226 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!"); 1207 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!");
1227 effect->x = op->x; 1208 effect->x = op->x;
1229 } 1210 }
1230 else 1211 else
1231 { 1212 {
1232 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target)); 1213 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target));
1233 target->stats.hp = target->stats.maxhp * 2; 1214 target->stats.hp = target->stats.maxhp * 2;
1234 free_object (effect); 1215 effect->destroy ();
1235 return 0; 1216 return 0;
1236 } 1217 }
1237 } 1218 }
1238 } 1219 }
1239 else 1220 else
1240 { 1221 {
1241 /* how much woe to inflict :) */ 1222 /* how much woe to inflict :) */
1242 effect->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1223 effect->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1243 } 1224 }
1244 1225
1245 set_owner (effect, op); 1226 effect->set_owner (op);
1246 set_spell_skill (op, caster, spell, effect); 1227 set_spell_skill (op, caster, spell, effect);
1247 1228
1248 /* ok, tell it where to be, and insert! */ 1229 /* ok, tell it where to be, and insert! */
1249 effect->x = target->x; 1230 effect->x = target->x;
1250 effect->y = target->y; 1231 effect->y = target->y;
1270 sint16 new_x, new_y; 1251 sint16 new_x, new_y;
1271 maptile *m; 1252 maptile *m;
1272 1253
1273 if (op->range-- <= 0) 1254 if (op->range-- <= 0)
1274 { 1255 {
1275 remove_ob (op); 1256 op->destroy ();
1276 free_object (op);
1277 return; 1257 return;
1278 } 1258 }
1279 1259
1280 owner = get_owner (op); 1260 owner = op->owner;
1281#if 0 1261#if 0
1282 /* It'd make things nastier if this wasn't here - spells cast by 1262 /* It'd make things nastier if this wasn't here - spells cast by
1283 * monster that are then killed would continue to survive 1263 * monster that are then killed would continue to survive
1284 */ 1264 */
1285 if (owner == NULL) 1265 if (owner == NULL)
1286 { 1266 {
1287 remove_ob (op); 1267 op->destroy ();
1288 free_object (op);
1289 return; 1268 return;
1290 } 1269 }
1291#endif 1270#endif
1292 1271
1293 new_x = op->x + DIRX (op); 1272 new_x = op->x + DIRX (op);
1300 hit_map (op, op->direction, AT_MAGIC, 1); 1279 hit_map (op, op->direction, AT_MAGIC, 1);
1301 /* Basically, missile only hits one thing then goes away. 1280 /* Basically, missile only hits one thing then goes away.
1302 * we need to remove it if someone hasn't already done so. 1281 * we need to remove it if someone hasn't already done so.
1303 */ 1282 */
1304 if (!op->destroyed ()) 1283 if (!op->destroyed ())
1305 free_object (op); 1284 op->destroy ();
1306 1285
1307 return; 1286 return;
1308 } 1287 }
1309 1288
1310 remove_ob (op); 1289 op->remove ();
1311 1290
1312 if (!op->direction || (mflags & P_OUT_OF_MAP)) 1291 if (!op->direction || (mflags & P_OUT_OF_MAP))
1313 { 1292 {
1314 free_object (op); 1293 op->destroy ();
1315 return; 1294 return;
1316 } 1295 }
1317 1296
1318 op->x = new_x; 1297 op->x = new_x;
1319 op->y = new_y; 1298 op->y = new_y;
1320 op->map = m; 1299 op->map = m;
1321 i = spell_find_dir (op->map, op->x, op->y, get_owner (op)); 1300 i = spell_find_dir (op->map, op->x, op->y, op->owner);
1322 if (i > 0 && i != op->direction) 1301 if (i > 0 && i != op->direction)
1323 { 1302 {
1324 op->direction = i; 1303 op->direction = i;
1325 SET_ANIMATION (op, op->direction); 1304 SET_ANIMATION (op, op->direction);
1326 } 1305 }
1416 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1395 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1417 if (mflags & P_OUT_OF_MAP) 1396 if (mflags & P_OUT_OF_MAP)
1418 continue; 1397 continue;
1419 if (mflags & P_IS_ALIVE) 1398 if (mflags & P_IS_ALIVE)
1420 { 1399 {
1421 for (tmp = get_map_ob (m, sx, sy); tmp; tmp = tmp->above) 1400 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above)
1422 { 1401 {
1423 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1402 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1424 break; 1403 break;
1425 } 1404 }
1426 if (tmp) 1405 if (tmp)
1549 force->stats.ac = spell_ob->stats.ac; 1528 force->stats.ac = spell_ob->stats.ac;
1550 force->stats.wc = spell_ob->stats.wc; 1529 force->stats.wc = spell_ob->stats.wc;
1551 1530
1552 change_abil (tmp, force); /* Mostly to display any messages */ 1531 change_abil (tmp, force); /* Mostly to display any messages */
1553 insert_ob_in_ob (force, tmp); 1532 insert_ob_in_ob (force, tmp);
1554 fix_player (tmp); 1533 tmp->update_stats ();
1555 return 1; 1534 return 1;
1556 1535
1557} 1536}
1558 1537
1559 1538
1610 1589
1611 /* If there is nothing living on this space, no need to go further */ 1590 /* If there is nothing living on this space, no need to go further */
1612 if (!(mflags & P_IS_ALIVE)) 1591 if (!(mflags & P_IS_ALIVE))
1613 continue; 1592 continue;
1614 1593
1615 for (tmp = get_map_ob (m, nx, ny); tmp; tmp = tmp->above) 1594 for (tmp = GET_MAP_OB (m, nx, ny); tmp; tmp = tmp->above)
1616 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1595 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1617 break; 1596 break;
1618 1597
1619 /* There can be living objects that are not monsters */ 1598 /* There can be living objects that are not monsters */
1620 if (!tmp || tmp->type == PLAYER) 1599 if (!tmp || tmp->type == PLAYER)
1708 SET_FLAG (head, FLAG_FRIENDLY); 1687 SET_FLAG (head, FLAG_FRIENDLY);
1709 /* Prevent uncontolled outbreaks of self replicating monsters. 1688 /* Prevent uncontolled outbreaks of self replicating monsters.
1710 Typical use case is charm, go somwhere, use aggravation to make hostile. 1689 Typical use case is charm, go somwhere, use aggravation to make hostile.
1711 This could lead to fun stuff like mice outbreak in bigworld and server crawl. */ 1690 This could lead to fun stuff like mice outbreak in bigworld and server crawl. */
1712 CLEAR_FLAG (head, FLAG_GENERATOR); 1691 CLEAR_FLAG (head, FLAG_GENERATOR);
1713 set_owner (head, op); 1692 head->set_owner (op);
1714 set_spell_skill (op, caster, spell, head); 1693 set_spell_skill (op, caster, spell, head);
1715 add_friendly_object (head); 1694 add_friendly_object (head);
1716 head->attack_movement = PETMOVE; 1695 head->attack_movement = PETMOVE;
1717 done_one = 1; 1696 done_one = 1;
1718 change_exp (op, head->stats.exp / 2, head->skill, SK_EXP_ADD_SKILL); 1697 change_exp (op, head->stats.exp / 2, head->skill, SK_EXP_ADD_SKILL);
1746 int i, j, dam_save, dir, mflags; 1725 int i, j, dam_save, dir, mflags;
1747 sint16 nx, ny, hx, hy; 1726 sint16 nx, ny, hx, hy;
1748 object *owner; 1727 object *owner;
1749 maptile *m; 1728 maptile *m;
1750 1729
1751 owner = get_owner (op); 1730 owner = op->owner;
1752 1731
1753 /* the following logic makes sure that the ball doesn't move into a wall, 1732 /* the following logic makes sure that the ball doesn't move into a wall,
1754 * and makes sure that it will move along a wall to try and get at it's 1733 * and makes sure that it will move along a wall to try and get at it's
1755 * victim. The block immediately below more or less chooses a random 1734 * victim. The block immediately below more or less chooses a random
1756 * offset to move the ball, eg, keep it mostly on course, with some 1735 * offset to move the ball, eg, keep it mostly on course, with some
1785 nx = op->x; 1764 nx = op->x;
1786 ny = op->y; 1765 ny = op->y;
1787 m = op->map; 1766 m = op->map;
1788 } 1767 }
1789 1768
1790 remove_ob (op); 1769 op->remove ();
1791 op->y = ny; 1770 op->y = ny;
1792 op->x = nx; 1771 op->x = nx;
1793 insert_ob_in_map (op, m, op, 0); 1772 insert_ob_in_map (op, m, op, 0);
1794 1773
1795 dam_save = op->stats.dam; /* save the original dam: we do halfdam on 1774 dam_save = op->stats.dam; /* save the original dam: we do halfdam on
1835 } 1814 }
1836 1815
1837 /* restore to the center location and damage */ 1816 /* restore to the center location and damage */
1838 op->stats.dam = dam_save; 1817 op->stats.dam = dam_save;
1839 1818
1840 i = spell_find_dir (op->map, op->x, op->y, get_owner (op)); 1819 i = spell_find_dir (op->map, op->x, op->y, op->owner);
1841 1820
1842 if (i >= 0) 1821 if (i >= 0)
1843 { /* we have a preferred direction! */ 1822 { /* we have a preferred direction! */
1844 /* pick another direction if the preferred dir is blocked. */ 1823 /* pick another direction if the preferred dir is blocked. */
1845 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP || 1824 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP ||
1871 maptile *m; 1850 maptile *m;
1872#endif 1851#endif
1873 int basedir; 1852 int basedir;
1874 object *owner; 1853 object *owner;
1875 1854
1876 owner = get_owner (op); 1855 owner = op->owner;
1877 if (op->duration == 0 || owner == NULL) 1856 if (op->duration == 0 || owner == NULL)
1878 { 1857 {
1879 remove_ob (op); 1858 op->destroy ();
1880 free_object (op);
1881 return; 1859 return;
1882 } 1860 }
1861
1883 op->duration--; 1862 op->duration--;
1884 1863
1885 basedir = op->direction; 1864 basedir = op->direction;
1886 if (basedir == 0) 1865 if (basedir == 0)
1887 { 1866 {
1986 return 0; 1965 return 0;
1987 1966
1988 tmp = get_archetype (SWARM_SPELL); 1967 tmp = get_archetype (SWARM_SPELL);
1989 tmp->x = op->x; 1968 tmp->x = op->x;
1990 tmp->y = op->y; 1969 tmp->y = op->y;
1991 set_owner (tmp, op); /* needed so that if swarm elements kill, caster gets xp. */ 1970 tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */
1992 set_spell_skill (op, caster, spell, tmp); 1971 set_spell_skill (op, caster, spell, tmp);
1993 1972
1994 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */ 1973 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */
1995 tmp->spell = arch_to_object (spell->other_arch); 1974 tmp->spell = arch_to_object (spell->other_arch);
1996 1975
2043 return 0; 2022 return 0;
2044 } 2023 }
2045 2024
2046 if (mflags & P_IS_ALIVE && spell->attacktype) 2025 if (mflags & P_IS_ALIVE && spell->attacktype)
2047 { 2026 {
2048 for (target = get_map_ob (m, x, y); target; target = target->above) 2027 for (target = GET_MAP_OB (m, x, y); target; target = target->above)
2049 if (QUERY_FLAG (target, FLAG_MONSTER)) 2028 if (QUERY_FLAG (target, FLAG_MONSTER))
2050 { 2029 {
2051 /* oky doky. got a target monster. Lets make a blinding attack */ 2030 /* oky doky. got a target monster. Lets make a blinding attack */
2052 if (target->head) 2031 if (target->head)
2053 target = target->head; 2032 target = target->head;
2135 2114
2136 /* Only bother looking on this space if there is something living here */ 2115 /* Only bother looking on this space if there is something living here */
2137 if (mflags & P_IS_ALIVE) 2116 if (mflags & P_IS_ALIVE)
2138 { 2117 {
2139 /* search this square for a victim */ 2118 /* search this square for a victim */
2140 for (walk = get_map_ob (m, x, y); walk; walk = walk->above) 2119 for (walk = GET_MAP_OB (m, x, y); walk; walk = walk->above)
2141 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) 2120 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER))
2142 { /* found a victim */ 2121 { /* found a victim */
2143 object *disease = arch_to_object (spell->other_arch); 2122 object *disease = arch_to_object (spell->other_arch);
2144 2123
2145 set_owner (disease, op); 2124 disease->set_owner (op);
2146 set_spell_skill (op, caster, spell, disease); 2125 set_spell_skill (op, caster, spell, disease);
2147 disease->stats.exp = 0; 2126 disease->stats.exp = 0;
2148 disease->level = caster_level (caster, spell); 2127 disease->level = caster_level (caster, spell);
2149 2128
2150 /* do level adjustments */ 2129 /* do level adjustments */
2199 { 2178 {
2200 object *flash; /* visual effect for inflicting disease */ 2179 object *flash; /* visual effect for inflicting disease */
2201 2180
2202 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); 2181 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name);
2203 2182
2204 free_object (disease); /* don't need this one anymore */ 2183 disease->destroy (); /* don't need this one anymore */
2205 flash = get_archetype (ARCH_DETECT_MAGIC); 2184 flash = get_archetype (ARCH_DETECT_MAGIC);
2206 flash->x = x; 2185 flash->x = x;
2207 flash->y = y; 2186 flash->y = y;
2208 flash->map = walk->map; 2187 flash->map = walk->map;
2209 insert_ob_in_map (flash, walk->map, op, 0); 2188 insert_ob_in_map (flash, walk->map, op, 0);
2210 return 1; 2189 return 1;
2211 } 2190 }
2212 free_object (disease); 2191
2192 disease->destroy ();
2213 } 2193 }
2214 } /* if living creature */ 2194 } /* if living creature */
2215 } /* for range of spaces */ 2195 } /* for range of spaces */
2216 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2196 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2217 return 1; 2197 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines