^X weapon feedback

Report weapon skill in the ^X status section when dual-wielding,
The effective skill level is the lower of the weapon's skill and
two-weapon skill, separately for primary and secondary.  It's a
much bigger chunk of code than most enlightenment/^X features so
I put it in its own routine.
This commit is contained in:
PatR
2020-04-06 06:25:17 -07:00
parent d07595db2c
commit dc9de59f63
2 changed files with 163 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ $NHDT-Date: 1586178711 2020/04/06 13:11:51 $
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ $NHDT-Date: 1586179508 2020/04/06 13:25:08 $
General Fixes and Modified Features
-----------------------------------
@@ -235,6 +235,7 @@ for !fixinv option where inventory letters normally don't stick, try to put
a throw-and-return weapon back into the same inventory slot it gets
thrown from; only works if it does return and is successfully caught
wizard mode #wizborn command
include more skill information in ^X output when dual-wielding
Platform- and/or Interface-Specific New Features

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 insight.c $NHDT-Date: 1582321544 2020/02/21 21:45:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */
/* NetHack 3.7 insight.c $NHDT-Date: 1586179508 2020/04/06 13:25:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -27,6 +27,7 @@ static void FDECL(basics_enlightenment, (int, int));
static void FDECL(characteristics_enlightenment, (int, int));
static void FDECL(one_characteristic, (int, int, int));
static void FDECL(status_enlightenment, (int, int));
static void FDECL(weapon_insight, (int));
static void FDECL(attributes_enlightenment, (int, int));
static void FDECL(show_achievements, (int));
static int FDECL(CFDECLSPEC vanqsort_cmp, (const genericptr,
@@ -740,7 +741,7 @@ int mode;
int final;
{
boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
int cap, wtype;
int cap;
char buf[BUFSZ], youtoo[BUFSZ];
boolean Riding = (u.usteed
/* if hero dies while dismounting, u.usteed will still
@@ -1015,8 +1016,27 @@ int final;
still useful though) */
you_are("unencumbered", "");
}
/* current weapon(s) and corresponding skill level(s) */
weapon_insight(final);
/* report 'nudity' */
if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
if (u.uroleplay.nudist)
enl_msg(You_, "do", "did", " not wear any armor", "");
else
you_are("not wearing any armor", "");
}
}
/* report being weaponless; distinguish whether gloves are worn */
/* extracted from status_enlightenment() to reduce clutter there */
static void
weapon_insight(final)
int final;
{
char buf[BUFSZ];
int wtype;
/* report being weaponless; distinguish whether gloves are worn
[perhaps mention silver ring(s) when not wearning gloves?] */
if (!uwep) {
you_are(uarmg ? "empty handed" /* gloves imply hands */
: humanoid(g.youmonst.data)
@@ -1025,29 +1045,39 @@ int final;
/* alternate phrasing for paws or lack of hands */
: "not wielding anything",
"");
/* two-weaponing implies hands (can't be polymorphed) and
/* two-weaponing implies hands and
a weapon or wep-tool (not other odd stuff) in each hand */
} else if (u.twoweap) {
you_are("wielding two weapons at once", "");
/* report most weapons by their skill class (so a katana will be
described as a long sword, for instance; mattock and hook are
exceptions), or wielded non-weapon item by its object class */
described as a long sword, for instance; mattock, hook, and aklys
are exceptions), or wielded non-weapon item by its object class */
} else {
const char *what = weapon_descr(uwep);
/* [what about other silver items?] */
if (uwep->otyp == SHIELD_OF_REFLECTION)
what = shield_simple_name(uwep); /* silver|smooth shield */
else if (is_wet_towel(uwep))
what = /* (uwep->spe < 3) ? "moist towel" : */ "wet towel";
if (!strcmpi(what, "armor") || !strcmpi(what, "food")
|| !strcmpi(what, "venom"))
Sprintf(buf, "wielding some %s", what);
else
/* [maybe include known blessed?] */
Sprintf(buf, "wielding %s",
(uwep->quan == 1L) ? an(what) : makeplural(what));
you_are(buf, "");
}
/*
* Skill with current weapon. Might help players who've never
* noticed #enhance or decided that it was pointless.
*/
if ((wtype = uwep_skill_type()) != P_NONE) {
if ((wtype = weapon_type(uwep)) != P_NONE && !is_ammo(uwep)) {
char sklvlbuf[20];
int sklvl = P_SKILL(wtype);
boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED);
@@ -1060,21 +1090,130 @@ int final;
or "you are unskilled/skilled in <skill>" */
Sprintf(buf, "%s %s %s", sklvlbuf,
hav ? "skill with" : "in", skill_name(wtype));
if (can_advance(wtype, FALSE))
Sprintf(eos(buf), " and %s that",
!final ? "can enhance" : "could have enhanced");
if (hav)
you_have(buf, "");
else
you_are(buf, "");
}
/* report 'nudity' */
if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) {
if (u.uroleplay.nudist)
enl_msg(You_, "do", "did", " not wear any armor", "");
else
you_are("not wearing any armor", "");
}
if (!u.twoweap) {
if (can_advance(wtype, FALSE))
Sprintf(eos(buf), " and %s that",
!final ? "can enhance" : "could have enhanced");
if (hav)
you_have(buf, "");
else
you_are(buf, "");
} else { /* twoweap, so two-weapon skill is at least unskilled */
static const char also_[] = "also ";
char pfx[QBUFSZ], sfx[QBUFSZ],
sknambuf2[20], sklvlbuf2[20], twobuf[20];
const char *also = "", *also2 = "", *also3 = (char *) 0,
*verb_present, *verb_past;
int a1, a2, ab,
wtype2 = weapon_type(uswapwep),
sklvl2 = P_SKILL(wtype2),
twoskl = P_SKILL(P_TWO_WEAPON_COMBAT);
boolean hav2 = (sklvl2 != P_UNSKILLED && sklvl2 != P_SKILLED);
/* normally hero must have access to two-weapon skill in
order to initiate u.twoweap, but not if polymorphed into
a form which has multiple weapon attacks, so we need to
avoid getting bitten by unexpected skill value */
if (twoskl == P_ISRESTRICTED) {
twoskl = P_UNSKILLED;
/* restricted is the same as unskilled as far as bonus
or penaly goes, and it isn't ordinarily seen so
skill_level_name() returns "Unknown" for it */
Strcpy(twobuf, "restricted");
} else {
(void) lcase(skill_level_name(P_TWO_WEAPON_COMBAT, twobuf));
}
/* keep buf[] from above in case skill levels match */
pfx[0] = sfx[0] = '\0';
if (twoskl < sklvl) {
/* twoskil won't be restricted so sklvl is at least basic */
Sprintf(pfx, "Your skill in %s ", skill_name(wtype));
Sprintf(sfx, " limited by being %s with two weapons", twobuf);
also = also_;
} else if (twoskl > sklvl) {
/* sklvl might be restricted */
Strcpy(pfx, "Your two weapon skill ");
Strcpy(sfx, " limited by ");
if (sklvl > P_ISRESTRICTED)
Sprintf(eos(sfx), "being %s", sklvlbuf);
else
Sprintf(eos(sfx), "having no skill");
Sprintf(eos(sfx), " with %s", skill_name(wtype));
also2 = also_;
} else {
Strcat(buf, " and two weapons");
also3 = also_;
}
if (*pfx)
enl_msg(pfx, "is", "was", sfx, "");
else if (hav)
you_have(buf, "");
else
you_are(buf, "");
if (wtype2 == wtype)
return;
Strcpy(sknambuf2, skill_name(wtype2));
(void) lcase(skill_level_name(wtype2, sklvlbuf2));
verb_present = "is", verb_past = "was";
pfx[0] = sfx[0] = buf[0] = '\0';
if (twoskl < sklvl2) {
/* twoskil is at least unskilled, sklvl2 at least basic */
Sprintf(pfx, "Your skill in %s ", sknambuf2);
Sprintf(sfx, " %slimited by being %s with two weapons",
also, twobuf);
} else if (twoskl > sklvl2) {
/* sklvl2 might be restricted */
Strcpy(pfx, "Your two weapon skill ");
Sprintf(sfx, " %slimited by ", also2);
if (sklvl2 > P_ISRESTRICTED)
Sprintf(eos(sfx), "being %s with", sklvlbuf2);
else
Strcat(eos(sfx), "having no skill");
Sprintf(eos(sfx), " with %s", sknambuf2);
} else {
/* equal; two-weapon is at least unskilled, so so is sklvl2;
"you [also] have basic/expert/master/grand-master skill
with <skill>" or "you [also] are unskilled/skilled in*" */
Sprintf(buf, "%s %s %s", sklvlbuf2,
hav2 ? "skill with" : "in", sknambuf2);
Strcat(buf, " and two weapons");
if (also3) {
Strcpy(pfx, "You also ");
Sprintf(sfx, " %s", buf), buf[0] = '\0';
verb_present = hav2 ? "have" : "are";
verb_past = hav2 ? "had" : "were";
}
}
if (*pfx)
enl_msg(pfx, verb_present, verb_past, sfx, "");
else if (hav2)
you_have(buf, "");
else
you_are(buf, "");
a1 = can_advance(wtype, FALSE);
a2 = can_advance(wtype2, FALSE);
ab = can_advance(P_TWO_WEAPON_COMBAT, FALSE);
if (a1 || a2 || ab) {
Sprintf(sfx, " skill%s with %s%s%s%s%s",
(a1 + a2 + ab > 1) ? "s" : "",
a1 ? skill_name(wtype) : "",
((a1 && a2 && ab) ? ", "
: (a1 && (a2 || ab)) ? " and " : ""),
a2 ? skill_name(wtype2) : "",
((a1 && a2 && ab) ? ", and "
: (a2 && ab) ? " and " : ""),
ab ? "two weapons" : "");
enl_msg(You_, "can enhance", "could have enhanced", sfx, "");
}
} /* two-weapon */
} /* skill applies */
}
/* attributes: intrinsics and the like, other non-obvious capabilities */