add 'montelecontrol' option (wizard-mode only)
Add a new debugging option, 'montelecontrol', that allows a wizard- mode player to choose a teleporting monster's destination. If player picks a bad spot, confirmation will be requested. If accepted, the spot will be used even though the consequences could be bad; that's on the player. If rejected, the destination will be assigned as if no control had been attempted rather than try again. The fuzzer isn't allowed to override a bad spot if it tries to pick one. That would probably trigger a sanity_check warning; the fuzzer causes impossible warnings to behave as if panic, so accepting a bad spot would just be fuzzer suicide. It is allowed to randomly set the option and maybe--though extremely unlikely--randomly pick a valid controlled destination.
This commit is contained in:
@@ -135,6 +135,7 @@ tiled_map show map as tiles, forces ascii_map Off; Qt, X11
|
|||||||
Boolean options available when running in debug mode (aka wizard mode):
|
Boolean options available when running in debug mode (aka wizard mode):
|
||||||
menu_tab_sep menu formatting--do not touch
|
menu_tab_sep menu formatting--do not touch
|
||||||
monpolycontrol have player choose shape-changing monsters' new shapes
|
monpolycontrol have player choose shape-changing monsters' new shapes
|
||||||
|
montelecontrol let player choose destination for teleported monsters
|
||||||
travel_debug show state of travel pathfinding algorithm on the map
|
travel_debug show state of travel pathfinding algorithm on the map
|
||||||
wizweight include item weights in inventory display
|
wizweight include item weights in inventory display
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -37,7 +37,7 @@
|
|||||||
.ds f0 "\*(vr
|
.ds f0 "\*(vr
|
||||||
.ds f1
|
.ds f1
|
||||||
.\"DO NOT REMOVE NH_DATESUB .ds f2 "DATE(%B %-d, %Y)
|
.\"DO NOT REMOVE NH_DATESUB .ds f2 "DATE(%B %-d, %Y)
|
||||||
.ds f2 "May 7, 2023
|
.ds f2 "June 8, 2023
|
||||||
.
|
.
|
||||||
.\" A note on some special characters:
|
.\" A note on some special characters:
|
||||||
.\" \(lq = left double quote
|
.\" \(lq = left double quote
|
||||||
@@ -4121,6 +4121,9 @@ Default \(oq}\(cq.
|
|||||||
.lp monpolycontrol
|
.lp monpolycontrol
|
||||||
Prompt for new form whenever any monster changes shape (default off).
|
Prompt for new form whenever any monster changes shape (default off).
|
||||||
Debug mode only.
|
Debug mode only.
|
||||||
|
.lp montelecontrol
|
||||||
|
Prompt for destination whenever any monster gets teleported (default off).
|
||||||
|
Debug mode only.
|
||||||
.lp mouse_support
|
.lp mouse_support
|
||||||
Allow use of the mouse for input and travel.
|
Allow use of the mouse for input and travel.
|
||||||
Valid settings are:
|
Valid settings are:
|
||||||
|
|||||||
+5
-1
@@ -46,7 +46,7 @@
|
|||||||
\author{Original version - Eric S. Raymond\\
|
\author{Original version - Eric S. Raymond\\
|
||||||
(Edited and expanded for 3.7.0 by Mike Stephenson and others)}
|
(Edited and expanded for 3.7.0 by Mike Stephenson and others)}
|
||||||
%DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)}
|
%DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)}
|
||||||
\date{May 7, 2023}
|
\date{June 8, 2023}
|
||||||
|
|
||||||
\maketitle
|
\maketitle
|
||||||
|
|
||||||
@@ -4511,6 +4511,10 @@ Default `{\tt \verb+}+}'.
|
|||||||
Prompt for new form whenever any monster changes shape (default off).
|
Prompt for new form whenever any monster changes shape (default off).
|
||||||
Debug mode only.
|
Debug mode only.
|
||||||
%.lp
|
%.lp
|
||||||
|
\item[\ib{montelecontrol}]
|
||||||
|
Prompt for destination whenever any monster gets teleported (default off).
|
||||||
|
Debug mode only.
|
||||||
|
%.lp
|
||||||
\item[\ib{mouse\verb+_+support}]
|
\item[\ib{mouse\verb+_+support}]
|
||||||
Allow use of the mouse for input and travel.
|
Allow use of the mouse for input and travel.
|
||||||
Valid settings are:
|
Valid settings are:
|
||||||
|
|||||||
@@ -2820,6 +2820,7 @@ extern void level_tele_trap(struct trap *, unsigned);
|
|||||||
extern void rloc_to(struct monst *, coordxy, coordxy);
|
extern void rloc_to(struct monst *, coordxy, coordxy);
|
||||||
extern void rloc_to_flag(struct monst *, coordxy, coordxy, unsigned);
|
extern void rloc_to_flag(struct monst *, coordxy, coordxy, unsigned);
|
||||||
extern boolean rloc(struct monst *, unsigned);
|
extern boolean rloc(struct monst *, unsigned);
|
||||||
|
extern boolean control_mon_tele(struct monst *, coord *cc, unsigned, boolean);
|
||||||
extern boolean tele_restrict(struct monst *);
|
extern boolean tele_restrict(struct monst *);
|
||||||
extern void mtele_trap(struct monst *, struct trap *, int);
|
extern void mtele_trap(struct monst *, struct trap *, int);
|
||||||
extern int mlevel_tele_trap(struct monst *, struct trap *, boolean, int);
|
extern int mlevel_tele_trap(struct monst *, struct trap *, boolean, int);
|
||||||
|
|||||||
@@ -236,6 +236,7 @@ struct instance_flags {
|
|||||||
boolean debug_mongen; /* debug: prevent monster generation */
|
boolean debug_mongen; /* debug: prevent monster generation */
|
||||||
boolean debug_hunger; /* debug: prevent hunger */
|
boolean debug_hunger; /* debug: prevent hunger */
|
||||||
boolean mon_polycontrol; /* debug: control monster polymorphs */
|
boolean mon_polycontrol; /* debug: control monster polymorphs */
|
||||||
|
boolean mon_telecontrol; /* debug: control monster teleports */
|
||||||
boolean in_dumplog; /* doing the dumplog right now? */
|
boolean in_dumplog; /* doing the dumplog right now? */
|
||||||
boolean in_parse; /* is a command being parsed? */
|
boolean in_parse; /* is a command being parsed? */
|
||||||
/* suppress terminate during options parsing, for --showpaths */
|
/* suppress terminate during options parsing, for --showpaths */
|
||||||
|
|||||||
@@ -454,6 +454,9 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
|||||||
NHOPTB(monpolycontrol, Advanced, 0, opt_in, set_wizonly,
|
NHOPTB(monpolycontrol, Advanced, 0, opt_in, set_wizonly,
|
||||||
Off, Yes, No, No, NoAlias, &iflags.mon_polycontrol, Term_False,
|
Off, Yes, No, No, NoAlias, &iflags.mon_polycontrol, Term_False,
|
||||||
"control monster polymorphs")
|
"control monster polymorphs")
|
||||||
|
NHOPTB(montelecontrol, Advanced, 0, opt_in, set_wizonly,
|
||||||
|
Off, Yes, No, No, NoAlias, &iflags.mon_telecontrol, Term_False,
|
||||||
|
"control monster teleport destinations")
|
||||||
NHOPTC(monsters, Advanced, MAXMCLASSES, opt_in, set_in_config,
|
NHOPTC(monsters, Advanced, MAXMCLASSES, opt_in, set_in_config,
|
||||||
No, Yes, No, No, NoAlias,
|
No, Yes, No, No, NoAlias,
|
||||||
"list of symbols to use for monsters")
|
"list of symbols to use for monsters")
|
||||||
|
|||||||
@@ -3564,6 +3564,17 @@ mnexto(struct monst *mtmp, unsigned int rlocflags)
|
|||||||
deal_with_overcrowding(mtmp);
|
deal_with_overcrowding(mtmp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* wizard-mode player can choose destination by setting 'montelecontrol'
|
||||||
|
option; enexto()'s value for 'mm' will be the default; 'savemm' is
|
||||||
|
used to make sure player doesn't choose hero's location and then
|
||||||
|
answer 'y' to the 'override invalid spot' prompt */
|
||||||
|
if (iflags.mon_telecontrol) {
|
||||||
|
coord savemm = mm;
|
||||||
|
|
||||||
|
if (!control_mon_tele(mtmp, &mm, rlocflags, FALSE))
|
||||||
|
mm = savemm;
|
||||||
|
}
|
||||||
|
|
||||||
rloc_to_flag(mtmp, mm.x, mm.y, rlocflags);
|
rloc_to_flag(mtmp, mm.x, mm.y, rlocflags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3595,6 +3606,7 @@ maybe_mnexto(struct monst *mtmp)
|
|||||||
if (couldsee(mm.x, mm.y)
|
if (couldsee(mm.x, mm.y)
|
||||||
/* don't move grid bugs diagonally */
|
/* don't move grid bugs diagonally */
|
||||||
&& (diagok || mm.x == mtmp->mx || mm.y == mtmp->my)) {
|
&& (diagok || mm.x == mtmp->mx || mm.y == mtmp->my)) {
|
||||||
|
/* [this doesn't honor the 'montelecontrol' option] */
|
||||||
rloc_to(mtmp, mm.x, mm.y);
|
rloc_to(mtmp, mm.x, mm.y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3658,6 +3670,7 @@ mnearto(
|
|||||||
newx = mm.x;
|
newx = mm.x;
|
||||||
newy = mm.y;
|
newy = mm.y;
|
||||||
}
|
}
|
||||||
|
/* [this doesn't honor the 'montelecontrol' option] */
|
||||||
rloc_to_flag(mtmp, newx, newy, rlocflags);
|
rloc_to_flag(mtmp, newx, newy, rlocflags);
|
||||||
|
|
||||||
if (move_other && othermon) {
|
if (move_other && othermon) {
|
||||||
|
|||||||
@@ -1735,6 +1735,16 @@ rloc(
|
|||||||
goto found_xy;
|
goto found_xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wizard-mode player can choose destination by setting 'montelecontrol'
|
||||||
|
option; ignored if/when this is arrival of a migrating monster */
|
||||||
|
if (iflags.mon_telecontrol && mtmp->mx) {
|
||||||
|
cc.x = mtmp->mx, cc.y = mtmp->my;
|
||||||
|
if (control_mon_tele(mtmp, &cc, rlocflags, TRUE)) {
|
||||||
|
x = cc.x, y = cc.y;
|
||||||
|
goto found_xy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* this used to try randomly 1000 times, then fallback to left-to-right
|
/* this used to try randomly 1000 times, then fallback to left-to-right
|
||||||
top-to-bottom exhaustive check; now that the exhaustive check uses
|
top-to-bottom exhaustive check; now that the exhaustive check uses
|
||||||
randomized order, reduce the number of random attempts to 50;
|
randomized order, reduce the number of random attempts to 50;
|
||||||
@@ -1788,6 +1798,45 @@ rloc(
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* let wizard-mode player choose a teleporting monster's destination */
|
||||||
|
boolean
|
||||||
|
control_mon_tele(
|
||||||
|
struct monst *mon,
|
||||||
|
coord *cc_p, /* input: default spot; output: player selected spot */
|
||||||
|
unsigned rlocflags,
|
||||||
|
boolean via_rloc)
|
||||||
|
{
|
||||||
|
char tcbuf[BUFSZ];
|
||||||
|
|
||||||
|
if (!isok(cc_p->x, cc_p->y)) {
|
||||||
|
cc_p->x = mon->mx, cc_p->y = mon->my;
|
||||||
|
if (!isok(cc_p->x, cc_p->y))
|
||||||
|
cc_p->x = u.ux, cc_p->y = u.uy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wizard || !iflags.mon_telecontrol)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pline("Teleport %s @ <%d,%d> where?",
|
||||||
|
noit_mon_nam(mon), mon->mx, mon->my);
|
||||||
|
/* getpos '?' will show "Move the cursor to <where to teleport Foo>:" */
|
||||||
|
Sprintf(tcbuf, "where to teleport %s", noit_mon_nam(mon));
|
||||||
|
if (getpos(cc_p, FALSE, tcbuf) >= 0 && !u_at(cc_p->x, cc_p->y)) {
|
||||||
|
if (via_rloc
|
||||||
|
? rloc_pos_ok(cc_p->x, cc_p->y, mon)
|
||||||
|
: goodpos(cc_p->x, cc_p->y, mon, rlocflags))
|
||||||
|
return TRUE;
|
||||||
|
if (!iflags.debug_fuzzer) {
|
||||||
|
Sprintf(tcbuf, "<%d,%d> is not considered viable; force anyway?",
|
||||||
|
mon->mx, mon->my);
|
||||||
|
if (y_n(tcbuf) == 'y')
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pline("%s destination.", via_rloc ? "Picking random" : "Using derived");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mvault_tele(struct monst* mtmp)
|
mvault_tele(struct monst* mtmp)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user