summaryrefslogblamecommitdiff
path: root/conf/magic.conf
blob: e0fb308cefd71434e9e67059352ada42c817f649 (plain) (tree)






























                                     



                            
                            











                                             







                                                                                        
                                
                             
                                        





                                                          
                                
                             
                                        


























                                                                                                                                                                         
                                







                                                                                    

                                             
                     
                                            



                                                                                                            
 


































                                                                                                                             
                                          








                                                                                               
 






                                                               
                                                         



                                                                                                       
                                                         








                                                                                                       

                                                             
                                                                                        
                                                      
























                                                                                                                
                                          









                                                                      
                                          









                                                          
                                          









                                                           
                                          
















                                                                           






















                                                                                                                                                           















































                                                                                                                                          
                                      


















                                                                                                                              
                                           













                                                                                                                        


                                                                        



















                                                                                            
                                      










                                                                                      
                                            
                                     
                                           


                                                                                                                     
                                             









                                                   
                                          









                                                                                                               
                                          









                                                                                                               
                                          
























































                                                                                                                
                                        


























                                                                                                    
                                        







                                                                                 

                                                                           




































                                                                                                                      
                      




                                                                                          










































                                                                                                                                                       
 









                                                                                  
                                                                                    









                                                                                 
# 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 ASTRAL	= 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

# Schools of magic
CONST SC_HALT_REGENERATE	= 195
CONST SC_FLYING_BACKPACK	= 196
CONST SC_MBARRIER		= 197
CONST SC_HASTE			= 198
CONST SC_PHYS_SHIELD		= 199

# Special effects
CONST SFX_DEFAULT	= 10
CONST SFX_SUMMON_START	= 21
CONST SFX_SUMMON_FIRE	= 22
CONST SFX_TELEPORT	= 24
CONST SFX_BARRIER	= 10
CONST SFX_UNBARRIER	= 10
CONST SFX_HEAL		= 3

CONST MAX_RAIN_SPELL_RADIUS = 20

# Default sfx on caster
PROCEDURE default_effect() =
          sfx(caster, school - MAGIC + 2, 0);

PROCEDURE sfx_generic(target) =
          sfx(target, SFX_DEFAULT, 0);

# Increase spellpower by school and general magic skill
PROCEDURE adjust_spellpower(school) =
          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?

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);
          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);
          injure(caster, target, d, 0);

PROCEDURE melee_damage(target, damage, dmgplus) =
          CALL attack_check(target);
          d = damage + random(dmgplus);
          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, 0, attack_animation);

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);


#--------------------------------------------------------------------------------
# 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 lesser-heal (target : STRING) : "#imx" =
      LET level = 0
          school = LIFE
      IN (MANA 5, CASTTIME 400,
          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"]))
          => EFFECT CALL adjust_spellpower(school);
                    IF failed(pc(target))
                      THEN target = caster; # quest handling goes here
                      ELSE target = pc(target);
                    CALL heal(target, 200);


SPELL flare-dart : "#fla" =
      LET level = 0
          school = WAR
      IN (MANA 15, 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_bonus = 5 + level(caster) / 3;
                    CALL install_attack_spell(3 + spellpower / 30,
                                         1200,
                                         4, 31);

             ATTRIGGER CALL attack_check(target);
                       CALL elt_damage (target, damage, damage_bonus, ELT_WATER, ELT_FIRE, 15);

SPELL magic-blade : "#mbl" =
      LET level = 0
          school = WAR
      IN (MANA 12, 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));
              | 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));
             )
                    
SPELL aggravate : "#qaw" =
      LET level = 0
          school = NATURE
      IN (MANA 5, CASTTIME 300,
          REQUIRE skill(caster, MAGIC) > level)
                    => 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" =
      LET level = 0
          school = ASTRAL
      IN (MANA 20, CASTTIME 3000,
          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);


#--------------------------------------------------------------------------------
# Level 1 spells
#--------------------------------------------------------------------------------

SPELL make-arrows : "#mkarrows" =
      LET level = 1
          school = TRANSMUTE
      IN (MANA 20, CASTTIME 2000,
          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);

SPELL make-shirt : "#mkshirt" =
      LET level = 1
          school = TRANSMUTE
      IN (MANA 20, CASTTIME 2000,
          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);

SPELL make-tanktop : "#mktanktop" =
      LET level = 1
          school = TRANSMUTE
      IN (MANA 20, CASTTIME 2000,
          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);

SPELL make-short-tanktop : "#mkshorttanktop" =
      LET level = 1
          school = TRANSMUTE
      IN (MANA 20, CASTTIME 2000,
          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);

SPELL lightning-strike : "#kig" =
      LET level = 1
          school = WAR
      IN (MANA 25, 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,
                                              3000,
                                              8, 31);
             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;
                            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));

SPELL fire-ball : "#pof" =
      LET level = 1
          school = WAR
      IN (MANA 30, CASTTIME 1000,
          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);
                            )

SPELL magic-knuckles (target : PC) : "#iom" =
      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(target);
                    CALL install_melee_spell(10 + spellpower / 12, 1000, 0);
             ATTRIGGER CALL melee_damage(target, 40 + (str / 2) + spellpower / 20, 5 + str);

SPELL flying-backpack (target : PC) : "#uuy" =
      LET level = 1
          school = NATURE
      IN (MANA 12, CASTTIME 1000,
          REQUIRE skill(caster, MAGIC) > level,
          REQUIRE skill(caster, school) > level,
          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.");
         ATEND message (target, "Your backpack is no longer levitating.");
               sfx(target, 2, 0);


SPELL protect (target : PC) : "#ism" =
      LET level = 1
          school = NATURE
      IN (MANA 18, CASTTIME 1000,
          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 / 12), 0, 0, 0, 5000 + (spellpower * 500));
                message (target, "You feel more protected.");
         ATEND message (target, "You feel less protected.");
               sfx(target, 111, 0);


LOCAL SPELL rain : "#flosh" =
      LET level = 1
          school = NATURE
      IN (MANA 20, 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();
                range = min(MAX_RAIN_SPELL_RADIUS, 3 + spellpower / 30);
                area = rbox(location(caster), range);
                FOR i = 0 TO spellpower DO (
                    FOR j = 0 TO spellpower / 100 DO (
                        location = random_location(area);
                        sfx(location, 25, 0);
                        FOREACH TARGET target IN rbox(location, 1) DO
                            IF element(target) = ELT_FIRE
                            THEN injure(caster, target, 5 + random(5 + spellpower / 10), 0);
                    )
                    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" =
      LET level = 1
          school = NATURE
      IN (MANA 18, CASTTIME 1000,
          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, 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));
                message (target, "You are surrounded by a magical barrier.");
         ATEND message (target, "Your magical barrier disspiates.");
               sfx(target, SFX_UNBARRIER, 0);


LOCAL SPELL summon-scorps : "#kbms" =
      LET level = 1
          school = ASTRAL
      IN (MANA 25, CASTTIME 3000,
          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);

LOCAL SPELL summon-red-scorps : "#kbmq" =
      LET level = 1
          school = ASTRAL
      IN (MANA 30, CASTTIME 3000,
          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);


SPELL detect-players : "#ewm" =
      LET level = 1
          school = MAGIC
      IN (MANA 10, 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
                       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 lay-on-hands (target : STRING) : "#loh" =
      LET level = 1
          school = LIFE
      IN (MANA 8, CASTTIME 400,
          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 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);

                    IF payment < available
                    THEN power = needed;
                    ELSE (payment = available;
                          power = (available * 200) / pay_fraction;
                    )
                         
                    instaheal(caster, 0 - payment, 0);
                    CALL quickheal(target, power);
                    status_change(caster, SC_HALT_REGENERATE, 0, 0, 0, 0, 10000);

#--------------------------------------------------------------------------------
# Level 2 spells
#--------------------------------------------------------------------------------

SPELL summon-partner : "#aid" = 
      LET level = 2
          school = ASTRAL
      IN (MANA 30, CASTTIME 2000,
          REQUIRE skill(caster, MAGIC) > level,
          REQUIRE skill(caster, school) > level,
          REQUIRE is_married(caster))
	=> 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 (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 4 spells
#--------------------------------------------------------------------------------

SPELL shroud : "#aw" = 
      LET level = 4
          school = ASTRAL
      IN (MANA 40, CASTTIME 400,
          REQUIRE skill(caster, MAGIC) > level,
          REQUIRE skill(caster, school) > level)
	=> EFFECT CALL default_effect();
                  shroud(caster, 0x04);

#--------------------------------------------------------------------------------
# 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)))=>
       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 have 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.");