summaryrefslogtreecommitdiff
path: root/conf
diff options
context:
space:
mode:
Diffstat (limited to 'conf')
-rw-r--r--conf/magic.conf613
1 files changed, 474 insertions, 139 deletions
diff --git a/conf/magic.conf b/conf/magic.conf
index 390df589..b56fc1d1 100644
--- a/conf/magic.conf
+++ b/conf/magic.conf
@@ -23,6 +23,7 @@ CONST ELT_GHOST = 8
CONST ELT_UNDEAD = 9
# Schools of magic
+CONST SC_HIDE = 194
CONST SC_HALT_REGENERATE = 195
CONST SC_FLYING_BACKPACK = 196
CONST SC_MBARRIER = 197
@@ -34,12 +35,24 @@ 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_BARRIER = 10
CONST SFX_UNBARRIER = 10
CONST SFX_HEAL = 3
CONST MAX_RAIN_SPELL_RADIUS = 20
+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
+
# Default sfx on caster
PROCEDURE default_effect() =
sfx(caster, school - MAGIC + 2, 0);
@@ -47,11 +60,73 @@ PROCEDURE default_effect() =
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, gain) = # `gain' influences the likelihood of an increase
+ last_heal_xp = (script_int(caster, SCRIPT_XP) >> SCRIPT_HEALSPELL_SHIFT) & SCRIPT_HEALSPELL_MASK;
+ IF (target <> caster
+ && value > (20 + 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);
+ )
+
+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) =
+ score = experience + random(min(spellpower, (experience / 3) + 1));
+ IF (score >= difficulty)
+ THEN create_item(caster, good_item, count);
+ ELSE (
+ 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;
- IF ((school = LIFE) && (target = partner(caster)))
- THEN spellpower = spellpower + 200; # Do something for wedding rings, too?
+ # Below, we adjust by special items
+ IF ((school = LIFE || school = NATURE) && (target = partner(caster)))
+ THEN (spellpower = spellpower + 200;
+ IF is_equipped(caster, "WeddingRing")
+ THEN spellpower = spellpower + 50;
+ IF is_equipped(target, "WeddingRing")
+ THEN spellpower = spellpower + 50;)
PROCEDURE heal(target, max_heal) =
CALL default_effect();
@@ -89,6 +164,9 @@ PROCEDURE elt_damage(target, damage, dmgplus, bonus_elt, malus_elt, effect) =
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);
@@ -115,162 +193,259 @@ PROCEDURE summon_spell(mob_id, count, delay, lifetime, control_level) =
# Level 0 spells
#--------------------------------------------------------------------------------
-#SPELL reset : "#reset" =
-# EFFECT { skill 340, 0;
-# skill 341, 0;
-# skill 342, 0;
-# skill 343, 0;
-# skill 344, 0;
-# skill 345, 0;
-# }
+SPELL transmute-wood-to-mouboo : "#T00" =
+ LET level = 0
+ school = TRANSMUTE
+ IN (MANA 5, CASTTIME 4000,
+ REQUIRE skill(caster, MAGIC) > level,
+ REQUIRE skill(caster, school) > level,
+ COMPONENTS ["RawLog"])
+ => EFFECT CALL adjust_spellpower(school);
+ CALL default_effect();
+ CALL create_item("MoubooFigurine", 1, "WarpedLog", 40);
+ CALL gain_xp(1);
+
+SPELL make-sulphur : "#T01" =
+ LET level = 0
+ school = TRANSMUTE
+ IN (MANA 4, CASTTIME 4000,
+ REQUIRE skill(caster, MAGIC) > level,
+ REQUIRE skill(caster, school) > level,
+ COMPONENTS ["PileOfAsh"])
+ => EFFECT CALL adjust_spellpower(school);
+ CALL default_effect();
+ CALL create_item("SulphurPowder", 1 + spellpower / 100 + (random(max(1, 800 - spellpower)) / 180), "PileOfAsh", 50);
+ CALL gain_xp(1);
-SPELL lesser-heal (target : STRING) : "#imx" =
+SPELL lesser-heal (target : STRING) : "#L00" =
LET level = 0
school = LIFE
- IN (MANA 5, CASTTIME 400,
+ 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 / 50)),
- (COMPONENTS ["MaggotSlime"] OR COMPONENTS ["BugLeg"]))
+ rdistance(location(caster), location(pc(target))) < 2 + (spellpower / 100)),
+ (COMPONENTS ["LifeStone"]))
=> EFFECT CALL adjust_spellpower(school);
+ CALL default_effect();
IF failed(pc(target))
- THEN target = caster; # quest handling goes here
+ THEN (IF ((target = "mouboo" || target = "Mouboo")
+ && rdistance(location(caster), location(npc("Mouboo"))) < 2 + (spellpower / 100))
+ THEN { mes "Your spell seems to have no effect on the mouboo."; next; close; }
+ ELSE target = caster;)
ELSE target = pc(target);
+ CALL gain_heal_xp(100, 1); # report half values for non-instaheal
CALL heal(target, 200);
+ CALL gain_xp(1);
-SPELL flare-dart : "#fla" =
+SPELL flare-dart : "#W00" =
LET level = 0
school = WAR
- IN (MANA 15, CASTTIME 500,
+ IN (MANA 10, CASTTIME 500,
REQUIRE skill(caster, MAGIC) > level,
(REQUIRE skill(caster, school) > 2 OR COMPONENTS ["SulphurPowder"]))
=> EFFECT CALL adjust_spellpower(school);
CALL default_effect();
- damage = min(40 + skill(caster, school) * 20,
- 10 + spellpower);
+ damage = 5 * sqrt(spellpower);
damage_bonus = 5 + level(caster) / 3;
- CALL install_attack_spell(3 + spellpower / 30,
+ CALL install_attack_spell(3 + spellpower / 50,
1200,
4, 31);
-
+ CALL gain_xp(1);
ATTRIGGER CALL attack_check(target);
CALL elt_damage (target, damage, damage_bonus, ELT_WATER, ELT_FIRE, 15);
-SPELL magic-blade : "#mbl" =
+
+SPELL magic-blade : "#W01" =
LET level = 0
school = WAR
- IN (MANA 12, CASTTIME 500,
+ IN (MANA 9, CASTTIME 500,
REQUIRE skill(caster, MAGIC) > level)
=> ( COMPONENTS ["SharpKnife"] =>
EFFECT CALL adjust_spellpower(WAR);
CALL default_effect();
- CALL install_melee_spell(10 + spellpower / 10, 900, 30);
- ATTRIGGER CALL melee_damage(target, 60 + spellpower / 20, 5 + str(caster));
+ CALL install_melee_spell(10 + spellpower / 15, 1200, 30);
+ CALL gain_xp(1);
+ ATTRIGGER CALL melee_damage(target, 60, 5 + str(caster));
| COMPONENTS ["Knife"] =>
EFFECT CALL adjust_spellpower(WAR);
CALL default_effect();
- CALL install_melee_spell(10 + spellpower / 10, 900, 30);
- ATTRIGGER CALL melee_damage(target, 40 + spellpower / 20, 5 + str(caster));
+ CALL install_melee_spell(10 + spellpower / 15, 1200, 30);
+ CALL gain_xp(1);
+ ATTRIGGER CALL melee_damage(target, 40, 5 + str(caster));
)
-SPELL aggravate : "#qaw" =
+SPELL aggravate : "#N00" =
LET level = 0
school = NATURE
- IN (MANA 5, CASTTIME 300,
+ IN (MANA 3, CASTTIME 1000,
REQUIRE skill(caster, MAGIC) > level)
- => EFFECT CALL adjust_spellpower(school);
+ => EFFECT CALL adjust_spellpower(school);
CALL default_effect();
FOREACH MOB target IN rbox(location(caster), 1 + spellpower / 20) DO
(CALL sfx_generic(target);
aggravate(target, 0, caster);)
-LOCAL SPELL summon-maggots : "#kbm" =
+LOCAL SPELL summon-maggots : "#A00" =
LET level = 0
school = ASTRAL
- IN (MANA 20, CASTTIME 3000,
+ IN (MANA 21, CASTTIME 20000,
REQUIRE skill(caster, MAGIC) > level,
COMPONENTS ["MaggotSlime"])
=> EFFECT CALL adjust_spellpower(school);
- CALL summon_spell(1002, 3 + spellpower / 15, 5000 - (spellpower * 10), spellpower * 500, 1);
+ 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 : "#mkarrows" =
+SPELL make-arrows : "#T10" =
LET level = 1
school = TRANSMUTE
- IN (MANA 20, CASTTIME 2000,
+ 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();
- create_item(caster, "Arrow", 1 + spellpower / 15);
+ CALL create_item("Arrow", 1 + spellpower / 40 + (random(max(1, 800 - spellpower)) / 80), "WarpedLog", 500);
+ CALL gain_xp(1);
-SPELL make-shirt : "#mkshirt" =
+SPELL make-shirt : "#T11" =
LET level = 1
school = TRANSMUTE
- IN (MANA 20, CASTTIME 2000,
+ 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();
- create_item(caster, "CottonShirt", 1);
+ CALL create_item("CottonShirt", 1, "CottonCloth", 425);
+ CALL gain_xp(2);
-SPELL make-tanktop : "#mktanktop" =
+SPELL make-tanktop : "#T12" =
LET level = 1
school = TRANSMUTE
- IN (MANA 20, CASTTIME 2000,
+ 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();
- create_item(caster, "TanktopWhite", 1);
+ CALL create_item("WhiteTankTop", 1, "CottonCloth", 350);
+ CALL gain_xp(2);
-SPELL make-short-tanktop : "#mkshorttanktop" =
+SPELL make-short-tanktop : "#T13" =
LET level = 1
school = TRANSMUTE
- IN (MANA 20, CASTTIME 2000,
+ 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();
- create_item(caster, "ShortTanktopWhite", 1);
+ CALL create_item("WhiteShortTankTop", 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 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 if_then_else(failed(pc(target)), 1,
+ (rdistance(location(caster),
+ location(pc(target))) < 2 + (spellpower / 50))
+ && not (running_status_update(pc(target), SC_HALT_REGENERATE))
+ ))
+ => EFFECT CALL adjust_spellpower(school);
+ 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 (target = caster;
+ needed = max_hp(target) - hp(target);
+ ))
+ 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);
+ CALL quickheal(target, power);
+ status_change(caster, SC_HALT_REGENERATE, 0, 0, 0, 0, 10000);
+ IF ((caster <> target) && (payment >= 100))
+ THEN CALL gain_xp(min(4, payment / 100));
-SPELL lightning-strike : "#kig" =
+SPELL lightning-strike : "#W10" =
LET level = 1
school = WAR
- IN (MANA 25, CASTTIME 1000,
+ 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 = min(100 + skill(caster, school) * 50,
- 50 + spellpower * 2);
- damage_bonus = level(caster) + spellpower;
- CALL install_attack_spell(1 + spellpower / 60,
+ 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 (
-# message(caster, "found-rain at " + s.area + " vs. " + location(caster) + " inside: " + is_in(location(caster), s.area));
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;
);
-# message(caster, "in-rain : " + in_rain);
IF in_rain & 1
THEN (# caster standing in the rain? This is going to be fun.
used = 0;
@@ -284,32 +459,41 @@ SPELL lightning-strike : "#kig" =
) ELSE
CALL elt_damage (target, damage, damage_bonus, ELT_EARTH, ELT_WIND, 17 + random(3));
-SPELL fire-ball : "#pof" =
+LOCAL SPELL arrow-hail : "#W11" =
LET level = 1
school = WAR
- IN (MANA 30, CASTTIME 1000,
+ IN (MANA 25, CASTTIME 5000,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
- (REQUIRE skill(caster, school) > 3 OR 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);
- )
+ 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();
+ range = 7;
+ area = rbox(awayfrom(location(caster), dir(caster), 1 + range), range);
+ damage = 100;
+ damage_bonus = spellpower / 5;
+ CALL gain_xp(2);
+ FOR i = 0 TO spellpower / 8 DO (
+ FOR j = 0 TO 3 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 - min(spellpower / 3, 180)) + random(50) + random(50);
+ );
-SPELL magic-knuckles (target : PC) : "#iom" =
+SPELL magic-knuckles : "#W12" =
LET level = 1
school = WAR
IN (MANA 20, CASTTIME 500,
@@ -318,16 +502,17 @@ SPELL magic-knuckles (target : PC) : "#iom" =
(REQUIRE skill(caster, school) > 3 OR COMPONENTS ["Beer"]))
=>
EFFECT CALL adjust_spellpower(WAR);
- str = str(target);
- CALL install_melee_spell(10 + spellpower / 12, 1000, 0);
- ATTRIGGER CALL melee_damage(target, 40 + (str / 2) + spellpower / 20, 5 + str);
+ 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) : "#uuy" =
+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();
@@ -335,14 +520,14 @@ SPELL flying-backpack (target : PC) : "#uuy" =
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) : "#ism" =
+SPELL protect (target : PC) : "#N11" =
LET level = 1
school = NATURE
- IN (MANA 18, CASTTIME 1000,
+ IN (MANA 14, CASTTIME 1500,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
(REQUIRE skill(caster, school) > 3 OR COMPONENTS ["HardSpike"]),
@@ -351,27 +536,47 @@ SPELL protect (target : PC) : "#ism" =
sfx(target, 11, 0);
IF (caster <> target)
THEN CALL default_effect();
- status_change(target, SC_PHYS_SHIELD, 5 + max(15, spellpower / 12), 0, 0, 0, 5000 + (spellpower * 500));
+ status_change(target, SC_PHYS_SHIELD, 5 + max(15, spellpower / 20), 0, 0, 0, 5000 + (spellpower * 400));
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 : "#flosh" =
+LOCAL SPELL rain : "#N13" =
LET level = 1
school = NATURE
- IN (MANA 20, CASTTIME 3000,
+ IN (MANA 17, CASTTIME 3000,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
(REQUIRE skill(caster, school) > 3 OR COMPONENTS ["BottleOfWater"]))
=> EFFECT CALL adjust_spellpower(school);
CALL default_effect();
+ CALL gain_xp(1);
range = min(MAX_RAIN_SPELL_RADIUS, 3 + spellpower / 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 DO (
FOR j = 0 TO spellpower / 100 DO (
location = random_location(area);
- sfx(location, 25, 0);
+ sfx(location, SFX_RAIN, 0);
FOREACH TARGET target IN rbox(location, 1) DO
IF element(target) = ELT_FIRE
THEN injure(caster, target, 5 + random(5 + spellpower / 10), 0);
@@ -379,70 +584,62 @@ LOCAL SPELL rain : "#flosh" =
WAIT 300 - min(spellpower, 200) + random(100);
);
-SPELL happy-curse (target : PC) : "#happy" =
- LET level = 1
- school = NATURE
- IN (MANA 10, CASTTIME 1000,
- REQUIRE skill(caster, MAGIC) > level,
- REQUIRE skill(caster, school) > level,
- (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["WhiteFur"]),
- 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;);
-
-SPELL barrier (target : PC) : "#iso" =
+SPELL barrier (target : PC) : "#A10" =
LET level = 1
- school = NATURE
- IN (MANA 18, CASTTIME 1000,
+ school = ASTRAL
+ IN (MANA 16, CASTTIME 1000,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
- (REQUIRE skill(caster, school) > 3 OR COMPONENTS ["HardSpike"]),
+ (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, 30 + max(30, spellpower / 8), 0, 0, 0, 2000 + (spellpower * 200));
+ 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 disspiates.");
sfx(target, SFX_UNBARRIER, 0);
-LOCAL SPELL summon-scorps : "#kbms" =
+LOCAL SPELL summon-scorps : "#A11" =
LET level = 1
school = ASTRAL
- IN (MANA 25, CASTTIME 3000,
+ IN (MANA 33, CASTTIME 20000,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
COMPONENTS ["ScorpionStinger"])
=> EFFECT CALL adjust_spellpower(school);
CALL default_effect();
- CALL summon_spell(1003, 1 + spellpower / 30, 5000 - (spellpower * 9), spellpower * 400, 2);
+ CALL gain_xp(1);
+ CALL summon_spell(1003, 1 + spellpower / 140, 5000 - (spellpower * 9), spellpower * 400, 2);
-LOCAL SPELL summon-red-scorps : "#kbmq" =
+LOCAL SPELL summon-red-scorps : "#A12" =
LET level = 1
school = ASTRAL
- IN (MANA 30, CASTTIME 3000,
+ IN (MANA 39, CASTTIME 20000,
REQUIRE skill(caster, MAGIC) > level,
REQUIRE skill(caster, school) > level,
COMPONENTS ["RedScorpionStinger"])
=> EFFECT CALL adjust_spellpower(school);
CALL default_effect();
- CALL summon_spell(1004, 1 + spellpower / 40, 5000 - (spellpower * 8), spellpower * 350, 3);
+ CALL gain_xp(1);
+ CALL summon_spell(1004, 1 + spellpower / 230 + spellpower / 430, 5000 - (spellpower * 8), spellpower * 350, 3);
-SPELL detect-players : "#ewm" =
+SPELL detect-players : "#G10" =
LET level = 1
school = MAGIC
- IN (MANA 10, CASTTIME 300,
+ 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
+ DO IF ((target <> caster)
+ && not (running_status_update(pc(target), SC_HIDE)))
THEN (IF message <> ""
THEN message = message + ", ";
message = message + name_of (target);
@@ -453,43 +650,115 @@ SPELL detect-players : "#ewm" =
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 lay-on-hands (target : STRING) : "#loh" =
+SPELL enchant-lifestone : "#G12" =
LET level = 1
- school = LIFE
- IN (MANA 8, CASTTIME 400,
- REQUIRE hp(caster) > max_hp(caster) / 20,
+ school = MAGIC
+ IN (MANA 15, CASTTIME 4000,
REQUIRE skill(caster, MAGIC) > level,
- REQUIRE if_then_else(failed(pc(target)), 1,
- (rdistance(location(caster),
- location(pc(target))) < 2 + (spellpower / 50))
- && not (running_status_update(pc(target), SC_HALT_REGENERATE))
- ))
+ REQUIRE skill(caster, school) > level,
+ (COMPONENTS ["MaggotSlime"] OR COMPONENTS["BugLeg"]
+ OR COMPONENTS ["MauveHerb", "AlizarinHerb", "CobaltHerb", "GambogeHerb"]))
=> EFFECT CALL adjust_spellpower(school);
- IF failed(pc(target))
- THEN target = caster; # quest handling goes here
- 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);
+ CALL default_effect();
+ create_item(caster, "LifeStone", 1);
+ CALL gain_xp(1);
- IF payment < available
- THEN power = needed;
- ELSE (payment = available;
- power = (available * 200) / pay_fraction;
+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 + ".");
)
-
- instaheal(caster, 0 - payment, 0);
- CALL quickheal(target, power);
- status_change(caster, SC_HALT_REGENERATE, 0, 0, 0, 0, 10000);
+
+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);
#--------------------------------------------------------------------------------
# Level 2 spells
#--------------------------------------------------------------------------------
-SPELL summon-partner : "#aid" =
+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,
@@ -506,6 +775,8 @@ SPELL summon-partner : "#aid" =
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);
@@ -519,15 +790,29 @@ SPELL summon-partner : "#aid" =
# Level 4 spells
#--------------------------------------------------------------------------------
-SPELL shroud : "#aw" =
+SPELL shroud : "#N40" =
LET level = 4
- school = ASTRAL
+ 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 (100000 / (spellpower + 10));
+ sfx(location(caster), SFX_TELEPORT, 1);
+ warp(caster, random_location(anchor(destination)));
+ sfx(location(caster), SFX_TELEPORT, 100);
+
#--------------------------------------------------------------------------------
# Special-purpose quasispells
#--------------------------------------------------------------------------------
@@ -643,3 +928,53 @@ LOCAL SPELL mouboo-smell : "#s" =
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 : "##0" = @("013-1.gat", 41, 92) @+ (3, 3);
+TELEPORT-ANCHOR pachua : "##1" = @("006-1.gat", 22, 101) @+ (3, 3);
+TELEPORT-ANCHOR desert : "##2" = @("005-1.gat", 160, 64) @+ (5, 5);
+TELEPORT-ANCHOR forest : "##3" = @("015-1.gat", 35, 35) @+ (40, 40);
+TELEPORT-ANCHOR snakecave : "##4" = @("011-4.gat", 50, 75) @+ (3, 3);
+TELEPORT-ANCHOR dimondscove : "##5" = @("010-2.gat", 23, 79) @+ (3, 3);