# Special-purpose globals obscure_chance = 95 min_casttime = 200 # Schools of magic CONST MAGIC = 340 CONST LIFE = 341 CONST WAR = 342 CONST TRANSMUTE = 343 CONST NATURE = 344 CONST NECROMANCY = 345 # Elements CONST ELT_NEUTRAL = 0 CONST ELT_WATER = 1 CONST ELT_EARTH = 2 CONST ELT_FIRE = 3 CONST ELT_WIND = 4 CONST ELT_POISON = 5 CONST ELT_SHADOW = 6 CONST ELT_HOLY = 7 CONST ELT_GHOST = 8 CONST ELT_UNDEAD = 9 # Status effects CONST SC_WINDWALK = 116 CONST SC_POISON = 132 CONST SC_SHEARED = 194 # This is the same as SC_HIDE, since mobs can't hide and shearing is only used for mobs. Feel free to fix! CONST SC_HIDE = 194 CONST SC_HALT_REGENERATE = 195 CONST SC_FLYING_BACKPACK = 196 CONST SC_MBARRIER = 197 CONST SC_HASTE = 198 CONST SC_PHYS_SHIELD = 199 CONST EVOL_GUILD = 500 CONST EVOL_CRAFT = 501 CONST EVOL_DYE = 502 CONST SO_GMINVISIBLE = 4096 # Spells constants CONST LESSER_HEAL_HP =50 CONST MEDIUM_HEAL_HP =250 CONST FULL_HEAL_HP =1000000 CONST LESSER_GROUP_HEAL_HP =30 CONST MEDIUM_GROUP_HEAL_HP =150 CONST FULL_GROUP_HEAL_HP_PERC =80 # Special effects CONST SFX_DEFAULT = 10 CONST SFX_SUMMON_START = 21 CONST SFX_SUMMON_FIRE = 22 CONST SFX_TELEPORT = 24 CONST SFX_RAIN = 25 CONST SFX_HIT = 25 CONST SFX_ARROW_HAIL = 27 CONST SFX_SNOW = 33 CONST SFX_BARRIER = 10 CONST SFX_UNBARRIER = 10 CONST SFX_HEAL = 3 CONST MAX_RAIN_SPELL_RADIUS = 15 CONST MAX_MAGIC_LEVEL = 2 # Increase up to 5 as each new magic level is completed. CONST MAGIC_FLAGS = "MAGIC_FLAGS" CONST MFLAG_MADE_CONC_POTION = 16384 CONST MFLAG_MADE_CONC_POTION_SHIFT = 14 CONST SCRIPT_XP = "MAGIC_EXPERIENCE" CONST SCRIPT_XP_MASK = 0xffff CONST SCRIPT_XP_SHIFT = 0 CONST SCRIPT_LASTSPELL_MASK = 0xff CONST SCRIPT_LASTSPELL_SHIFT = 16 CONST SCRIPT_HEALSPELL_MASK = 0xff CONST SCRIPT_HEALSPELL_SHIFT = 24 CONST DEBUG = 0 CONST ATTACK_ICON_GENERIC = 2000 CONST ATTACK_ICON_SHEARING = 2001 # Default sfx on caster PROCEDURE default_effect() = sfx(caster, school - MAGIC + 2, 0); PROCEDURE sfx_generic(target) = sfx(target, SFX_DEFAULT, 0); PROCEDURE set_var(name, mask, shift, value) = set_script_variable(caster, name, script_int(caster, name) & (neg (mask << shift)) | ((value & mask) << shift)); PROCEDURE gain_heal_xp(value, # How many HP we healed gain, # how many life magic experience points we can potentially gain heal_xp_value_divisor, # 1 for instaheal, 2 for slow heal base_exp_factor) = # factor for how many base experience points (max) the player should be allowed to gain last_heal_xp = (script_int(caster, SCRIPT_XP) >> SCRIPT_HEALSPELL_SHIFT) & SCRIPT_HEALSPELL_MASK; IF (target <> caster && (value / heal_xp_value_divisor) > (10 + last_heal_xp + random(last_heal_xp + 1) + random(last_heal_xp + 1))) THEN ( heal_xp = last_heal_xp + gain; IF (heal_xp > SCRIPT_HEALSPELL_MASK) THEN heal_xp = SCRIPT_HEALSPELL_MASK; CALL set_var(SCRIPT_XP, SCRIPT_HEALSPELL_MASK, SCRIPT_HEALSPELL_SHIFT, heal_xp); ) IF target <> caster THEN gain_experience(caster, base_exp_factor * extract_healer_experience(target, value), 0, 1); PROCEDURE gain_xp(gain) = IF (level + 3 > skill(caster, MAGIC)) # Level 4 and 5 magic users don't gain anything from spell levels 0 resp. 0+1 THEN ( index = spell_index(self_spell); last_index = (script_int(caster, SCRIPT_XP) >> SCRIPT_LASTSPELL_SHIFT) & SCRIPT_LASTSPELL_MASK; last_xp = (script_int(caster, SCRIPT_XP) >> SCRIPT_XP_SHIFT) & SCRIPT_XP_MASK; IF (index != last_index) THEN ( # Some variation observed xp = last_xp + gain; IF (xp > SCRIPT_XP_MASK) THEN xp = SCRIPT_XP_MASK; CALL set_var(SCRIPT_XP, SCRIPT_XP_MASK, SCRIPT_XP_SHIFT, xp); CALL set_var(SCRIPT_XP, SCRIPT_LASTSPELL_MASK, SCRIPT_LASTSPELL_SHIFT, index); IF DEBUG THEN message(caster, "Spell xp = " + xp); ) ELSE IF DEBUG THEN message(caster, "Re-cast same spell, xp remain at " + last_xp); ) PROCEDURE create_item(good_item, count, bad_item, difficulty) = success = 1; score = experience + random(min(spellpower, (experience / 3) + 1)); IF (score >= difficulty) THEN create_item(caster, good_item, count); ELSE ( success = 0; score = score + random(luk(caster)) + random(luk(caster)); IF (score < difficulty / 3) THEN ( message(caster, "Your spell backfires!"); IF (random(110) < (luk(caster))) THEN itemheal(caster, 0 - ((level + 1) * (level + 2) * (3 + random(28))), 0); ELSE itemheal(caster, 0 - (level + 1), 0); ) ELSE IF (score < (difficulty * 2) / 3) THEN ( IF random(5) = 0 THEN (message(caster, "Your spell solidifies into the shape of a mysterious object!"); create_item(caster, "Iten", 1);) ELSE message(caster, "Your spell escapes!"); ) ELSE ( message(caster, "Your spell takes on a mind of its own!"); IF random(3) = 0 THEN create_item(caster, bad_item, 1); ) ) # Increase spellpower by school and general magic skill PROCEDURE adjust_spellpower(school) = experience = (script_int(caster, SCRIPT_XP) >> SCRIPT_XP_SHIFT) & SCRIPT_XP_MASK; spellpower = spellpower + (skill(caster, MAGIC) + skill(caster, school)) * 10; # Below, we adjust by special items IF (not(failed(target)) && (school = LIFE || school = NATURE)) THEN IF (target) THEN IF (pc(target) = partner(caster)) THEN (spellpower = spellpower + 200; IF is_equipped(caster, "WeddingRing") THEN spellpower = spellpower + 50; IF is_equipped(pc(target), "WeddingRing") THEN spellpower = spellpower + 50;) PROCEDURE heal(target, max_heal) = CALL default_effect(); IF caster <> target THEN sfx(target, SFX_HEAL, 0); power = spellpower + vit(caster); power = min(max_heal, (max_heal * power) / 250); itemheal(target, power, 0); # Goes through instaheal instead of itemheal PROCEDURE quickheal(target, power) = CALL default_effect(); IF caster <> target THEN sfx(target, SFX_HEAL, 0); instaheal(target, power, 0); # Can attack the target? Imports attack_range from dynamic environment PROCEDURE attack_check(target) = IF (not (line_of_sight(location(caster), location(target)))) THEN ABORT; IF (not (rdistance(location(caster), location(target)) <= attack_range)) THEN ABORT; # Cause elemental damage. bonus_elt grants an attack bonus, malus_elt reduces the attack. `effect' is the sfx ID. PROCEDURE elt_damage(target, damage, dmgplus, bonus_elt, malus_elt, effect) = d = damage + random(dmgplus); evade = level(target) + mdef(target); IF (element(target) = malus_elt) THEN d = d / 3; IF (element(target) = bonus_elt) THEN d = (d * (4 + element_level(target))) / 4; #message(caster, "bonus=" + (element(target) = bonus_elt) + " malus=" + (element(target) = malus_elt) + " damage=" + damage + " + r(" + dmgplus + ") -> " + d); sfx(target, effect, 0); IF (spellpower - random(100) < evade) THEN d = 0; injure(caster, target, d, 0); PROCEDURE melee_damage(target, damage, dmgplus) = CALL attack_check(target); d = damage + random(dmgplus); evade = level(target) + mdef(target); IF (spellpower - random(100) < evade) THEN d = 0; injure(caster, target, d, 0); PROCEDURE install_attack_spell(charges, base_delay, range, attack_animation) = CALL default_effect(); attack_range = range; override_attack(caster, charges, ((200 - agi(caster)) * base_delay) / 200, range, ATTACK_ICON_GENERIC, attack_animation, 0); PROCEDURE install_melee_spell(charges, base_delay, attack_animation) = CALL install_attack_spell(charges, base_delay, 1, attack_animation); PROCEDURE summon_spell(mob_id, count, delay, lifetime, control_level) = CALL default_effect(); sfx(location, SFX_SUMMON_START, 0); WAIT delay; sfx(location, SFX_SUMMON_FIRE, 0); spawn(rbox(location, 2), caster, mob_id, if_then_else(skill(caster, ASTRAL) >= control_level, 2, 1), # pets when level is high enough count, lifetime); PROCEDURE abort_on_area_shield(pos) = IF (is_exterior(pos) = 1 && (map_nr(pos) = 1 # Tulimshar ||map_nr(pos) = 9 # Hurnscald ||map_nr(pos) = 20 ||map_nr(pos) = 99)) # Nivalis THEN (message(caster, "A powerful magic drains your spell just as it is beginning to take shape!"); ABORT;) #-------------------------------------------------------------------------------- # Level 0 spells #-------------------------------------------------------------------------------- SPELL ask-magic-exp : "#G01" = LET level = 0 school = MAGIC IN (MANA 1, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); level = skill (caster, MAGIC); experience = (script_int(caster, SCRIPT_XP) >> SCRIPT_XP_SHIFT) & SCRIPT_XP_MASK; IF (experience == SCRIPT_XP_MASK && level > 4) THEN message (caster, "You are as proficient at magic as you can possibly be."); ELSE ( # This duplicates the table in mana-seed.txt IF level > 4 THEN max_experience = SCRIPT_XP_MASK; ELSE IF level = 4 THEN max_experience = 40000; ELSE IF level = 3 THEN max_experience = 8000; ELSE IF level = 2 THEN max_experience = 1200; ELSE max_experience = 100; ratio = (10 * experience - random(max_experience / 30)) / max_experience; #Randomness: jitter a bit at the transitions to give more precise information if used frequently IF ratio >= 45 THEN message(caster, "Magic flows naturally from you, readily and with ease. Your understanding of what you can currently control at present is flawless, far beyond your requirements to cast magic at this level." + if_then_else(level >= MAX_MAGIC_LEVEL,""," Surely the Mana Seed will more than readily offer more magic for such a proficient user.")); ELSE IF ratio >= 20 THEN message(caster, "You have perfect control of what you understand now, but there is now a distinct sensation of something more, something indescribable. If only the Mana Seed would give more magic to you..."); ELSE IF ratio >= 10 THEN message(caster, "You feel in perfect control of your magic" + if_then_else(level >= MAX_MAGIC_LEVEL,".",", and seem on the verge of something more... perhaps you should see the Mana Seed to ask for more magic?")); ELSE IF ratio >= 9 THEN message(caster, "You feel in almost perfect control of your magic."); ELSE IF ratio >= 8 THEN message(caster, "You feel that you have very good control of your magic."); ELSE IF ratio >= 7 THEN message(caster, "You feel quite in control of your magic."); ELSE IF ratio >= 6 THEN message(caster, "You feel mostly in control of your magic."); ELSE IF ratio >= 5 THEN message(caster, "You feel somewhat in control of your magic."); ELSE IF ratio >= 4 THEN message(caster, "You feel you still have a few difficulties in controlling your magic."); ELSE IF ratio >= 3 THEN message(caster, "Trying to control your magic is still rather troublesome."); ELSE IF ratio >= 2 THEN message(caster, "You feel that you have only the bare minimum of control over your magic."); ELSE IF ratio >= 1 THEN message(caster, "You feel quite overwhelmed by your magic, but are beginning to see patterns."); ELSE message (caster, "You feel completely overwhelmed by your magic."); ) # SPELL ask-life-magic-exp : "#G02" = # LET level = 0 # school = MAGIC # IN (MANA 1, CASTTIME 1000, # REQUIRE skill(caster, MAGIC) > level) # => EFFECT CALL adjust_spellpower(school); # CALL default_effect(); # message(caster, "You have " + ((script_int(caster, "MAGIC_EXPERIENCE") >> 24) & 0xff) + " Life Magic Experience points."); SPELL transmute-wood-to-figurine (name : STRING) : "#T00" = LET level = 0 school = TRANSMUTE IN (MANA 5, CASTTIME 4000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["RawLog"]) => ( REQUIRE name = "boo" => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("MoubooFigurine", 1, "WarpedLog", 40); CALL gain_xp(1); | REQUIRE name = "lurk" => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("WarpedLog", 1, "WarpedLog", 40); message (caster, "You have no idea what a Skrytlurk looks like."); ) #-------------------------------------------------------------------------------- # Evol Level 0 Life magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL lesser-heal (target : STRING) : "#L00" = LET level = 0 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF failed(pc(target)) THEN (target = caster;) ELSE (target = pc(target); IF is_dead(target) THEN ABORT;) CALL gain_heal_xp(min(200, max_hp(target) - hp(target)), 1, 2, 2); # report half values for non-instaheal CALL heal(target, LESSER_HEAL_HP); CALL gain_xp(1); SPELL cure-poison (target : PC) : "#L01" = LET level = 0 school = LIFE IN (MANA 15, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE (rdistance(location(caster), location(pc(target))) < 1 + (spellpower / 60)), CATALYSTS ["Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF (running_status_update (target, SC_POISON)) THEN (CALL gain_heal_xp(40, 1, 2, 2); stop_status_change (target, SC_POISON); CALL gain_xp(2); IF caster <> target THEN sfx(target, SFX_HEAL, 0);); SPELL lesser-group-heal : "#L02" = LET level = 0 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH PC target IN rbox(location(caster), 4) DO IF ( is_dead(target) = 0 && target <> caster && line_of_sight(location(caster), location(target))) THEN (CALL sfx_generic(target); CALL quickheal(target, LESSER_GROUP_HEAL_HP); CALL gain_heal_xp(min(LESSER_GROUP_HEAL_HP, max_hp(target) - hp(target)), 1, 2, 2);) CALL gain_xp(1); #-------------------------------------------------------------------------------- # End of Evol Level 0 Life magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 1 Life magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL medium-group-heal : "#L10" = LET level = 1 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH PC target IN rbox(location(caster), 6) DO IF ( is_dead(target) = 0 && target <> caster && line_of_sight(location(caster), location(target))) THEN (CALL sfx_generic(target); CALL quickheal(target, MEDIUM_GROUP_HEAL_HP); CALL gain_heal_xp(min(MEDIUM_GROUP_HEAL_HP, max_hp(target) - hp(target)), 1, 2, 2);) CALL gain_xp(1); SPELL transfusion (target : STRING) : "#L11" = LET level = 1 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF failed(pc(target)) THEN (target = caster;) ELSE (target = pc(target); IF is_dead(target) THEN ABORT;) CALL gain_heal_xp(min(200, max_hp(target) - hp(target)), 1, 2, 2); # report half values for non-instaheal points = min(500, hp(caster) - 1); CALL quickheal(caster, -1 * points); CALL quickheal(target, points); CALL gain_xp(1); SPELL medium-heal (target : STRING) : "#L12" = LET level = 1 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF failed(pc(target)) THEN (target = caster;) ELSE (target = pc(target); IF is_dead(target) THEN ABORT;) CALL gain_heal_xp(min(200, max_hp(target) - hp(target)), 1, 2, 2); # report half values for non-instaheal CALL heal(target, MEDIUM_HEAL_HP); CALL gain_xp(1); #-------------------------------------------------------------------------------- # End of Evol Level 1 Life magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 2 Life magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL revive (target : PC) : "#L20" = LET level = 2 school = LIFE IN (MANA 12, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["Acorn"]), REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF (target <> caster) #resurrect the target with 100% hp, 100% mp (1 flag to use %, 0 to use absolute values) THEN(resurrect(target, 1, 1, 0); CALL gain_xp(10); sfx(target, school - MAGIC + 2, 0);) SPELL full-group-heal : "#L21" = LET level = 2 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH PC target IN rbox(location(caster), 10) DO IF ( is_dead(target) = 0 && target <> caster && line_of_sight(location(caster), location(target))) THEN (CALL sfx_generic(target); CALL quickheal(target, max_hp(target) * (FULL_GROUP_HEAL_HP_PERC / 100)); CALL gain_heal_xp(min(max_hp(target) * (FULL_GROUP_HEAL_HP_PERC / 100), max_hp(target) - hp(target)), 1, 2, 2);) CALL gain_xp(1); SPELL full-heal (target : STRING) : "#L22" = LET level = 2 school = LIFE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE if_then_else(failed(pc(target)), 1, rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)), (CATALYSTS ["Acorn"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF failed(pc(target)) THEN (target = caster;) ELSE (target = pc(target); IF is_dead(target) THEN ABORT;) CALL gain_heal_xp(min(200, max_hp(target) - hp(target)), 1, 2, 2); # report half values for non-instaheal CALL heal(target, FULL_HEAL_HP); CALL gain_xp(1); #-------------------------------------------------------------------------------- # End of Evol Level 2 Life magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 0 Nature magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL rain : "#N00" = LET level = 0 school = NATURE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, CATALYSTS ["Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); #CALL abort_on_area_shield(location(caster)); CALL gain_xp(1); range = min(MAX_RAIN_SPELL_RADIUS, 3 + min(spellpower, 200) / 30); area = rbox(location(caster), range); FOR i = 0 TO (spellpower / 3) DO ( FOR j = 0 TO min(spellpower / 2, 200) / 100 DO ( location = random_location(area); sfx(location, SFX_RAIN, 0); ) WAIT 400 + random(100); ); SPELL speed : "#N02" = LET level = 0 school = NATURE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, CATALYSTS ["Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); status_change(caster, SC_WINDWALK, 16, -50, 0, 0, 30000); CALL gain_xp(1); message(caster, "You feel you can move fast"); #-------------------------------------------------------------------------------- # End of Evol Level 0 Nature magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 1 Nature magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL snow : "#N10" = LET level = 0 school = NATURE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, CATALYSTS ["Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); #CALL abort_on_area_shield(location(caster)); CALL gain_xp(1); range = min(MAX_RAIN_SPELL_RADIUS, 3 + min(spellpower, 200) / 30); area = rbox(location(caster), range); FOR i = 0 TO (spellpower / 3) DO ( FOR j = 0 TO min(spellpower / 2, 200) / 100 DO ( location = random_location(area); sfx(location, SFX_SNOW, 0); ) #WAIT 100 + random(100); ); SPELL anti-magic (target : PC) : "#N12" = LET level = 1 school = NATURE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, CATALYSTS ["Acorn"], REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); sfx(target, 11, 0); IF (caster <> target) THEN CALL default_effect(); status_change(target, SC_MBARRIER, 20 + max(30, spellpower / 8), 0, 0, 0, 2000 + (spellpower * 200)); status_change(target, SC_PHYS_SHIELD, 5 + max(15, spellpower / 20), 0, 0, 0, 5000 + (spellpower * 1000)); message (target, "You are surrounded by a magical barrier."); CALL gain_xp(5); ATEND message (target, "Your magical barrier dissipates."); sfx(target, 111, 0); #-------------------------------------------------------------------------------- # End of Evol Level 1 Nature magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 1 Necromancy magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL destruction : "#NE12" = LET level = 2 school = NECROMANCY IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, CATALYSTS ["Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH MOB target IN rbox(location(caster), 10) DO ( injure(caster, target, 1000, 0);) #sfx(target, 16, 0);) itemheal(caster, -1 * hp(caster) + 1, -10000); CALL gain_xp(1); #-------------------------------------------------------------------------------- # End of Evol Level 1 Necromancy magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 0 Transmutation magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL herb-transmut (target : PC) : "#T00" = LET level = 0 school = TRANSMUTE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, CATALYSTS ["Acorn"], CATALYSTS [646] OR CATALYSTS [647] OR CATALYSTS [648] OR CATALYSTS [649]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); esc = random(30); IF (esc = 0) THEN ( message (caster, "Your spell escapes!"); ABORT; ) { set @herbs[0], 646; set @herbs[1], 647; set @herbs[2], 648; set @herbs[3], 649; set @c, 4; set @herb, rand(@c); l_RandHerb: if (countitem(@herbs[@herb])) goto l_Delete; set @c, @c - 1; set @herbs[@herb], @herbs[@c]; set @herb, rand(@c); goto l_RandHerb; l_Delete: set @herb, @herbs[@herb]; delitem @herb, 1; l_NewHerb: set @herbs[0], 646; set @herbs[1], 647; set @herbs[2], 648; set @herbs[3], 649; set @c, 4; set @newherb, rand(@c); l_RandNewHerb: if (@herbs[@newherb] != @herb) goto l_Create; set @c, @c - 1; set @herbs[@newherb], @herbs[@c]; set @newherb, rand(@c); goto l_RandNewHerb; l_Create: getitem @herbs[@newherb], 1; if (@sec) goto l_Finish; set @sec, rand(29); if (@sec == 1) goto l_NewHerb; l_Finish: set @sec, 0; }; SPELL make-turtle : "#T02" = LET level = 0 school = TRANSMUTE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, #REQUIRE skill(caster, school) > level, COMPONENTS ["Acorn", "Acorn", "Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); spawn(rbox(location(caster), 2), caster, 1002, 1, 1, 1000000000); #-------------------------------------------------------------------------------- # End of Evol Level 0 Transmutation magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Evol Level 1 Transmutation magic spells (change acorns with the real component) #-------------------------------------------------------------------------------- SPELL make-bee : "#T12" = LET level = 0 school = TRANSMUTE IN (MANA 6, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, #REQUIRE skill(caster, school) > level, COMPONENTS ["Acorn", "Acorn", "Acorn", "Acorn"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); spawn(rbox(location(caster), 2), caster, 1005, 1, 1, 1000000000); #-------------------------------------------------------------------------------- # End of Evol Level 1 Transmutation magic spells #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Old TMW spells (to get rid of) #-------------------------------------------------------------------------------- SPELL aggravate : "#N00" = LET level = 0 school = NATURE IN (MANA 3, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH MOB target IN rbox(location(caster), 2 + spellpower / 50) DO IF line_of_sight(location(caster), location(target)) THEN (CALL sfx_generic(target); aggravate(target, 0, caster);) SPELL grow-mauve : "#N01" = LET level = 0 school = NATURE IN (MANA 4, CASTTIME 2000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["MauveHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); spawn(rbox(location, 2), caster, 1029, 1, skill(caster, school) / 2 + 1, 10000); SPELL grow-alizarin : "#N02" = LET level = 0 school = NATURE IN (MANA 4, CASTTIME 2000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["AlizarinHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); spawn(rbox(location, 2), caster, 1032, 1, skill(caster, school) / 2 + 1, 10000); SPELL grow-gamboge : "#N03" = LET level = 0 school = NATURE IN (MANA 4, CASTTIME 2000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["GambogeHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); spawn(rbox(location, 2), caster, 1031, 1, skill(caster, school) / 2 + 1, 10000); SPELL grow-cobalt : "#N04" = LET level = 0 school = NATURE IN (MANA 4, CASTTIME 2000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["CobaltHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); spawn(rbox(location, 2), caster, 1030, 1, skill(caster, school) / 2 + 1, 10000); LOCAL SPELL summon-maggots : "#A00" = LET level = 0 school = ASTRAL IN (MANA 21, CASTTIME 20000, REQUIRE skill(caster, MAGIC) > level, COMPONENTS ["MaggotSlime", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL gain_xp(1); CALL summon_spell(1002, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 5), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); SPELL detect-magic : "#G00" = LET level = 0 school = MAGIC IN (MANA 3, CASTTIME 6000, REQUIRE skill(caster, MAGIC) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); range = 1 + spellpower / 50; FOREACH NPC n IN rbox(location(caster), range) DO IF (contains_string(name_of(n), "#MAGIC") || contains_string(name_of(n), "#_M")) THEN sfx(n, SFX_DEFAULT, 0); FOREACH SPELL s IN rbox(location(caster), range) DO IF (s <> self_invocation) THEN sfx(s, SFX_DEFAULT, 0); #-------------------------------------------------------------------------------- # Level 1 spells #-------------------------------------------------------------------------------- SPELL make-arrows : "#T10" = LET level = 1 school = TRANSMUTE IN (MANA 8, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["RawLog"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("Arrow", 1 + spellpower / 40 + (random(max(1, 800 - spellpower)) / 80), "WarpedLog", 500); CALL gain_xp(1); SPELL make-shirt : "#T11" = LET level = 1 school = TRANSMUTE IN (MANA 25, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS [5 * "CottonCloth"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("CottonShirt", 1, "CottonCloth", 425); CALL gain_xp(2); SPELL make-tanktop : "#T12" = LET level = 1 school = TRANSMUTE IN (MANA 25, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS [4 * "CottonCloth"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("TankTop", 1, "CottonCloth", 350); CALL gain_xp(2); SPELL make-short-tanktop : "#T13" = LET level = 1 school = TRANSMUTE IN (MANA 25, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS [3 * "CottonCloth"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("ShortTankTop", 1, "CottonCloth", 250); CALL gain_xp(2); SPELL make-iron-powder : "#T14" = LET level = 1 school = TRANSMUTE IN (MANA 8, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["IronOre"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("IronPowder", 1 + spellpower / 140 + (random(max(1, 900 - spellpower)) / 220), "IronOre", 700); CALL gain_xp(3); SPELL make-concentration-potion : "#T15" = LET level = 1 school = TRANSMUTE IN (MANA 8, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["BottleOfWater", 2 * "CobaltHerb", 2 * "Petal"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item( if_then_else(random(2000 + experience) < experience, "ConcentrationPotion", "DarkConcentrationPotion"), 1, if_then_else(random(2), 744, "DarkConcentrationPotion"), 2000); IF (success) THEN CALL set_var(MAGIC_FLAGS, 1, MFLAG_MADE_CONC_POTION_SHIFT, 1); CALL gain_xp(4); SPELL merge-concentration-potions : "#T16" = LET level = 1 school = TRANSMUTE IN (MANA 8, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["DarkConcentrationPotion", 744]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL create_item("ConcentrationPotion", 1, 744, 1000); message (caster, "success = " + success); IF (success) THEN CALL set_var(MAGIC_FLAGS, 1, MFLAG_MADE_CONC_POTION_SHIFT, 1); CALL gain_xp(4); SPELL lay-on-hands (target : STRING) : "#L10" = LET level = 1 school = LIFE IN (MANA 10, CASTTIME 500, REQUIRE hp(caster) > max_hp(caster) / 20, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE if_then_else(failed(pc(target)), 1, (pc(target) <> caster) && (rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 50)) && not (running_status_update(pc(target), SC_HALT_REGENERATE)) )) => EFFECT CALL adjust_spellpower(school); IF (not (target)) THEN ABORT; IF failed(pc(target)) THEN (IF ((target = "mouboo" || target = "Mouboo") && (rdistance(location(caster), location(npc("Mouboo"))) < 2 + (spellpower / 100))) THEN (needed = 1000; { set @spell, 1; callfunc "QuestMoubooHeal"; }) ELSE ABORT; ) ELSE (target = pc(target); needed = max_hp(target) - hp(target);) pay_fraction = max(80, 200 - (vit(caster) + (spellpower / 10))); # Pay at least 40% payment = (needed * pay_fraction) / 200; available = hp(caster) - (max_hp(caster) / 20); IF payment < available THEN power = needed; ELSE (payment = available; power = (available * 200) / pay_fraction; ) CALL gain_heal_xp(power, 1, 1, 3); CALL quickheal(target, power); status_change(caster, SC_HALT_REGENERATE, 0, 0, 0, 0, 10000); CALL gain_xp(min(4, payment / 100)); SPELL lightning-strike : "#ingrav" = LET level = 1 school = WAR IN (MANA 20, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["IronPowder"])) => EFFECT CALL adjust_spellpower(school); damage = spellpower; damage_bonus = 1 + spellpower / 2; CALL install_attack_spell(1 + spellpower / 90, 3000, 8, 31); CALL gain_xp(2); ATTRIGGER CALL attack_check(target); in_rain = 0; area = location(caster); FOREACH SPELL s IN rbox(location(caster), MAX_RAIN_SPELL_RADIUS + 1) DO IF name_of(s) = "rain" THEN ( IF is_in (location(caster), s.area) THEN (in_rain = in_rain | 1; area = area + s.area;); IF is_in (location(target), s.area) THEN in_rain = in_rain | 2; ); IF (in_rain & 1) || (check_status_change(caster,SC_DRUNK)) THEN (# caster standing in the rain? This is going to be fun. used = 0; FOREACH TARGET t IN area DO IF (random(200) + luk(caster) > 175) THEN (used = used + 1; CALL elt_damage (t, damage / 6, 1 + (damage_bonus / 3), ELT_EARTH, ELT_WIND, 17 + random(3));); IF (not(used) || (random(200) + luk(caster) < 150)) THEN (sfx(caster, 17 + random(3), 0); itemheal(caster, 0 - damage - (random(damage_bonus)), 0);); ) ELSE CALL elt_damage (target, damage, damage_bonus, ELT_EARTH, ELT_WIND, 17 + random(3)); LOCAL SPELL arrow-hail : "#W11" = LET level = 1 school = WAR IN (MANA 25, CASTTIME 5000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE is_exterior(location(caster)), (COMPONENTS [20 * "Arrow"] OR COMPONENTS [20 * "IronArrow"]), (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["SulphurPowder"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL abort_on_area_shield(location(caster)); range = 7; area = rbox(awayfrom(location(caster), dir(caster), 1 + range), range); FOREACH SPELL s IN rbox(awayfrom(location(caster), dir(caster), 1 + range), range * 2) DO IF (s <> self_invocation) && (name_of(s) = "arrow-hail") THEN (message (caster, "A nearby arrow hail spell absorbs your magic!"); ABORT;) damage = 125; damage_bonus = spellpower / 5; CALL gain_xp(2); FOR i = 0 TO spellpower / 8 DO ( FOR j = 0 TO 2 DO ( location = random_location(area); sfx(location, SFX_ARROW_HAIL, 0); done = 0; FOREACH TARGET target IN rbox(location, 0) DO ( injure(caster, target, damage + random(damage_bonus) + random(damage_bonus), 0); done = 1; BREAK; ) IF location(caster) = location && not(done) THEN (itemheal(caster, 0 - (damage + random(damage_bonus) + random(damage_bonus)), 0); sfx(caster, SFX_HIT, 0); ) ); WAIT 250 + random(50) + random(50); ); SPELL magic-knuckles : "#W12" = LET level = 1 school = WAR IN (MANA 20, CASTTIME 500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["Beer"])) => EFFECT CALL adjust_spellpower(WAR); str = str(caster); CALL install_melee_spell(10 + spellpower / 10, 1300, 34); ATTRIGGER CALL melee_damage(target, 30, 5 + (str * 2)); SPELL flying-backpack (target : PC) : "#N10" = LET level = 1 school = NATURE IN (MANA 12, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["SilkCocoon"]), REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF (caster <> target) THEN sfx(caster, 2, 0); status_change(target, SC_FLYING_BACKPACK, 0, 0, 0, 0, 5000 + (spellpower * 500)); message (target, "Your backpack is lifted by a mystical force; you no longer feel it pressing on your back."); CALL gain_xp(1); ATEND message (target, "Your backpack is no longer levitating."); sfx(target, 2, 0); SPELL protect (target : PC) : "#N11" = LET level = 1 school = NATURE IN (MANA 14, CASTTIME 1500, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["HardSpike"]), REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); sfx(target, 11, 0); IF (caster <> target) THEN CALL default_effect(); status_change(target, SC_PHYS_SHIELD, 5 + max(15, spellpower / 20), 0, 0, 0, 5000 + (spellpower * 1000)); message (target, "You feel more protected."); CALL gain_xp(2); ATEND message (target, "You feel less protected."); sfx(target, 111, 0); SPELL happy-curse (target : PC) : "#N12" = LET level = 1 school = NATURE IN (MANA 13, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["GingerBreadMan"]), REQUIRE rdistance(location(target), location(caster)) < 1 + spellpower / 100) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOR i = 0 TO (spellpower / 10) DO (emote(target, 3); WAIT 500;); CALL gain_xp(1); LOCAL SPELL rain : "#N13" = LET level = 1 school = NATURE IN (MANA 17, CASTTIME 3000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE is_exterior(location(caster)), (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["BottleOfWater"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL abort_on_area_shield(location(caster)); FOREACH SPELL s IN rbox(location(caster), MAX_RAIN_SPELL_RADIUS + 1) DO IF (s <> self_invocation) && (name_of(s) = "rain") THEN (message (caster, "A nearby raincloud absorbs your magic."); ABORT;) CALL gain_xp(1); range = min(MAX_RAIN_SPELL_RADIUS, 3 + min(spellpower, 200) / 30); area = rbox(location(caster), range); IF (is_in(location(npc("#DruidTree0#_M")), area) || is_in(location(npc("#DruidTree1#_M")), area)) THEN { set @flag, 1; callfunc "QuestTreeTrigger"; }; FOR i = 0 TO (spellpower / 3) DO ( FOR j = 0 TO min(spellpower / 2, 200) / 100 DO ( location = random_location(area); sfx(location, SFX_RAIN, 0); FOREACH TARGET target IN rbox(location, 1) DO IF element(target) = ELT_FIRE THEN injure(caster, target, 2 + random(5 + spellpower / 15), 0); ) WAIT 400 + random(100); ); LOCAL SPELL snow : "#N23" = LET level = 1 school = NATURE IN (MANA 18, CASTTIME 3000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE is_exterior(location(caster)), (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["BottleOfWater"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL abort_on_area_shield(location(caster)); FOREACH SPELL s IN rbox(location(caster), MAX_RAIN_SPELL_RADIUS + 1) DO IF (s <> self_invocation) && (name_of(s) = "snow") THEN (message (caster, "A nearby snowcloud absorbs your magic."); ABORT;) CALL gain_xp(1); range = min(MAX_RAIN_SPELL_RADIUS, 3 + min(spellpower, 200) / 30); area = rbox(location(caster), range); FOR i = 0 TO (spellpower / 8) DO ( FOR j = 0 TO min(spellpower / 2, 200) / 100 DO ( location = random_location(area); sfx(location, 29, 0); FOREACH TARGET target IN rbox(location(area), 0) DO IF element(target) = ELT_FIRE THEN injure(caster, target, 2 + random(5 + spellpower / 15), 0); ) WAIT 200 + random(100); ); PROCEDURE shear-drop(target, target2, item, prob) = IF (target = name || target2 = name) THEN (IF (score < prob) THEN drop_item_for(place, item, 1, 60000, caster, 5000);) PROCEDURE shear-drop2(target, target2, item, prob, item2, prob2) = IF (target = name || target2 = name) THEN (IF (score < prob) THEN drop_item_for(place, item, 1, 60000, caster, 5000); ELSE CALL shear-drop(target, target2, item2, prob2 + prob);) PROCEDURE shear-drop3(target, target2, item, prob, item2, prob2, item3, prob3) = IF (target = name || target2 = name) THEN (IF (score < prob) THEN drop_item_for(place, item, 1, 60000, caster, 5000); ELSE CALL shear-drop2(target, target2, item2, prob2 + prob, item3, prob3 + prob);) SPELL shear : "#N14" = LET level = 1 school = NATURE IN (MANA 23, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); override_attack (caster, 1, 2000, 1, ATTACK_ICON_SHEARING, 30, 0); ATTRIGGER IF not(is_pc(target)) THEN (score = random (1000 - (random (spellpower))); # lower score -> more valuable item name = name_of(target); place = random_location(rbox(location(target), 1)); IF running_status_update(target, SC_SHEARED) THEN ABORT; status_change(target, SC_SHEARED, 1, 1, 1, 1, 600000); # 10 minutes CALL shear-drop("Fluffy", "Fluffy", "WhiteFur", 300); CALL shear-drop("EasterFluffy", "Easter Fluffy", "WhiteFur", 300); CALL shear-drop("SpikyMushroom", "Spiky Mushroom", "HardSpike", 250); CALL shear-drop("Mouboo", "Mouboo", "CottonCloth", 175); CALL shear-drop("Cobalt", "CobaltPlant", "CobaltHerb", 700); CALL shear-drop("Alizarin", "AlizarinPlant", "AlizarinHerb", 700); CALL shear-drop("Gamboge", "GambogePlant", "GambogeHerb", 700); CALL shear-drop("Mauve", "MauvePlant", "MauveHerb", 700); CALL shear-drop("SilkWorm", "Silkworm", "SilkCocoon", 300); IF ((name = "Fluffy" || name = "Mouboo") && random(2)) THEN { set @value, 1; callfunc "QuestSagathaHappy"; }; ) SPELL barrier (target : PC) : "#A10" = LET level = 1 school = ASTRAL IN (MANA 16, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["SmallMushroom"]), REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); sfx(target, SFX_BARRIER, 0); IF (caster <> target) THEN CALL default_effect(); status_change(target, SC_MBARRIER, 20 + max(30, spellpower / 8), 0, 0, 0, 2000 + (spellpower * 200)); message (target, "You are surrounded by a magical barrier."); CALL gain_xp(3); ATEND message (target, "Your magical barrier dissipates."); sfx(target, SFX_UNBARRIER, 0); LOCAL SPELL summon-spiky-mushrooms : "#A11" = LET level = 1 school = ASTRAL IN (MANA 33, CASTTIME 20000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["HardSpike", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); CALL summon_spell(1019, 1 + spellpower / 120, 5000 - (spellpower * 9), spellpower * 400, 2); LOCAL SPELL summon-fluffies : "#A12" = LET level = 1 school = ASTRAL IN (MANA 39, CASTTIME 20000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["WhiteFur", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); CALL summon_spell(1020, 1 + spellpower / 170 + spellpower / 430, 5000 - (spellpower * 8), spellpower * 350, 3); SPELL detect-players : "#G10" = LET level = 1 school = MAGIC IN (MANA 7, CASTTIME 300, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); message = ""; FOREACH PC target IN rbox(location(caster), spellpower / 2) DO IF ((target <> caster) && not (running_status_update(pc(target), SC_HIDE)) && not (status_option(target, SO_GMINVISIBLE))) THEN (IF message <> "" THEN message = message + ", "; message = message + name_of (target); IF spellpower > 99 THEN message = message + "(" + level(target) + ")"; ) IF message = "" THEN message(caster, "You sense no-one else nearby."); ELSE message(caster, "You sense the following: " + message); SPELL reveal : "#G11" = LET level = 1 school = MAGIC IN (MANA 18, CASTTIME 3000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); FOREACH PC target IN rbox(location(caster), 1 + spellpower / 100) DO IF has_shroud(target) && level(caster) * 2 > level(target) THEN (unshroud(target); sfx(target, SFX_DEFAULT, 500);) SPELL enchant-lifestone : "#G12" = LET level = 1 school = MAGIC IN (MANA 15, CASTTIME 4000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (COMPONENTS["BugLeg"] OR COMPONENTS ["MaggotSlime"] OR COMPONENTS ["MauveHerb", "AlizarinHerb", "CobaltHerb", "GambogeHerb"])) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); create_item(caster, "Lifestone", 1); CALL gain_xp(1); SPELL sense-spouse : "#G13" = LET level = 1 school = MAGIC IN (MANA 7, CASTTIME 400, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE is_married(caster), REQUIRE is_equipped(caster, "WeddingRing")) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF (failed(partner(caster)) || not(is_equipped(partner(caster), "WeddingRing"))) THEN (message(caster, "You cannot sense your partner."); ABORT;) partner = partner(caster); name = name_of(partner); IF (is_dead(partner) || (map_nr(location(partner)) <> map_nr(location(caster)))) THEN (message(caster, "You cannot sense " + name + " nearby."); ABORT;) IF (map_level(location(partner)) > 2 && map_level(location(caster)) < map_level(location(partner))) THEN (message(caster, "You sense " + name + " somewhere below."); ABORT;) IF (map_level(location(caster)) > 2 && map_level(location(partner)) < map_level(location(caster))) THEN (message(caster, "You sense " + name + " somewhere above."); ABORT;) IF (map_level(location(caster)) <> map_level(location(partner))) THEN message(caster, "You sense " + name + " somewhere in the vincinity."); ELSE (distance = rdistance(location(caster), location(partner)); dir = dir_towards(location(caster), location(partner), 1); IF (distance < 3) THEN message(caster, "You sense " + name + " right next to you."); ELSE IF (distance < 30) THEN message(caster, "You sense " + name + " close by, towards the " + dir + "."); ELSE IF (distance < 200) THEN message(caster, "You sense " + name + " nearby, towards the " + dir + "."); ELSE message(caster, "You sense " + name + " in the " + dir + "."); ) SPELL hide (target : PC) : "#A13" = LET level = 1 school = ASTRAL IN (MANA 11, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["CottonCloth"]), REQUIRE rdistance(location(target), location(caster)) < 2 + spellpower / 30) => EFFECT CALL adjust_spellpower(school); sfx(target, SFX_DEFAULT, 0); IF (caster <> target) THEN CALL default_effect(); status_change(target, SC_HIDE, 0, 0, 0, 0, 5000 + (spellpower * 2500)); CALL gain_xp(2); message(target, "You are hidden!"); IF (caster <> target) THEN message(caster, "You hid someone!"); ATEND message(target, "You are no longer hidden."); #-------------------------------------------------------------------------------- # Level 2 spells #-------------------------------------------------------------------------------- SPELL fire-ball : "#W22" = LET level = 2 school = WAR IN (MANA 30, CASTTIME 1000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["PileOfAsh"]) => EFFECT CALL adjust_spellpower(school); damage = min(50 + skill(caster, school) * 40, 30 + ((spellpower * 3) / 2)); damage_bonus = level(caster) + spellpower * 2; radius = 2 + spellpower / 50; CALL install_attack_spell(1 + spellpower / 60, 5000, 10, 31); ATTRIGGER CALL attack_check(target); loc = location(target); #WAIT 500; sfx(loc, 16, 0); FOREACH TARGET target IN rbox(loc, radius) DO IF line_of_sight(loc, location(target)) THEN (divisor = (3 + rdistance(loc, location(target))); CALL elt_damage (target, (damage * 3) / divisor, (damage_bonus * 3) / divisor, ELT_WATER, ELT_FIRE, 15); ) SPELL summon-partner : "#A23" = LET level = 2 school = ASTRAL IN (MANA 30, CASTTIME 2000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, REQUIRE is_married(caster), REQUIRE is_equipped(caster, "WeddingRing")) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); IF (failed (partner (caster))) THEN message (caster, "You call out for your partner, but there is no response."); ELSE (message (caster, "You call out for " + (name_of (partner (caster))) + "."); message (partner(caster), name_of(caster) + " is calling for your aid!"); sfx(partner(caster), 2, 0); WAIT (max (5000, 30000 - (spellpower * 60))); IF (failed (partner (caster))) THEN message (caster, "Your partner has abandoned you."); ELSE IF (is_dead (partner (caster))) THEN message (caster, "Something seems to have happened to " + (name_of(partner(caster))) + "."); ELSE (sfx(location(partner(caster)), SFX_TELEPORT, 0); dest = awayfrom(location(caster), random_dir(1), 1); warp(partner(caster), dest); sfx(dest, SFX_TELEPORT, 0); ) ) #-------------------------------------------------------------------------------- # Level 1 (magic level 2) #-------------------------------------------------------------------------------- LOCAL SPELL summon-cow : "#A32" = LET level = 1 school = ASTRAL IN (MANA 33, CASTTIME 20000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(1); CALL summon_spell(1021, 1 + spellpower / 120, 5000 - (spellpower * 9), spellpower * 400, 2); LOCAL SPELL summon-bats : "#kalbalark" = LET level = 1 school = ASTRAL IN (MANA 25, CASTTIME 20000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["BatTeeth", "BatWing", "BatTeeth", "BatWing", "BatTeeth", "BatWing", "BatTeeth", "BatWing", "BatTeeth", "BatWing", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(2); mob = 1017; IF(check_status_change(caster,200)) THEN mob = 1021; CALL summon_spell(mob, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 5), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); #-------------------------------------------------------------------------------- # Level 2 (magic level 3) #-------------------------------------------------------------------------------- LOCAL SPELL summon-whiteghost : "#kalshiro" = LET level = 2 school = ASTRAL IN (MANA 25, CASTTIME 30000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["YggdrasilHerb", "YggdrasilHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(10); CALL summon_spell(1119, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 5), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); LOCAL SPELL summon-cobaltghost : "#kalbaoi" = LET level = 2 school = ASTRAL IN (MANA 25, CASTTIME 30000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["CobaltHerb", "CobaltHerb", "CobaltHerb", "CobaltHerb", "CobaltHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(10); CALL summon_spell(1120, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 10), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); LOCAL SPELL summon-mauveghost : "#kaliziorn" = LET level = 2 school = ASTRAL IN (MANA 25, CASTTIME 30000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["MauveHerb", "MauveHerb", "MauveHerb", "MauveHerb", "MauveHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL gain_xp(10); CALL summon_spell(1121, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 10), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); LOCAL SPELL summon-alizaringhost : "#kalizeden" = LET level = 2 school = ASTRAL IN (MANA 25, CASTTIME 30000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS ["AlizarinHerb", "AlizarinHerb", "AlizarinHerb", "AlizarinHerb", "AlizarinHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL gain_xp(10); CALL summon_spell(1122, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 10), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); LOCAL SPELL summon-gambogeghost : "#kalambodge" = LET level = 2 school = ASTRAL IN (MANA 25, CASTTIME 30000, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level, COMPONENTS [5 * "GambogeHerb", "Root"]) => EFFECT CALL adjust_spellpower(school); CALL default_effect(); CALL gain_xp(10); CALL summon_spell(1123, 1 + ((sqrt(spellpower) + (spellpower / 15)) / 10), 5000 - (spellpower * 5), 10000 + (spellpower * 50), 1); #-------------------------------------------------------------------------------- # Level 4 spells #-------------------------------------------------------------------------------- SPELL shroud : "#N40" = LET level = 4 school = NATURE IN (MANA 40, CASTTIME 400, REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level) => EFFECT CALL default_effect(); shroud(caster, 0x04); SPELL teleport (destination : STRING) : "#A40" = LET level = 4 school = ASTRAL IN (MANA 80, CASTTIME 400, # COMPONENT ["EtherEssence"], # CATALYST ["TeleportCrystal"], REQUIRE skill(caster, MAGIC) > level, REQUIRE skill(caster, school) > level) => EFFECT CALL default_effect(); WAIT 1000 + (200000 / (spellpower + 10)); sfx(location(caster), SFX_TELEPORT, 200); warp(caster, random_location(anchor(destination))); sfx(caster, SFX_TELEPORT, 200); #-------------------------------------------------------------------------------- # Debug keywords #-------------------------------------------------------------------------------- SPELL debug : "debug" = REQUIRE DEBUG => EFFECT message (caster, "FLAGS: " + "drank=" + ((script_int(caster, "MAGIC_FLAGS") & 1) > 0) + ", " + "Kmseed=" + ((script_int(caster, "MAGIC_FLAGS") & 2) > 0) + ", " + "touched-mseed=" + ((script_int(caster, "MAGIC_FLAGS") & 4) > 0) + ", " + "mseed-max=" + ((script_int(caster, "MAGIC_FLAGS") & 8) > 0) + ", " + "Kauldsbel=" + ((script_int(caster, "MAGIC_FLAGS") & 16) > 0) + ", " + "Kwyara=" + ((script_int(caster, "MAGIC_FLAGS") & 32) > 0) + ", " + "Ksagatha=" + ((script_int(caster, "MAGIC_FLAGS") & 64) > 0) + ", " + "Kmpotion=" + ((script_int(caster, "MAGIC_FLAGS") & 128) > 0) + ", " + "mseed-rumour=" + ((script_int(caster, "MAGIC_FLAGS") & 256) > 0) + ", " + "Kcuttree=" + ((script_int(caster, "MAGIC_FLAGS") & 512) > 0) + ", " + "cut=" + ((script_int(caster, "MAGIC_FLAGS") & 1024) > 0) + ", " + "Kdruidtree=" + ((script_int(caster, "MAGIC_FLAGS") & 2048) > 0) + ", " + "Kimp=" + ((script_int(caster, "MAGIC_FLAGS") & 4096) > 0) + ", " + "Koldwiz=" + ((script_int(caster, "MAGIC_FLAGS") & 8192) > 0) + ", " + "made-conc=" + ((script_int(caster, "MAGIC_FLAGS") & 16384) > 0) + ", " + "elanore-omar=" + ((script_int(caster, "MAGIC_FLAGS") & 32768) > 0)); message (caster, "EXP: " + (script_int(caster, "MAGIC_EXPERIENCE") & 0xffff) + ", lastspell=" + ((script_int(caster, "MAGIC_EXPERIENCE") >> 16) & 0xff) + ", healexp=" + ((script_int(caster, "MAGIC_EXPERIENCE") >> 24) & 0xff)); message (caster, "STATUS: " + "auldsbel:" + (script_int(caster, "QUEST_MAGIC") & 0x1f) + "," + ((script_int(caster, "QUEST_MAGIC") >> 5) & 0x7) + ", " + "dt/mb:" + ((script_int(caster, "QUEST_MAGIC") >> 8) & 0xf) + ", " + "s-unhappy:" + ((script_int(caster, "QUEST_MAGIC") >> 12) & 0xf) + ", " + "sagatha:" + ((script_int(caster, "QUEST_MAGIC") >> 16) & 0xff) + ", " + "swords:" + ((script_int(caster, "QUEST_MAGIC") >> 24) & 0xff) + ", " + "imp:" + ((script_int(caster, "QUEST_MAGIC2") >> 0) & 0xf) + ", " + "elanore:" + ((script_int(caster, "QUEST_MAGIC2") >> 4) & 0xf) + ", " + "elanore-sub:" + ((script_int(caster, "QUEST_MAGIC2") >> 12) & 0xf) + ", " + "wyara:" + ((script_int(caster, "QUEST_MAGIC2") >> 8) & 0xf)); PROCEDURE debug_xmod(name, mask, shift, gain) = value = ((script_int(caster, name) >> shift) & mask) + gain; IF (value < 0) THEN value = 0; IF (value > mask) THEN value = mask; CALL set_var(name, mask, shift, value); PROCEDURE debug_mod(name, delta) = IF (name = "mexp") THEN CALL debug_xmod("MAGIC_EXPERIENCE", 0xffff, 0, delta); ELSE IF (name = "lastspell") THEN CALL debug_xmod("MAGIC_EXPERIENCE", 0xff, 16, delta); ELSE IF (name = "healexp") THEN CALL debug_xmod("MAGIC_EXPERIENCE", 0xff, 24, delta); ELSE IF (name = "drank") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 0, delta); ELSE IF (name = "Kmseed") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 1, delta); ELSE IF (name = "touched-mseed") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 2, delta); ELSE IF (name = "mseed-max") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 3, delta); ELSE IF (name = "Kauldsbel") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 4, delta); ELSE IF (name = "Kwyara") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 5, delta); ELSE IF (name = "Ksagatha") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 6, delta); ELSE IF (name = "Kmpotion") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 7, delta); ELSE IF (name = "mseed-rumour") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 8, delta); ELSE IF (name = "Kcuttree") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 9, delta); ELSE IF (name = "cut") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 10, delta); ELSE IF (name = "Kdruidtree") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 11, delta); ELSE IF (name = "Kimp") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 12, delta); ELSE IF (name = "oldwiz") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 13, delta); ELSE IF (name = "made-conc") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 14, delta); ELSE IF (name = "elanore-omar") THEN CALL debug_xmod("MAGIC_FLAGS", 0x1, 15, delta); ELSE IF (name = "auldsbel") THEN CALL debug_xmod("QUEST_MAGIC", 0x1f, 0, delta); ELSE IF (name = "Qauldsbel") THEN CALL debug_xmod("QUEST_MAGIC", 0x7, 5, delta); ELSE IF (name = "dt") THEN CALL debug_xmod("QUEST_MAGIC", 0x3, 10, delta); ELSE IF (name = "mb") THEN CALL debug_xmod("QUEST_MAGIC", 0x3, 8, delta); ELSE IF (name = "s-unhappy") THEN CALL debug_xmod("QUEST_MAGIC", 0xff, 12, delta); ELSE IF (name = "sagatha") THEN CALL debug_xmod("QUEST_MAGIC", 0xff, 16, delta); ELSE IF (name = "swords") THEN CALL debug_xmod("QUEST_MAGIC", 0xff, 24, delta); ELSE IF (name = "imp") THEN CALL debug_xmod("QUEST_MAGIC2", 0xf, 0, delta); ELSE IF (name = "elanore") THEN CALL debug_xmod("QUEST_MAGIC2", 0xf, 4, delta); ELSE IF (name = "wyara") THEN CALL debug_xmod("QUEST_MAGIC2", 0xf, 8, delta); ELSE IF (name = "elanore-sub") THEN CALL debug_xmod("QUEST_MAGIC2", 0xf, 12, delta); ELSE message(caster, "Unknown"); SPELL debug-up1 (name : STRING) : "debug+1" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 1); SPELL debug-down1 (name : STRING) : "debug-1" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 0 - 1); SPELL debug-up16 (name : STRING) : "debug+16" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 16); SPELL debug-down16 (name : STRING) : "debug-16" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 0 - 16); SPELL debug-up256 (name : STRING) : "debug+256" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 256); SPELL debug-down256 (name : STRING) : "debug-256" = REQUIRE DEBUG => EFFECT CALL debug_mod(name, 0 - 256); SPELL debug-reset : "debug-reset" = REQUIRE DEBUG => EFFECT set_script_variable(caster, "QUEST_MAGIC", 0); set_script_variable(caster, "QUEST_MAGIC2", 0); set_script_variable(caster, "MAGIC_FLAGS", 0); set_script_variable(caster, "MAGIC_EXP", 0); #-------------------------------------------------------------------------------- # Special-purpose quasispells #-------------------------------------------------------------------------------- CONST MIN_MARRY_LEVEL = 32; NONMAGIC SILENT SPELL marriage (target : PC) : "marry" = (REQUIRE (is_in(location(caster), @("014-1.gat", 28,39) @+ (8, 6)) || is_in(location(caster), @("021-2.gat", 20,25) @+ (4, 4)) ))=> EFFECT IF target == caster # no valid target or tried to marry self? THEN ABORT; IF (level(caster) < MIN_MARRY_LEVEL) THEN (message(caster, "You must be level " + MIN_MARRY_LEVEL + " or higher to marry!"); ABORT;) IF (level(target) < MIN_MARRY_LEVEL) THEN (message(caster, "Your partner must be level " + MIN_MARRY_LEVEL + " or higher to marry!"); ABORT;) IF partner(caster) = target THEN (message(caster, "You and " + name_of(target) + " are already married."); ABORT;) IF is_married(caster) THEN (message(caster, "You are already married!"); ABORT;) IF is_married(target) THEN (message(caster, name_of(target) + " is already married."); ABORT;); IF distance(location(caster), location(target)) <> 1 THEN (message(caster, "You need to stand next to each other."); ABORT;); IF (count_item(caster, "WeddingRing") == 0 || count_item(target, "WeddingRing") == 0) THEN (message(caster, "You must both be wearing your wedding rings!"); ABORT;) script_target = target; { announce @caster_name$ + " is asking " + strcharinfo(0) + " for marriage.", 2; mes @caster_name$ + " wishes to marry you."; mes "Do you accept?"; next; menu "Yes, I do!", L_yes, "No.", -; close; L_yes: if marriage(@caster_name$) announce @caster_name$ + " and " + strcharinfo(0) + " are now married!", 0; close; } IF not (is_married(caster)) THEN message(caster, name_of(target) + " turned down your marriage offer."); # SPELL change-hair-colour (colour : STRING) : "trapa" = # (MANA 20) => EFFECT IF colour = "nworbl" # THEN x = 0; # light brown # ELSE IF colour = "der" # THEN x = 1; # red # ELSE IF colour = "neerg" # THEN x = 2; # green # ELSE IF colour = "elprup" # THEN x = 3; # purple # ELSE IF colour = "yerg" # THEN x = 4; # grey # ELSE IF colour = "wolley" # THEN x = 5; # yellow # ELSE IF colour = "eulb" # THEN x = 6; # blue # ELSE IF colour = "nwrob" # THEN x = 7; # brown # ELSE IF colour = "elpropl" # THEN x = 8; # light purple # ELSE IF colour = "elpropd" # THEN x = 9; # dark purple # ELSE x = random(10); # sfx(caster, 2, 0); # set_hair_colour(caster, x); # SPELL trick-or-treat : "trick-or-treat" = # (CASTTIME 30000, MANA 20, # COMPONENTS [ "BugLeg" ]) => EFFECT IF (random(2)) # THEN (sfx(caster, 2, 0); # FOR i = 0 TO random(10) DO # drop_item_for (random_location(rbox(location(caster), 5)), # "Candy", 1, 10000 + random(10000), caster, 3000); # FOR i = 0 TO random(10) DO # drop_item_for (random_location(rbox(location(caster), 5)), # "ChocolateBar", 1, 10000 + random(10000), caster, 3000); # ) # ELSE (sfx(caster, 5, 0); # message(caster, "No treat for you!"); # spawn(rbox(location(caster), 3), caster, 1010, 0, 1 + random(3), 10000 + random(20000)); # FOREACH MOB target IN rbox(location(caster), 5) DO # (sfx(target, 5, 0); # aggravate(target, 0, caster);)) LOCAL SPELL mouboo-groan : "#g" = (MANA 1, REQUIRE name_of(caster) = "MOUBOOTAUR") => EFFECT FOREACH PC p IN rbox(location(caster), 200) DO distance = rdistance(location(caster), location(p)); IF (distance < 15) THEN message(p, "The moubootaur's groaning rings in your ears!"); ELSE IF (distance < 70) THEN message(p, "You hear a loud groaning noise, not far away..."); ELSE message(p, "You hear an odd groaning noise in the distance..."); LOCAL SPELL mouboo-smell : "#s" = (MANA 1, REQUIRE name_of(caster) = "MOUBOOTAUR") => EFFECT WAIT 30000; FOREACH PC p IN rbox(location(caster), 30) DO message(p, "You notice a strange smell all around you."); PROCEDURE hug_tree(target) = IF (target = "" || target = "tree" || target = "tree*" || target = "Tree" || target = "Tree*" || target = "druid" || target = "druid*" || target = "Druid" || target = "Druid*") THEN { set @flag, 2; callfunc "QuestTreeTrigger"; }; NONMAGIC SPELL hug0 (target : STRING) : "hug" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); NONMAGIC SPELL hug1 (target : STRING) : "*hug*" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); NONMAGIC SPELL hug2 (target : STRING) : "*hug" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); NONMAGIC SPELL hug3 (target : STRING) : "hugs" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); NONMAGIC SPELL hug4 (target : STRING) : "*hugs*" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); NONMAGIC SPELL hug5 (target : STRING) : "*hugs" = REQUIRE ((rdistance(location(caster), location(npc("#DruidTree0#_M"))) <= 1 || rdistance(location(caster), location(npc("#DruidTree1#_M"))) <= 1)) => EFFECT CALL hug_tree(target); #-------------------------------------------------------------------------------- # Teleport anchors #-------------------------------------------------------------------------------- TELEPORT-ANCHOR tulimshar : "tulimshar" = @("001-1.gat", 43, 66) @+ (3, 3); TELEPORT-ANCHOR hurnscald : "hurnscald" = @("009-1.gat", 55, 37) @+ (3, 3); TELEPORT-ANCHOR nivalis : "nivalis" = @("020-1.gat", 75, 63) @+ (19, 12); TELEPORT-ANCHOR wizardhut : "##00" = @("013-1.gat", 41, 92) @+ (3, 3); TELEPORT-ANCHOR pachua : "##01" = @("006-1.gat", 22, 101) @+ (3, 3); TELEPORT-ANCHOR desert : "##02" = @("005-1.gat", 160, 64) @+ (5, 5); TELEPORT-ANCHOR forest : "##03" = @("015-1.gat", 35, 35) @+ (40, 40); TELEPORT-ANCHOR snakecave : "##04" = @("011-4.gat", 50, 75) @+ (3, 3); TELEPORT-ANCHOR dimondscove : "##05" = @("010-2.gat", 23, 79) @+ (3, 3);