Big ball-of-mud commit after completing removal of direct print_msg() calls in game... printmsg-purged
authorMartin Read <martin@blackswordsonics.com>
Sun, 9 Feb 2014 15:09:16 +0000 (15:09 +0000)
committerMartin Read <martin@blackswordsonics.com>
Sun, 9 Feb 2014 15:09:16 +0000 (15:09 +0000)
17 files changed:
Makefile
combat.cc
default.permobjs
display-nc.cc
display.hh
fov.cc
main.cc
map.cc
mon2.cc
monsters.cc
notify-local-tty.cc
notify.hh
objects.cc
objects.hh
pobj_comp
u.cc
victrix-abyssi.hh

index b7843f6..827505f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -75,17 +75,17 @@ permobj.cc pobj_id.hh: default.permobjs $(srcdir)/pobj_comp
        $(srcdir)/pobj_comp $<
 
 ## Dependencies for the build
-combat.o: combat.cc combat.hh victrix-abyssi.hh monsters.hh objects.hh pobj_id.hh
+combat.o: combat.cc combat.hh victrix-abyssi.hh monsters.hh objects.hh notify.hh pobj_id.hh
 
 display-nc.o: display-nc.cc victrix-abyssi.hh display.hh pobj_id.hh
 
-main.o: main.cc combat.hh victrix-abyssi.hh monsters.hh pobj_id.hh
+main.o: main.cc combat.hh victrix-abyssi.hh monsters.hh notify.hh pobj_id.hh
 
-map.o: map.cc victrix-abyssi.hh objects.hh
+map.o: map.cc victrix-abyssi.hh notify.hh objects.hh
 
-monsters.o: monsters.cc victrix-abyssi.hh monsters.hh objects.hh
+monsters.o: monsters.cc victrix-abyssi.hh monsters.hh notify.hh objects.hh
 
-mon2.o: mon2.cc victrix-abyssi.hh sorcery.hh monsters.hh objects.hh
+mon2.o: mon2.cc victrix-abyssi.hh sorcery.hh monsters.hh notify.hh objects.hh
 
 notify-local-tty.o: notify-local-tty.cc victrix-abyssi.hh combat.hh monsters.hh notify.hh objects.hh sorcery.hh pobj_id.hh
 
@@ -98,12 +98,12 @@ permobj.o: permobj.cc victrix-abyssi.hh objects.hh
 
 permons.o: permons.cc victrix-abyssi.hh monsters.hh
 
-pmon2.o: pmon2.cc victrix-abyssi.hh monsters.hh
+pmon2.o: pmon2.cc victrix-abyssi.hh notify.hh monsters.hh
 
-objects.o: objects.cc victrix-abyssi.hh objects.hh monsters.hh pobj_id.hh
+objects.o: objects.cc victrix-abyssi.hh notify.hh objects.hh monsters.hh pobj_id.hh
 
-sorcery.o: sorcery.cc victrix-abyssi.hh sorcery.hh objects.hh monsters.hh
+sorcery.o: sorcery.cc victrix-abyssi.hh notify.hh sorcery.hh objects.hh monsters.hh
 
-u.o: u.cc combat.hh victrix-abyssi.hh monsters.hh objects.hh pobj_id.hh
+u.o: u.cc combat.hh victrix-abyssi.hh notify.hh monsters.hh objects.hh pobj_id.hh
 
 # vim:ts=8:sts=8:sw=8:noexpandtab
index ca028f4..e803241 100644 (file)
--- a/combat.cc
+++ b/combat.cc
@@ -161,10 +161,8 @@ int ushootm(Offset step)
                     switch (kb)
                     {
                     case 0:
-                        notify_knockback_mon_fail();
                         break;
                     case 1:
-                        notify_knockback_mon_pass();
                         break;
                     case 2:
                         /* message handled elsewhere */
@@ -285,16 +283,8 @@ int mshootu(int mon)
     step = mysign(delta);
     /* Don't get the bonus that applies to melee attacks. */
     tohit = zero_die(mptr->rtohit);
-    print_mon_name(mon, 3);
     dtype = permons[mptr->mon_id].rdtyp;
-    if (dtype == DT_PHYS)
-    {
-        print_msg(" %s at you!\n", permons[mptr->mon_id].shootverb);
-    }
-    else
-    {
-        print_msg(" %s %s at you!\n", permons[mptr->mon_id].shootverb, damtype_names[dtype]);
-    }
+    notify_mon_ranged_attack(mon);
     if ((dtype == DT_NECRO) || (dtype == DT_ELEC))
     {
         /* Use agility-based defence for necromantic blasts and lightning
@@ -313,18 +303,18 @@ int mshootu(int mon)
     /* Move projectile one square before looking for targets. */
     for ((done = 0), (c = mptr->pos + step); !done; c += step)
     {
-        int mon;
+        int victim;
         if ((lvl.terrain_at(c) == WALL) || (lvl.terrain_at(c) == DOOR))
         {
             done = 1;
         }
-        mon = lvl.mon_at(c);
+        victim = lvl.mon_at(c);
         if (c == u.pos)
         {
             if (tohit >= defence)
             {
                 done = 1;
-                print_msg("It hits you!\n");
+                notify_mon_ranged_hit_player(mon);
                 unaffected = u.resists(dtype);
                 if (!unaffected)
                 {
@@ -336,13 +326,13 @@ int mshootu(int mon)
             }
             else
             {
-                print_msg("It misses you.\n");
+                notify_mon_ranged_missed_player(mon);
             }
         }
-        else if (mon != NO_MON)
+        else if (victim != NO_MON)
         {
             done = 1;
-            bystander = monsters + mon;
+            bystander = monsters + victim;
             switch (dtype)
             {
             case DT_COLD:
@@ -381,8 +371,9 @@ int mshootu(int mon)
             }
             if (tohit >= bystander->defence)
             {
+                notify_mon_ranged_hit_mon(mon, victim);
                 damage = one_die(mptr->rdam);
-                damage_mon(mon, dtype, false);
+                damage_mon(victim, dtype, false);
             }
         }
     }
index e519f96..b415a9c 100644 (file)
@@ -8,6 +8,7 @@ COLOUR iron
 POWER 4
 POWER2 0
 DEPTH 1
+DAMAGEABLE
 
 WEAPON long sword
 PLURAL long swords
@@ -19,6 +20,7 @@ COLOUR iron
 POWER 10
 POWER2 0
 DEPTH 4
+DAMAGEABLE
 
 WEAPON mace
 PLURAL maces
@@ -30,6 +32,7 @@ COLOUR iron
 POWER 7
 POWER2 0
 DEPTH 2
+DAMAGEABLE
 
 WEAPON runesword
 PLURAL runeswords
@@ -41,6 +44,7 @@ COLOUR l_cyan
 POWER 20
 POWER2 0
 DEPTH 12
+DAMAGEABLE
 
 WEAPON tormentor's lash
 PLURAL tormentor's lashes
@@ -53,6 +57,8 @@ POWER 20
 POWER2 0
 DEPTH 30
 NOTIFY_EQUIP
+DAMAGEABLE
+BREAK_REACT
 
 WEAPON staff of fire
 PLURAL staves of fire
@@ -64,6 +70,8 @@ COLOUR d_grey
 POWER 10
 POWER2 0
 DEPTH 20
+DAMAGEABLE
+ACTIVATABLE
 
 WEAPON bow
 PLURAL bows
@@ -75,6 +83,7 @@ COLOUR brown
 POWER 8
 POWER2 0
 DEPTH 1
+DAMAGEABLE
 
 WEAPON crossbow
 PLURAL crossbows
@@ -86,6 +95,7 @@ COLOUR brown
 POWER 16
 POWER2 0
 DEPTH 6
+DAMAGEABLE
 
 WEAPON thunderbow
 PLURAL thunderbows
@@ -97,6 +107,7 @@ COLOUR l_cyan
 POWER 16
 POWER2 0
 DEPTH 30
+DAMAGEABLE
 
 POTION healing potion
 PLURAL healing potions
@@ -108,6 +119,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 POTION body potion
 PLURAL body potions
@@ -119,6 +131,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 5
+STACKABLE
 
 POTION agility potion
 PLURAL agility potions
@@ -130,6 +143,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 5
+STACKABLE
 
 POTION restoration potion
 PLURAL restoration potions
@@ -141,39 +155,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 1
-
-#FLASK poison flask
-#PLURAL poison flask
-#DESC This fragile bottle is full of contact poison.
-#RARITY 10 
-#ASCII '~'
-#UTF8 "~"
-#COLOUR l_grey
-#POWER 0
-#POWER2 0
-#DEPTH 1
-
-#FLASK fire flask
-#PLURAL fire flasks
-#DESC The volatile, phosphorus-laced liquid in this sealed flask will ignite spontaneously when exposed to the air.
-#RARITY 40 
-#ASCII '~'
-#UTF8 "~"
-#COLOUR l_grey
-#POWER 0
-#POWER2 0
-#DEPTH 20
-
-#FLASK weakness flask
-#PLURAL weakness flasks
-#DESC Dousing the living in this vile liquid causes immediate and severe physical degeneration.
-#RARITY 40 
-#ASCII '~'
-#UTF8 "~"
-#COLOUR l_grey
-#POWER 0
-#POWER2 0
-#DEPTH 20
+STACKABLE
 
 SCROLL teleport scroll
 PLURAL teleport scrolls
@@ -185,6 +167,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 SCROLL fire scroll
 PLURAL fire scrolls
@@ -196,6 +179,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 SCROLL protection scroll
 PLURAL protection scrolls
@@ -207,6 +191,7 @@ COLOUR l_grey
 POWER 0
 POWER2 0
 DEPTH 8
+STACKABLE
 
 ARMOUR leather armour
 PLURAL suits of leather armour
@@ -218,6 +203,7 @@ COLOUR brown
 POWER 3
 POWER2 10
 DEPTH 1
+DAMAGEABLE
 
 ARMOUR chainmail
 PLURAL suits of chainmail
@@ -229,6 +215,7 @@ COLOUR iron
 POWER 6
 POWER2 25
 DEPTH 3
+DAMAGEABLE
 
 ARMOUR plate armour
 PLURAL suits of plate armour
@@ -240,6 +227,7 @@ COLOUR iron
 POWER 10
 POWER2 40
 DEPTH 6
+DAMAGEABLE
 
 ARMOUR mage armour
 PLURAL suits of mage armour
@@ -251,6 +239,7 @@ COLOUR l_cyan
 POWER 15
 POWER2 40
 DEPTH 12
+DAMAGEABLE
 
 ARMOUR mundane robe
 PLURAL mundane robes
@@ -262,6 +251,7 @@ COLOUR green
 POWER 2
 POWER2 5
 DEPTH 1
+DAMAGEABLE
 
 ARMOUR robe of swiftness
 PLURAL robes of swiftness
@@ -273,6 +263,7 @@ COLOUR green
 POWER 8
 POWER2 0
 DEPTH 8
+DAMAGEABLE
 
 ARMOUR robe of shadows
 PLURAL robes of shadows
@@ -284,6 +275,7 @@ COLOUR d_grey
 POWER 14
 POWER2 -15
 DEPTH 18
+DAMAGEABLE
 
 ARMOUR dragonhide armour
 PLURAL suits of dragonhide armour
@@ -295,6 +287,7 @@ COLOUR red
 POWER 12
 POWER2 10
 DEPTH 21
+DAMAGEABLE
 
 ARMOUR meteoric plate armour
 PLURAL suits of meteoric plate armour
@@ -306,6 +299,7 @@ COLOUR iron
 POWER 18
 POWER2 40
 DEPTH 27
+DAMAGEABLE
 
 ARMOUR sacred chainmail
 PLURAL suits of sacred chainmail
@@ -317,6 +311,7 @@ COLOUR white
 POWER 15
 POWER2 25
 DEPTH 24
+DAMAGEABLE
 
 ARMOUR ragged shift
 PLURAL ragged shifts
@@ -329,6 +324,7 @@ POWER 1
 POWER2 0
 DEPTH 1
 DRESS
+DAMAGEABLE
 
 ARMOUR battle ballgown
 PLURAL battle ballgowns
@@ -341,6 +337,8 @@ POWER 3
 POWER2 10
 DEPTH 1
 DRESS
+DAMAGEABLE
+BREAK_REACT
 
 ARMOUR imperatrix gown
 PLURAL imperatrix gowns
@@ -353,9 +351,41 @@ POWER 15
 POWER2 10
 DEPTH 24
 DRESS
+DAMAGEABLE
+BREAK_REACT
+
+ARMOUR foetid vestments
+PLURAL sets of foetid vestments
+DESC These stained, reeking robes seem to harbour great power despite their half-rotten state.
+RARITY 90
+ASCII '['
+UTF8 "["
+COLOUR l_green
+POWER 15
+POWER2 0
+DEPTH 30
+NOTIFY_EQUIP
+DAMAGEABLE
+BREAK_REACT
+
+ARMOUR lich's robe
+PLURAL lich's robes
+DESC Separated from its ancient owner, this robe hums with magical power.
+RARITY 100
+ASCII '['
+UTF8 "["
+COLOUR purple
+POWER 15
+POWER2 0
+DEPTH 30
+NOTIFY_EQUIP
 
 # Mr Read would like to note that he invented the following item and its
 # game mechanics *before* becoming aware of the anime series _Kill la Kill_.
+#
+# Mr Read would also like to note that this item is why a paperdoll sprite
+# for the princess is not a planned feature of any official graphical port
+# of Victrix Abyssi.
 ARMOUR set of ribbons
 PLURAL sets of ribbons
 DESC These ribbons, arranged as if to form an alleged garment, make your fingers tingle with magic.
@@ -368,6 +398,8 @@ POWER2 -15
 DEPTH 30
 NOTIFY_EQUIP
 DRESS
+DAMAGEABLE
+BREAK_REACT
 
 RING regeneration ring
 PLURAL regeneration rings
@@ -434,6 +466,7 @@ COLOUR brown
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 FOOD parcel of dried fruit
 PLURAL parcels of dried fruit
@@ -445,6 +478,7 @@ COLOUR yellow
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 FOOD round of elven waybread
 PLURAL rounds of elven waybread
@@ -456,6 +490,7 @@ COLOUR white
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 FOOD devil spleen
 PLURAL devil spleens
@@ -467,6 +502,7 @@ COLOUR l_red
 POWER 0
 POWER2 0
 DEPTH 1
+STACKABLE
 
 CARRION corpse
 PLURAL corpses
index bae2a8b..f302143 100644 (file)
@@ -1101,11 +1101,19 @@ void get_player_action(Action *act)
             act->cmd = STAND_STILL;
             return;
         case '\x04':
-            act->cmd = WIZARD_DESCEND;
-            return;
+            if (wizard_mode)
+            {
+                act->cmd = WIZARD_DESCEND;
+                return;
+            }
+            break;
         case '\x05':
-            act->cmd = WIZARD_LEVELUP;
-            return;
+            if (wizard_mode)
+            {
+                act->cmd = WIZARD_LEVELUP;
+                return;
+            }
+            break;
         }
     }
     print_msg("BUG: broke out of input loop!\n");
@@ -1345,5 +1353,70 @@ static void run_main_menu(void)
     }
 }
 
+void welcome(void)
+{
+    print_msg("Welcome to the Abyss, Princess %s.\n", u.name);
+    print_msg("Press '?' for help.\n");
+}
+
+void describe_object(int obj)
+{
+    Obj *optr;
+    Permobj *poptr;
+    print_obj_name(obj);
+    optr = objects + obj;
+    poptr = permobjs + optr->obj_id;
+    print_msg("\n%s\n", poptr->description);
+}
+
+void print_obj_name(int obj)
+{
+    Obj *optr;
+    Permobj *poptr;
+    optr = objects + obj;
+    poptr = permobjs + optr->obj_id;
+    if (optr->quan > 1)
+    {
+        print_msg("%d %s", optr->quan, poptr->plural);
+    }
+    else if (po_is_stackable(optr->obj_id))
+    {
+        print_msg("1 %s", poptr->name);
+    }
+    else if ((poptr->poclass == POCLASS_WEAPON) ||
+             (poptr->poclass == POCLASS_ARMOUR))
+    {
+        print_msg("a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR);
+    }
+    else
+    {
+        print_msg("a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name);
+    }
+}
+
+void print_mon_name(int mon, int article)
+{
+    if (permons[monsters[mon].mon_id].name[0] == '\0')
+    {
+        print_msg("GROB THE VOID (%d)", monsters[mon].mon_id);
+        return;
+    }
+    switch (article)
+    {
+    case 0:     /* a */
+        print_msg("a%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
+        break;
+    case 1: /* the */
+        print_msg("the %s", permons[monsters[mon].mon_id].name);
+        break;
+    case 2: /* A */
+        print_msg("A%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
+        break;
+    case 3: /* The */
+        print_msg("The %s", permons[monsters[mon].mon_id].name);
+        break;
+    }
+}
+
 /* display-nc.cc */
 // vim:cindent
index 5ca99b2..6553451 100644 (file)
@@ -47,6 +47,7 @@ extern void pressanykey(void);
 extern void show_discoveries(void);
 extern void touch_one_screen(Coord c);
 extern bool query_wizmode_death(void);
+extern void welcome(void);
 
 /* "I've changed things that need to be redisplayed" flags. */
 extern bool hard_redraw;
diff --git a/fov.cc b/fov.cc
index fc96864..db670a8 100644 (file)
--- a/fov.cc
+++ b/fov.cc
@@ -407,7 +407,7 @@ void resolve_radiance(Radiance *rad)
         break;
 
     default:
-        print_msg("FATAL: attempt to use unimplemented radiance evaluation order %d\n", rad->order);
+        debug_unimplemented_radiance_order(rad->order);
         abort();
     }
 }
diff --git a/main.cc b/main.cc
index e94aa5a..0b050c3 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -265,7 +265,7 @@ Action_cost do_player_action(Action *act)
         }
         else
         {
-            print_msg("Nothing to get.\n");
+            notify_nothing_to_get();
             return Cost_none;
         }
 
@@ -312,20 +312,21 @@ Action_cost do_player_action(Action *act)
     case TAKE_OFF_ARMOUR:
         if (u.armour != NO_OBJ)
         {
+            int saved_armour = u.armour;
             if ((u.resistances[DT_FIRE] == RESIST_ARMOUR) &&
                 (lvl.terrain_at(u.pos) == LAVA))
             {
-                print_msg("Your armour is your only current source of fire\nresistance; removing it here would incinerate you.\n");
+                notify_lava_blocks_unequip();
                 return Cost_none;
             }
             u.armour = NO_OBJ;
             recalc_defence();
-            print_msg("You take off your armour.\n");
+            notify_armour_unequip(saved_armour);
             return Cost_std;
         }
         else
         {
-            print_msg("You aren't wearing any armour.\n");
+            debug_take_off_no_armour();
             return Cost_none;
         }
 
@@ -337,7 +338,7 @@ Action_cost do_player_action(Action *act)
         }
         else
         {
-            print_msg("There are no stairs here.\n");
+            debug_descend_non_stairs();
         }
         return Cost_none;
 
@@ -387,7 +388,7 @@ Action_cost do_player_action(Action *act)
         }
         else
         {
-            print_msg("You aren't a wizard.\n");
+            debug_wizmode_violation();
         }
         return Cost_none;
 
@@ -401,7 +402,7 @@ Action_cost do_player_action(Action *act)
         }
         else
         {
-            print_msg("You aren't a wizard.\n");
+            debug_wizmode_violation();
         }
         return Cost_none;
     }
@@ -412,8 +413,7 @@ void main_loop(void)
 {
     int i;
     int action_speed = 0;
-    print_msg("Welcome to the Abyss, Princess %s.\n", u.name);
-    print_msg("Press '?' for help.\n");
+    welcome();
     while (!game_finished)
     {
         switch (game_tick & 3)
diff --git a/map.cc b/map.cc
index 4c2a5f0..2c27773 100644 (file)
--- a/map.cc
+++ b/map.cc
@@ -204,9 +204,8 @@ static void run_random_walk(Coord oc, rwalk_mod_funcptr func,
     }
     if (bailout < 1)
     {
-        print_msg("Bailed out while excavating level!\n");
+        debug_excavation_bailout();
     }
-
 }
 
 /*! \brief Entry point for level generation.
@@ -661,27 +660,9 @@ void deserialize_chunk(FILE *fp, Chunk *c)
     static uint32_t deserializable_regions[CHUNK_EDGE][CHUNK_EDGE];
     int i;
     int j;
-    i = fread(deserializable_terrain, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    if (i != CHUNK_EDGE * CHUNK_EDGE)
-    {
-        print_msg("deserialize_chunk expected %d got %d line %d\n",
-                  CHUNK_EDGE * CHUNK_EDGE, i, __LINE__);
-        throw(errno);
-    }
-    i = fread(deserializable_flags, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    if (i != CHUNK_EDGE * CHUNK_EDGE)
-    {
-        print_msg("deserialize_chunk expected %d got %d line %d\n",
-                  CHUNK_EDGE * CHUNK_EDGE, i, __LINE__);
-        throw(errno);
-    }
-    i = fread(deserializable_regions, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    if (i != CHUNK_EDGE * CHUNK_EDGE)
-    {
-        print_msg("deserialize_chunk expected %d got %d line %d\n",
-                  CHUNK_EDGE * CHUNK_EDGE, i, __LINE__);
-        throw(errno);
-    }
+    wrapped_fread(deserializable_terrain, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
+    wrapped_fread(deserializable_flags, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
+    wrapped_fread(deserializable_regions, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
     for (i = 0; i < CHUNK_EDGE; ++i)
     {
         for (j = 0; j < CHUNK_EDGE; ++j)
diff --git a/mon2.cc b/mon2.cc
index 0b40437..8e8b10a 100644 (file)
--- a/mon2.cc
+++ b/mon2.cc
@@ -591,15 +591,14 @@ void mon_acts(int mon)
     oncardinal = delta.rcardinal();
     if (delta.len_cheb() == 0)
     {
-        print_msg("Program disordered: monster in player's square.\n");
-        print_msg("Discarding misplaced monster.\n");
+        debug_misplaced_monster();
         mptr->used = false;
         lvl.set_mon_at(c, NO_MON);
         return;
     }
     if (lvl.mon_at(c) != mon)
     {
-        print_msg("Program disordered: monster(s) misplaced.\n");
+        debug_misplaced_monster();
         mptr->used = false;
         if (lvl.mon_at(c) != NO_MON)
         {
index 082fc7c..5d5fb4f 100644 (file)
@@ -2,7 +2,7 @@
  *  \brief Monster-related functions
  */
 
-/* Copyright 2005-2013 Martin Read
+/* Copyright 2005-2014 Martin Read
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -107,7 +107,7 @@ int create_mon(int pm_idx, Coord c)
     int mon;
     if (lvl.mon_at(c) != NO_MON)
     {
-        print_msg("Attempt to create monster at occupied space %d %d\n", c.y, c.x);
+        debug_create_mon_occupied(c);
         return NO_MON;
     }
     if (pm_idx == NO_PMON)
@@ -115,6 +115,7 @@ int create_mon(int pm_idx, Coord c)
         pm_idx = get_random_pmon();
         if (pm_idx == NO_PMON)
         {
+            debug_pmon_select_failed();
             return NO_MON;
         }
     }
@@ -280,30 +281,6 @@ bool Mon::can_pass(Coord c) const
     return true;
 }
 
-void print_mon_name(int mon, int article)
-{
-    if (permons[monsters[mon].mon_id].name[0] == '\0')
-    {
-        print_msg("GROB THE VOID (%d)", monsters[mon].mon_id);
-        return;
-    }
-    switch (article)
-    {
-    case 0:     /* a */
-        print_msg("a%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
-        break;
-    case 1: /* the */
-        print_msg("the %s", permons[monsters[mon].mon_id].name);
-        break;
-    case 2: /* A */
-        print_msg("A%s %s", is_vowel(permons[monsters[mon].mon_id].name[0]) ? "n" : "", permons[monsters[mon].mon_id].name);
-        break;
-    case 3: /* The */
-        print_msg("The %s", permons[monsters[mon].mon_id].name);
-        break;
-    }
-}
-
 void heal_mon(int mon, int amount, int cansee)
 {
     if (amount > (monsters[mon].hpmax - monsters[mon].hpcur))
@@ -314,8 +291,7 @@ void heal_mon(int mon, int amount, int cansee)
     {
         if (cansee)
         {
-            print_mon_name(mon, 3);
-            print_msg(" looks healthier.\n");
+            notify_mon_healed(mon);
         }
         monsters[mon].hpcur += amount;
     }
@@ -329,22 +305,12 @@ void damage_mon(int mon, int amount, bool by_you)
     {
         if (by_you)
         {
-            print_msg("You kill ");
-            if (mon_visible(mon))
-            {
-                print_mon_name(mon, 1);
-            }
-            else
-            {
-                print_msg("something");
-            }
-            print_msg("!\n");
+            notify_player_killed_mon(mon);
             gain_experience(permons[mptr->mon_id].exp);
         }
         else if (mon_visible(mon))
         {
-            print_mon_name(mon, 2);
-            print_msg(" dies.\n");
+            notify_mon_dies(mon);
         }
         death_drop(mon);
         lvl.set_mon_at(mptr->pos, NO_MON);
@@ -375,6 +341,7 @@ Pass_fail teleport_mon_to_you(int mon)
     Coord c;
     int success = 0;
     Mon *mptr = monsters + mon;
+    Coord oldpos = mptr->pos;
     for (tryct = 0; tryct < 40; tryct++)
     {
         delta = random_step();
@@ -388,8 +355,7 @@ Pass_fail teleport_mon_to_you(int mon)
     if (success)
     {
         reloc_mon(mon, c);
-        print_mon_name(mon, 2);
-        print_msg(" appears in a puff of smoke.\n");
+        notify_mon_appears(mon);
         return You_pass;
     }
     return You_fail;
@@ -425,15 +391,16 @@ int knockback_mon(int mon, Offset step, bool cansee, bool by_you)
     {
         if (cansee)
         {
-            print_mon_name(mon, 3);
-            print_msg(" wobbles slightly.\n");
+            notify_knockback_mon_resisted(mon);
         }
         return 0;
     }
     if (terrain_blocks_beings(terr))
     {
-        print_mon_name(mon, 3);
-        print_msg(" is slammed against the wall.\n");
+        if (cansee)
+        {
+            notify_knockback_mon_blocked(mon);
+        }
         return 0;
     }
     switch (terr)
@@ -443,20 +410,18 @@ int knockback_mon(int mon, Offset step, bool cansee, bool by_you)
         {
             if (cansee)
             {
-                print_mon_name(mon, 3);
-                print_msg(" is hurled out over the lava.\n");
+                notify_knockback_mon_hover_lava(mon);
             }
         }
         else
         {
             if (cansee)
             {
-                print_mon_name(mon, 3);
-                print_msg(" tumbles into a pool of molten rock.\n");
+                notify_knockback_mon_immersed_lava(mon);
             }
             else
             {
-                print_msg("Splut!\n");
+                notify_knockback_mon_lava_offscreen();
             }
             if (!mptr->resists(DT_FIRE))
             {
@@ -470,20 +435,18 @@ int knockback_mon(int mon, Offset step, bool cansee, bool by_you)
         {
             if (cansee)
             {
-                print_mon_name(mon, 3);
-                print_msg(" is hurled out over the water.\n");
+                notify_knockback_mon_hover_water(mon);
             }
         }
         else
         {
             if (cansee)
             {
-                print_mon_name(mon, 3);
-                print_msg(" tumbles into the water.\n");
+                notify_knockback_mon_immersed_water(mon);
             }
             else
             {
-                print_msg("Splash!\n");
+                notify_knockback_mon_water_offscreen();
             }
             if (!mptr->resists(DT_DROWNING))
             {
@@ -515,13 +478,12 @@ void move_mon(int mon, Coord c)
     mptr = monsters + mon;
     if (!mptr->can_pass(c))
     {
-        print_msg("Warning: monster attempted an invalid move.\n");
+        debug_mon_invalid_move(mon, c);
         return;
     }
     if (lvl.mon_at(mptr->pos) != mon)
     {
-        print_msg("Monster map array in disorder.\n");
-        press_enter();
+        debug_misplaced_monster();
         return;
     }
     reloc_mon(mon, c);
@@ -531,19 +493,12 @@ void move_mon(int mon, Coord c)
 void summon_demon_near(Coord c)
 {
     Coord c2 = c + random_step();
-    int i;
+    int mon;
     if ((lvl.terrain_at(c2) == FLOOR) && (lvl.mon_at(c2) == NO_MON) &&
         (c2 != u.pos))
     {
-        i = create_mon(PM_DEMON, c2);
-        if (i != NO_MON)
-        {
-            print_msg("Another demon appears!\n");
-        }
-        else
-        {
-            print_msg("You smell sulphurous fumes.\n");
-        }
+        mon = create_mon(PM_DEMON, c2);
+        notify_summon_demon(mon);
     }
 }
 
@@ -571,6 +526,7 @@ void update_mon(int mon)
     if (monsters[mon].hpcur < monsters[mon].hpmax)
     {
         cansee = mon_visible(mon);
+        // TODO modify regen handling to use flags/fields instead of switching on mon_id
         switch (monsters[mon].mon_id)
         {
         case PM_TROLL:
@@ -578,7 +534,7 @@ void update_mon(int mon)
             {
                 if (cansee)
                 {
-                    print_msg("The troll regenerates.\n");
+                    notify_mon_regenerates(mon);
                 }
                 heal_mon(mon, one_die(3) + 3, 0);
             }
index 62a7a21..9b5f37c 100644 (file)
@@ -262,6 +262,18 @@ void notify_summon_help(int mon, bool success)
     }
 }
 
+void notify_summon_demon(int mon)
+{
+    if (mon != NO_MON)
+    {
+        print_msg("Another demon appears!\n");
+    }
+    else
+    {
+        print_msg("You smell sulphurous fumes.\n");
+    }
+}
+
 void notify_mon_disappear(int mon)
 {
     print_mon_name(mon, 3);
@@ -317,11 +329,6 @@ void notify_no_attackee(void)
     print_msg("Nothing to attack.\n");
 }
 
-void notify_knockback_mon_fail(void)
-{
-    print_msg("Your foe staggers a little.\n");
-}
-
 void notify_knockback_mon_pass(void)
 {
     print_msg("Your foe is knocked backwards by the force of the shot.\n");
@@ -373,6 +380,82 @@ void notify_player_hurt_mon(int mon, int damage)
     print_msg("You do %d damage.\n", damage);
 }
 
+void notify_player_killed_mon(int mon)
+{
+    print_msg("You kill ");
+    if (mon_visible(mon))
+    {
+        print_mon_name(mon, 1);
+    }
+    else
+    {
+        print_msg("something");
+    }
+    print_msg("!\n");
+}
+
+void notify_mon_dies(int mon)
+{
+    print_mon_name(mon, 2);
+    print_msg(" dies.\n");
+}
+
+void notify_knockback_mon_resisted(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" wobbles slightly.\n");
+}
+
+void notify_knockback_mon_blocked(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" is slammed against the wall.\n");
+}
+
+void notify_knockback_mon_hover_lava(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" is hurled out over the lava.\n");
+}
+
+void notify_knockback_mon_hover_water(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" is hurled out over the water.\n");
+}
+
+void notify_knockback_mon_immersed_lava(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" tumbles into a pool of molten rock.\n");
+}
+
+void notify_knockback_mon_immersed_water(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" tumbles into the water.\n");
+}
+
+void notify_knockback_mon_lava_offscreen(void)
+{
+    print_msg("Splut!\n");
+}
+
+void notify_knockback_mon_water_offscreen(void)
+{
+    print_msg("Splash!\n");
+}
+
+void notify_mon_disappears(int mon, Coord oldpos)
+{
+}
+
+void notify_mon_appears(int mon)
+{
+    print_mon_name(mon, 2);
+    print_msg(" appears in a puff of smoke.\n");
+}
+
 void notify_mon_hit_armour(int mon)
 {
     print_msg("Your armour deflects ");
@@ -392,6 +475,38 @@ void notify_mon_hit_player(int mon)
     print_msg(" hits you.\n");
 }
 
+void notify_mon_ranged_attack(int mon)
+{
+    int pm = monsters[mon].mon_id;
+    Damtyp dt = permons[pm].rdtyp;
+    print_mon_name(mon, 3);
+    if (dt == DT_PHYS)
+    {
+        print_msg(" %s at you!\n", permons[pm].shootverb);
+    }
+    else
+    {
+        print_msg(" %s %s at you!\n", permons[pm].shootverb, damtype_names[dt]);
+    }
+}
+
+void notify_mon_ranged_hit_mon(int er, int ee)
+{
+    // TODO make this message specific and non-sucky.
+    print_msg("It hits a bystander.\n");
+}
+
+void notify_mon_ranged_missed_player(int mon)
+{
+    print_msg("It misses you.\n");
+}
+
+void notify_mon_ranged_hit_player(int mon)
+{
+    print_msg("It hits you!\n");
+}
+
+
 void notify_no_flask_target(void)
 {
     print_msg("That would be a waste; there's nobody to throw it at.\n");
@@ -412,6 +527,21 @@ void notify_zap_no_weapon(void)
     print_msg("You have no weapon in hand.\n");
 }
 
+void notify_magic_powerless_ring(void)
+{
+    print_msg("Your current ring seems to have no magic powers to activate.\n");
+}
+
+void notify_emanate_powerless_armour(void)
+{
+    print_msg("Your current attire seems to have no magic powers to activate.\n");
+}
+
+void notify_zap_powerless_weapon(void)
+{
+    print_msg("Your current weapon seems to have no magic powers to activate.\n");
+}
+
 void notify_armour_equip(void)
 {
     Permobj *pobj = permobjs + objects[u.armour].obj_id;
@@ -435,6 +565,22 @@ void notify_armour_equip(void)
     }
 }
 
+void notify_armour_unequip(int obj)
+{
+    // TODO add unequip messages for NOTIFY_EQUIP armours.
+    print_msg("You take off your armour.\n");
+}
+
+void notify_lava_blocks_unequip(void)
+{
+    print_msg("That item is your only current source of fire resistance; setting it aside here would incinerate you.\n");
+}
+
+void notify_water_blocks_unequip(void)
+{
+    print_msg("Setting that item aside here would cause your death by drowning.\n");
+}
+
 void notify_player_touch_effect(Damtyp dt)
 {
     switch (dt)
@@ -500,6 +646,104 @@ void notify_read_scroll_protection(void)
     print_msg("You feel like something is helping you.\n");
 }
 
+void notify_telering_activation(int specific)
+{
+    switch (specific)
+    {
+    case 0:
+        print_msg("You are too hungry to activate your ring's power.\n");
+        break;
+    case 1:
+        print_msg("You activate your ring's power of teleportation.\n");
+        break;
+    case 2:
+        print_msg("BUG: Some clown thinks teleport rings have a 'item isn't hungry' message.\n");
+        break;
+    case 3:
+        print_msg("BUG: Some clown thinks teleport rings have a 'item force-activates itself' message.\n");
+        break;
+    default:
+        print_msg("BUG: notify_telering_activation called with invalid subcode %d\n", specific);
+        break;
+    }
+}
+
+void notify_firestaff_activation(int specific)
+{
+    switch (specific)
+    {
+    case 0:
+        print_msg("You are too hungry to activate your staff's power.\n");
+        break;
+    case 1:
+        print_msg("You unleash the fiery powers of your staff!\n");
+        break;
+    case 2:
+        print_msg("BUG: Some clown thinks staves of fire have a 'item isn't hungry' message.\n");
+        break;
+    case 3:
+        print_msg("BUG: Some clown thinks staves of fire have a 'item force-activates itself' message.\n");
+        break;
+    default:
+        print_msg("BUG: notify_firestaff_activation called with invalid subcode %d\n", specific);
+        break;
+    }
+}
+
+void notify_fireitem_hit(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" is engulfed in roaring flames.\n");
+}
+
+void notify_lash_activation(int specific)
+{
+    switch (specific)
+    {
+    case 0:
+        print_msg("You are too hungry to willingly let the lash draw on your strength.\n");
+        break;
+    case 1:
+        if (u.sympathy[FePo_flesh] > 10)
+        {
+            print_msg("A delightful tingle runs up your arm as the lash draws on your strength to repair itself.\n");
+        }
+        else
+        {
+            print_msg("A pins-and-needles sensation runs up your arm as the lash draws on your strength to repair itself.\n");
+        }
+        break;
+    case 2:
+        print_msg("The lash is undamaged; it hungers not for your strength.\n");
+        break;
+    case 3:
+        print_msg("Pain explodes%s through your arm as the lash restores itself!\n", (u.sympathy[FePo_flesh] > 10) ? " delightfully" : "");
+        break;
+    default:
+        print_msg("BUG: notify_ribbon_activation called with invalid subcode %d\n", specific);
+        break;
+    }
+}
+
+void notify_ribbon_activation(int specific)
+{
+    switch (specific)
+    {
+    case 0:
+        print_msg("You are too hungry to willingly let the ribbons draw on your strength.\n");
+        break;
+    case 1:
+        print_msg("You gasp%s as the ribbons draw on your strength to repair themselves.\n", (u.sympathy[FePo_flesh] > 10) ? " in delight" : "");
+        break;
+    case 2:
+        print_msg("The ribbons are undamaged; they hunger not for your strength.\n");
+        break;
+    default:
+        print_msg("BUG: notify_ribbon_activation called with invalid subcode %d\n", specific);
+        break;
+    }
+}
+
 void notify_dress_shredded(void)
 {
     print_msg("Your dress has been reduced to a tattered wreck.\n");
@@ -510,11 +754,94 @@ void notify_eat_food(bool ravenous)
     print_msg(ravenous ? "You ravenously devour your food!\n" : "You eat some food.\n");
 }
 
+void notify_ingest_spleen(void)
+{
+    print_msg("%s power suffuses your body as you devour the devil spleen.\n", u.corrupt() ? "Delicious" : "Vile");
+}
+
 void notify_quaff_potion_restoration(void)
 {
     print_msg("This potion makes you feel warm all over.\n");
 }
 
+void notify_nothing_to_get(void)
+{
+    print_msg("Nothing to get.\n");
+}
+
+void notify_mon_healed(int mon)
+{
+    print_mon_name(mon, 3);
+    print_msg(" looks healthier.\n");
+}
+
+void notify_mon_regenerates(int mon)
+{
+    // TODO allow things that aren't trolls to be regenerators
+    print_msg("The troll regenerates.\n");
+}
+
+void notify_unwield(int obj, Noisiness noisy)
+{
+    if (noisy == Noise_std)
+    {
+        print_msg("Weapon unwielded.\n");
+    }
+}
+
+void notify_wield_weapon(int obj)
+{
+    print_msg("Wielding ");
+    print_obj_name(obj);
+    print_msg(".\n");
+}
+
+void notify_weapon_broke(int obj)
+{
+    print_msg("Your weapon breaks!\n");
+}
+
+void notify_armour_broke(int obj)
+{
+    print_msg("Your armour is ruined!\n");
+}
+
+void notify_drop_item(int obj)
+{
+    print_msg("You drop ");
+    print_obj_name(obj);
+    print_msg(".\n");
+}
+
+void notify_drop_blocked(void)
+{
+    print_msg("There is already an item here.\n");
+}
+
+void notify_get_item(int from, int slot)
+{
+    if (from)
+    {
+        print_msg("You get ");
+        print_obj_name(from);
+        print_msg(".\nYou now have\n");
+        print_msg("%c) ", 'a' + slot);
+        print_obj_name(u.inventory[slot]);
+        print_msg("\n");
+    }
+    else
+    {
+        print_msg("You now have\n");
+        print_msg("%c) ", 'a' + slot);
+        print_obj_name(u.inventory[slot]);
+        print_msg("\n");
+    }
+}
+
+void notify_pack_full(void)
+{
+    print_msg("Your pack is full.\n");
+}
 /* Debugging notifications */
 
 void debug_bad_monspell(int spell)
@@ -592,5 +919,85 @@ void debug_quaff_non_potion(void)
     print_msg("Impossible: quaffing non-potion\n");
 }
 
+void debug_descend_non_stairs(void)
+{
+    print_msg("BUG: Received use-stairs command standing on non-stairs.\n");
+}
+
+void debug_wizmode_violation(void)
+{
+    print_msg("BUG: Received wizmode command when not in wizmode.\n");
+}
+
+void debug_take_off_no_armour(void)
+{
+    print_msg("BUG: Taking off armour when no armour equipped.\n");
+}
+
+void debug_excavation_bailout(void)
+{
+    print_msg("BUG: Bailed out while excavating level!\n");
+}
+
+void debug_object_pool_exhausted(void)
+{
+    print_msg("NOTICE: Ran out of objects[].\n");
+}
+
+void debug_pobj_select_failed(void)
+{
+    print_msg("NOTICE: Failed to choose a permobj.\n");
+}
+
+void debug_misplaced_monster(void)
+{
+    print_msg("BUG: Misplaced monster detected.\n");
+}
+
+void debug_create_mon_occupied(Coord c)
+{
+    print_msg("BUG: Attempt to create mon at occupied space y=%d x=%d\n", c.y, c.x);
+}
+
+void debug_monster_pool_exhauseted(void)
+{
+    print_msg("NOTICE: Ran out of monsters[].\n");
+}
+
+void debug_pmon_select_failed(void)
+{
+    print_msg("BUG: Failed to choose a permon.\n");
+}
+
+void debug_dump_write_failed(void)
+{
+    print_msg("NOTICE: Couldn't create dump file. Dump failed.\n");
+}
+
+void debug_unwield_nothing(void)
+{
+    print_msg("BUG: got to player_unwield() with no weapon wielded - have a quiet word with your HCI module's author, please.\n");
+}
+
+void debug_unimplemented_activation(int po)
+{
+    print_msg("BUG: permobj %d should be activatable but has no activation handler.\n");
+}
+
+void debug_unimplemented_break_reaction(int po)
+{
+    print_msg("BUG: permobj %d should react to hitting durability 0 but has no break reaction handler.\n");
+}
+
+void debug_mon_invalid_move(int mon, Coord c)
+{
+    print_msg("BUG: monster %d attempted move to impassable location y=%d x=%d\n", mon, c.y, c.x);
+}
+
+void debug_unimplemented_radiance_order(int order)
+{
+    print_msg("FATAL: attempt to use unimplemented radiance evaluation order %d\n", order);
+}
+
 /* notify-local-tty.cc */
 // vim:cindent
index 847f5e3..80a81f0 100644 (file)
--- a/notify.hh
+++ b/notify.hh
@@ -62,20 +62,46 @@ void notify_cant_go(void);
 // Unsorted notifications
 void notify_obj_at(Coord c);
 void notify_dress_shredded(void);
+void notify_mon_healed(int mon);
+void notify_mon_regenerates(int mon);
+void notify_mon_disappears(int mon, Coord oldpos);
+void notify_mon_appears(int mon);
 
 // Item manipulation notifications
 void notify_magic_no_ring(void);
 void notify_emanate_no_armour(void);
 void notify_zap_no_weapon(void);
+void notify_magic_powerless_ring(void);
+void notify_emanate_powerless_armour(void);
+void notify_zap_powerless_weapon(void);
 void notify_armour_equip(void);
+void notify_armour_unequip(int obj);
+void notify_lava_blocks_unequip(void);
+void notify_water_blocks_unequip(void);
+void notify_nothing_to_get(void);
+void notify_unwield(int obj, Noisiness noisy);
+void notify_wield_weapon(int obj);
+void notify_weapon_broke(int obj);
+void notify_armour_broke(int obj);
+void notify_drop_item(int obj);
+void notify_drop_blocked(void);
+void notify_get_item(int from, int slot);
+void notify_pack_full(void);
 
 // Magic item use releated notifications
 void notify_read_scroll_protection(void);
 
 void notify_quaff_potion_restoration(void);
 
+void notify_ribbon_activation(int specific);
+void notify_lash_activation(int specific);
+void notify_firestaff_activation(int specific);
+void notify_fireitem_hit(int mon);
+void notify_telering_activation(int specific);
+
 void notify_item_explodes_flames(int obj);
 void notify_eat_food(bool ravenous);
+void notify_ingest_spleen(void);
 
 // combat notifications
 void notify_swing_bow(void);
@@ -85,18 +111,34 @@ void notify_player_miss(int mon);
 void notify_ring_boost(int mon, int pobj);
 void notify_player_hit_mon(int mon);
 void notify_player_hurt_mon(int mon, int damage);
-void notify_knockback_mon_pass(void);
-void notify_knockback_mon_fail(void);
+void notify_player_killed_mon(int mon);
+void notify_knockback_mon_resisted(int mon);
+void notify_knockback_mon_blocked(int mon);
+void notify_knockback_mon_hover_lava(int mon);
+void notify_knockback_mon_hover_water(int mon);
+void notify_knockback_mon_immersed_lava(int mon);
+void notify_knockback_mon_immersed_water(int mon);
+void notify_knockback_mon_water_offscreen(void);
+void notify_knockback_mon_lava_offscreen(void);
+
 void notify_player_shot_terrain(int obj, Coord c);
+
 void notify_mon_hit_armour(int mon);
 void notify_mon_missed_player(int mon);
 void notify_mon_hit_player(int mon);
+void notify_mon_ranged_attack(int mon);
+void notify_mon_ranged_hit_player(int mon);
+void notify_mon_ranged_missed_player(int mon);
+void notify_mon_ranged_hit_mon(int er, int ee);
+void notify_mon_dies(int mon);
+
 void notify_player_damage_taken(int amount);
 void notify_player_touch_effect(Damtyp dt);
 void notify_player_ignore_damage(Damtyp dt);
 
 // Sorcery notifications
 void notify_summon_help(int mon, bool success);
+void notify_summon_demon(int mon);
 void notify_monster_cursing(int mon);
 void notify_mon_disappear(int mon);
 void notify_moncurse_fail(void);
@@ -117,12 +159,28 @@ void debug_bad_damage_type(int dt);
 void debug_unimplemented(void);
 void debug_wear_while_wearing(void);
 void debug_wear_uncarried_armour(void);
+void debug_unwield_nothing(void);
+void debug_take_off_no_armour(void);
 void debug_remove_no_ring(void);
 void debug_put_on_second_ring(void);
 void debug_put_on_uncarried_ring(void);
 void debug_eat_non_food(int obj);
 void debug_read_non_scroll(void);
 void debug_quaff_non_potion(void);
+void debug_descend_non_stairs(void);
+void debug_wizmode_violation(void);
+void debug_excavation_bailout(void);
+void debug_object_pool_exhausted(void);
+void debug_pobj_select_failed(void);
+void debug_misplaced_monster(void);
+void debug_create_mon_occupied(Coord c);
+void debug_monster_pool_exhausted(void);
+void debug_mon_invalid_move(int mon, Coord c);
+void debug_pmon_select_failed(void);
+void debug_dump_write_failed(void);
+void debug_unimplemented_activation(int po);
+void debug_unimplemented_break_reaction(int po);
+void debug_unimplemented_radiance_order(int order);
 
 #endif
 
index aa843da..d03cc2c 100644 (file)
@@ -79,8 +79,7 @@ Action_cost read_scroll(int obj)
             {
                 if (!pmon_resists_fire(monsters[i].mon_id))
                 {
-                    //print_mon_name(i, 3);
-                    //print_msg(" is burned.\n");
+                    notify_fireitem_hit(i);
                     damage_mon(i, dice(4, 10), true);
                 }
             }
@@ -130,25 +129,15 @@ bool consume_obj(int obj)
         {
             if (obj == u.armour)
             {
-                if ((objects[obj].obj_id == PO_BATTLE_BALLGOWN) ||
-                    (objects[obj].obj_id == PO_IMPERATRIX_GOWN))
-                {
-                    objects[obj].quan = 1;
-                    objects[obj].used = true;
-                    objects[obj].durability = 50 + zero_die(51);
-                    objects[obj].obj_id = PO_RAGGED_SHIFT;
-                    notify_dress_shredded();
-                }
-                else
-                {
-                    u.armour = NO_OBJ;
-                }
+                u.armour = NO_OBJ;
                 recalc_defence();
+                notify_armour_broke(obj);
             }
             else if (obj == u.weapon)
             {
                 u.weapon = NO_OBJ;
                 recalc_defence();
+                notify_weapon_broke(obj);
             }
             else if (obj == u.ring)
             {
@@ -182,7 +171,7 @@ Action_cost eat_food(int obj)
     }
     if (optr->obj_id == PO_DEVIL_SPLEEN)
     {
-        print_msg("Vile power suffuses your body as you devour the devil\nspleen.\n");
+        notify_ingest_spleen();
         if (zero_die(2))
         {
             gain_body(1);
@@ -191,8 +180,8 @@ Action_cost eat_food(int obj)
         {
             gain_agility(1);
         }
-        // TODO
-        // gain_power(Power_demonic);
+        // TODO add more tracking state to this item so we don't have to randomize the fell power choice
+        ++u.sympathy[zero_die(TOTAL_FELL_POWERS)];
     }
     else
     {
@@ -319,11 +308,9 @@ void flavours_init(void)
     permobjs[PO_RESTORATION_POTION].power = colour_choices[3];
 }
 
-int create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coord c)
+int get_first_free_obj(void)
 {
     int obj;
-    int po_idx;
-    int tryct;
     for (obj = 0; obj < 100; obj++)
     {
         if (!objects[obj].used)
@@ -331,9 +318,17 @@ int create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coo
             break;
         }
     }
+    return (obj == 100) ? NO_OBJ : obj;
+}
+
+int create_obj_class(enum poclass_num po_class, int quantity, bool with_you, Coord c)
+{
+    int po_idx;
+    int tryct;
+    int obj = get_first_free_obj();
     if (obj == 100)
     {
-        print_msg("ERROR: Ran out of objects[].\n");
+        debug_object_pool_exhausted();
         return NO_OBJ;
     }
     for (tryct = 0; tryct < 200; tryct++)
@@ -391,17 +386,10 @@ int get_random_pobj(void)
 
 int create_obj(int po_idx, int quantity, bool with_you, Coord c)
 {
-    int i;
-    for (i = 0; i < 100; i++)
-    {
-        if (!objects[i].used)
-        {
-            break;
-        }
-    }
-    if (i == 100)
+    int obj = get_first_free_obj();
+    if (obj == 100)
     {
-        print_msg("ERROR: Ran out of objects[].\n");
+        debug_object_pool_exhausted();
         return NO_OBJ;
     }
     if (po_idx == NO_POBJ)
@@ -409,14 +397,15 @@ int create_obj(int po_idx, int quantity, bool with_you, Coord c)
         po_idx = get_random_pobj();
         if (po_idx == NO_POBJ)
         {
+            debug_pobj_select_failed();
             return NO_OBJ;
         }
     }
-    objects[i].obj_id = po_idx;
-    objects[i].with_you = with_you;
-    objects[i].used = true;
-    objects[i].pos = c;
-    objects[i].quan = quantity;
+    objects[obj].obj_id = po_idx;
+    objects[obj].with_you = with_you;
+    objects[obj].used = true;
+    objects[obj].pos = c;
+    objects[obj].quan = quantity;
     switch (permobjs[po_idx].poclass)
     {
     case POCLASS_WEAPON:
@@ -424,16 +413,16 @@ int create_obj(int po_idx, int quantity, bool with_you, Coord c)
         /* Set durability of weapons and armour to a suitable value.
          * 100 has been chosen for the moment, but this may need
          * tuning. */
-        objects[i].durability = OBJ_MAX_DUR;
+        objects[obj].durability = OBJ_MAX_DUR;
         break;
     default:
         break;
     }
-    if (!objects[i].with_you)
+    if (!objects[obj].with_you)
     {
-        lvl.set_obj_at(c, i);
+        lvl.set_obj_at(c, obj);
     }
-    return i;
+    return obj;
 }
 
 void sprint_obj_name(char *buf, int obj, int len)
@@ -486,31 +475,6 @@ void fprint_obj_name(FILE *fp, int obj)
     }
 }
 
-void print_obj_name(int obj)
-{
-    Obj *optr;
-    Permobj *poptr;
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
-    if (optr->quan > 1)
-    {
-        print_msg("%d %s", optr->quan, poptr->plural);
-    }
-    else if (po_is_stackable(optr->obj_id))
-    {
-        print_msg("1 %s", poptr->name);
-    }
-    else if ((poptr->poclass == POCLASS_WEAPON) ||
-             (poptr->poclass == POCLASS_ARMOUR))
-    {
-        print_msg("a%s %s (%d/%d)", is_vowel(poptr->name[0]) ? "n" : "", poptr->name, optr->durability, OBJ_MAX_DUR);
-    }
-    else
-    {
-        print_msg("a%s %s", is_vowel(poptr->name[0]) ? "n" : "", poptr->name);
-    }
-}
-
 Action_cost drop_obj(int inv_idx)
 {
     Obj *optr;
@@ -525,14 +489,12 @@ Action_cost drop_obj(int inv_idx)
         }
         u.inventory[inv_idx] = NO_OBJ;
         optr->with_you = false;
-        print_msg("You drop ");
-        print_obj_name(lvl.obj_at(u.pos));
-        print_msg(".\n");
+        notify_drop_item(lvl.obj_at(u.pos));
         return Cost_std;
     }
     else
     {
-        print_msg("There is already an item here.\n");
+        notify_drop_blocked();
         return Cost_none;
     }
 }
@@ -561,15 +523,11 @@ void attempt_pickup(void)
         {
             if ((objects[u.inventory[i]].obj_id == objects[lvl.obj_at(u.pos)].obj_id))
             {
-                print_msg("You get ");
-                print_obj_name(lvl.obj_at(u.pos));
-                print_msg(".\nYou now have\n");
+                int stale_obj = lvl.obj_at(u.pos);
                 objects[u.inventory[i]].quan += objects[lvl.obj_at(u.pos)].quan;
-                objects[lvl.obj_at(u.pos)].used = false;
+                objects[stale_obj].used = false;
                 lvl.set_obj_at(u.pos, NO_OBJ);
-                print_msg("%c) ", 'a' + i);
-                print_obj_name(u.inventory[i]);
-                print_msg("\n");
+                notify_get_item(stale_obj, i);
                 return;
             }
         }
@@ -583,96 +541,94 @@ void attempt_pickup(void)
     }
     if (i == 19)
     {
-        print_msg("Your pack is full.\n");
+        notify_pack_full();
         return;
     }
     u.inventory[i] = lvl.obj_at(u.pos);
     lvl.set_obj_at(u.pos, NO_OBJ);
     objects[u.inventory[i]].with_you = true;
     objects[u.inventory[i]].pos = Nowhere;
-    print_msg("You now have\n");
-    print_msg("%c) ", 'a' + i);
-    print_obj_name(u.inventory[i]);
-    print_msg("\n");
+    notify_get_item(NO_OBJ, i);
 }
 
-void damage_obj(int obj)
+void break_reaction(int obj)
 {
-    /* Only weapons and armour have non-zero durability. */
-    if (objects[obj].durability == 0)
+    switch (objects[obj].obj_id)
     {
-        /* Break the object. Weapons and armour don't stack. */
-        if (obj == u.weapon)
+    case PO_SET_OF_RIBBONS:
+        if (u.food < 500)
         {
-            print_msg("Your weapon breaks!\n");
+            int shortfall = (u.food < 0) ? 500 : 500 - u.food;
+            int damage = (shortfall + 24) / 25;
+            u.food = (u.food < 0) ? u.food : 0;
+            notify_ribbon_activation(3);
+            damage_u(damage, DEATH_RIBBONS, "");
         }
-        else if (obj == u.armour)
+        else
         {
-            print_msg("Your armour is ruined!\n");
+            u.food -= 500;
+            objects[obj].durability = 100;
+            notify_ribbon_activation(1);
         }
+        break;
+
+    case PO_TORMENTORS_LASH:
+        if (u.food < 500)
+        {
+            int shortfall = (u.food < 0) ? 500 : 500 - u.food;
+            int damage = (shortfall + 24) / 25;
+            u.food = (u.food < 0) ? u.food : 0;
+            notify_lash_activation(3);
+            damage_u(damage, DEATH_LASH, "");
+        }
+        else
+        {
+            u.food -= 500;
+            objects[obj].durability = 100;
+            notify_lash_activation(1);
+        }
+        break;
+
+    default:
+        if (permobjs[objects[obj].obj_id].flags[0] & POF_DRESS)
+        {
+            objects[obj].durability = 50 + zero_die(51);
+            objects[obj].obj_id = PO_RAGGED_SHIFT;
+            notify_dress_shredded();
+            recalc_defence();
+        }
+        else
+        {
+            debug_unimplemented_break_reaction(objects[obj].obj_id);
+        }
+        break;
+    }
+}
+
+void damage_obj(int obj)
+{
+    /* Only weapons and armour have non-zero durability. */
+    if (objects[obj].durability == 0)
+    {
+        /* Break the object. Weapons and armour don't stack. */
         consume_obj(obj);
     }
     else
     {
         objects[obj].durability--;
-        if (objects[obj].durability == 0)
+        if ((objects[obj].durability == 0) && (permobjs[objects[obj].obj_id].flags[0] & POF_BREAK_REACT))
         {
-            switch (objects[obj].obj_id)
-            {
-            case PO_SET_OF_RIBBONS:
-                if (u.food < 500)
-                {
-                    int shortfall = (u.food < 0) ? 500 : 500 - u.food;
-                    int damage = (shortfall + 24) / 25;
-                    u.food = (u.food < 0) ? u.food : 0;
-                    print_msg("Blood trickles from your nose as the ribbons drain your\nstrength repair themselves.\n");
-                    damage_u(damage, DEATH_RIBBONS, "");
-                }
-                else
-                {
-                    print_msg("You gasp as the ribbons drain your strength to repair\nthemselves.\n");
-                    u.food -= 500;
-                }
-                break;
-
-            case PO_TORMENTORS_LASH:
-                if (u.food < 500)
-                {
-                    int shortfall = (u.food < 0) ? 500 : 500 - u.food;
-                    int damage = (shortfall + 24) / 25;
-                    u.food = (u.food < 0) ? u.food : 0;
-                    print_msg("Pain explodes through your arm as the lash restores\nitself!\n");
-                    damage_u(damage, DEATH_LASH, "");
-                }
-                else
-                {
-                    print_msg("A pins-and-needles sensation washes over you as the lash\nrestores itself.\n");
-                    u.food -= 500;
-                }
-                break;
-            }
+            break_reaction(obj);
         }
     }
 } 
 
-void describe_object(int obj)
-{
-    Obj *optr;
-    Permobj *poptr;
-    print_obj_name(obj);
-    optr = objects + obj;
-    poptr = permobjs + optr->obj_id;
-    print_msg("\n%s\n", poptr->description);
-}
-
 int evasion_penalty(int obj)
 {
     if (permobjs[objects[obj].obj_id].poclass == POCLASS_ARMOUR)
     {
         return permobjs[objects[obj].obj_id].power2;
     }
-    /* Haxx0r. Or maybe a bug. */
-    print_msg("Trying to find evasion penalty of non-armour!\n");
     return 100;
 }
 
@@ -685,17 +641,24 @@ Action_cost magic_ring(void)
         if (u.food >= 50)
         {
             u.food -= 50;
-            print_msg("You activate your ring's power of teleportation.\n");
+            notify_telering_activation(1);
             teleport_u();
             return Cost_std;
         }
         else
         {
-            print_msg("You're too hungry to activate your ring.\n");
+            notify_telering_activation(0);
         }
         return Cost_none;
     default:
-        print_msg("Your current ring has no activatable power.\n");
+        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        {
+            debug_unimplemented_activation(optr->obj_id);
+        }
+        else
+        {
+            notify_magic_powerless_ring();
+        }
         return Cost_none;
     }
 }
@@ -711,11 +674,11 @@ Action_cost emanate_armour(void)
         {
             if (u.food < 5 * (OBJ_MAX_DUR - optr->durability))
             {
-                print_msg("You are too hungry to willingly let the ribbons draw on\nyour strength.\n");
+                notify_ribbon_activation(0);
             }
             else
             {
-                print_msg("You gasp as the ribbons draw on your strength to\nrepair themselves.\n");
+                notify_ribbon_activation(1);
                 u.food -= 5 * (OBJ_MAX_DUR - optr->durability);
                 optr->durability = OBJ_MAX_DUR;
                 cost = Cost_std;
@@ -723,11 +686,18 @@ Action_cost emanate_armour(void)
         }
         else
         {
-            print_msg("The ribbons are undamaged.\n");
+            notify_ribbon_activation(2);
         }
         break;
     default:
-        print_msg("Your current attire has no activatable powers.\n");
+        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        {
+            debug_unimplemented_activation(optr->obj_id);
+        }
+        else
+        {
+            notify_emanate_powerless_armour();
+        }
         break;
     }
     return Cost_none;
@@ -743,7 +713,7 @@ Action_cost zap_weapon(void)
         {
             Coord c;
             u.food -= 150;
-            print_msg("You unleash the fiery powers of your staff!\n");
+            notify_firestaff_activation(1);
             for (c.y = u.pos.y - 1; c.y <= u.pos.y + 1; ++c.y)
             {
                 if ((c.y < 0) || (c.y >= DUN_HEIGHT))
@@ -763,8 +733,7 @@ Action_cost zap_weapon(void)
                         Mon *mptr = monsters + mon;
                         if (!pmon_resists_fire(mptr->mon_id))
                         {
-                            print_mon_name(mon, 3);
-                            print_msg(" is engulfed in roaring flames.\n");
+                            notify_fireitem_hit(mon);
                             damage_mon(mon, dice(4, 10), true);
                         }
                     }
@@ -774,11 +743,19 @@ Action_cost zap_weapon(void)
         }
         else
         {
-            print_msg("You are too hungry to activate your staff's power.\n");
+            notify_firestaff_activation(0);
+            return Cost_none;
         }
         return Cost_std;
     default:
-        print_msg("Your current weapon has no activatable powers.\n");
+        if (permobjs[optr->obj_id].flags[0] & POF_ACTIVATABLE)
+        {
+            debug_unimplemented_activation(optr->obj_id);
+        }
+        else
+        {
+            notify_zap_powerless_weapon();
+        }
         return Cost_none;
     }
 }
@@ -790,16 +767,15 @@ Action_cost zap_weapon(void)
  */
 Action_cost player_unwield(Noisiness noisy)
 {
+    int saved_weapon = u.weapon;
     if (u.weapon == NO_OBJ)
     {
-        print_msg("BUG: got to player_unwield() with no weapon wielded - have a quiet word with your HCI module's author, please.\n");
+        debug_unwield_nothing();
         return Cost_none;
     }
     u.weapon = NO_OBJ;
-    if (noisy == Noise_std)
-    {
-        print_msg("Weapon unwielded.\n");
-    }
+    recalc_defence();
+    notify_unwield(saved_weapon, Noise_std);
     return Cost_std;
 }
 
@@ -810,9 +786,7 @@ Action_cost player_wield(int slot, Noisiness noisy)
         player_unwield(Noise_low);
     }
     u.weapon = u.inventory[slot];
-    print_msg("Wielding ");
-    print_obj_name(u.weapon);
-    print_msg(".\n");
+    notify_wield_weapon(u.weapon);
     recalc_defence();
     return Cost_std;
 }
@@ -872,7 +846,7 @@ Pass_fail ring_removal_unsafe(Noisiness noisy)
     {
         if (noisy != Noise_silent)
         {
-            print_msg("That ring is your only current source of fire resistance. Removing it here would incinerate you.\n");
+            notify_lava_blocks_unequip();
         }
         return You_fail;
     }
@@ -880,7 +854,7 @@ Pass_fail ring_removal_unsafe(Noisiness noisy)
     {
         if (noisy != Noise_silent)
         {
-            print_msg("Since nobody ever taught you to swim, removing that ring here would result in your death by drowning.\n");
+            notify_water_blocks_unequip();
         }
         return You_fail;
     }
index c576447..762b440 100644 (file)
@@ -53,7 +53,11 @@ enum poclass_num {
 #define POBJ_FLAG_WORDS 1
 
 // POF field 0
-#define POF_NOTIFY_EQUIP 0x00000001u
+#define POF_NOTIFY_EQUIP 0x00000001u // item has special messages when changing equip status
+#define POF_ACTIVATABLE 0x00000002u // item can be activated when equipped
+#define POF_STACKABLE 0x00000004u // item can stack
+#define POF_DAMAGEABLE 0x00000008u // track durability
+#define POF_BREAK_REACT 0x00000010u // item reacts to breakage attempts
 #define POF_DRESS 0x00010000u
 
 /*! \brief The 'permanent object' database */
index fca3765..8447be1 100755 (executable)
--- a/pobj_comp
+++ b/pobj_comp
@@ -21,8 +21,12 @@ our @carrion;
 
 our %flag_indices =
 (
-    'NOTIFY_EQUIP' => 0, # the first of probably many.
-    'DRESS' => 0
+    'NOTIFY_EQUIP' => 0,
+    'ACTIVATABLE' => 0,
+    'STACKABLE' => 0,
+    'DAMAGEABLE' => 0,
+    'BREAK_REACT' => 0,
+    'DRESS' => 0,
 );
 
 
diff --git a/u.cc b/u.cc
index 910830d..4694063 100644 (file)
--- a/u.cc
+++ b/u.cc
@@ -335,7 +335,7 @@ void write_char_dump(void)
     fp = fopen(filename, "w");
     if (fp == NULL)
     {
-        print_msg("Couldn't create dump file. Dump failed.\n");
+        debug_dump_write_failed();
         return;
     }
     fprintf(fp, "%s, level %d princess (%d XP)\n", u.name, u.level, u.experience);
index 70e87a6..f7d5ac0 100644 (file)
@@ -126,6 +126,15 @@ enum Death {
     DEATH_LASH, DEATH_RIBBONS
 };
 
+enum Fell_powers {
+    FePo_iron, // boosted by ironguard armour, hellglaive
+    FePo_decay, // boosted by foetid vestments, 
+    FePo_bone, // boosted by lich's robe, vampire ring
+    FePo_flesh // boosted by t's lash or the ribbons,
+};
+
+#define TOTAL_FELL_POWERS (1 + FePo_flesh)
+
 #define RESIST_MASK_TEMPORARY   0x0000FFFFu
 #define RESIST_MASK_PERM_EQUIP  0xFFFF0000u
 #define RESIST_RING     0x00010000u
@@ -157,7 +166,14 @@ struct Player {
     int weapon;         /* For now, you can only wield one weapon. */
     int armour;         /* For now, you can only wear one item of armour. */
     int ring;           /* For now, you can only wear one magic ring. */
+    // TODO make these meters mean something - cosmetically for starters
+    int sympathy[TOTAL_FELL_POWERS];
     bool resists(Damtyp dtype) const;
+    bool martial(void) const { return sympathy[FePo_iron] > 10; }
+    bool rotten(void) const { return sympathy[FePo_decay] > 10; }
+    bool thanatoic(void) const { return sympathy[FePo_bone] > 10; }
+    bool sybaritic(void) const { return sympathy[FePo_flesh] > 10; }
+    bool corrupt(void) const { return martial() || rotten() || thanatoic() || sybaritic(); }
 };
 
 /*! \brief Represent an in-game action in more detail than Game_cmd