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.23 by root, Mon Dec 25 11:25:50 2006 UTC vs.
Revision 1.26 by pippijn, Sat Jan 6 14:42:31 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
3 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
6 7
7 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
27 */ 28 */
28 29
29#include <global.h> 30#include <global.h>
30#include <object.h> 31#include <object.h>
31#include <living.h> 32#include <living.h>
32#ifndef __CEXTRACT__
33# include <sproto.h> 33#include <sproto.h>
34#endif
35#include <spells.h> 34#include <spells.h>
36#include <sounds.h> 35#include <sounds.h>
37 36
38/* this function checks to see if a spell pushes objects as well 37/* 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) 38 * as flies over and damages them (only used for cones for now)
149 tmp->stats.Dex -= 10; /* less forks from main bolt too */ 148 tmp->stats.Dex -= 10; /* less forks from main bolt too */
150 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */ 149 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */
151 new_bolt->speed_left = -0.1; 150 new_bolt->speed_left = -0.1;
152 new_bolt->direction = t_dir; 151 new_bolt->direction = t_dir;
153 new_bolt->duration++; 152 new_bolt->duration++;
154 new_bolt->x = sx;
155 new_bolt->y = sy;
156 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */ 153 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */
157 new_bolt->stats.dam++; 154 new_bolt->stats.dam++;
158 tmp->stats.dam /= 2; /* reduce father bolt damage */ 155 tmp->stats.dam /= 2; /* reduce father bolt damage */
159 tmp->stats.dam++; 156 tmp->stats.dam++;
160 new_bolt = insert_ob_in_map (new_bolt, m, op, 0); 157 if ((new_bolt = m->insert (new_bolt, sx, sy, op)))
161 update_turn_face (new_bolt); 158 update_turn_face (new_bolt);
162} 159}
163 160
164/* move_bolt: moves bolt 'op'. Basically, it just advances a space, 161/* move_bolt: moves bolt 'op'. Basically, it just advances a space,
165 * and checks for various things that may stop it. 162 * and checks for various things that may stop it.
166 */ 163 */
171 object *tmp; 168 object *tmp;
172 int mflags; 169 int mflags;
173 sint16 x, y; 170 sint16 x, y;
174 maptile *m; 171 maptile *m;
175 172
176 if (--(op->duration) < 0) 173 if (--op->duration < 0)
177 { 174 {
178 op->destroy (); 175 op->destroy ();
179 return; 176 return;
180 } 177 }
181 178
183 180
184 if (!op->direction) 181 if (!op->direction)
185 return; 182 return;
186 183
187 if (--op->range < 0) 184 if (--op->range < 0)
188 {
189 op->range = 0; 185 op->range = 0;
190 }
191 else 186 else
192 { 187 {
193 x = op->x + DIRX (op); 188 x = op->x + DIRX (op);
194 y = op->y + DIRY (op); 189 y = op->y + DIRY (op);
195 m = op->map; 190 m = op->map;
203 * on the space. So only call reflwall if we think the data it returns 198 * on the space. So only call reflwall if we think the data it returns
204 * will be useful. 199 * will be useful.
205 */ 200 */
206 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)) || ((mflags & P_IS_ALIVE) && reflwall (m, x, y, op))) 201 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)) || ((mflags & P_IS_ALIVE) && reflwall (m, x, y, op)))
207 { 202 {
208
209 if (!QUERY_FLAG (op, FLAG_REFLECTING)) 203 if (!QUERY_FLAG (op, FLAG_REFLECTING))
210 return; 204 return;
211 205
212 /* Since walls don't run diagonal, if the bolt is in 206 /* Since walls don't run diagonal, if the bolt is in
213 * one of 4 main directions, it just reflects back in the 207 * one of 4 main directions, it just reflects back in the
243 else if (left) 237 else if (left)
244 op->direction = absdir (op->direction + 2); 238 op->direction = absdir (op->direction + 2);
245 else if (right) 239 else if (right)
246 op->direction = absdir (op->direction - 2); 240 op->direction = absdir (op->direction - 2);
247 } 241 }
242
248 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */ 243 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */
249 return; 244 return;
250 } 245 }
251 else 246 else
252 { /* Create a copy of this object and put it ahead */ 247 { /* Create a copy of this object and put it ahead */
253 tmp = op->clone (); 248 object *tmp = op->clone ();
254 249
250 m->insert (tmp, x, y, op);
255 tmp->speed_left = -0.1; 251 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 */ 252 /* To make up for the decrease at the top of the function */
259 tmp->duration++; 253 tmp->duration++;
260 254
261 /* New forking code. Possibly create forks of this object 255 /* New forking code. Possibly create forks of this object
262 * going off in other directions. 256 * going off in other directions.
263 */ 257 */
264
265 if (rndm (0, 99) < tmp->stats.Dex) 258 if (rndm (0, 99) < tmp->stats.Dex)
266 { /* stats.Dex % of forking */ 259 { /* stats.Dex % of forking */
267 forklightning (op, tmp); 260 forklightning (op, tmp);
268 } 261 }
262
269 /* In this way, the object left behind sticks on the space, but 263 /* In this way, the object left behind sticks on the space, but
270 * doesn't create any bolts that continue to move onward. 264 * doesn't create any bolts that continue to move onward.
271 */ 265 */
272 op->range = 0; 266 op->range = 0;
273 } /* copy object and move it along */ 267 } /* copy object and move it along */
338 tmp->y = op->y; 332 tmp->y = op->y;
339 tmp->direction = absdir (tmp->direction + 4); 333 tmp->direction = absdir (tmp->direction + 4);
340 tmp->map = op->map; 334 tmp->map = op->map;
341 } 335 }
342 336
343 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 337 if ((tmp = tmp->insert_at (tmp, op)))
344 move_bolt (tmp); 338 move_bolt (tmp);
345 339
346 return 1; 340 return 1;
347} 341}
348 342
359 * At least that is what I think this does. 353 * At least that is what I think this does.
360 */ 354 */
361void 355void
362explosion (object *op) 356explosion (object *op)
363{ 357{
364 object *tmp;
365 maptile *m = op->map; 358 maptile *m = op->map;
366 int i; 359 int i;
367 360
368 if (--(op->duration) < 0) 361 if (--op->duration < 0)
369 { 362 {
370 op->destroy (); 363 op->destroy ();
371 return; 364 return;
372 } 365 }
373 366
379 { 372 {
380 sint16 dx, dy; 373 sint16 dx, dy;
381 374
382 dx = op->x + freearr_x[i]; 375 dx = op->x + freearr_x[i];
383 dy = op->y + freearr_y[i]; 376 dy = op->y + freearr_y[i];
377
384 /* ok_to_put_more already does things like checks for walls, 378 /* ok_to_put_more already does things like checks for walls,
385 * out of map, etc. 379 * out of map, etc.
386 */ 380 */
387 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype)) 381 if (ok_to_put_more (op->map, dx, dy, op, op->attacktype))
388 { 382 {
389 tmp = op->clone (); 383 object *tmp = op->clone ();
384
390 tmp->state = 0; 385 tmp->state = 0;
391 tmp->speed_left = -0.21; 386 tmp->speed_left = -0.21;
392 tmp->range--; 387 tmp->range--;
393 tmp->value = 0; 388 tmp->value = 0;
394 tmp->x = dx; 389
395 tmp->y = dy; 390 m->insert (tmp, dx, dy, op);
396 insert_ob_in_map (tmp, m, op, 0);
397 } 391 }
398 } 392 }
399 } 393 }
400} 394}
401 395
416 return; 410 return;
417 } 411 }
418 412
419 if (op->env) 413 if (op->env)
420 { 414 {
421 object *env;
422
423 env = object_get_env_recursive (op); 415 object *env = object_get_env_recursive (op);
424 if (env->map == NULL || out_of_map (env->map, env->x, env->y)) 416 if (env->map == NULL || out_of_map (env->map, env->x, env->y))
425 { 417 {
426 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 418 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
427 op->destroy (); 419 op->destroy ();
428 return; 420 return;
429 } 421 }
430 422
431 op->remove (); 423 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON);
432 op->x = env->x;
433 op->y = env->y;
434 insert_ob_in_map (op, env->map, op, INS_NO_MERGE | INS_NO_WALK_ON);
435 } 424 }
436 else if (out_of_map (op->map, op->x, op->y)) 425 else if (out_of_map (op->map, op->x, op->y))
437 { 426 {
438 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 427 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
439 op->destroy (); 428 op->destroy ();
468 { 457 {
469 op->destroy (); 458 op->destroy ();
470 return; 459 return;
471 } 460 }
472 461
473 tmp->x = op->x;
474 tmp->y = op->y;
475
476 /* special for bombs - it actually has sane values for these */ 462 /* special for bombs - it actually has sane values for these */
477 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 463 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
478 { 464 {
479 tmp->attacktype = op->attacktype; 465 tmp->attacktype = op->attacktype;
480 tmp->range = op->range; 466 tmp->range = op->range;
483 } 469 }
484 else 470 else
485 { 471 {
486 if (op->attacktype & AT_MAGIC) 472 if (op->attacktype & AT_MAGIC)
487 tmp->attacktype |= AT_MAGIC; 473 tmp->attacktype |= AT_MAGIC;
474
488 /* Spell doc describes what is going on here */ 475 /* Spell doc describes what is going on here */
489 tmp->stats.dam = op->dam_modifier; 476 tmp->stats.dam = op->dam_modifier;
490 tmp->range = op->stats.maxhp; 477 tmp->range = op->stats.maxhp;
491 tmp->duration = op->stats.hp; 478 tmp->duration = op->stats.hp;
492 /* Used for spell tracking - just need a unique val for this spell - 479 /* Used for spell tracking - just need a unique val for this spell -
500 tmp->stats.sp = op->direction; 487 tmp->stats.sp = op->direction;
501 488
502 /* Prevent recursion */ 489 /* Prevent recursion */
503 op->move_on = 0; 490 op->move_on = 0;
504 491
505 insert_ob_in_map (tmp, op->map, op, 0); 492 tmp->insert_at (op, op);
506 /* remove the firebullet */ 493 /* remove the firebullet */
507 if (!op->destroyed ())
508 {
509 op->destroy (); 494 op->destroy ();
510 }
511} 495}
512
513
514 496
515/* checks to see what op should do, given the space it is on 497/* checks to see what op should do, given the space it is on
516 * (eg, explode, damage player, etc) 498 * (eg, explode, damage player, etc)
517 */ 499 */
518
519void 500void
520check_bullet (object *op) 501check_bullet (object *op)
521{ 502{
522 object *tmp; 503 object *tmp;
523 int dam, mflags; 504 int dam, mflags;
612 op->destroy (); 593 op->destroy ();
613 594
614 return; 595 return;
615 } 596 }
616 597
617 op->remove (); 598 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; 599 return;
622 600
623 if (reflwall (op->map, op->x, op->y, op)) 601 if (reflwall (op->map, op->x, op->y, op))
624 { 602 {
625 op->direction = absdir (op->direction + 4); 603 op->direction = absdir (op->direction + 4);
700 tmp->y = op->y; 678 tmp->y = op->y;
701 tmp->direction = absdir (tmp->direction + 4); 679 tmp->direction = absdir (tmp->direction + 4);
702 tmp->map = op->map; 680 tmp->map = op->map;
703 } 681 }
704 682
705 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0))) 683 if ((tmp = tmp->insert_at (tmp, op)))
706 check_bullet (tmp); 684 check_bullet (tmp);
707 685
708 return 1; 686 return 1;
709} 687}
710 688
722void 700void
723cone_drop (object *op) 701cone_drop (object *op)
724{ 702{
725 object *new_ob = arch_to_object (op->other_arch); 703 object *new_ob = arch_to_object (op->other_arch);
726 704
727 new_ob->x = op->x;
728 new_ob->y = op->y;
729 new_ob->level = op->level; 705 new_ob->level = op->level;
730 new_ob->set_owner (op->owner); 706 new_ob->set_owner (op->owner);
731 707
732 /* preserve skill ownership */ 708 /* preserve skill ownership */
733 if (op->skill && op->skill != new_ob->skill) 709 if (op->skill && op->skill != new_ob->skill)
734 {
735 new_ob->skill = op->skill; 710 new_ob->skill = op->skill;
736 }
737 insert_ob_in_map (new_ob, op->map, op, 0);
738 711
712 new_ob->insert_at (op, op);
739} 713}
740 714
741/* move_cone: causes cone object 'op' to move a space/hit creatures */ 715/* move_cone: causes cone object 'op' to move a space/hit creatures */
742 716
743void 717void
747 721
748 /* if no map then hit_map will crash so just ignore object */ 722 /* if no map then hit_map will crash so just ignore object */
749 if (!op->map) 723 if (!op->map)
750 { 724 {
751 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 725 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
752 op->speed = 0; 726 op->set_speed (0);
753 update_ob_speed (op);
754 return; 727 return;
755 } 728 }
756 729
757 /* lava saves it's life, but not yours :) */ 730 /* lava saves it's life, but not yours :) */
758 if (QUERY_FLAG (op, FLAG_LIFESAVE)) 731 if (QUERY_FLAG (op, FLAG_LIFESAVE))
806 779
807 if (ok_to_put_more (op->map, x, y, op, op->attacktype)) 780 if (ok_to_put_more (op->map, x, y, op, op->attacktype))
808 { 781 {
809 object *tmp = op->clone (); 782 object *tmp = op->clone ();
810 783
811 tmp->x = x;
812 tmp->y = y;
813
814 tmp->duration = op->duration + 1; 784 tmp->duration = op->duration + 1;
815 785
816 /* Use for spell tracking - see ok_to_put_more() */ 786 /* Use for spell tracking - see ok_to_put_more() */
817 tmp->stats.maxhp = op->stats.maxhp; 787 tmp->stats.maxhp = op->stats.maxhp;
818 insert_ob_in_map (tmp, op->map, op, 0); 788
789 op->map->insert (tmp, x, y, op);
790
819 if (tmp->other_arch) 791 if (tmp->other_arch)
820 cone_drop (tmp); 792 cone_drop (tmp);
821 } 793 }
822 } 794 }
823} 795}
902 success = 1; 874 success = 1;
903 tmp = arch_to_object (spell->other_arch); 875 tmp = arch_to_object (spell->other_arch);
904 tmp->set_owner (op); 876 tmp->set_owner (op);
905 set_spell_skill (op, caster, spell, tmp); 877 set_spell_skill (op, caster, spell, tmp);
906 tmp->level = caster_level (caster, spell); 878 tmp->level = caster_level (caster, spell);
907 tmp->x = sx;
908 tmp->y = sy;
909 tmp->attacktype = spell->attacktype; 879 tmp->attacktype = spell->attacktype;
910 880
911 /* holy word stuff */ 881 /* holy word stuff */
912 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) 882 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER))
913 if (!tailor_god_spell (tmp, op)) 883 if (!tailor_god_spell (tmp, op))
950 920
951 if (!(tmp->move_type & MOVE_FLY_LOW)) 921 if (!(tmp->move_type & MOVE_FLY_LOW))
952 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name); 922 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name);
953 923
954 if (!tmp->move_on && tmp->stats.dam) 924 if (!tmp->move_on && tmp->stats.dam)
955 {
956 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name); 925 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name);
957 }
958 926
959 insert_ob_in_map (tmp, m, op, 0); 927 m->insert (tmp, sx, sy, op);
960 928
961 /* This is used for tracking spells so that one effect doesn't hit 929 /* This is used for tracking spells so that one effect doesn't hit
962 * a single space too many times. 930 * a single space too many times.
963 */ 931 */
964 tmp->stats.maxhp = tmp->count; 932 tmp->stats.maxhp = tmp->count;
983void 951void
984animate_bomb (object *op) 952animate_bomb (object *op)
985{ 953{
986 int i; 954 int i;
987 object *env, *tmp; 955 object *env, *tmp;
988 archetype *at;
989 956
990 if (op->state != NUM_ANIMATIONS (op) - 1) 957 if (op->state != NUM_ANIMATIONS (op) - 1)
991 return; 958 return;
992 959
993 env = object_get_env_recursive (op); 960 env = object_get_env_recursive (op);
998 return; 965 return;
999 966
1000 if (env->type == PLAYER) 967 if (env->type == PLAYER)
1001 esrv_del_item (env->contr, op->count); 968 esrv_del_item (env->contr, op->count);
1002 969
1003 op->remove (); 970 if (!(op = op->insert_at (env, op)))
1004 op->x = env->x;
1005 op->y = env->y;
1006 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL)
1007 return; 971 return;
1008 } 972 }
1009 973
1010 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding 974 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding
1011 // on a safe map. I don't like this special casing, but it seems to be neccessary 975 // on a safe map. I don't like this special casing, but it seems to be neccessary
1018 982
1019 /* This copies a lot of the code from the fire bullet, 983 /* This copies a lot of the code from the fire bullet,
1020 * but using the cast_bullet isn't really feasible, 984 * but using the cast_bullet isn't really feasible,
1021 * so just set up the appropriate values. 985 * so just set up the appropriate values.
1022 */ 986 */
1023 at = archetype::find (SPLINT); 987 if (archetype *at = archetype::find (SPLINT))
1024 if (at)
1025 { 988 {
1026 for (i = 1; i < 9; i++) 989 for (i = 1; i < 9; i++)
1027 { 990 {
1028 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) 991 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i]))
1029 continue; 992 continue;
993
1030 tmp = arch_to_object (at); 994 tmp = arch_to_object (at);
1031 tmp->direction = i; 995 tmp->direction = i;
1032 tmp->range = op->range; 996 tmp->range = op->range;
1033 tmp->stats.dam = op->stats.dam; 997 tmp->stats.dam = op->stats.dam;
1034 tmp->duration = op->duration; 998 tmp->duration = op->duration;
1035 tmp->attacktype = op->attacktype; 999 tmp->attacktype = op->attacktype;
1036 tmp->set_owner (op); 1000 tmp->set_owner (op);
1037 if (op->skill && op->skill != tmp->skill) 1001 if (op->skill && op->skill != tmp->skill)
1038 {
1039 tmp->skill = op->skill; 1002 tmp->skill = op->skill;
1040 } 1003
1041 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1004 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1042 SET_ANIMATION (tmp, i); 1005 SET_ANIMATION (tmp, i);
1043 tmp->x = op->x + freearr_x[i]; 1006
1044 tmp->y = op->y + freearr_x[i]; 1007 op->map->insert (tmp, op->x + freearr_x[i], op->y + freearr_x[i], op);
1045 insert_ob_in_map (tmp, op->map, op, 0);
1046 move_bullet (tmp); 1008 move_bullet (tmp);
1047 } 1009 }
1048 } 1010 }
1049 1011
1050 explode_bullet (op); 1012 explode_bullet (op);
1073 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1035 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1074 tmp->attacktype = spell->attacktype; 1036 tmp->attacktype = spell->attacktype;
1075 1037
1076 tmp->set_owner (op); 1038 tmp->set_owner (op);
1077 set_spell_skill (op, caster, spell, tmp); 1039 set_spell_skill (op, caster, spell, tmp);
1078 tmp->x = dx; 1040
1079 tmp->y = dy; 1041 m->insert (tmp, dx, dy, op);
1080 insert_ob_in_map (tmp, m, op, 0);
1081 return 1; 1042 return 1;
1082} 1043}
1083 1044
1084/**************************************************************************** 1045/****************************************************************************
1085 * 1046 *
1228 1189
1229 effect->set_owner (op); 1190 effect->set_owner (op);
1230 set_spell_skill (op, caster, spell, effect); 1191 set_spell_skill (op, caster, spell, effect);
1231 1192
1232 /* ok, tell it where to be, and insert! */ 1193 /* ok, tell it where to be, and insert! */
1233 effect->x = target->x; 1194 effect->insert_at (target, op);
1234 effect->y = target->y;
1235 insert_ob_in_map (effect, target->map, op, 0);
1236 1195
1237 return 1; 1196 return 1;
1238} 1197}
1239 1198
1240 1199
1295 { 1254 {
1296 op->destroy (); 1255 op->destroy ();
1297 return; 1256 return;
1298 } 1257 }
1299 1258
1300 op->x = new_x;
1301 op->y = new_y;
1302 op->map = m;
1303 i = spell_find_dir (op->map, op->x, op->y, op->owner); 1259 i = spell_find_dir (m, new_x, new_y, op->owner);
1304 if (i > 0 && i != op->direction) 1260 if (i > 0 && i != op->direction)
1305 { 1261 {
1306 op->direction = i; 1262 op->direction = i;
1307 SET_ANIMATION (op, op->direction); 1263 SET_ANIMATION (op, op->direction);
1308 } 1264 }
1309 1265
1310 insert_ob_in_map (op, op->map, op, 0); 1266 m->insert (op, new_x, new_y, op);
1311} 1267}
1312 1268
1313/**************************************************************************** 1269/****************************************************************************
1314 * Destruction 1270 * Destruction
1315 ****************************************************************************/ 1271 ****************************************************************************/
1393 for (j = -range; j < range; j++) 1349 for (j = -range; j < range; j++)
1394 { 1350 {
1395 m = op->map; 1351 m = op->map;
1396 sx = op->x + i; 1352 sx = op->x + i;
1397 sy = op->y + j; 1353 sy = op->y + j;
1354
1398 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1355 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1399 if (mflags & P_OUT_OF_MAP) 1356 if (mflags & P_OUT_OF_MAP)
1400 continue; 1357 continue;
1358
1401 if (mflags & P_IS_ALIVE) 1359 if (mflags & P_IS_ALIVE)
1402 { 1360 {
1403 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above) 1361 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above)
1404 {
1405 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1362 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1406 break; 1363 break;
1407 } 1364
1408 if (tmp) 1365 if (tmp)
1409 { 1366 {
1410 if (tmp->head) 1367 if (tmp->head)
1411 tmp = tmp->head; 1368 tmp = tmp->head;
1412 1369
1415 { 1372 {
1416 if (spell_ob->subtype == SP_DESTRUCTION) 1373 if (spell_ob->subtype == SP_DESTRUCTION)
1417 { 1374 {
1418 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1375 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1419 if (spell_ob->other_arch) 1376 if (spell_ob->other_arch)
1420 {
1421 tmp = arch_to_object (spell_ob->other_arch); 1377 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1422 tmp->x = sx;
1423 tmp->y = sy;
1424 insert_ob_in_map (tmp, m, op, 0);
1425 }
1426 } 1378 }
1427 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100) 1379 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100)
1428 { 1380 {
1429 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch) 1381 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch)
1430 {
1431 object *effect = arch_to_object (spell_ob->other_arch); 1382 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1432
1433 effect->x = sx;
1434 effect->y = sy;
1435 insert_ob_in_map (effect, m, op, 0);
1436 }
1437 } 1383 }
1438 } 1384 }
1439 } 1385 }
1440 } 1386 }
1441 } 1387 }
1442 } 1388 }
1389
1443 op->skill = skill; 1390 op->skill = skill;
1444 return 1; 1391 return 1;
1445} 1392}
1446 1393
1447/*************************************************************************** 1394/***************************************************************************
1701 head->stats.exp = 0; 1648 head->stats.exp = 0;
1702 } 1649 }
1703 1650
1704 /* If a monster was effected, put an effect in */ 1651 /* If a monster was effected, put an effect in */
1705 if (done_one && spell->other_arch) 1652 if (done_one && spell->other_arch)
1706 {
1707 tmp = arch_to_object (spell->other_arch); 1653 m->insert (arch_to_object (spell->other_arch), nx, ny, op);
1708 tmp->x = nx;
1709 tmp->y = ny;
1710 insert_ob_in_map (tmp, m, op, 0);
1711 }
1712 } /* for y */ 1654 } /* for y */
1713 1655
1714 return 1; 1656 return 1;
1715} 1657}
1716 1658
1767 nx = op->x; 1709 nx = op->x;
1768 ny = op->y; 1710 ny = op->y;
1769 m = op->map; 1711 m = op->map;
1770 } 1712 }
1771 1713
1772 op->remove (); 1714 m->insert (op, nx, ny, op);
1773 op->y = ny;
1774 op->x = nx;
1775 insert_ob_in_map (op, m, op, 0);
1776 1715
1777 dam_save = op->stats.dam; /* save the original dam: we do halfdam on 1716 dam_save = op->stats.dam; /* save the original dam: we do halfdam on
1778 surrounding squares */ 1717 surrounding squares */
1779 1718
1780 /* loop over current square and neighbors to hit. 1719 /* loop over current square and neighbors to hit.
1806 1745
1807 } 1746 }
1808 1747
1809 /* insert the other arch */ 1748 /* insert the other arch */
1810 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy)))) 1749 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy))))
1811 { 1750 m->insert (arch_to_object (op->other_arch), hx, hy, op);
1812 new_ob = arch_to_object (op->other_arch);
1813 new_ob->x = hx;
1814 new_ob->y = hy;
1815 insert_ob_in_map (new_ob, m, op, 0);
1816 }
1817 } 1751 }
1818 1752
1819 /* restore to the center location and damage */ 1753 /* restore to the center location and damage */
1820 op->stats.dam = dam_save; 1754 op->stats.dam = dam_save;
1821 1755
1824 if (i >= 0) 1758 if (i >= 0)
1825 { /* we have a preferred direction! */ 1759 { /* we have a preferred direction! */
1826 /* pick another direction if the preferred dir is blocked. */ 1760 /* pick another direction if the preferred dir is blocked. */
1827 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP || 1761 if (get_map_flags (op->map, &m, nx + freearr_x[i], ny + freearr_y[i], &hx, &hy) & P_OUT_OF_MAP ||
1828 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy))) 1762 OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy)))
1829 {
1830 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */ 1763 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */
1831 } 1764
1832 op->direction = i; 1765 op->direction = i;
1833 } 1766 }
1834} 1767}
1835 1768
1836 1769
1966 1899
1967 if (!spell->other_arch) 1900 if (!spell->other_arch)
1968 return 0; 1901 return 0;
1969 1902
1970 tmp = get_archetype (SWARM_SPELL); 1903 tmp = get_archetype (SWARM_SPELL);
1971 tmp->x = op->x;
1972 tmp->y = op->y;
1973 tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */ 1904 tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */
1974 set_spell_skill (op, caster, spell, tmp); 1905 set_spell_skill (op, caster, spell, tmp);
1975 1906
1976 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */ 1907 tmp->level = caster_level (caster, spell); /*needed later, to get level dep. right. */
1977 tmp->spell = arch_to_object (spell->other_arch); 1908 tmp->spell = arch_to_object (spell->other_arch);
1978 1909
1979 tmp->attacktype = tmp->spell->attacktype; 1910 tmp->attacktype = tmp->spell->attacktype;
1980 1911
1981 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) 1912 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER)
1982 {
1983 if (!tailor_god_spell (tmp, op)) 1913 if (!tailor_god_spell (tmp, op))
1984 return 1; 1914 return 1;
1985 } 1915
1986 tmp->duration = SP_level_duration_adjust (caster, spell); 1916 tmp->duration = SP_level_duration_adjust (caster, spell);
1987 for (i = 0; i < spell->duration; i++) 1917 for (i = 0; i < spell->duration; i++)
1988 tmp->duration += die_roll (1, 3, op, PREFER_HIGH); 1918 tmp->duration += die_roll (1, 3, op, PREFER_HIGH);
1989 1919
1990 tmp->direction = dir; 1920 tmp->direction = dir;
1991 tmp->invisible = 1; 1921 tmp->invisible = 1;
1992 insert_ob_in_map (tmp, op->map, op, 0); 1922
1923 tmp->insert_at (op, op);
1993 return 1; 1924 return 1;
1994} 1925}
1995 1926
1996 1927
1997/* See the spells documentation file for why this is its own 1928/* See the spells documentation file for why this is its own
2057 { 1988 {
2058 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); 1989 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell);
2059 if (tmp->glow_radius > MAX_LIGHT_RADII) 1990 if (tmp->glow_radius > MAX_LIGHT_RADII)
2060 tmp->glow_radius = MAX_LIGHT_RADII; 1991 tmp->glow_radius = MAX_LIGHT_RADII;
2061 } 1992 }
2062 tmp->x = x; 1993
2063 tmp->y = y; 1994 m->insert (tmp, x, y, op);
2064 insert_ob_in_map (tmp, m, op, 0);
2065 return 1; 1995 return 1;
2066} 1996}
2067 1997
2068 1998
2069 1999
2182 object *flash; /* visual effect for inflicting disease */ 2112 object *flash; /* visual effect for inflicting disease */
2183 2113
2184 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); 2114 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name);
2185 2115
2186 disease->destroy (); /* don't need this one anymore */ 2116 disease->destroy (); /* don't need this one anymore */
2187 flash = get_archetype (ARCH_DETECT_MAGIC); 2117 walk->map->insert (get_archetype (ARCH_DETECT_MAGIC), x, y, op);
2188 flash->x = x;
2189 flash->y = y;
2190 flash->map = walk->map;
2191 insert_ob_in_map (flash, walk->map, op, 0);
2192 return 1; 2118 return 1;
2193 } 2119 }
2194 2120
2195 disease->destroy (); 2121 disease->destroy ();
2196 } 2122 }
2197 } /* if living creature */ 2123 } /* if living creature */
2198 } /* for range of spaces */ 2124 } /* for range of spaces */
2125
2199 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2126 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2200 return 1; 2127 return 1;
2201} 2128}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines