/* This function is the very heart of the entire magic system. All invocations * of all types of magic -- objects, spoken and unspoken PC and NPC spells, the * works -- all come through this function eventually. This is also the entry * point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently * ignored here, to make callers simpler. */ int call_magic(struct char_data *caster, struct char_data *cvict, struct obj_data *ovict, int spellnum, int level, int casttype) { int savetype; if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE) return (0); if (!cast_wtrigger(caster, cvict, ovict, spellnum)) return 0; if (!cast_otrigger(caster, ovict, spellnum)) return 0; if (!cast_mtrigger(caster, cvict, spellnum)) return 0; if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_NOMAGIC)) { send_to_char(caster, "Your magic fizzles out and dies.\r\n"); act("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM); return (0); } if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && (SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) { send_to_char(caster, "A flash of white light fills the room, dispelling your violent magic!\r\n"); act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM); return (0); } if (cvict && MOB_FLAGGED(cvict, MOB_NOKILL)) { send_to_char(caster, "This mob is protected.\r\n"); return (0); } /* determine the type of saving throw */ switch (casttype) { case CAST_STAFF: case CAST_SCROLL: case CAST_POTION: case CAST_WAND: savetype = SAVING_ROD; break; case CAST_SPELL: savetype = SAVING_SPELL; break; default: savetype = SAVING_BREATH; break; } if (IS_SET(SINFO.routines, MAG_DAMAGE)) if (mag_damage(level, caster, cvict, spellnum, savetype) == -1) return (-1); /* Successful and target died, don't cast again. */ if (IS_SET(SINFO.routines, MAG_AFFECTS)) mag_affects(level, caster, cvict, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_UNAFFECTS)) mag_unaffects(level, caster, cvict, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_POINTS)) mag_points(level, caster, cvict, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_ALTER_OBJS)) mag_alter_objs(level, caster, ovict, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_GROUPS)) mag_groups(level, caster, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_MASSES)) mag_masses(level, caster, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_AREAS)) mag_areas(level, caster, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_SUMMONS)) mag_summons(level, caster, ovict, spellnum, savetype); if (IS_SET(SINFO.routines, MAG_CREATIONS)) mag_creations(level, caster, spellnum); if (IS_SET(SINFO.routines, MAG_ROOMS)) mag_rooms(level, caster, spellnum); if (IS_SET(SINFO.routines, MAG_MANUAL)) switch (spellnum) { case SPELL_CHARM: MANUAL_SPELL(spell_charm); break; case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break; case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break; case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break; case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break; case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break; case SPELL_SUMMON: MANUAL_SPELL(spell_summon); break; case SPELL_WORD_OF_RECALL: MANUAL_SPELL(spell_recall); break; case SPELL_TELEPORT: MANUAL_SPELL(spell_teleport); break; } return (1); }
int cast_spell(struct char_data *ch, struct char_data *tch, struct obj_data *tobj, struct spell_info_type *sptr, char *tar_str) { if (!magic_enabled) return (0); if (!sptr) { extended_mudlog(NRM, SYSL_BUGS, TRUE, "cast_spell() called without a valid sptr: ch: %s, tch: %s", GET_NAME(ch), GET_NAME(tch)); return (0); } if (GET_POS(ch) < sptr->min_position) { switch (GET_POS(ch)) { case POS_SLEEPING: send_to_char("You dream about great magical powers.\r\n", ch); break; case POS_RESTING: send_to_char("You cannot concentrate while resting.\r\n", ch); break; case POS_SITTING: send_to_char("You can't do this sitting!\r\n", ch); break; case POS_FIGHTING: send_to_char("Impossible! You can't concentrate enough!\r\n", ch); break; default: send_to_char("You can't do much of anything like this!\r\n", ch); break; } return (0); } if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == tch)) { send_to_char("You are afraid you might hurt your master!\r\n", ch); return (0); } if ((tch != ch) && IS_SET(sptr->targets, TAR_SELF_ONLY)) { send_to_char("You can only cast this spell upon yourself!\r\n", ch); return (0); } if ((tch == ch) && IS_SET(sptr->targets, TAR_NOT_SELF)) { send_to_char("You cannot cast this spell upon yourself!\r\n", ch); return (0); } if (IS_SET(sptr->routines, MAG_GROUPS) && !AFF_FLAGGED(ch, AFF_GROUP)) { send_to_char("You can't cast this spell if you're not in a group!\r\n",ch); return (0); } if (cast_mtrigger(tch, ch, tar_str, sptr) == 0) return (0); if (cast_otrigger(tobj, ch, tar_str, sptr) == 0) return (0); if (cast_wtrigger(ch, tch, tobj, tar_str, sptr) == 0) return (0); send_to_char(OK, ch); say_spell(ch, sptr, tch, tobj); return (call_magic(ch, tch, tobj, sptr, (GET_SKILL(ch, sptr->skill)/100), CAST_SPELL, tar_str)); }