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.9 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.23 by root, Mon Dec 25 11:25:50 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines