From e0db29db45b051e87d49d296de4a7546a9249b5a Mon Sep 17 00:00:00 2001 From: Erik Lunna Date: Mon, 11 Dec 2023 14:18:37 +0100 Subject: [PATCH] Added the showdmg option from SLASH'EM. This actually proved to be quite useful in Hack'EM for analyzing damage, looking at balance issues, and bugfixing. It can be enabled by setting the showdmg option to true/on. For the time being, I will be leaving this feature in for players to use. If we settle in on a long term stable version, this might be turned off for non-wizmode use. This initial commit covers most of the places that damage occurs, but in a future commit I want to consolidate the monster damage code to a damage_mon function and also make sure all of the other more obscure damage instances being done to the player (ie: while polymorphed) are also covered. --- include/extern.h | 1 + include/flag.h | 1 + include/optlist.h | 3 +++ src/do.c | 1 + src/dokick.c | 4 +++- src/exper.c | 1 + src/explode.c | 4 ++++ src/hack.c | 21 +++++++++++++++++++++ src/mhitm.c | 8 +++++++- src/mhitu.c | 11 +++++++++-- src/mon.c | 3 +++ src/mthrowu.c | 1 + src/muse.c | 6 +++++- src/polyself.c | 8 ++++++-- src/read.c | 1 + src/trap.c | 2 ++ src/uhitm.c | 10 +++++++++- src/zap.c | 3 +++ 18 files changed, 81 insertions(+), 8 deletions(-) diff --git a/include/extern.h b/include/extern.h index 6fc891625c..0af579d1de 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1039,6 +1039,7 @@ extern int monster_nearby(void); extern void end_running(boolean); extern void nomul(int); extern void unmul(const char *); +extern void showdmg(int, boolean); extern int saving_grace(int); extern void losehp(int, const char *, schar); extern int weight_cap(void); diff --git a/include/flag.h b/include/flag.h index d99efe2944..3f74abe7b4 100644 --- a/include/flag.h +++ b/include/flag.h @@ -56,6 +56,7 @@ struct flag { boolean safe_dog; /* give complete protection to the dog */ boolean safe_wait; /* prevent wait or search next to hostile */ boolean showexp; /* show experience points */ + boolean showdmg; /* Display damage being dealt */ boolean showscore; /* show score */ boolean silent; /* whether the bell rings or not */ boolean sortpack; /* sorted inventory */ diff --git a/include/optlist.h b/include/optlist.h index 48eb9b76cf..6062c889ab 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -603,6 +603,9 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(selectsaved, Advanced, 0, opt_out, set_in_config, On, Yes, No, No, NoAlias, &iflags.wc2_selectsaved, Term_False, (char *)0) + NHOPTB(showdmg, Status, 0, opt_in, set_in_game, + Off, Yes, No, No, NoAlias, &flags.showdmg, Term_False, + "show damage results in messages") NHOPTB(showexp, Status, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.showexp, Term_False, "show experience points in status line") diff --git a/src/do.c b/src/do.c index b716c7cdcf..7777022e99 100644 --- a/src/do.c +++ b/src/do.c @@ -203,6 +203,7 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) /* normally we'd use ohitmon() but it can call drop_throw() which calls flooreffects() */ damage = dmgval(obj, mtmp); + showdmg(damage, FALSE); mtmp->mhp -= damage; if (DEADMONSTER(mtmp)) { if (canspotmon(mtmp)) diff --git a/src/dokick.c b/src/dokick.c index 2b126c6805..33b7f14717 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -89,8 +89,10 @@ kickdmg(struct monst *mon, boolean clumsy) if (uarmf) dmg += uarmf->spe; dmg += u.udaminc; /* add ring(s) of increase damage */ - if (dmg > 0) + if (dmg > 0) { + showdmg(dmg, FALSE); mon->mhp -= dmg; + } if (!DEADMONSTER(mon) && martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove && mon != u.ustuck && !mon->mtrapped) { /* see if the monster has a place to move into */ diff --git a/src/exper.c b/src/exper.c index 1548c98d01..5b81cddfef 100644 --- a/src/exper.c +++ b/src/exper.c @@ -254,6 +254,7 @@ losexp( if (u.uhpmax > olduhpmax) setuhpmax(olduhpmax); + showdmg(num, TRUE); u.uhp -= num; if (u.uhp < 1) u.uhp = 1; diff --git a/src/explode.c b/src/explode.c index be99846d99..d430b69b06 100644 --- a/src/explode.c +++ b/src/explode.c @@ -520,6 +520,7 @@ explode( if ((explmask[i][j] & EXPL_MON) != 0) { golemeffects(mtmp, (int) adtyp, dam + idamres); + showdmg(idamnonres, FALSE); mtmp->mhp -= idamnonres; } else { /* call resist with 0 and do damage manually so 1) we can @@ -547,6 +548,7 @@ explode( mdam *= 2; else if (resists_fire(mtmp) && adtyp == AD_COLD) mdam *= 2; + showdmg(mdam + idamres + idamnonres, FALSE); mtmp->mhp -= mdam; mtmp->mhp -= (idamres + idamnonres); } @@ -631,6 +633,8 @@ explode( u.mh -= damu; else u.uhp -= damu; + + showdmg(damu, TRUE); gc.context.botl = 1; } diff --git a/src/hack.c b/src/hack.c index 332c320216..e2e834d854 100644 --- a/src/hack.c +++ b/src/hack.c @@ -3949,6 +3949,24 @@ saving_grace(int dmg) return dmg; } + +/* Print the amount of damage inflicted */ +/* KMH -- Centralized to one function +* Damage to the player will be in parentheses "(3)" +* Damage to the monster will be brackets "[3]" +* */ +void +showdmg(int n, boolean you) +{ + if (!flags.showdmg) + return; + if (you) + pline("(%d pt%s)", n, (n > 1 ? "s" : "")); + else + pline("[%d pt%s]", n, (n > 1 ? "s" : "")); + return; +} + void losehp(int n, const char *knam, schar k_format) { @@ -3963,6 +3981,7 @@ losehp(int n, const char *knam, schar k_format) end_running(TRUE); if (Upolyd) { u.mh -= n; + showdmg(n, TRUE); if (u.mhmax < u.mh) u.mhmax = u.mh; if (u.mh < 1) @@ -3974,6 +3993,8 @@ losehp(int n, const char *knam, schar k_format) n = saving_grace(n); u.uhp -= n; + showdmg(n, TRUE); + if (u.uhp > u.uhpmax) u.uhpmax = u.uhp; /* perhaps n was negative */ if (u.uhp < 1) { diff --git a/src/mhitm.c b/src/mhitm.c index fcdb3aa118..6752f69bc0 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -350,7 +350,10 @@ mattackm( ftmp = (int) ((magr->m_lev - 4) / 2) + 4; tmp += ftmp; if (canseemon(magr)) { - pline("%s flanks %s.", Monnam(magr), mon_nam(mdef)); + if (flags.showdmg) + pline("%s flanks %s. [-%dAC]", Monnam(magr), mon_nam(mdef), ftmp); + else + pline("%s flanks %s.", Monnam(magr), mon_nam(mdef)); } } @@ -1119,6 +1122,7 @@ mdamagem( if (!mhm.damage) return mhm.hitflags; + showdmg(mhm.damage, FALSE); mdef->mhp -= mhm.damage; if (mdef->mhp < 1) { if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */ @@ -1210,6 +1214,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) pline("%s shudders!", Before); dmg += (mdef->mhpmax + 1) / 2; + showdmg(dmg, mdef == &gy.youmonst); mdef->mhp -= dmg; dmg = 0; if (DEADMONSTER(mdef)) { @@ -1490,6 +1495,7 @@ passivemm( tmp = 0; assess_dmg: + showdmg(tmp, FALSE); if ((magr->mhp -= tmp) <= 0) { monkilled(magr, "", (int) mddat->mattk[i].adtyp); return (mdead | mhit | M_ATTK_AGR_DIED); diff --git a/src/mhitu.c b/src/mhitu.c index 85b8776226..d98bccb6a3 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -714,7 +714,9 @@ mattacku(register struct monst *mtmp) if (3 + find_mac(mtmp) <= rnd(20)) { pline("%s is hit by a falling piercer (you)!", Monnam(mtmp)); - if ((mtmp->mhp -= d(3, 6)) < 1) + int tdmg = d(3, 6); + showdmg(tdmg, FALSE); + if ((mtmp->mhp -= tdmg) < 1) killed(mtmp); } else pline("%s is almost hit by a falling piercer (you)!", @@ -844,7 +846,10 @@ mattacku(register struct monst *mtmp) /* Scale with monster difficulty */ ftmp = (int) ((mtmp->m_lev - 4) / 2) + 4; tmp += ftmp; - You("are being flanked!"); + if (flags.showdmg) + You("are being flanked! [-%dAC]", ftmp); + else + You("are being flanked!"); } /* make eels visible the moment they hit/miss us */ @@ -2067,6 +2072,7 @@ void mdamageu(struct monst *mtmp, int n) { gc.context.botl = 1; + showdmg(n, TRUE); if (Upolyd) { u.mh -= n; if (u.mh < 1) @@ -2682,6 +2688,7 @@ passiveum( tmp = 0; assess_dmg: + showdmg(tmp, FALSE); if ((mtmp->mhp -= tmp) <= 0) { pline("%s dies!", Monnam(mtmp)); xkilled(mtmp, XKILL_NOMSG); diff --git a/src/mon.c b/src/mon.c index 9677f4b1e0..f2566eda28 100644 --- a/src/mon.c +++ b/src/mon.c @@ -789,6 +789,7 @@ minliquid_core(struct monst* mtmp) if (cansee(mtmp->mx, mtmp->my)) pline("%s rusts.", Monnam(mtmp)); + showdmg(dam, FALSE); mtmp->mhp -= dam; if (mtmp->mhpmax > dam) mtmp->mhpmax -= dam; @@ -833,6 +834,7 @@ minliquid_core(struct monst* mtmp) else xkilled(mtmp, XKILL_NOMSG); } else { + showdmg(1, FALSE); mtmp->mhp -= 1; if (DEADMONSTER(mtmp)) { if (cansee(mtmp->mx, mtmp->my)) @@ -2998,6 +3000,7 @@ corpse_chance( losehp(Maybe_Half_Phys(tmp), gk.killer.name, KILLED_BY_AN); } else { You_hear("an explosion."); + showdmg(tmp, FALSE); magr->mhp -= tmp; if (DEADMONSTER(magr)) mondied(magr); diff --git a/src/mthrowu.c b/src/mthrowu.c index 4c5aaa71f7..7cb690b53f 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -446,6 +446,7 @@ ohitmon( /* might already be dead (if petrified) */ if (!harmless && !DEADMONSTER(mtmp)) { + showdmg(damage, FALSE); mtmp->mhp -= damage; if (DEADMONSTER(mtmp)) { if (vis || (verbose && !gm.mtarget)) diff --git a/src/muse.c b/src/muse.c index a0634c6694..d6c4afb71e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -141,6 +141,7 @@ precheck(struct monst *mon, struct obj *obj) ? "nearby" : "in the distance"); } m_useup(mon, obj); + showdmg(dam, FALSE); mon->mhp -= dam; if (DEADMONSTER(mon)) { monkilled(mon, "", AD_RBRE); @@ -1953,9 +1954,12 @@ use_offensive(struct monst *mtmp) if (dist2(mtmp2->mx, mtmp2->my, mtmp->mx, mtmp->my) < 3) { if (resists_fire(mtmp2)) continue; + showdmg(num, FALSE); mtmp2->mhp -= num; - if (resists_cold(mtmp2)) + if (resists_cold(mtmp2)) { + showdmg(3 * num, FALSE); mtmp2->mhp -= 3 * num; + } if (DEADMONSTER(mtmp2)) { mondied(mtmp2); break; diff --git a/src/polyself.c b/src/polyself.c index 2c00dae5df..27f0516ee3 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1681,8 +1681,10 @@ dogaze(void) (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); if (lev > rn2(20)) ignite_items(mtmp->minvent); - if (dmg) + if (dmg) { + showdmg(dmg, FALSE); mtmp->mhp -= dmg; + } if (DEADMONSTER(mtmp)) killed(mtmp); } else if (adtyp == AD_BLND) { @@ -1692,7 +1694,8 @@ dogaze(void) pline("%s doesn't seem affected.", Monnam(mtmp)); dmg = 0; } - if(dmg) { + if (dmg) { + showdmg(dmg, FALSE); mtmp->mhp -= dmg; mtmp->mcansee = 0; mtmp->mblinded = rnd(50); @@ -1914,6 +1917,7 @@ domindblast(void) u_sen ? "telepathy" : telepathic(mtmp->data) ? "latent telepathy" : "mind"); + showdmg(dmg, FALSE); mtmp->mhp -= dmg; if (DEADMONSTER(mtmp)) killed(mtmp); diff --git a/src/read.c b/src/read.c index a54809551f..e70dafcb80 100644 --- a/src/read.c +++ b/src/read.c @@ -2297,6 +2297,7 @@ drop_boulder_on_monster(coordxy x, coordxy y, boolean confused, boolean byu) xname(helmet), mhim(mtmp)); } } + showdmg(mdmg, FALSE); mtmp->mhp -= mdmg; if (DEADMONSTER(mtmp)) { if (byu) { diff --git a/src/trap.c b/src/trap.c index a6453ced0b..b907a170dc 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2276,6 +2276,7 @@ trapeffect_anti_magic( if (in_sight) seetrap(trap); + showdmg(dmgval2, FALSE); mtmp->mhp -= dmgval2; if (DEADMONSTER(mtmp)) monkilled(mtmp, @@ -6452,6 +6453,7 @@ thitm( dam = 1; } if (!harmless) { + showdmg(dam, FALSE); mon->mhp -= dam; if (mon->mhp <= 0) { int xx = mon->mx, yy = mon->my; diff --git a/src/uhitm.c b/src/uhitm.c index b6c633833d..cadced423a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -385,7 +385,10 @@ find_roll_to_hit( /* Scale with monster difficulty */ ftmp = (int) ((u.ulevel - 4) / 2) + 4; tmp += ftmp; - You("flank %s.", mon_nam(mtmp)); + if (flags.showdmg) + You("flank %s. [-%dAC]", mon_nam(mtmp), ftmp); + else + You("flank %s.", mon_nam(mtmp)); } /* role/race adjustments */ @@ -1847,6 +1850,7 @@ hmon_hitmon( so we test for 1; 0 shouldn't be able to happen here... */ && hmd.dmg > 0 && u.uconduct.weaphit <= 1) first_weapon_hit(obj); + showdmg(hmd.dmg, FALSE); mon->mhp -= hmd.dmg; } /* adjustments might have made tmp become less than what @@ -2456,6 +2460,7 @@ mhitm_ad_drli( if (mdef->mhpmax > (int) mdef->m_lev) mdef->mhpmax = (int) mdef->m_lev + 1; } + showdmg(mhm->damage, FALSE); mdef->mhp -= mhm->damage; /* !m_lev: level 0 monster is killed regardless of hit points rather than drop to level -1; note: some non-living creatures @@ -5047,6 +5052,7 @@ damageum( return mhm.hitflags; mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ + showdmg(mhm.damage, FALSE); mdef->mhp -= mhm.damage; if (DEADMONSTER(mdef)) { /* troll killed by Trollsbane won't auto-revive; FIXME? same when @@ -5377,6 +5383,7 @@ gulpum(struct monst *mdef, struct attack *mattk) break; } end_engulf(); + showdmg(dam, FALSE); mdef->mhp -= dam; if (DEADMONSTER(mdef)) { killed(mdef); @@ -6561,6 +6568,7 @@ light_hits_gremlin(struct monst *mon, int dmg) { pline("%s %s!", Monnam(mon), (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain"); + showdmg(dmg, FALSE); mon->mhp -= dmg; wake_nearto(mon->mx, mon->my, 30); if (DEADMONSTER(mon)) { diff --git a/src/zap.c b/src/zap.c index 3d8cc138ea..3db36ddbf1 100644 --- a/src/zap.c +++ b/src/zap.c @@ -471,6 +471,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) shieldeff(mtmp->mx, mtmp->my); } else if (!resist(mtmp, otmp->oclass, dmg, NOTELL) && !DEADMONSTER(mtmp)) { + showdmg(dmg, FALSE); mtmp->mhp -= dmg; mtmp->mhpmax -= dmg; /* die if already level 0, regardless of hit points */ @@ -4459,6 +4460,7 @@ zhitm( tmp = 0; /* don't allow negative damage */ debugpline3("zapped monster hp = %d (= %d - %d)", mon->mhp - tmp, mon->mhp, tmp); + showdmg(tmp, FALSE); mon->mhp -= tmp; return tmp; } @@ -6107,6 +6109,7 @@ resist(struct monst *mtmp, char oclass, int damage, int tell) if (damage) { int saved_mhp = mtmp->mhp; + showdmg(damage, FALSE); mtmp->mhp -= damage; if (DEADMONSTER(mtmp)) { if (gm.m_using)