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.59 by root, Sat May 17 15:25:19 2008 UTC vs.
Revision 1.66 by root, Mon Sep 29 10:31:32 2008 UTC

148 new_bolt->duration++; 148 new_bolt->duration++;
149 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */ 149 new_bolt->stats.dam /= 2; /* reduce daughter bolt damage */
150 new_bolt->stats.dam++; 150 new_bolt->stats.dam++;
151 tmp->stats.dam /= 2; /* reduce father bolt damage */ 151 tmp->stats.dam /= 2; /* reduce father bolt damage */
152 tmp->stats.dam++; 152 tmp->stats.dam++;
153
153 if ((new_bolt = m->insert (new_bolt, sx, sy, op))) 154 if ((new_bolt = m->insert (new_bolt, sx, sy, op)))
154 update_turn_face (new_bolt); 155 update_turn_face (new_bolt);
155} 156}
156 157
157/* move_bolt: moves bolt 'op'. Basically, it just advances a space, 158/* move_bolt: moves bolt 'op'. Basically, it just advances a space,
164 sint16 x, y; 165 sint16 x, y;
165 maptile *m; 166 maptile *m;
166 167
167 if (--op->duration < 0) 168 if (--op->duration < 0)
168 { 169 {
169 op->destroy (); 170 op->drop_and_destroy ();
170 return; 171 return;
171 } 172 }
172 173
173 hit_map (op, 0, op->attacktype, 1); 174 hit_map (op, 0, op->attacktype, 1);
174 175
306 307
307 maptile *newmap; 308 maptile *newmap;
308 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y); 309 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
309 if (mflags & P_OUT_OF_MAP) 310 if (mflags & P_OUT_OF_MAP)
310 { 311 {
311 tmp->destroy (); 312 tmp->drop_and_destroy ();
312 return 0; 313 return 0;
313 } 314 }
314 315
315 tmp->map = newmap; 316 tmp->map = newmap;
316 317
317 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 318 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
318 { 319 {
319 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 320 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
320 { 321 {
321 tmp->destroy (); 322 tmp->drop_and_destroy ();
322 return 0; 323 return 0;
323 } 324 }
324 325
325 tmp->x = op->x; 326 tmp->x = op->x;
326 tmp->y = op->y; 327 tmp->y = op->y;
350 maptile *m = op->map; 351 maptile *m = op->map;
351 int i; 352 int i;
352 353
353 if (--op->duration < 0) 354 if (--op->duration < 0)
354 { 355 {
355 op->destroy (); 356 op->destroy (true);
356 return; 357 return;
357 } 358 }
358 359
359 hit_map (op, 0, op->attacktype, 0); 360 hit_map (op, 0, op->attacktype, 0);
360 361
392void 393void
393explode_bullet (object *op) 394explode_bullet (object *op)
394{ 395{
395 object *tmp, *owner; 396 object *tmp, *owner;
396 397
397 if (op->other_arch == NULL) 398 if (!op->other_arch)
398 { 399 {
399 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 400 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
400 op->destroy (); 401 op->destroy (true);
401 return; 402 return;
402 } 403 }
403 404
404 if (op->env) 405 if (op->env)
405 { 406 {
406 object *env = op->outer_env (); 407 object *env = op->outer_env ();
407 408
408 if (!env->map || out_of_map (env->map, env->x, env->y)) 409 if (!env->map || out_of_map (env->map, env->x, env->y))
409 { 410 {
410 LOG (llevError, "BUG: explode_bullet(): env out of map\n"); 411 LOG (llevError, "BUG: explode_bullet(): env out of map\n");
411 op->destroy (); 412 op->destroy (true);
412 return; 413 return;
413 } 414 }
414 415
415 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON); 416 op->insert_at (env, op, INS_NO_MERGE | INS_NO_WALK_ON);
416 } 417 }
417 else if (out_of_map (op->map, op->x, op->y)) 418 else if (out_of_map (op->map, op->x, op->y))
418 { 419 {
419 LOG (llevError, "BUG: explode_bullet(): op out of map\n"); 420 LOG (llevError, "BUG: explode_bullet(): op out of map\n");
420 op->destroy (); 421 op->destroy (true);
421 return; 422 return;
422 } 423 }
423 424
424 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps 425 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent explosions of any kind on safe maps
425 // NOTE: If this breaks something important: remove this. I can't think of anything 426 // NOTE: If this breaks something important: remove this. I can't think of anything
426 // bad at the moment that might happen from this. 427 // bad at the moment that might happen from this.
427 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 428 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
428 { 429 {
429 op->destroy (); 430 op->destroy (true);
430 return; 431 return;
431 } 432 }
432 433
433 if (op->attacktype) 434 if (op->attacktype)
434 { 435 {
444 tmp->set_owner (op); 445 tmp->set_owner (op);
445 tmp->skill = op->skill; 446 tmp->skill = op->skill;
446 447
447 owner = op->owner; 448 owner = op->owner;
448 449
449 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) 450 if ((tmp->attacktype & AT_HOLYWORD
451 || tmp->attacktype & AT_GODPOWER)
452 && owner
453 && !tailor_god_spell (tmp, owner))
450 { 454 {
451 op->destroy (); 455 op->destroy (true);
452 return; 456 return;
453 } 457 }
454 458
455 /* special for bombs - it actually has sane values for these */ 459 /* special for bombs - it actually has sane values for these */
456 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 460 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
484 488
485 tmp->insert_at (op, op); 489 tmp->insert_at (op, op);
486 tmp->play_sound (tmp->sound); 490 tmp->play_sound (tmp->sound);
487 491
488 /* remove the firebullet */ 492 /* remove the firebullet */
489 op->destroy (); 493 op->destroy (true);
490} 494}
491 495
492/* 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
493 * (eg, explode, damage player, etc) 497 * (eg, explode, damage player, etc)
494 */ 498 */
520 { 524 {
521 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 525 if (QUERY_FLAG (tmp, FLAG_ALIVE))
522 { 526 {
523 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 527 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
524 528
529 // TODO: can't understand the following if's
525 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 530 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
526 { 531 {
527 if (!QUERY_FLAG (op, FLAG_REMOVED)) 532 if (!QUERY_FLAG (op, FLAG_REMOVED))
528 { 533 {
529 op->destroy (); 534 op->destroy (true);
530 return; 535 return;
531 } 536 }
532 } 537 }
533 } 538 }
534 } 539 }
563 if (--op->range <= 0) 568 if (--op->range <= 0)
564 { 569 {
565 if (op->other_arch) 570 if (op->other_arch)
566 explode_bullet (op); 571 explode_bullet (op);
567 else 572 else
568 op->destroy (); 573 op->destroy (true);
569 574
570 return; 575 return;
571 } 576 }
572 577
573 new_x = op->x + DIRX (op); 578 new_x = op->x + DIRX (op);
575 m = op->map; 580 m = op->map;
576 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y); 581 mflags = get_map_flags (m, &m, new_x, new_y, &new_x, &new_y);
577 582
578 if (mflags & P_OUT_OF_MAP) 583 if (mflags & P_OUT_OF_MAP)
579 { 584 {
580 op->destroy (); 585 op->destroy (true);
581 return; 586 return;
582 } 587 }
583 588
584 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) 589 if (!op->direction || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))
585 { 590 {
586 if (op->other_arch) 591 if (op->other_arch)
587 explode_bullet (op); 592 explode_bullet (op);
588 else 593 else
589 op->destroy (); 594 op->destroy (true);
590 595
591 return; 596 return;
592 } 597 }
593 598
594 if (!(op = m->insert (op, new_x, new_y, op))) 599 if (!(op = m->insert (op, new_x, new_y, op)))
650 655
651 maptile *newmap; 656 maptile *newmap;
652 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y); 657 mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y);
653 if (mflags & P_OUT_OF_MAP) 658 if (mflags & P_OUT_OF_MAP)
654 { 659 {
655 tmp->destroy (); 660 tmp->destroy (true);
656 return 0; 661 return 0;
657 } 662 }
658 663
659 tmp->map = newmap; 664 tmp->map = newmap;
660 665
661 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y))) 666 if (OB_TYPE_MOVE_BLOCK (tmp, GET_MAP_MOVE_BLOCK (tmp->map, tmp->x, tmp->y)))
662 { 667 {
663 if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) 668 if (!QUERY_FLAG (tmp, FLAG_REFLECTING))
664 { 669 {
665 tmp->destroy (); 670 tmp->destroy (true);
666 return 0; 671 return 0;
667 } 672 }
668 673
669 tmp->x = op->x; 674 tmp->x = op->x;
670 tmp->y = op->y; 675 tmp->y = op->y;
725 * when their cone dies when they die. 730 * when their cone dies when they die.
726 */ 731 */
727 /* If no owner left, the spell dies out. */ 732 /* If no owner left, the spell dies out. */
728 if (op->owner == NULL) 733 if (op->owner == NULL)
729 { 734 {
730 op->destroy (); 735 op->destroy (true);
731 return; 736 return;
732 } 737 }
733#endif 738#endif
734 739
735 hit_map (op, 0, op->attacktype, 0); 740 hit_map (op, 0, op->attacktype, 0);
742 check_spell_knockback (op); 747 check_spell_knockback (op);
743 748
744 if (op->destroyed ()) 749 if (op->destroyed ())
745 return; 750 return;
746 751
747 if ((op->duration--) < 0) 752 if (op->duration-- < 0)
748 { 753 {
749 op->destroy (); 754 op->destroy (true);
750 return; 755 return;
751 } 756 }
752 /* Object has hit maximum range, so don't have it move 757 /* Object has hit maximum range, so don't have it move
753 * any further. When the duration above expires, 758 * any further. When the duration above expires,
754 * then the object will get removed. 759 * then the object will get removed.
859 864
860 success = 1; 865 success = 1;
861 tmp = arch_to_object (spell->other_arch); 866 tmp = arch_to_object (spell->other_arch);
862 tmp->set_owner (op); 867 tmp->set_owner (op);
863 set_spell_skill (op, caster, spell, tmp); 868 set_spell_skill (op, caster, spell, tmp);
864 tmp->level = caster_level (caster, spell); 869 tmp->level = casting_level (caster, spell);
865 tmp->attacktype = spell->attacktype; 870 tmp->attacktype = spell->attacktype;
866 871
867 /* holy word stuff */ 872 /* holy word stuff */
868 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) 873 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER))
869 if (!tailor_god_spell (tmp, op)) 874 if (!tailor_god_spell (tmp, op))
953 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding 958 // elmex Tue Aug 15 17:46:51 CEST 2006: Prevent bomb from exploding
954 // on a safe map. I don't like this special casing, but it seems to be neccessary 959 // on a safe map. I don't like this special casing, but it seems to be neccessary
955 // as bombs can be carried. 960 // as bombs can be carried.
956 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 961 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
957 { 962 {
958 op->destroy (); 963 op->destroy (true);
959 return; 964 return;
960 } 965 }
961 966
962 /* This copies a lot of the code from the fire bullet, 967 /* This copies a lot of the code from the fire bullet,
963 * but using the cast_bullet isn't really feasible, 968 * but using the cast_bullet isn't really feasible,
1111 effect = arch_to_object (spell->other_arch); 1116 effect = arch_to_object (spell->other_arch);
1112 else 1117 else
1113 return 0; 1118 return 0;
1114 1119
1115 /* tailor the effect by priest level and worshipped God */ 1120 /* tailor the effect by priest level and worshipped God */
1116 effect->level = caster_level (caster, spell); 1121 effect->level = casting_level (caster, spell);
1117 effect->attacktype = spell->attacktype; 1122 effect->attacktype = spell->attacktype;
1118 if (effect->attacktype & (AT_HOLYWORD | AT_GODPOWER)) 1123 if (effect->attacktype & (AT_HOLYWORD | AT_GODPOWER))
1119 { 1124 {
1120 if (tailor_god_spell (effect, op)) 1125 if (tailor_god_spell (effect, op))
1121 new_draw_info_format (NDI_UNIQUE, 0, op, "%s answers your call!", determine_god (op)); 1126 new_draw_info_format (NDI_UNIQUE, 0, op, "%s answers your call!", determine_god (op));
1145 } 1150 }
1146 else 1151 else
1147 { 1152 {
1148 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target)); 1153 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s looks stronger!", query_name (target));
1149 target->stats.hp = target->stats.maxhp * 2; 1154 target->stats.hp = target->stats.maxhp * 2;
1150 effect->destroy (); 1155 effect->destroy (true);
1151 return 0; 1156 return 0;
1152 } 1157 }
1153 } 1158 }
1154 } 1159 }
1155 else 1160 else
1178void 1183void
1179move_missile (object *op) 1184move_missile (object *op)
1180{ 1185{
1181 if (op->range-- <= 0) 1186 if (op->range-- <= 0)
1182 { 1187 {
1183 op->destroy (); 1188 op->drop_and_destroy ();
1184 return; 1189 return;
1185 } 1190 }
1186 1191
1187 mapxy pos (op); 1192 mapxy pos (op);
1188 pos.move (op->direction); 1193 pos.move (op->direction);
1189 1194
1190 if (!pos.normalise ()) 1195 if (!pos.normalise ())
1191 { 1196 {
1192 op->destroy (); 1197 op->destroy (true);
1193 return; 1198 return;
1194 } 1199 }
1195 1200
1196 mapspace &ms = pos.ms (); 1201 mapspace &ms = pos.ms ();
1197 1202
1199 { 1204 {
1200 hit_map (op, op->direction, AT_MAGIC, 1); 1205 hit_map (op, op->direction, AT_MAGIC, 1);
1201 /* Basically, missile only hits one thing then goes away. 1206 /* Basically, missile only hits one thing then goes away.
1202 * we need to remove it if someone hasn't already done so. 1207 * we need to remove it if someone hasn't already done so.
1203 */ 1208 */
1204 op->destroy (); 1209 op->destroy (true);
1205 return; 1210 return;
1206 } 1211 }
1207 1212
1208 if (!op->direction) 1213 if (!op->direction)
1209 { 1214 {
1210 op->destroy (); 1215 op->destroy (true);
1211 return; 1216 return;
1212 } 1217 }
1213 1218
1214 int i = spell_find_dir (pos.m, pos.x, pos.y, op->owner); 1219 int i = spell_find_dir (pos.m, pos.x, pos.y, op->owner);
1215 if (i > 0 && i != op->direction) 1220 if (i > 0 && i != op->direction)
1450 1455
1451 /* We precompute some values here so that we don't have to keep 1456 /* We precompute some values here so that we don't have to keep
1452 * doing it over and over again. 1457 * doing it over and over again.
1453 */ 1458 */
1454 god = find_god (determine_god (op)); 1459 god = find_god (determine_god (op));
1455 level = caster_level (caster, spell); 1460 level = casting_level (caster, spell);
1456 range = spell->range + SP_level_range_adjust (caster, spell); 1461 range = spell->range + SP_level_range_adjust (caster, spell);
1457 1462
1458 /* On the bright side, no monster should ever have a race of GOD_... 1463 /* On the bright side, no monster should ever have a race of GOD_...
1459 * so even if the player doesn't worship a god, if race=GOD_.., it 1464 * so even if the player doesn't worship a god, if race=GOD_.., it
1460 * won't ever match anything. 1465 * won't ever match anything.
1610 * about. was called move_ball_lightning, but since more than the ball 1615 * about. was called move_ball_lightning, but since more than the ball
1611 * lightning spell used it, that seemed misnamed. 1616 * lightning spell used it, that seemed misnamed.
1612 * op is the spell effect. 1617 * op is the spell effect.
1613 * note that duration is handled by process_object() in time.c 1618 * note that duration is handled by process_object() in time.c
1614 */ 1619 */
1615
1616void 1620void
1617move_ball_spell (object *op) 1621move_ball_spell (object *op)
1618{ 1622{
1619 int i, j, dam_save, dir, mflags; 1623 int i, j, dam_save, dir, mflags;
1620 sint16 nx, ny, hx, hy; 1624 sint16 nx, ny, hx, hy;
1733 object *owner = op->env; 1737 object *owner = op->env;
1734 1738
1735 if (!owner) // MUST not happen, remove when true TODO 1739 if (!owner) // MUST not happen, remove when true TODO
1736 { 1740 {
1737 LOG (llevError, "swarm spell found outside inventory: %s\n", op->debug_desc ()); 1741 LOG (llevError, "swarm spell found outside inventory: %s\n", op->debug_desc ());
1738 op->destroy (); 1742 op->destroy (true);
1739 return; 1743 return;
1740 } 1744 }
1741 1745
1742 if (!op->duration || !owner->is_on_map ()) 1746 if (!op->duration || !owner->is_on_map ())
1743 { 1747 {
1744 op->destroy (); 1748 op->drop_and_destroy ();
1745 return; 1749 return;
1746 } 1750 }
1747 1751
1748 op->duration--; 1752 op->duration--;
1749 1753
1750 int basedir = op->direction; 1754 int basedir = op->direction;
1751 if (!basedir) 1755 if (!basedir)
1756 {
1752 /* spray in all directions! 8) */ 1757 /* spray in all directions! 8) */
1753 basedir = (op->facing += op->state) % 8 + 1; 1758 op->facing = (op->facing + op->state) & 7;
1759 basedir = op->facing + 1;
1760 }
1754 1761
1755#if 0 1762#if 0
1756 // this is bogus: it causes wrong places to be checked below 1763 // this is bogus: it causes wrong places to be checked below
1757 // (a wall 2 cells away will block the effect...) and 1764 // (a wall 2 cells away will block the effect...) and
1758 // doesn't work for SP_BULLET anyhow, so again tests the wrong 1765 // doesn't work for SP_BULLET anyhow, so again tests the wrong
1840{ 1847{
1841 if (!spell->other_arch) 1848 if (!spell->other_arch)
1842 return 0; 1849 return 0;
1843 1850
1844 object *tmp = archetype::get (SWARM_SPELL); 1851 object *tmp = archetype::get (SWARM_SPELL);
1852
1845 set_spell_skill (op, caster, spell, tmp); 1853 set_spell_skill (op, caster, spell, tmp);
1846 tmp->level = caster_level (caster, spell); /* needed later, to get level dep. right. */ 1854 tmp->level = casting_level (caster, spell); /* needed later, to get level dep. right. */
1847 tmp->spell = spell->other_arch->instance (); 1855 tmp->spell = spell->other_arch->instance ();
1848 tmp->attacktype = tmp->spell->attacktype; 1856 tmp->attacktype = tmp->spell->attacktype;
1849 1857
1850 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) 1858 if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER)
1851 if (!tailor_god_spell (tmp, op)) 1859 if (!tailor_god_spell (tmp, op))
1994 object *disease = arch_to_object (spell->other_arch); 2002 object *disease = arch_to_object (spell->other_arch);
1995 2003
1996 disease->set_owner (op); 2004 disease->set_owner (op);
1997 set_spell_skill (op, caster, spell, disease); 2005 set_spell_skill (op, caster, spell, disease);
1998 disease->stats.exp = 0; 2006 disease->stats.exp = 0;
1999 disease->level = caster_level (caster, spell); 2007 disease->level = casting_level (caster, spell);
2000 2008
2001 /* do level adjustments */ 2009 /* do level adjustments */
2002 if (disease->stats.wc) 2010 if (disease->stats.wc)
2003 disease->stats.wc += dur_mod / 2; 2011 disease->stats.wc += dur_mod / 2;
2004 2012
2048 2056
2049 if (infect_object (walk, disease, 1)) 2057 if (infect_object (walk, disease, 1))
2050 { 2058 {
2051 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name); 2059 new_draw_info_format (NDI_UNIQUE, 0, op, "You inflict %s on %s!", &disease->name, &walk->name);
2052 2060
2053 disease->destroy (); /* don't need this one anymore */ 2061 disease->destroy (true); /* don't need this one anymore */
2054 walk->map->insert (get_archetype ("detect_magic"), x, y, op); 2062 walk->map->insert (get_archetype ("detect_magic"), x, y, op);
2055 return 1; 2063 return 1;
2056 } 2064 }
2057 2065
2058 disease->destroy (); 2066 disease->destroy (true);
2059 } 2067 }
2060 } /* if living creature */ 2068 } /* if living creature */
2061 } /* for range of spaces */ 2069 } /* for range of spaces */
2062 2070
2063 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!"); 2071 new_draw_info (NDI_UNIQUE, 0, op, "No one caught anything!");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines