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.15 by root, Sat Sep 16 22:24:13 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))
140 138
141 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, sx, sy))) 139 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (m, sx, sy)))
142 return; 140 return;
143 141
144 /* OK, we made a fork */ 142 /* OK, we made a fork */
145 new_bolt = get_object (); 143 new_bolt = tmp->clone ();
146 copy_object (tmp, new_bolt);
147 144
148 /* reduce chances of subsequent forking */ 145 /* reduce chances of subsequent forking */
149 new_bolt->stats.Dex -= 10; 146 new_bolt->stats.Dex -= 10;
150 tmp->stats.Dex -= 10; /* less forks from main bolt too */ 147 tmp->stats.Dex -= 10; /* less forks from main bolt too */
151 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */ 148 new_bolt->stats.Con += 25 * new_dir; /* adjust the left bias */
152 new_bolt->speed_left = -0.1; 149 new_bolt->speed_left = -0.1;
153 new_bolt->direction = t_dir; 150 new_bolt->direction = t_dir;
154 new_bolt->duration++; 151 new_bolt->duration++;
155 new_bolt->x = sx;
156 new_bolt->y = sy;
157 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */ 152 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */
158 new_bolt->stats.dam++; 153 new_bolt->stats.dam++;
159 tmp->stats.dam /= 2; /* reduce father bolt damage */ 154 tmp->stats.dam /= 2; /* reduce father bolt damage */
160 tmp->stats.dam++; 155 tmp->stats.dam++;
161 new_bolt = insert_ob_in_map (new_bolt, m, op, 0); 156 if ((new_bolt = m->insert (new_bolt, sx, sy, op)))
162 update_turn_face (new_bolt); 157 update_turn_face (new_bolt);
163} 158}
164 159
165/* move_bolt: moves bolt 'op'. Basically, it just advances a space, 160/* move_bolt: moves bolt 'op'. Basically, it just advances a space,
166 * and checks for various things that may stop it. 161 * and checks for various things that may stop it.
167 */ 162 */
172 object *tmp; 167 object *tmp;
173 int mflags; 168 int mflags;
174 sint16 x, y; 169 sint16 x, y;
175 maptile *m; 170 maptile *m;
176 171
177 if (--(op->duration) < 0) 172 if (--op->duration < 0)
178 { 173 {
179 remove_ob (op); 174 op->destroy ();
180 free_object (op);
181 return; 175 return;
182 } 176 }
183 177
184 hit_map (op, 0, op->attacktype, 1); 178 hit_map (op, 0, op->attacktype, 1);
185 179
186 if (!op->direction) 180 if (!op->direction)
187 return; 181 return;
188 182
189 if (--op->range < 0) 183 if (--op->range < 0)
190 {
191 op->range = 0; 184 op->range = 0;
192 }
193 else 185 else
194 { 186 {
195 x = op->x + DIRX (op); 187 x = op->x + DIRX (op);
196 y = op->y + DIRY (op); 188 y = op->y + DIRY (op);
197 m = op->map; 189 m = op->map;
205 * 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
206 * will be useful. 198 * will be useful.
207 */ 199 */
208 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)))
209 { 201 {
210
211 if (!QUERY_FLAG (op, FLAG_REFLECTING)) 202 if (!QUERY_FLAG (op, FLAG_REFLECTING))
212 return; 203 return;
213 204
214 /* Since walls don't run diagonal, if the bolt is in 205 /* Since walls don't run diagonal, if the bolt is in
215 * one of 4 main directions, it just reflects back in the 206 * one of 4 main directions, it just reflects back in the
245 else if (left) 236 else if (left)
246 op->direction = absdir (op->direction + 2); 237 op->direction = absdir (op->direction + 2);
247 else if (right) 238 else if (right)
248 op->direction = absdir (op->direction - 2); 239 op->direction = absdir (op->direction - 2);
249 } 240 }
241
250 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */ 242 update_turn_face (op); /* A bolt *must* be IS_TURNABLE */
251 return; 243 return;
252 } 244 }
253 else 245 else
254 { /* Create a copy of this object and put it ahead */ 246 { /* Create a copy of this object and put it ahead */
255 tmp = get_object (); 247 object *tmp = op->clone ();
256 copy_object (op, tmp); 248
249 m->insert (tmp, x, y, op);
257 tmp->speed_left = -0.1; 250 tmp->speed_left = -0.1;
258 tmp->x += DIRX (tmp), tmp->y += DIRY (tmp);
259 tmp = insert_ob_in_map (tmp, op->map, op, 0);
260 /* 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 */
261 tmp->duration++; 252 tmp->duration++;
262 253
263 /* New forking code. Possibly create forks of this object 254 /* New forking code. Possibly create forks of this object
264 * going off in other directions. 255 * going off in other directions.
265 */ 256 */
266
267 if (rndm (0, 99) < tmp->stats.Dex) 257 if (rndm (0, 99) < tmp->stats.Dex)
268 { /* stats.Dex % of forking */ 258 { /* stats.Dex % of forking */
269 forklightning (op, tmp); 259 forklightning (op, tmp);
270 } 260 }
261
271 /* 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
272 * doesn't create any bolts that continue to move onward. 263 * doesn't create any bolts that continue to move onward.
273 */ 264 */
274 op->range = 0; 265 op->range = 0;
275 } /* copy object and move it along */ 266 } /* copy object and move it along */
282 * we remove the magic flag - that can be derived from 273 * we remove the magic flag - that can be derived from
283 * spob->attacktype. 274 * spob->attacktype.
284 * This function sets up the appropriate owner and skill 275 * This function sets up the appropriate owner and skill
285 * pointers. 276 * pointers.
286 */ 277 */
287
288int 278int
289fire_bolt (object *op, object *caster, int dir, object *spob, object *skill) 279fire_bolt (object *op, object *caster, int dir, object *spob, object *skill)
290{ 280{
291 object *tmp = NULL; 281 object *tmp = NULL;
292 int mflags; 282 int mflags;
310 300
311 tmp->direction = dir; 301 tmp->direction = dir;
312 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 302 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
313 SET_ANIMATION (tmp, dir); 303 SET_ANIMATION (tmp, dir);
314 304
315 set_owner (tmp, op); 305 tmp->set_owner (op);
316 set_spell_skill (op, caster, spob, tmp); 306 set_spell_skill (op, caster, spob, tmp);
317 307
318 tmp->x = op->x + DIRX (tmp); 308 tmp->x = op->x + DIRX (tmp);
319 tmp->y = op->y + DIRY (tmp); 309 tmp->y = op->y + DIRY (tmp);
320 tmp->map = op->map; 310 tmp->map = op->map;
321 311
312 maptile *newmap;
322 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);
323 if (mflags & P_OUT_OF_MAP) 314 if (mflags & P_OUT_OF_MAP)
324 { 315 {
325 free_object (tmp); 316 tmp->destroy ();
326 return 0; 317 return 0;
327 } 318 }
319
320 tmp->map = newmap;
321
328 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)))
329 { 323 {
330 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 324 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
331 { 325 {
332 free_object (tmp); 326 tmp->destroy ();
333 return 0; 327 return 0;
334 } 328 }
329
335 tmp->x = op->x; 330 tmp->x = op->x;
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 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 335
336 if ((tmp = tmp->insert_at (tmp, op)))
341 move_bolt (tmp); 337 move_bolt (tmp);
338
342 return 1; 339 return 1;
343} 340}
344 341
345 342
346 343
355 * At least that is what I think this does. 352 * At least that is what I think this does.
356 */ 353 */
357void 354void
358explosion (object *op) 355explosion (object *op)
359{ 356{
360 object *tmp;
361 maptile *m = op->map; 357 maptile *m = op->map;
362 int i; 358 int i;
363 359
364 if (--(op->duration) < 0) 360 if (--op->duration < 0)
365 { 361 {
366 remove_ob (op); 362 op->destroy ();
367 free_object (op);
368 return; 363 return;
369 } 364 }
365
370 hit_map (op, 0, op->attacktype, 0); 366 hit_map (op, 0, op->attacktype, 0);
371 367
372 if (op->range > 0) 368 if (op->range > 0)
373 { 369 {
374 for (i = 1; i < 9; i++) 370 for (i = 1; i < 9; i++)
375 { 371 {
376 sint16 dx, dy; 372 sint16 dx, dy;
377 373
378 dx = op->x + freearr_x[i]; 374 dx = op->x + freearr_x[i];
379 dy = op->y + freearr_y[i]; 375 dy = op->y + freearr_y[i];
376
380 /* ok_to_put_more already does things like checks for walls, 377 /* ok_to_put_more already does things like checks for walls,
381 * out of map, etc. 378 * out of map, etc.
382 */ 379 */
383 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))
384 { 381 {
385 tmp = get_object (); 382 object *tmp = op->clone ();
386 copy_object (op, tmp); 383
387 tmp->state = 0; 384 tmp->state = 0;
388 tmp->speed_left = -0.21; 385 tmp->speed_left = -0.21;
389 tmp->range--; 386 tmp->range--;
390 tmp->value = 0; 387 tmp->value = 0;
391 tmp->x = dx; 388
392 tmp->y = dy; 389 m->insert (tmp, dx, dy, op);
393 insert_ob_in_map (tmp, m, op, 0);
394 } 390 }
395 } 391 }
396 } 392 }
397} 393}
398 394
407 object *tmp, *owner; 403 object *tmp, *owner;
408 404
409 if (op->other_arch == NULL) 405 if (op->other_arch == NULL)
410 { 406 {
411 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 407 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
412 remove_ob (op); 408 op->destroy ();
413 free_object (op);
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 remove_ob (op); 418 op->destroy ();
426 free_object (op);
427 return; 419 return;
428 } 420 }
429 remove_ob (op); 421
430 op->x = env->x; 422 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON);
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 remove_ob (op); 427 op->destroy ();
438 free_object (op);
439 return; 428 return;
440 } 429 }
441 430
442 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps 431 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps
443 // NOTE: If this breaks something important: remove this. I can't think of anything 432 // NOTE: If this breaks something important: remove this. I can't think of anything
444 // bad at the moment that might happen from this. 433 // bad at the moment that might happen from this.
445 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 434 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
446 { 435 {
447 remove_ob (op); 436 op->destroy ();
448 free_object (op);
449 return; 437 return;
450 } 438 }
451 439
452 if (op->attacktype) 440 if (op->attacktype)
453 { 441 {
457 } 445 }
458 446
459 /* other_arch contains what this explodes into */ 447 /* other_arch contains what this explodes into */
460 tmp = arch_to_object (op->other_arch); 448 tmp = arch_to_object (op->other_arch);
461 449
462 copy_owner (tmp, op); 450 tmp->set_owner (op);
463 tmp->skill = op->skill; 451 tmp->skill = op->skill;
464 452
465 owner = get_owner (op); 453 owner = op->owner;
466 454
467 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) 455 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner))
468 { 456 {
469 remove_ob (op); 457 op->destroy ();
470 free_object (op);
471 return; 458 return;
472 } 459 }
473
474 tmp->x = op->x;
475 tmp->y = op->y;
476 460
477 /* special for bombs - it actually has sane values for these */ 461 /* special for bombs - it actually has sane values for these */
478 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 462 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
479 { 463 {
480 tmp->attacktype = op->attacktype; 464 tmp->attacktype = op->attacktype;
484 } 468 }
485 else 469 else
486 { 470 {
487 if (op->attacktype & AT_MAGIC) 471 if (op->attacktype & AT_MAGIC)
488 tmp->attacktype |= AT_MAGIC; 472 tmp->attacktype |= AT_MAGIC;
473
489 /* Spell doc describes what is going on here */ 474 /* Spell doc describes what is going on here */
490 tmp->stats.dam = op->dam_modifier; 475 tmp->stats.dam = op->dam_modifier;
491 tmp->range = op->stats.maxhp; 476 tmp->range = op->stats.maxhp;
492 tmp->duration = op->stats.hp; 477 tmp->duration = op->stats.hp;
493 /* 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 -
501 tmp->stats.sp = op->direction; 486 tmp->stats.sp = op->direction;
502 487
503 /* Prevent recursion */ 488 /* Prevent recursion */
504 op->move_on = 0; 489 op->move_on = 0;
505 490
506 insert_ob_in_map (tmp, op->map, op, 0); 491 tmp->insert_at (op, op);
507 /* remove the firebullet */ 492 /* remove the firebullet */
508 if (!op->destroyed ()) 493 op->destroy ();
509 {
510 remove_ob (op);
511 free_object (op);
512 }
513} 494}
514
515
516 495
517/* 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
518 * (eg, explode, damage player, etc) 497 * (eg, explode, damage player, etc)
519 */ 498 */
520
521void 499void
522check_bullet (object *op) 500check_bullet (object *op)
523{ 501{
524 object *tmp; 502 object *tmp;
525 int dam, mflags; 503 int dam, mflags;
540 518
541 /* 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 */
542 if (!(mflags & P_IS_ALIVE)) 520 if (!(mflags & P_IS_ALIVE))
543 return; 521 return;
544 522
545 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)
546 { 524 {
547 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 525 if (QUERY_FLAG (tmp, FLAG_ALIVE))
548 { 526 {
549 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 527 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
550 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 528 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
551 { 529 {
552 if (!QUERY_FLAG (op, FLAG_REMOVED)) 530 if (!QUERY_FLAG (op, FLAG_REMOVED))
553 { 531 {
554 remove_ob (op); 532 op->destroy ();
555 free_object (op);
556 return; 533 return;
557 } 534 }
558 } 535 }
559 } 536 }
560 } 537 }
561} 538}
562
563 539
564/* Basically, we move 'op' one square, and if it hits something, 540/* Basically, we move 'op' one square, and if it hits something,
565 * call check_bullet. 541 * call check_bullet.
566 * This function is only applicable to bullets, but not to all 542 * This function is only applicable to bullets, but not to all
567 * fired arches (eg, bolts). 543 * fired arches (eg, bolts).
568 */ 544 */
569
570void 545void
571move_bullet (object *op) 546move_bullet (object *op)
572{ 547{
573 sint16 new_x, new_y; 548 sint16 new_x, new_y;
574 int mflags; 549 int mflags;
589 564
590 /* Reached the end of its life - remove it */ 565 /* Reached the end of its life - remove it */
591 if (--op->range <= 0) 566 if (--op->range <= 0)
592 { 567 {
593 if (op->other_arch) 568 if (op->other_arch)
594 {
595 explode_bullet (op); 569 explode_bullet (op);
596 }
597 else 570 else
598 { 571 op->destroy ();
599 remove_ob (op); 572
600 free_object (op);
601 }
602 return; 573 return;
603 } 574 }
604 575
605 new_x = op->x + DIRX (op); 576 new_x = op->x + DIRX (op);
606 new_y = op->y + DIRY (op); 577 new_y = op->y + DIRY (op);
607 m = op->map; 578 m = op->map;
608 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y); 579 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y);
609 580
610 if (mflags & P_OUT_OF_MAP) 581 if (mflags & P_OUT_OF_MAP)
611 { 582 {
612 remove_ob (op); 583 op->destroy ();
613 free_object (op);
614 return; 584 return;
615 } 585 }
616 586
617 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 587 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))
618 { 588 {
619 if (op->other_arch) 589 if (op->other_arch)
620 {
621 explode_bullet (op); 590 explode_bullet (op);
622 }
623 else 591 else
624 { 592 op->destroy ();
625 remove_ob (op); 593
626 free_object (op);
627 }
628 return; 594 return;
629 } 595 }
630 596
631 remove_ob (op); 597 if (!(op = m->insert (op, new_x, new_y, op)))
632 op->x = new_x;
633 op->y = new_y;
634 if ((op = insert_ob_in_map (op, m, op, 0)) == NULL)
635 return; 598 return;
636 599
637 if (reflwall (op->map, op->x, op->y, op)) 600 if (reflwall (op->map, op->x, op->y, op))
638 { 601 {
639 op->direction = absdir (op->direction + 4); 602 op->direction = absdir (op->direction + 4);
640 update_turn_face (op); 603 update_turn_face (op);
641 } 604 }
642 else 605 else
643 {
644 check_bullet (op); 606 check_bullet (op);
645 }
646} 607}
647 608
648 609
649 610
650 611
685 646
686 tmp->direction = dir; 647 tmp->direction = dir;
687 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 648 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
688 SET_ANIMATION (tmp, dir); 649 SET_ANIMATION (tmp, dir);
689 650
690 set_owner (tmp, op); 651 tmp->set_owner (op);
691 set_spell_skill (op, caster, spob, tmp); 652 set_spell_skill (op, caster, spob, tmp);
692 653
693 tmp->x = op->x + freearr_x[dir]; 654 tmp->x = op->x + freearr_x[dir];
694 tmp->y = op->y + freearr_y[dir]; 655 tmp->y = op->y + freearr_y[dir];
695 tmp->map = op->map; 656 tmp->map = op->map;
696 657
658 maptile *newmap;
697 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);
698 if (mflags & P_OUT_OF_MAP) 660 if (mflags & P_OUT_OF_MAP)
699 { 661 {
700 free_object (tmp); 662 tmp->destroy ();
701 return 0; 663 return 0;
702 } 664 }
665
666 tmp->map = newmap;
667
703 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)))
704 { 669 {
705 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 670 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
706 { 671 {
707 free_object (tmp); 672 tmp->destroy ();
708 return 0; 673 return 0;
709 } 674 }
675
710 tmp->x = op->x; 676 tmp->x = op->x;
711 tmp->y = op->y; 677 tmp->y = op->y;
712 tmp->direction = absdir (tmp->direction + 4); 678 tmp->direction = absdir (tmp->direction + 4);
713 tmp->map = op->map; 679 tmp->map = op->map;
714 } 680 }
715 if ((tmp = insert_ob_in_map (tmp, tmp->map, op, 0)) != NULL) 681
716 { 682 if ((tmp = tmp->insert_at (tmp, op)))
717 check_bullet (tmp); 683 check_bullet (tmp);
718 } 684
719 return 1; 685 return 1;
720} 686}
721 687
722 688
723 689
733void 699void
734cone_drop (object *op) 700cone_drop (object *op)
735{ 701{
736 object *new_ob = arch_to_object (op->other_arch); 702 object *new_ob = arch_to_object (op->other_arch);
737 703
738 new_ob->x = op->x;
739 new_ob->y = op->y;
740 new_ob->level = op->level; 704 new_ob->level = op->level;
741 set_owner (new_ob, op->owner); 705 new_ob->set_owner (op->owner);
742 706
743 /* preserve skill ownership */ 707 /* preserve skill ownership */
744 if (op->skill && op->skill != new_ob->skill) 708 if (op->skill && op->skill != new_ob->skill)
745 {
746 new_ob->skill = op->skill; 709 new_ob->skill = op->skill;
747 }
748 insert_ob_in_map (new_ob, op->map, op, 0);
749 710
711 new_ob->insert_at (op, op);
750} 712}
751 713
752/* 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 */
753 715
754void 716void
758 720
759 /* 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 */
760 if (!op->map) 722 if (!op->map)
761 { 723 {
762 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");
763 op->speed = 0; 725 op->set_speed (0);
764 update_ob_speed (op);
765 return; 726 return;
766 } 727 }
767 728
768 /* lava saves it's life, but not yours :) */ 729 /* lava saves it's life, but not yours :) */
769 if (QUERY_FLAG (op, FLAG_LIFESAVE)) 730 if (QUERY_FLAG (op, FLAG_LIFESAVE))
775#if 0 736#if 0
776 /* Disable this - enabling it makes monsters easier, as 737 /* Disable this - enabling it makes monsters easier, as
777 * when their cone dies when they die. 738 * when their cone dies when they die.
778 */ 739 */
779 /* If no owner left, the spell dies out. */ 740 /* If no owner left, the spell dies out. */
780 if (get_owner (op) == NULL) 741 if (op->owner == NULL)
781 { 742 {
782 remove_ob (op); 743 op->destroy ();
783 free_object (op);
784 return; 744 return;
785 } 745 }
786#endif 746#endif
787 747
788 hit_map (op, 0, op->attacktype, 0); 748 hit_map (op, 0, op->attacktype, 0);
797 if (op->destroyed ()) 757 if (op->destroyed ())
798 return; 758 return;
799 759
800 if ((op->duration--) < 0) 760 if ((op->duration--) < 0)
801 { 761 {
802 remove_ob (op); 762 op->destroy ();
803 free_object (op);
804 return; 763 return;
805 } 764 }
806 /* Object has hit maximum range, so don't have it move 765 /* Object has hit maximum range, so don't have it move
807 * any further. When the duration above expires, 766 * any further. When the duration above expires,
808 * then the object will get removed. 767 * then the object will get removed.
817 { 776 {
818 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)]; 777 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)];
819 778
820 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))
821 { 780 {
822 object *tmp = get_object (); 781 object *tmp = op->clone ();
823
824 copy_object (op, tmp);
825 tmp->x = x;
826 tmp->y = y;
827 782
828 tmp->duration = op->duration + 1; 783 tmp->duration = op->duration + 1;
829 784
830 /* Use for spell tracking - see ok_to_put_more() */ 785 /* Use for spell tracking - see ok_to_put_more() */
831 tmp->stats.maxhp = op->stats.maxhp; 786 tmp->stats.maxhp = op->stats.maxhp;
832 insert_ob_in_map (tmp, op->map, op, 0); 787
788 op->map->insert (tmp, x, y, op);
789
833 if (tmp->other_arch) 790 if (tmp->other_arch)
834 cone_drop (tmp); 791 cone_drop (tmp);
835 } 792 }
836 } 793 }
837} 794}
913 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype) 870 if ((movetype & GET_MAP_MOVE_BLOCK (m, sx, sy)) == movetype)
914 continue; 871 continue;
915 872
916 success = 1; 873 success = 1;
917 tmp = arch_to_object (spell->other_arch); 874 tmp = arch_to_object (spell->other_arch);
918 set_owner (tmp, op); 875 tmp->set_owner (op);
919 set_spell_skill (op, caster, spell, tmp); 876 set_spell_skill (op, caster, spell, tmp);
920 tmp->level = caster_level (caster, spell); 877 tmp->level = caster_level (caster, spell);
921 tmp->x = sx;
922 tmp->y = sy;
923 tmp->attacktype = spell->attacktype; 878 tmp->attacktype = spell->attacktype;
924 879
925 /* holy word stuff */ 880 /* holy word stuff */
926 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) 881 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER))
927 if (!tailor_god_spell (tmp, op)) 882 if (!tailor_god_spell (tmp, op))
964 919
965 if (!(tmp->move_type & MOVE_FLY_LOW)) 920 if (!(tmp->move_type & MOVE_FLY_LOW))
966 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);
967 922
968 if (!tmp->move_on && tmp->stats.dam) 923 if (!tmp->move_on && tmp->stats.dam)
969 {
970 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);
971 }
972 925
973 insert_ob_in_map (tmp, m, op, 0); 926 m->insert (tmp, sx, sy, op);
974 927
975 /* 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
976 * a single space too many times. 929 * a single space too many times.
977 */ 930 */
978 tmp->stats.maxhp = tmp->count; 931 tmp->stats.maxhp = tmp->count;
997void 950void
998animate_bomb (object *op) 951animate_bomb (object *op)
999{ 952{
1000 int i; 953 int i;
1001 object *env, *tmp; 954 object *env, *tmp;
1002 archetype *at;
1003 955
1004 if (op->state != NUM_ANIMATIONS (op) - 1) 956 if (op->state != NUM_ANIMATIONS (op) - 1)
1005 return; 957 return;
1006 958
1007 env = object_get_env_recursive (op); 959 env = object_get_env_recursive (op);
1012 return; 964 return;
1013 965
1014 if (env->type == PLAYER) 966 if (env->type == PLAYER)
1015 esrv_del_item (env->contr, op->count); 967 esrv_del_item (env->contr, op->count);
1016 968
1017 remove_ob (op); 969 if (!(op = op->insert_at (env, op)))
1018 op->x = env->x;
1019 op->y = env->y;
1020 if ((op = insert_ob_in_map (op, env->map, op, 0)) == NULL)
1021 return; 970 return;
1022 } 971 }
1023 972
1024 // 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
1025 // 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
1026 // as bombs can be carried. 975 // as bombs can be carried.
1027 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 976 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
1028 { 977 {
1029 remove_ob (op); 978 op->destroy ();
1030 free_object (op);
1031 return; 979 return;
1032 } 980 }
1033 981
1034 /* This copies a lot of the code from the fire bullet, 982 /* This copies a lot of the code from the fire bullet,
1035 * but using the cast_bullet isn't really feasible, 983 * but using the cast_bullet isn't really feasible,
1036 * so just set up the appropriate values. 984 * so just set up the appropriate values.
1037 */ 985 */
1038 at = archetype::find (SPLINT); 986 if (archetype *at = archetype::find (SPLINT))
1039 if (at)
1040 { 987 {
1041 for (i = 1; i < 9; i++) 988 for (i = 1; i < 9; i++)
1042 { 989 {
1043 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]))
1044 continue; 991 continue;
992
1045 tmp = arch_to_object (at); 993 tmp = arch_to_object (at);
1046 tmp->direction = i; 994 tmp->direction = i;
1047 tmp->range = op->range; 995 tmp->range = op->range;
1048 tmp->stats.dam = op->stats.dam; 996 tmp->stats.dam = op->stats.dam;
1049 tmp->duration = op->duration; 997 tmp->duration = op->duration;
1050 tmp->attacktype = op->attacktype; 998 tmp->attacktype = op->attacktype;
1051 copy_owner (tmp, op); 999 tmp->set_owner (op);
1052 if (op->skill && op->skill != tmp->skill) 1000 if (op->skill && op->skill != tmp->skill)
1053 {
1054 tmp->skill = op->skill; 1001 tmp->skill = op->skill;
1055 } 1002
1056 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE)) 1003 if (QUERY_FLAG (tmp, FLAG_IS_TURNABLE))
1057 SET_ANIMATION (tmp, i); 1004 SET_ANIMATION (tmp, i);
1058 tmp->x = op->x + freearr_x[i]; 1005
1059 tmp->y = op->y + freearr_x[i]; 1006 op->map->insert (tmp, op->x + freearr_x[i], op->y + freearr_x[i], op);
1060 insert_ob_in_map (tmp, op->map, op, 0);
1061 move_bullet (tmp); 1007 move_bullet (tmp);
1062 } 1008 }
1063 } 1009 }
1064 1010
1065 explode_bullet (op); 1011 explode_bullet (op);
1086 tmp->range = spell->range + SP_level_range_adjust (caster, spell); 1032 tmp->range = spell->range + SP_level_range_adjust (caster, spell);
1087 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1033 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1088 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 1034 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
1089 tmp->attacktype = spell->attacktype; 1035 tmp->attacktype = spell->attacktype;
1090 1036
1091 set_owner (tmp, op); 1037 tmp->set_owner (op);
1092 set_spell_skill (op, caster, spell, tmp); 1038 set_spell_skill (op, caster, spell, tmp);
1093 tmp->x = dx; 1039
1094 tmp->y = dy; 1040 m->insert (tmp, dx, dy, op);
1095 insert_ob_in_map (tmp, m, op, 0);
1096 return 1; 1041 return 1;
1097} 1042}
1098 1043
1099/**************************************************************************** 1044/****************************************************************************
1100 * 1045 *
1139 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW) 1084 if (GET_MAP_MOVE_BLOCK (mp, x, y) & MOVE_FLY_LOW)
1140 return NULL; 1085 return NULL;
1141 1086
1142 if (mflags & P_IS_ALIVE) 1087 if (mflags & P_IS_ALIVE)
1143 { 1088 {
1144 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)
1145 { 1090 {
1146 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER)) 1091 if (QUERY_FLAG (target->head ? target->head : target, FLAG_MONSTER))
1147 { 1092 {
1148 return target; 1093 return target;
1149 } 1094 }
1216 if (effect->attacktype & AT_DEATH) 1161 if (effect->attacktype & AT_DEATH)
1217 { 1162 {
1218 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1163 effect->level = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1219 1164
1220 /* casting death spells at undead isn't a good thing */ 1165 /* casting death spells at undead isn't a good thing */
1221 if QUERY_FLAG
1222 (target, FLAG_UNDEAD) 1166 if (QUERY_FLAG (target, FLAG_UNDEAD))
1223 { 1167 {
1224 if (random_roll (0, 2, op, PREFER_LOW)) 1168 if (random_roll (0, 2, op, PREFER_LOW))
1225 { 1169 {
1226 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!"); 1170 new_draw_info (NDI_UNIQUE, 0, op, "Idiot! Your spell boomerangs!");
1227 effect->x = op->x; 1171 effect->x = op->x;
1229 } 1173 }
1230 else 1174 else
1231 { 1175 {
1232 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target)); 1176 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target));
1233 target->stats.hp = target->stats.maxhp * 2; 1177 target->stats.hp = target->stats.maxhp * 2;
1234 free_object (effect); 1178 effect->destroy ();
1235 return 0; 1179 return 0;
1236 } 1180 }
1237 } 1181 }
1238 } 1182 }
1239 else 1183 else
1240 { 1184 {
1241 /* how much woe to inflict :) */ 1185 /* how much woe to inflict :) */
1242 effect->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1186 effect->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1243 } 1187 }
1244 1188
1245 set_owner (effect, op); 1189 effect->set_owner (op);
1246 set_spell_skill (op, caster, spell, effect); 1190 set_spell_skill (op, caster, spell, effect);
1247 1191
1248 /* ok, tell it where to be, and insert! */ 1192 /* ok, tell it where to be, and insert! */
1249 effect->x = target->x; 1193 effect->insert_at (target, op);
1250 effect->y = target->y;
1251 insert_ob_in_map (effect, target->map, op, 0);
1252 1194
1253 return 1; 1195 return 1;
1254} 1196}
1255 1197
1256 1198
1270 sint16 new_x, new_y; 1212 sint16 new_x, new_y;
1271 maptile *m; 1213 maptile *m;
1272 1214
1273 if (op->range-- <= 0) 1215 if (op->range-- <= 0)
1274 { 1216 {
1275 remove_ob (op); 1217 op->destroy ();
1276 free_object (op);
1277 return; 1218 return;
1278 } 1219 }
1279 1220
1280 owner = get_owner (op); 1221 owner = op->owner;
1281#if 0 1222#if 0
1282 /* It'd make things nastier if this wasn't here - spells cast by 1223 /* It'd make things nastier if this wasn't here - spells cast by
1283 * monster that are then killed would continue to survive 1224 * monster that are then killed would continue to survive
1284 */ 1225 */
1285 if (owner == NULL) 1226 if (owner == NULL)
1286 { 1227 {
1287 remove_ob (op); 1228 op->destroy ();
1288 free_object (op);
1289 return; 1229 return;
1290 } 1230 }
1291#endif 1231#endif
1292 1232
1293 new_x = op->x + DIRX (op); 1233 new_x = op->x + DIRX (op);
1300 hit_map (op, op->direction, AT_MAGIC, 1); 1240 hit_map (op, op->direction, AT_MAGIC, 1);
1301 /* Basically, missile only hits one thing then goes away. 1241 /* Basically, missile only hits one thing then goes away.
1302 * we need to remove it if someone hasn't already done so. 1242 * we need to remove it if someone hasn't already done so.
1303 */ 1243 */
1304 if (!op->destroyed ()) 1244 if (!op->destroyed ())
1305 free_object (op); 1245 op->destroy ();
1306 1246
1307 return; 1247 return;
1308 } 1248 }
1309 1249
1310 remove_ob (op); 1250 op->remove ();
1311 1251
1312 if (!op->direction || (mflags & P_OUT_OF_MAP)) 1252 if (!op->direction || (mflags & P_OUT_OF_MAP))
1313 { 1253 {
1314 free_object (op); 1254 op->destroy ();
1315 return; 1255 return;
1316 } 1256 }
1317 1257
1318 op->x = new_x; 1258 i = spell_find_dir (m, new_x, new_y, op->owner);
1319 op->y = new_y;
1320 op->map = m;
1321 i = spell_find_dir (op->map, op->x, op->y, get_owner (op));
1322 if (i > 0 && i != op->direction) 1259 if (i > 0 && i != op->direction)
1323 { 1260 {
1324 op->direction = i; 1261 op->direction = i;
1325 SET_ANIMATION (op, op->direction); 1262 SET_ANIMATION (op, op->direction);
1326 } 1263 }
1327 1264
1328 insert_ob_in_map (op, op->map, op, 0); 1265 m->insert (op, new_x, new_y, op);
1329} 1266}
1330 1267
1331/**************************************************************************** 1268/****************************************************************************
1332 * Destruction 1269 * Destruction
1333 ****************************************************************************/ 1270 ****************************************************************************/
1411 for (j = -range; j < range; j++) 1348 for (j = -range; j < range; j++)
1412 { 1349 {
1413 m = op->map; 1350 m = op->map;
1414 sx = op->x + i; 1351 sx = op->x + i;
1415 sy = op->y + j; 1352 sy = op->y + j;
1353
1416 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1354 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1417 if (mflags & P_OUT_OF_MAP) 1355 if (mflags & P_OUT_OF_MAP)
1418 continue; 1356 continue;
1357
1419 if (mflags & P_IS_ALIVE) 1358 if (mflags & P_IS_ALIVE)
1420 { 1359 {
1421 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)
1422 {
1423 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER) 1361 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1424 break; 1362 break;
1425 } 1363
1426 if (tmp) 1364 if (tmp)
1427 { 1365 {
1428 if (tmp->head) 1366 if (tmp->head)
1429 tmp = tmp->head; 1367 tmp = tmp->head;
1430 1368
1433 { 1371 {
1434 if (spell_ob->subtype == SP_DESTRUCTION) 1372 if (spell_ob->subtype == SP_DESTRUCTION)
1435 { 1373 {
1436 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1374 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1437 if (spell_ob->other_arch) 1375 if (spell_ob->other_arch)
1438 {
1439 tmp = arch_to_object (spell_ob->other_arch); 1376 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1440 tmp->x = sx;
1441 tmp->y = sy;
1442 insert_ob_in_map (tmp, m, op, 0);
1443 }
1444 } 1377 }
1445 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)
1446 { 1379 {
1447 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch) 1380 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch)
1448 {
1449 object *effect = arch_to_object (spell_ob->other_arch); 1381 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1450
1451 effect->x = sx;
1452 effect->y = sy;
1453 insert_ob_in_map (effect, m, op, 0);
1454 }
1455 } 1382 }
1456 } 1383 }
1457 } 1384 }
1458 } 1385 }
1459 } 1386 }
1460 } 1387 }
1388
1461 op->skill = skill; 1389 op->skill = skill;
1462 return 1; 1390 return 1;
1463} 1391}
1464 1392
1465/*************************************************************************** 1393/***************************************************************************
1549 force->stats.ac = spell_ob->stats.ac; 1477 force->stats.ac = spell_ob->stats.ac;
1550 force->stats.wc = spell_ob->stats.wc; 1478 force->stats.wc = spell_ob->stats.wc;
1551 1479
1552 change_abil (tmp, force); /* Mostly to display any messages */ 1480 change_abil (tmp, force); /* Mostly to display any messages */
1553 insert_ob_in_ob (force, tmp); 1481 insert_ob_in_ob (force, tmp);
1554 fix_player (tmp); 1482 tmp->update_stats ();
1555 return 1; 1483 return 1;
1556 1484
1557} 1485}
1558 1486
1559 1487
1610 1538
1611 /* 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 */
1612 if (!(mflags & P_IS_ALIVE)) 1540 if (!(mflags & P_IS_ALIVE))
1613 continue; 1541 continue;
1614 1542
1615 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)
1616 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1544 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1617 break; 1545 break;
1618 1546
1619 /* There can be living objects that are not monsters */ 1547 /* There can be living objects that are not monsters */
1620 if (!tmp || tmp->type == PLAYER) 1548 if (!tmp || tmp->type == PLAYER)
1708 SET_FLAG (head, FLAG_FRIENDLY); 1636 SET_FLAG (head, FLAG_FRIENDLY);
1709 /* Prevent uncontolled outbreaks of self replicating monsters. 1637 /* Prevent uncontolled outbreaks of self replicating monsters.
1710 Typical use case is charm, go somwhere, use aggravation to make hostile. 1638 Typical use case is charm, go somwhere, use aggravation to make hostile.
1711 This could lead to fun stuff like mice outbreak in bigworld and server crawl. */ 1639 This could lead to fun stuff like mice outbreak in bigworld and server crawl. */
1712 CLEAR_FLAG (head, FLAG_GENERATOR); 1640 CLEAR_FLAG (head, FLAG_GENERATOR);
1713 set_owner (head, op); 1641 head->set_owner (op);
1714 set_spell_skill (op, caster, spell, head); 1642 set_spell_skill (op, caster, spell, head);
1715 add_friendly_object (head); 1643 add_friendly_object (head);
1716 head->attack_movement = PETMOVE; 1644 head->attack_movement = PETMOVE;
1717 done_one = 1; 1645 done_one = 1;
1718 change_exp (op, head->stats.exp / 2, head->skill, SK_EXP_ADD_SKILL); 1646 change_exp (op, head->stats.exp / 2, head->skill, SK_EXP_ADD_SKILL);
1719 head->stats.exp = 0; 1647 head->stats.exp = 0;
1720 } 1648 }
1721 1649
1722 /* If a monster was effected, put an effect in */ 1650 /* If a monster was effected, put an effect in */
1723 if (done_one && spell->other_arch) 1651 if (done_one && spell->other_arch)
1724 {
1725 tmp = arch_to_object (spell->other_arch); 1652 m->insert (arch_to_object (spell->other_arch), nx, ny, op);
1726 tmp->x = nx;
1727 tmp->y = ny;
1728 insert_ob_in_map (tmp, m, op, 0);
1729 }
1730 } /* for y */ 1653 } /* for y */
1731 1654
1732 return 1; 1655 return 1;
1733} 1656}
1734 1657
1746 int i, j, dam_save, dir, mflags; 1669 int i, j, dam_save, dir, mflags;
1747 sint16 nx, ny, hx, hy; 1670 sint16 nx, ny, hx, hy;
1748 object *owner; 1671 object *owner;
1749 maptile *m; 1672 maptile *m;
1750 1673
1751 owner = get_owner (op); 1674 owner = op->owner;
1752 1675
1753 /* the following logic makes sure that the ball doesn't move into a wall, 1676 /* the following logic makes sure that the ball doesn't move into a wall,
1754 * and makes sure that it will move along a wall to try and get at it's 1677 * and makes sure that it will move along a wall to try and get at it's
1755 * victim. The block immediately below more or less chooses a random 1678 * victim. The block immediately below more or less chooses a random
1756 * offset to move the ball, eg, keep it mostly on course, with some 1679 * offset to move the ball, eg, keep it mostly on course, with some
1785 nx = op->x; 1708 nx = op->x;
1786 ny = op->y; 1709 ny = op->y;
1787 m = op->map; 1710 m = op->map;
1788 } 1711 }
1789 1712
1790 remove_ob (op); 1713 m->insert (op, nx, ny, op);
1791 op->y = ny;
1792 op->x = nx;
1793 insert_ob_in_map (op, m, op, 0);
1794 1714
1795 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
1796 surrounding squares */ 1716 surrounding squares */
1797 1717
1798 /* loop over current square and neighbors to hit. 1718 /* loop over current square and neighbors to hit.
1824 1744
1825 } 1745 }
1826 1746
1827 /* insert the other arch */ 1747 /* insert the other arch */
1828 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))))
1829 { 1749 m->insert (arch_to_object (op->other_arch), hx, hy, op);
1830 new_ob = arch_to_object (op->other_arch);
1831 new_ob->x = hx;
1832 new_ob->y = hy;
1833 insert_ob_in_map (new_ob, m, op, 0);
1834 }
1835 } 1750 }
1836 1751
1837 /* restore to the center location and damage */ 1752 /* restore to the center location and damage */
1838 op->stats.dam = dam_save; 1753 op->stats.dam = dam_save;
1839 1754
1840 i = spell_find_dir (op->map, op->x, op->y, get_owner (op)); 1755 i = spell_find_dir (op->map, op->x, op->y, op->owner);
1841 1756
1842 if (i >= 0) 1757 if (i >= 0)
1843 { /* we have a preferred direction! */ 1758 { /* we have a preferred direction! */
1844 /* pick another direction if the preferred dir is blocked. */ 1759 /* pick another direction if the preferred dir is blocked. */
1845 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 ||
1846 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)))
1847 {
1848 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */ 1762 i = absdir (i + rndm (0, 2) - 1); /* -1, 0, +1 */
1849 } 1763
1850 op->direction = i; 1764 op->direction = i;
1851 } 1765 }
1852} 1766}
1853 1767
1854 1768
1871 maptile *m; 1785 maptile *m;
1872#endif 1786#endif
1873 int basedir; 1787 int basedir;
1874 object *owner; 1788 object *owner;
1875 1789
1876 owner = get_owner (op); 1790 owner = op->owner;
1877 if (op->duration == 0 || owner == NULL) 1791 if (op->duration == 0 || owner == NULL)
1878 { 1792 {
1879 remove_ob (op); 1793 op->destroy ();
1880 free_object (op);
1881 return; 1794 return;
1882 } 1795 }
1796
1883 op->duration--; 1797 op->duration--;
1884 1798
1885 basedir = op->direction; 1799 basedir = op->direction;
1886 if (basedir == 0) 1800 if (basedir == 0)
1887 { 1801 {
1984 1898
1985 if (!spell->other_arch) 1899 if (!spell->other_arch)
1986 return 0; 1900 return 0;
1987 1901
1988 tmp = get_archetype (SWARM_SPELL); 1902 tmp = get_archetype (SWARM_SPELL);
1989 tmp->x = op->x;
1990 tmp->y = op->y;
1991 set_owner (tmp, 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. */
1992 set_spell_skill (op, caster, spell, tmp); 1904 set_spell_skill (op, caster, spell, tmp);
1993 1905
1994 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. */
1995 tmp->spell = arch_to_object (spell->other_arch); 1907 tmp->spell = arch_to_object (spell->other_arch);
1996 1908
1997 tmp->attacktype = tmp->spell->attacktype; 1909 tmp->attacktype = tmp->spell->attacktype;
1998 1910
1999 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) 1911 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER)
2000 {
2001 if (!tailor_god_spell (tmp, op)) 1912 if (!tailor_god_spell (tmp, op))
2002 return 1; 1913 return 1;
2003 } 1914
2004 tmp->duration = SP_level_duration_adjust (caster, spell); 1915 tmp->duration = SP_level_duration_adjust (caster, spell);
2005 for (i = 0; i < spell->duration; i++) 1916 for (i = 0; i < spell->duration; i++)
2006 tmp->duration += die_roll (1, 3, op, PREFER_HIGH); 1917 tmp->duration += die_roll (1, 3, op, PREFER_HIGH);
2007 1918
2008 tmp->direction = dir; 1919 tmp->direction = dir;
2009 tmp->invisible = 1; 1920 tmp->invisible = 1;
2010 insert_ob_in_map (tmp, op->map, op, 0); 1921
1922 tmp->insert_at (op, op);
2011 return 1; 1923 return 1;
2012} 1924}
2013 1925
2014 1926
2015/* See the spells documentation file for why this is its own 1927/* See the spells documentation file for why this is its own
2043 return 0; 1955 return 0;
2044 } 1956 }
2045 1957
2046 if (mflags & P_IS_ALIVE && spell->attacktype) 1958 if (mflags & P_IS_ALIVE && spell->attacktype)
2047 { 1959 {
2048 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)
2049 if (QUERY_FLAG (target, FLAG_MONSTER)) 1961 if (QUERY_FLAG (target, FLAG_MONSTER))
2050 { 1962 {
2051 /* oky doky. got a target monster. Lets make a blinding attack */ 1963 /* oky doky. got a target monster. Lets make a blinding attack */
2052 if (target->head) 1964 if (target->head)
2053 target = target->head; 1965 target = target->head;
2075 { 1987 {
2076 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); 1988 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell);
2077 if (tmp->glow_radius > MAX_LIGHT_RADII) 1989 if (tmp->glow_radius > MAX_LIGHT_RADII)
2078 tmp->glow_radius = MAX_LIGHT_RADII; 1990 tmp->glow_radius = MAX_LIGHT_RADII;
2079 } 1991 }
2080 tmp->x = x; 1992
2081 tmp->y = y; 1993 m->insert (tmp, x, y, op);
2082 insert_ob_in_map (tmp, m, op, 0);
2083 return 1; 1994 return 1;
2084} 1995}
2085 1996
2086 1997
2087 1998
2135 2046
2136 /* 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 */
2137 if (mflags & P_IS_ALIVE) 2048 if (mflags & P_IS_ALIVE)
2138 { 2049 {
2139 /* search this square for a victim */ 2050 /* search this square for a victim */
2140 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)
2141 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER)) 2052 if (QUERY_FLAG (walk, FLAG_MONSTER) || (walk->type == PLAYER))
2142 { /* found a victim */ 2053 { /* found a victim */
2143 object *disease = arch_to_object (spell->other_arch); 2054 object *disease = arch_to_object (spell->other_arch);
2144 2055
2145 set_owner (disease, op); 2056 disease->set_owner (op);
2146 set_spell_skill (op, caster, spell, disease); 2057 set_spell_skill (op, caster, spell, disease);
2147 disease->stats.exp = 0; 2058 disease->stats.exp = 0;
2148 disease->level = caster_level (caster, spell); 2059 disease->level = caster_level (caster, spell);
2149 2060
2150 /* do level adjustments */ 2061 /* do level adjustments */
2199 { 2110 {
2200 object *flash; /* visual effect for inflicting disease */ 2111 object *flash; /* visual effect for inflicting disease */
2201 2112
2202 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);
2203 2114
2204 free_object (disease); /* don't need this one anymore */ 2115 disease->destroy (); /* don't need this one anymore */
2205 flash = get_archetype (ARCH_DETECT_MAGIC); 2116 walk->map->insert (get_archetype (ARCH_DETECT_MAGIC), x, y, op);
2206 flash->x = x;
2207 flash->y = y;
2208 flash->map = walk->map;
2209 insert_ob_in_map (flash, walk->map, op, 0);
2210 return 1; 2117 return 1;
2211 } 2118 }
2212 free_object (disease); 2119
2120 disease->destroy ();
2213 } 2121 }
2214 } /* if living creature */ 2122 } /* if living creature */
2215 } /* for range of spaces */ 2123 } /* for range of spaces */
2124
2216 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2125 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");
2217 return 1; 2126 return 1;
2218} 2127}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines