/*
* The spells of the mage guild.
* What more can be said?
*
* (C) 1991, 1992 Auronthas
*/
#include "/std/include/std.h"
#include "defines.h"
#include "spells.h"
#define DESTINATION "players/auronthas/workroom"
#define QAL query_alignment()
#define QINT query_int()
#define SPELLHOME "players/auronthas/spells/"
#define HOME "players/auronthas/"
#define SET_CASTER set_caster_name(environment()->query_name())
#define MR(o) (random(100)<o->query_skill("magic_resistance"))
#define CAP(c) capitalize(c)
#define REDUCE "drain"
#define MORE_EVIL(n) this_player()->set_al(this_player()->query_al()-n)
#define SET_DUR(s) set_duration(query_spell_duration(recognize_spell(s))*TP->QL)
#define CHECK_FOR_RESISTANCE(o) if(o->query_skill("magic_resistance")>random(100)){write("Your magic fails.\n");return;}
#define ILLEGAL_INDEX(n) (n < 0 || n >= sizeof(spell_info))
#define in_room(o) present(o,environment(this_player()))
#define on_player(o) present(o,this_player())
int t, n, ran;
int spinc, max_spells;
string temp1, temp2;
object all, ting, target, next;
object dispel_ob;
string damage_type;
string whoname,temp1,temp2,d1;
string drain_mess1, drain_mess2, drain_mess3;
mixed *spell_info;
id(STRING str) {
if(TP->QL < 20) return 0;
return str == "spells" || str == "master spell object" ||
str == "master";
}
STRING
short() {
return "master spell object";
}
VOID
reset(INT arg)
{
if(arg) return;
spell_info = ({
/* SPELL NAME ABBREV. DUR. COST SCHOOL LEVEL */
/* ----------------------- ------------- ------ ------ ------ ----- */
({ "Detect Magic", "detectmagic", 0, 2, DIVI, 1 }),
({ "Find Familiar", "familiar", 0, 10, SUMM, 1 }),
({ "Identify", "identify", 0, 5, DIVI, 1 }),
({ "Shield I", "shield1", 10, 5, PROT, 1 }),
({ "Ventriliquism", "ventr", 0, 3, ILLU, 1 }),
({ "Aural Illusion", "auril", 0, 6, ILLU, 2 }),
({ "Bladerune I", "bladerune", 5, 8, ENCH, 2 }),
({ "Detect Evil", "detectevil", 0, 2, DIVI, 2 }),
({ "Detect Good", "detectgood", 0, 2, DIVI, 2 }),
({ "Light", "light", 20, 5, ELEM, 2 }),
({ "Armour I", "armor", 10, 7, PROT, 3 }),
({ "Chill Touch", "chill", 10, 10, NECR, 3 }),
({ "Darkfire Bolt I", "darkfire", 0, 8, DARK, 3 }),
({ "Fireblade I", "fireblade", 10, 10, ELEM, 3 }),
({ "Cure Wounds I ", "cure", 0, 5, HEAL, 3 }),
({ "Know Alignment", "knowalign", 0, 5, DIVI, 4 }),
({ "See Invisible", "seeinvis", 0, 12, DIVI, 4 }),
({ "Analyze", "analyze", 0, 6, DIVI, 5 }),
({ "Scare", "scare", 0, 15, ENCH, 5 }),
({ "Shield II", "shield2", 15, 10, PROT, 5 }),
({ "Summon Insects", "insects", 5, 10, SUMM, 5 }),
({ "Bladerune II", "bladerune2", 10, 15, ENCH, 6 }),
({ "Blur", "blur", 10, 10, ILLU, 6 }),
({ "Clairvoyance", "clairvoyance", 10, 15, DIVI, 6 }),
({ "Consume Corpse", "consume", 0, 10, NECR, 6 }),
({ "Water Bolt", "waterbolt", 0, 7, ELEM, 6 }),
({ "Armour II", "armour2", 15, 14, PROT, 7 }),
({ "Fireblade II", "fireblade2", 15, 15, ELEM, 7 }),
({ "Heal II", "heal2", 0, 10, HEAL, 7 }),
({ "Remove Curse", "removecurse", 0, 20, ENCH, 7 }),
({ "Call Power I", "callpower", 0, 10, SUMM, 8 }),
({ "Darkness", "darkness", 20, 15, DARK, 8 }),
({ "Darkfire Bolt II", "darkfire2", 0, 16, DARK, 8 }),
({ "Ice Bolt", "icebolt", 0, 10, ELEM, 8 }),
({ "Locate", "locate", 0, 10, DIVI, 8 }),
({ "Neutralize Poison", "neutralize", 0, 15, HEAL, 8 }),
({ "Levitate", "levitate", 15, 15, ENCH, 9 }),
({ "Rope Trick", "rope", 20, 20, ENCH, 9 }),
({ "Vampiric Touch", "touch", 0, 15, NECR, 9 }),
({ "Fire Bolt", "firebolt", 0, 13, ELEM, 10 }),
({ "Instability", "instability", 0, 20, SUMM, 10 }),
({ "Invisibility", "invis", 30, 25, ENCH, 10 }),
({ "Shield III", "shield3", 20, 15, PROT, 10 }),
({ "Bladerune III", "bladerune3", 15, 20, ENCH, 11 }),
({ "Charm", "charm", 0, 15, ENCH, 11 }),
({ "Dispel Magic", "dispel", 0, 20, ENCH, 11 }),
({ "Illusion", "illusion", 0, 10, ILLU, 11 }),
({ "Animate Dead", "animate", 30, 35, NECR, 12 }),
({ "Armour III", "armour3", 20, 21, PROT, 12 }),
({ "Fireblade III", "fireblade3", 20, 20, ELEM, 12 }),
({ "Cure Wounds III", "cure3", 0, 15, HEAL, 12 }),
({ "Call Power II", "callpower2", 0, 20, SUMM, 13 }),
({ "Darkfire Bolt III", "darkfire3", 0, 24, DARK, 13 }),
({ "Lightning Bolt", "lightning", 0, 16, ELEM, 13 }),
({ "Regeneration", "regen", 15, 25, HEAL, 13 }),
({ "Read Mind", "readmind", 0, 15, DIVI, 14 }),
({ "Summon Spirit", "spirit", 20, 30, SUMM, 14 }),
({ "Shadow Warrior", "warrior", 20, 20, ILLU, 14 }),
({ "Spell Wall", "spellwall", 10, 10, PROT, 14 }),
({ "Harm", "Harm", 0, 20, DARK, 15 }),
({ "Summonc Demon", "summondemon", 20, 60, DARK, 15 }),
({ "Bladerune IV", "rune4", 20, 25, ENCH, 16 }),
({ "Fireblade IV", "fireblade4", 20, 20, ELEM, 16 }),
({ "Shield IV", "shield4", 25, 20, PROT, 16 }),
({ "Armour IV", "armour4", 25, 28, PROT, 17 }),
({ "Heal IV", "cure4", 0, 20, HEAL, 17 }),
({ "Shadow Monster", "monster", 20, 30, ILLU, 17 }),
({ "Darkfire Bolt IV", "darkfire4", 0, 32, DARK, 18 }),
({ "Dimension Door", "dimdoor", 0, 50, ENCH, 18 }),
({ "Unlife", "unlife", 0, 50, NECR, 18 }),
({ "Call Total Power", "totalpower", 0, 40, SUMM, 19 }),
/* ({ "Disintegrate", "disintegrate", 0, 30, DARK, 19 }),*/
({ "Meteor Swarm", "meteor", 0, 50, ELEM, 19 }),
});
DESTINATION->load_me();
move_object(THO, DESTINATION);
}
/* in_room(str) checks if an object with the id str is in the room */
#if 0 /* Using macros for these */
OBJECT
in_room(STRING str)
{
return present(str,EN(TP));
}
OBJECT
on_player(STRING str)
{
return present(str,TP);
}
#endif
OBJECT
is_here(str)
{
if(IN_ROOM(str)) return IN_ROOM(str);
return ON_PLAYER(str);
}
/* General attack spell, 17/07-91
*
* Argument descriptions:
*
* string mess1: Replaces # with name of the target (sent to caster)
* string mess2: Replaces # with name of the caster (sent to target)
* string mess3: Replaces # with name of the caster and & with name of the
* target (sent to everyone else in the room)
* string name: Name of target. 0 is returned if that being is not present in
* the room.
* int damage: The actual amount of damage done. (Armour helps)
* string type: The type of damage done. Types: heat,cold,impact,electricity,
*
* not hit_player.
* Returns 1 if the spell works, 0 otherwise.
*/
INT
attack_spell(name,mess1,mess2,mess3,damage,type) {
object who, splw, skill;
string s1,s2,s3,d2;
int dam, i, j;
if (EN(TP)->query_property("no_fight"))
{
write("You can not fight here.\n");
return 0;
}
if (EN(TP)->query_property("no_mattack"))
{
write("You are unable to use aggressive magic here.\n");
return;
}
if (!name) who=TP->query_attack();
else who=IN_ROOM(name);
if (!who)
{
write("At whom?\n");
return 0;
}
if(!living(who))
{
write("Not a living thing!\n");
return 0;
}
if(who == TP)
{
write("What? Yourself?\n");
say(TP->QN+" was about to attack "+TP->QOBJ+
"self, but changed "+TP->QPOS+" mind.\n");
return 0;
}
skill = present("spell_skill",TP);
if(!skill)
{
write("Your magic seriously fails you!\n");
say(TP->QN+" fails terribly!\n");
return 0;
}
damage_type = type;
whoname = who->query_name();
/* while(sscanf(mess1, "%s#%s", d1, d2))
mess1 = d1 + whoname + d2;
while(sscanf(mess2, "%s#%s", d1, d2))
mess2 = d1 + TP->QN + d2;
while(sscanf(mess3, "%s#%s", d1, d2))
mess3 = d1 + TP->QN + d2;
while(sscanf(mess3, "%s&%s", d1, d2))
mess3 = d1 + whoname + d2;
skill->set_messages(mess1,mess2,mess3);*/
skill->set_damage_type(type);
skill->set_spell_damage(damage);
if(!TP->query_attack())
{
if(type=="fire" || type=="heat")
{
s1="You start calling the forces of fire.";
s2=TP->QN+" starts mumbling and arches of fire leap between "+
TP->query_possessive()+" fingers.\n"+
CAP(TP->query_pronoun())+" stretches a hand towards "+
who->QN+".";
}
else if(type=="cold" || type=="ice")
{
s1="You utter the harsh tones of a spell.";
s2=TP->QN+" utters a spell in harsh tones, stretching a hand\n"+
"towards "+who->QN+".";
}
else if(type=="lightning" || type=="electricity")
{
s1="Lightning crackles between your fingers as you start casting a spell.";
s2=TP->QN+" mumbles something and stretches a hand towards\n"+
who->QN+", lightning crackling between "+TP->query_possessive()+" fingers.";
}
else if(type=="crush" || type=="impact")
{
s1="You perform somatic preparations to a spell.";
s2=TP->QN+" waves "+TP->query_possessive()+" hands in front of "+
TP->query_objective()+".";
}
else if(type=="drain")
{
s1="You start preparing black art.";
s2=TP->QN+" starts preparing black art, glaring towards "+who->QN;
}
write(s1+"\n");
say(s2+"\n");
}
/* write(mess1 + "\n");
say(mess3 + "\n",TP);*/
splw = ON_PLAYER("spellwall");
if (splw)
{
damage -= splw->query_effect(damage);
write(whoname + " has protective magic on " + who->query_objective() + ".\n");
tell_object(who, "A protective spell reduces the effects.\n");
}
if(who->query_skill("magic_resistance") > random(100))
{
say("It had no obvious effect.\n");
write("It had no obvious effect.\n");
damage=0;
if(!who->query_attack())
{
who->attacked_by(TP);
}
return 1;
}
temp1=who->query_possessive(); /** Have to use these variables, there */
temp2=who->query_pronoun(); /** would be too many locals if else. */
d1=who->query_objective();
/* if (type == "drain")
{
s3 = convert(drain_mess3,whoname,temp1,temp2,d1);
if (who->query_hp() <= damage-1)
{
who->hit_player(who->query_ac()+5+damage);
if(!who)
{
write(s3+"\n");
say(s3+"\n");
}
return 1;
}
i = who->query_hp();
dam = i - who->reduce_hit_point(damage);
j = get_mess(dam);
s1 = convert(drain_mess1[j],whoname,temp1,temp2,d1);
s2 = convert(drain_mess2[j],whoname,temp1,temp2,d1);
tell_object(who,s2+"\n");
say(CAP(s1)+"\n",who);
who->attacked_by(TP); /** To start a combat **/
/* return 1;
}*/
TP->do_attack(who,skill);
return 1;
}
/******* HERE THEY ARE: SPELLS! ********/
/*** Detect Magic ***/
INT
detma()
{
object obj;
t=0;
obj = first_inventory(environment(TP));
while(obj)
{
if(obj->query_property("magic"))
{
write(obj->short()+" (in the room) is magical.\n");
t=1;
}
obj = next_inventory(obj);
}
obj = first_inventory(TP);
while(obj)
{
if(obj->query_property("magic"))
{
write(obj->short()+" (on you) is magical.\n");
t=1;
}
obj = next_inventory(obj);
}
if(!t)
write("Nothing magical here.\n");
else
write("Ok.\n");
return 1;
}
/*** Find Familiar ***/
/*
INT
findf()
{
object familiar;
if(call_other(SPELLHOME+"flagger","check_flag",TP->query_real_name(),3))
write("You already have a familiar!\n");
return 1;
}
if(do_cost("findf")) return 1;
call_other(SPELLHOME+"flagger","set_flag",TP->query_real_name(),2);
ran = random(11)+2;
ran += (TP->QAL/100);
if (ran < 2)
familiar = clone_object(SPELLHOME+"imp");
else if (ran >= 2 && ran <= 4)
familiar = clone_object(SPELLHOME+"toad");
else if (ran >= 5 || ran == 6 || ran == 8 || ran == 9)
familiar = clone_object(SPELLHOME+"cat");
else if (ran == 7)
familiar = clone_object(SPELLHOME+"drake");
else if (ran >= 10 && ran <= 12)
familiar = clone_object(SPELLHOME+"weasel");
else if (ran >= 13)
familiar = clone_object(SPELLHOME+"brownie");
familiar->set_master(TP->QN);
move_object(familiar,environment(TP));
say(familiar->short()+" arrives.\n");
write(familiar->short()+" comes to you. You are now bound together.\n");
return 1;
}
*/
/*** Identify ***/
INT
ident(STRING item)
{
object ting;
string kort;
if(!item) {
write("Please specify an item.\n");
return 0;
}
ting = ON_PLAYER(item);
if (!ting) {
write("No "+item+" on you.\n");
return 0;
}
if(ting->query_info())
write(ting->query_info());
kort = ting->short();
ting->identify();
if (kort != ting->short())
write(CAP(ting ->short())+"\n");
write("Ok.\n");
return 1;
}
/*** Shield I ***/
sh1()
{
return shield(2);
}
/*** Shield II ***/
sh2()
{
return shield(2);
}
/*** Shield III ***/
sh3()
{
return shield(3);
}
/*** Shield IV ***/
sh4()
{
return shield(4);
}
static shield(ac)
{
object shieldspell;
if(EN(TP)->query_property("no_mdefense"))
{
write("You cannot use defensive magic here!\n");
return;
}
shieldspell = clone_object(SPELLHOME+"prot_spell");
shieldspell->set_spell_name("shield");
shieldspell->set_ac(ac);
shieldspell->SET_CASTER;
shieldspell->SET_DUR("ar"+ac);
move_object(shieldspell,TP);
return 1;
}
/*** Armour I ***/
ar1()
{
return armour(1);
}
/*** Armour II ***/
ar2()
{
return armour(2);
}
/*** Armour III ***/
ar3()
{
return armour(3);
}
/*** Armour IV ***/
ar4()
{
return armour(4);
}
static armour(ac)
{
object armourspell;
if(EN(TP)->query_property("no_mdefense"))
{
write("You cannot use defensive magic here!\n");
return;
}
armourspell = clone_object(SPELLHOME+"prot_spell");
armourspell->set_spell_name("armour");
armourspell->set_ac(ac+1);
armourspell->SET_CASTER;
armourspell->SET_DUR("ar"+ac);
move_object(armourspell,TP);
return 1;
}
/*** Ventriliquism ***/
ventr(str)
{
string who,what;
object guy;
sscanf(str,"%s %s",who,what);
guy = present(lower_case(who),environment(TP));
if (!guy) {
write("Who?\n");
return 0;
}
if(((guy->QINT) - 4 + random(10) <= TP->SK_ILLU) && !MR(guy)) {
write("You made it!\n");
say(who+" says: "+what+"\n",guy);
tell_object(guy,"You say: "+what+"\n");
return 1;
} else {
write(who+" resisted the magic!\n");
say(TP->QN+" tried to ventriliquate something from "+CAP(who)+
"'s mouth.\n",guy);
tell_object(guy,TP->QN+" tried to ventriliquate something from your mouth.\n");
}
return 1;
}
/*** Aural Illusion ***/
auril(what)
{
object all;
say("There is a sound of "+what+"\n");
all=all_inventory(EN(TP));
for (t=0 ; t<sizeof(all) ; t++)
{
if((living(all[t]) && !all[t]->query_npc() &&
all[t]->query_int()-4+random(10) > TP->SK_ILLU) || MR(all[t]))
{
tell_object(all[t],"..but it was just an illusion cast by "+
TP->QN+"..\n");
}
}
return 1;
}
/*** Bladerune I-IV ***/
blru1(str)
{
bladerune(str, "1");
return 1;
}
blru2(str)
{
bladerune(str, "2");
return 1;
}
blru3(str)
{
bladerune(str, "3");
return 1;
}
blru4(str)
{
bladerune(str, "4");
return 1;
}
bladerune(str, f)
{
object weapon;
object enchantment;
weapon = is_here(str);
if(!weapon)
{
write("Cast spell on what weapon?\n");
return;
}
if(!weapon->weapon_class())
{
write("Not a weapon!\n");
return;
}
enchantment = clone_object(SPELLHOME + "bla_run" + f);
weapon->set_hit_func(enchantment);
weapon->set_short(weapon->short() + " (enchanted)");
write("You enchant "+ str +".\n");
say(TP->QN + " enchants " + str + ".\n");
move_object(enchantment, weapon);
enchantment->SET_CASTER;
enchantment->SET_DUR("blru"+f);
}
/* Chill touch */
chto(str)
{
object chill;
if(!attack_spell
(str,"You touch #.",
"# touches you with an icing chill.",
"# touches &.",
random(10) + 1, REDUCE)) return 0;
chill = clone_object(SPELLHOME + "chill");
move_object(chill, IN_ROOM(str));
chill->SET_DUR("chto");
}
/*** Darkfire bolt I ***/
dafb1(str)
{
if(!attack_spell(str,
"You throw a black flame at #.",
"# throws a black flame at you.",
"# throws a black flame at &.",
random(15),"fire")) return;
MORE_EVIL(1);
return 1;
}
/*** Darkfire bolt II ***/
dafb2(str)
{
if(!attack_spell(str,
"You hurl darkfire at #.",
"# hurls black fire at you.",
"# hurls black fire at &.",
random(25),"fire")) return;
MORE_EVIL(2);
return 1;
}
/*** Darkfire bolt III ***/
dafb3(str)
{
if(!attack_spell(str,
"You shoot a bolt of darkfire at #.",
"# shoots a bolt of black fire at you.",
"# shhots a bolt of black fire at &.",
random(40),"fire")) return;
MORE_EVIL(3);
return 1;
}
/** Darkfire bolt IV ***/
dafb4(str)
{
if(!attack_spell(str,
"You unleash the flames of hell at #.",
"Black fire pours from #'s arms at you.",
"Black fire pours from #'s arms at &.",
random(55),"fire")) return;
MORE_EVIL(4);
return 1;
}
/*** Heal I to IV ***/
heal1(str)
{
return heal(str,random(10)+1);
}
heal2(str)
{
return heal(str,random(20)+1);
}
heal3(str)
{
return heal(str,random(30)+1);
}
heal4(str)
{
return heal(str,random(40)+1);
}
static heal(st,am)
{
object ob;
if(!st) ob=TP; else ob=IN_ROOM(st);
if(!ob)
{
write("No-one with that name here..\n");
return;
}
if(!living(ob))
{
write("That is not a living thing!\n");
return 0;
}
ob->reduce_hit_point(-am);
tell_object(ob,TP->QN+" heals you.\n");
say(TP->QN+" mumbles a spell of healing.\n");
say(TP->QN+" heals "+CAP(ob->QN)+".\n",ob);
write("Ok.\n");
return 1;
}
/* Detect evil and good */
dete()
{
int al;
string na;
all = all_inventory(environment(TP));
for(t = 0 ; t < sizeof(all) ; t++)
{
if(living(all[t]) && !all[t]->resist_magic())
{
al = all[t]->QAL;
na = capitalize(all[t]->QN);
if (al <= -1000)
write(na + " radiates an extremely evil aura.\n");
if (al <= -200 && al > -1000)
write(na + " is evil.\n");
if (al <= -40 && al > -200)
write(na + " is a little evil.");
if (al > -40)
write(na + " is not particularly evil.\n");
}
}
write("Ok.\n");
return 1;
}
detg()
{
int al;
string na;
all = all_inventory(environment(TP));
for(t = 0 ; t < sizeof(all) ; t++)
{
if(living(all[t]) && !all[t]->resist_magic())
{
al = all[t]->QAL;
na = capitalize(all[t]->QN);
if (al >= 1000)
write(na + " radiates an extremely good aura.\n");
if (al >= 200 && al < 1000)
write(na + " is good.\n");
if (al >= 40 && al < 200)
write(na + " is a little good.");
if (al < 40)
write(na + " is not particularly good.\n");
}
}
write("Ok.\n");
return 1;
}
/*** Reveal Invisible ***/
revin()
{
object invisible;
invisible = filter_objects(all_inventory(EN(TP)),"is_invisible",this_object());
for (t=0 ; t<sizeof(invisible) ; t++)
{
if(invisible[t]->QL > 19 || invisible[t]->resist_magic())
{
write("You feel the presence of someone invisible.\n");
}
else
{
invisible[t]->vis();
write(CAP(invisible[t]->QN)+" was invisible.\n");
}
}
write("Ok.\n");
return 1;
}
is_invisible(ob)
{
if (living(ob) && (ob->short() == "" || ob->short() == 0 || !ob->short()))
return 1;
}
/*** Know Alignment ***/
knowa()
{
object beings;
int al;
all=all_inventory(EN(TP));
beings = filter_objects(all,"knowal_filter",this_object());
for (t=0 ; t<sizeof(beings) ; t++)
{
if (beings[t] != TP)
{
al = beings[t]->QAL;
write(CAP(beings[t]->QN)+" is ");
if (al > 1000)
{
write("saintly");
}
else if (al > 200)
{
write("good");
}
else if (al > 40)
{
write("nice");
}
else if (al > -40)
{
write ("neutral");
}
else if (al > -200)
{
write ("nasty");
}
else if (al > -1000)
{
write ("evil");
}
else write("demonic");
write(".\n");
}
}
write("Ok.\n");
return 1;
}
knowal_filter(ob)
{
if (living(ob) && !ob->resist_magic())
return 1;
}
/*** Scare ***/
scare(str)
{
object who;
if(!str)
{
write("Scare who?\n");
return 0;
}
who = IN_ROOM(str);
if (!who) return 0;
if (!living(who))
{
write("Seemed like it had no effect...\n");
say(TP->QN+" tries to scare "+who->short()+".\n");
return 1;
}
if ((TP->SK_ENCH - who->QL) < 0)
{
if(!random(4) && !MR(who))
{
write("You scare "+CAP(who->QN)+".\n");
tell_object(who,TP->QN+" suddenly appears very frightening!\n");
say(TP->QN+" scares "+CAP(who->QN)+".\n",who);
who->run_away();
}
else
{
write(who->QN+" resists your spell!\n");
say(who->QN+" mumbles a useless spell.\n",who);
tell_object(who,TP->QN+" tries to scare you.\n");
}
return 1;
}
if (!MR(who))
{
write("You scare " + who->QN+".\n");
tell_object(who,TP->QN+" suddenly appears very frightening!\n");
say(TP->QN+" scares "+CAP(who->QN)+".\n",who);
who->run_away();
}
else
{
write(CAP(who->QN)+" resists your spell!\n");
tell_object(who,TP->QN+" tries to scare you.\n");
}
return 1;
}
/*** Emote ***/
emote(str) {
write ("Ok.\n");
say(TP->QN+" "+str+"\n");
return 1;
}
/*** Blur ***/
blur()
{
object blur;
if(EN(TP)->query_property("no_mdefense"))
{
write("You cannot use defensive magic here!\n");
return;
}
blur = clone_object(SPELLHOME+"prot_spell");
blur->set_spell_name("blur");
blur->set_ac(1+random(3));
blur->SET_CASTER;
blur->SET_DUR("blur");
move_object(blur,TP);
return 1;
}
/*** Clairvoyance ***/
/*
clvoy() {
write("You sit down and start concentrating deeply.\n");
say(TP->QN+" sits down and starts to concentrate.\n");
write("\nType 'abort' to abort the spell.\n"+
"You can now walk around visually for a while.\n");
eyes = clone_object(SPELLHOME+"clv_eyes");
keeper = clone_object(SPELLHOME+"keeper");
keeper->set_caller(this_object());
eyes->set_keeper(keeper);
eyes->set_viewer(TP);
eyes->set_oldroom(EN(TP));
move_object(keeper, TP);
move_object(eyes, EN(TP));
call_out("no_clairvoyance", query_duration(recognize_abbr("clvoy")));
return 1;
}
clv_interruption() {
write("You are interrupted!\n");
remove_call_out("no_clairvoyance");
no_clairvoyance();
}
no_clairvoyance() {
write("You are yanked back to your body!\n");
destruct(eyes);
destruct(keeper);
}
*/
/*** Consume Corpse ***/
conco()
{
object cor;
t=0;
cor=IN_ROOM("corpse");
if(!cor)
{
write("No corpse here!\n");
return;
}
while (cor)
{
write("You consume "+cor->short()+".\n");
say(TP->QN+" greedily eats "+cor->short()+".\n");
destruct(cor);
t++;
cor=present("corpse",this_object());
}
write("You feel better.\n");
TP->heal_self((t*random(8))+t);
if(TP->QAL > -200)
{
write("You feel your soul perverting.\n");
MORE_EVIL(30);
}
return 1;
}
/*** Water Bolt ***/
wbolt(str) {
if(attack_spell(str,
"You aim a bolt of water at #.",
"# shoots a bolt of water at you.",
"# fires a bolt of water at &.",
random(10)+5,"impact")) return 1;
}
/*** Remove Curse ***/
recur(str) {
object who;
object curse;
int curseflags;
if (!str) who = TP;
else who = IN_ROOM(str);
if(!who) {
write("At whom?");
return 0;
}
if(!living(who)) {
write("Not a living thing!\n");
return 0;
}
while(present("curse",who)) {
curse = present("curse",who);
curse->remove_curse();
}
curseflags = call_other(HOME+"workroom", "query_curse_flags");
if(intp(curseflags)) {
call_other(HOME+"flagger","clear_flag",lower_case(who->QN),curseflags);
return 1;
}
for (t=0 ; t<sizeof(curseflags) ; t++) {
call_other(HOME+"flagger","clear_flag",lower_case(who->QN),curseflags[t]);
}
write("Ok.\n");
return 1;
}
/*** Call Power I ***/
capo1() {
if (TP->query_hp() < 35) {
write("You are too weak!\n");
return 0;
}
TP->reduce_hit_point(25);
spinc = 10+random(30);
call_out("giveback_sp",1);
write("You feel your body wither, but your mind fills up with energy!\n");
say(TP->QN+" trades blood with power!\n");
return 1;
}
/*** Call Power II ***/
capo2() {
if (TP->query_hp() < 60) {
write("You are not strong enough right now.\n");
return 0;
}
TP->reduce_hit_point(50);
spinc = 30 + random(50);
call_out("giveback_sp",1);
write("You fall to your knees as you sacrifice your body for power.\n");
say(TP->QN+" falls to "+TP->query_possessive()+" knees, there is "+
"an aura of power around "+TP->query_objective()+".\n");
if (! random(6)) {
write("This was worse than you had imagined. You start trembling.\n");
say(TP->QN+" starts trembling from the strain.\n");
TP->set_con(TP->query_con()-1);
}
return 1;
}
/*** Call Total Power ***/
catop() {
int oldhp, sp1, sp2, dms, con;
if (TP->query_hp() < 100) {
write("You do not possess the strength to accomplish such a spell.\n");
return 0;
}
oldhp = TP->query_hp();
sp1 = TP->query_spell_points();
TP->reduce_hit_point(oldhp-10);
spinc = random(((oldhp-10)*8)/5);
call_out("giveback_sp",1);
sp2 = TP->query_spell_points();
if (spinc-sp2+sp1 > 70) {
write("This was more energy than your body could handle. You lose control!\n");
say(TP->QN+" starts burning. Fire spews out of "+
TP->query_possessive()+" mouth,\n"+
"and "+TP->query_possessive()+" eyes glow bright red!\n");
say("You cannot avoid being hit by the flames.\n");
all=all_inventory(EN(TP));
for(t=0 ; t<sizeof(all) ; t++) {
if(living(all[t])) {
dms++;
all[t]->reduce_hit_point(random(20));
}
}
write("Your head clears just enough for you to understand what just happened.\n");
if(dms) {
write("You feel weaker, and you have accidentally damaged\n"+
"the others in the room person");
if(dms > 1) write("s");
write(".\n");
con = TP->query_con()-(random(3)+1);
if (con < 1) con = 1;
TP->set_con(con);
}
}
return 1;
}
giveback_sp()
{
ENV -> restore_spell_points(spinc);
}
/*** Light ***/
light()
{
object light;
int i;
light = clone_object(SPELLHOME + "light");
i = TP->query_skill(query_spell_school(recognize_spell("light"))) / 25;
if (!i) i = 1;
light->set_level(i);
i = light->SET_DUR("light");
move_object(light, TP);
say(TP->QN + " mumbles softly, and a globe of light appears between " +
TP->QPOS + " hands.\n");
write("You summon a small globe of light.\n");
}
/*** Darkness ***/
dark()
{
object dark;
int i;
dark = clone_object(SPELLHOME + "light");
i = TP->query_skill(query_spell_school(recognize_spell("darkness"))) / 25;
if (!i)
i = 1;
dark->set_level(-i);
i = dark->SET_DUR("darkmess");
move_object(dark, EN(TP));
write("You summon darkness.\n");
say(TP->QN + " casts a spell.\n");
}
/*** Ice Bolt ***/
ibolt(str) {
return attack_spell(str,
"You hurl a bolt of ice towards #.",
"# casts an ice bolt in your direction.",
"# smites a bolt of ice towards &.",
random(15)+10,
"ice");
}
/*** Locate ***/
locat(str) {
object who;
who = find_player(lower_case(str));
if (!who) {
write("No such player.\n");
return 1;
}
write("You see:\n");
EN(who)->long();
return 1;
}
/*** Neutralize Poison ***/
nepoi(str) {
object who, poison;
if(!who) who=TP;
else who=IN_ROOM(str);
if(!who) {
write("At whom?\n");
return 0;
}
if(!living(who) && who->id("corpse")) {
write("Sorry, "+CAP(str)+" is already dead.\n");
return 0;
}
if(!living(who)) {
write("Not a living thing!\n");
return 0;
}
while(present("poison",who)) {
poison = present("poison",who);
poison->neutralize();
}
write("Ok.\n");
return 1;
}
/*** Rope Trick ***/
roptr() {
object ob;
write("You create a magical rope which you climb into safety.\n");
say(TP->QN+" summons a magical rope and climbs it. Then both are gone.\n");
while (TP->query_attack()) {
TP->query_attack()->stop_fight();
}
TP->stop_fight();
ob=clone_object(SPELLHOME+"rope_obj");
ob->SET_DUR("roptr");
ob->set_oldroom(EN(TP));
move_object(ob,TP);
move_object(TP,SPELLHOME+"ethplane");
TP->glance();
return 1;
}
/*** Vampiric Touch ***/
vamto(str) {
int dam;
dam=random(20)+5;
if(!attack_spell(str,
"You draw life force from #.",
"# touches you with a life draining touch.",
"# touches &.",
dam,"drain")) return 0;
TP->heal_self(dam);
tell_object(IN_ROOM(str),"You feel weaker!\n");
write("You feel a surge in your blood.\n");
if(TP->QAL > -200)
MORE_EVIL(20);
return 1;
}
/*** Fire Bolt ***/
fbolt(str) {
return attack_spell(str,
"You cast a firebolt at #.",
"# casts a firebolt at you.",
"# casts a firebolt at &.",
random(35),"fire");
}
/*** Invisibility ***/
invis(str) {
object who, invisibility;
if(!str) who=TP;
else who=IN_ROOM(str);
if(!who) {
write("At whom?\n");
return 0;
}
if(!living(who)) {
write("Cannot make non-living objects invisible!\n");
return 0;
}
if(who->query_npc()) {
write("Can only make players invisible.\n");
return 0;
}
if(who != TP) {
tell_object(who,TP->QN+" makes you invisible.\n");
write("You make "+CAP(who->QN)+" invisible.\n");
}
invisibility = clone_object(SPELLHOME+"invis_sp");
move_object(invisibility,who);
return 1;
}
/*** Charm ***/
/*
charm(str) {
object who;
who=IN_ROOM(str);
if(!who) {
write("Charm who?\n");
return 0;
}
if(who==TP) {
write("Oh yeah, you're such a nice guy!\n");
return 0;
}
if(!living(who)) {
write("Well, you could try, but you can't exactly expect any results..\n");
return 0;
}
}
*/
/*** Dispel Magic ***/
disp()
{
object all2;
say(TP->QN+" casts a spell.\n");
all=all_inventory(EN(TP));
for(t=0 ; t<sizeof(all) ; t++)
{
if(all[t]->dispel())
{
all[t]->dispel();
}
all2 = present("spell",all[t]);
if((all2) && (all[t] != TP))
{
while(present("spell", all[t]))
{
all2 = present("spell",all[t]);
if(all2->id("spell"))
{
all2->dispel();
}
all2 = next_inventory(all[t]);
}
}
}
write("Ok.\n");
return 1;
}
/*** Illusion ***/
illus(str)
{
all=filter_objects(all_inventory(EN(TP)),"illusion_filter",this_object());
for(t=0 ; t<sizeof(all) ; t++)
{
if((all[t]->QL-4+random(10)) > TP->QINT)
tell_object(all[t],TP->QN+" casts an illusion of:\n");
}
say(str+"\n");
write("Ok.\n");
return 1;
}
illusion_filter(ob)
{
if(living(ob)) return 1;
}
/*** Lightning Bolt ***/
lbolt(str) {
if(attack_spell(str,
"You shoot a lightning bolt at #.",
"# shoots a bolt of lightning at you.",
"# zaps & with a lightning bolt.",
random(20)+10),"lightning") return 1;
}
/*** Regeneration ***/
regen(str) {
object who,regen;
if(!str) who=TP;
else who=IN_ROOM(str);
if(!who) {
write("At whom?\n");
return 0;
}
if(!living(who)) {
write("Non-living matter cannot regenerate!\n");
return 0;
}
regen = clone_object(SPELLHOME+"regener");
regen->SET_DUR("regen");
move_object(regen,who);
return 1;
}
/*** Read Mind ***/
readm(str)
{
object who,skill;
string know,dummy;
who=IN_ROOM(str);
if(who==TP)
{
write("That shouldn't really be necessary, should it?\n");
return 0;
}
if(!who)
{
write("Read who's mind?\n");
return 0;
}
if(!living(who))
{
write("No mind to read there, dummy!\n");
return 0;
}
skill=present("spell_skill",who);
if(!skill)
{
write(CAP(who->QN)+" is not working magic.\n");
return 1;
}
tell_object(who,TP->QN+" probes your mind.\n");
say(TP->QN+" looks intensely at "+CAP(who->QN)+".\n",who);
know=skill->query_known();
write(CAP(who->QN)+" knows the following spells:\n");
for (t=0,n=0 ; t<query_max_spells() ; t++,n++)
{
if(test_bit(know,t))
{
dummy = query_all_spell_names()[t]+" ";
write(CAP(extract(dummy,0,19)));
if(n==3) {
write("\n");
n=-1;
}
}
}
if(n != -1) write("\n");
return 1;
}
/*** Harm ***/
harm(str)
{
if(!attack_spell(str,
"You point a finger at #, inflicting pain.",
"You feel a sharp pain in your chest as # points a finger at you.",
"# points a finger at &, who staggers.",
random(40),"drain")) return 0;
if(TP->QAL > -200)
MORE_EVIL(10);
return 1;
}
/*** Meteor Swarm ***/
metsw(str)
{
if(attack_spell(str,
"You send a swarm of burning meteors towards #.",
"# hurls a swarm of fiery meteors at you!",
"# sends a small swarm of fiery meteors right towards &.",
random(60)+30,"impact")) return 1;
}
/*** Disintegrate ***/
INT
disintegrate(STRING str)
{
object what;
what = is_here(str);
if(!what)
{
write("Disintegrate what?\n");
return 0;
}
if(living(what) && !what->query_npc())
{
write("Cannot disintegrate living players.\n");
return 0;
}
if(!what->get())
{
write("You cannot disintegrate "+what->short()+"!\n");
return 0;
}
if(living(what))
move_object(what,"/room/void");
say(TP->QN+" mutters an ancient spell.");
write("You disintegrate "+str+".\n");
say(TP->QN+" turned "+what->short()+" to dust!\n");
destruct(what);
return 1;
}
/*****************************************************************************/
INT
spell_help(INT spell)
{
if(ILLEGAL_INDEX(spell)) return 0;
write(CAP(spell_info[spell][SP_NAME]) + " (" +
CAP(query_school(spell)) +
") :\n" + "Level: "+query_spell_level(spell) + " MP: " +
query_cost(spell));
if(query_duration(spell) > 0)
write(" Duration: " + query_duration(spell));
write("\nAbbrevation: " + query_spell_abbr(spell) + "\n");
cat("/"+SPELLHOME + "helpdir/" + query_spell_abbr(spell) + ".doc");
return 1;
}
INT recognize_spell(STRING str)
{
for (t=0 ; t<sizeof(spell_info) ; t++)
if (spell_info[t][SP_ABBR] == str || spell_info[t][SP_NAME] == str)
return t;
return -1;
}
INT
recognize_spell_abbr(STRING str)
{
for (t=0 ; t<sizeof(spell_info) ; t++)
if (spell_info[t][SP_ABBR] == str)
return t;
return -1;
}
INT
recognize_spell_name(STRING str)
{
for (t=0 ; t<sizeof(spell_info) ; t++)
if (spell_info[t][SP_NAME] == str)
return t;
return -1;
}
STRING
query_school(INT n)
{
switch (n) {
case DARK: return "dark arts"; break;
case DIVI: return "divination"; break;
case ELEM: return "elemental magic"; break;
case ENCH: return "enchantment magic"; break;
case HEAL: return "healing magic"; break;
case ILLU: return "illusion"; break;
case NECR: return "necromancy"; break;
case PROT: return "protection magic"; break;
case SUMM: return "summoning"; break;
default: return "unknown"; break;
}
}
INT
query_spell_school(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_SCHOOL];
}
INT
query_spell_level(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_LEVEL];
}
STRING
query_spell_name(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_NAME];
}
INT
query_spell_cost(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_COST];
}
STRING
query_spell_abbr(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_ABBR];
}
INT
query_spell_duration(INT n)
{
if (ILLEGAL_INDEX(n)) return -1;
return spell_info[n][SP_DURATION];
}
INT
query_max_spells()
{
return sizeof(spell_info);
}
MIXED
query_spell_info(INT spell, INT info)
{
if (ILLEGAL_INDEX(spell)) return -1;
return spell_info[spell][info];
}
MIXED_ARR
return_spell_info()
{
return spell_info;
}