--- deliantra/server/server/spell_util.c 2006/08/02 17:26:29 1.10 +++ deliantra/server/server/spell_util.c 2006/08/12 11:51:38 1.11 @@ -1021,7 +1021,7 @@ int cast_spell(object *op, object *caster,int dir,object *spell_ob, char *stringarg) { const char *godname; - int success=0,mflags, cast_level=0, old_shoottype; + int success=0,mflags, cast_level=0, old_shoottype, ev = 0; object *skill=NULL; old_shoottype = op->contr ? op->contr->shoottype : 0; @@ -1221,233 +1221,250 @@ change_skill(op, skill, 0); /* needed for proper exp credit */ } - switch(spell_ob->subtype) { - /* The order of case statements is same as the order they show up - * in in spells.h. - */ - case SP_RAISE_DEAD: - success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); - break; - - case SP_RUNE: - success = write_rune(op,caster, spell_ob, dir,stringarg); - break; - - case SP_MAKE_MARK: - success = write_mark(op, spell_ob, stringarg); - break; - - case SP_BOLT: - success = fire_bolt(op,caster,dir,spell_ob,skill); - break; - - case SP_BULLET: - success = fire_bullet(op, caster, dir, spell_ob); - break; - - case SP_CONE: - success = cast_cone(op, caster, dir, spell_ob); - break; - - case SP_BOMB: - success = create_bomb(op,caster,dir, spell_ob); - break; - - case SP_WONDER: - success = cast_wonder(op,caster, dir,spell_ob); - break; - - case SP_SMITE: - success = cast_smite_spell(op,caster, dir,spell_ob); - break; - - case SP_MAGIC_MISSILE: - success = fire_arch_from_position(op, caster, op->x + freearr_x[dir], - op->y + freearr_y[dir], dir, spell_ob); - break; - - case SP_SUMMON_GOLEM: - success = summon_golem(op, caster, dir, spell_ob); - old_shoottype = range_golem; - break; - - case SP_DIMENSION_DOOR: - /* dimension door needs the actual caster, because that is what is - * moved. - */ - success = dimension_door(op,caster, spell_ob, dir); - break; + /* elmex: FIXME: + * This is a little bit hacky, i needed a special field in spell objects + * to identify that it triggers EVENT_CAST_SPELL events. So that only special + * spells call out into the plugin (which might be very slow). + * I choose custom_name because it's set by the loader and a player can't modify it + * on the spell object. + * I would more like a simple flag... but that can be done later. + */ + LOG(llevError,"cast_spell: custom_name: %s\n", spell_ob->arch->clone.custom_name); + if (spell_ob->arch->clone.custom_name) + { + ev = execute_global_event(EVENT_CAST_SPELL, op, caster, spell_ob, dir, stringarg ? stringarg : ""); + LOG(llevError,"cast_spell: EVENT!!!!\n"); + } + + if (!ev) + switch(spell_ob->subtype) + { + /* The order of case statements is same as the order they show up + * in in spells.h. + */ + case SP_RAISE_DEAD: + success = cast_raise_dead_spell(op,caster, spell_ob, dir,stringarg); + break; - case SP_MAGIC_MAPPING: - if(op->type==PLAYER) { - spell_effect(spell_ob, op->x, op->y, op->map, op); - draw_magic_map(op); - success=1; - } - else success=0; - break; + case SP_RUNE: + success = write_rune(op,caster, spell_ob, dir,stringarg); + break; + + case SP_MAKE_MARK: + success = write_mark(op, spell_ob, stringarg); + break; + + case SP_BOLT: + success = fire_bolt(op,caster,dir,spell_ob,skill); + break; + + case SP_BULLET: + success = fire_bullet(op, caster, dir, spell_ob); + break; + + case SP_CONE: + success = cast_cone(op, caster, dir, spell_ob); + break; + + case SP_BOMB: + success = create_bomb(op,caster,dir, spell_ob); + break; + + case SP_WONDER: + success = cast_wonder(op,caster, dir,spell_ob); + break; + + case SP_SMITE: + success = cast_smite_spell(op,caster, dir,spell_ob); + break; + + case SP_MAGIC_MISSILE: + success = fire_arch_from_position(op, caster, op->x + freearr_x[dir], + op->y + freearr_y[dir], dir, spell_ob); + break; + + case SP_SUMMON_GOLEM: + success = summon_golem(op, caster, dir, spell_ob); + old_shoottype = range_golem; + break; - case SP_MAGIC_WALL: - success = magic_wall(op,caster,dir,spell_ob); - break; - - case SP_DESTRUCTION: - success = cast_destruction(op,caster,spell_ob); - break; - - case SP_PERCEIVE_SELF: - success = perceive_self(op); - break; - - case SP_WORD_OF_RECALL: - success = cast_word_of_recall(op,caster,spell_ob); - break; - - case SP_INVISIBLE: - success = cast_invisible(op,caster,spell_ob); - break; - - case SP_PROBE: - success = probe(op,caster, spell_ob, dir); - break; - - case SP_HEALING: - success = cast_heal(op,caster, spell_ob, dir); - break; - - case SP_CREATE_FOOD: - success = cast_create_food(op,caster,spell_ob, dir,stringarg); - break; - - case SP_EARTH_TO_DUST: - success = cast_earth_to_dust(op,caster,spell_ob); - break; - - case SP_CHANGE_ABILITY: - success = cast_change_ability(op,caster,spell_ob, dir, 0); - break; - - case SP_BLESS: - success = cast_bless(op,caster,spell_ob, dir); - break; - - case SP_CURSE: - success = cast_curse(op,caster,spell_ob, dir); - break; - - case SP_SUMMON_MONSTER: - success = summon_object(op,caster,spell_ob, dir,stringarg); - break; - - case SP_CHARGING: - success = recharge(op, caster, spell_ob); - break; + case SP_DIMENSION_DOOR: + /* dimension door needs the actual caster, because that is what is + * moved. + */ + success = dimension_door(op,caster, spell_ob, dir); + break; + + case SP_MAGIC_MAPPING: + if(op->type==PLAYER) { + spell_effect(spell_ob, op->x, op->y, op->map, op); + draw_magic_map(op); + success=1; + } + else success=0; + break; + + case SP_MAGIC_WALL: + success = magic_wall(op,caster,dir,spell_ob); + break; + + case SP_DESTRUCTION: + success = cast_destruction(op,caster,spell_ob); + break; + + case SP_PERCEIVE_SELF: + success = perceive_self(op); + break; + + case SP_WORD_OF_RECALL: + success = cast_word_of_recall(op,caster,spell_ob); + break; + + case SP_INVISIBLE: + success = cast_invisible(op,caster,spell_ob); + break; + + case SP_PROBE: + success = probe(op,caster, spell_ob, dir); + break; + + case SP_HEALING: + success = cast_heal(op,caster, spell_ob, dir); + break; + + case SP_CREATE_FOOD: + success = cast_create_food(op,caster,spell_ob, dir,stringarg); + break; + + case SP_EARTH_TO_DUST: + success = cast_earth_to_dust(op,caster,spell_ob); + break; + + case SP_CHANGE_ABILITY: + success = cast_change_ability(op,caster,spell_ob, dir, 0); + break; - case SP_POLYMORPH: + case SP_BLESS: + success = cast_bless(op,caster,spell_ob, dir); + break; + + case SP_CURSE: + success = cast_curse(op,caster,spell_ob, dir); + break; + + case SP_SUMMON_MONSTER: + success = summon_object(op,caster,spell_ob, dir,stringarg); + break; + + case SP_CHARGING: + success = recharge(op, caster, spell_ob); + break; + + case SP_POLYMORPH: #ifdef NO_POLYMORPH - /* Not great, but at least provide feedback so if players do have - * polymorph (ie, find it as a preset item or left over from before - * it was disabled), they get some feedback. - */ - new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); - success = 0; + /* Not great, but at least provide feedback so if players do have + * polymorph (ie, find it as a preset item or left over from before + * it was disabled), they get some feedback. + */ + new_draw_info(NDI_UNIQUE, 0,op,"The spell fizzles"); + success = 0; #else - success = cast_polymorph(op,caster,spell_ob, dir); + success = cast_polymorph(op,caster,spell_ob, dir); #endif - break; + break; + + case SP_ALCHEMY: + success = alchemy(op, caster, spell_ob); + break; + + case SP_REMOVE_CURSE: + success = remove_curse(op, caster, spell_ob); + break; + + case SP_IDENTIFY: + success = cast_identify(op, caster, spell_ob); + break; + + case SP_DETECTION: + success = cast_detection(op, caster, spell_ob, skill); + break; + + case SP_MOOD_CHANGE: + success = mood_change(op, caster, spell_ob); + break; + + case SP_MOVING_BALL: + if (spell_ob->path_repelled && + (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { + new_draw_info_format(NDI_UNIQUE, 0, op, + "You lack the proper attunement to cast %s", spell_ob->name); + success = 0; + } else + success = fire_arch_from_position(op,caster, + op->x + freearr_x[dir], op->y + freearr_y[dir], + dir, spell_ob); + break; + + case SP_SWARM: + success = fire_swarm(op, caster, spell_ob, dir); + break; + + case SP_CHANGE_MANA: + success = cast_transfer(op,caster, spell_ob, dir); + break; + + case SP_DISPEL_RUNE: + /* in rune.c */ + success = dispel_rune(op,caster, spell_ob, skill, dir); + break; + + case SP_CREATE_MISSILE: + success = cast_create_missile(op,caster,spell_ob, dir,stringarg); + break; + + case SP_CONSECRATE: + success = cast_consecrate(op, caster, spell_ob); + break; - case SP_ALCHEMY: - success = alchemy(op, caster, spell_ob); - break; - - case SP_REMOVE_CURSE: - success = remove_curse(op, caster, spell_ob); - break; - - case SP_IDENTIFY: - success = cast_identify(op, caster, spell_ob); - break; - - case SP_DETECTION: - success = cast_detection(op, caster, spell_ob, skill); - break; - - case SP_MOOD_CHANGE: - success = mood_change(op, caster, spell_ob); - break; - - case SP_MOVING_BALL: - if (spell_ob->path_repelled && - (spell_ob->path_repelled & caster->path_attuned) != spell_ob->path_repelled) { - new_draw_info_format(NDI_UNIQUE, 0, op, - "You lack the proper attunement to cast %s", spell_ob->name); - success = 0; - } else - success = fire_arch_from_position(op,caster, - op->x + freearr_x[dir], op->y + freearr_y[dir], - dir, spell_ob); - break; - - case SP_SWARM: - success = fire_swarm(op, caster, spell_ob, dir); - break; - - case SP_CHANGE_MANA: - success = cast_transfer(op,caster, spell_ob, dir); - break; - - case SP_DISPEL_RUNE: - /* in rune.c */ - success = dispel_rune(op,caster, spell_ob, skill, dir); - break; - - case SP_CREATE_MISSILE: - success = cast_create_missile(op,caster,spell_ob, dir,stringarg); - break; - - case SP_CONSECRATE: - success = cast_consecrate(op, caster, spell_ob); - break; - - case SP_ANIMATE_WEAPON: - success = animate_weapon(op, caster, spell_ob, dir); - old_shoottype = range_golem; - break; - - case SP_LIGHT: - success = cast_light(op, caster, spell_ob, dir); - break; - - case SP_CHANGE_MAP_LIGHT: - success = cast_change_map_lightlevel(op, caster, spell_ob); - break; - - case SP_FAERY_FIRE: - success = cast_destruction(op,caster,spell_ob); - break; - - case SP_CAUSE_DISEASE: - success = cast_cause_disease(op, caster, spell_ob, dir); - break; - - case SP_AURA: - success = create_aura(op, caster, spell_ob); - break; - - case SP_TOWN_PORTAL: - success= cast_create_town_portal (op,caster,spell_ob, dir); - break; + case SP_ANIMATE_WEAPON: + success = animate_weapon(op, caster, spell_ob, dir); + old_shoottype = range_golem; + break; + + case SP_LIGHT: + success = cast_light(op, caster, spell_ob, dir); + break; + + case SP_CHANGE_MAP_LIGHT: + success = cast_change_map_lightlevel(op, caster, spell_ob); + break; + + case SP_FAERY_FIRE: + success = cast_destruction(op,caster,spell_ob); + break; + + case SP_CAUSE_DISEASE: + success = cast_cause_disease(op, caster, spell_ob, dir); + break; + + case SP_AURA: + success = create_aura(op, caster, spell_ob); + break; + + case SP_TOWN_PORTAL: + success= cast_create_town_portal (op,caster,spell_ob, dir); + break; case SP_PARTY_SPELL: success = cast_party_spell (op, caster, dir, spell_ob, stringarg); break; - default: - LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", - spell_ob->subtype); + default: + LOG(llevError,"cast_spell: Unhandled spell subtype %d\n", + spell_ob->subtype); - } + } /* FIXME - we need some better sound suppport */ // yes, for example, augment map info with the spell effect