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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines