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.16 by root, Tue Dec 12 20:53:03 2006 UTC vs.
Revision 1.23 by root, Mon Dec 25 11:25:50 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines