Merge branch 'NetHack-5.0' of https://rodney.nethack.org:20040/git/NHsource into NetHack-5.0

This commit is contained in:
nhkeni
2026-06-19 20:59:55 -04:00
16 changed files with 96 additions and 60 deletions
+2
View File
@@ -61,6 +61,8 @@ fix a bug in which steeds would continuously gain movement points while
being ridden
when hero's behavior makes erinyes stronger, cap level at 49 rather than 50
with inventory item action for leash, distingluish leash-in-use from empty one
deafness check was missing from a shopkeeper message in ready_weapon()
thrown ball travel did not check for regions (pr #1595 by copperwater)
Platform- and/or Interface-Specific Fixes
+1
View File
@@ -2996,6 +2996,7 @@ extern void credit_report(struct monst *shkp, int idx,
boolean silent) NONNULLARG1;
extern void use_unpaid_trapobj(struct obj *, coordxy, coordxy) NONNULLARG1;
extern void noisy_shop(struct mkroom *);
extern const char *says(void);
/* ### shknam.c ### */
-9
View File
@@ -128,14 +128,6 @@ extern void curses_refresh_nethack_windows(void);
extern void curses_del_nhwin(winid wid);
extern void curses_del_wid(winid wid);
extern void curs_destroy_all_wins(void);
#ifdef ENHANCED_SYMBOLS
extern void curses_putch(winid wid, int x, int y, int ch,
struct unicode_representation *u, int color,
int framecolor, int attrs);
#else
extern void curses_putch(winid wid, int x, int y, int ch, int color,
int framecolor, int attrs);
#endif
extern void curses_get_window_size(winid wid, int *height, int *width);
extern boolean curses_window_has_border(winid wid);
extern boolean curses_window_exists(winid wid);
@@ -145,7 +137,6 @@ extern void curses_puts(winid wid, int attr, const char *text);
extern void curses_clear_nhwin(winid wid);
extern void curses_alert_win_border(winid wid, boolean onoff);
extern void curses_alert_main_borders(boolean onoff);
extern int get_framecolor(int nhcolor, int framecolor);
extern void curses_draw_map(int sx, int sy, int ex, int ey);
extern boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey,
int ux, int uy);
+8 -3
View File
@@ -808,7 +808,8 @@ drag_ball(coordxy x, coordxy y, int *bc_control,
miss(xname(uball), victim);
} /* now check again in case mon died */
if (!m_at(uchain->ox, uchain->oy)) {
if (!m_at(uchain->ox, uchain->oy)
&& in_out_region(uchain->ox, uchain->oy)) {
u.ux = uchain->ox;
u.uy = uchain->oy;
newsym(u.ux0, u.uy0);
@@ -820,6 +821,9 @@ drag_ball(coordxy x, coordxy y, int *bc_control,
*ballx = uchain->ox;
*bally = uchain->oy;
move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy);
/* weirdness: you were dragged back on account of the ball falling
* into the pit, but if you escape the pit, the ball is "on top of"
* the pit and does not hinder your movement further */
spoteffects(TRUE);
return FALSE;
}
@@ -932,10 +936,11 @@ drop_ball(coordxy x, coordxy y)
&& (is_pool(x, y)
|| ((t = t_at(x, y))
&& (is_pit(t->ttyp)
|| is_hole(t->ttyp))))) {
|| is_hole(t->ttyp))))
&& in_out_region(x, y)) {
u.ux = x;
u.uy = y;
} else {
} else if (in_out_region(x - u.dx, y - u.dy)) {
u.ux = x - u.dx;
u.uy = y - u.dy;
}
+2 -1
View File
@@ -886,7 +886,8 @@ static struct {
int index;
uint32 value;
} color_256_definitions[] = {
/* color values are from unnethack */
/* from unnethack - these are the colors used by xterm
when $TERM is set to xterm-256color */
{ 16, 0x000000 }, { 17, 0x00005f }, { 18, 0x000087 },
{ 19, 0x0000af }, { 20, 0x0000d7 }, { 21, 0x0000ff },
{ 22, 0x005f00 }, { 23, 0x005f5f }, { 24, 0x005f87 },
+2 -1
View File
@@ -299,7 +299,8 @@ demon_talk(struct monst *mtmp)
pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
flags.female ? "Sister" : "Brother");
else if (canseemon(mtmp))
pline("%s says something.", Amonnam(mtmp));
pline("%s %s something.", Amonnam(mtmp),
says());
if (!tele_restrict(mtmp))
(void) rloc(mtmp, RLOC_MSG);
return 1;
+3 -2
View File
@@ -554,10 +554,11 @@ outrumor(
switch (mechanism) {
case BY_ORACLE:
/* Oracle delivers the rumor */
pline("True to her word, the Oracle %ssays: ",
pline("True to her word, the Oracle %s%s: ",
(!rn2(4) ? "offhandedly "
: (!rn2(3) ? "casually "
: (rn2(2) ? "nonchalantly " : ""))));
: (rn2(2) ? "nonchalantly " : ""))),
says());
SetVoice((struct monst *) 0, 0, 80, voice_oracle);
verbalize1(line);
/* [WIS exercised by getrumor()] */
+6
View File
@@ -2049,6 +2049,12 @@ dopay(void)
return paid ? ECMD_TIME : ECMD_OK;
}
const char *
says(void)
{
return Deaf ? "signs" : "says";
}
/* for menustyle=Traditional, choose between paying for everything (by
declining to itemize), asking item-by-item (by accepting itemization),
or switch to selecting via menu (special 'm' answer at "Itemize? [ynq m]"
+7 -2
View File
@@ -262,8 +262,13 @@ ready_weapon(struct obj *wep)
if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy)))
!= (struct monst *) 0) {
pline("%s says \"You be careful with my %s!\"",
shkname(this_shkp), xname(wep));
/* check msound because we don't have access to muteshk() */
if (!Deaf && this_shkp->data->msound > MS_ANIMAL)
pline("%s %s \"You be careful with my %s!\"",
shkname(this_shkp), says(), xname(wep));
else
pline("%s looks apprehensive about your wielding %s %s.",
shkname(this_shkp), mhis(this_shkp), xname(wep));
}
}
}
+3 -3
View File
@@ -8,8 +8,8 @@
# MS Visual Studio Visual C++ compiler
#
# Visual Studio Compilers Tested:
# - Microsoft Visual Studio Community 2022 v 17.14.33
# - Microsoft Visual Studio Community 2026 v 18.7.0
# - Microsoft Visual Studio Community 2022 v 17.14.35
# - Microsoft Visual Studio Community 2026 v 18.7.1
#
#==============================================================================
# This is used for building two distinct executables of NetHack:
@@ -1204,7 +1204,7 @@ rc=Rc.exe
#
# Recently tested versions:
TESTEDVS2022 = 14.44.35225.0
TESTEDVS2026 = 14.51.36247.0
TESTEDVS2026 = 14.51.36248.0
VS20261ST = 1450000000
VS2026CUR = $(TESTEDVS2026:.=)
+7 -5
View File
@@ -7,6 +7,7 @@
#include "hack.h"
#include "wincurs.h"
#include "cursinit.h"
#include "cursmisc.h"
/* Initialization and startup functions for curses interface */
@@ -334,18 +335,18 @@ curses_init_nhcolors(void)
/* COLOR_foo + 8 means COLOR | A_BOLD when COLORS < 16 */
/* otherwise assume the terminal has least 16 different colors */
/* these map to the NetHack CLR_ defines */
static const int fg_clr[16] = {
static const int basic_fg_clr[16] = {
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE,
-1, COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8,
COLOR_BLUE + 8, COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8
};
static const int bg_clr[8] = {
static const int bg_clr[CURSES_NUM_BACKGROUND_COLORS] = {
-1, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
};
int bg, nhclr;
int maxc = (COLORS >= 16) ? 16 : 8;
int maxc = curses_has_256color() ? 256 : (COLORS >= 16) ? 16 : 8;
if (!has_colors())
return;
@@ -353,8 +354,9 @@ curses_init_nhcolors(void)
use_default_colors();
for (nhclr = CLR_BLACK; nhclr < maxc; nhclr++) {
for (bg = 0; bg < 8; bg++) {
init_pair((maxc * bg) + nhclr + 1, fg_clr[nhclr], bg_clr[bg]);
for (bg = 0; bg < CURSES_NUM_BACKGROUND_COLORS; bg++) {
int fg_color = (nhclr < 16) ? basic_fg_clr[nhclr] : nhclr;
init_pair((maxc * bg) + nhclr + 1, fg_color, bg_clr[bg]);
}
}
+15 -16
View File
@@ -7,6 +7,7 @@
#include "hack.h"
#include "color.h"
#include "wincurs.h"
#include "curswins.h"
#ifdef CURSES_UNICODE
#include <locale.h>
#endif
@@ -939,15 +940,16 @@ curses_print_glyph(
{
int glyph;
int ch;
int color;
int nhcolor = 0;
struct glyph_attributes attr;
unsigned int special;
int attr = -1;
attr.attribute_flags = -1;
glyph = glyphinfo->glyph;
special = glyphinfo->gm.glyphflags;
ch = glyphinfo->ttychar;
color = glyphinfo->gm.sym.color;
attr.basic_color = glyphinfo->gm.sym.color;
attr.color256 = 0;
attr.framecolor = bkglyphinfo->framecolor;
/* Extra color handling
* FIQ: The curses library does not support truecolor, only the more limited 256
* color mode. On top of this, the windowport only supports 16 color mode.
@@ -956,19 +958,17 @@ curses_print_glyph(
if (glyphinfo->gm.customcolor != 0
&& (curses_procs.wincap2 & WC2_EXTRACOLORS) != 0) {
if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) {
color = COLORVAL(glyphinfo->gm.customcolor);
#if 0
attr.basic_color = COLORVAL(glyphinfo->gm.customcolor);
} else {
/* 24-bit color, NH_BASIC_COLOR == 0 */
nhcolor = COLORVAL(glyphinfo->gm.customcolor);
#endif
attr.color256 = glyphinfo->gm.color256idx;
}
}
if ((special & MG_PET) && iflags.hilite_pet) {
attr = curses_convert_attr(iflags.wc2_petattr);
attr.attribute_flags = curses_convert_attr(iflags.wc2_petattr);
}
if ((special & MG_DETECT) && iflags.use_inverse) {
attr = A_REVERSE;
attr.attribute_flags = A_REVERSE;
}
if (SYMHANDLING(H_DEC))
ch = curses_convert_glyph(ch, glyph);
@@ -981,9 +981,9 @@ curses_print_glyph(
*/
if ((special & MG_OBJPILE) && iflags.hilite_pile) {
if (iflags.wc_color)
color = get_framecolor(color, CLR_BLUE);
attr.framecolor = CLR_BLUE;
else /* if (iflags.use_inverse) */
attr = A_REVERSE;
attr.attribute_flags = A_REVERSE;
}
/* water and lava look the same except for color; when color is off
(checked by core), render lava in inverse video so that it looks
@@ -992,11 +992,11 @@ curses_print_glyph(
if ((special & (MG_BW_LAVA | MG_BW_ICE | MG_BW_SINK | MG_BW_ENGR))
!= 0 && iflags.use_inverse) {
/* reset_glyphmap() only sets MG_BW_foo if color is off */
attr = A_REVERSE;
attr.attribute_flags = A_REVERSE;
}
/* highlight female monsters (wizard mode option) */
if ((special & MG_FEMALE) && wizard && iflags.wizmgender) {
attr = A_REVERSE;
attr.attribute_flags = A_REVERSE;
}
}
@@ -1006,8 +1006,7 @@ curses_print_glyph(
&& glyphinfo->gm.u && glyphinfo->gm.u->utf8str)
? glyphinfo->gm.u : NULL,
#endif
(nhcolor != 0) ? nhcolor : color,
bkglyphinfo->framecolor, attr);
&attr);
}
+7 -1
View File
@@ -91,6 +91,12 @@ curses_read_char(void)
return ch;
}
boolean
curses_has_256color(void)
{
return (COLORS >= 256) && (COLOR_PAIRS >= 256 * CURSES_NUM_BACKGROUND_COLORS);
}
/* Turn on or off the specified color and / or attribute */
void
@@ -147,7 +153,7 @@ curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff)
if (use_bold) {
wattron(win, A_BOLD);
}
wattron(win, COLOR_PAIR(curses_color));
wcolor_set(win, curses_color, &curses_color);
}
if (attr != NONE) {
+3
View File
@@ -8,8 +8,11 @@
/* Global declarations */
#define CURSES_NUM_BACKGROUND_COLORS 8
int curses_getch(void);
int curses_read_char(void);
boolean curses_has_256color(void);
void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff);
void curses_menu_color_attr(WINDOW *win, int color, int attr, int onoff);
void curses_bail(const char *mesg);
+20 -13
View File
@@ -40,7 +40,8 @@ typedef struct nhwd {
typedef struct nhchar {
int ch; /* character */
int color; /* color info for character */
int color; /* basic color info for character */
int color256; /* extended color for the character, 0 if none */
int framecolor; /* background color info for character */
int attr; /* attributes of character */
struct unicode_representation *unicode_representation;
@@ -532,7 +533,7 @@ curses_putch(winid wid, int x, int y, int ch,
#ifdef ENHANCED_SYMBOLS
struct unicode_representation *unicode_representation,
#endif
int color, int framecolor, int attr)
const struct glyph_attributes *attr)
{
static boolean map_initted = FALSE;
int sx, sy, ex, ey;
@@ -554,9 +555,10 @@ curses_putch(winid wid, int x, int y, int ch,
--x; /* map column [0] is not used; draw column [1] in first screen col */
map[y][x].ch = ch;
map[y][x].color = color;
map[y][x].framecolor = framecolor;
map[y][x].attr = attr;
map[y][x].color = attr->basic_color;
map[y][x].color256 = attr->color256;
map[y][x].framecolor = attr->framecolor;
map[y][x].attr = attr->attribute_flags;
#ifdef ENHANCED_SYMBOLS
map[y][x].unicode_representation = unicode_representation;
#endif
@@ -763,22 +765,27 @@ is_main_window(winid wid)
coordinates without a refresh. Currently only used for the map. */
/* convert nhcolor (fg) and framecolor (bg) to curses colorpair */
int
get_framecolor(int nhcolor, int framecolor)
static int
get_framecolor(const nethack_char *nch)
{
int bgcolor = (nch->framecolor != NO_COLOR) ? nch->framecolor : 0;
/* curses_toggle_color_attr() adds the +1 and takes care of COLORS < 16 */
return (16 * (framecolor % 8)) + (nhcolor % 16);
if (curses_has_256color()) {
int color = nch->color256 ? nch->color256 : nch->color;
return (256 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (color % 256);
} else
return (16 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (nch->color % 16);
}
static void
write_char(WINDOW * win, int x, int y, nethack_char nch)
{
int curscolor = nch.color, cursattr = nch.attr;
int curscolor;
int cursattr = nch.attr;
if (nch.framecolor != NO_COLOR) {
curscolor = get_framecolor(nch.color, nch.framecolor);
if (nch.attr == A_REVERSE)
cursattr = A_NORMAL; /* hilited pet looks odd otherwise */
curscolor = get_framecolor(&nch);
if ((nch.framecolor != NO_COLOR) && (nch.attr == A_REVERSE)) {
cursattr = A_NORMAL; /* hilited pet looks odd otherwise */
}
curses_toggle_color_attr(win, curscolor, cursattr, ON);
#if defined(CURSES_UNICODE) && defined(ENHANCED_SYMBOLS)
+10 -4
View File
@@ -6,6 +6,12 @@
#ifndef CURSWIN_H
# define CURSWIN_H
struct glyph_attributes {
int basic_color; // basic color
int color256; // extended color (0 if not defined), used when supported
int framecolor;
int attribute_flags;
};
/* Global declarations */
@@ -27,11 +33,11 @@ void curses_del_wid(winid wid);
void curs_destroy_all_wins(void);
#ifdef ENHANCED_SYMBOLS
void curses_putch(winid wid, int x, int y, int ch,
struct unicode_representation *ur, int color,
int framecolor, int attrs);
struct unicode_representation *ur,
const struct glyph_attributes *attr);
#else
void curses_putch(winid wid, int x, int y, int ch, int color,
int framecolor, int attrs);
void curses_putch(winid wid, int x, int y, int ch,
const struct glyph_attributes *attr);
#endif
void curses_get_window_xy(winid wid, int *x, int *y);
boolean curses_window_has_border(winid wid);