NOTE: This patch causes weird segfaults and other strangness if the info patches are not applied. This is due to the hard-coded ego types, which if they don't exist, are beyond the end of the array.

If you apply this patch and play a module, guess what? You're using the modules info files, which don't have the correct ego types. Apply the info patches by hand to the modules' lists.

You'll see this problem for any GF_RAISE using function, like the "undeath" runespells, the necromacer's "raise" spells, and the paths of the dead raise corpse effect.

The correct way to fix this would be to make it compile a list if ego undead ego types, and choose from those, as opposed to hard-coding the ego values. You could even make it complain if there aren't enough undead ego types to choose from.

Yeah. Have fun with that.

diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/lib/edit/misc.txt floor_patch/lib/edit/misc.txt
--- tome-225-src/lib/edit/misc.txt      2003-12-11 13:32:39.000000000 -0700
+++ floor_patch/lib/edit/misc.txt       2004-01-26 10:18:17.000000000 -0700
@@ -22,7 +22,7 @@ M:R:1078
 # Maximum number of monsters in re_info.txt
 # WARNING ! Use the exact amount of ego types used, if not you
 # will get weird results !
-M:r:14
+M:r:21
 
 # Maximum number of items in k_info.txt
 M:K:819
diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/lib/edit/re_info.txt floor_patch/lib/edit/re_info.txt
--- tome-225-src/lib/edit/re_info.txt   2003-12-11 13:32:39.000000000 -0700
+++ floor_patch/lib/edit/re_info.txt    2004-01-27 14:55:22.000000000 -0700
@@ -32,7 +32,7 @@ V:2.0.0
 
 # A few undeads, to be created by the ANIM_DEAD spell
 
-N:1:Skeleton
+N:1:Skeletal
 G:s:*
 I:%100:+1d+1:+0:+5:-5
 W:+5:13:%30:%95:B
@@ -71,8 +71,14 @@ M:NO_SLEEP | SMART | EVIL | COLD_BLOOD
 O:DROP_SKELETON | GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS | 
 O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL
 S:1_IN_4 | 
-S:BLINK | TELE_TO | TELE_AWAY | BRAIN_SMASH | DRAIN_MANA | CAUSE_3 | 
+S:BLINK | TELE_TO | BRAIN_SMASH | DRAIN_MANA | CAUSE_3 | 
 S:BLIND | HOLD | SLOW | SCARE
+#Liches loose breath weapons
+T:BR_NUKE | BR_ACID | BR_ELEC | BR_FIRE |
+T:BR_COLD | BR_POIS | BR_NETH | BR_LITE | BR_DARK |
+T:BR_CONF | BR_SOUN | BR_CHAO | BR_DISE | BR_NEXU |
+T:BR_TIME | BR_INER | BR_GRAV | BR_SHAR | BR_PLAS |
+T:BR_WALL | BR_MANA | BR_DISI
 
 N:4:Spectral
 G:G:*
@@ -171,9 +178,129 @@ W:+0:15:+0:+0:B
 F:WILD_TOWN
 H:ANIMAL
 
+# Mummies gain a vulnerability to fire, and -10 speed.
+# They also follow you forever, and are usually asleep.
+N:14:mummified
+G:z:*
+I:-10:+0d%150:+20:%120:+10
+W:+10:22:%50:%130:B
+F:MORTAL | DROP_CORPSE
+H:UNDEAD | NONLIVING | AQUATIC
+M:EVIL | UNDEAD | COLD_BLOOD | EMPTY_MIND | FORCE_SLEEP
+M:IM_POIS | IM_COLD | IM_ELEC | SUSCEP_FIRE | RES_TELE
+O:AURA_FIRE | IM_FIRE
+O:GOOD | WEIRD_MIND
+S:1_IN_7 | 
+S:BLIND | SCARE | DRAIN_MANA | CAUSE_1 | DARKNESS
+T:BA_FIRE | BO_FIRE | BR_FIRE | BO_PLAS
+
+#Skulls gain flight
+N:15:skull
+G:s:*
+I:+0:+0d%50:+0:%150:+0
+W:+10:16:%10:%150:A
+F:MORTAL | DROP_SKELETON
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g | R_CHAR_c
+M:EVIL | UNDEAD | COLD_BLOOD | WEIRD_MIND | NO_CONF | NO_SLEEP
+M:CAN_FLY | IM_POIS | IM_COLD | NO_CUT | BASH_DOOR
+O:GOOD | EMPTY_MIND | MORTAL
+
+# Vampires can still drop corpses
+# Their advantages are pretty traditional.
+# Spells are copies from 'Vampire' in k_info.txt
+N:16:Vampiric
+G:V:*
+I:+0:+0d+0:+0:+0:+0
+W:+20:15:+0:%150:B
+F:MORTAL | SMART | DROP_CORPSE | R_CHAR_h | R_CHAR_p | R_CHAR_P | R_CHAR_O
+# F:R_CHAR_y | R_CHAR_k | R_CHAR_o
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g
+M:FORCE_MAXHP | CAN_FLY | EVIL | UNDEAD | HURT_LITE | COLD_BLOOD
+M:IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | OPEN_DOOR | TAKE_ITEM
+O:GOOD | FRIEND | FRIENDS | ESCORT | ESCORTS |
+O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL
+S:1_IN_9 | 
+S:TELE_TO | HOLD | SCARE | CAUSE_2 | MIND_BLAST | FORGET | DARKNESS
+#T: Vampires retain all their normal spells
+
+# Master Vampires are MUCH tougher, about twice as tough as a vamp.
+N:17:Vampiric Master
+G:V:*
+I:+0:+0d%200:+0:+0:+0
+W:+40:20:+0:%300:B
+F:MORTAL | SMART | DROP_CORPSE | R_CHAR_h | R_CHAR_p | R_CHAR_P | R_CHAR_O
+#F:R_CHAR_y | R_CHAR_k | R_CHAR_o
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g
+M:FORCE_MAXHP | CAN_FLY | EVIL | UNDEAD | HURT_LITE | COLD_BLOOD
+M:IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | OPEN_DOOR | TAKE_ITEM
+M:REGENERATE | NO_CUT
+O:GOOD | FRIEND | FRIENDS | ESCORT | ESCORTS |
+O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL
+S:1_IN_7 | 
+S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | 
+S:BRAIN_SMASH | DARKNESS | BO_NETH
+#T: Vampires retain all their normal spells
+
+
+#Skull Druj's gain some spells, and lose movement.
+N:18:skull druj
+G:s:*
+I:+0:+0d%50:+0:%150:+0
+W:+40:30:%10:%300:A
+F:MORTAL | DROP_SKELETON
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g | R_CHAR_c
+M:EVIL | UNDEAD | COLD_BLOOD | WEIRD_MIND | NO_CONF | NO_SLEEP
+M:IM_POIS | IM_COLD | NO_CUT | BASH_DOOR | NEVER_MOVE | RES_TELE
+O:GOOD | EMPTY_MIND | MORTAL
+S:1_IN_1 | 
+S:SLOW | CAUSE_4 | MIND_BLAST | BRAIN_SMASH | TRAPS | BO_PLAS | 
+S:BO_NETH | BA_WATE | S_UNDEAD
+
+N:19:Master Lich
+G:L:*
+I:+10:+0d%200:+10:+20:-10
+W:+40:25:%50:%400:B
+F:DROP_SKELETON | SMART | R_CHAR_h | R_CHAR_p | R_CHAR_P | R_CHAR_O
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g
+M:UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF
+M:NO_SLEEP | SMART | EVIL | COLD_BLOOD | RES_TELE | ONLY_ITEM | OPEN_DOOR
+M:BASH_DOOR | NO_CUT
+O:GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS |
+O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL
+S:1_IN_3 | 
+S:BLINK | TELE_TO | BLIND | HOLD | CONF | SCARE | CAUSE_3 | CAUSE_4 | 
+S:DRAIN_MANA | BRAIN_SMASH | S_UNDEAD
+
+N:20:Arch Lich
+G:L:*
+I:+20:+0d%100:+10:+20:-10
+W:+50:30:%0:%400:B
+F:DROP_SKELETON | SMART | R_CHAR_h | R_CHAR_p | R_CHAR_P | R_CHAR_O
+H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g
+M:UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF
+M:NO_SLEEP | SMART | EVIL | COLD_BLOOD | RES_TELE | ONLY_ITEM | OPEN_DOOR
+M:BASH_DOOR | NO_CUT | CAN_FLY | PASS_WALL
+O:GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS |
+O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL
+S:1_IN_3 | 
+S:BLINK | TELE_TO | BLIND | HOLD | SCARE | CAUSE_4 | 
+S:DRAIN_MANA | BRAIN_SMASH | S_HI_UNDEAD | FORGET |
+S:TPORT | HEAL | S_DEMON | BA_NETH | ANIM_DEAD
+#Arch Liches loose breath weapons, as they are immaterial
+T:BR_NUKE | BR_ACID | BR_ELEC | BR_FIRE |
+T:BR_COLD | BR_POIS | BR_NETH | BR_LITE | BR_DARK |
+T:BR_CONF | BR_SOUN | BR_CHAO | BR_DISE | BR_NEXU |
+T:BR_TIME | BR_INER | BR_GRAV | BR_SHAR | BR_PLAS |
+T:BR_WALL | BR_MANA | BR_DISI
+
+
+
+#Other possible undead egos: Wights, Ghouls, Wraiths
+#We already have a 'greater mummy' type in k_info. Add a 'basic mummy' type
+
 # N:x:ego name
 # G:x:y                 x is the char, y the attribute, * means the normal one
-# I:speed:(dice)d(side):aaf:ac:sleep
+# I:speed:(dice)d(side):aaf:ac:sleep   aaf is 'how far to look for player'
 # W:lev:rarity:weight:xp:place('B'efore or 'A'fter)
 # F:flags that the normal monster *must* have
 # H:flags that the normal monster *must not* have
diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/src/cmd7.c floor_patch/src/cmd7.c
--- tome-225-src/src/cmd7.c     2003-12-11 13:32:40.000000000 -0700
+++ floor_patch/src/cmd7.c      2004-01-28 10:38:22.000000000 -0700
@@ -5420,13 +5420,14 @@ void do_cmd_set_piercing(void)
  */
 void necro_info(char *p, int power)
 {
+       int to_s2 = p_ptr->to_s / 2;
        int plev = get_skill(SKILL_NECROMANCY);
 
        strcpy(p, "");
 
        switch (power)
        {
-       case 0:
+       case 0:/* Horrify */
                {
                        if (p_ptr->to_s)
                                strnfmt(p, 80, " power %dd%d+%d", 2 + (plev * 2 / 3), 4, (p_ptr->to_s * 2));
@@ -5434,16 +5435,30 @@ void necro_info(char *p, int power)
                                strnfmt(p, 80, " power %dd%d", 2 + (plev * 2 / 3), 4);
                        break;
                }
-       case 2:
+       case 1: /* Raise Dead */
+               {
+                       strnfmt(p, 80, " rad %d d%d", 1+to_s2+(plev/10), plev*3 );
+                       break;
+               }
+       case 2: /* Necromatic Teeth */
                {
                        strnfmt(p, 80, " dur d%d+%d", 100 + (plev * 4), 200 + (plev * 3));
                        break;
                }
-       case 3:
+       case 3: /* Absorb Souls */
                {
                        strnfmt(p, 80, " dur d%d+%d", 30 + (plev * 2), 50 + plev);
                        break;
                }
+       case 4: /* Vampirism */
+               {
+                       strnfmt(p, 80, " dam %d", (1 + to_s2 + (plev/15))*100 );
+                       break;
+               }
+       case 5: /* Death */
+               {
+                       break;
+               }
        }
 }
 
diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/src/melee2.c floor_patch/src/melee2.c
--- tome-225-src/src/melee2.c   2003-12-11 13:32:40.000000000 -0700
+++ floor_patch/src/melee2.c    2004-01-29 19:46:36.000000000 -0700
@@ -140,6 +140,16 @@ bool mon_take_hit_mon(int s_idx, int m_i
 
                                /* Gain experience */
                                gain_exp(new_exp);
+
+                               /* If Monster lore skill is over 35, count it as 'our' kill for monster recall */
+                               if (get_skill(SKILL_LORE) > 34 && (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE))))
+                               {
+                                       /* Count kills this life */
+                                       if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++;
+
+                                       /* Count kills in all lives */
+                                       if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;
+                               }
                        }
 
                        /* When an Unique dies, it stays dead */
@@ -7336,10 +7347,10 @@ static void process_monster(int m_idx, b
 
                                        /* Take or Kill objects on the floor */
                                        /* rr9: Pets will no longer pick up/destroy items */
-                                       if ((((r_ptr->flags2 & (RF2_TAKE_ITEM)) &&
+                                       if (((r_ptr->flags2 & (RF2_TAKE_ITEM)) &&
                                                        ((is_friend(m_ptr) <= 0) || p_ptr->pet_pickup_items)) ||
-                                                       (r_ptr->flags2 & (RF2_KILL_ITEM))) &&
-                                                       (is_friend(m_ptr) <= 0))
+                                                       ((r_ptr->flags2 & (RF2_KILL_ITEM)) &&
+                                                       (is_friend(m_ptr) <= 0)))
                                        {
                                                u32b f1, f2, f3, f4, f5, esp;
 
diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/src/monster2.c floor_patch/src/monster2.c
--- tome-225-src/src/monster2.c 2003-12-11 13:32:41.000000000 -0700
+++ floor_patch/src/monster2.c  2004-01-27 16:30:44.000000000 -0700
@@ -4085,6 +4085,18 @@ void monster_drop_carried_objects(monste
 
                /* Drop it */
                drop_near(q_ptr, -1, m_ptr->fy, m_ptr->fx);
+               /* Comment on visible drops */
+               if( m_ptr->ml)
+               {
+                       char m_name[80];
+                       char o_name[80];
+                       /* get monster's name */
+                       monster_desc(m_name,m_ptr,0);
+                       /* get Object's name */
+                       object_desc(o_name,q_ptr, TRUE, 0);
+                       /* Print the message */
+                       msg_format("%s drops %s",m_name,o_name);
+               }
        }
 
        /* Forget objects */
diff -udprBb --exclude='*.o' --exclude='*.raw' tome-225-src/src/spells1.c floor_patch/src/spells1.c
--- tome-225-src/src/spells1.c  2003-12-11 13:32:39.000000000 -0700
+++ floor_patch/src/spells1.c   2004-01-29 10:14:11.000000000 -0700
@@ -3870,19 +3870,34 @@ static bool project_f(int who, int r, in
 
 
 /* Array of raisable ego monster */
-#define MAX_RAISE 10
+#define MAX_RAISE 25
 static int raise_ego[MAX_RAISE] =
 {
-       1,       /* Skeleton */
-       1,       /* Skeleton */
-       1,       /* Skeleton */
-       1,       /* Skeleton */
-       2,       /* Zombie */
-       2,       /* Zombie */
-       2,       /* Zombie */
-       4,       /* Spectre */
-       4,       /* Spectre */
-       3,       /* Lich */
+       1,       /* 00 Skeleton +5 */
+       1,       /* 01 Skeleton +5 */
+       1,       /* 02 Skeleton +5 */
+       1,       /* 03 Skeleton +5 */
+       2,       /* 04 Zombie +10 */
+       2,       /* 05 Zombie +10 */
+       2,       /* 06 Zombie +10 */
+       14,      /* 07 Mumified +10 */
+       14,      /* 08 Mumified +10 */
+       14,      /* 09 Mumified +10 */
+       15,      /* 10 Skull +10 */
+       15,      /* 11 Skull +10 */
+       15,      /* 12 Skull +10 */
+       4,       /* 13 Spectre +20 */
+       4,       /* 14 Spectre +20 */
+       4,       /* 15 Spectre +20 */
+       16,      /* 16 Vampire +20 */
+       16,      /* 17 Vampire +20 */
+       16,      /* 18 Vampire +20 */
+       3,       /* 19 Lich +30 */
+       3,       /* 20 Lich +30 */
+       19,      /* 21 Master Lich +40 */
+       17,      /* 22 Master Vampire +40 */
+       18,      /* 23 Skull Druj +40 */
+       20       /* 24 Arch Lich +50 */
 };
 
 
@@ -3916,7 +3931,6 @@ static bool project_o(int who, int r, in
 
        int o_sval = 0;
        bool is_potion = FALSE;
-       int xx, yy;
 
 
        /* XXX XXX XXX */
@@ -4176,17 +4190,45 @@ static bool project_o(int who, int r, in
                        }
                case GF_RAISE:
                        {
-                               xx = x;
-                               yy = y;
-                               get_pos_player(7, &y, &x);
+                               int ego = 0;
+                               int tries = 0;
 
                                /* Only corpses can be raised */
-                               if (o_ptr->tval == TV_CORPSE)
+                               if (o_ptr->tval != TV_CORPSE || o_ptr->sval == SV_CORPSE_MEAT)
+                                       break;
+
+                               /* HACK! for the player, modify damage to necromancy skill / (1/2 dist) */
+                               /* this is to give necromancers not QUITE the disadvantage they would otherwise have */
+                               if(!who)
                                {
-                                       int ego = raise_ego[rand_int(MAX_RAISE)];
+                                       int dist=distance(x,y,p_ptr->px,p_ptr->py);
+                                       dam=get_skill(SKILL_NECROMANCY)*3 + 3;
+                                       if(dist)
+                                               dam/=dist;
+                               }
 
-                                       if (place_monster_one(y, x, o_ptr->pval2, ego, FALSE, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
-                                               msg_print("A monster raises from the grave!");
+                               /* 'dam' is level of spell effect, retry until monster level <= dam */
+                               /* BUT: the damage is dam/dist, so only the epicenter gets the full effect */
+                               /* SO: *2 for authenticity? or modify backwards by dist? or call it good? */
+                               while(tries++ < 20)
+                               {
+                                       int level=r_info[o_ptr->pval2].level;
+                                       int el=0;
+                                       ego = raise_ego[rand_int(MAX_RAISE)];
+                                       MODIFY_AUX(level,re_info[ego].level);
+                                       MODIFY_AUX(el,re_info[ego].level);
+                                       if(level < dam && el < dam/3 )
+                                               break;
+                               }
+                               if( tries < 100 )
+                               {
+                                       int xx, yy;
+                                       /* get an free grid approximately near the object */
+                                       get_pos_player(2, &yy, &xx);
+                                       /* message if we can't figure a place to put the monster... */
+                                       note_kill = " twitches, writhes, and vanishes.";
+                                       if (place_monster_one(yy, xx, o_ptr->pval2, ego, FALSE, (!who) ? MSTATUS_PET : MSTATUS_ENEMY))
+                                               note_kill= (plural ? " spew forth a hideous monster!" : " spews forth a hideous monster!" );
                                        do_kill = TRUE;
                                }
                                break;

JohnGilmore/Better Necromancy (last edited 2006-07-13 02:32:00 by JohnGilmore)