From: Martin Read Date: Sun, 9 Feb 2014 15:09:16 +0000 (+0000) Subject: Big ball-of-mud commit after completing removal of direct print_msg() calls in game... X-Git-Tag: printmsg-purged X-Git-Url: http://git.blackswordsonics.com/?a=commitdiff_plain;h=b5ceed7dc66e22fe3bf508bd09a45152fa74b8f2;p=victrix-abyssi Big ball-of-mud commit after completing removal of direct print_msg() calls in game logic --- diff --git a/Makefile b/Makefile index b7843f6..827505f 100644 --- 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 diff --git a/combat.cc b/combat.cc index ca028f4..e803241 100644 --- 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); } } } diff --git a/default.permobjs b/default.permobjs index e519f96..b415a9c 100644 --- a/default.permobjs +++ b/default.permobjs @@ -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 diff --git a/display-nc.cc b/display-nc.cc index bae2a8b..f302143 100644 --- a/display-nc.cc +++ b/display-nc.cc @@ -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 diff --git a/display.hh b/display.hh index 5ca99b2..6553451 100644 --- a/display.hh +++ b/display.hh @@ -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 --- 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 --- 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 --- 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 --- 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) { diff --git a/monsters.cc b/monsters.cc index 082fc7c..5d5fb4f 100644 --- a/monsters.cc +++ b/monsters.cc @@ -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); } diff --git a/notify-local-tty.cc b/notify-local-tty.cc index 62a7a21..9b5f37c 100644 --- a/notify-local-tty.cc +++ b/notify-local-tty.cc @@ -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 diff --git a/notify.hh b/notify.hh index 847f5e3..80a81f0 100644 --- 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 diff --git a/objects.cc b/objects.cc index aa843da..d03cc2c 100644 --- a/objects.cc +++ b/objects.cc @@ -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; } diff --git a/objects.hh b/objects.hh index c576447..762b440 100644 --- a/objects.hh +++ b/objects.hh @@ -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 */ diff --git a/pobj_comp b/pobj_comp index fca3765..8447be1 100755 --- 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 --- 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); diff --git a/victrix-abyssi.hh b/victrix-abyssi.hh index 70e87a6..f7d5ac0 100644 --- a/victrix-abyssi.hh +++ b/victrix-abyssi.hh @@ -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