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.20 by root, Mon Dec 18 02:35:01 2006 UTC vs.
Revision 1.25 by root, Tue Dec 26 20:04:09 2006 UTC

27 */ 27 */
28 28
29#include <global.h> 29#include <global.h>
30#include <object.h> 30#include <object.h>
31#include <living.h> 31#include <living.h>
32#ifndef __CEXTRACT__
33# include <sproto.h> 32#include <sproto.h>
34#endif
35#include <spells.h> 33#include <spells.h>
36#include <sounds.h> 34#include <sounds.h>
37 35
38/* this function checks to see if a spell pushes objects as well 36/* this function checks to see if a spell pushes objects as well
39 * as flies over and damages them (only used for cones for now) 37 * as flies over and damages them (only used for cones for now)
57 { 55 {
58 weight_move = op->weight + (op->weight * op->level) / 3; 56 weight_move = op->weight + (op->weight * op->level) / 3;
59 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */ 57 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */
60 } 58 }
61 59
62 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 60 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
63 { 61 {
64 int num_sections = 1; 62 int num_sections = 1;
65 63
66 /* don't move DM */ 64 /* don't move DM */
67 if (QUERY_FLAG (tmp, FLAG_WIZ)) 65 if (QUERY_FLAG (tmp, FLAG_WIZ))
149 tmp->stats.Dex -= 10; /* less forks from main bolt too */ 147 tmp->stats.Dex -= 10; /* less forks from main bolt too */
150 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */ 148 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */
151 new_bolt->speed_left = -0.1; 149 new_bolt->speed_left = -0.1;
152 new_bolt->direction = t_dir; 150 new_bolt->direction = t_dir;
153 new_bolt->duration++; 151 new_bolt->duration++;
154 new_bolt->x = sx;
155 new_bolt->y = sy;
156 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */ 152 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */
157 new_bolt->stats.dam++; 153 new_bolt->stats.dam++;
158 tmp->stats.dam /= 2; /* reduce father bolt damage */ 154 tmp->stats.dam /= 2; /* reduce father bolt damage */
159 tmp->stats.dam++; 155 tmp->stats.dam++;
160 new_bolt = insert_ob_in_map (new_bolt, m, op, 0); 156 if ((new_bolt = m->insert (new_bolt, sx, sy, op)))
161 update_turn_face (new_bolt); 157 update_turn_face (new_bolt);
162} 158}
163 159
164/* move_bolt: moves bolt 'op'. Basically, it just advances a space, 160/* move_bolt: moves bolt 'op'. Basically, it just advances a space,
165 * and checks for various things that may stop it. 161 * and checks for various things that may stop it.
166 */ 162 */
171 object *tmp; 167 object *tmp;
172 int mflags; 168 int mflags;
173 sint16 x, y; 169 sint16 x, y;
174 maptile *m; 170 maptile *m;
175 171
176 if (--(op->duration) < 0) 172 if (--op->duration < 0)
177 { 173 {
178 op->destroy (); 174 op->destroy ();
179 return; 175 return;
180 } 176 }
181 177
183 179
184 if (!op->direction) 180 if (!op->direction)
185 return; 181 return;
186 182
187 if (--op->range < 0) 183 if (--op->range < 0)
188 {
189 op->range = 0; 184 op->range = 0;
190 }
191 else 185 else
192 { 186 {
193 x = op->x + DIRX (op); 187 x = op->x + DIRX (op);
194 y = op->y + DIRY (op); 188 y = op->y + DIRY (op);
195 m = op->map; 189 m = op->map;
203 * on the space. So only call reflwall if we think the data it returns 197 * on the space. So only call reflwall if we think the data it returns
204 * will be useful. 198 * will be useful.
205 */ 199 */
206 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)) || ((mflags & P_IS_ALIVE) && reflwall (m, x, y, op))) 200 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)) || ((mflags & P_IS_ALIVE) && reflwall (m, x, y, op)))
207 { 201 {
208
209 if (!QUERY_FLAG (op, FLAG_REFLECTING)) 202 if (!QUERY_FLAG (op, FLAG_REFLECTING))
210 return; 203 return;
211 204
212 /* Since walls don't run diagonal, if the bolt is in 205 /* Since walls don't run diagonal, if the bolt is in
213 * one of 4 main directions, it just reflects back in the 206 * one of 4 main directions, it just reflects back in the
243 else if (left) 236 else if (left)
244 op->direction = absdir (op->direction + 2); 237 op->direction = absdir (op->direction + 2);
245 else if (right) 238 else if (right)
246 op->direction = absdir (op->direction - 2); 239 op->direction = absdir (op->direction - 2);
247 } 240 }
241
248 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */ 242 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */
249 return; 243 return;
250 } 244 }
251 else 245 else
252 { /* Create a copy of this object and put it ahead */ 246 { /* Create a copy of this object and put it ahead */
253 tmp = op->clone (); 247 object *tmp = op->clone ();
254 248
249 m->insert (tmp, x, y, op);
255 tmp->speed_left = -0.1; 250 tmp->speed_left = -0.1;
256 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp);
257 tmp = insert_ob_in_map (tmp, op->map, op, 0);
258 /* To make up for the decrease at the top of the function */ 251 /* To make up for the decrease at the top of the function */
259 tmp->duration++; 252 tmp->duration++;
260 253
261 /* New forking code. Possibly create forks of this object 254 /* New forking code. Possibly create forks of this object
262 * going off in other directions. 255 * going off in other directions.
263 */ 256 */
264
265 if (rndm (0, 99) < tmp->stats.Dex) 257 if (rndm (0, 99) < tmp->stats.Dex)
266 { /* stats.Dex % of forking */ 258 { /* stats.Dex % of forking */
267 forklightning (op, tmp); 259 forklightning (op, tmp);
268 } 260 }
261
269 /* In this way, the object left behind sticks on the space, but 262 /* In this way, the object left behind sticks on the space, but
270 * doesn't create any bolts that continue to move onward. 263 * doesn't create any bolts that continue to move onward.
271 */ 264 */
272 op->range = 0; 265 op->range = 0;
273 } /* copy object and move it along */ 266 } /* copy object and move it along */
280 * we remove the magic flag - that can be derived from 273 * we remove the magic flag - that can be derived from
281 * spob->attacktype. 274 * spob->attacktype.
282 * This function sets up the appropriate owner and skill 275 * This function sets up the appropriate owner and skill
283 * pointers. 276 * pointers.
284 */ 277 */
285
286int 278int
287fire_bolt (object *op, object *caster, int dir, object *spob, object *skill) 279fire_bolt (object *op, object *caster, int dir, object *spob, object *skill)
288{ 280{
289 object *tmp = NULL; 281 object *tmp = NULL;
290 int mflags; 282 int mflags;
315 307
316 tmp->x = op->x + DIRX (tmp); 308 tmp->x = op->x + DIRX (tmp);
317 tmp->y = op->y + DIRY (tmp); 309 tmp->y = op->y + DIRY (tmp);
318 tmp->map = op->map; 310 tmp->map = op->map;
319 311
312 maptile *newmap;
320 mflags = get_map_flags (tmp->map, &tmp->map, tmp->x, tmp->y, &tmp->x, &tmp->y); 313 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
321 if (mflags & P_OUT_OF_MAP) 314 if (mflags & P_OUT_OF_MAP)
322 { 315 {
323 tmp->destroy (); 316 tmp->destroy ();
324 return 0; 317 return 0;
325 } 318 }
319
320 tmp->map = newmap;
326 321
327 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 322 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
328 { 323 {
329 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 324 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
330 { 325 {
336 tmp->y = op->y; 331 tmp->y = op->y;
337 tmp->direction = absdir (tmp->direction + 4); 332 tmp->direction = absdir (tmp->direction + 4);
338 tmp->map = op->map; 333 tmp->map = op->map;
339 } 334 }
340 335
341 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 336 if ((tmp = tmp->insert_at (tmp, op)))
342 move_bolt (tmp); 337 move_bolt (tmp);
343 338
344 return 1; 339 return 1;
345} 340}
346 341
357 * At least that is what I think this does. 352 * At least that is what I think this does.
358 */ 353 */
359void 354void
360explosion (object *op) 355explosion (object *op)
361{ 356{
362 object *tmp;
363 maptile *m = op->map; 357 maptile *m = op->map;
364 int i; 358 int i;
365 359
366 if (--(op->duration) < 0) 360 if (--op->duration < 0)
367 { 361 {
368 op->destroy (); 362 op->destroy ();
369 return; 363 return;
370 } 364 }
371 365
377 { 371 {
378 sint16 dx, dy; 372 sint16 dx, dy;
379 373
380 dx = op->x + freearr_x[i]; 374 dx = op->x + freearr_x[i];
381 dy = op->y + freearr_y[i]; 375 dy = op->y + freearr_y[i];
376
382 /* ok_to_put_more already does things like checks for walls, 377 /* ok_to_put_more already does things like checks for walls,
383 * out of map, etc. 378 * out of map, etc.
384 */ 379 */
385 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype)) 380 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype))
386 { 381 {
387 tmp = op->clone (); 382 object *tmp = op->clone ();
383
388 tmp->state = 0; 384 tmp->state = 0;
389 tmp->speed_left = -0.21; 385 tmp->speed_left = -0.21;
390 tmp->range--; 386 tmp->range--;
391 tmp->value = 0; 387 tmp->value = 0;
392 tmp->x = dx; 388
393 tmp->y = dy; 389 m->insert (tmp, dx, dy, op);
394 insert_ob_in_map (tmp, m, op, 0);
395 } 390 }
396 } 391 }
397 } 392 }
398} 393}
399 394
414 return; 409 return;
415 } 410 }
416 411
417 if (op->env) 412 if (op->env)
418 { 413 {
419 object *env;
420
421 env = object_get_env_recursive (op); 414 object *env = object_get_env_recursive (op);
422 if (env->map == NULL || out_of_map (env->map, env->x, env->y)) 415 if (env->map == NULL || out_of_map (env->map, env->x, env->y))
423 { 416 {
424 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 417 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
425 op->destroy (); 418 op->destroy ();
426 return; 419 return;
427 } 420 }
428 421
429 op->remove (); 422 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON);
430 op->x = env->x;
431 op->y = env->y;
432 insert_ob_in_map (op, env->map, op, INS_NO_MERGE | INS_NO_WALK_ON);
433 } 423 }
434 else if (out_of_map (op->map, op->x, op->y)) 424 else if (out_of_map (op->map, op->x, op->y))
435 { 425 {
436 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 426 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
437 op->destroy (); 427 op->destroy ();
466 { 456 {
467 op->destroy (); 457 op->destroy ();
468 return; 458 return;
469 } 459 }
470 460
471 tmp->x = op->x;
472 tmp->y = op->y;
473
474 /* special for bombs - it actually has sane values for these */ 461 /* special for bombs - it actually has sane values for these */
475 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 462 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
476 { 463 {
477 tmp->attacktype = op->attacktype; 464 tmp->attacktype = op->attacktype;
478 tmp->range = op->range; 465 tmp->range = op->range;
481 } 468 }
482 else 469 else
483 { 470 {
484 if (op->attacktype & AT_MAGIC) 471 if (op->attacktype & AT_MAGIC)
485 tmp->attacktype |= AT_MAGIC; 472 tmp->attacktype |= AT_MAGIC;
473
486 /* Spell doc describes what is going on here */ 474 /* Spell doc describes what is going on here */
487 tmp->stats.dam = op->dam_modifier; 475 tmp->stats.dam = op->dam_modifier;
488 tmp->range = op->stats.maxhp; 476 tmp->range = op->stats.maxhp;
489 tmp->duration = op->stats.hp; 477 tmp->duration = op->stats.hp;
490 /* Used for spell tracking - just need a unique val for this spell - 478 /* Used for spell tracking - just need a unique val for this spell -
498 tmp->stats.sp = op->direction; 486 tmp->stats.sp = op->direction;
499 487
500 /* Prevent recursion */ 488 /* Prevent recursion */
501 op->move_on = 0; 489 op->move_on = 0;
502 490
503 insert_ob_in_map (tmp, op->map, op, 0); 491 tmp->insert_at (op, op);
504 /* remove the firebullet */ 492 /* remove the firebullet */
505 if (!op->destroyed ())
506 {
507 op->destroy (); 493 op->destroy ();
508 }
509} 494}
510
511
512 495
513/* checks to see what op should do, given the space it is on 496/* checks to see what op should do, given the space it is on
514 * (eg, explode, damage player, etc) 497 * (eg, explode, damage player, etc)
515 */ 498 */
516
517void 499void
518check_bullet (object *op) 500check_bullet (object *op)
519{ 501{
520 object *tmp; 502 object *tmp;
521 int dam, mflags; 503 int dam, mflags;
536 518
537 /* If nothing alive on this space, no reason to do anything further */ 519 /* If nothing alive on this space, no reason to do anything further */
538 if (!(mflags & P_IS_ALIVE)) 520 if (!(mflags & P_IS_ALIVE))
539 return; 521 return;
540 522
541 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 523 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
542 { 524 {
543 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 525 if (QUERY_FLAG (tmp, FLAG_ALIVE))
544 { 526 {
545 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 527 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
546 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 528 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
553 } 535 }
554 } 536 }
555 } 537 }
556} 538}
557 539
558
559/* Basically, we move 'op' one square, and if it hits something, 540/* Basically, we move 'op' one square, and if it hits something,
560 * call check_bullet. 541 * call check_bullet.
561 * This function is only applicable to bullets, but not to all 542 * This function is only applicable to bullets, but not to all
562 * fired arches (eg, bolts). 543 * fired arches (eg, bolts).
563 */ 544 */
564
565void 545void
566move_bullet (object *op) 546move_bullet (object *op)
567{ 547{
568 sint16 new_x, new_y; 548 sint16 new_x, new_y;
569 int mflags; 549 int mflags;
612 op->destroy (); 592 op->destroy ();
613 593
614 return; 594 return;
615 } 595 }
616 596
617 op->remove (); 597 if (!(op = m->insert (op, new_x, new_y, op)))
618 op->x = new_x;
619 op->y = new_y;
620 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL)
621 return; 598 return;
622 599
623 if (reflwall (op->map, op->x, op->y, op)) 600 if (reflwall (op->map, op->x, op->y, op))
624 { 601 {
625 op->direction = absdir (op->direction + 4); 602 op->direction = absdir (op->direction + 4);
626 update_turn_face (op); 603 update_turn_face (op);
627 } 604 }
628 else 605 else
629 {
630 check_bullet (op); 606 check_bullet (op);
631 }
632} 607}
633 608
634 609
635 610
636 611
678 653
679 tmp->x = op->x + freearr_x[dir]; 654 tmp->x = op->x + freearr_x[dir];
680 tmp->y = op->y + freearr_y[dir]; 655 tmp->y = op->y + freearr_y[dir];
681 tmp->map = op->map; 656 tmp->map = op->map;
682 657
658 maptile *newmap;
683 mflags = get_map_flags (tmp->map, &tmp->map, tmp->x, tmp->y, &tmp->x, &tmp->y); 659 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
684 if (mflags & P_OUT_OF_MAP) 660 if (mflags & P_OUT_OF_MAP)
685 { 661 {
686 tmp->destroy (); 662 tmp->destroy ();
687 return 0; 663 return 0;
688 } 664 }
665
666 tmp->map = newmap;
689 667
690 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 668 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
691 { 669 {
692 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 670 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
693 { 671 {
699 tmp->y = op->y; 677 tmp->y = op->y;
700 tmp->direction = absdir (tmp->direction + 4); 678 tmp->direction = absdir (tmp->direction + 4);
701 tmp->map = op->map; 679 tmp->map = op->map;
702 } 680 }
703 681
704 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 682 if ((tmp = tmp->insert_at (tmp, op)))
705 check_bullet (tmp); 683 check_bullet (tmp);
706 684
707 return 1; 685 return 1;
708} 686}
709 687
721void 699void
722cone_drop (object *op) 700cone_drop (object *op)
723{ 701{
724 object *new_ob = arch_to_object (op->other_arch); 702 object *new_ob = arch_to_object (op->other_arch);
725 703
726 new_ob->x = op->x;
727 new_ob->y = op->y;
728 new_ob->level = op->level; 704 new_ob->level = op->level;
729 new_ob->set_owner (op->owner); 705 new_ob->set_owner (op->owner);
730 706
731 /* preserve skill ownership */ 707 /* preserve skill ownership */
732 if (op->skill && op->skill != new_ob->skill) 708 if (op->skill && op->skill != new_ob->skill)
733 {
734 new_ob->skill = op->skill; 709 new_ob->skill = op->skill;
735 }
736 insert_ob_in_map (new_ob, op->map, op, 0);
737 710
711 new_ob->insert_at (op, op);
738} 712}
739 713
740/* move_cone: causes cone object 'op' to move a space/hit creatures */ 714/* move_cone: causes cone object 'op' to move a space/hit creatures */
741 715
742void 716void
746 720
747 /* if no map then hit_map will crash so just ignore object */ 721 /* if no map then hit_map will crash so just ignore object */
748 if (!op->map) 722 if (!op->map)
749 { 723 {
750 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 724 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
751 op->speed = 0; 725 op->set_speed (0);
752 update_ob_speed (op);
753 return; 726 return;
754 } 727 }
755 728
756 /* lava saves it's life, but not yours :) */ 729 /* lava saves it's life, but not yours :) */
757 if (QUERY_FLAG (op, FLAG_LIFESAVE)) 730 if (QUERY_FLAG (op, FLAG_LIFESAVE))
805 778
806 if (ok_to_put_more (op->map, x, y, op, op->attacktype)) 779 if (ok_to_put_more (op->map, x, y, op, op->attacktype))
807 { 780 {
808 object *tmp = op->clone (); 781 object *tmp = op->clone ();
809 782
810 tmp->x = x;
811 tmp->y = y;
812
813 tmp->duration = op->duration + 1; 783 tmp->duration = op->duration + 1;
814 784
815 /* Use for spell tracking - see ok_to_put_more() */ 785 /* Use for spell tracking - see ok_to_put_more() */
816 tmp->stats.maxhp = op->stats.maxhp; 786 tmp->stats.maxhp = op->stats.maxhp;
817 insert_ob_in_map (tmp, op->map, op, 0); 787
788 op->map->insert (tmp, x, y, op);
789
818 if (tmp->other_arch) 790 if (tmp->other_arch)
819 cone_drop (tmp); 791 cone_drop (tmp);
820 } 792 }
821 } 793 }
822} 794}
901 success = 1; 873 success = 1;
902 tmp = arch_to_object (spell->other_arch); 874 tmp = arch_to_object (spell->other_arch);
903 tmp->set_owner (op); 875 tmp->set_owner (op);
904 set_spell_skill (op, caster, spell, tmp); 876 set_spell_skill (op, caster, spell, tmp);
905 tmp->level = caster_level (caster, spell); 877 tmp->level = caster_level (caster, spell);
906 tmp->x = sx;
907 tmp->y = sy;
908 tmp->attacktype = spell->attacktype; 878 tmp->attacktype = spell->attacktype;
909 879
910 /* holy word stuff */ 880 /* holy word stuff */
911 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) 881 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER))
912 if (!tailor_god_spell (tmp, op)) 882 if (!tailor_god_spell (tmp, op))
949 919
950 if (!(tmp->move_type & MOVE_FLY_LOW)) 920 if (!(tmp->move_type & MOVE_FLY_LOW))
951 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name); 921 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name);
952 922
953 if (!tmp->move_on && tmp->stats.dam) 923 if (!tmp->move_on && tmp->stats.dam)
954 {
955 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name); 924 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name);
956 }
957 925
958 insert_ob_in_map (tmp, m, op, 0); 926 m->insert (tmp, sx, sy, op);
959 927
960 /* This is used for tracking spells so that one effect doesn't hit 928 /* This is used for tracking spells so that one effect doesn't hit
961 * a single space too many times. 929 * a single space too many times.
962 */ 930 */
963 tmp->stats.maxhp = tmp->count; 931 tmp->stats.maxhp = tmp->count;
982void 950void
983animate_bomb (object *op) 951animate_bomb (object *op)
984{ 952{
985 int i; 953 int i;
986 object *env, *tmp; 954 object *env, *tmp;
987 archetype *at;
988 955
989 if (op->state != NUM_ANIMATIONS (op) - 1) 956 if (op->state != NUM_ANIMATIONS (op) - 1)
990 return; 957 return;
991 958
992 env = object_get_env_recursive (op); 959 env = object_get_env_recursive (op);
997 return; 964 return;
998 965
999 if (env->type == PLAYER) 966 if (env->type == PLAYER)
1000 esrv_del_item (env->contr, op->count); 967 esrv_del_item (env->contr, op->count);
1001 968
1002 op->remove (); 969 if (!(op = op->insert_at (env, op)))
1003 op->x = env->x;
1004 op->y = env->y;
1005 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL)
1006 return; 970 return;
1007 } 971 }
1008 972
1009 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding 973 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding
1010 // on a safe map. I don't like this special casing, but it seems to be neccessary 974 // on a safe map. I don't like this special casing, but it seems to be neccessary
1017 981
1018 /* This copies a lot of the code from the fire bullet, 982 /* This copies a lot of the code from the fire bullet,
1019 * but using the cast_bullet isn't really feasible, 983 * but using the cast_bullet isn't really feasible,
1020 * so just set up the appropriate values. 984 * so just set up the appropriate values.
1021 */ 985 */
1022 at = archetype::find (SPLINT); 986 if (archetype *at = archetype::find (SPLINT))
1023 if (at)
1024 { 987 {
1025 for (i = 1; i < 9; i++) 988 for (i = 1; i < 9; i++)
1026 { 989 {
1027 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) 990 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i]))
1028 continue; 991 continue;
992
1029 tmp = arch_to_object (at); 993 tmp = arch_to_object (at);
1030 tmp->direction = i; 994 tmp->direction = i;
1031 tmp->range = op->range; 995 tmp->range = op->range;
1032 tmp->stats.dam = op->stats.dam; 996 tmp->stats.dam = op->stats.dam;
1033 tmp->duration = op->duration; 997 tmp->duration = op->duration;
1034 tmp->attacktype = op->attacktype; 998 tmp->attacktype = op->attacktype;
1035 tmp->set_owner (op); 999 tmp->set_owner (op);
1036 if (op->skill && op->skill != tmp->skill) 1000 if (op->skill && op->skill != tmp->skill)
1037 {
1038 tmp->skill = op->skill; 1001 tmp->skill = op->skill;
1039 } 1002
1040 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1003 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1041 SET_ANIMATION (tmp, i); 1004 SET_ANIMATION (tmp, i);
1042 tmp->x = op->x + freearr_x[i]; 1005
1043 tmp->y = op->y + freearr_x[i]; 1006 op->map->insert (tmp, op->x + freearr_x[i], op->y + freearr_x[i], op);
1044 insert_ob_in_map (tmp, op->map, op, 0);
1045 move_bullet (tmp); 1007 move_bullet (tmp);
1046 } 1008 }
1047 } 1009 }
1048 1010
1049 explode_bullet (op); 1011 explode_bullet (op);
1072 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1034 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1073 tmp->attacktype = spell->attacktype; 1035 tmp->attacktype = spell->attacktype;
1074 1036
1075 tmp->set_owner (op); 1037 tmp->set_owner (op);
1076 set_spell_skill (op, caster, spell, tmp); 1038 set_spell_skill (op, caster, spell, tmp);
1077 tmp->x = dx; 1039
1078 tmp->y = dy; 1040 m->insert (tmp, dx, dy, op);
1079 insert_ob_in_map (tmp, m, op, 0);
1080 return 1; 1041 return 1;
1081} 1042}
1082 1043
1083/**************************************************************************** 1044/****************************************************************************
1084 * 1045 *
1123 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW) 1084 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW)
1124 return NULL; 1085 return NULL;
1125 1086
1126 if (mflags & P_IS_ALIVE) 1087 if (mflags & P_IS_ALIVE)
1127 { 1088 {
1128 for (target = get_map_ob (mp, x, y); target; target = target->above) 1089 for (target = GET_MAP_OB (mp, x, y); target; target = target->above)
1129 { 1090 {
1130 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER)) 1091 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER))
1131 { 1092 {
1132 return target; 1093 return target;
1133 } 1094 }
1227 1188
1228 effect->set_owner (op); 1189 effect->set_owner (op);
1229 set_spell_skill (op, caster, spell, effect); 1190 set_spell_skill (op, caster, spell, effect);
1230 1191
1231 /* ok, tell it where to be, and insert! */ 1192 /* ok, tell it where to be, and insert! */
1232 effect->x = target->x; 1193 effect->insert_at (target, op);
1233 effect->y = target->y;
1234 insert_ob_in_map (effect, target->map, op, 0);
1235 1194
1236 return 1; 1195 return 1;
1237} 1196}
1238 1197
1239 1198
1294 { 1253 {
1295 op->destroy (); 1254 op->destroy ();
1296 return; 1255 return;
1297 } 1256 }
1298 1257
1299 op->x = new_x;
1300 op->y = new_y;
1301 op->map = m;
1302 i = spell_find_dir (op->map, op->x, op->y, op->owner); 1258 i = spell_find_dir (m, new_x, new_y, op->owner);
1303 if (i > 0 && i != op->direction) 1259 if (i > 0 && i != op->direction)
1304 { 1260 {
1305 op->direction = i; 1261 op->direction = i;
1306 SET_ANIMATION (op, op->direction); 1262 SET_ANIMATION (op, op->direction);
1307 } 1263 }
1308 1264
1309 insert_ob_in_map (op, op->map, op, 0); 1265 m->insert (op, new_x, new_y, op);
1310} 1266}
1311 1267
1312/**************************************************************************** 1268/****************************************************************************
1313 * Destruction 1269 * Destruction
1314 ****************************************************************************/ 1270 ****************************************************************************/
1392 for (j = -range; j < range; j++) 1348 for (j = -range; j < range; j++)
1393 { 1349 {
1394 m = op->map; 1350 m = op->map;
1395 sx = op->x + i; 1351 sx = op->x + i;
1396 sy = op->y + j; 1352 sy = op->y + j;
1353
1397 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1354 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1398 if (mflags & P_OUT_OF_MAP) 1355 if (mflags & P_OUT_OF_MAP)
1399 continue; 1356 continue;
1357
1400 if (mflags & P_IS_ALIVE) 1358 if (mflags & P_IS_ALIVE)
1401 { 1359 {
1402 for (tmp = get_map_ob (m, sx, sy); tmp; tmp = tmp->above) 1360 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above)
1403 {
1404 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1361 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1405 break; 1362 break;
1406 } 1363
1407 if (tmp) 1364 if (tmp)
1408 { 1365 {
1409 if (tmp->head) 1366 if (tmp->head)
1410 tmp = tmp->head; 1367 tmp = tmp->head;
1411 1368
1414 { 1371 {
1415 if (spell_ob->subtype == SP_DESTRUCTION) 1372 if (spell_ob->subtype == SP_DESTRUCTION)
1416 { 1373 {
1417 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1374 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1418 if (spell_ob->other_arch) 1375 if (spell_ob->other_arch)
1419 {
1420 tmp = arch_to_object (spell_ob->other_arch); 1376 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1421 tmp->x = sx;
1422 tmp->y = sy;
1423 insert_ob_in_map (tmp, m, op, 0);
1424 }
1425 } 1377 }
1426 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100) 1378 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100)
1427 { 1379 {
1428 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch) 1380 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch)
1429 {
1430 object *effect = arch_to_object (spell_ob->other_arch); 1381 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1431
1432 effect->x = sx;
1433 effect->y = sy;
1434 insert_ob_in_map (effect, m, op, 0);
1435 }
1436 } 1382 }
1437 } 1383 }
1438 } 1384 }
1439 } 1385 }
1440 } 1386 }
1441 } 1387 }
1388
1442 op->skill = skill; 1389 op->skill = skill;
1443 return 1; 1390 return 1;
1444} 1391}
1445 1392
1446/*************************************************************************** 1393/***************************************************************************
1530 force->stats.ac = spell_ob->stats.ac; 1477 force->stats.ac = spell_ob->stats.ac;
1531 force->stats.wc = spell_ob->stats.wc; 1478 force->stats.wc = spell_ob->stats.wc;
1532 1479
1533 change_abil (tmp, force); /* Mostly to display any messages */ 1480 change_abil (tmp, force); /* Mostly to display any messages */
1534 insert_ob_in_ob (force, tmp); 1481 insert_ob_in_ob (force, tmp);
1535 fix_player (tmp); 1482 tmp->update_stats ();
1536 return 1; 1483 return 1;
1537 1484
1538} 1485}
1539 1486
1540 1487
1591 1538
1592 /* If there is nothing living on this space, no need to go further */ 1539 /* If there is nothing living on this space, no need to go further */
1593 if (!(mflags & P_IS_ALIVE)) 1540 if (!(mflags & P_IS_ALIVE))
1594 continue; 1541 continue;
1595 1542
1596 for (tmp = get_map_ob (m, nx, ny); tmp; tmp = tmp->above) 1543 for (tmp = GET_MAP_OB (m, nx, ny); tmp; tmp = tmp->above)
1597 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1544 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1598 break; 1545 break;
1599 1546
1600 /* There can be living objects that are not monsters */ 1547 /* There can be living objects that are not monsters */
1601 if (!tmp || tmp->type == PLAYER) 1548 if (!tmp || tmp->type == PLAYER)
1700 head->stats.exp = 0; 1647 head->stats.exp = 0;
1701 } 1648 }
1702 1649
1703 /* If a monster was effected, put an effect in */ 1650 /* If a monster was effected, put an effect in */
1704 if (done_one && spell->other_arch) 1651 if (done_one && spell->other_arch)
1705 {
1706 tmp = arch_to_object (spell->other_arch); 1652 m->insert (arch_to_object (spell->other_arch), nx, ny, op);
1707 tmp->x = nx;
1708 tmp->y = ny;
1709 insert_ob_in_map (tmp, m, op, 0);
1710 }
1711 } /* for y */ 1653 } /* for y */
1712 1654
1713 return 1; 1655 return 1;
1714} 1656}
1715 1657
1766 nx = op->x; 1708 nx = op->x;
1767 ny = op->y; 1709 ny = op->y;
1768 m = op->map; 1710 m = op->map;
1769 } 1711 }
1770 1712
1771 op->remove (); 1713 m->insert (op, nx, ny, op);
1772 op->y = ny;
1773 op->x = nx;
1774 insert_ob_in_map (op, m, op, 0);
1775 1714
1776 dam_save = op->stats.dam; /* save the original dam: we do halfdam on 1715 dam_save = op->stats.dam; /* save the original dam: we do halfdam on
1777 surrounding squares */ 1716 surrounding squares */
1778 1717
1779 /* loop over current square and neighbors to hit. 1718 /* loop over current square and neighbors to hit.
1805 1744
1806 } 1745 }
1807 1746
1808 /* insert the other arch */ 1747 /* insert the other arch */
1809 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy)))) 1748 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy))))
1810 { 1749 m->insert (arch_to_object (op->other_arch), hx, hy, op);
1811 new_ob = arch_to_object (op->other_arch);
1812 new_ob->x = hx;
1813 new_ob->y = hy;
1814 insert_ob_in_map (new_ob, m, op, 0);
1815 }
1816 } 1750 }
1817 1751
1818 /* restore to the center location and damage */ 1752 /* restore to the center location and damage */
1819 op->stats.dam = dam_save; 1753 op->stats.dam = dam_save;
1820 1754
1823 if (i >= 0) 1757 if (i >= 0)
1824 { /* we have a preferred direction! */ 1758 { /* we have a preferred direction! */
1825 /* pick another direction if the preferred dir is blocked. */ 1759 /* pick another direction if the preferred dir is blocked. */
1826 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP || 1760 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP ||
1827 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy))) 1761 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy)))
1828 {
1829 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */ 1762 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */
1830 } 1763
1831 op->direction = i; 1764 op->direction = i;
1832 } 1765 }
1833} 1766}
1834 1767
1835 1768
1965 1898
1966 if (!spell->other_arch) 1899 if (!spell->other_arch)
1967 return 0; 1900 return 0;
1968 1901
1969 tmp = get_archetype (SWARM_SPELL); 1902 tmp = get_archetype (SWARM_SPELL);
1970 tmp->x = op->x;
1971 tmp->y = op->y;
1972 tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */ 1903 tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */
1973 set_spell_skill (op, caster, spell, tmp); 1904 set_spell_skill (op, caster, spell, tmp);
1974 1905
1975 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */ 1906 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */
1976 tmp->spell = arch_to_object (spell->other_arch); 1907 tmp->spell = arch_to_object (spell->other_arch);
1977 1908
1978 tmp->attacktype = tmp->spell->attacktype; 1909 tmp->attacktype = tmp->spell->attacktype;
1979 1910
1980 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) 1911 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER)
1981 {
1982 if (!tailor_god_spell (tmp, op)) 1912 if (!tailor_god_spell (tmp, op))
1983 return 1; 1913 return 1;
1984 } 1914
1985 tmp->duration = SP_level_duration_adjust (caster, spell); 1915 tmp->duration = SP_level_duration_adjust (caster, spell);
1986 for (i = 0; i < spell->duration; i++) 1916 for (i = 0; i < spell->duration; i++)
1987 tmp->duration += die_roll (1, 3, op, PREFER_HIGH); 1917 tmp->duration += die_roll (1, 3, op, PREFER_HIGH);
1988 1918
1989 tmp->direction = dir; 1919 tmp->direction = dir;
1990 tmp->invisible = 1; 1920 tmp->invisible = 1;
1991 insert_ob_in_map (tmp, op->map, op, 0); 1921
1922 tmp->insert_at (op, op);
1992 return 1; 1923 return 1;
1993} 1924}
1994 1925
1995 1926
1996/* See the spells documentation file for why this is its own 1927/* See the spells documentation file for why this is its own
2024 return 0; 1955 return 0;
2025 } 1956 }
2026 1957
2027 if (mflags & P_IS_ALIVE && spell->attacktype) 1958 if (mflags & P_IS_ALIVE && spell->attacktype)
2028 { 1959 {
2029 for (target = get_map_ob (m, x, y); target; target = target->above) 1960 for (target = GET_MAP_OB (m, x, y); target; target = target->above)
2030 if (QUERY_FLAG (target, FLAG_MONSTER)) 1961 if (QUERY_FLAG (target, FLAG_MONSTER))
2031 { 1962 {
2032 /* oky doky. got a target monster. Lets make a blinding attack */ 1963 /* oky doky. got a target monster. Lets make a blinding attack */
2033 if (target->head) 1964 if (target->head)
2034 target = target->head; 1965 target = target->head;
2056 { 1987 {
2057 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); 1988 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell);
2058 if (tmp->glow_radius > MAX_LIGHT_RADII) 1989 if (tmp->glow_radius > MAX_LIGHT_RADII)
2059 tmp->glow_radius = MAX_LIGHT_RADII; 1990 tmp->glow_radius = MAX_LIGHT_RADII;
2060 } 1991 }
2061 tmp->x = x; 1992
2062 tmp->y = y; 1993 m->insert (tmp, x, y, op);
2063 insert_ob_in_map (tmp, m, op, 0);
2064 return 1; 1994 return 1;
2065} 1995}
2066 1996
2067 1997
2068 1998
2116 2046
2117 /* Only bother looking on this space if there is something living here */ 2047 /* Only bother looking on this space if there is something living here */
2118 if (mflags & P_IS_ALIVE) 2048 if (mflags & P_IS_ALIVE)
2119 { 2049 {
2120 /* search this square for a victim */ 2050 /* search this square for a victim */
2121 for (walk = get_map_ob (m, x, y); walk; walk = walk->above) 2051 for (walk = GET_MAP_OB (m, x, y); walk; walk = walk->above)
2122 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) 2052 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER))
2123 { /* found a victim */ 2053 { /* found a victim */
2124 object *disease = arch_to_object (spell->other_arch); 2054 object *disease = arch_to_object (spell->other_arch);
2125 2055
2126 disease->set_owner (op); 2056 disease->set_owner (op);
2181 object *flash; /* visual effect for inflicting disease */ 2111 object *flash; /* visual effect for inflicting disease */
2182 2112
2183 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); 2113 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name);
2184 2114
2185 disease->destroy (); /* don't need this one anymore */ 2115 disease->destroy (); /* don't need this one anymore */
2186 flash = get_archetype (ARCH_DETECT_MAGIC); 2116 walk->map->insert (get_archetype (ARCH_DETECT_MAGIC), x, y, op);
2187 flash->x = x;
2188 flash->y = y;
2189 flash->map = walk->map;
2190 insert_ob_in_map (flash, walk->map, op, 0);
2191 return 1; 2117 return 1;
2192 } 2118 }
2193 2119
2194 disease->destroy (); 2120 disease->destroy ();
2195 } 2121 }
2196 } /* if living creature */ 2122 } /* if living creature */
2197 } /* for range of spaces */ 2123 } /* for range of spaces */
2124
2198 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2125 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2199 return 1; 2126 return 1;
2200} 2127}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines