pauper tweaks

For 'pauper', most roles start without any skills.  However, strong
fighter types were starting with basic bare-handed combat/marital arts,
giving them a big advantage.  Knights were starting with basic riding,
which is probably useless now that they have to acquire a saddle to
use it (see below).  Take those initial skills away, producing an even
playing field.

Non-paupers get their initial skills without needing to spend any skill
credits (aka slots) on those.  Give paupers 2 starting credits that
they'll be able to use once they acquire suitable weapons or spells
and train them up, so that once they're reasonably developed they won't
lag in skills compared to non-paupers.

Pauper knights were still starting with a saddled pony.  Suppress the
saddle when the knight is a pauper.

Wizards start knowing a lot of spellbooks.  Pauper wizards shouldn't.

Give most roles advance knowledge of one low level spell or other item.
It won't benefit them unless/until they find the corresponding item.
This commit is contained in:
PatR
2024-09-01 15:11:28 -07:00
parent 78042680b8
commit 96787441e9
4 changed files with 130 additions and 52 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 dog.c $NHDT-Date: 1700012881 2023/11/15 01:48:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.147 $ */
/* NetHack 3.7 dog.c $NHDT-Date: 1725227804 2024/09/01 21:56:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -186,6 +186,7 @@ make_familiar(struct obj *otmp, coordxy x, coordxy y, boolean quietly)
return mtmp;
}
/* used exclusively for hero's starting pet */
struct monst *
makedog(void)
{
@@ -219,13 +220,19 @@ makedog(void)
mtmp = makemon(&mons[pettype], u.ux, u.uy, MM_EDOG);
if (!mtmp)
return ((struct monst *) 0); /* pets were genocided */
return ((struct monst *) 0); /* pets were genocided [how?] */
svc.context.startingpet_mid = mtmp->m_id;
/* Horses already wear a saddle */
if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
otmp->dknown = otmp->bknown = otmp->rknown = 1;
put_saddle_on_mon(otmp, mtmp);
if (!svc.context.startingpet_mid) {
svc.context.startingpet_mid = mtmp->m_id;
if (!u.uroleplay.pauper) {
/* initial horses already wear a saddle (unless hero is a pauper) */
if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
otmp->dknown = otmp->bknown = otmp->rknown = 1;
put_saddle_on_mon(otmp, mtmp);
}
}
} else {
impossible("makedog() when startingpet_mid is already non-zero?");
}
if (!gp.petname_used++ && *petname)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 spell.c $NHDT-Date: 1718303203 2024/06/13 18:26:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.171 $ */
/* NetHack 3.7 spell.c $NHDT-Date: 1725227807 2024/09/01 21:56:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */
/* Copyright (c) M. Stephenson 1988 */
/* NetHack may be freely redistributed. See license for details. */
@@ -888,7 +888,8 @@ skill_based_spellbook_id(void)
}
if (objects[booktype].oc_level <= known_up_to_level)
makeknown(booktype);
/* makeknown(booktype) but don't exercise Wisdom */
discover_object(booktype, TRUE, FALSE);
}
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 u_init.c $NHDT-Date: 1725138482 2024/08/31 21:08:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */
/* NetHack 3.7 u_init.c $NHDT-Date: 1725227809 2024/09/01 21:56:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2017. */
/* NetHack may be freely redistributed. See license for details. */
@@ -20,10 +20,11 @@ staticfn void ini_inv_adjust_obj(struct trobj *,
struct obj *) NONNULLPTRS;
staticfn void ini_inv_use_obj(struct obj *) NONNULLARG1;
staticfn void ini_inv(struct trobj *) NONNULLARG1;
staticfn void knows_object(int);
staticfn void knows_object(int, boolean);
staticfn void knows_class(char);
staticfn void u_init_role(void);
staticfn void u_init_race(void);
staticfn void pauper_reinit(void);
staticfn void u_init_carry_attr_boost(void);
staticfn boolean restricted_spell_discipline(int);
@@ -557,9 +558,9 @@ static const struct def_skill Skill_W[] = {
};
staticfn void
knows_object(int obj)
knows_object(int obj, boolean override_pauper)
{
if (u.uroleplay.pauper)
if (u.uroleplay.pauper && !override_pauper)
return;
discover_object(obj, TRUE, FALSE);
objects[obj].oc_pre_discovered = 1; /* not a "discovery" */
@@ -607,7 +608,7 @@ knows_class(char sym)
}
if (objects[ct].oc_class == sym && !objects[ct].oc_magic)
knows_object(ct);
knows_object(ct, FALSE);
}
}
@@ -636,8 +637,10 @@ u_init_role(void)
ini_inv(Lamp);
else if (!rn2(5))
ini_inv(Magicmarker);
knows_object(SACK);
knows_object(TOUCHSTONE);
knows_object(SACK, FALSE);
knows_object(TOUCHSTONE, FALSE); /* FALSE: don't override pauper here,
* but TOUCHSTONE will be made known
* in pauper_reinit() */
skill_init(Skill_A);
break;
case PM_BARBARIAN:
@@ -662,7 +665,7 @@ u_init_role(void)
ini_inv(Healer);
if (!rn2(25))
ini_inv(Lamp);
knows_object(POT_FULL_HEALING);
knows_object(POT_FULL_HEALING, FALSE);
skill_init(Skill_H);
break;
case PM_KNIGHT:
@@ -686,7 +689,7 @@ u_init_role(void)
ini_inv(Lamp);
knows_class(ARMOR_CLASS);
/* sufficiently martial-arts oriented item to ignore language issue */
knows_object(SHURIKEN);
knows_object(SHURIKEN, FALSE);
skill_init(Skill_Mon);
break;
}
@@ -696,7 +699,7 @@ u_init_role(void)
ini_inv(Magicmarker);
else if (!rn2(10))
ini_inv(Lamp);
knows_object(POT_WATER);
knows_object(POT_WATER, TRUE); /* override pauper */
skill_init(Skill_P);
/* KMH, conduct --
* Some may claim that this isn't agnostic, since they
@@ -719,7 +722,8 @@ u_init_role(void)
ini_inv(Rogue);
if (!rn2(5))
ini_inv(Blindfold);
knows_object(SACK);
knows_object(SACK, FALSE); /* FALSE: don't override pauper here, but sack
* will be made known in pauper_reinit() */
knows_class(WEAPON_CLASS); /* daggers only */
skill_init(Skill_R);
break;
@@ -736,7 +740,9 @@ u_init_role(void)
if (objects[i].oc_magic) /* skip "magic koto" */
continue;
if (Japanese_item_name(i, (const char *) 0))
knows_object(i);
/* we don't override pauper here because that would give
samarai an advantage of knowing several items in advance */
knows_object(i, FALSE);
}
skill_init(Skill_S);
break;
@@ -797,28 +803,28 @@ u_init_race(void)
}
/* Elves can recognize all elvish objects */
knows_object(ELVEN_SHORT_SWORD);
knows_object(ELVEN_ARROW);
knows_object(ELVEN_BOW);
knows_object(ELVEN_SPEAR);
knows_object(ELVEN_DAGGER);
knows_object(ELVEN_BROADSWORD);
knows_object(ELVEN_MITHRIL_COAT);
knows_object(ELVEN_LEATHER_HELM);
knows_object(ELVEN_SHIELD);
knows_object(ELVEN_BOOTS);
knows_object(ELVEN_CLOAK);
knows_object(ELVEN_SHORT_SWORD, FALSE);
knows_object(ELVEN_ARROW, FALSE);
knows_object(ELVEN_BOW, FALSE);
knows_object(ELVEN_SPEAR, FALSE);
knows_object(ELVEN_DAGGER, FALSE);
knows_object(ELVEN_BROADSWORD, FALSE);
knows_object(ELVEN_MITHRIL_COAT, FALSE);
knows_object(ELVEN_LEATHER_HELM, FALSE);
knows_object(ELVEN_SHIELD, FALSE);
knows_object(ELVEN_BOOTS, FALSE);
knows_object(ELVEN_CLOAK, FALSE);
break;
case PM_DWARF:
/* Dwarves can recognize all dwarvish objects */
knows_object(DWARVISH_SPEAR);
knows_object(DWARVISH_SHORT_SWORD);
knows_object(DWARVISH_MATTOCK);
knows_object(DWARVISH_IRON_HELM);
knows_object(DWARVISH_MITHRIL_COAT);
knows_object(DWARVISH_CLOAK);
knows_object(DWARVISH_ROUNDSHIELD);
knows_object(DWARVISH_SPEAR, FALSE);
knows_object(DWARVISH_SHORT_SWORD, FALSE);
knows_object(DWARVISH_MATTOCK, FALSE);
knows_object(DWARVISH_IRON_HELM, FALSE);
knows_object(DWARVISH_MITHRIL_COAT, FALSE);
knows_object(DWARVISH_CLOAK, FALSE);
knows_object(DWARVISH_ROUNDSHIELD, FALSE);
break;
case PM_GNOME:
@@ -829,17 +835,17 @@ u_init_race(void)
if (!Role_if(PM_WIZARD))
ini_inv(Xtra_food);
/* Orcs can recognize all orcish objects */
knows_object(ORCISH_SHORT_SWORD);
knows_object(ORCISH_ARROW);
knows_object(ORCISH_BOW);
knows_object(ORCISH_SPEAR);
knows_object(ORCISH_DAGGER);
knows_object(ORCISH_CHAIN_MAIL);
knows_object(ORCISH_RING_MAIL);
knows_object(ORCISH_HELM);
knows_object(ORCISH_SHIELD);
knows_object(URUK_HAI_SHIELD);
knows_object(ORCISH_CLOAK);
knows_object(ORCISH_SHORT_SWORD, FALSE);
knows_object(ORCISH_ARROW, FALSE);
knows_object(ORCISH_BOW, FALSE);
knows_object(ORCISH_SPEAR, FALSE);
knows_object(ORCISH_DAGGER, FALSE);
knows_object(ORCISH_CHAIN_MAIL, FALSE);
knows_object(ORCISH_RING_MAIL, FALSE);
knows_object(ORCISH_HELM, FALSE);
knows_object(ORCISH_SHIELD, FALSE);
knows_object(URUK_HAI_SHIELD, FALSE);
knows_object(ORCISH_CLOAK, FALSE);
break;
default: /* impossible */
@@ -847,6 +853,67 @@ u_init_race(void)
}
}
/* for 'pauper' aka 'unpreparsed'; take away any skills (bare-handed combat,
riding) that are better than unskilled; learn the book (without carrying
it or knowing its spell yet) for some key spells */
staticfn void
pauper_reinit(void)
{
int skill, preknown = STRANGE_OBJECT;
if (!u.uroleplay.pauper)
return;
for (skill = 0; skill < P_NUM_SKILLS; skill++)
if (P_SKILL(skill) > P_UNSKILLED) {
P_SKILL(skill) = P_UNSKILLED;
P_ADVANCE(skill) = 0;
}
/* pauper has lost out on initial skills, but provide some unspent skill
credits to make up for that */
u.weapon_slots = 2;
/* paupers don't know any spells yet, but several roles will recognize
the spellbook for a key spell (not necessarily that role's special
spell); "supply chests" on the first few levels provide a fairly
high chance to find the book; some other roles know a non-book item */
switch (Role_switch) {
case PM_HEALER:
preknown = SPE_HEALING;
break;
case PM_CLERIC:
case PM_KNIGHT:
case PM_MONK:
preknown = SPE_PROTECTION;
break;
case PM_WIZARD:
preknown = SPE_FORCE_BOLT;
break;
case PM_ARCHEOLOGIST:
preknown = TOUCHSTONE;
break;
case PM_CAVE_DWELLER:
preknown = FLINT;
break;
case PM_ROGUE:
case PM_TOURIST:
preknown = SACK;
break;
case PM_SAMURAI:
/* food ration isn't interesting to discover, but put "gunyoki" into
discoveries list for players who might not recognize what it is */
preknown = FOOD_RATION;
break;
default:
case PM_BARBARIAN:
case PM_RANGER:
case PM_VALKYRIE:
break;
}
if (preknown != STRANGE_OBJECT)
knows_object(preknown, TRUE);
}
/* boost STR and CON until hero can carry inventory */
staticfn void
u_init_carry_attr_boost(void)
@@ -950,6 +1017,8 @@ u_init(void)
u_init_role();
u_init_race();
if (u.uroleplay.pauper)
pauper_reinit();
/* roughly based on distribution in human population */
u.uhandedness = rn2(10) ? RIGHT_HANDED : LEFT_HANDED;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 weapon.c $NHDT-Date: 1723318730 2024/08/10 19:38:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */
/* NetHack 3.7 weapon.c $NHDT-Date: 1725227810 2024/09/01 21:56:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1705,7 +1705,8 @@ skill_init(const struct def_skill *class_skill)
(despite the function name, this works for spell skills too) */
unrestrict_weapon_skill(spell_skilltype(gu.urole.spelspec));
skill_based_spellbook_id();
if (!u.uroleplay.pauper) /* paupers lack advanced access to books */
skill_based_spellbook_id();
}
void