/* * The spells of the guild. * What more can be said? * * (c) Auronthas begun 10.07.91 * most work done 17-18.07.91 */ #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 QNAME query_name() #define QLEV query_level() #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->QINT) #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; INT id(STRING str) { if(TP->QLEV < 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", "detma", 0, 2, DIVI, 1 }), ({ "find familiar", "findf", 0, 10, SUMM, 1 }), ({ "identify", "ident", 0, 5, DIVI, 1 }), ({ "shield i", "sh1", 10, 5, PROT, 1 }), ({ "ventriliquism", "ventr", 0, 3, ILLU, 1 }), ({ "aural illusion", "auril", 0, 6, ILLU, 2 }), ({ "bladerune i", "blru1", 5, 8, ENCH, 2 }), ({ "detect evil", "dete", 0, 2, DIVI, 2 }), ({ "detect good", "detg", 0, 2, DIVI, 2 }), ({ "light", "light", 20, 5, ELEM, 2 }), ({ "armour i", "ar1", 10, 7, PROT, 3 }), ({ "chill touch", "chto", 10, 10, NECR, 3 }), ({ "darkfire bolt i", "dafb1", 0, 8, DARK, 3 }), ({ "fireblade i", "fibl1", 10, 10, ELEM, 3 }), ({ "heal i", "heal1", 0, 5, HEAL, 3 }), ({ "know alignment", "knowa", 0, 5, DIVI, 4 }), ({ "reveal invisible", "revin", 0, 12, DIVI, 4 }), ({ "analyze", "analy", 0, 6, DIVI, 5 }), ({ "scare", "scare", 0, 15, ENCH, 5 }), ({ "shield ii", "sh2", 15, 10, PROT, 5 }), ({ "summon insects", "sumin", 5, 10, SUMM, 5 }), ({ "emote", "emote", 0, 5, ILLU, 5 }), ({ "bladerune ii", "blru2", 10, 15, ENCH, 6 }), ({ "blur", "blur", 10, 10, ILLU, 6 }), ({ "clairvoyance", "clvoy", 10, 15, DIVI, 6 }), ({ "consume corpse", "conco", 0, 10, NECR, 6 }), ({ "water bolt", "wbolt", 0, 7, ELEM, 6 }), ({ "armour ii", "ar2", 15, 14, PROT, 7 }), ({ "fireblade ii", "fibl2", 15, 15, ELEM, 7 }), ({ "heal ii", "heal2", 0, 10, HEAL, 7 }), ({ "remove curse", "recur", 0, 20, ENCH, 7 }), ({ "call power i", "capo1", 0, 10, SUMM, 8 }), ({ "darkness", "dark", 20, 15, DARK, 8 }), ({ "darkfire bolt ii", "dabf2", 0, 16, DARK, 8 }), ({ "ice bolt"," ibolt", 0, 10, ELEM, 8 }), ({ "locate", "locat", 0, 10, DIVI, 8 }), ({ "neutralize poison", "nepoi", 0, 15, HEAL, 8 }), ({ "levitate", "levit", 15, 15, ENCH, 9 }), ({ "rope trick", "roptr", 20, 20, ENCH, 9 }), ({ "vampiric touch", "vamto", 0, 15, NECR, 9 }), ({ "fire bolt", "fbolt", 0, 13, ELEM, 10 }), ({ "instability", "insta", 0, 20, SUMM, 10 }), ({ "invisibility", "invis", 30, 25, ENCH, 10 }), ({ "shield iii", "sh3", 20, 15, PROT, 10 }), ({ "bladerune iii", "blru3", 15, 20, ENCH, 11 }), ({ "charm", "charm", 0, 15, ENCH, 11 }), ({ "dispel magic", "disp", 0, 20, ENCH, 11 }), ({ "illusion", "illus", 0, 10, ILLU, 11 }), ({ "animate dead", "anded", 30, 35, NECR, 12 }), ({ "armour iii", "ar3", 20, 21, PROT, 12 }), ({ "fireblade iii", "fibl3", 20, 20, ELEM, 12 }), ({ "heal iii", "heal3", 0, 15, HEAL, 12 }), ({ "call power ii", "capo2", 0, 20, SUMM, 13 }), ({ "darkfire bolt iii", "dafb3", 0, 24, DARK, 13 }), ({ "lightning bolt", "lbolt", 0, 16, ELEM, 13 }), ({ "regeneration", "regen", 15, 25, HEAL, 13 }), ({ "read mind", "readm", 0, 15, DIVI, 14 }), ({ "summon spirit", "suspi", 20, 30, SUMM, 14 }), ({ "shadow warrior", "shwar", 20, 20, ILLU, 14 }), ({ "spell wall", "spwal", 10, 10, PROT, 14 }), ({ "harm", "harm", 0, 20, DARK, 15 }), ({ "summon demon", "sudem", 20, 60, DARK, 15 }), ({ "bladerune iv", "blru4", 20, 25, ENCH, 16 }), ({ "fireblade iv", "fibl4", 20, 20, ELEM, 16 }), ({ "shield iv"," sh4", 25, 20, PROT, 16 }), ({ "armour iv", "ar4", 25, 28, PROT, 17 }), ({ "heal iv", "heal4", 0, 20, HEAL, 17 }), ({ "shadow monster", "shmon", 20, 30, ILLU, 17 }), ({ "darkfire bolt iv", "dafb4", 0, 32, DARK, 18 }), ({ "dimension door", "dimdo", 0, 50, ENCH, 18 }), ({ "unlife", "unlif", 0, 50, NECR, 18 }), ({ "call total power", "catop", 0, 40, SUMM, 19 }), ({ "disintegrate", "disin", 0, 30, DARK, 19 }), ({ "meteor swarm", "metsw", 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->QNAME+" 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->QNAME+" 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->QNAME + d2; while(sscanf(mess3, "%s#%s", d1, d2)) mess3 = d1 + TP->QNAME + 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->QNAME+" starts mumbling and arches of fire leap between "+ TP->query_possessive()+" fingers.\n"+ CAP(TP->query_pronoun())+" stretches a hand towards "+ who->QNAME+"."; } else if(type=="cold" || type=="ice") { s1="You utter the harsh tones of a spell."; s2=TP->QNAME+" utters a spell in harsh tones, stretching a hand\n"+ "towards "+who->QNAME+"."; } else if(type=="lightning" || type=="electricity") { s1="Lightning crackles between your fingers as you start casting a spell."; s2=TP->QNAME+" mumbles something and stretches a hand towards\n"+ who->QNAME+", lightning crackling between "+TP->query_possessive()+" fingers."; } else if(type=="crush" || type=="impact") { s1="You perform somatic preparations to a spell."; s2=TP->QNAME+" waves "+TP->query_possessive()+" hands in front of "+ TP->query_objective()+"."; } else if(type=="drain") { s1="You start preparing black art."; s2=TP->QNAME+" starts preparing black art, glaring towards "+who->QNAME; } 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->QNAME); 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->QNAME+" tried to ventriliquate something from "+CAP(who)+ "'s mouth.\n",guy); tell_object(guy,TP->QNAME+" 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->QNAME+"..\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->QNAME + " 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->QNAME+" heals you.\n"); say(TP->QNAME+" mumbles a spell of healing.\n"); say(TP->QNAME+" heals "+CAP(ob->QNAME)+".\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]->QNAME); 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]->QNAME); 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]->QLEV > 19 || invisible[t]->resist_magic()) { write("You feel the presence of someone invisible.\n"); } else { invisible[t]->vis(); write(CAP(invisible[t]->QNAME)+" 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]->QNAME)+" 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->QNAME+" tries to scare "+who->short()+".\n"); return 1; } if ((TP->SK_ENCH - who->QLEV) < 0) { if(!random(4) && !MR(who)) { write("You scare "+CAP(who->QNAME)+".\n"); tell_object(who,TP->QNAME+" suddenly appears very frightening!\n"); say(TP->QNAME+" scares "+CAP(who->QNAME)+".\n",who); who->run_away(); } else { write(who->QNAME+" resists your spell!\n"); say(who->QNAME+" mumbles a useless spell.\n",who); tell_object(who,TP->QNAME+" tries to scare you.\n"); } return 1; } if (!MR(who)) { write("You scare " + who->QNAME+".\n"); tell_object(who,TP->QNAME+" suddenly appears very frightening!\n"); say(TP->QNAME+" scares "+CAP(who->QNAME)+".\n",who); who->run_away(); } else { write(CAP(who->QNAME)+" resists your spell!\n"); tell_object(who,TP->QNAME+" tries to scare you.\n"); } return 1; } /*** Emote ***/ emote(str) { write ("Ok.\n"); say(TP->QNAME+" "+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->QNAME+" 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->QNAME+" 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->QNAME),curseflags); return 1; } for (t=0 ; t<sizeof(curseflags) ; t++) { call_other(HOME+"flagger","clear_flag",lower_case(who->QNAME),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->QNAME+" 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->QNAME+" 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->QNAME+" 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->QNAME+" 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(1); move_object(light, this_player()); i = light->SET_DUR("light"); 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() { int i; object darkness; darkness = clone_object(SPELLHOME + "light"); i = TP->query_skill(query_spell_school(recognize_spell("darkness"))) / 25; if (!i) i = 1; darkness->set_level(-i); write("You summon darkness.\n"); say(TP->QN + " casts a spell.\n"); move_object(darkness,EN(TP)); i = darkness->SET_DUR("darkness"); return 1; } /*** Ice Bolt ***/ ibolt(str) { if(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") return 1; } /*** 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->QNAME+" 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) { if(attack_spell(str, "You cast a firebolt at #.", "# casts a firebolt at you.", "# casts a firebolt at &.", random(35),"fire")) return 1; } /*** 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->QNAME+" makes you invisible.\n"); write("You make "+CAP(who->QNAME)+" 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->QNAME+" 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]->QLEV-4+random(10)) > TP->QINT) tell_object(all[t],TP->QNAME+" 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->QNAME)+" is not working magic.\n"); return 1; } tell_object(who,TP->QNAME+" probes your mind.\n"); say(TP->QNAME+" looks intensely at "+CAP(who->QNAME)+".\n",who); know=skill->query_known(); write(CAP(who->QNAME)+" 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->QNAME+" mutters an ancient spell."); write("You disintegrate "+str+".\n"); say(TP->QNAME+" 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]) 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; }