Skip to content

Commit 180371f

Browse files
committed
Underline peaceful monsters via config (tty and curses).
From xNetHack git commit 29b2c92 (modified): allow players to have peaceful monsters appear underlined. By default it's off, but can be enbled in-game through options, or by placing 'underline_peacefuls' in your rc config.
1 parent 06da26d commit 180371f

15 files changed

+109
-51
lines changed

doc/evilhack-changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -3390,4 +3390,5 @@ The following changes to date are:
33903390
- Fix: Lava gremlin exploding a forge
33913391
- Fix: ID_MANIFEST target (windows build)
33923392
- New conduct: never forged an artifact
3393+
- Underline peaceful monsters via config (tty and curses)
33933394

include/display.h

+37-29
Original file line numberDiff line numberDiff line change
@@ -294,20 +294,21 @@
294294
*/
295295
#define NUM_ZAP 11 /* number of zap beam types */
296296

297-
#define GLYPH_MON_OFF 0
298-
#define GLYPH_PET_OFF (NUMMONS + GLYPH_MON_OFF)
299-
#define GLYPH_INVIS_OFF (NUMMONS + GLYPH_PET_OFF)
300-
#define GLYPH_DETECT_OFF (1 + GLYPH_INVIS_OFF)
301-
#define GLYPH_BODY_OFF (NUMMONS + GLYPH_DETECT_OFF)
302-
#define GLYPH_RIDDEN_OFF (NUMMONS + GLYPH_BODY_OFF)
303-
#define GLYPH_OBJ_OFF (NUMMONS + GLYPH_RIDDEN_OFF)
304-
#define GLYPH_CMAP_OFF (NUM_OBJECTS + GLYPH_OBJ_OFF)
305-
#define GLYPH_EXPLODE_OFF ((MAXPCHARS - MAXEXPCHARS) + GLYPH_CMAP_OFF)
306-
#define GLYPH_ZAP_OFF ((MAXEXPCHARS * EXPL_MAX) + GLYPH_EXPLODE_OFF)
307-
#define GLYPH_SWALLOW_OFF ((NUM_ZAP << 2) + GLYPH_ZAP_OFF)
308-
#define GLYPH_WARNING_OFF ((NUMMONS << 3) + GLYPH_SWALLOW_OFF)
309-
#define GLYPH_STATUE_OFF (WARNCOUNT + GLYPH_WARNING_OFF)
310-
#define MAX_GLYPH (NUMMONS + GLYPH_STATUE_OFF)
297+
#define GLYPH_MON_OFF 0
298+
#define GLYPH_PET_OFF (NUMMONS + GLYPH_MON_OFF)
299+
#define GLYPH_PEACEFUL_OFF (NUMMONS + GLYPH_PET_OFF)
300+
#define GLYPH_INVIS_OFF (NUMMONS + GLYPH_PEACEFUL_OFF)
301+
#define GLYPH_DETECT_OFF (1 + GLYPH_INVIS_OFF)
302+
#define GLYPH_BODY_OFF (NUMMONS + GLYPH_DETECT_OFF)
303+
#define GLYPH_RIDDEN_OFF (NUMMONS + GLYPH_BODY_OFF)
304+
#define GLYPH_OBJ_OFF (NUMMONS + GLYPH_RIDDEN_OFF)
305+
#define GLYPH_CMAP_OFF (NUM_OBJECTS + GLYPH_OBJ_OFF)
306+
#define GLYPH_EXPLODE_OFF ((MAXPCHARS - MAXEXPCHARS) + GLYPH_CMAP_OFF)
307+
#define GLYPH_ZAP_OFF ((MAXEXPCHARS * EXPL_MAX) + GLYPH_EXPLODE_OFF)
308+
#define GLYPH_SWALLOW_OFF ((NUM_ZAP << 2) + GLYPH_ZAP_OFF)
309+
#define GLYPH_WARNING_OFF ((NUMMONS << 3) + GLYPH_SWALLOW_OFF)
310+
#define GLYPH_STATUE_OFF (WARNCOUNT + GLYPH_WARNING_OFF)
311+
#define MAX_GLYPH (NUMMONS + GLYPH_STATUE_OFF)
311312

312313
#define NO_GLYPH MAX_GLYPH
313314
#define GLYPH_INVISIBLE GLYPH_INVIS_OFF
@@ -323,6 +324,8 @@
323324
((int) what_mon(racial_mndx(mon), rng) + GLYPH_RIDDEN_OFF)
324325
#define pet_to_glyph(mon, rng) \
325326
((int) what_mon(racial_mndx(mon), rng) + GLYPH_PET_OFF)
327+
#define peaceful_to_glyph(mon, rng) \
328+
((int) what_mon(racial_mndx(mon), rng) + GLYPH_PEACEFUL_OFF)
326329

327330
/* This has the unfortunate side effect of needing a global variable */
328331
/* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */
@@ -348,7 +351,6 @@
348351
: has_omonst(obj) && use_racial_glyph(OMONST(obj)) \
349352
? (int) ERAC(OMONST(obj))->rmnum + GLYPH_STATUE_OFF \
350353
: (int) (obj)->corpsenm + GLYPH_STATUE_OFF)
351-
352354

353355
#define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF)
354356
#define explosion_to_glyph(expltype, idx) \
@@ -364,6 +366,7 @@
364366
#define detected_monnum_to_glyph(mnum) ((int) (mnum) + GLYPH_DETECT_OFF)
365367
#define ridden_monnum_to_glyph(mnum) ((int) (mnum) + GLYPH_RIDDEN_OFF)
366368
#define petnum_to_glyph(mnum) ((int) (mnum) + GLYPH_PET_OFF)
369+
#define peacefulnum_to_glyph(mnum) ((int) (mnum) + GLYPH_PEACEFUL_OFF)
367370

368371
/* The hero's glyph when seen as a monster.
369372
*/
@@ -387,17 +390,19 @@
387390
* to return).
388391
*/
389392
#define glyph_to_mon(glyph) \
390-
(glyph_is_normal_monster(glyph) \
391-
? ((glyph) - GLYPH_MON_OFF) \
392-
: glyph_is_pet(glyph) \
393-
? ((glyph) - GLYPH_PET_OFF) \
394-
: glyph_is_detected_monster(glyph) \
395-
? ((glyph) - GLYPH_DETECT_OFF) \
396-
: glyph_is_ridden_monster(glyph) \
397-
? ((glyph) - GLYPH_RIDDEN_OFF) \
398-
: glyph_is_statue(glyph) \
399-
? ((glyph) - GLYPH_STATUE_OFF) \
400-
: NO_GLYPH)
393+
(glyph_is_normal_monster(glyph) \
394+
? ((glyph) - GLYPH_MON_OFF) \
395+
: glyph_is_pet(glyph) \
396+
? ((glyph) - GLYPH_PET_OFF) \
397+
: glyph_is_peaceful(glyph) \
398+
? ((glyph) - GLYPH_PEACEFUL_OFF) \
399+
: glyph_is_detected_monster(glyph) \
400+
? ((glyph) - GLYPH_DETECT_OFF) \
401+
: glyph_is_ridden_monster(glyph) \
402+
? ((glyph) - GLYPH_RIDDEN_OFF) \
403+
: glyph_is_statue(glyph) \
404+
? ((glyph) - GLYPH_STATUE_OFF) \
405+
: NO_GLYPH)
401406
#define glyph_to_obj(glyph) \
402407
(glyph_is_body(glyph) \
403408
? CORPSE \
@@ -420,13 +425,16 @@
420425
* Return true if the given glyph is what we want. Note that bodies are
421426
* considered objects.
422427
*/
423-
#define glyph_is_monster(glyph) \
424-
(glyph_is_normal_monster(glyph) || glyph_is_pet(glyph) \
425-
|| glyph_is_ridden_monster(glyph) || glyph_is_detected_monster(glyph))
428+
#define glyph_is_monster(glyph) \
429+
(glyph_is_normal_monster(glyph) || glyph_is_pet(glyph) \
430+
|| glyph_is_peaceful(glyph) || glyph_is_ridden_monster(glyph) \
431+
|| glyph_is_detected_monster(glyph))
426432
#define glyph_is_normal_monster(glyph) \
427433
((glyph) >= GLYPH_MON_OFF && (glyph) < (GLYPH_MON_OFF + NUMMONS))
428434
#define glyph_is_pet(glyph) \
429435
((glyph) >= GLYPH_PET_OFF && (glyph) < (GLYPH_PET_OFF + NUMMONS))
436+
#define glyph_is_peaceful(glyph) \
437+
((glyph) >= GLYPH_PEACEFUL_OFF && (glyph) < (GLYPH_PEACEFUL_OFF + NUMMONS))
430438
#define glyph_is_body(glyph) \
431439
((glyph) >= GLYPH_BODY_OFF && (glyph) < (GLYPH_BODY_OFF + NUMMONS))
432440

include/flag.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,10 @@ struct instance_flags {
437437
boolean wc2_softkeyboard; /* use software keyboard */
438438
boolean wc2_wraptext; /* wrap text */
439439
boolean wc2_selectsaved; /* display a menu of user's saved games */
440-
boolean wc2_darkgray; /* try to use dark-gray color for black glyphs */
441-
boolean wc2_hitpointbar; /* show graphical bar representing hit points */
440+
boolean wc2_darkgray; /* try to use dark-gray color for black glyphs */
441+
boolean wc2_hitpointbar; /* show graphical bar representing hit points */
442442
boolean wc2_guicolor; /* allow colours in gui (outside map) */
443+
boolean wc2_underline_peacefuls; /* underline peaceful monsters */
443444
int wc_mouse_support; /* allow mouse support */
444445
int wc2_term_cols; /* terminal width, in characters */
445446
int wc2_term_rows; /* terminal height, in characters */
@@ -485,6 +486,7 @@ struct instance_flags {
485486
#endif
486487
#define use_color wc_color
487488
#define hilite_pet wc_hilite_pet
489+
#define underline_peacefuls wc2_underline_peacefuls
488490
#define use_inverse wc_inverse
489491
#ifdef MAC_GRAPHICS_ENV
490492
#define large_font obsolete

include/hack.h

+10-9
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,16 @@ enum dismount_types {
7676
#define MG_FLAG_NOOVERRIDE 0x01
7777

7878
/* Special returns from mapglyph() */
79-
#define MG_CORPSE 0x01
80-
#define MG_INVIS 0x02
81-
#define MG_DETECT 0x04
82-
#define MG_PET 0x08
83-
#define MG_RIDDEN 0x10
84-
#define MG_STATUE 0x20
85-
#define MG_OBJPILE 0x40 /* more than one stack of objects */
86-
#define MG_BW_LAVA 0x80 /* 'black & white lava': highlight lava if it
87-
can't be distringuished from water by color */
79+
#define MG_CORPSE 0x00001
80+
#define MG_INVIS 0x00002
81+
#define MG_DETECT 0x00004
82+
#define MG_PET 0x00008
83+
#define MG_RIDDEN 0x00010
84+
#define MG_STATUE 0x00020
85+
#define MG_OBJPILE 0x00040 /* more than one stack of objects */
86+
#define MG_BW_LAVA 0x00080 /* 'black & white lava': highlight lava if it
87+
can't be distringuished from water by color */
88+
#define MG_PEACEFUL 0x00100 /* peaceful monster */
8889

8990
/* sellobj_state() states */
9091
#define SELL_NORMAL (0)

include/winprocs.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ extern
217217
#define WC2_DARKGRAY 0x00020L /* 06 use bold black for black glyphs */
218218
#define WC2_HITPOINTBAR 0x00040L /* 07 show bar representing hit points */
219219
#define WC2_FLUSH_STATUS 0x00080L /* 08 call status_update(BL_FLUSH)
220-
* after updating status window fields */
220+
* after updating status window fields */
221221
#define WC2_RESET_STATUS 0x00100L /* 09 call status_update(BL_RESET) to
222-
* indicate 'draw everything' */
222+
* indicate 'draw everything' */
223223
#define WC2_TERM_SIZE 0x00200L /* 10 support setting terminal size */
224224
#define WC2_STATUSLINES 0x00400L /* 16 switch between 2 or 3 lines of status */
225225
#define WC2_WINDOWBORDERS 0x00800L /* 11 display borders on nh windows */
@@ -228,11 +228,12 @@ extern
228228
/* pline() can overload the display attributes argument passed to putstr()
229229
with one or more flags and at most one of bold/blink/inverse/&c */
230230
#define WC2_URGENT_MESG 0x04000L /* 14 putstr(WIN_MESSAGE) supports urgency
231-
* via non-display attribute flag */
231+
* via non-display attribute flag */
232232
#define WC2_SUPPRESS_HIST 0x08000L /* 15 putstr(WIN_MESSAGE) supports history
233-
* suppression via non-disp attr */
233+
* suppression via non-disp attr */
234234
#define WC2_MENU_GLYPHS 0x10000L /* 16 object menu glyphs in inventory */
235-
/* 15 free bits */
235+
#define WC2_PEACEFUL 0x20000L /* 17 supports underlined peaceful monsters */
236+
/* 14 free bits */
236237

237238
#define ALIGN_LEFT 1
238239
#define ALIGN_RIGHT 2

src/detect.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ boolean showtail;
8787
else
8888
show_glyph(mtmp->mx, mtmp->my, mtmp->mtame
8989
? pet_to_glyph(mtmp, newsym_rn2)
90-
: mon_to_glyph(mtmp, newsym_rn2));
90+
: mtmp->mpeaceful ? peaceful_to_glyph(mtmp, newsym_rn2)
91+
: mon_to_glyph(mtmp, newsym_rn2));
9192

9293
if (showtail && mtmp->data == &mons[PM_LONG_WORM])
9394
detect_wsegs(mtmp, 0);

src/display.c

+8
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,11 @@ xchar worm_tail; /* mon is actually a worm tail */
487487
num = petnum_to_glyph(PM_LONG_WORM_TAIL);
488488
else
489489
num = pet_to_glyph(mon, rn2_on_display_rng);
490+
} else if (mon->mpeaceful && !Hallucination) {
491+
if (worm_tail)
492+
num = peacefulnum_to_glyph(PM_LONG_WORM_TAIL);
493+
else
494+
num = peaceful_to_glyph(mon, rn2_on_display_rng);
490495
} else if (has_erid(mon) || mon->ridden_by) {
491496
num = ridden_mon_to_glyph(mon, rn2_on_display_rng);
492497
} else if (sightflags == DETECTED) {
@@ -1595,6 +1600,9 @@ int x, y, glyph;
15951600
} else if (glyph >= GLYPH_INVIS_OFF) { /* invisible mon */
15961601
text = "invisible mon";
15971602
offset = glyph - GLYPH_INVIS_OFF;
1603+
} else if (glyph >= GLYPH_PEACEFUL_OFF) { /* peaceful mon */
1604+
text = "peaceful mon";
1605+
offset = glyph - GLYPH_PEACEFUL_OFF;
15981606
} else if (glyph >= GLYPH_PET_OFF) { /* a pet */
15991607
text = "pet";
16001608
offset = glyph - GLYPH_PET_OFF;

src/mapglyph.c

+7
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,13 @@ unsigned mgflags;
329329
else
330330
invis_color(offset);
331331
special |= MG_INVIS;
332+
} else if ((offset = (glyph - GLYPH_PEACEFUL_OFF)) >= 0) { /* peaceful */
333+
idx = mons[offset].mlet + SYM_OFF_M;
334+
if (has_rogue_color)
335+
color = NO_COLOR; /* no need to check iflags.use_color */
336+
else
337+
mon_color(offset);
338+
special |= MG_PEACEFUL;
332339
} else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */
333340
idx = mons[offset].mlet + SYM_OFF_M;
334341
if (has_rogue_color)

src/mon.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -4786,6 +4786,7 @@ boolean via_attack;
47864786
mon->mpeaceful = 0;
47874787
growl(mon);
47884788
}
4789+
newsym(mon->mx, mon->my); /* clear peaceful glyph */
47894790
}
47904791
}
47914792

@@ -4800,6 +4801,7 @@ boolean via_attack;
48004801
if (mtmp->mtame)
48014802
return;
48024803
mtmp->mpeaceful = 0;
4804+
newsym(mtmp->mx, mtmp->my); /* clear peaceful glyph */
48034805
/* peacefuls always catch convicts stealing. but, convicts don't feel
48044806
guilty about it. (note there's still an alignment penalty for
48054807
*failing* to steal from a priest) in steal_it()) */
@@ -4850,6 +4852,7 @@ boolean via_attack;
48504852
continue;
48514853
if (mon->data == q_guardian && mon->mpeaceful) {
48524854
mon->mpeaceful = 0;
4855+
newsym(mon->mx, mon->my); /* clear peaceful glyph */
48534856
if (canseemon(mon))
48544857
++got_mad;
48554858
}
@@ -4906,6 +4909,7 @@ boolean via_attack;
49064909
perhaps reduce tameness? */
49074910
} else {
49084911
mon->mpeaceful = 0;
4912+
newsym(mon->mx, mon->my); /* clear peaceful glyph */
49094913
if (u.ualign.type != A_NONE) {
49104914
if (canspotmon(mon))
49114915
You_feel("guilty.");
@@ -6107,6 +6111,7 @@ boolean silent;
61076111
mtmp->msleeping = mtmp->mfrozen = 0;
61086112
}
61096113
mtmp->mpeaceful = 0;
6114+
newsym(mtmp->mx, mtmp->my); /* clear peaceful glyph */
61106115
}
61116116
}
61126117
if (ct) {
@@ -6137,8 +6142,10 @@ pacify_guards()
61376142
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
61386143
if (DEADMONSTER(mtmp))
61396144
continue;
6140-
if (is_watch(mtmp->data))
6145+
if (is_watch(mtmp->data)) {
61416146
mtmp->mpeaceful = 1;
6147+
newsym(mtmp->mx, mtmp->my); /* enable peaceful glyph */
6148+
}
61426149
}
61436150
}
61446151

@@ -6374,6 +6381,7 @@ struct monst *mtmp;
63746381
mon->mconf = 0;
63756382
mon->mstun = 0;
63766383
mon->mpeaceful = 1;
6384+
newsym(mon->mx, mon->my); /* enable peaceful glyph */
63776385
}
63786386
}
63796387
/* in case player kills themselves while defeating
@@ -6387,6 +6395,7 @@ struct monst *mtmp;
63876395
and get the hell out before the situation becomes dire */
63886396
com_pager(201);
63896397
mtmp->mpeaceful = 0;
6398+
newsym(mtmp->mx, mtmp->my); /* clear peaceful glyph */
63906399
paralyze_monst(mtmp, 100);
63916400
} else {
63926401
com_pager(200);

src/options.c

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ static struct Bool_Opt {
163163
{ "help", &flags.help, TRUE, SET_IN_GAME },
164164
{ "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME },
165165
{ "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
166+
{ "underline_peacefuls", &iflags.wc2_underline_peacefuls, FALSE, SET_IN_GAME }, /*WC2*/
166167
{ "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME },
167168
{ "hitpointbar", &iflags.wc2_hitpointbar, FALSE, SET_IN_GAME }, /*WC2*/
168169
#ifndef MAC

src/read.c

+5
Original file line numberDiff line numberDiff line change
@@ -3197,6 +3197,11 @@ struct _create_particular_data *d;
31973197
mtmp->mtame = 0; /* sanity precaution */
31983198
mtmp->mpeaceful = d->makepeaceful ? 1 : 0;
31993199
set_malign(mtmp);
3200+
if (iflags.wc2_underline_peacefuls) {
3201+
/* mpeaceful is only set here, so the previous calls to newsym
3202+
* will make it look like the monster isn't peaceful. */
3203+
newsym(mtmp->mx, mtmp->my);
3204+
}
32003205
}
32013206
if (d->saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
32023207
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);

src/worm.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,9 @@ boolean use_detection_glyph;
468468
? detected_monnum_to_glyph(what_tail)
469469
: (worm->mtame
470470
? petnum_to_glyph(what_tail)
471-
: monnum_to_glyph(what_tail));
471+
: (worm->mpeaceful
472+
? peacefulnum_to_glyph(what_tail)
473+
: monnum_to_glyph(what_tail)));
472474
show_glyph(curr->wx, curr->wy, num);
473475
curr = curr->nseg;
474476
}

win/curses/cursmain.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct window_procs curses_procs = {
5353
#endif
5454
| WC2_FLUSH_STATUS | WC2_TERM_SIZE
5555
| WC2_STATUSLINES | WC2_WINDOWBORDERS | WC2_PETATTR | WC2_GUICOLOR
56-
| WC2_SUPPRESS_HIST | WC2_MENU_GLYPHS),
56+
| WC2_SUPPRESS_HIST | WC2_MENU_GLYPHS | WC2_PEACEFUL),
5757
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
5858
curses_init_nhwindows,
5959
curses_player_selection,
@@ -700,6 +700,8 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph,
700700
mapglyph(glyph, &ch, &color, &special, x, y, 0);
701701
if ((special & MG_PET) && iflags.hilite_pet) {
702702
attr = iflags.wc2_petattr;
703+
} else if ((special & MG_PEACEFUL) && iflags.underline_peacefuls) {
704+
attr = A_UNDERLINE;
703705
}
704706
if ((special & MG_DETECT) && iflags.use_inverse) {
705707
attr = A_REVERSE;

win/share/tilemap.c

+1
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ init_tilemap()
289289
for (i = 0; i < NUMMONS; i++) {
290290
tilemap[GLYPH_MON_OFF + i] = tilenum;
291291
tilemap[GLYPH_PET_OFF + i] = tilenum;
292+
tilemap[GLYPH_PEACEFUL_OFF + i] = tilenum;
292293
tilemap[GLYPH_DETECT_OFF + i] = tilenum;
293294
tilemap[GLYPH_RIDDEN_OFF + i] = tilenum;
294295
tilemap[GLYPH_BODY_OFF + i] = corpsetile;

0 commit comments

Comments
 (0)