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.12 by root, Thu Sep 14 21:16:13 2006 UTC vs.
Revision 1.24 by root, Tue Dec 26 08:55:00 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines