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.13 by root, Thu Sep 14 22:34:05 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))
117void 115void
118forklightning (object *op, object *tmp) 116forklightning (object *op, object *tmp)
119{ 117{
120 int new_dir = 1; /* direction or -1 for left, +1 for right 0 if no new bolt */ 118 int new_dir = 1; /* direction or -1 for left, +1 for right 0 if no new bolt */
121 int t_dir; /* stores temporary dir calculation */ 119 int t_dir; /* stores temporary dir calculation */
122 mapstruct *m; 120 maptile *m;
123 sint16 sx, sy; 121 sint16 sx, sy;
124 object *new_bolt; 122 object *new_bolt;
125 123
126 /* pick a fork direction. tmp->stats.Con is the left bias 124 /* pick a fork direction. tmp->stats.Con is the left bias
127 * i.e., the chance in 100 of forking LEFT 125 * i.e., the chance in 100 of forking LEFT
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 */
170move_bolt (object *op) 167move_bolt (object *op)
171{ 168{
172 object *tmp; 169 object *tmp;
173 int mflags; 170 int mflags;
174 sint16 x, y; 171 sint16 x, y;
175 mapstruct *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
356 */ 358 */
357void 359void
358explosion (object *op) 360explosion (object *op)
359{ 361{
360 object *tmp; 362 object *tmp;
361 mapstruct *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;
402 * explode. 403 * explode.
403 */ 404 */
404void 405void
405explode_bullet (object *op) 406explode_bullet (object *op)
406{ 407{
407 tag_t op_tag = op->count;
408 object *tmp, *owner; 408 object *tmp, *owner;
409 409
410 if (op->other_arch == NULL) 410 if (op->other_arch == NULL)
411 { 411 {
412 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 412 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
413 remove_ob (op); 413 op->destroy ();
414 free_object (op);
415 return; 414 return;
416 } 415 }
417 416
418 if (op->env) 417 if (op->env)
419 { 418 {
421 420
422 env = object_get_env_recursive (op); 421 env = object_get_env_recursive (op);
423 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))
424 { 423 {
425 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 424 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
426 remove_ob (op); 425 op->destroy ();
427 free_object (op);
428 return; 426 return;
429 } 427 }
428
430 remove_ob (op); 429 op->remove ();
431 op->x = env->x; 430 op->x = env->x;
432 op->y = env->y; 431 op->y = env->y;
433 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);
434 } 433 }
435 else if (out_of_map (op->map, op->x, op->y)) 434 else if (out_of_map (op->map, op->x, op->y))
436 { 435 {
437 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 436 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
438 remove_ob (op); 437 op->destroy ();
439 free_object (op);
440 return; 438 return;
441 } 439 }
442 440
443 // 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
444 // 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
445 // bad at the moment that might happen from this. 443 // bad at the moment that might happen from this.
446 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)
447 { 445 {
448 remove_ob (op); 446 op->destroy ();
449 free_object (op);
450 return; 447 return;
451 } 448 }
452 449
453 if (op->attacktype) 450 if (op->attacktype)
454 { 451 {
455 hit_map (op, 0, op->attacktype, 1); 452 hit_map (op, 0, op->attacktype, 1);
456 if (was_destroyed (op, op_tag)) 453 if (op->destroyed ())
457 return; 454 return;
458 } 455 }
459 456
460 /* other_arch contains what this explodes into */ 457 /* other_arch contains what this explodes into */
461 tmp = arch_to_object (op->other_arch); 458 tmp = arch_to_object (op->other_arch);
462 459
463 copy_owner (tmp, op); 460 tmp->set_owner (op);
464 tmp->skill = op->skill; 461 tmp->skill = op->skill;
465 462
466 owner = get_owner (op); 463 owner = op->owner;
467 464
468 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))
469 { 466 {
470 remove_ob (op); 467 op->destroy ();
471 free_object (op);
472 return; 468 return;
473 } 469 }
474 470
475 tmp->x = op->x; 471 tmp->x = op->x;
476 tmp->y = op->y; 472 tmp->y = op->y;
504 /* Prevent recursion */ 500 /* Prevent recursion */
505 op->move_on = 0; 501 op->move_on = 0;
506 502
507 insert_ob_in_map (tmp, op->map, op, 0); 503 insert_ob_in_map (tmp, op->map, op, 0);
508 /* remove the firebullet */ 504 /* remove the firebullet */
509 if (!was_destroyed (op, op_tag)) 505 if (!op->destroyed ())
510 { 506 {
511 remove_ob (op); 507 op->destroy ();
512 free_object (op);
513 } 508 }
514} 509}
515 510
516 511
517 512
520 */ 515 */
521 516
522void 517void
523check_bullet (object *op) 518check_bullet (object *op)
524{ 519{
525 tag_t op_tag = op->count, tmp_tag;
526 object *tmp; 520 object *tmp;
527 int dam, mflags; 521 int dam, mflags;
528 mapstruct *m; 522 maptile *m;
529 sint16 sx, sy; 523 sint16 sx, sy;
530 524
531 mflags = get_map_flags (op->map, &m, op->x, op->y, &sx, &sy); 525 mflags = get_map_flags (op->map, &m, op->x, op->y, &sx, &sy);
532 526
533 if (!(mflags & P_IS_ALIVE) && !OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 527 if (!(mflags & P_IS_ALIVE) && !OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
542 536
543 /* 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 */
544 if (!(mflags & P_IS_ALIVE)) 538 if (!(mflags & P_IS_ALIVE))
545 return; 539 return;
546 540
547 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)
548 { 542 {
549 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 543 if (QUERY_FLAG (tmp, FLAG_ALIVE))
550 { 544 {
551 tmp_tag = tmp->count;
552 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 545 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
553 if (was_destroyed (op, op_tag) || !was_destroyed (tmp, tmp_tag) || (op->stats.dam -= dam) < 0) 546 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
554 { 547 {
555 if (!QUERY_FLAG (op, FLAG_REMOVED)) 548 if (!QUERY_FLAG (op, FLAG_REMOVED))
556 { 549 {
557 remove_ob (op); 550 op->destroy ();
558 free_object (op);
559 return; 551 return;
560 } 552 }
561 } 553 }
562 } 554 }
563 } 555 }
564} 556}
565
566 557
567/* Basically, we move 'op' one square, and if it hits something, 558/* Basically, we move 'op' one square, and if it hits something,
568 * call check_bullet. 559 * call check_bullet.
569 * This function is only applicable to bullets, but not to all 560 * This function is only applicable to bullets, but not to all
570 * fired arches (eg, bolts). 561 * fired arches (eg, bolts).
571 */ 562 */
572
573void 563void
574move_bullet (object *op) 564move_bullet (object *op)
575{ 565{
576 sint16 new_x, new_y; 566 sint16 new_x, new_y;
577 int mflags; 567 int mflags;
578 mapstruct *m; 568 maptile *m;
579 569
580#if 0 570#if 0
581 /* We need a better general purpose way to do this */ 571 /* We need a better general purpose way to do this */
582 572
583 /* peterm: added to make comet leave a trail of burnouts 573 /* peterm: added to make comet leave a trail of burnouts
584 it's an unadulterated hack, but the effect is cool. */ 574 it's an unadulterated hack, but the effect is cool. */
585 if (op->stats.sp == SP_METEOR) 575 if (op->stats.sp == SP_METEOR)
586 { 576 {
587 replace_insert_ob_in_map ("fire_trail", op); 577 replace_insert_ob_in_map ("fire_trail", op);
588 if (was_destroyed (op, op_tag)) 578 if (op->destroyed ())
589 return; 579 return;
590 } /* end addition. */ 580 } /* end addition. */
591#endif 581#endif
592 582
593 /* Reached the end of its life - remove it */ 583 /* Reached the end of its life - remove it */
594 if (--op->range <= 0) 584 if (--op->range <= 0)
595 { 585 {
596 if (op->other_arch) 586 if (op->other_arch)
597 {
598 explode_bullet (op); 587 explode_bullet (op);
599 }
600 else 588 else
601 { 589 op->destroy ();
602 remove_ob (op); 590
603 free_object (op);
604 }
605 return; 591 return;
606 } 592 }
607 593
608 new_x = op->x + DIRX (op); 594 new_x = op->x + DIRX (op);
609 new_y = op->y + DIRY (op); 595 new_y = op->y + DIRY (op);
610 m = op->map; 596 m = op->map;
611 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);
612 598
613 if (mflags & P_OUT_OF_MAP) 599 if (mflags & P_OUT_OF_MAP)
614 { 600 {
615 remove_ob (op); 601 op->destroy ();
616 free_object (op);
617 return; 602 return;
618 } 603 }
619 604
620 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)))
621 { 606 {
622 if (op->other_arch) 607 if (op->other_arch)
623 {
624 explode_bullet (op); 608 explode_bullet (op);
625 }
626 else 609 else
627 { 610 op->destroy ();
628 remove_ob (op); 611
629 free_object (op);
630 }
631 return; 612 return;
632 } 613 }
633 614
634 remove_ob (op); 615 op->remove ();
635 op->x = new_x; 616 op->x = new_x;
636 op->y = new_y; 617 op->y = new_y;
637 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL) 618 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL)
638 return; 619 return;
639 620
641 { 622 {
642 op->direction = absdir (op->direction + 4); 623 op->direction = absdir (op->direction + 4);
643 update_turn_face (op); 624 update_turn_face (op);
644 } 625 }
645 else 626 else
646 {
647 check_bullet (op); 627 check_bullet (op);
648 }
649} 628}
650 629
651 630
652 631
653 632
688 667
689 tmp->direction = dir; 668 tmp->direction = dir;
690 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 669 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
691 SET_ANIMATION (tmp, dir); 670 SET_ANIMATION (tmp, dir);
692 671
693 set_owner (tmp, op); 672 tmp->set_owner (op);
694 set_spell_skill (op, caster, spob, tmp); 673 set_spell_skill (op, caster, spob, tmp);
695 674
696 tmp->x = op->x + freearr_x[dir]; 675 tmp->x = op->x + freearr_x[dir];
697 tmp->y = op->y + freearr_y[dir]; 676 tmp->y = op->y + freearr_y[dir];
698 tmp->map = op->map; 677 tmp->map = op->map;
699 678
679 maptile *newmap;
700 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);
701 if (mflags & P_OUT_OF_MAP) 681 if (mflags & P_OUT_OF_MAP)
702 { 682 {
703 free_object (tmp); 683 tmp->destroy ();
704 return 0; 684 return 0;
705 } 685 }
686
687 tmp->map = newmap;
688
706 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)))
707 { 690 {
708 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 691 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
709 { 692 {
710 free_object (tmp); 693 tmp->destroy ();
711 return 0; 694 return 0;
712 } 695 }
696
713 tmp->x = op->x; 697 tmp->x = op->x;
714 tmp->y = op->y; 698 tmp->y = op->y;
715 tmp->direction = absdir (tmp->direction + 4); 699 tmp->direction = absdir (tmp->direction + 4);
716 tmp->map = op->map; 700 tmp->map = op->map;
717 } 701 }
702
718 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 703 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)))
719 {
720 check_bullet (tmp); 704 check_bullet (tmp);
721 } 705
722 return 1; 706 return 1;
723} 707}
724 708
725 709
726 710
739 object *new_ob = arch_to_object (op->other_arch); 723 object *new_ob = arch_to_object (op->other_arch);
740 724
741 new_ob->x = op->x; 725 new_ob->x = op->x;
742 new_ob->y = op->y; 726 new_ob->y = op->y;
743 new_ob->level = op->level; 727 new_ob->level = op->level;
744 set_owner (new_ob, op->owner); 728 new_ob->set_owner (op->owner);
745 729
746 /* preserve skill ownership */ 730 /* preserve skill ownership */
747 if (op->skill && op->skill != new_ob->skill) 731 if (op->skill && op->skill != new_ob->skill)
748 { 732 {
749 new_ob->skill = op->skill; 733 new_ob->skill = op->skill;
756 740
757void 741void
758move_cone (object *op) 742move_cone (object *op)
759{ 743{
760 int i; 744 int i;
761 tag_t tag;
762 745
763 /* 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 */
764 if (!op->map) 747 if (!op->map)
765 { 748 {
766 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");
767 op->speed = 0; 750 op->set_speed (0);
768 update_ob_speed (op);
769 return; 751 return;
770 } 752 }
771 753
772 /* lava saves it's life, but not yours :) */ 754 /* lava saves it's life, but not yours :) */
773 if (QUERY_FLAG (op, FLAG_LIFESAVE)) 755 if (QUERY_FLAG (op, FLAG_LIFESAVE))
779#if 0 761#if 0
780 /* Disable this - enabling it makes monsters easier, as 762 /* Disable this - enabling it makes monsters easier, as
781 * when their cone dies when they die. 763 * when their cone dies when they die.
782 */ 764 */
783 /* If no owner left, the spell dies out. */ 765 /* If no owner left, the spell dies out. */
784 if (get_owner (op) == NULL) 766 if (op->owner == NULL)
785 { 767 {
786 remove_ob (op); 768 op->destroy ();
787 free_object (op);
788 return; 769 return;
789 } 770 }
790#endif 771#endif
791 772
792 tag = op->count;
793 hit_map (op, 0, op->attacktype, 0); 773 hit_map (op, 0, op->attacktype, 0);
794 774
795 /* Check to see if we should push anything. 775 /* Check to see if we should push anything.
796 * Spell objects with weight push whatever they encounter to some 776 * Spell objects with weight push whatever they encounter to some
797 * degree. 777 * degree.
798 */ 778 */
799 if (op->weight) 779 if (op->weight)
800 check_spell_knockback (op); 780 check_spell_knockback (op);
801 781
802 if (was_destroyed (op, tag)) 782 if (op->destroyed ())
803 return; 783 return;
804 784
805 if ((op->duration--) < 0) 785 if ((op->duration--) < 0)
806 { 786 {
807 remove_ob (op); 787 op->destroy ();
808 free_object (op);
809 return; 788 return;
810 } 789 }
811 /* Object has hit maximum range, so don't have it move 790 /* Object has hit maximum range, so don't have it move
812 * any further. When the duration above expires, 791 * any further. When the duration above expires,
813 * then the object will get removed. 792 * then the object will get removed.
822 { 801 {
823 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)];
824 803
825 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))
826 { 805 {
827 object *tmp = get_object (); 806 object *tmp = op->clone ();
828 807
829 copy_object (op, tmp);
830 tmp->x = x; 808 tmp->x = x;
831 tmp->y = y; 809 tmp->y = y;
832 810
833 tmp->duration = op->duration + 1; 811 tmp->duration = op->duration + 1;
834 812
852int 830int
853cast_cone (object *op, object *caster, int dir, object *spell) 831cast_cone (object *op, object *caster, int dir, object *spell)
854{ 832{
855 object *tmp; 833 object *tmp;
856 int i, success = 0, range_min = -1, range_max = 1; 834 int i, success = 0, range_min = -1, range_max = 1;
857 mapstruct *m; 835 maptile *m;
858 sint16 sx, sy; 836 sint16 sx, sy;
859 MoveType movetype; 837 MoveType movetype;
860 838
861 if (!spell->other_arch) 839 if (!spell->other_arch)
862 return 0; 840 return 0;
918 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype) 896 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype)
919 continue; 897 continue;
920 898
921 success = 1; 899 success = 1;
922 tmp = arch_to_object (spell->other_arch); 900 tmp = arch_to_object (spell->other_arch);
923 set_owner (tmp, op); 901 tmp->set_owner (op);
924 set_spell_skill (op, caster, spell, tmp); 902 set_spell_skill (op, caster, spell, tmp);
925 tmp->level = caster_level (caster, spell); 903 tmp->level = caster_level (caster, spell);
926 tmp->x = sx; 904 tmp->x = sx;
927 tmp->y = sy; 905 tmp->y = sy;
928 tmp->attacktype = spell->attacktype; 906 tmp->attacktype = spell->attacktype;
1017 return; 995 return;
1018 996
1019 if (env->type == PLAYER) 997 if (env->type == PLAYER)
1020 esrv_del_item (env->contr, op->count); 998 esrv_del_item (env->contr, op->count);
1021 999
1022 remove_ob (op); 1000 op->remove ();
1023 op->x = env->x; 1001 op->x = env->x;
1024 op->y = env->y; 1002 op->y = env->y;
1025 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)
1026 return; 1004 return;
1027 } 1005 }
1029 // 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
1030 // 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
1031 // as bombs can be carried. 1009 // as bombs can be carried.
1032 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)
1033 { 1011 {
1034 remove_ob (op); 1012 op->destroy ();
1035 free_object (op);
1036 return; 1013 return;
1037 } 1014 }
1038 1015
1039 /* This copies a lot of the code from the fire bullet, 1016 /* This copies a lot of the code from the fire bullet,
1040 * but using the cast_bullet isn't really feasible, 1017 * but using the cast_bullet isn't really feasible,
1051 tmp->direction = i; 1028 tmp->direction = i;
1052 tmp->range = op->range; 1029 tmp->range = op->range;
1053 tmp->stats.dam = op->stats.dam; 1030 tmp->stats.dam = op->stats.dam;
1054 tmp->duration = op->duration; 1031 tmp->duration = op->duration;
1055 tmp->attacktype = op->attacktype; 1032 tmp->attacktype = op->attacktype;
1056 copy_owner (tmp, op); 1033 tmp->set_owner (op);
1057 if (op->skill && op->skill != tmp->skill) 1034 if (op->skill && op->skill != tmp->skill)
1058 { 1035 {
1059 tmp->skill = op->skill; 1036 tmp->skill = op->skill;
1060 } 1037 }
1061 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1038 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1075{ 1052{
1076 1053
1077 object *tmp; 1054 object *tmp;
1078 int mflags; 1055 int mflags;
1079 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir]; 1056 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir];
1080 mapstruct *m; 1057 maptile *m;
1081 1058
1082 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy); 1059 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy);
1083 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) 1060 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK))
1084 { 1061 {
1085 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1062 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
1091 tmp->range = spell->range + SP_level_range_adjust (caster, spell); 1068 tmp->range = spell->range + SP_level_range_adjust (caster, spell);
1092 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);
1093 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1070 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1094 tmp->attacktype = spell->attacktype; 1071 tmp->attacktype = spell->attacktype;
1095 1072
1096 set_owner (tmp, op); 1073 tmp->set_owner (op);
1097 set_spell_skill (op, caster, spell, tmp); 1074 set_spell_skill (op, caster, spell, tmp);
1098 tmp->x = dx; 1075 tmp->x = dx;
1099 tmp->y = dy; 1076 tmp->y = dy;
1100 insert_ob_in_map (tmp, m, op, 0); 1077 insert_ob_in_map (tmp, m, op, 0);
1101 return 1; 1078 return 1;
1121get_pointed_target (object *op, int dir, int range, int type) 1098get_pointed_target (object *op, int dir, int range, int type)
1122{ 1099{
1123 object *target; 1100 object *target;
1124 sint16 x, y; 1101 sint16 x, y;
1125 int dist, mflags; 1102 int dist, mflags;
1126 mapstruct *mp; 1103 maptile *mp;
1127 1104
1128 if (dir == 0) 1105 if (dir == 0)
1129 return NULL; 1106 return NULL;
1130 1107
1131 for (dist = 1; dist < range; dist++) 1108 for (dist = 1; dist < range; dist++)
1144 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW) 1121 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW)
1145 return NULL; 1122 return NULL;
1146 1123
1147 if (mflags & P_IS_ALIVE) 1124 if (mflags & P_IS_ALIVE)
1148 { 1125 {
1149 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)
1150 { 1127 {
1151 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER)) 1128 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER))
1152 { 1129 {
1153 return target; 1130 return target;
1154 } 1131 }
1221 if (effect->attacktype & AT_DEATH) 1198 if (effect->attacktype & AT_DEATH)
1222 { 1199 {
1223 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1200 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1224 1201
1225 /* casting death spells at undead isn't a good thing */ 1202 /* casting death spells at undead isn't a good thing */
1226 if QUERY_FLAG
1227 (target, FLAG_UNDEAD) 1203 if (QUERY_FLAG (target, FLAG_UNDEAD))
1228 { 1204 {
1229 if (random_roll (0, 2, op, PREFER_LOW)) 1205 if (random_roll (0, 2, op, PREFER_LOW))
1230 { 1206 {
1231 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!"); 1207 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!");
1232 effect->x = op->x; 1208 effect->x = op->x;
1234 } 1210 }
1235 else 1211 else
1236 { 1212 {
1237 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));
1238 target->stats.hp = target->stats.maxhp * 2; 1214 target->stats.hp = target->stats.maxhp * 2;
1239 free_object (effect); 1215 effect->destroy ();
1240 return 0; 1216 return 0;
1241 } 1217 }
1242 } 1218 }
1243 } 1219 }
1244 else 1220 else
1245 { 1221 {
1246 /* how much woe to inflict :) */ 1222 /* how much woe to inflict :) */
1247 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);
1248 } 1224 }
1249 1225
1250 set_owner (effect, op); 1226 effect->set_owner (op);
1251 set_spell_skill (op, caster, spell, effect); 1227 set_spell_skill (op, caster, spell, effect);
1252 1228
1253 /* ok, tell it where to be, and insert! */ 1229 /* ok, tell it where to be, and insert! */
1254 effect->x = target->x; 1230 effect->x = target->x;
1255 effect->y = target->y; 1231 effect->y = target->y;
1271move_missile (object *op) 1247move_missile (object *op)
1272{ 1248{
1273 int i, mflags; 1249 int i, mflags;
1274 object *owner; 1250 object *owner;
1275 sint16 new_x, new_y; 1251 sint16 new_x, new_y;
1276 mapstruct *m; 1252 maptile *m;
1277 1253
1278 if (op->range-- <= 0) 1254 if (op->range-- <= 0)
1279 { 1255 {
1280 remove_ob (op); 1256 op->destroy ();
1281 free_object (op);
1282 return; 1257 return;
1283 } 1258 }
1284 1259
1285 owner = get_owner (op); 1260 owner = op->owner;
1286#if 0 1261#if 0
1287 /* 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
1288 * monster that are then killed would continue to survive 1263 * monster that are then killed would continue to survive
1289 */ 1264 */
1290 if (owner == NULL) 1265 if (owner == NULL)
1291 { 1266 {
1292 remove_ob (op); 1267 op->destroy ();
1293 free_object (op);
1294 return; 1268 return;
1295 } 1269 }
1296#endif 1270#endif
1297 1271
1298 new_x = op->x + DIRX (op); 1272 new_x = op->x + DIRX (op);
1300 1274
1301 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y); 1275 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y);
1302 1276
1303 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))) 1277 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))))
1304 { 1278 {
1305 tag_t tag = op->count;
1306
1307 hit_map (op, op->direction, AT_MAGIC, 1); 1279 hit_map (op, op->direction, AT_MAGIC, 1);
1308 /* Basically, missile only hits one thing then goes away. 1280 /* Basically, missile only hits one thing then goes away.
1309 * 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.
1310 */ 1282 */
1311 if (!was_destroyed (op, tag)) 1283 if (!op->destroyed ())
1312 { 1284 op->destroy ();
1313 remove_ob (op); 1285
1314 free_object (op);
1315 }
1316 return; 1286 return;
1317 } 1287 }
1318 1288
1319 remove_ob (op); 1289 op->remove ();
1290
1320 if (!op->direction || (mflags & P_OUT_OF_MAP)) 1291 if (!op->direction || (mflags & P_OUT_OF_MAP))
1321 { 1292 {
1322 free_object (op); 1293 op->destroy ();
1323 return; 1294 return;
1324 } 1295 }
1296
1325 op->x = new_x; 1297 op->x = new_x;
1326 op->y = new_y; 1298 op->y = new_y;
1327 op->map = m; 1299 op->map = m;
1328 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);
1329 if (i > 0 && i != op->direction) 1301 if (i > 0 && i != op->direction)
1330 { 1302 {
1331 op->direction = i; 1303 op->direction = i;
1332 SET_ANIMATION (op, op->direction); 1304 SET_ANIMATION (op, op->direction);
1333 } 1305 }
1306
1334 insert_ob_in_map (op, op->map, op, 0); 1307 insert_ob_in_map (op, op->map, op, 0);
1335} 1308}
1336 1309
1337/**************************************************************************** 1310/****************************************************************************
1338 * Destruction 1311 * Destruction
1384int 1357int
1385cast_destruction (object *op, object *caster, object *spell_ob) 1358cast_destruction (object *op, object *caster, object *spell_ob)
1386{ 1359{
1387 int i, j, range, mflags, friendly = 0, dam, dur; 1360 int i, j, range, mflags, friendly = 0, dam, dur;
1388 sint16 sx, sy; 1361 sint16 sx, sy;
1389 mapstruct *m; 1362 maptile *m;
1390 object *tmp; 1363 object *tmp;
1391 const char *skill; 1364 const char *skill;
1392 1365
1393 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 1366 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
1394 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 1367 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
1422 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1395 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1423 if (mflags & P_OUT_OF_MAP) 1396 if (mflags & P_OUT_OF_MAP)
1424 continue; 1397 continue;
1425 if (mflags & P_IS_ALIVE) 1398 if (mflags & P_IS_ALIVE)
1426 { 1399 {
1427 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)
1428 { 1401 {
1429 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1402 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1430 break; 1403 break;
1431 } 1404 }
1432 if (tmp) 1405 if (tmp)
1555 force->stats.ac = spell_ob->stats.ac; 1528 force->stats.ac = spell_ob->stats.ac;
1556 force->stats.wc = spell_ob->stats.wc; 1529 force->stats.wc = spell_ob->stats.wc;
1557 1530
1558 change_abil (tmp, force); /* Mostly to display any messages */ 1531 change_abil (tmp, force); /* Mostly to display any messages */
1559 insert_ob_in_ob (force, tmp); 1532 insert_ob_in_ob (force, tmp);
1560 fix_player (tmp); 1533 tmp->update_stats ();
1561 return 1; 1534 return 1;
1562 1535
1563} 1536}
1564 1537
1565 1538
1576mood_change (object *op, object *caster, object *spell) 1549mood_change (object *op, object *caster, object *spell)
1577{ 1550{
1578 object *tmp, *god, *head; 1551 object *tmp, *god, *head;
1579 int done_one, range, mflags, level, at, best_at; 1552 int done_one, range, mflags, level, at, best_at;
1580 sint16 x, y, nx, ny; 1553 sint16 x, y, nx, ny;
1581 mapstruct *m; 1554 maptile *m;
1582 const char *race; 1555 const char *race;
1583 1556
1584 /* We precompute some values here so that we don't have to keep 1557 /* We precompute some values here so that we don't have to keep
1585 * doing it over and over again. 1558 * doing it over and over again.
1586 */ 1559 */
1616 1589
1617 /* 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 */
1618 if (!(mflags & P_IS_ALIVE)) 1591 if (!(mflags & P_IS_ALIVE))
1619 continue; 1592 continue;
1620 1593
1621 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)
1622 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1595 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1623 break; 1596 break;
1624 1597
1625 /* There can be living objects that are not monsters */ 1598 /* There can be living objects that are not monsters */
1626 if (!tmp || tmp->type == PLAYER) 1599 if (!tmp || tmp->type == PLAYER)
1714 SET_FLAG (head, FLAG_FRIENDLY); 1687 SET_FLAG (head, FLAG_FRIENDLY);
1715 /* Prevent uncontolled outbreaks of self replicating monsters. 1688 /* Prevent uncontolled outbreaks of self replicating monsters.
1716 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.
1717 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. */
1718 CLEAR_FLAG (head, FLAG_GENERATOR); 1691 CLEAR_FLAG (head, FLAG_GENERATOR);
1719 set_owner (head, op); 1692 head->set_owner (op);
1720 set_spell_skill (op, caster, spell, head); 1693 set_spell_skill (op, caster, spell, head);
1721 add_friendly_object (head); 1694 add_friendly_object (head);
1722 head->attack_movement = PETMOVE; 1695 head->attack_movement = PETMOVE;
1723 done_one = 1; 1696 done_one = 1;
1724 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);
1750move_ball_spell (object *op) 1723move_ball_spell (object *op)
1751{ 1724{
1752 int i, j, dam_save, dir, mflags; 1725 int i, j, dam_save, dir, mflags;
1753 sint16 nx, ny, hx, hy; 1726 sint16 nx, ny, hx, hy;
1754 object *owner; 1727 object *owner;
1755 mapstruct *m; 1728 maptile *m;
1756 1729
1757 owner = get_owner (op); 1730 owner = op->owner;
1758 1731
1759 /* 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,
1760 * 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
1761 * victim. The block immediately below more or less chooses a random 1734 * victim. The block immediately below more or less chooses a random
1762 * 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
1791 nx = op->x; 1764 nx = op->x;
1792 ny = op->y; 1765 ny = op->y;
1793 m = op->map; 1766 m = op->map;
1794 } 1767 }
1795 1768
1796 remove_ob (op); 1769 op->remove ();
1797 op->y = ny; 1770 op->y = ny;
1798 op->x = nx; 1771 op->x = nx;
1799 insert_ob_in_map (op, m, op, 0); 1772 insert_ob_in_map (op, m, op, 0);
1800 1773
1801 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
1841 } 1814 }
1842 1815
1843 /* restore to the center location and damage */ 1816 /* restore to the center location and damage */
1844 op->stats.dam = dam_save; 1817 op->stats.dam = dam_save;
1845 1818
1846 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);
1847 1820
1848 if (i >= 0) 1821 if (i >= 0)
1849 { /* we have a preferred direction! */ 1822 { /* we have a preferred direction! */
1850 /* pick another direction if the preferred dir is blocked. */ 1823 /* pick another direction if the preferred dir is blocked. */
1851 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 ||
1872#if 0 1845#if 0
1873 static int cardinal_adjust[9] = { -3, -2, -1, 0, 0, 0, 1, 2, 3 }; 1846 static int cardinal_adjust[9] = { -3, -2, -1, 0, 0, 0, 1, 2, 3 };
1874 static int diagonal_adjust[10] = { -3, -2, -2, -1, 0, 0, 1, 2, 2, 3 }; 1847 static int diagonal_adjust[10] = { -3, -2, -2, -1, 0, 0, 1, 2, 2, 3 };
1875 sint16 target_x, target_y, origin_x, origin_y; 1848 sint16 target_x, target_y, origin_x, origin_y;
1876 int adjustdir; 1849 int adjustdir;
1877 mapstruct *m; 1850 maptile *m;
1878#endif 1851#endif
1879 int basedir; 1852 int basedir;
1880 object *owner; 1853 object *owner;
1881 1854
1882 owner = get_owner (op); 1855 owner = op->owner;
1883 if (op->duration == 0 || owner == NULL) 1856 if (op->duration == 0 || owner == NULL)
1884 { 1857 {
1885 remove_ob (op); 1858 op->destroy ();
1886 free_object (op);
1887 return; 1859 return;
1888 } 1860 }
1861
1889 op->duration--; 1862 op->duration--;
1890 1863
1891 basedir = op->direction; 1864 basedir = op->direction;
1892 if (basedir == 0) 1865 if (basedir == 0)
1893 { 1866 {
1992 return 0; 1965 return 0;
1993 1966
1994 tmp = get_archetype (SWARM_SPELL); 1967 tmp = get_archetype (SWARM_SPELL);
1995 tmp->x = op->x; 1968 tmp->x = op->x;
1996 tmp->y = op->y; 1969 tmp->y = op->y;
1997 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. */
1998 set_spell_skill (op, caster, spell, tmp); 1971 set_spell_skill (op, caster, spell, tmp);
1999 1972
2000 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. */
2001 tmp->spell = arch_to_object (spell->other_arch); 1974 tmp->spell = arch_to_object (spell->other_arch);
2002 1975
2025cast_light (object *op, object *caster, object *spell, int dir) 1998cast_light (object *op, object *caster, object *spell, int dir)
2026{ 1999{
2027 object *target = NULL, *tmp = NULL; 2000 object *target = NULL, *tmp = NULL;
2028 sint16 x, y; 2001 sint16 x, y;
2029 int dam, mflags; 2002 int dam, mflags;
2030 mapstruct *m; 2003 maptile *m;
2031 2004
2032 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2005 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2033 2006
2034 if (!dir) 2007 if (!dir)
2035 { 2008 {
2049 return 0; 2022 return 0;
2050 } 2023 }
2051 2024
2052 if (mflags & P_IS_ALIVE && spell->attacktype) 2025 if (mflags & P_IS_ALIVE && spell->attacktype)
2053 { 2026 {
2054 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)
2055 if (QUERY_FLAG (target, FLAG_MONSTER)) 2028 if (QUERY_FLAG (target, FLAG_MONSTER))
2056 { 2029 {
2057 /* oky doky. got a target monster. Lets make a blinding attack */ 2030 /* oky doky. got a target monster. Lets make a blinding attack */
2058 if (target->head) 2031 if (target->head)
2059 target = target->head; 2032 target = target->head;
2103cast_cause_disease (object *op, object *caster, object *spell, int dir) 2076cast_cause_disease (object *op, object *caster, object *spell, int dir)
2104{ 2077{
2105 sint16 x, y; 2078 sint16 x, y;
2106 int i, mflags, range, dam_mod, dur_mod; 2079 int i, mflags, range, dam_mod, dur_mod;
2107 object *walk; 2080 object *walk;
2108 mapstruct *m; 2081 maptile *m;
2109 2082
2110 x = op->x; 2083 x = op->x;
2111 y = op->y; 2084 y = op->y;
2112 2085
2113 /* If casting from a scroll, no direction will be available, so refer to the 2086 /* If casting from a scroll, no direction will be available, so refer to the
2141 2114
2142 /* 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 */
2143 if (mflags & P_IS_ALIVE) 2116 if (mflags & P_IS_ALIVE)
2144 { 2117 {
2145 /* search this square for a victim */ 2118 /* search this square for a victim */
2146 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)
2147 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) 2120 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER))
2148 { /* found a victim */ 2121 { /* found a victim */
2149 object *disease = arch_to_object (spell->other_arch); 2122 object *disease = arch_to_object (spell->other_arch);
2150 2123
2151 set_owner (disease, op); 2124 disease->set_owner (op);
2152 set_spell_skill (op, caster, spell, disease); 2125 set_spell_skill (op, caster, spell, disease);
2153 disease->stats.exp = 0; 2126 disease->stats.exp = 0;
2154 disease->level = caster_level (caster, spell); 2127 disease->level = caster_level (caster, spell);
2155 2128
2156 /* do level adjustments */ 2129 /* do level adjustments */
2205 { 2178 {
2206 object *flash; /* visual effect for inflicting disease */ 2179 object *flash; /* visual effect for inflicting disease */
2207 2180
2208 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);
2209 2182
2210 free_object (disease); /* don't need this one anymore */ 2183 disease->destroy (); /* don't need this one anymore */
2211 flash = get_archetype (ARCH_DETECT_MAGIC); 2184 flash = get_archetype (ARCH_DETECT_MAGIC);
2212 flash->x = x; 2185 flash->x = x;
2213 flash->y = y; 2186 flash->y = y;
2214 flash->map = walk->map; 2187 flash->map = walk->map;
2215 insert_ob_in_map (flash, walk->map, op, 0); 2188 insert_ob_in_map (flash, walk->map, op, 0);
2216 return 1; 2189 return 1;
2217 } 2190 }
2218 free_object (disease); 2191
2192 disease->destroy ();
2219 } 2193 }
2220 } /* if living creature */ 2194 } /* if living creature */
2221 } /* for range of spaces */ 2195 } /* for range of spaces */
2222 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2196 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2223 return 1; 2197 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines