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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines