--- deliantra/server/server/spell_attack.C 2008/04/20 23:25:43 1.51 +++ deliantra/server/server/spell_attack.C 2008/05/17 14:11:13 1.57 @@ -1,7 +1,7 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2002-2003,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * @@ -38,7 +38,6 @@ * but moved here so it could be applied to bolts too * op is the spell object. */ - void check_spell_knockback (object *op) { @@ -108,10 +107,9 @@ * ***************************************************************************/ -/* Causes op to fork. op is the original bolt, tmp +/* Causes op to fork. op is the original bolt, tmp * is the first piece of the fork. */ - void forklightning (object *op, object *tmp) { @@ -622,11 +620,11 @@ if (!spob->other_arch) return 0; - tmp = arch_to_object (spob->other_arch); - if (tmp == NULL) + tmp = spob->other_arch->instance (); + if (!tmp) return 0; - /* peterm: level dependency for bolts */ + /* peterm: level dependency for bolts */ tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob); tmp->attacktype = spob->attacktype; if (spob->slaying) @@ -646,8 +644,8 @@ tmp->set_owner (op); set_spell_skill (op, caster, spob, tmp); - tmp->x = op->x + freearr_x[dir]; - tmp->y = op->y + freearr_y[dir]; + tmp->x = op->x + freearr_x[dir]; + tmp->y = op->y + freearr_y[dir]; tmp->map = op->map; maptile *newmap; @@ -950,9 +948,6 @@ if (env->map == NULL) return; - if (env->type == PLAYER) - esrv_del_item (env->contr, op->count); - if (!(op = op->insert_at (env, op))) return; } @@ -1603,7 +1598,9 @@ /* charm */ if (QUERY_FLAG (spell, FLAG_NO_ATTACK) && !QUERY_FLAG (head, FLAG_FRIENDLY)) { - /* Prevent uncontolled outbreaks of self replicating monsters. + INVOKE_OBJECT (KILL, head, ARG_OBJECT (caster)); + + /* Prevent uncontrolled outbreaks of self replicating monsters. Typical use case is charm, go somwhere, use aggravation to make hostile. This could lead to fun stuff like mice outbreak in bigworld and server crawl. */ CLEAR_FLAG (head, FLAG_GENERATOR); @@ -1732,15 +1729,13 @@ } } - -/* move_swarm_spell: peterm +/* move_swarm_spell: peterm * This is an implementation of the swarm spell. It was written for - * meteor swarm, but it could be used for any swarm. A swarm spell + * meteor swarm, but it could be used for any swarm. A swarm spell * is a special type of object that casts swarms of other types - * of spells. Which spell it casts is flexible. It fires the spells + * of spells. Which spell it casts is flexible. It fires the spells * from a set of squares surrounding the caster, in a given direction. */ - void move_swarm_spell (object *op) { @@ -1751,11 +1746,9 @@ int adjustdir; maptile *m; #endif - int basedir; - object *owner; + object *owner = op->env; - owner = op->owner; - if (op->duration == 0 || owner == NULL) + if (!op->duration || !owner->is_on_map ()) { op->destroy (); return; @@ -1763,12 +1756,10 @@ op->duration--; - basedir = op->direction; - if (basedir == 0) - { - /* spray in all directions! 8) */ - basedir = rndm (1, 8); - } + int basedir = op->direction; + if (!basedir) + /* spray in all directions! 8) */ + basedir = (op->facing += op->state) % 8 + 1; #if 0 // this is bogus: it causes wrong places to be checked below @@ -1838,13 +1829,10 @@ if (op->spell->subtype == SP_BULLET) fire_bullet (owner, op, basedir, op->spell); else if (op->spell->subtype == SP_MAGIC_MISSILE) - fire_arch_from_position (owner, op, op->x, op->y, basedir, op->spell); + fire_arch_from_position (owner, op, owner->x, owner->y, basedir, op->spell); } } - - - /* fire_swarm: * The following routine creates a swarm of objects. It actually * sets up a specific swarm object, which then fires off all @@ -1856,23 +1844,16 @@ * spell - the spell that is this spell. * n: the number to be fired. */ - int fire_swarm (object *op, object *caster, object *spell, int dir) { - object *tmp; - int i; - if (!spell->other_arch) return 0; - tmp = get_archetype (SWARM_SPELL); - tmp->set_owner (op); /* needed so that if swarm elements kill, caster gets xp. */ + 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->spell = arch_to_object (spell->other_arch); - + tmp->level = caster_level (caster, spell); /* needed later, to get level dep. right. */ + tmp->spell = spell->other_arch->instance (); tmp->attacktype = tmp->spell->attacktype; if (tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) @@ -1880,17 +1861,19 @@ return 1; tmp->duration = SP_level_duration_adjust (caster, spell); - for (i = 0; i < spell->duration; i++) + for (int i = 0; i < spell->duration; i++) tmp->duration += die_roll (1, 3, op, PREFER_HIGH); tmp->direction = dir; tmp->invisible = 1; + tmp->facing = rndm (1, 8); // initial firing direction + tmp->state = rndm (4) * 2 + 1; // direction increment + + op->insert (tmp); - tmp->insert_at (op, op); return 1; } - /* See the spells documentation file for why this is its own * function. */