Shopkeepers hold a grudge against past thieves
When you steal from a shop, its shopkeeper will remember you as a thief and charge you higher prices in the future (as well as be more curt and less polite in interactions with you, though not outright hostile) even if you pacify them, or die on the level and revisit it later as a bones file. This was an idea aosdict had, and I think it makes sense that a shopkeeper doesn't forgive and forget, immediately returning to treating you exactly like anyone else, just because you were terrorized into paying her back. Paying a shopkeeper off may cause her to stop actively attacking you, but it feels like she'd have her eye on you as a known thief going forward (and maybe would hang up a sign with your picture, saying something like "DO NOT ACCEPT CHECKS FROM THIS HERO"). This surchage already existed, but since it was tied to active anger (which typically causes a shopkeeper to quickly abandon their shop to follow you) it was somewhat rare to see it in action. I did not implement it here, but one possible further tweak might be to clear the surcharge if the shopkeeper is pacified via taming magic (which more-or-less magically brainwashes the target to feel positively towards the hero) but not if you simply pay your debts.
This commit is contained in:
committed by
Pasi Kallinen
parent
94e8141c01
commit
8a549b0a60
77
src/shk.c
77
src/shk.c
@@ -28,7 +28,7 @@ static const char the_contents_of[] = "the contents of ";
|
||||
|
||||
static void append_honorific(char *);
|
||||
static long addupbill(struct monst *);
|
||||
static void pacify_shk(struct monst *);
|
||||
static void pacify_shk(struct monst *, boolean);
|
||||
static struct bill_x *onbill(struct obj *, struct monst *, boolean);
|
||||
static struct monst *next_shkp(struct monst *, boolean);
|
||||
static long shop_debt(struct eshk *);
|
||||
@@ -166,10 +166,7 @@ next_shkp(register struct monst *shkp, boolean withbill)
|
||||
}
|
||||
|
||||
if (shkp) {
|
||||
if (NOTANGRY(shkp)) {
|
||||
if (ESHK(shkp)->surcharge)
|
||||
pacify_shk(shkp);
|
||||
} else {
|
||||
if (ANGRY(shkp)) {
|
||||
if (!ESHK(shkp)->surcharge)
|
||||
rile_shk(shkp);
|
||||
}
|
||||
@@ -246,7 +243,7 @@ restshk(struct monst* shkp, boolean ghostly)
|
||||
if (ghostly) {
|
||||
assign_level(&eshkp->shoplevel, &u.uz);
|
||||
if (ANGRY(shkp) && strncmpi(eshkp->customer, g.plname, PL_NSIZ))
|
||||
pacify_shk(shkp);
|
||||
pacify_shk(shkp, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -413,15 +410,16 @@ u_left_shop(char *leavestring, boolean newlev)
|
||||
* Player just stepped onto shop-boundary (known from above logic).
|
||||
* Try to intimidate him into paying his bill
|
||||
*/
|
||||
boolean not_upset = !eshkp->surcharge;
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
verbalize(NOTANGRY(shkp) ? "%s! Please pay before leaving."
|
||||
: "%s! Don't you leave without paying!",
|
||||
verbalize(not_upset ? "%s! Please pay before leaving."
|
||||
: "%s! Don't you leave without paying!",
|
||||
g.plname);
|
||||
else
|
||||
pline("%s %s that you need to pay before leaving%s",
|
||||
Shknam(shkp),
|
||||
NOTANGRY(shkp) ? "points out" : "makes it clear",
|
||||
NOTANGRY(shkp) ? "." : "!");
|
||||
not_upset ? "points out" : "makes it clear",
|
||||
not_upset ? "." : "!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -594,7 +592,7 @@ u_entered_shop(char* enterstring)
|
||||
eshkp->visitct = 0;
|
||||
eshkp->following = 0;
|
||||
(void) strncpy(eshkp->customer, g.plname, PL_NSIZ);
|
||||
pacify_shk(shkp);
|
||||
pacify_shk(shkp, TRUE);
|
||||
}
|
||||
|
||||
if (muteshk(shkp) || eshkp->following)
|
||||
@@ -620,6 +618,13 @@ u_entered_shop(char* enterstring)
|
||||
pline("%s seems %s over your return to %s %s!",
|
||||
Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))],
|
||||
noit_mhis(shkp), shtypes[rt - SHOPBASE].name);
|
||||
} else if (eshkp->surcharge) {
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
verbalize("Back again, %s? I've got my %s on you.",
|
||||
g.plname, mbodypart(shkp, EYE));
|
||||
else
|
||||
pline_The("atmosphere at %s %s seems unwelcoming.",
|
||||
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
|
||||
} else if (eshkp->robbed) {
|
||||
if (!Deaf)
|
||||
pline("%s mutters imprecations against shoplifters.",
|
||||
@@ -640,7 +645,7 @@ u_entered_shop(char* enterstring)
|
||||
}
|
||||
/* can't do anything about blocking if teleported in */
|
||||
if (!inside_shop(u.ux, u.uy)) {
|
||||
boolean should_block;
|
||||
boolean should_block, not_upset = !eshkp->surcharge;
|
||||
int cnt;
|
||||
const char *tool;
|
||||
struct obj *pick = carrying(PICK_AXE),
|
||||
@@ -667,25 +672,25 @@ u_entered_shop(char* enterstring)
|
||||
makeknown(DWARVISH_MATTOCK);
|
||||
}
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
verbalize(NOTANGRY(shkp)
|
||||
verbalize(not_upset
|
||||
? "Will you please leave your %s%s outside?"
|
||||
: "Leave the %s%s outside.",
|
||||
tool, plur(cnt));
|
||||
else
|
||||
pline("%s %s to let you in with your %s%s.",
|
||||
Shknam(shkp),
|
||||
NOTANGRY(shkp) ? "is hesitant" : "refuses",
|
||||
not_upset ? "is hesitant" : "refuses",
|
||||
tool, plur(cnt));
|
||||
should_block = TRUE;
|
||||
} else if (u.usteed) {
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
verbalize(NOTANGRY(shkp) ? "Will you please leave %s outside?"
|
||||
: "Leave %s outside.",
|
||||
verbalize(not_upset ? "Will you please leave %s outside?"
|
||||
: "Leave %s outside.",
|
||||
y_monnam(u.usteed));
|
||||
else
|
||||
pline("%s %s to let you in while you're riding %s.",
|
||||
Shknam(shkp),
|
||||
NOTANGRY(shkp) ? "doesn't want" : "refuses",
|
||||
not_upset ? "doesn't want" : "refuses",
|
||||
y_monnam(u.usteed));
|
||||
should_block = TRUE;
|
||||
} else {
|
||||
@@ -832,10 +837,7 @@ shop_keeper(char rmno)
|
||||
shkp = (rmno >= ROOMOFFSET) ? g.rooms[rmno - ROOMOFFSET].resident : 0;
|
||||
if (shkp) {
|
||||
if (has_eshk(shkp)) {
|
||||
if (NOTANGRY(shkp)) {
|
||||
if (ESHK(shkp)->surcharge)
|
||||
pacify_shk(shkp);
|
||||
} else {
|
||||
if (ANGRY(shkp)) {
|
||||
if (!ESHK(shkp)->surcharge)
|
||||
rile_shk(shkp);
|
||||
}
|
||||
@@ -1070,10 +1072,10 @@ angry_shk_exists(void)
|
||||
|
||||
/* remove previously applied surcharge from all billed items */
|
||||
static void
|
||||
pacify_shk(register struct monst* shkp)
|
||||
pacify_shk(register struct monst* shkp, boolean clear_surcharge)
|
||||
{
|
||||
NOTANGRY(shkp) = TRUE; /* make peaceful */
|
||||
if (ESHK(shkp)->surcharge) {
|
||||
if (clear_surcharge && ESHK(shkp)->surcharge) {
|
||||
register struct bill_x *bp = ESHK(shkp)->bill_p;
|
||||
register int ct = ESHK(shkp)->billct;
|
||||
|
||||
@@ -1125,7 +1127,7 @@ make_happy_shk(register struct monst* shkp, register boolean silentkops)
|
||||
boolean wasmad = ANGRY(shkp);
|
||||
struct eshk *eshkp = ESHK(shkp);
|
||||
|
||||
pacify_shk(shkp);
|
||||
pacify_shk(shkp, FALSE);
|
||||
eshkp->following = 0;
|
||||
eshkp->robbed = 0L;
|
||||
if (!Role_if(PM_ROGUE))
|
||||
@@ -1559,13 +1561,15 @@ dopay(void)
|
||||
}
|
||||
if (!ANGRY(shkp) && paid) {
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
verbalize("Thank you for shopping in %s %s!",
|
||||
verbalize("Thank you for shopping in %s %s%s",
|
||||
s_suffix(shkname(shkp)),
|
||||
shtypes[eshkp->shoptype - SHOPBASE].name);
|
||||
shtypes[eshkp->shoptype - SHOPBASE].name,
|
||||
!eshkp->surcharge ? "!" : ".");
|
||||
else
|
||||
pline("%s nods appreciatively at you for shopping in %s %s!",
|
||||
Shknam(shkp), noit_mhis(shkp),
|
||||
shtypes[eshkp->shoptype - SHOPBASE].name);
|
||||
pline("%s nods%s at you for shopping in %s %s%s",
|
||||
Shknam(shkp), !eshkp->surcharge ? " appreciatively" : "",
|
||||
noit_mhis(shkp), shtypes[eshkp->shoptype - SHOPBASE].name,
|
||||
!eshkp->surcharge ? "!" : ".");
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
@@ -1865,7 +1869,7 @@ inherits(struct monst* shkp, int numsk, int croaked, boolean silently)
|
||||
: "you ",
|
||||
noit_mhim(shkp));
|
||||
/* shopkeeper has now been paid in full */
|
||||
pacify_shk(shkp);
|
||||
pacify_shk(shkp, FALSE);
|
||||
eshkp->following = 0;
|
||||
eshkp->robbed = 0L;
|
||||
}
|
||||
@@ -2713,10 +2717,11 @@ addtobill(
|
||||
} else {
|
||||
long save_quan = obj->quan;
|
||||
|
||||
Strcpy(buf, "\"For you, ");
|
||||
Strcpy(buf, "\"For you,");
|
||||
if (ANGRY(shkp)) {
|
||||
Strcat(buf, "scum;");
|
||||
} else {
|
||||
Strcat(buf, " scum;");
|
||||
} else if (!ESHK(shkp)->surcharge) {
|
||||
Strcat(buf, " ");
|
||||
append_honorific(buf);
|
||||
Strcat(buf, "; only");
|
||||
}
|
||||
@@ -4339,7 +4344,7 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
|
||||
pline("Mollified, %s accepts your restitution.", shkname(shkp));
|
||||
/* move shk back to his home loc */
|
||||
home_shk(shkp, FALSE);
|
||||
pacify_shk(shkp);
|
||||
pacify_shk(shkp, FALSE);
|
||||
/* home_shk() suppresses rloc()'s vanish/appear messages */
|
||||
if (shkp->mx != sx || shkp->my != sy) {
|
||||
if (was_outside && canspotmon(shkp))
|
||||
@@ -4569,6 +4574,10 @@ shk_chat(struct monst* shkp)
|
||||
pline("%s %s about a recent robbery.",
|
||||
Shknam(shkp),
|
||||
(!Deaf && !muteshk(shkp)) ? "complains" : "indicates concern");
|
||||
} else if (eshk->surcharge) {
|
||||
pline("%s %s that %s is watching you carefully.", Shknam(shkp),
|
||||
(!Deaf && !muteshk(shkp)) ? "warns you" : "indicates",
|
||||
noit_mhe(shkp));
|
||||
} else if ((shkmoney = money_cnt(shkp->minvent)) < 50L) {
|
||||
pline("%s %s that business is bad.",
|
||||
Shknam(shkp),
|
||||
|
||||
Reference in New Issue
Block a user