--- deliantra/server/server/spell_attack.C 2008/07/14 00:04:57 1.62 +++ deliantra/server/server/spell_attack.C 2008/12/22 21:51:11 1.71 @@ -167,7 +167,7 @@ if (--op->duration < 0) { - op->destroy (); + op->drop_and_destroy (); return; } @@ -309,7 +309,7 @@ mflags = get_map_flags (tmp->map, &newmap, tmp->x, tmp->y, &tmp->x, &tmp->y); if (mflags & P_OUT_OF_MAP) { - tmp->destroy (); + tmp->drop_and_destroy (); return 0; } @@ -319,7 +319,7 @@ { if (!QUERY_FLAG (tmp, FLAG_REFLECTING)) { - tmp->destroy (); + tmp->drop_and_destroy (); return 0; } @@ -395,7 +395,7 @@ { object *tmp, *owner; - if (op->other_arch == NULL) + if (!op->other_arch) { LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); op->destroy (); @@ -447,7 +447,10 @@ owner = op->owner; - if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) + if ((tmp->attacktype & AT_HOLYWORD + || tmp->attacktype & AT_GODPOWER) + && owner + && !tailor_god_spell (tmp, owner)) { op->destroy (); return; @@ -523,6 +526,7 @@ { dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); + // TODO: can't understand the following if's if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) { if (!QUERY_FLAG (op, FLAG_REMOVED)) @@ -735,15 +739,20 @@ hit_map (op, 0, op->attacktype, 0); + if (!op->is_on_map ()) + return; + /* Check to see if we should push anything. * Spell objects with weight push whatever they encounter to some * degree. */ if (op->weight) - check_spell_knockback (op); + { + check_spell_knockback (op); - if (op->destroyed ()) - return; + if (!op->is_on_map ()) + return; + } if (op->duration-- < 0) { @@ -862,7 +871,7 @@ tmp = arch_to_object (spell->other_arch); tmp->set_owner (op); set_spell_skill (op, caster, spell, tmp); - tmp->level = caster_level (caster, spell); + tmp->level = casting_level (caster, spell); tmp->attacktype = spell->attacktype; /* holy word stuff */ @@ -1001,10 +1010,18 @@ maptile *m; mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy); - if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) + + // when creating a bomb below ourself it should always work, even + // when movement is blocked (somehow we got here, somehow we are here, + // so we should also be able to make a bomb here). (originally added + // to fix create bomb traps in doors, which cast with dir=0). + if (dir) { - new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); - return 0; + if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) + { + new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); + return 0; + } } tmp = arch_to_object (spell->other_arch); @@ -1114,7 +1131,7 @@ return 0; /* tailor the effect by priest level and worshipped God */ - effect->level = caster_level (caster, spell); + effect->level = casting_level (caster, spell); effect->attacktype = spell->attacktype; if (effect->attacktype & (AT_HOLYWORD | AT_GODPOWER)) { @@ -1181,7 +1198,7 @@ { if (op->range-- <= 0) { - op->destroy (); + op->drop_and_destroy (); return; } @@ -1243,10 +1260,7 @@ tmp->speed = 0.01; tmp->stats.food = time; SET_FLAG (tmp, FLAG_IS_USED_UP); - tmp->glow_radius = radius; - if (tmp->glow_radius > MAX_LIGHT_RADII) - tmp->glow_radius = MAX_LIGHT_RADII; - + tmp->glow_radius = min (MAX_LIGHT_RADIUS, radius); tmp = insert_ob_in_ob (tmp, op); if (tmp->glow_radius > op->glow_radius) @@ -1453,7 +1467,7 @@ * doing it over and over again. */ god = find_god (determine_god (op)); - level = caster_level (caster, spell); + level = casting_level (caster, spell); range = spell->range + SP_level_range_adjust (caster, spell); /* On the bright side, no monster should ever have a race of GOD_... @@ -1606,7 +1620,6 @@ return 1; } - /* Move_ball_spell: This handles ball type spells that just sort of wander * about. was called move_ball_lightning, but since more than the ball * lightning spell used it, that seemed misnamed. @@ -1641,7 +1654,6 @@ /* i bit 0: alters sign of offset * other bits (i / 2): absolute value of offset */ - int offset = ((i ^ j) & 1) ? (i / 2) : -(i / 2); int tmpdir = absdir (op->direction + offset); @@ -1653,6 +1665,7 @@ break; } } + if (dir == 0) { nx = op->x; @@ -1741,7 +1754,7 @@ if (!op->duration || !owner->is_on_map ()) { - op->destroy (); + op->drop_and_destroy (); return; } @@ -1847,7 +1860,7 @@ object *tmp = archetype::get (SWARM_SPELL); set_spell_skill (op, caster, spell, tmp); - tmp->level = caster_level (caster, spell); /* needed later, to get level dep. right. */ + tmp->level = casting_level (caster, spell); /* needed later, to get level dep. right. */ tmp->spell = spell->other_arch->instance (); tmp->attacktype = tmp->spell->attacktype; @@ -1883,43 +1896,40 @@ dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); - if (!dir) + if (dir) { - new_draw_info (NDI_UNIQUE, 0, op, "In what direction?"); - return 0; - } - - x = op->x + freearr_x[dir]; - y = op->y + freearr_y[dir]; - m = op->map; + x = op->x + freearr_x[dir]; + y = op->y + freearr_y[dir]; + m = op->map; - mflags = get_map_flags (m, &m, x, y, &x, &y); + mflags = get_map_flags (m, &m, x, y, &x, &y); - if (mflags & P_OUT_OF_MAP) - { - new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there."); - return 0; - } + if (mflags & P_OUT_OF_MAP) + { + new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there."); + return 0; + } - if (mflags & P_IS_ALIVE && spell->attacktype) - { - for (target = GET_MAP_OB (m, x, y); target; target = target->above) - if (QUERY_FLAG (target, FLAG_MONSTER)) - { - /* oky doky. got a target monster. Lets make a blinding attack */ - if (target->head) - target = target->head; + if (mflags & P_IS_ALIVE && spell->attacktype) + { + for (target = GET_MAP_OB (m, x, y); target; target = target->above) + if (QUERY_FLAG (target, FLAG_MONSTER)) + { + /* oky doky. got a target monster. Lets make a blinding attack */ + if (target->head) + target = target->head; - hit_player (target, dam, op, spell->attacktype, 1); - return 1; /* one success only! */ - } - } + hit_player (target, dam, op, spell->attacktype, 1); + return 1; /* one success only! */ + } + } - /* no live target, perhaps a wall is in the way? */ - if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) - { - new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); - return 0; + /* no live target, perhaps a wall is in the way? */ + if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) + { + new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); + return 0; + } } /* ok, looks groovy to just insert a new light on the map */ @@ -1929,15 +1939,17 @@ LOG (llevError, "Error: spell arch for cast_light() missing.\n"); return 0; } + tmp->stats.food = spell->duration + SP_level_duration_adjust (caster, spell); + if (tmp->glow_radius) - { - tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); - if (tmp->glow_radius > MAX_LIGHT_RADII) - tmp->glow_radius = MAX_LIGHT_RADII; - } + tmp->glow_radius = min (MAX_LIGHT_RADIUS, spell->range + SP_level_range_adjust (caster, spell)); + + if (dir) + m->insert (tmp, x, y, op); + else + caster->outer_env ()->insert (tmp); - m->insert (tmp, x, y, op); return 1; } @@ -2000,7 +2012,7 @@ disease->set_owner (op); set_spell_skill (op, caster, spell, disease); disease->stats.exp = 0; - disease->level = caster_level (caster, spell); + disease->level = casting_level (caster, spell); /* do level adjustments */ if (disease->stats.wc)