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.11 by root, Mon Sep 11 20:26:41 2006 UTC vs.
Revision 1.23 by root, Mon Dec 25 11:25:50 2006 UTC

1
2/*
3 * static char *rcsid_spell_attack_c =
4 * "$Id: spell_attack.C,v 1.11 2006/09/11 20:26:41 root Exp $";
5 */
6
7
8/* 1/*
9 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
10 3
11 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team
12 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
23 16
24 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 20
28 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
29*/ 22*/
30 23
31/* This file contains all the spell attack code. Grouping this code 24/* This file contains all the spell attack code. Grouping this code
32 * together should hopefully make it easier to find the relevent bits 25 * together should hopefully make it easier to find the relevent bits
33 * of code 26 * of code
64 { 57 {
65 weight_move = op->weight + (op->weight * op->level) / 3; 58 weight_move = op->weight + (op->weight * op->level) / 3;
66 /*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); */
67 } 60 }
68 61
69 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)
70 { 63 {
71 int num_sections = 1; 64 int num_sections = 1;
72 65
73 /* don't move DM */ 66 /* don't move DM */
74 if (QUERY_FLAG (tmp, FLAG_WIZ)) 67 if (QUERY_FLAG (tmp, FLAG_WIZ))
124void 117void
125forklightning (object *op, object *tmp) 118forklightning (object *op, object *tmp)
126{ 119{
127 int new_dir = 1; /* direction or -1 for left, +1 for right 0 if no new bolt */ 120 int new_dir = 1; /* direction or -1 for left, +1 for right 0 if no new bolt */
128 int t_dir; /* stores temporary dir calculation */ 121 int t_dir; /* stores temporary dir calculation */
129 mapstruct *m; 122 maptile *m;
130 sint16 sx, sy; 123 sint16 sx, sy;
131 object *new_bolt; 124 object *new_bolt;
132 125
133 /* pick a fork direction. tmp->stats.Con is the left bias 126 /* pick a fork direction. tmp->stats.Con is the left bias
134 * i.e., the chance in 100 of forking LEFT 127 * i.e., the chance in 100 of forking LEFT
147 140
148 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)))
149 return; 142 return;
150 143
151 /* OK, we made a fork */ 144 /* OK, we made a fork */
152 new_bolt = get_object (); 145 new_bolt = tmp->clone ();
153 copy_object (tmp, new_bolt);
154 146
155 /* reduce chances of subsequent forking */ 147 /* reduce chances of subsequent forking */
156 new_bolt->stats.Dex -= 10; 148 new_bolt->stats.Dex -= 10;
157 tmp->stats.Dex -= 10; /* less forks from main bolt too */ 149 tmp->stats.Dex -= 10; /* less forks from main bolt too */
158 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */ 150 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */
177move_bolt (object *op) 169move_bolt (object *op)
178{ 170{
179 object *tmp; 171 object *tmp;
180 int mflags; 172 int mflags;
181 sint16 x, y; 173 sint16 x, y;
182 mapstruct *m; 174 maptile *m;
183 175
184 if (--(op->duration) < 0) 176 if (--(op->duration) < 0)
185 { 177 {
186 remove_ob (op); 178 op->destroy ();
187 free_object (op);
188 return; 179 return;
189 } 180 }
190 181
191 hit_map (op, 0, op->attacktype, 1); 182 hit_map (op, 0, op->attacktype, 1);
192 183
257 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */ 248 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */
258 return; 249 return;
259 } 250 }
260 else 251 else
261 { /* Create a copy of this object and put it ahead */ 252 { /* Create a copy of this object and put it ahead */
262 tmp = get_object (); 253 tmp = op->clone ();
263 copy_object (op, tmp); 254
264 tmp->speed_left = -0.1; 255 tmp->speed_left = -0.1;
265 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp); 256 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp);
266 tmp = insert_ob_in_map (tmp, op->map, op, 0); 257 tmp = insert_ob_in_map (tmp, op->map, op, 0);
267 /* 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 */
268 tmp->duration++; 259 tmp->duration++;
289 * we remove the magic flag - that can be derived from 280 * we remove the magic flag - that can be derived from
290 * spob->attacktype. 281 * spob->attacktype.
291 * This function sets up the appropriate owner and skill 282 * This function sets up the appropriate owner and skill
292 * pointers. 283 * pointers.
293 */ 284 */
294
295int 285int
296fire_bolt (object *op, object *caster, int dir, object *spob, object *skill) 286fire_bolt (object *op, object *caster, int dir, object *spob, object *skill)
297{ 287{
298 object *tmp = NULL; 288 object *tmp = NULL;
299 int mflags; 289 int mflags;
317 307
318 tmp->direction = dir; 308 tmp->direction = dir;
319 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 309 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
320 SET_ANIMATION (tmp, dir); 310 SET_ANIMATION (tmp, dir);
321 311
322 set_owner (tmp, op); 312 tmp->set_owner (op);
323 set_spell_skill (op, caster, spob, tmp); 313 set_spell_skill (op, caster, spob, tmp);
324 314
325 tmp->x = op->x + DIRX (tmp); 315 tmp->x = op->x + DIRX (tmp);
326 tmp->y = op->y + DIRY (tmp); 316 tmp->y = op->y + DIRY (tmp);
327 tmp->map = op->map; 317 tmp->map = op->map;
328 318
319 maptile *newmap;
329 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);
330 if (mflags & P_OUT_OF_MAP) 321 if (mflags & P_OUT_OF_MAP)
331 { 322 {
332 free_object (tmp); 323 tmp->destroy ();
333 return 0; 324 return 0;
334 } 325 }
326
327 tmp->map = newmap;
328
335 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)))
336 { 330 {
337 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 331 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
338 { 332 {
339 free_object (tmp); 333 tmp->destroy ();
340 return 0; 334 return 0;
341 } 335 }
336
342 tmp->x = op->x; 337 tmp->x = op->x;
343 tmp->y = op->y; 338 tmp->y = op->y;
344 tmp->direction = absdir (tmp->direction + 4); 339 tmp->direction = absdir (tmp->direction + 4);
345 tmp->map = op->map; 340 tmp->map = op->map;
346 } 341 }
342
347 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)
348 move_bolt (tmp); 344 move_bolt (tmp);
345
349 return 1; 346 return 1;
350} 347}
351 348
352 349
353 350
363 */ 360 */
364void 361void
365explosion (object *op) 362explosion (object *op)
366{ 363{
367 object *tmp; 364 object *tmp;
368 mapstruct *m = op->map; 365 maptile *m = op->map;
369 int i; 366 int i;
370 367
371 if (--(op->duration) < 0) 368 if (--(op->duration) < 0)
372 { 369 {
373 remove_ob (op); 370 op->destroy ();
374 free_object (op);
375 return; 371 return;
376 } 372 }
373
377 hit_map (op, 0, op->attacktype, 0); 374 hit_map (op, 0, op->attacktype, 0);
378 375
379 if (op->range > 0) 376 if (op->range > 0)
380 { 377 {
381 for (i = 1; i < 9; i++) 378 for (i = 1; i < 9; i++)
387 /* ok_to_put_more already does things like checks for walls, 384 /* ok_to_put_more already does things like checks for walls,
388 * out of map, etc. 385 * out of map, etc.
389 */ 386 */
390 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))
391 { 388 {
392 tmp = get_object (); 389 tmp = op->clone ();
393 copy_object (op, tmp);
394 tmp->state = 0; 390 tmp->state = 0;
395 tmp->speed_left = -0.21; 391 tmp->speed_left = -0.21;
396 tmp->range--; 392 tmp->range--;
397 tmp->value = 0; 393 tmp->value = 0;
398 tmp->x = dx; 394 tmp->x = dx;
409 * explode. 405 * explode.
410 */ 406 */
411void 407void
412explode_bullet (object *op) 408explode_bullet (object *op)
413{ 409{
414 tag_t op_tag = op->count;
415 object *tmp, *owner; 410 object *tmp, *owner;
416 411
417 if (op->other_arch == NULL) 412 if (op->other_arch == NULL)
418 { 413 {
419 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 414 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
420 remove_ob (op); 415 op->destroy ();
421 free_object (op);
422 return; 416 return;
423 } 417 }
424 418
425 if (op->env) 419 if (op->env)
426 { 420 {
428 422
429 env = object_get_env_recursive (op); 423 env = object_get_env_recursive (op);
430 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))
431 { 425 {
432 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 426 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
433 remove_ob (op); 427 op->destroy ();
434 free_object (op);
435 return; 428 return;
436 } 429 }
430
437 remove_ob (op); 431 op->remove ();
438 op->x = env->x; 432 op->x = env->x;
439 op->y = env->y; 433 op->y = env->y;
440 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);
441 } 435 }
442 else if (out_of_map (op->map, op->x, op->y)) 436 else if (out_of_map (op->map, op->x, op->y))
443 { 437 {
444 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 438 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
445 remove_ob (op); 439 op->destroy ();
446 free_object (op);
447 return; 440 return;
448 } 441 }
449 442
450 // 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
451 // 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
452 // bad at the moment that might happen from this. 445 // bad at the moment that might happen from this.
453 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)
454 { 447 {
455 remove_ob (op); 448 op->destroy ();
456 free_object (op);
457 return; 449 return;
458 } 450 }
459 451
460 if (op->attacktype) 452 if (op->attacktype)
461 { 453 {
462 hit_map (op, 0, op->attacktype, 1); 454 hit_map (op, 0, op->attacktype, 1);
463 if (was_destroyed (op, op_tag)) 455 if (op->destroyed ())
464 return; 456 return;
465 } 457 }
466 458
467 /* other_arch contains what this explodes into */ 459 /* other_arch contains what this explodes into */
468 tmp = arch_to_object (op->other_arch); 460 tmp = arch_to_object (op->other_arch);
469 461
470 copy_owner (tmp, op); 462 tmp->set_owner (op);
471 tmp->skill = op->skill; 463 tmp->skill = op->skill;
472 464
473 owner = get_owner (op); 465 owner = op->owner;
474 466
475 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))
476 { 468 {
477 remove_ob (op); 469 op->destroy ();
478 free_object (op);
479 return; 470 return;
480 } 471 }
481 472
482 tmp->x = op->x; 473 tmp->x = op->x;
483 tmp->y = op->y; 474 tmp->y = op->y;
511 /* Prevent recursion */ 502 /* Prevent recursion */
512 op->move_on = 0; 503 op->move_on = 0;
513 504
514 insert_ob_in_map (tmp, op->map, op, 0); 505 insert_ob_in_map (tmp, op->map, op, 0);
515 /* remove the firebullet */ 506 /* remove the firebullet */
516 if (!was_destroyed (op, op_tag)) 507 if (!op->destroyed ())
517 { 508 {
518 remove_ob (op); 509 op->destroy ();
519 free_object (op);
520 } 510 }
521} 511}
522 512
523 513
524 514
527 */ 517 */
528 518
529void 519void
530check_bullet (object *op) 520check_bullet (object *op)
531{ 521{
532 tag_t op_tag = op->count, tmp_tag;
533 object *tmp; 522 object *tmp;
534 int dam, mflags; 523 int dam, mflags;
535 mapstruct *m; 524 maptile *m;
536 sint16 sx, sy; 525 sint16 sx, sy;
537 526
538 mflags = get_map_flags (op->map, &m, op->x, op->y, &sx, &sy); 527 mflags = get_map_flags (op->map, &m, op->x, op->y, &sx, &sy);
539 528
540 if (!(mflags & P_IS_ALIVE) && !OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy))) 529 if (!(mflags & P_IS_ALIVE) && !OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
549 538
550 /* 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 */
551 if (!(mflags & P_IS_ALIVE)) 540 if (!(mflags & P_IS_ALIVE))
552 return; 541 return;
553 542
554 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)
555 { 544 {
556 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 545 if (QUERY_FLAG (tmp, FLAG_ALIVE))
557 { 546 {
558 tmp_tag = tmp->count;
559 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 547 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
560 if (was_destroyed (op, op_tag) || !was_destroyed (tmp, tmp_tag) || (op->stats.dam -= dam) < 0) 548 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
561 { 549 {
562 if (!QUERY_FLAG (op, FLAG_REMOVED)) 550 if (!QUERY_FLAG (op, FLAG_REMOVED))
563 { 551 {
564 remove_ob (op); 552 op->destroy ();
565 free_object (op);
566 return; 553 return;
567 } 554 }
568 } 555 }
569 } 556 }
570 } 557 }
571} 558}
572
573 559
574/* Basically, we move 'op' one square, and if it hits something, 560/* Basically, we move 'op' one square, and if it hits something,
575 * call check_bullet. 561 * call check_bullet.
576 * This function is only applicable to bullets, but not to all 562 * This function is only applicable to bullets, but not to all
577 * fired arches (eg, bolts). 563 * fired arches (eg, bolts).
578 */ 564 */
579
580void 565void
581move_bullet (object *op) 566move_bullet (object *op)
582{ 567{
583 sint16 new_x, new_y; 568 sint16 new_x, new_y;
584 int mflags; 569 int mflags;
585 mapstruct *m; 570 maptile *m;
586 571
587#if 0 572#if 0
588 /* We need a better general purpose way to do this */ 573 /* We need a better general purpose way to do this */
589 574
590 /* peterm: added to make comet leave a trail of burnouts 575 /* peterm: added to make comet leave a trail of burnouts
591 it's an unadulterated hack, but the effect is cool. */ 576 it's an unadulterated hack, but the effect is cool. */
592 if (op->stats.sp == SP_METEOR) 577 if (op->stats.sp == SP_METEOR)
593 { 578 {
594 replace_insert_ob_in_map ("fire_trail", op); 579 replace_insert_ob_in_map ("fire_trail", op);
595 if (was_destroyed (op, op_tag)) 580 if (op->destroyed ())
596 return; 581 return;
597 } /* end addition. */ 582 } /* end addition. */
598#endif 583#endif
599 584
600 /* Reached the end of its life - remove it */ 585 /* Reached the end of its life - remove it */
601 if (--op->range <= 0) 586 if (--op->range <= 0)
602 { 587 {
603 if (op->other_arch) 588 if (op->other_arch)
604 {
605 explode_bullet (op); 589 explode_bullet (op);
606 }
607 else 590 else
608 { 591 op->destroy ();
609 remove_ob (op); 592
610 free_object (op);
611 }
612 return; 593 return;
613 } 594 }
614 595
615 new_x = op->x + DIRX (op); 596 new_x = op->x + DIRX (op);
616 new_y = op->y + DIRY (op); 597 new_y = op->y + DIRY (op);
617 m = op->map; 598 m = op->map;
618 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);
619 600
620 if (mflags & P_OUT_OF_MAP) 601 if (mflags & P_OUT_OF_MAP)
621 { 602 {
622 remove_ob (op); 603 op->destroy ();
623 free_object (op);
624 return; 604 return;
625 } 605 }
626 606
627 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)))
628 { 608 {
629 if (op->other_arch) 609 if (op->other_arch)
630 {
631 explode_bullet (op); 610 explode_bullet (op);
632 }
633 else 611 else
634 { 612 op->destroy ();
635 remove_ob (op); 613
636 free_object (op);
637 }
638 return; 614 return;
639 } 615 }
640 616
641 remove_ob (op); 617 op->remove ();
642 op->x = new_x; 618 op->x = new_x;
643 op->y = new_y; 619 op->y = new_y;
644 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL) 620 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL)
645 return; 621 return;
646 622
648 { 624 {
649 op->direction = absdir (op->direction + 4); 625 op->direction = absdir (op->direction + 4);
650 update_turn_face (op); 626 update_turn_face (op);
651 } 627 }
652 else 628 else
653 {
654 check_bullet (op); 629 check_bullet (op);
655 }
656} 630}
657 631
658 632
659 633
660 634
695 669
696 tmp->direction = dir; 670 tmp->direction = dir;
697 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 671 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
698 SET_ANIMATION (tmp, dir); 672 SET_ANIMATION (tmp, dir);
699 673
700 set_owner (tmp, op); 674 tmp->set_owner (op);
701 set_spell_skill (op, caster, spob, tmp); 675 set_spell_skill (op, caster, spob, tmp);
702 676
703 tmp->x = op->x + freearr_x[dir]; 677 tmp->x = op->x + freearr_x[dir];
704 tmp->y = op->y + freearr_y[dir]; 678 tmp->y = op->y + freearr_y[dir];
705 tmp->map = op->map; 679 tmp->map = op->map;
706 680
681 maptile *newmap;
707 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);
708 if (mflags & P_OUT_OF_MAP) 683 if (mflags & P_OUT_OF_MAP)
709 { 684 {
710 free_object (tmp); 685 tmp->destroy ();
711 return 0; 686 return 0;
712 } 687 }
688
689 tmp->map = newmap;
690
713 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)))
714 { 692 {
715 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 693 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
716 { 694 {
717 free_object (tmp); 695 tmp->destroy ();
718 return 0; 696 return 0;
719 } 697 }
698
720 tmp->x = op->x; 699 tmp->x = op->x;
721 tmp->y = op->y; 700 tmp->y = op->y;
722 tmp->direction = absdir (tmp->direction + 4); 701 tmp->direction = absdir (tmp->direction + 4);
723 tmp->map = op->map; 702 tmp->map = op->map;
724 } 703 }
704
725 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 705 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)))
726 {
727 check_bullet (tmp); 706 check_bullet (tmp);
728 } 707
729 return 1; 708 return 1;
730} 709}
731 710
732 711
733 712
746 object *new_ob = arch_to_object (op->other_arch); 725 object *new_ob = arch_to_object (op->other_arch);
747 726
748 new_ob->x = op->x; 727 new_ob->x = op->x;
749 new_ob->y = op->y; 728 new_ob->y = op->y;
750 new_ob->level = op->level; 729 new_ob->level = op->level;
751 set_owner (new_ob, op->owner); 730 new_ob->set_owner (op->owner);
752 731
753 /* preserve skill ownership */ 732 /* preserve skill ownership */
754 if (op->skill && op->skill != new_ob->skill) 733 if (op->skill && op->skill != new_ob->skill)
755 { 734 {
756 new_ob->skill = op->skill; 735 new_ob->skill = op->skill;
763 742
764void 743void
765move_cone (object *op) 744move_cone (object *op)
766{ 745{
767 int i; 746 int i;
768 tag_t tag;
769 747
770 /* if no map then hit_map will crash so just ignore object */ 748 /* if no map then hit_map will crash so just ignore object */
771 if (!op->map) 749 if (!op->map)
772 { 750 {
773 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 751 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
786#if 0 764#if 0
787 /* Disable this - enabling it makes monsters easier, as 765 /* Disable this - enabling it makes monsters easier, as
788 * when their cone dies when they die. 766 * when their cone dies when they die.
789 */ 767 */
790 /* If no owner left, the spell dies out. */ 768 /* If no owner left, the spell dies out. */
791 if (get_owner (op) == NULL) 769 if (op->owner == NULL)
792 { 770 {
793 remove_ob (op); 771 op->destroy ();
794 free_object (op);
795 return; 772 return;
796 } 773 }
797#endif 774#endif
798 775
799 tag = op->count;
800 hit_map (op, 0, op->attacktype, 0); 776 hit_map (op, 0, op->attacktype, 0);
801 777
802 /* Check to see if we should push anything. 778 /* Check to see if we should push anything.
803 * Spell objects with weight push whatever they encounter to some 779 * Spell objects with weight push whatever they encounter to some
804 * degree. 780 * degree.
805 */ 781 */
806 if (op->weight) 782 if (op->weight)
807 check_spell_knockback (op); 783 check_spell_knockback (op);
808 784
809 if (was_destroyed (op, tag)) 785 if (op->destroyed ())
810 return; 786 return;
811 787
812 if ((op->duration--) < 0) 788 if ((op->duration--) < 0)
813 { 789 {
814 remove_ob (op); 790 op->destroy ();
815 free_object (op);
816 return; 791 return;
817 } 792 }
818 /* Object has hit maximum range, so don't have it move 793 /* Object has hit maximum range, so don't have it move
819 * any further. When the duration above expires, 794 * any further. When the duration above expires,
820 * then the object will get removed. 795 * then the object will get removed.
829 { 804 {
830 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)];
831 806
832 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))
833 { 808 {
834 object *tmp = get_object (); 809 object *tmp = op->clone ();
835 810
836 copy_object (op, tmp);
837 tmp->x = x; 811 tmp->x = x;
838 tmp->y = y; 812 tmp->y = y;
839 813
840 tmp->duration = op->duration + 1; 814 tmp->duration = op->duration + 1;
841 815
859int 833int
860cast_cone (object *op, object *caster, int dir, object *spell) 834cast_cone (object *op, object *caster, int dir, object *spell)
861{ 835{
862 object *tmp; 836 object *tmp;
863 int i, success = 0, range_min = -1, range_max = 1; 837 int i, success = 0, range_min = -1, range_max = 1;
864 mapstruct *m; 838 maptile *m;
865 sint16 sx, sy; 839 sint16 sx, sy;
866 MoveType movetype; 840 MoveType movetype;
867 841
868 if (!spell->other_arch) 842 if (!spell->other_arch)
869 return 0; 843 return 0;
925 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype) 899 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype)
926 continue; 900 continue;
927 901
928 success = 1; 902 success = 1;
929 tmp = arch_to_object (spell->other_arch); 903 tmp = arch_to_object (spell->other_arch);
930 set_owner (tmp, op); 904 tmp->set_owner (op);
931 set_spell_skill (op, caster, spell, tmp); 905 set_spell_skill (op, caster, spell, tmp);
932 tmp->level = caster_level (caster, spell); 906 tmp->level = caster_level (caster, spell);
933 tmp->x = sx; 907 tmp->x = sx;
934 tmp->y = sy; 908 tmp->y = sy;
935 tmp->attacktype = spell->attacktype; 909 tmp->attacktype = spell->attacktype;
1024 return; 998 return;
1025 999
1026 if (env->type == PLAYER) 1000 if (env->type == PLAYER)
1027 esrv_del_item (env->contr, op->count); 1001 esrv_del_item (env->contr, op->count);
1028 1002
1029 remove_ob (op); 1003 op->remove ();
1030 op->x = env->x; 1004 op->x = env->x;
1031 op->y = env->y; 1005 op->y = env->y;
1032 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL) 1006 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL)
1033 return; 1007 return;
1034 } 1008 }
1036 // 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
1037 // 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
1038 // as bombs can be carried. 1012 // as bombs can be carried.
1039 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)
1040 { 1014 {
1041 remove_ob (op); 1015 op->destroy ();
1042 free_object (op);
1043 return; 1016 return;
1044 } 1017 }
1045 1018
1046 /* This copies a lot of the code from the fire bullet, 1019 /* This copies a lot of the code from the fire bullet,
1047 * but using the cast_bullet isn't really feasible, 1020 * but using the cast_bullet isn't really feasible,
1048 * so just set up the appropriate values. 1021 * so just set up the appropriate values.
1049 */ 1022 */
1050 at = find_archetype (SPLINT); 1023 at = archetype::find (SPLINT);
1051 if (at) 1024 if (at)
1052 { 1025 {
1053 for (i = 1; i < 9; i++) 1026 for (i = 1; i < 9; i++)
1054 { 1027 {
1055 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) 1028 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i]))
1058 tmp->direction = i; 1031 tmp->direction = i;
1059 tmp->range = op->range; 1032 tmp->range = op->range;
1060 tmp->stats.dam = op->stats.dam; 1033 tmp->stats.dam = op->stats.dam;
1061 tmp->duration = op->duration; 1034 tmp->duration = op->duration;
1062 tmp->attacktype = op->attacktype; 1035 tmp->attacktype = op->attacktype;
1063 copy_owner (tmp, op); 1036 tmp->set_owner (op);
1064 if (op->skill && op->skill != tmp->skill) 1037 if (op->skill && op->skill != tmp->skill)
1065 { 1038 {
1066 tmp->skill = op->skill; 1039 tmp->skill = op->skill;
1067 } 1040 }
1068 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1041 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1082{ 1055{
1083 1056
1084 object *tmp; 1057 object *tmp;
1085 int mflags; 1058 int mflags;
1086 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir]; 1059 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir];
1087 mapstruct *m; 1060 maptile *m;
1088 1061
1089 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy); 1062 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy);
1090 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) 1063 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK))
1091 { 1064 {
1092 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1065 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
1098 tmp->range = spell->range + SP_level_range_adjust (caster, spell); 1071 tmp->range = spell->range + SP_level_range_adjust (caster, spell);
1099 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);
1100 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1073 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1101 tmp->attacktype = spell->attacktype; 1074 tmp->attacktype = spell->attacktype;
1102 1075
1103 set_owner (tmp, op); 1076 tmp->set_owner (op);
1104 set_spell_skill (op, caster, spell, tmp); 1077 set_spell_skill (op, caster, spell, tmp);
1105 tmp->x = dx; 1078 tmp->x = dx;
1106 tmp->y = dy; 1079 tmp->y = dy;
1107 insert_ob_in_map (tmp, m, op, 0); 1080 insert_ob_in_map (tmp, m, op, 0);
1108 return 1; 1081 return 1;
1128get_pointed_target (object *op, int dir, int range, int type) 1101get_pointed_target (object *op, int dir, int range, int type)
1129{ 1102{
1130 object *target; 1103 object *target;
1131 sint16 x, y; 1104 sint16 x, y;
1132 int dist, mflags; 1105 int dist, mflags;
1133 mapstruct *mp; 1106 maptile *mp;
1134 1107
1135 if (dir == 0) 1108 if (dir == 0)
1136 return NULL; 1109 return NULL;
1137 1110
1138 for (dist = 1; dist < range; dist++) 1111 for (dist = 1; dist < range; dist++)
1151 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW) 1124 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW)
1152 return NULL; 1125 return NULL;
1153 1126
1154 if (mflags & P_IS_ALIVE) 1127 if (mflags & P_IS_ALIVE)
1155 { 1128 {
1156 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)
1157 { 1130 {
1158 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER)) 1131 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER))
1159 { 1132 {
1160 return target; 1133 return target;
1161 } 1134 }
1228 if (effect->attacktype & AT_DEATH) 1201 if (effect->attacktype & AT_DEATH)
1229 { 1202 {
1230 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1203 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1231 1204
1232 /* casting death spells at undead isn't a good thing */ 1205 /* casting death spells at undead isn't a good thing */
1233 if QUERY_FLAG
1234 (target, FLAG_UNDEAD) 1206 if (QUERY_FLAG (target, FLAG_UNDEAD))
1235 { 1207 {
1236 if (random_roll (0, 2, op, PREFER_LOW)) 1208 if (random_roll (0, 2, op, PREFER_LOW))
1237 { 1209 {
1238 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!"); 1210 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!");
1239 effect->x = op->x; 1211 effect->x = op->x;
1241 } 1213 }
1242 else 1214 else
1243 { 1215 {
1244 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));
1245 target->stats.hp = target->stats.maxhp * 2; 1217 target->stats.hp = target->stats.maxhp * 2;
1246 free_object (effect); 1218 effect->destroy ();
1247 return 0; 1219 return 0;
1248 } 1220 }
1249 } 1221 }
1250 } 1222 }
1251 else 1223 else
1252 { 1224 {
1253 /* how much woe to inflict :) */ 1225 /* how much woe to inflict :) */
1254 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);
1255 } 1227 }
1256 1228
1257 set_owner (effect, op); 1229 effect->set_owner (op);
1258 set_spell_skill (op, caster, spell, effect); 1230 set_spell_skill (op, caster, spell, effect);
1259 1231
1260 /* ok, tell it where to be, and insert! */ 1232 /* ok, tell it where to be, and insert! */
1261 effect->x = target->x; 1233 effect->x = target->x;
1262 effect->y = target->y; 1234 effect->y = target->y;
1278move_missile (object *op) 1250move_missile (object *op)
1279{ 1251{
1280 int i, mflags; 1252 int i, mflags;
1281 object *owner; 1253 object *owner;
1282 sint16 new_x, new_y; 1254 sint16 new_x, new_y;
1283 mapstruct *m; 1255 maptile *m;
1284 1256
1285 if (op->range-- <= 0) 1257 if (op->range-- <= 0)
1286 { 1258 {
1287 remove_ob (op); 1259 op->destroy ();
1288 free_object (op);
1289 return; 1260 return;
1290 } 1261 }
1291 1262
1292 owner = get_owner (op); 1263 owner = op->owner;
1293#if 0 1264#if 0
1294 /* 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
1295 * monster that are then killed would continue to survive 1266 * monster that are then killed would continue to survive
1296 */ 1267 */
1297 if (owner == NULL) 1268 if (owner == NULL)
1298 { 1269 {
1299 remove_ob (op); 1270 op->destroy ();
1300 free_object (op);
1301 return; 1271 return;
1302 } 1272 }
1303#endif 1273#endif
1304 1274
1305 new_x = op->x + DIRX (op); 1275 new_x = op->x + DIRX (op);
1307 1277
1308 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y); 1278 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y);
1309 1279
1310 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))) 1280 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))))
1311 { 1281 {
1312 tag_t tag = op->count;
1313
1314 hit_map (op, op->direction, AT_MAGIC, 1); 1282 hit_map (op, op->direction, AT_MAGIC, 1);
1315 /* Basically, missile only hits one thing then goes away. 1283 /* Basically, missile only hits one thing then goes away.
1316 * 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.
1317 */ 1285 */
1318 if (!was_destroyed (op, tag)) 1286 if (!op->destroyed ())
1319 { 1287 op->destroy ();
1320 remove_ob (op); 1288
1321 free_object (op);
1322 }
1323 return; 1289 return;
1324 } 1290 }
1325 1291
1326 remove_ob (op); 1292 op->remove ();
1293
1327 if (!op->direction || (mflags & P_OUT_OF_MAP)) 1294 if (!op->direction || (mflags & P_OUT_OF_MAP))
1328 { 1295 {
1329 free_object (op); 1296 op->destroy ();
1330 return; 1297 return;
1331 } 1298 }
1299
1332 op->x = new_x; 1300 op->x = new_x;
1333 op->y = new_y; 1301 op->y = new_y;
1334 op->map = m; 1302 op->map = m;
1335 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);
1336 if (i > 0 && i != op->direction) 1304 if (i > 0 && i != op->direction)
1337 { 1305 {
1338 op->direction = i; 1306 op->direction = i;
1339 SET_ANIMATION (op, op->direction); 1307 SET_ANIMATION (op, op->direction);
1340 } 1308 }
1309
1341 insert_ob_in_map (op, op->map, op, 0); 1310 insert_ob_in_map (op, op->map, op, 0);
1342} 1311}
1343 1312
1344/**************************************************************************** 1313/****************************************************************************
1345 * Destruction 1314 * Destruction
1391int 1360int
1392cast_destruction (object *op, object *caster, object *spell_ob) 1361cast_destruction (object *op, object *caster, object *spell_ob)
1393{ 1362{
1394 int i, j, range, mflags, friendly = 0, dam, dur; 1363 int i, j, range, mflags, friendly = 0, dam, dur;
1395 sint16 sx, sy; 1364 sint16 sx, sy;
1396 mapstruct *m; 1365 maptile *m;
1397 object *tmp; 1366 object *tmp;
1398 const char *skill; 1367 const char *skill;
1399 1368
1400 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 1369 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
1401 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 1370 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
1429 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1398 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1430 if (mflags & P_OUT_OF_MAP) 1399 if (mflags & P_OUT_OF_MAP)
1431 continue; 1400 continue;
1432 if (mflags & P_IS_ALIVE) 1401 if (mflags & P_IS_ALIVE)
1433 { 1402 {
1434 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)
1435 { 1404 {
1436 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1405 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1437 break; 1406 break;
1438 } 1407 }
1439 if (tmp) 1408 if (tmp)
1562 force->stats.ac = spell_ob->stats.ac; 1531 force->stats.ac = spell_ob->stats.ac;
1563 force->stats.wc = spell_ob->stats.wc; 1532 force->stats.wc = spell_ob->stats.wc;
1564 1533
1565 change_abil (tmp, force); /* Mostly to display any messages */ 1534 change_abil (tmp, force); /* Mostly to display any messages */
1566 insert_ob_in_ob (force, tmp); 1535 insert_ob_in_ob (force, tmp);
1567 fix_player (tmp); 1536 tmp->update_stats ();
1568 return 1; 1537 return 1;
1569 1538
1570} 1539}
1571 1540
1572 1541
1583mood_change (object *op, object *caster, object *spell) 1552mood_change (object *op, object *caster, object *spell)
1584{ 1553{
1585 object *tmp, *god, *head; 1554 object *tmp, *god, *head;
1586 int done_one, range, mflags, level, at, best_at; 1555 int done_one, range, mflags, level, at, best_at;
1587 sint16 x, y, nx, ny; 1556 sint16 x, y, nx, ny;
1588 mapstruct *m; 1557 maptile *m;
1589 const char *race; 1558 const char *race;
1590 1559
1591 /* We precompute some values here so that we don't have to keep 1560 /* We precompute some values here so that we don't have to keep
1592 * doing it over and over again. 1561 * doing it over and over again.
1593 */ 1562 */
1623 1592
1624 /* 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 */
1625 if (!(mflags & P_IS_ALIVE)) 1594 if (!(mflags & P_IS_ALIVE))
1626 continue; 1595 continue;
1627 1596
1628 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)
1629 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1598 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1630 break; 1599 break;
1631 1600
1632 /* There can be living objects that are not monsters */ 1601 /* There can be living objects that are not monsters */
1633 if (!tmp || tmp->type == PLAYER) 1602 if (!tmp || tmp->type == PLAYER)
1721 SET_FLAG (head, FLAG_FRIENDLY); 1690 SET_FLAG (head, FLAG_FRIENDLY);
1722 /* Prevent uncontolled outbreaks of self replicating monsters. 1691 /* Prevent uncontolled outbreaks of self replicating monsters.
1723 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.
1724 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. */
1725 CLEAR_FLAG (head, FLAG_GENERATOR); 1694 CLEAR_FLAG (head, FLAG_GENERATOR);
1726 set_owner (head, op); 1695 head->set_owner (op);
1727 set_spell_skill (op, caster, spell, head); 1696 set_spell_skill (op, caster, spell, head);
1728 add_friendly_object (head); 1697 add_friendly_object (head);
1729 head->attack_movement = PETMOVE; 1698 head->attack_movement = PETMOVE;
1730 done_one = 1; 1699 done_one = 1;
1731 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);
1757move_ball_spell (object *op) 1726move_ball_spell (object *op)
1758{ 1727{
1759 int i, j, dam_save, dir, mflags; 1728 int i, j, dam_save, dir, mflags;
1760 sint16 nx, ny, hx, hy; 1729 sint16 nx, ny, hx, hy;
1761 object *owner; 1730 object *owner;
1762 mapstruct *m; 1731 maptile *m;
1763 1732
1764 owner = get_owner (op); 1733 owner = op->owner;
1765 1734
1766 /* 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,
1767 * 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
1768 * victim. The block immediately below more or less chooses a random 1737 * victim. The block immediately below more or less chooses a random
1769 * 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
1798 nx = op->x; 1767 nx = op->x;
1799 ny = op->y; 1768 ny = op->y;
1800 m = op->map; 1769 m = op->map;
1801 } 1770 }
1802 1771
1803 remove_ob (op); 1772 op->remove ();
1804 op->y = ny; 1773 op->y = ny;
1805 op->x = nx; 1774 op->x = nx;
1806 insert_ob_in_map (op, m, op, 0); 1775 insert_ob_in_map (op, m, op, 0);
1807 1776
1808 dam_save = op->stats.dam; /* save the original dam: we do halfdam on 1777 dam_save = op->stats.dam; /* save the original dam: we do halfdam on
1848 } 1817 }
1849 1818
1850 /* restore to the center location and damage */ 1819 /* restore to the center location and damage */
1851 op->stats.dam = dam_save; 1820 op->stats.dam = dam_save;
1852 1821
1853 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);
1854 1823
1855 if (i >= 0) 1824 if (i >= 0)
1856 { /* we have a preferred direction! */ 1825 { /* we have a preferred direction! */
1857 /* pick another direction if the preferred dir is blocked. */ 1826 /* pick another direction if the preferred dir is blocked. */
1858 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 ||
1879#if 0 1848#if 0
1880 static int cardinal_adjust[9] = { -3, -2, -1, 0, 0, 0, 1, 2, 3 }; 1849 static int cardinal_adjust[9] = { -3, -2, -1, 0, 0, 0, 1, 2, 3 };
1881 static int diagonal_adjust[10] = { -3, -2, -2, -1, 0, 0, 1, 2, 2, 3 }; 1850 static int diagonal_adjust[10] = { -3, -2, -2, -1, 0, 0, 1, 2, 2, 3 };
1882 sint16 target_x, target_y, origin_x, origin_y; 1851 sint16 target_x, target_y, origin_x, origin_y;
1883 int adjustdir; 1852 int adjustdir;
1884 mapstruct *m; 1853 maptile *m;
1885#endif 1854#endif
1886 int basedir; 1855 int basedir;
1887 object *owner; 1856 object *owner;
1888 1857
1889 owner = get_owner (op); 1858 owner = op->owner;
1890 if (op->duration == 0 || owner == NULL) 1859 if (op->duration == 0 || owner == NULL)
1891 { 1860 {
1892 remove_ob (op); 1861 op->destroy ();
1893 free_object (op);
1894 return; 1862 return;
1895 } 1863 }
1864
1896 op->duration--; 1865 op->duration--;
1897 1866
1898 basedir = op->direction; 1867 basedir = op->direction;
1899 if (basedir == 0) 1868 if (basedir == 0)
1900 { 1869 {
1999 return 0; 1968 return 0;
2000 1969
2001 tmp = get_archetype (SWARM_SPELL); 1970 tmp = get_archetype (SWARM_SPELL);
2002 tmp->x = op->x; 1971 tmp->x = op->x;
2003 tmp->y = op->y; 1972 tmp->y = op->y;
2004 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. */
2005 set_spell_skill (op, caster, spell, tmp); 1974 set_spell_skill (op, caster, spell, tmp);
2006 1975
2007 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. */
2008 tmp->spell = arch_to_object (spell->other_arch); 1977 tmp->spell = arch_to_object (spell->other_arch);
2009 1978
2032cast_light (object *op, object *caster, object *spell, int dir) 2001cast_light (object *op, object *caster, object *spell, int dir)
2033{ 2002{
2034 object *target = NULL, *tmp = NULL; 2003 object *target = NULL, *tmp = NULL;
2035 sint16 x, y; 2004 sint16 x, y;
2036 int dam, mflags; 2005 int dam, mflags;
2037 mapstruct *m; 2006 maptile *m;
2038 2007
2039 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 2008 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2040 2009
2041 if (!dir) 2010 if (!dir)
2042 { 2011 {
2056 return 0; 2025 return 0;
2057 } 2026 }
2058 2027
2059 if (mflags & P_IS_ALIVE && spell->attacktype) 2028 if (mflags & P_IS_ALIVE && spell->attacktype)
2060 { 2029 {
2061 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)
2062 if (QUERY_FLAG (target, FLAG_MONSTER)) 2031 if (QUERY_FLAG (target, FLAG_MONSTER))
2063 { 2032 {
2064 /* oky doky. got a target monster. Lets make a blinding attack */ 2033 /* oky doky. got a target monster. Lets make a blinding attack */
2065 if (target->head) 2034 if (target->head)
2066 target = target->head; 2035 target = target->head;
2110cast_cause_disease (object *op, object *caster, object *spell, int dir) 2079cast_cause_disease (object *op, object *caster, object *spell, int dir)
2111{ 2080{
2112 sint16 x, y; 2081 sint16 x, y;
2113 int i, mflags, range, dam_mod, dur_mod; 2082 int i, mflags, range, dam_mod, dur_mod;
2114 object *walk; 2083 object *walk;
2115 mapstruct *m; 2084 maptile *m;
2116 2085
2117 x = op->x; 2086 x = op->x;
2118 y = op->y; 2087 y = op->y;
2119 2088
2120 /* If casting from a scroll, no direction will be available, so refer to the 2089 /* If casting from a scroll, no direction will be available, so refer to the
2148 2117
2149 /* 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 */
2150 if (mflags & P_IS_ALIVE) 2119 if (mflags & P_IS_ALIVE)
2151 { 2120 {
2152 /* search this square for a victim */ 2121 /* search this square for a victim */
2153 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)
2154 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) 2123 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER))
2155 { /* found a victim */ 2124 { /* found a victim */
2156 object *disease = arch_to_object (spell->other_arch); 2125 object *disease = arch_to_object (spell->other_arch);
2157 2126
2158 set_owner (disease, op); 2127 disease->set_owner (op);
2159 set_spell_skill (op, caster, spell, disease); 2128 set_spell_skill (op, caster, spell, disease);
2160 disease->stats.exp = 0; 2129 disease->stats.exp = 0;
2161 disease->level = caster_level (caster, spell); 2130 disease->level = caster_level (caster, spell);
2162 2131
2163 /* do level adjustments */ 2132 /* do level adjustments */
2212 { 2181 {
2213 object *flash; /* visual effect for inflicting disease */ 2182 object *flash; /* visual effect for inflicting disease */
2214 2183
2215 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);
2216 2185
2217 free_object (disease); /* don't need this one anymore */ 2186 disease->destroy (); /* don't need this one anymore */
2218 flash = get_archetype (ARCH_DETECT_MAGIC); 2187 flash = get_archetype (ARCH_DETECT_MAGIC);
2219 flash->x = x; 2188 flash->x = x;
2220 flash->y = y; 2189 flash->y = y;
2221 flash->map = walk->map; 2190 flash->map = walk->map;
2222 insert_ob_in_map (flash, walk->map, op, 0); 2191 insert_ob_in_map (flash, walk->map, op, 0);
2223 return 1; 2192 return 1;
2224 } 2193 }
2225 free_object (disease); 2194
2195 disease->destroy ();
2226 } 2196 }
2227 } /* if living creature */ 2197 } /* if living creature */
2228 } /* for range of spaces */ 2198 } /* for range of spaces */
2229 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2199 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2230 return 1; 2200 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines