Merge branch 'NetHack-3.7' into NetHack-3.7-Jan2020
This commit is contained in:
@@ -3907,6 +3907,10 @@ Values are \(lqautodetect\(rq, \(lqdefault\(rq, or \(lqvga\(rq.
|
||||
Setting \(lqvga\(rq (or \(lqautodetect\(rq with vga hardware present)
|
||||
will cause the game to display tiles.
|
||||
Cannot be set with the \(oqO\(cq command.
|
||||
.lp video_height
|
||||
Set the VGA mode resolution height (MS-DOS only, with video:vga)
|
||||
.lp video_width
|
||||
Set the VGA mode resolution width (MS-DOS only, with video:vga)
|
||||
.lp videocolors
|
||||
Set the color palette for PC systems using NO_TERMS
|
||||
(default 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only).
|
||||
|
||||
@@ -4342,6 +4342,12 @@ Setting {\it vga\/} (or {\it autodetect\/} with vga hardware present) will
|
||||
cause the game to display tiles.
|
||||
Cannot be set with the `{\tt O}' command.
|
||||
%.lp
|
||||
\item[\ib{video\verb+_+height}]
|
||||
Set the VGA mode resolution height (MS-DOS only, with video:vga)
|
||||
%.lp
|
||||
\item[\ib{video\verb+_+width}]
|
||||
Set the VGA mode resolution width (MS-DOS only, with video:vga)
|
||||
%.lp
|
||||
\item[\ib{videocolors}]
|
||||
\begin{sloppypar}
|
||||
Set the color palette for PC systems using NO\verb+_+TERMS
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ $NHDT-Date: 1579914040 2020/01/25 01:00:40 $
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ $NHDT-Date: 1580043420 2020/01/26 12:57:00 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -47,6 +47,7 @@ if at the edge of the map window, trying to move farther fails but used a turn
|
||||
hero can no longer wear blindfold/towel/lenses when poly'd into headless form
|
||||
revamp achievement tracking for exploring Mine's End and Sokoban (by acquiring
|
||||
luckstone and bag of holding or amulet of reflection, respectively)
|
||||
throttle long worm growth rate and HP accumulation
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
@@ -110,8 +111,8 @@ when hallucinating, see hallucinated liquids when looking at water or lava
|
||||
on the map
|
||||
applying a spellbook hints about read charges left
|
||||
wizard mode wishing for level topology can now create hidden doors (ask for
|
||||
"secret door" when at a door or wall location) and hidden corridor
|
||||
spots ("secret corridor" at a corridor location)
|
||||
"secret door" when at a door or wall location), hidden corridor
|
||||
spots ("secret corridor" at a corridor location), and clouds
|
||||
tiny chance for randomly created spellbooks to be Discworld novels instead
|
||||
of having only one in the first book or scroll shop created (won't
|
||||
occur in hero's initial inventory or NPC priest inventory or be
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1578895332 2020/01/13 06:02:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.785 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1580044333 2020/01/26 13:12:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.786 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1437,7 +1437,7 @@ E int FDECL(mfndpos, (struct monst *, coord *, long *, long));
|
||||
E boolean FDECL(monnear, (struct monst *, int, int));
|
||||
E void NDECL(dmonsfree);
|
||||
E void FDECL(elemental_clog, (struct monst *));
|
||||
E int FDECL(mcalcmove, (struct monst *));
|
||||
E int FDECL(mcalcmove, (struct monst *, BOOLEAN_P));
|
||||
E void NDECL(mcalcdistress);
|
||||
E void FDECL(replmon, (struct monst *, struct monst *));
|
||||
E void FDECL(relmon, (struct monst *, struct monst **));
|
||||
|
||||
@@ -367,6 +367,10 @@ struct instance_flags {
|
||||
int wc_map_mode; /* specify map viewing options, mostly
|
||||
* for backward compatibility */
|
||||
int wc_player_selection; /* method of choosing character */
|
||||
#if defined(MSDOS)
|
||||
unsigned wc_video_width; /* X resolution of screen */
|
||||
unsigned wc_video_height; /* Y resolution of screen */
|
||||
#endif
|
||||
boolean wc_splash_screen; /* display an opening splash screen or not */
|
||||
boolean wc_popup_dialog; /* put queries in pop up dialogs instead of
|
||||
* in the message window */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 obj.h $NHDT-Date: 1508827590 2017/10/24 06:46:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
|
||||
/* NetHack 3.6 obj.h $NHDT-Date: 1580036271 2020/01/26 10:57:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2006. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -114,7 +114,6 @@ struct obj {
|
||||
#define leashmon corpsenm /* gets m_id of attached pet */
|
||||
#define fromsink corpsenm /* a potion from a sink */
|
||||
#define novelidx corpsenm /* 3.6 tribute - the index of the novel title */
|
||||
#define record_achieve_special corpsenm
|
||||
int usecount; /* overloaded for various things that tally */
|
||||
#define spestudied usecount /* # of times a spellbook has been studied */
|
||||
unsigned oeaten; /* nutrition left in food, if partly eaten */
|
||||
|
||||
23
include/rm.h
23
include/rm.h
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 rm.h $NHDT-Date: 1578258722 2020/01/05 21:12:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */
|
||||
/* NetHack 3.6 rm.h $NHDT-Date: 1580070206 2020/01/26 20:23:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2017. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -528,16 +528,19 @@ struct rm {
|
||||
#define SV7 0x80
|
||||
#define SVALL 0xFF
|
||||
|
||||
#define doormask flags
|
||||
#define altarmask flags
|
||||
#define wall_info flags
|
||||
#define ladder flags
|
||||
#define drawbridgemask flags
|
||||
#define looted flags
|
||||
#define icedpool flags
|
||||
|
||||
/* if these get changed or expanded, make sure wizard-mode wishing becomes
|
||||
aware of the new usage */
|
||||
#define doormask flags /* door, sdoor (note conflict with wall_info) */
|
||||
#define altarmask flags /* alignment and maybe temple */
|
||||
#define wall_info flags /* wall, sdoor (note conflict with doormask) */
|
||||
#define ladder flags /* up or down */
|
||||
#define drawbridgemask flags /* what's underneath when the span is open */
|
||||
#define looted flags /* used for throne, tree, fountain, sink, door */
|
||||
#define icedpool flags /* used for ice (in case it melts) */
|
||||
/* horizonal applies to walls, doors (including sdoor); also to iron bars
|
||||
even though they don't have separate symbols for horizontal and vertical */
|
||||
#define blessedftn horizontal /* a fountain that grants attribs */
|
||||
#define disturbed horizontal /* a grave that has been disturbed */
|
||||
#define disturbed horizontal /* a grave that has been disturbed */
|
||||
|
||||
struct damage {
|
||||
struct damage *next;
|
||||
|
||||
@@ -18,9 +18,15 @@ struct TileImage {
|
||||
|
||||
boolean FDECL(read_tiles, (const char *filename, BOOLEAN_P true_color));
|
||||
const struct Pixel *NDECL(get_palette);
|
||||
boolean FDECL(set_tile_type, (BOOLEAN_P true_color));
|
||||
void NDECL(free_tiles);
|
||||
const struct TileImage *FDECL(get_tile, (unsigned tile_index));
|
||||
|
||||
/* For resizing tiles */
|
||||
struct TileImage *FDECL(stretch_tile, (const struct TileImage *,
|
||||
unsigned, unsigned));
|
||||
void FDECL(free_tile, (struct TileImage *));
|
||||
|
||||
/* Used internally by the tile set code */
|
||||
struct TileSetImage {
|
||||
/* Image data */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 allmain.c $NHDT-Date: 1578448653 2020/01/08 01:57:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */
|
||||
/* NetHack 3.6 allmain.c $NHDT-Date: 1580044340 2020/01/26 13:12:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -125,7 +125,7 @@ boolean resuming;
|
||||
to skip dead monsters here because they will have
|
||||
been purged at end of their previous round of moving */
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
||||
mtmp->movement += mcalcmove(mtmp);
|
||||
mtmp->movement += mcalcmove(mtmp, TRUE);
|
||||
|
||||
/* occasionally add another monster; since this takes
|
||||
place after movement has been allotted, the new
|
||||
@@ -139,7 +139,7 @@ boolean resuming;
|
||||
/* calculate how much time passed. */
|
||||
if (u.usteed && u.umoved) {
|
||||
/* your speed doesn't augment steed's speed */
|
||||
moveamt = mcalcmove(u.usteed);
|
||||
moveamt = mcalcmove(u.usteed, TRUE);
|
||||
} else {
|
||||
moveamt = g.youmonst.data->mmove;
|
||||
|
||||
|
||||
29
src/mon.c
29
src/mon.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1577759850 2019/12/31 02:37:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.319 $ */
|
||||
/* NetHack 3.6 mon.c $NHDT-Date: 1580044343 2020/01/26 13:12:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.320 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -633,9 +633,11 @@ register struct monst *mtmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* calculate 'mon's movement for current turn; called from moveloop() */
|
||||
int
|
||||
mcalcmove(mon)
|
||||
mcalcmove(mon, m_moving)
|
||||
struct monst *mon;
|
||||
boolean m_moving; /* True: adjust for moving; False: just adjust for speed */
|
||||
{
|
||||
int mmove = mon->data->mmove;
|
||||
int mmove_adj;
|
||||
@@ -656,17 +658,18 @@ struct monst *mon;
|
||||
mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
|
||||
}
|
||||
|
||||
/* Randomly round the monster's speed to a multiple of NORMAL_SPEED.
|
||||
This makes it impossible for the player to predict when they'll get
|
||||
a free turn (thus preventing exploits like "melee kiting"), while
|
||||
retaining guarantees about shopkeepers not being outsped by a
|
||||
normal-speed player, normal-speed players being unable to open up
|
||||
a gap when fleeing a normal-speed monster, etc. */
|
||||
mmove_adj = mmove % NORMAL_SPEED;
|
||||
mmove -= mmove_adj;
|
||||
if (rn2(NORMAL_SPEED) < mmove_adj)
|
||||
mmove += NORMAL_SPEED;
|
||||
|
||||
if (m_moving) {
|
||||
/* Randomly round the monster's speed to a multiple of NORMAL_SPEED.
|
||||
This makes it impossible for the player to predict when they'll
|
||||
get a free turn (thus preventing exploits like "melee kiting"),
|
||||
while retaining guarantees about shopkeepers not being outsped
|
||||
by a normal-speed player, normal-speed players being unable
|
||||
to open up a gap when fleeing a normal-speed monster, etc. */
|
||||
mmove_adj = mmove % NORMAL_SPEED;
|
||||
mmove -= mmove_adj;
|
||||
if (rn2(NORMAL_SPEED) < mmove_adj)
|
||||
mmove += NORMAL_SPEED;
|
||||
}
|
||||
return mmove;
|
||||
}
|
||||
|
||||
|
||||
95
src/objnam.c
95
src/objnam.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1579261291 2020/01/17 11:41:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1580070220 2020/01/26 20:23:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2952,8 +2952,8 @@ char *bp, *p;
|
||||
int locked, trapped;
|
||||
{
|
||||
struct rm *lev;
|
||||
boolean madeterrain = FALSE, badterrain = FALSE;
|
||||
int trap, x = u.ux, y = u.uy;
|
||||
boolean madeterrain = FALSE, badterrain = FALSE, didblock;
|
||||
int trap, oldtyp, x = u.ux, y = u.uy;
|
||||
|
||||
for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
|
||||
struct trap *t;
|
||||
@@ -2978,21 +2978,25 @@ int locked, trapped;
|
||||
/* furniture and terrain (use at your own risk; can clobber stairs
|
||||
or place furniture on existing traps which shouldn't be allowed) */
|
||||
lev = &levl[x][y];
|
||||
oldtyp = lev->typ;
|
||||
didblock = does_block(x, y, lev);
|
||||
p = eos(bp);
|
||||
if (!BSTRCMPI(bp, p - 8, "fountain")) {
|
||||
lev->typ = FOUNTAIN;
|
||||
g.level.flags.nfountains++;
|
||||
if (!strncmpi(bp, "magic ", 6))
|
||||
lev->blessedftn = 1;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
lev->blessedftn = !strncmpi(bp, "magic ", 6);
|
||||
pline("A %sfountain.", lev->blessedftn ? "magic " : "");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 6, "throne")) {
|
||||
lev->typ = THRONE;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A throne.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "sink")) {
|
||||
lev->typ = SINK;
|
||||
g.level.flags.nsinks++;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A sink.");
|
||||
madeterrain = TRUE;
|
||||
|
||||
@@ -3000,6 +3004,7 @@ int locked, trapped;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "pool")
|
||||
|| !BSTRCMPI(bp, p - 4, "moat")) {
|
||||
lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
|
||||
lev->flags = 0;
|
||||
del_engr_at(x, y);
|
||||
pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
|
||||
/* Must manually make kelp! */
|
||||
@@ -3009,6 +3014,7 @@ int locked, trapped;
|
||||
/* also matches "molten lava" */
|
||||
} else if (!BSTRCMPI(bp, p - 4, "lava")) {
|
||||
lev->typ = LAVAPOOL;
|
||||
lev->flags = 0;
|
||||
del_engr_at(x, y);
|
||||
pline("A pool of molten lava.");
|
||||
if (!(Levitation || Flying))
|
||||
@@ -3028,29 +3034,51 @@ int locked, trapped;
|
||||
al = A_NONE;
|
||||
else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
|
||||
al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
|
||||
lev->altarmask = Align2amask(al);
|
||||
lev->altarmask = Align2amask(al); /* overlays 'flags' */
|
||||
pline("%s altar.", An(align_str(al)));
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 5, "grave")
|
||||
|| !BSTRCMPI(bp, p - 9, "headstone")) {
|
||||
make_grave(x, y, (char *) 0);
|
||||
pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
|
||||
: "Can't place a grave here");
|
||||
madeterrain = TRUE;
|
||||
if (IS_GRAVE(lev->typ)) {
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
lev->disturbed = !strncmpi(bp, "disturbed ", 10);
|
||||
pline("A %sgrave.", lev->disturbed ? "disturbed " : "");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
pline("Can't place a grave here");
|
||||
badterrain = TRUE;
|
||||
}
|
||||
} else if (!BSTRCMPI(bp, p - 4, "tree")) {
|
||||
lev->typ = TREE;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A tree.");
|
||||
block_point(x, y);
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "bars")) {
|
||||
lev->typ = IRONBARS;
|
||||
lev->flags = 0;
|
||||
/* [FIXME: if this isn't a wall or door location where 'horizontal'
|
||||
is already set up, that should be calculated for this spot.
|
||||
Unforutnately, it can be tricky; placing one in open space
|
||||
and then another adjacent might need to recalculate first one.] */
|
||||
pline("Iron bars.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 5, "cloud")) {
|
||||
lev->typ = CLOUD;
|
||||
lev->flags = 0;
|
||||
pline("A cloud.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 11, "secret door")) {
|
||||
if (lev->typ == DOOR
|
||||
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)) {
|
||||
/* require door or wall so that the 'horizontal' flag will
|
||||
already have the correct value (it will matter once the
|
||||
secret door is discovered and becomes a regular door);
|
||||
player might choose to put SDOOR on top of existing SDOOR
|
||||
to control its trapped state; iron bars are surrogate walls */
|
||||
if (lev->typ == DOOR || lev->typ == SDOOR
|
||||
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)
|
||||
|| lev->typ == IRONBARS) {
|
||||
lev->typ = SDOOR;
|
||||
lev->wall_info = 0;
|
||||
lev->wall_info = 0; /* overlays 'flags' */
|
||||
/* lev->horizontal stays as-is */
|
||||
/* no special handling for rogue level is necessary;
|
||||
exposing a secret door there yields a doorless doorway */
|
||||
@@ -3068,7 +3096,6 @@ int locked, trapped;
|
||||
#endif
|
||||
if (trapped)
|
||||
lev->doormask |= D_TRAPPED;
|
||||
block_point(x, y);
|
||||
pline("Secret door.");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
@@ -3078,7 +3105,7 @@ int locked, trapped;
|
||||
} else if (!BSTRCMPI(bp, p - 15, "secret corridor")) {
|
||||
if (lev->typ == CORR) {
|
||||
lev->typ = SCORR;
|
||||
block_point(x, y);
|
||||
/* neither CORR nor SCORR uses 'flags' or 'horizontal' */
|
||||
pline("Secret corridor.");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
@@ -3094,11 +3121,41 @@ int locked, trapped;
|
||||
if (u.uinwater && !is_pool(u.ux, u.uy)) {
|
||||
u.uinwater = 0; /* leave the water */
|
||||
docrt();
|
||||
g.vision_full_recalc = 1;
|
||||
} else if (u.utrap && u.utraptype == TT_LAVA
|
||||
&& !is_lava(u.ux, u.uy)) {
|
||||
reset_utrap(FALSE);
|
||||
/* [block/unblock_point was handled by docrt -> vision_recalc] */
|
||||
} else {
|
||||
if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
|
||||
reset_utrap(FALSE);
|
||||
|
||||
if (does_block(x, y, lev)) {
|
||||
if (!didblock)
|
||||
block_point(x, y);
|
||||
} else {
|
||||
if (didblock)
|
||||
unblock_point(x, y);
|
||||
}
|
||||
}
|
||||
/* fixups for replaced terrain that aren't handled above;
|
||||
for fountain placed on fountain or sink placed on sink, the
|
||||
increment above gets canceled out by the decrement here;
|
||||
otherwise if fountain or sink was replaced, there's one less */
|
||||
if (IS_FOUNTAIN(oldtyp))
|
||||
g.level.flags.nfountains--;
|
||||
else if (IS_SINK(oldtyp))
|
||||
g.level.flags.nsinks--;
|
||||
/* horizontal is overlaid by fountain->blessedftn, grave->disturbed */
|
||||
if (IS_FOUNTAIN(oldtyp) || IS_GRAVE(oldtyp)
|
||||
|| IS_WALL(oldtyp) || oldtyp == IRONBARS
|
||||
|| IS_DOOR(oldtyp) || oldtyp == SDOOR) {
|
||||
/* when new terrain is a fountain, 'blessedftn' was explicitly
|
||||
set above; likewise for grave and 'disturbed'; when it's a
|
||||
secret door, the old type was a wall or a door and we retain
|
||||
the 'horizontal' value from those */
|
||||
if (!IS_FOUNTAIN(lev->typ) && !IS_GRAVE(lev->typ)
|
||||
&& lev->typ != SDOOR)
|
||||
lev->horizontal = 0; /* also clears blessedftn, disturbed */
|
||||
}
|
||||
/* note: lev->lit and lev->nondiggable retain their values even
|
||||
though those might not make sense with the new terrain */
|
||||
}
|
||||
if (madeterrain || badterrain) {
|
||||
/* cast 'const' away; caller won't modify this */
|
||||
|
||||
@@ -3368,8 +3368,31 @@ boolean tinitial, tfrom_file;
|
||||
return retval;
|
||||
}
|
||||
#endif /* VIDEOSHADES */
|
||||
|
||||
#ifdef MSDOS
|
||||
fullname = "video_width";
|
||||
if (match_optname(opts, fullname, 7, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
op = string_for_opt(opts, negated);
|
||||
iflags.wc_video_width = strtol(op, NULL, 10);
|
||||
return FALSE;
|
||||
}
|
||||
fullname = "video_height";
|
||||
if (match_optname(opts, fullname, 7, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
op = string_for_opt(opts, negated);
|
||||
iflags.wc_video_height = strtol(op, NULL, 10);
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef NO_TERMS
|
||||
/* video:string -- must be after longer tests */
|
||||
fullname = "video";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1574646949 2019/11/25 01:55:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1580036285 2020/01/26 10:58:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.148 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1571,10 +1571,13 @@ struct mkroom *croom;
|
||||
|
||||
/*
|
||||
* If this is a specific item of the right type and it is being
|
||||
* created on the right level, flag it as the designated item
|
||||
* created on the right level, record its obj->o_id to be able
|
||||
* to recognize it as the designated item
|
||||
* used to detect a special achievement (to whit, reaching and
|
||||
* exploring the target level, although the exploration part
|
||||
* might be short-circuited if a monster brings object to hero).
|
||||
* Achievement is accomplished and the recorded o_id is cleared
|
||||
* if/when it gets added into hero's inventory.
|
||||
*
|
||||
* Random items of the appropriate type won't trigger a false
|
||||
* match--they'll fail the (id != -1) test above--but the level
|
||||
|
||||
@@ -876,7 +876,6 @@ const char *status_fieldnm[MAXBLSTATS];
|
||||
const char *status_fieldfmt[MAXBLSTATS];
|
||||
char *status_vals[MAXBLSTATS];
|
||||
boolean status_activefields[MAXBLSTATS];
|
||||
NEARDATA winid WIN_STATUS;
|
||||
|
||||
void
|
||||
genl_status_init()
|
||||
|
||||
84
src/worm.c
84
src/worm.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1579990313 2020/01/25 22:11:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1580043421 2020/01/26 12:57:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -218,26 +218,65 @@ struct monst *worm;
|
||||
seg->nseg = new_seg; /* attach it to the end of the list */
|
||||
wheads[wnum] = new_seg; /* move the end pointer */
|
||||
|
||||
/*
|
||||
* [maybe] FIXME?
|
||||
* scheduling wgrowtime[] seems to be based on normal movement
|
||||
* speed (12) but long worms move at 1/4 of that (3), so they'll
|
||||
* reach the scheduled 'moves' more quickly (in terms of their
|
||||
* actual movement) and grow faster than was probably intended.
|
||||
*/
|
||||
if (wgrowtime[wnum] <= g.moves) {
|
||||
if (!wgrowtime[wnum])
|
||||
int whplimit, whpcap, wsegs = count_wsegs(worm);
|
||||
|
||||
/* first set up for the next time to grow */
|
||||
if (!wgrowtime[wnum]) {
|
||||
/* new worm; usually grow a tail segment on its next turn */
|
||||
wgrowtime[wnum] = g.moves + rnd(5);
|
||||
else
|
||||
wgrowtime[wnum] += rn1(15, 3);
|
||||
worm->mhp += 3;
|
||||
if (worm->mhp > MHPMAX)
|
||||
worm->mhp = MHPMAX;
|
||||
if (worm->mhp > worm->mhpmax)
|
||||
worm->mhpmax = worm->mhp;
|
||||
} else
|
||||
/* The worm doesn't grow, so the last segment goes away. */
|
||||
} else {
|
||||
int mmove = mcalcmove(worm, FALSE),
|
||||
/* prior to 3.7.0, next-grow increment was 3..17 but since
|
||||
it got checked every 4th turn when the speed 3 worm got
|
||||
to move, it was effectively 0..5; also, its usage was
|
||||
'wgrowtime += incr', so often 'wgrowtime' would be
|
||||
exceeded by 'moves' on consecutive turns for the worm,
|
||||
resulting in an excessively rapid growth cycle */
|
||||
incr = rn1(10, 2); /* 2..12; after adjusting for long worn
|
||||
* speed of 3, effective value is 8..48 */
|
||||
|
||||
incr = (incr * NORMAL_SPEED) / max(mmove, 1);
|
||||
wgrowtime[wnum] = g.moves + incr;
|
||||
}
|
||||
|
||||
/* increase HP based on number of segments; if it has shrunk, it
|
||||
won't gain new HP until regaining previous peak segment count;
|
||||
when wounded (whether from damage or from shrinking), the HP
|
||||
which might have been 'new' will heal */
|
||||
whplimit = !worm->m_lev ? 4 : (8 * (int) worm->m_lev);
|
||||
/* note: wsegs includes the hidden segment co-located with the head */
|
||||
if (wsegs > 33)
|
||||
whplimit += 2 * (wsegs - 33), wsegs = 33;
|
||||
if (wsegs > 22)
|
||||
whplimit += 4 * (wsegs - 22), wsegs = 22;
|
||||
if (wsegs > 11)
|
||||
whplimit += 6 * (wsegs - 11), wsegs = 11;
|
||||
whplimit += 8 * wsegs;
|
||||
if (whplimit > MHPMAX)
|
||||
whplimit = MHPMAX;
|
||||
|
||||
worm->mhp += d(2, 2); /* 2..4, average 3 */
|
||||
whpcap = max(whplimit, worm->mhpmax);
|
||||
if (worm->mhp < whpcap) {
|
||||
/* can't exceed segment-derived limit unless level increase after
|
||||
peak tail growth has already done so; when that isn't the case,
|
||||
if segment growth exceeds current max HP then increase it */
|
||||
if (worm->mhp > whpcap)
|
||||
worm->mhp = whpcap;
|
||||
if (worm->mhp > worm->mhpmax)
|
||||
worm->mhpmax = worm->mhp;
|
||||
} else {
|
||||
if (worm->mhp > worm->mhpmax)
|
||||
worm->mhp = worm->mhpmax;
|
||||
}
|
||||
} else {
|
||||
/* The worm doesn't grow, so the last segment goes away.
|
||||
(Done after inserting an extra segment at the head, so it
|
||||
isn't getting smaller here, just changing location without
|
||||
having to move any of the intermediate segments.) */
|
||||
shrink_worm(wnum);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -253,10 +292,11 @@ struct monst *worm;
|
||||
{
|
||||
shrink_worm((int) worm->wormno); /* shrink */
|
||||
|
||||
if (worm->mhp > 3)
|
||||
worm->mhp -= 3; /* mhpmax not changed ! */
|
||||
else
|
||||
worm->mhp = 1;
|
||||
if (worm->mhp > count_wsegs(worm)) {
|
||||
worm->mhp -= d(2, 2); /* 2..4, average 3; note: mhpmax not changed! */
|
||||
if (worm->mhp < 1)
|
||||
worm->mhp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -64,6 +64,11 @@ tgetch()
|
||||
{
|
||||
char ch;
|
||||
|
||||
#ifdef SCREEN_VESA
|
||||
if (iflags.usevesa) {
|
||||
vesa_flush_text();
|
||||
}
|
||||
#endif /*SCREEN_VESA*/
|
||||
/* BIOSgetch can use the numeric key pad on IBM compatibles. */
|
||||
#ifdef SIMULATE_CURSOR
|
||||
if (iflags.grmode && cursor_flag)
|
||||
|
||||
@@ -181,6 +181,10 @@ struct overview_planar_cell_struct {
|
||||
#define ATTRIB_VGA_INTENSE 14 /* Intense White 94/06/07 palette chg*/
|
||||
#endif /*SCREEN_VGA || SCREEN_8514*/
|
||||
|
||||
#if defined(SCREEN_VESA)
|
||||
#define BACKGROUND_VESA_COLOR 240
|
||||
#endif /*SCREEN_VESA*/
|
||||
|
||||
#if defined(PC9800)
|
||||
static unsigned char attr98[CLR_MAX] = {
|
||||
0xe1, /* 0 white */
|
||||
@@ -249,6 +253,7 @@ E void FDECL(txt_xputc, (CHAR_P, int));
|
||||
|
||||
/* ### vidvga.c ### */
|
||||
|
||||
enum vga_pan_direction { pan_left, pan_up, pan_right, pan_down };
|
||||
#ifdef SCREEN_VGA
|
||||
E void NDECL(vga_backsp);
|
||||
E void FDECL(vga_clear_screen, (int));
|
||||
@@ -274,7 +279,7 @@ E void FDECL(vga_tty_startup, (int *, int *));
|
||||
E void FDECL(vga_xputs, (const char *, int, int));
|
||||
E void FDECL(vga_xputc, (CHAR_P, int));
|
||||
E void FDECL(vga_xputg, (int, int, unsigned));
|
||||
E void FDECL(vga_userpan, (BOOLEAN_P));
|
||||
E void FDECL(vga_userpan, (enum vga_pan_direction));
|
||||
E void FDECL(vga_overview, (BOOLEAN_P));
|
||||
E void FDECL(vga_traditional, (BOOLEAN_P));
|
||||
E void NDECL(vga_refresh);
|
||||
@@ -303,10 +308,11 @@ E void FDECL(vesa_tty_startup, (int *, int *));
|
||||
E void FDECL(vesa_xputs, (const char *, int, int));
|
||||
E void FDECL(vesa_xputc, (CHAR_P, int));
|
||||
E void FDECL(vesa_xputg, (int, int, unsigned));
|
||||
E void FDECL(vesa_userpan, (BOOLEAN_P));
|
||||
E void FDECL(vesa_userpan, (enum vga_pan_direction));
|
||||
E void FDECL(vesa_overview, (BOOLEAN_P));
|
||||
E void FDECL(vesa_traditional, (BOOLEAN_P));
|
||||
E void NDECL(vesa_refresh);
|
||||
E void NDECL(vesa_flush_text);
|
||||
#endif /* SCREEN_VESA */
|
||||
#endif /* NO_TERMS */
|
||||
|
||||
|
||||
1480
sys/msdos/vidvesa.c
1480
sys/msdos/vidvesa.c
File diff suppressed because it is too large
Load Diff
@@ -502,18 +502,20 @@ boolean clearfirst;
|
||||
#endif /* USE_TILES && CLIPPING */
|
||||
|
||||
void
|
||||
vga_userpan(left)
|
||||
boolean left;
|
||||
vga_userpan(pan)
|
||||
enum vga_pan_direction pan;
|
||||
{
|
||||
int x;
|
||||
|
||||
/* pline("Into userpan"); */
|
||||
if (iflags.over_view || iflags.traditional_view)
|
||||
return;
|
||||
if (left)
|
||||
if (pan == pan_left)
|
||||
x = min(COLNO - 1, clipxmax + 10);
|
||||
else
|
||||
else if (pan == pan_right)
|
||||
x = max(0, clipx - 10);
|
||||
else
|
||||
return;
|
||||
vga_cliparound(x, 10); /* y value is irrelevant on VGA clipping */
|
||||
positionbar();
|
||||
vga_DrawCursor();
|
||||
|
||||
@@ -27,6 +27,10 @@ OPTIONS=rawio,BIOS,symset:IBMGraphics_2,roguesymset:RogueEpyx
|
||||
# To use VGA graphical tiles on an MS-DOS PC with VGA or better,uncomment
|
||||
# this:
|
||||
#OPTIONS=video:autodetect
|
||||
# And to explicitly set the resolution:
|
||||
#OPTIONS=video_width:1024
|
||||
#OPTIONS=video_height:768
|
||||
|
||||
|
||||
# If your machine is NEC PC-9800, use:
|
||||
#OPTIONS=rawio,BIOS,video:default
|
||||
|
||||
@@ -95,9 +95,6 @@ static XtSignalId X11_sig_id;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* this is only needed until X11_status_* routines are written */
|
||||
extern NEARDATA winid WIN_STATUS;
|
||||
|
||||
/* Interface definition, for windows.c */
|
||||
struct window_procs X11_procs = {
|
||||
"X11",
|
||||
|
||||
@@ -19,9 +19,6 @@ winid WIN_WORN = WIN_ERR;
|
||||
extern void tty_raw_print(const char *);
|
||||
extern void tty_raw_print_bold(const char *);
|
||||
|
||||
/* this is only needed until gnome_status_* routines are written */
|
||||
extern NEARDATA winid WIN_STATUS;
|
||||
|
||||
/* Interface definition, for windows.c */
|
||||
struct window_procs Gnome_procs = {
|
||||
"Gnome", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L,
|
||||
|
||||
@@ -107,15 +107,6 @@ struct TileSetImage *image;
|
||||
if (!read_info_header(fp, &header2)) goto error;
|
||||
if (!check_info_header(&header2)) goto error;
|
||||
|
||||
#if 0 /* TODO */
|
||||
if (header2.Compression == BI_PNG) {
|
||||
/* Image data is an embedded PNG bit stream */
|
||||
boolean ok = do_read_png_tiles(fp, image));
|
||||
fclose(fp);
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* header2.Height < 0 means the Y coordinate is reversed; the origin is
|
||||
* top left rather than bottom left */
|
||||
image->width = header2.Width;
|
||||
@@ -300,7 +291,7 @@ struct TileSetImage *image;
|
||||
break;
|
||||
case 32:
|
||||
for (x = 0; x < image->width; ++x) {
|
||||
uint32 color = read_u32(row_bytes + x * 2);
|
||||
uint32 color = read_u32(row_bytes + x * 4);
|
||||
row[x] = build_pixel(&header2, color);
|
||||
}
|
||||
break;
|
||||
@@ -609,7 +600,7 @@ uint32 color;
|
||||
if (mask == 0) return 0;
|
||||
bits = 0xFFFF; /* 0xFF, 0xF, 0x3, 0x1 */
|
||||
shift = 16; /* 8, 4, 2, 1 */
|
||||
while (bits != 0) {
|
||||
while (shift != 0) {
|
||||
if ((mask & bits) == 0) {
|
||||
mask >>= shift;
|
||||
color >>= shift;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "tileset.h"
|
||||
|
||||
static void FDECL(get_tile_map, (const char *));
|
||||
static unsigned FDECL(gcd, (unsigned, unsigned));
|
||||
static void FDECL(split_tiles, (const struct TileSetImage *));
|
||||
static void FDECL(free_image, (struct TileSetImage *));
|
||||
|
||||
@@ -100,6 +101,29 @@ error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Free tile memory not required by the chosen display mode */
|
||||
boolean
|
||||
set_tile_type(true_color)
|
||||
boolean true_color;
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (tiles) {
|
||||
if (true_color) {
|
||||
for (i = 0; i < num_tiles; ++i) {
|
||||
free((genericptr_t) tiles[i].indexes);
|
||||
tiles[i].indexes = NULL;
|
||||
}
|
||||
have_palette = FALSE;
|
||||
} else {
|
||||
for (i = 0; i < num_tiles; ++i) {
|
||||
free((genericptr_t) tiles[i].pixels);
|
||||
tiles[i].pixels = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const struct Pixel *
|
||||
get_palette()
|
||||
{
|
||||
@@ -155,6 +179,112 @@ unsigned tile_index;
|
||||
return &tiles[tile_index];
|
||||
}
|
||||
|
||||
/* Note that any tile returned by this function must be freed */
|
||||
struct TileImage *
|
||||
stretch_tile(inp_tile, out_width, out_height)
|
||||
const struct TileImage *inp_tile;
|
||||
unsigned out_width, out_height;
|
||||
{
|
||||
unsigned x_scale_inp, x_scale_out, y_scale_inp, y_scale_out;
|
||||
unsigned divisor;
|
||||
unsigned size;
|
||||
struct TileImage *out_tile;
|
||||
unsigned x_inp, y_inp, x2, y2, x_out, y_out;
|
||||
unsigned pos;
|
||||
|
||||
/* Derive the scale factors */
|
||||
divisor = gcd(out_width, inp_tile->width);
|
||||
x_scale_inp = inp_tile->width / divisor;
|
||||
x_scale_out = out_width / divisor;
|
||||
divisor = gcd(out_height, inp_tile->height);
|
||||
y_scale_inp = inp_tile->height / divisor;
|
||||
y_scale_out = out_height / divisor;
|
||||
|
||||
/* Derive the stretched tile */
|
||||
out_tile = (struct TileImage *) alloc(sizeof(struct TileImage));
|
||||
out_tile->width = out_width;
|
||||
out_tile->height = out_height;
|
||||
size = out_width * out_height;
|
||||
if (inp_tile->pixels != NULL) {
|
||||
out_tile->pixels = (struct Pixel *) alloc(size * sizeof(struct Pixel));
|
||||
divisor = x_scale_inp * y_scale_inp;
|
||||
for (y_out = 0; y_out < out_height; ++y_out) {
|
||||
for (x_out = 0; x_out < out_width; ++x_out) {
|
||||
unsigned r, g, b, a;
|
||||
|
||||
/* Derive output pixels by blending input pixels */
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
for (y2 = 0; y2 < y_scale_inp; ++y2) {
|
||||
y_inp = (y_out * y_scale_inp + y2) / y_scale_out;
|
||||
for (x2 = 0; x2 < x_scale_inp; ++x2) {
|
||||
x_inp = (x_out * x_scale_inp + x2) / x_scale_out;
|
||||
pos = y_inp * inp_tile->width + x_inp;
|
||||
r += inp_tile->pixels[pos].r;
|
||||
g += inp_tile->pixels[pos].g;
|
||||
b += inp_tile->pixels[pos].b;
|
||||
a += inp_tile->pixels[pos].a;
|
||||
}
|
||||
}
|
||||
|
||||
pos = y_out * out_width + x_out;
|
||||
out_tile->pixels[pos].r = r / divisor;
|
||||
out_tile->pixels[pos].g = g / divisor;
|
||||
out_tile->pixels[pos].b = b / divisor;
|
||||
out_tile->pixels[pos].a = a / divisor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_tile->pixels = NULL;
|
||||
}
|
||||
|
||||
/* If the output device uses a palette, we can't blend; just pick
|
||||
a subset of the pixels */
|
||||
if (inp_tile->indexes != NULL) {
|
||||
out_tile->indexes = (unsigned char *) alloc(size);
|
||||
for (y_out = 0; y_out < out_height; ++y_out) {
|
||||
for (x_out = 0; x_out < out_width; ++x_out) {
|
||||
pos = y_out * out_width + x_out;
|
||||
x_inp = x_out * x_scale_inp / x_scale_out;
|
||||
y_inp = y_out * y_scale_inp / y_scale_out;
|
||||
out_tile->indexes[pos] =
|
||||
inp_tile->indexes[y_inp * inp_tile->width + x_inp];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_tile->indexes = NULL;
|
||||
}
|
||||
return out_tile;
|
||||
}
|
||||
|
||||
/* Free a tile returned by stretch_tile */
|
||||
/* Do NOT use this with tiles returned by get_tile */
|
||||
void
|
||||
free_tile(tile)
|
||||
struct TileImage *tile;
|
||||
{
|
||||
if (tile != NULL) {
|
||||
free(tile->indexes);
|
||||
free(tile->pixels);
|
||||
free(tile);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the greatest common divisor */
|
||||
static unsigned
|
||||
gcd(a, b)
|
||||
unsigned a, b;
|
||||
{
|
||||
while (TRUE) {
|
||||
if (b == 0) return a;
|
||||
a %= b;
|
||||
if (a == 0) return b;
|
||||
b %= a;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
split_tiles(image)
|
||||
const struct TileSetImage *image;
|
||||
|
||||
@@ -72,9 +72,6 @@ extern short glyph2tile[];
|
||||
#define HUPSKIP_RESULT(RES) /*empty*/
|
||||
#endif /* ?HANGUP_HANDLING */
|
||||
|
||||
/* this is only needed until tty_status_* routines are written */
|
||||
extern NEARDATA winid WIN_STATUS;
|
||||
|
||||
/* Interface definition, for windows.c */
|
||||
struct window_procs tty_procs = {
|
||||
"tty",
|
||||
@@ -155,11 +152,12 @@ char defmorestr[] = "--More--";
|
||||
#if defined(USE_TILES) && defined(MSDOS)
|
||||
boolean clipping = FALSE; /* clipping on? */
|
||||
int clipx = 0, clipxmax = 0;
|
||||
int clipy = 0, clipymax = 0;
|
||||
#else
|
||||
static boolean clipping = FALSE; /* clipping on? */
|
||||
static int clipx = 0, clipxmax = 0;
|
||||
#endif
|
||||
static int clipy = 0, clipymax = 0;
|
||||
#endif
|
||||
#endif /* CLIPPING */
|
||||
|
||||
#if defined(USE_TILES) && defined(MSDOS)
|
||||
|
||||
Reference in New Issue
Block a user