Renaming bmagic files to sorcery
authorMartin Read <martin@blackswordsonics.com>
Sun, 22 Sep 2013 15:54:23 +0000 (16:54 +0100)
committerMartin Read <martin@blackswordsonics.com>
Sun, 22 Sep 2013 15:54:23 +0000 (16:54 +0100)
Makefile
bmagic.c [deleted file]
bmagic.h [deleted file]
sorcery.c [new file with mode: 0644]
sorcery.h [new file with mode: 0644]

index 82a734d..2bcf3f0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Makefile for Victrix Abyssi
 
-OBJS=bmagic.o combat.o display-nc.o main.o map.o misc.o monsters.o mon2.o objects.o permobj.o permons.o pmon2.o rng.o u.o vector.o
+OBJS=combat.o display-nc.o main.o map.o misc.o monsters.o mon2.o objects.o permobj.o permons.o pmon2.o rng.o sorcery.o u.o vector.o
 
 include dirs.mk
 include features.mk
@@ -48,10 +48,10 @@ objects.o: objects.c victrix-abyssi.h
 
 monsters.o: monsters.c victrix-abyssi.h monsters.h
 
-mon2.o: mon2.c victrix-abyssi.h bmagic.h monsters.h
+mon2.o: mon2.c victrix-abyssi.h sorcery.h monsters.h
 
 vector.o: vector.c victrix-abyssi.h
 
-bmagic.o: bmagic.c victrix-abyssi.h bmagic.h
+sorcery.o: sorcery.c victrix-abyssi.h sorcery.h
 
 # vim:ts=8:sw=8:noexpandtab
diff --git a/bmagic.c b/bmagic.c
deleted file mode 100644 (file)
index 8486216..0000000
--- a/bmagic.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*! \file sorcery.c 
- *  \brief evil magic used by monsters
- */
-
-/* Copyright 2005-2012 Martin Read
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "victrix-abyssi.h"
-#include "bmagic.h"
-#include "monsters.h"
-#include "combat.h"
-
-/* SORCERY
- *
- * Certain of the denizens of the dungeon have the power to use sorcery
- * against the player.
- * 
- * The "ordinary" lich may unleash bolts of necromantic force against
- * the player, or smite him at close quarters with their staves of necromancy,
- * or invoke grim curses against him.
- *
- * The dreaded master liches can smite the player from a distance with
- * their necromantic powers without lying on a cardinal direction from
- * him, and can steal the player's vitality with a touch, as well as having
- * the spells of their lesser brethren.  Furthermore, they may attempt to
- * evade the player in the same manner as wizards.
- *
- * Itinerant wizards roaming the dungeon cast bolts of lightning, and strike
- * in hand-to-hand combat with staves wreathed with enchantments of shattering
- * force; if sorely pressed, they may invoke their powers to teleport across
- * the dungeon level, cheating the player of his victory.
- * 
- * Archmages, learned scholars of the Black Arts and veterans of many a
- * confrontation, have the powers of wizards. In addition, an archmage who
- * teleports away from the player to evade death may well leave him with a
- * group of summoned monsters.
- * 
- * The more potent order of demons known as defilers may cast curses against
- * the player, or call down a column of fire to smite him.
- *
- * Some forms of sorcery may be defended against by wearing the proper
- * armour or putting on a suitable ring; others bypass all such defences to
- * strike the player directly, although some of these can be evaded by those
- * with high enough agility.
- */
-
-int mon_use_sorcery(int mon)
-{
-    /* Returns zero for no spell selected, -1 for unsupported spell
-     * selected, 1 for supported spell selected. */
-    struct mon *mptr = monsters + mon;
-    int dy, dx;
-    int sy, sx;
-    enum monspell to_cast = MS_REJECT;
-    int rval = 1;      /* Default to success; failure paths will force this
-                        * to an appropriate value. */
-    int dieroll;
-    int meleerange;
-    int oncardinal;
-    int i;
-    int cansee;
-    int range;
-    compute_directions(u.y, u.x, mptr->y, mptr->x, &dy, &dx, &sy, &sx, &meleerange, &oncardinal);
-    cansee = mon_visible(mon);
-    if ((dy * sy) >= (dx * sx))
-    {
-       range = dy * sy;
-    }
-    else
-    {
-       range = dx * sx;
-    }
-    switch (monsters[mon].mon_id)
-    {
-    case PM_ARCHMAGE:
-       if (cansee)
-       {
-           /* We have LOS; choose a spell on that basis. */
-           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 2))
-           {
-               to_cast = zero_die(3) ? MS_TELEPORT_ESCAPE : MS_TELEPORT_AND_SUMMON;
-           }
-           else if (meleerange && (zero_die(10) > 3))
-           {
-               to_cast = MS_STRIKE_STAFF;
-           }
-           else if (oncardinal)
-           {
-               to_cast = MS_LIGHTNING;
-           }
-       }
-       else if (!zero_die(40))
-       {
-           /* 
-            * We lack LOS, but pass the 1-in-40 chance; use
-            * sorcery to relocate us to the player's location.
-            */
-           to_cast = MS_TELEPORT_ASSAULT;
-       }
-       break;
-
-    case PM_WIZARD:
-       if (cansee)
-       {
-           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 2))
-           {
-               to_cast = MS_TELEPORT_ESCAPE;
-           }
-           else if (meleerange && (zero_die(10) > 2))
-           {
-               to_cast = MS_STRIKE_STAFF;
-           }
-           else if (oncardinal)
-           {
-               to_cast = MS_LIGHTNING;
-           }
-       }
-       else if (!zero_die(80))
-       {
-           /* we lack LOS, but passed the 1-in-80 chance to
-            * close with the player by means of sorcery. */
-           to_cast = MS_TELEPORT_ASSAULT;
-       }
-       break;
-
-    case PM_MASTER_LICH:
-       if (cansee)
-       {
-           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 4))
-           {
-               to_cast = ((mptr->next_summon < game_tick) || !zero_die(3)) ? MS_TELEPORT_ESCAPE : MS_TELEPORT_AND_SUMMON;
-           }
-           else if (meleerange)
-           {
-               switch (zero_die(7))
-               {
-               case 6:
-                   if (!u.withering)
-                   {
-                       to_cast = MS_CURSE_WITHERING;
-                       break;
-                   }
-               case 4:
-                   if (!u.leadfoot)
-                   {
-                       to_cast = MS_CURSE_LEADFOOT;
-                       break;
-                   }
-                   /* fall through */
-               case 5:
-                   if (!u.armourmelt)
-                   {
-                       to_cast = MS_CURSE_ARMOURMELT;
-                       break;
-                   }
-                   /* fall through */
-               default:
-                   to_cast = zero_die(2) ? MS_CHILLING_TOUCH : MS_STRIKE_STAFF;
-                   break;
-               }
-           }
-           else if (range < 3)
-           {
-               switch (zero_die(10))
-               {
-               case 9:
-                   if (!u.withering)
-                   {
-                       to_cast = MS_CURSE_WITHERING;
-                       break;
-                   }
-               case 8:
-                   if (!u.leadfoot)
-                   {
-                       to_cast = MS_CURSE_LEADFOOT;
-                       break;
-                   }
-                   /* fall through */
-               case 7:
-                   if (!u.armourmelt)
-                   {
-                       to_cast = MS_CURSE_ARMOURMELT;
-                       break;
-                   }
-                   /* fall through */
-               default:
-                   to_cast = MS_NECRO_SMITE;
-                   break;
-               }
-           }
-           else if (range < 8)
-           {
-               switch (zero_die(7))
-               {
-               case 6:
-                   if (!u.withering)
-                   {
-                       to_cast = MS_CURSE_WITHERING;
-                       break;
-                   }
-               case 4:
-                   if (!u.leadfoot)
-                   {
-                       to_cast = MS_CURSE_LEADFOOT;
-                       break;
-                   }
-                   /* fall through */
-               case 5:
-                   if (!u.armourmelt)
-                   {
-                       to_cast = MS_CURSE_ARMOURMELT;
-                       break;
-                   }
-                   /* fall through */
-               default:
-                   to_cast = MS_NECRO_SMITE;
-                   break;
-               }
-           }
-       }
-       else if (!zero_die(40))
-       {
-           /* we lack LOS, but passed the 1-in-40 chance to
-            * close with the player by means of sorcery. */
-           to_cast = MS_TELEPORT_ASSAULT;
-       }
-       break;
-    case PM_LICH:
-       if (cansee)
-       {
-           if (meleerange)
-           {
-               dieroll = zero_die(6);
-               switch (dieroll)
-               {
-               case 4:
-                   if (!u.leadfoot)
-                   {
-                       to_cast = MS_CURSE_LEADFOOT;
-                       break;
-                   }
-                   /* fall through */
-               case 5:
-                   if (!u.armourmelt)
-                   {
-                       to_cast = MS_CURSE_ARMOURMELT;
-                       break;
-                   }
-                   /* fall through */
-               default:
-                   to_cast = MS_NECRO_STAFF;
-                   break;
-               }
-           }
-           else if (oncardinal)
-           {
-               if (range < 3)
-               {
-                   switch (zero_die(6))
-                   {
-                   case 4:
-                       if (!u.leadfoot)
-                       {
-                           to_cast = MS_CURSE_LEADFOOT;
-                           break;
-                       }
-                       /* fall through */
-                   case 5:
-                       if (!u.armourmelt)
-                       {
-                           to_cast = MS_CURSE_ARMOURMELT;
-                           break;
-                       }
-                       /* fall through */
-                   default:
-                       to_cast = MS_NECRO_BOLT;
-                       break;
-                   }
-               }
-               else
-               {
-                   to_cast = MS_NECRO_BOLT;
-               }
-           }
-           break;
-       }
-       break;
-    case PM_DEFILER:
-       if (cansee)
-       {
-           if (!meleerange)
-           {
-               switch (zero_die(7))
-               {
-               case 6:
-                   if (!u.withering)
-                   {
-                       to_cast = MS_CURSE_WITHERING;
-                       break;
-                   }
-               case 4:
-                   if (!u.leadfoot)
-                   {
-                       to_cast = MS_CURSE_LEADFOOT;
-                       break;
-                   }
-                   /* fall through */
-               case 5:
-                   if (!u.armourmelt)
-                   {
-                       to_cast = MS_CURSE_ARMOURMELT;
-                       break;
-                   }
-                   /* fall through */
-               default:
-                   to_cast = MS_FIRE_COLUMN;
-                   break;
-               }
-           }
-       }
-       break;
-
-    default:
-       break;
-    }
-    switch (to_cast)
-    {
-    default:
-       /* If this happens, we're trying to cast an unimplemented
-        * spell. */
-       print_msg("Can't happen: Bogus spell %d!\n", to_cast);
-       rval = -1;
-       break;
-
-    case MS_REJECT:
-       /* No usable spell available. */
-       rval = 0;
-       break;
-
-    case MS_STRIKE_STAFF:
-       mhitu(mon, DT_PHYS);
-       break;
-
-    case MS_NECRO_STAFF:
-       mhitu(mon, DT_NECRO);
-       break;
-
-    case MS_CHILLING_TOUCH:
-       mhitu(mon, DT_COLD);
-       break;
-
-    case MS_LIGHTNING:
-    case MS_NECRO_BOLT:
-       mshootu(mon);
-       break;
-
-    case MS_TELEPORT_AND_SUMMON:
-        mptr->next_summon = game_tick + 1000;
-       /* Do the summoning... */
-       print_mon_name(mon, 3);
-       print_msg(" calls for help...\n");
-       /* (Try to) summon 2-6 monsters. */
-       i = summoning(mptr->y, mptr->x, dice(2, 3));
-       if (i == 0)
-       {
-           print_msg("... luckily for you, help wasn't listening.\n");
-       }
-       else
-       {
-           print_msg("... and gets it.\n");
-       }
-       /* ... and fall through. */
-    case MS_TELEPORT_ESCAPE:
-       print_mon_name(mon, 3);
-       print_msg(" vanishes in a puff of smoke.\n");
-       teleport_mon(mon);
-       break;
-
-    case MS_TELEPORT_ASSAULT:
-       /* It is rare that a monster will cast this spell, but not
-        * unheard of. */
-       teleport_mon_to_you(mon);
-       break;
-
-    case MS_CURSE_ARMOURMELT:
-       mon_curses(mon);
-       if (u.protection)
-       {
-           malignant_aura();
-       }
-       else
-       {
-           u.armourmelt = 10 + one_die(10);
-           print_msg("Your armour seems suddenly no stronger than dust!\n");
-       }
-       break;
-
-    case MS_CURSE_LEADFOOT:
-       mon_curses(mon);
-       if (u.protection)
-       {
-           malignant_aura();
-       }
-       else
-       {
-           u.leadfoot = 10 + one_die(10);
-           print_msg("Your feet feel like lead!\n");
-       }
-       break;
-
-    case MS_CURSE_WITHERING:
-       mon_curses(mon);
-       if (u.protection)
-       {
-           malignant_aura();
-       }
-       else
-       {
-           u.withering = 10 + one_die(10);
-           print_msg("Your limbs twist and wither!\n");
-       }
-       break;
-
-    case MS_NECRO_SMITE:
-       mon_curses(mon);
-       if (player_resists_dtype(DT_NECRO))
-       {
-           print_msg("Darkness reaches towards you, but dissolves.\n");
-       }
-       else
-       {
-           print_msg("Soul-chilling darkness engulfs you!\n");
-           damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
-       }
-       break;
-
-    case MS_FIRE_COLUMN:
-       mon_curses(mon);
-       print_msg("The fires of hell ");
-       if (player_resists_dtype(DT_FIRE))
-       {
-           print_msg("lightly singe you.\n");
-           damage_u(dice(1, 5), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
-       }
-       else
-       {
-           print_msg("burn you!\n");
-           damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
-       }
-       break;
-    }
-    return rval;
-}
-
-void malignant_aura()
-{
-    print_msg("A malignant aura surrounds you briefly.\n");
-}
-
-void mon_curses(int mon)
-{
-    print_mon_name(mon, 3);
-    print_msg(" points at you and curses horribly.\n");
-}
-
-/* bmagic.c */
-// vim:cindent
diff --git a/bmagic.h b/bmagic.h
deleted file mode 100644 (file)
index de5cc12..0000000
--- a/bmagic.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*! \file sorcery.h
- *  \brief Monster sorcery rules
- */
-
-/* Copyright 2005-2013 Martin Read
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SORCERY_H
-#define SORCERY_H
-
-/* XXX DATA TYPES XXX */
-
-enum monspell {
-       MS_REJECT = -1,         /* Rejection tag. */
-       /* "Melee" attacks */
-       MS_STRIKE_STAFF,        /* Wizard */
-       MS_NECRO_STAFF,         /* Lich */
-       MS_CHILLING_TOUCH,      /* Master Lich */
-       /* Ranged Attacks */
-       MS_LIGHTNING,   /* Wizard */
-       MS_NECRO_BOLT,  /* Lich */
-       MS_NECRO_SMITE, /* Master Lich - no cardinal alignment needed */
-       MS_FIRE_COLUMN, /* Defiler */
-       /* Curses */
-       MS_CURSE_ARMOURMELT,    /* All cursers */
-       MS_CURSE_LEADFOOT,      /* All cursers */
-       MS_CURSE_WITHERING,     /* Master Lich and Defiler only */
-       /* Evasion */
-       MS_TELEPORT_ESCAPE,     /* Wizard, Archmage, Master Lich */
-       MS_TELEPORT_AND_SUMMON, /* Archmage */
-       MS_TELEPORT_ASSAULT,    /* Wizard, Archmage, Master Lich */
-};
-
-extern int mon_use_sorcery(int mon);
-extern void mon_curses(int mon);
-extern void malignant_aura(void);
-
-#endif
-
-/* sorcery.h */
-// vim:cindent
diff --git a/sorcery.c b/sorcery.c
new file mode 100644 (file)
index 0000000..8486216
--- /dev/null
+++ b/sorcery.c
@@ -0,0 +1,487 @@
+/*! \file sorcery.c 
+ *  \brief evil magic used by monsters
+ */
+
+/* Copyright 2005-2012 Martin Read
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "victrix-abyssi.h"
+#include "bmagic.h"
+#include "monsters.h"
+#include "combat.h"
+
+/* SORCERY
+ *
+ * Certain of the denizens of the dungeon have the power to use sorcery
+ * against the player.
+ * 
+ * The "ordinary" lich may unleash bolts of necromantic force against
+ * the player, or smite him at close quarters with their staves of necromancy,
+ * or invoke grim curses against him.
+ *
+ * The dreaded master liches can smite the player from a distance with
+ * their necromantic powers without lying on a cardinal direction from
+ * him, and can steal the player's vitality with a touch, as well as having
+ * the spells of their lesser brethren.  Furthermore, they may attempt to
+ * evade the player in the same manner as wizards.
+ *
+ * Itinerant wizards roaming the dungeon cast bolts of lightning, and strike
+ * in hand-to-hand combat with staves wreathed with enchantments of shattering
+ * force; if sorely pressed, they may invoke their powers to teleport across
+ * the dungeon level, cheating the player of his victory.
+ * 
+ * Archmages, learned scholars of the Black Arts and veterans of many a
+ * confrontation, have the powers of wizards. In addition, an archmage who
+ * teleports away from the player to evade death may well leave him with a
+ * group of summoned monsters.
+ * 
+ * The more potent order of demons known as defilers may cast curses against
+ * the player, or call down a column of fire to smite him.
+ *
+ * Some forms of sorcery may be defended against by wearing the proper
+ * armour or putting on a suitable ring; others bypass all such defences to
+ * strike the player directly, although some of these can be evaded by those
+ * with high enough agility.
+ */
+
+int mon_use_sorcery(int mon)
+{
+    /* Returns zero for no spell selected, -1 for unsupported spell
+     * selected, 1 for supported spell selected. */
+    struct mon *mptr = monsters + mon;
+    int dy, dx;
+    int sy, sx;
+    enum monspell to_cast = MS_REJECT;
+    int rval = 1;      /* Default to success; failure paths will force this
+                        * to an appropriate value. */
+    int dieroll;
+    int meleerange;
+    int oncardinal;
+    int i;
+    int cansee;
+    int range;
+    compute_directions(u.y, u.x, mptr->y, mptr->x, &dy, &dx, &sy, &sx, &meleerange, &oncardinal);
+    cansee = mon_visible(mon);
+    if ((dy * sy) >= (dx * sx))
+    {
+       range = dy * sy;
+    }
+    else
+    {
+       range = dx * sx;
+    }
+    switch (monsters[mon].mon_id)
+    {
+    case PM_ARCHMAGE:
+       if (cansee)
+       {
+           /* We have LOS; choose a spell on that basis. */
+           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 2))
+           {
+               to_cast = zero_die(3) ? MS_TELEPORT_ESCAPE : MS_TELEPORT_AND_SUMMON;
+           }
+           else if (meleerange && (zero_die(10) > 3))
+           {
+               to_cast = MS_STRIKE_STAFF;
+           }
+           else if (oncardinal)
+           {
+               to_cast = MS_LIGHTNING;
+           }
+       }
+       else if (!zero_die(40))
+       {
+           /* 
+            * We lack LOS, but pass the 1-in-40 chance; use
+            * sorcery to relocate us to the player's location.
+            */
+           to_cast = MS_TELEPORT_ASSAULT;
+       }
+       break;
+
+    case PM_WIZARD:
+       if (cansee)
+       {
+           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 2))
+           {
+               to_cast = MS_TELEPORT_ESCAPE;
+           }
+           else if (meleerange && (zero_die(10) > 2))
+           {
+               to_cast = MS_STRIKE_STAFF;
+           }
+           else if (oncardinal)
+           {
+               to_cast = MS_LIGHTNING;
+           }
+       }
+       else if (!zero_die(80))
+       {
+           /* we lack LOS, but passed the 1-in-80 chance to
+            * close with the player by means of sorcery. */
+           to_cast = MS_TELEPORT_ASSAULT;
+       }
+       break;
+
+    case PM_MASTER_LICH:
+       if (cansee)
+       {
+           if ((mptr->hpcur < (mptr->hpmax * 25 / 100)) && (zero_die(10) < 4))
+           {
+               to_cast = ((mptr->next_summon < game_tick) || !zero_die(3)) ? MS_TELEPORT_ESCAPE : MS_TELEPORT_AND_SUMMON;
+           }
+           else if (meleerange)
+           {
+               switch (zero_die(7))
+               {
+               case 6:
+                   if (!u.withering)
+                   {
+                       to_cast = MS_CURSE_WITHERING;
+                       break;
+                   }
+               case 4:
+                   if (!u.leadfoot)
+                   {
+                       to_cast = MS_CURSE_LEADFOOT;
+                       break;
+                   }
+                   /* fall through */
+               case 5:
+                   if (!u.armourmelt)
+                   {
+                       to_cast = MS_CURSE_ARMOURMELT;
+                       break;
+                   }
+                   /* fall through */
+               default:
+                   to_cast = zero_die(2) ? MS_CHILLING_TOUCH : MS_STRIKE_STAFF;
+                   break;
+               }
+           }
+           else if (range < 3)
+           {
+               switch (zero_die(10))
+               {
+               case 9:
+                   if (!u.withering)
+                   {
+                       to_cast = MS_CURSE_WITHERING;
+                       break;
+                   }
+               case 8:
+                   if (!u.leadfoot)
+                   {
+                       to_cast = MS_CURSE_LEADFOOT;
+                       break;
+                   }
+                   /* fall through */
+               case 7:
+                   if (!u.armourmelt)
+                   {
+                       to_cast = MS_CURSE_ARMOURMELT;
+                       break;
+                   }
+                   /* fall through */
+               default:
+                   to_cast = MS_NECRO_SMITE;
+                   break;
+               }
+           }
+           else if (range < 8)
+           {
+               switch (zero_die(7))
+               {
+               case 6:
+                   if (!u.withering)
+                   {
+                       to_cast = MS_CURSE_WITHERING;
+                       break;
+                   }
+               case 4:
+                   if (!u.leadfoot)
+                   {
+                       to_cast = MS_CURSE_LEADFOOT;
+                       break;
+                   }
+                   /* fall through */
+               case 5:
+                   if (!u.armourmelt)
+                   {
+                       to_cast = MS_CURSE_ARMOURMELT;
+                       break;
+                   }
+                   /* fall through */
+               default:
+                   to_cast = MS_NECRO_SMITE;
+                   break;
+               }
+           }
+       }
+       else if (!zero_die(40))
+       {
+           /* we lack LOS, but passed the 1-in-40 chance to
+            * close with the player by means of sorcery. */
+           to_cast = MS_TELEPORT_ASSAULT;
+       }
+       break;
+    case PM_LICH:
+       if (cansee)
+       {
+           if (meleerange)
+           {
+               dieroll = zero_die(6);
+               switch (dieroll)
+               {
+               case 4:
+                   if (!u.leadfoot)
+                   {
+                       to_cast = MS_CURSE_LEADFOOT;
+                       break;
+                   }
+                   /* fall through */
+               case 5:
+                   if (!u.armourmelt)
+                   {
+                       to_cast = MS_CURSE_ARMOURMELT;
+                       break;
+                   }
+                   /* fall through */
+               default:
+                   to_cast = MS_NECRO_STAFF;
+                   break;
+               }
+           }
+           else if (oncardinal)
+           {
+               if (range < 3)
+               {
+                   switch (zero_die(6))
+                   {
+                   case 4:
+                       if (!u.leadfoot)
+                       {
+                           to_cast = MS_CURSE_LEADFOOT;
+                           break;
+                       }
+                       /* fall through */
+                   case 5:
+                       if (!u.armourmelt)
+                       {
+                           to_cast = MS_CURSE_ARMOURMELT;
+                           break;
+                       }
+                       /* fall through */
+                   default:
+                       to_cast = MS_NECRO_BOLT;
+                       break;
+                   }
+               }
+               else
+               {
+                   to_cast = MS_NECRO_BOLT;
+               }
+           }
+           break;
+       }
+       break;
+    case PM_DEFILER:
+       if (cansee)
+       {
+           if (!meleerange)
+           {
+               switch (zero_die(7))
+               {
+               case 6:
+                   if (!u.withering)
+                   {
+                       to_cast = MS_CURSE_WITHERING;
+                       break;
+                   }
+               case 4:
+                   if (!u.leadfoot)
+                   {
+                       to_cast = MS_CURSE_LEADFOOT;
+                       break;
+                   }
+                   /* fall through */
+               case 5:
+                   if (!u.armourmelt)
+                   {
+                       to_cast = MS_CURSE_ARMOURMELT;
+                       break;
+                   }
+                   /* fall through */
+               default:
+                   to_cast = MS_FIRE_COLUMN;
+                   break;
+               }
+           }
+       }
+       break;
+
+    default:
+       break;
+    }
+    switch (to_cast)
+    {
+    default:
+       /* If this happens, we're trying to cast an unimplemented
+        * spell. */
+       print_msg("Can't happen: Bogus spell %d!\n", to_cast);
+       rval = -1;
+       break;
+
+    case MS_REJECT:
+       /* No usable spell available. */
+       rval = 0;
+       break;
+
+    case MS_STRIKE_STAFF:
+       mhitu(mon, DT_PHYS);
+       break;
+
+    case MS_NECRO_STAFF:
+       mhitu(mon, DT_NECRO);
+       break;
+
+    case MS_CHILLING_TOUCH:
+       mhitu(mon, DT_COLD);
+       break;
+
+    case MS_LIGHTNING:
+    case MS_NECRO_BOLT:
+       mshootu(mon);
+       break;
+
+    case MS_TELEPORT_AND_SUMMON:
+        mptr->next_summon = game_tick + 1000;
+       /* Do the summoning... */
+       print_mon_name(mon, 3);
+       print_msg(" calls for help...\n");
+       /* (Try to) summon 2-6 monsters. */
+       i = summoning(mptr->y, mptr->x, dice(2, 3));
+       if (i == 0)
+       {
+           print_msg("... luckily for you, help wasn't listening.\n");
+       }
+       else
+       {
+           print_msg("... and gets it.\n");
+       }
+       /* ... and fall through. */
+    case MS_TELEPORT_ESCAPE:
+       print_mon_name(mon, 3);
+       print_msg(" vanishes in a puff of smoke.\n");
+       teleport_mon(mon);
+       break;
+
+    case MS_TELEPORT_ASSAULT:
+       /* It is rare that a monster will cast this spell, but not
+        * unheard of. */
+       teleport_mon_to_you(mon);
+       break;
+
+    case MS_CURSE_ARMOURMELT:
+       mon_curses(mon);
+       if (u.protection)
+       {
+           malignant_aura();
+       }
+       else
+       {
+           u.armourmelt = 10 + one_die(10);
+           print_msg("Your armour seems suddenly no stronger than dust!\n");
+       }
+       break;
+
+    case MS_CURSE_LEADFOOT:
+       mon_curses(mon);
+       if (u.protection)
+       {
+           malignant_aura();
+       }
+       else
+       {
+           u.leadfoot = 10 + one_die(10);
+           print_msg("Your feet feel like lead!\n");
+       }
+       break;
+
+    case MS_CURSE_WITHERING:
+       mon_curses(mon);
+       if (u.protection)
+       {
+           malignant_aura();
+       }
+       else
+       {
+           u.withering = 10 + one_die(10);
+           print_msg("Your limbs twist and wither!\n");
+       }
+       break;
+
+    case MS_NECRO_SMITE:
+       mon_curses(mon);
+       if (player_resists_dtype(DT_NECRO))
+       {
+           print_msg("Darkness reaches towards you, but dissolves.\n");
+       }
+       else
+       {
+           print_msg("Soul-chilling darkness engulfs you!\n");
+           damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+       }
+       break;
+
+    case MS_FIRE_COLUMN:
+       mon_curses(mon);
+       print_msg("The fires of hell ");
+       if (player_resists_dtype(DT_FIRE))
+       {
+           print_msg("lightly singe you.\n");
+           damage_u(dice(1, 5), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+       }
+       else
+       {
+           print_msg("burn you!\n");
+           damage_u(dice(1, 20), DEATH_KILLED_MON, permons[monsters[mon].mon_id].name);
+       }
+       break;
+    }
+    return rval;
+}
+
+void malignant_aura()
+{
+    print_msg("A malignant aura surrounds you briefly.\n");
+}
+
+void mon_curses(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" points at you and curses horribly.\n");
+}
+
+/* bmagic.c */
+// vim:cindent
diff --git a/sorcery.h b/sorcery.h
new file mode 100644 (file)
index 0000000..de5cc12
--- /dev/null
+++ b/sorcery.h
@@ -0,0 +1,62 @@
+/*! \file sorcery.h
+ *  \brief Monster sorcery rules
+ */
+
+/* Copyright 2005-2013 Martin Read
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SORCERY_H
+#define SORCERY_H
+
+/* XXX DATA TYPES XXX */
+
+enum monspell {
+       MS_REJECT = -1,         /* Rejection tag. */
+       /* "Melee" attacks */
+       MS_STRIKE_STAFF,        /* Wizard */
+       MS_NECRO_STAFF,         /* Lich */
+       MS_CHILLING_TOUCH,      /* Master Lich */
+       /* Ranged Attacks */
+       MS_LIGHTNING,   /* Wizard */
+       MS_NECRO_BOLT,  /* Lich */
+       MS_NECRO_SMITE, /* Master Lich - no cardinal alignment needed */
+       MS_FIRE_COLUMN, /* Defiler */
+       /* Curses */
+       MS_CURSE_ARMOURMELT,    /* All cursers */
+       MS_CURSE_LEADFOOT,      /* All cursers */
+       MS_CURSE_WITHERING,     /* Master Lich and Defiler only */
+       /* Evasion */
+       MS_TELEPORT_ESCAPE,     /* Wizard, Archmage, Master Lich */
+       MS_TELEPORT_AND_SUMMON, /* Archmage */
+       MS_TELEPORT_ASSAULT,    /* Wizard, Archmage, Master Lich */
+};
+
+extern int mon_use_sorcery(int mon);
+extern void mon_curses(int mon);
+extern void malignant_aura(void);
+
+#endif
+
+/* sorcery.h */
+// vim:cindent