fix github pull request #355 - Sokoban cheating

Track sokoban cheating (taking actions that incur a luck penalty).
The pull request only reported the number of times (possibly zero)
that the player broke nethack's sokoban rules when reporting the
"you obtained the Sokoban prize" achievement, which is when the
count is most meaningful, but this implements it as a full-fledged
conduct instead.  This way the #conduct command can be used after
"creative nethacking" to check immediately whether an action has
violated the Sokoban rules so a player willing to put in a bit of
effort can eventually learn which actions have a negative impact.

The new conduct is only shown during games where the character has
entered the Sokoban branch, but once that has happened it gets shown
no matter the location at the time of #conduct or end of game.

Most of this wasn't in the pull request:  expanding the Guidebook to
give more information about sokoban and its conduct.

Bump EDITLEVEL to invalidate to-be-3.7 save files because u.uconduct
has been extended.

Fixes #355
This commit is contained in:
PatR
2020-07-03 02:21:30 -07:00
parent 26dcf68df8
commit 8801ec34eb
7 changed files with 164 additions and 27 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 insight.c $NHDT-Date: 1586375531 2020/04/08 19:52:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */
/* NetHack 3.7 insight.c $NHDT-Date: 1593768047 2020/07/03 09:20:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1769,7 +1769,7 @@ show_conduct(final)
int final;
{
char buf[BUFSZ];
int ngenocided;
int ngenocided, soko_ach;
/* Create the conduct window */
g.en_win = create_nhwindow(NHW_MENU);
@@ -1866,6 +1866,38 @@ int final;
" for any artifacts", "");
}
/* only report Sokoban conduct if the Sokoban branch has been entered;
to find out whether that's the case, it's simpler to check the
recorded achievements than the convoluted dungeon data structure */
for (soko_ach = 0; u.uachieved[soko_ach]; ++soko_ach)
if (u.uachieved[soko_ach] == ACH_SOKO) /* "entered Sokoban" */
break;
if (u.uachieved[soko_ach]) {
const char *presentverb = "have violated", *pastverb = "violated";
Strcpy(buf, " the special Sokoban rules ");
switch (u.uconduct.sokocheat) {
case 0L:
presentverb = "have not violated";
pastverb = "did not violate";
Strcpy(buf, " any of the special Sokoban rules");
break;
case 1L:
Strcat(buf, "once");
break;
case 2L:
Strcat(buf, "twice");
break;
case 3L:
Strcat(buf, "thrice");
break;
default:
Sprintf(eos(buf), "%ld times", u.uconduct.sokocheat);
break;
}
enl_msg(You_, presentverb, pastverb, buf, "");
}
show_achievements(final);
/* Pop up the window and wait for a key */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 trap.c $NHDT-Date: 1586382778 2020/04/08 21:52:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.358 $ */
/* NetHack 3.6 trap.c $NHDT-Date: 1593768051 2020/07/03 09:20:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -5456,13 +5456,18 @@ void
sokoban_guilt()
{
if (Sokoban) {
u.uconduct.sokocheat++;
change_luck(-1);
/* TODO: issue some feedback so that player can learn that whatever
he/she just did is a naughty thing to do in sokoban and should
probably be avoided in future....
Caveat: doing this might introduce message sequencing issues,
depending upon feedback during the various actions which trigger
Sokoban luck penalties. */
/*
* TODO:
* Issue some feedback so that player can learn that whatever
* he/she just did is a naughty thing to do in sokoban and
* should probably be avoided in future....
*
* Caveat: doing this might introduce message sequencing
* issues, depending upon feedback during the various actions
* which trigger Sokoban luck penalties.
*/
}
}