From: nethack.allison Date: Sun, 1 Oct 2006 21:17:38 +0000 (+0000) Subject: statue patch (trunk only) X-Git-Tag: MOVE2GIT~867 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a0986b1e30b3fa6945a917cb99ddcc09fec5607a;p=nethack statue patch (trunk only) Pat wrote: > has a patch (we've added a couple of > his earlier ones) which changes the statue display from a single > one size fits all "`" to a gray monster symbol instead. > But I think the idea is a good one, and along with the > bouldersym option could make the fairly hard to > distinguish back-tick character go away. Sources tagged before applying NETHACK_PRE_STATUE, and afterwards with NETHACK_POST_STATUE for easy rollback. --- diff --git a/include/display.h b/include/display.h index 08a0eef79..20e51b2a6 100644 --- a/include/display.h +++ b/include/display.h @@ -276,7 +276,8 @@ #define GLYPH_ZAP_OFF ((MAXEXPCHARS * EXPL_MAX) + GLYPH_EXPLODE_OFF) #define GLYPH_SWALLOW_OFF ((NUM_ZAP << 2) + GLYPH_ZAP_OFF) #define GLYPH_WARNING_OFF ((NUMMONS << 3) + GLYPH_SWALLOW_OFF) -#define MAX_GLYPH (WARNCOUNT + GLYPH_WARNING_OFF) +#define GLYPH_STATUE_OFF (WARNCOUNT + GLYPH_WARNING_OFF) +#define MAX_GLYPH (NUMMONS + GLYPH_STATUE_OFF) #define NO_GLYPH MAX_GLYPH @@ -290,7 +291,22 @@ /* This has the unfortunate side effect of needing a global variable */ /* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */ +#define random_obj_to_glyph() \ + ((otg_temp = random_object()) == CORPSE ? \ + random_monster() + GLYPH_BODY_OFF : \ + otg_temp + GLYPH_OBJ_OFF) + #define obj_to_glyph(obj) \ + ((obj)->otyp == STATUE ? \ + statue_to_glyph(obj) : \ + Hallucination ? \ + random_obj_to_glyph() : \ + (obj)->otyp == CORPSE ? \ + (int) (obj)->corpsenm + GLYPH_BODY_OFF : \ + (int) (obj)->otyp + GLYPH_OBJ_OFF) + + +#define obj_to_glyph_vanilla(obj) \ (Hallucination ? \ ((otg_temp = random_object()) == CORPSE ? \ random_monster() + GLYPH_BODY_OFF : \ @@ -299,6 +315,15 @@ (int) (obj)->corpsenm + GLYPH_BODY_OFF : \ (int) (obj)->otyp + GLYPH_OBJ_OFF)) + +/* MRKR: Statues now have glyphs corresponding to the monster they */ +/* brepresent and look like monsters when you are hallucinating. */ + +#define statue_to_glyph(obj) \ + (Hallucination ? \ + random_monster() + GLYPH_MON_OFF : \ + (int) (obj)->corpsenm + GLYPH_STATUE_OFF) + #define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF) #define explosion_to_glyph(expltype,idx) \ ((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF) @@ -307,6 +332,7 @@ cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp))) /* Not affected by hallucination. Gives a generic body for CORPSE */ +/* MRKR: ...and the generic statue */ #define objnum_to_glyph(onum) ((int) (onum) + GLYPH_OBJ_OFF) #define monnum_to_glyph(mnum) ((int) (mnum) + GLYPH_MON_OFF) #define detected_monnum_to_glyph(mnum) ((int) (mnum) + GLYPH_DETECT_OFF) @@ -338,9 +364,11 @@ glyph_is_pet(glyph) ? ((glyph)-GLYPH_PET_OFF) : \ glyph_is_detected_monster(glyph) ? ((glyph)-GLYPH_DETECT_OFF) : \ glyph_is_ridden_monster(glyph) ? ((glyph)-GLYPH_RIDDEN_OFF) : \ + glyph_is_statue(glyph) ? ((glyph)-GLYPH_STATUE_OFF) : \ NO_GLYPH) #define glyph_to_obj(glyph) \ (glyph_is_body(glyph) ? CORPSE : \ + glyph_is_statue(glyph) ? STATUE : \ glyph_is_normal_object(glyph) ? ((glyph)-GLYPH_OBJ_OFF) : \ NO_GLYPH) #define glyph_to_trap(glyph) \ @@ -372,6 +400,12 @@ ((glyph) >= GLYPH_PET_OFF && (glyph) < (GLYPH_PET_OFF+NUMMONS)) #define glyph_is_body(glyph) \ ((glyph) >= GLYPH_BODY_OFF && (glyph) < (GLYPH_BODY_OFF+NUMMONS)) + +#define glyph_is_statue(glyph) \ + ((glyph) >= GLYPH_STATUE_OFF && (glyph) < (GLYPH_STATUE_OFF+NUMMONS)) +#define GLYPH_STATUE_VANILLA ((int) GLYPH_OBJ_OFF + STATUE) +#define glyph_is_statue_vanilla(glyph) ( glyph == GLYPH_STATUE_VANILLA) + #define glyph_is_ridden_monster(glyph) \ ((glyph) >= GLYPH_RIDDEN_OFF && (glyph) < (GLYPH_RIDDEN_OFF+NUMMONS)) #define glyph_is_detected_monster(glyph) \ @@ -381,6 +415,7 @@ ((glyph) >= GLYPH_OBJ_OFF && (glyph) < (GLYPH_OBJ_OFF+NUM_OBJECTS)) #define glyph_is_object(glyph) \ (glyph_is_normal_object(glyph) \ + || glyph_is_statue(glyph) \ || glyph_is_body(glyph)) #define glyph_is_trap(glyph) \ ((glyph) >= (GLYPH_CMAP_OFF+trap_to_defsym(1)) && \ diff --git a/include/hack.h b/include/hack.h index 37aff098a..680b42374 100644 --- a/include/hack.h +++ b/include/hack.h @@ -53,6 +53,7 @@ #define MG_DETECT 0x04 #define MG_PET 0x08 #define MG_RIDDEN 0x10 +#define MG_STATUE 0x20 /* sellobj_state() states */ #define SELL_NORMAL (0) diff --git a/src/display.c b/src/display.c index b9c7cf0e0..a8918aecf 100644 --- a/src/display.c +++ b/src/display.c @@ -256,8 +256,18 @@ map_object(obj, show) register int x = obj->ox, y = obj->oy; register int glyph = obj_to_glyph(obj); - if (level.flags.hero_memory) + if (level.flags.hero_memory) { + + /* MRKR: While hallucinating, statues are seen as random monsters */ + /* but remembered as random objects. */ + + if (Hallucination && obj->otyp == STATUE) { + levl[x][y].glyph = random_obj_to_glyph(); + } + else { levl[x][y].glyph = glyph; + } + } if (show) show_glyph(x, y, glyph); } @@ -1250,7 +1260,8 @@ show_glyph(x,y,glyph) * the definition. */ - if (glyph >= GLYPH_WARNING_OFF) { /* a warning */ + if (glyph >= GLYPH_WARNING_OFF + && glyph < GLYPH_STATUE_OFF) { /* a warning */ text = "warning"; offset = glyph - GLYPH_WARNING_OFF; } else if (glyph >= GLYPH_SWALLOW_OFF) { /* swallow border */ text = "swallow border"; offset = glyph - GLYPH_SWALLOW_OFF; diff --git a/src/mapglyph.c b/src/mapglyph.c index 23c886091..cf6b4697e 100644 --- a/src/mapglyph.c +++ b/src/mapglyph.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mapglyph.c 3.5 2006/09/17 */ +/* SCCS Id: @(#)mapglyph.c 3.5 2006/10/01 */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -82,7 +82,16 @@ unsigned *ospecial; * Warning: For speed, this makes an assumption on the order of * offsets. The order is set in display.h. */ - if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ + if ((offset = (glyph - GLYPH_STATUE_OFF)) >= 0) { /* a statue */ + idx = mons[offset].mlet + SYM_OFF_M; +# ifdef ROGUE_COLOR + if (has_rogue_color) + color = CLR_RED; + else +# endif + obj_color(STATUE); + special |= MG_STATUE; + } else if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ idx = offset + SYM_OFF_W; # ifdef ROGUE_COLOR if (has_rogue_color) diff --git a/src/pager.c b/src/pager.c index 9d232cee6..0fc1cf00b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -545,6 +545,8 @@ do_look(mode, click_cc) sym = showsyms[glyph_to_cmap(glyph)]; } else if (glyph_is_trap(glyph)) { sym = showsyms[trap_to_defsym(glyph_to_trap(glyph))]; + } else if (glyph_is_statue(glyph)) { + sym = showsyms[(int)mons[glyph_to_mon(glyph)].mlet + SYM_OFF_M]; } else if (glyph_is_object(glyph)) { sym = showsyms[(int)objects[glyph_to_obj(glyph)].oc_class + SYM_OFF_O]; if (sym == '`' && iflags.bouldersym && (int)glyph_to_obj(glyph) == BOULDER) diff --git a/src/restore.c b/src/restore.c index bd75a9285..2118e6c82 100644 --- a/src/restore.c +++ b/src/restore.c @@ -89,6 +89,8 @@ void FDECL( amii_setpens, (int) ); /* use colors from save file */ extern int amii_numcolors; #endif +#include "display.h" + boolean restoring = FALSE; static NEARDATA struct fruit *oldfruit; static NEARDATA long omoves; @@ -124,6 +126,15 @@ find_lev_obj() fobjtmp = otmp->nobj; place_object(otmp, otmp->ox, otmp->oy); } + + /* statue patch: imagine we're loading a vanilla nh file */ + for(x=0; xotyp == STATUE && + glyph_is_statue_vanilla(levl[x][y].glyph)) { + levl[x][y].glyph = obj_to_glyph(level.objects[x][y]); + } } /* Things that were marked "in_use" when the game was saved (ex. via the diff --git a/src/save.c b/src/save.c index fa8477503..3281f2da6 100644 --- a/src/save.c +++ b/src/save.c @@ -85,6 +85,23 @@ static long nulls[10]; #define HUP #endif + +/* compute object glyphs for vanilla nethack -- statue patch */ +void +make_glyphs_vanilla(lev) +xchar lev; +{ + int x,y; + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + if ( level.objects[x][y] != 0 && + level.objects[x][y]->otyp == STATUE && + glyph_is_statue(levl[x][y].glyph)) + levl[x][y].glyph = obj_to_glyph_vanilla(level.objects[x][y]); +} + + /* need to preserve these during save to avoid accessing freed memory */ static unsigned ustuck_id = 0, usteed_id = 0; @@ -511,6 +528,9 @@ int mode; short tlev; #endif + /* make remembered glyphs correct fo rloading into vanilla nh */ + make_glyphs_vanilla(lev); + /* if we're tearing down the current level without saving anything (which happens upon entrance to the endgame or after an aborted restore attempt) then we don't want to do any actual I/O */ diff --git a/src/sounds.c b/src/sounds.c index 75ca7c282..dff58f095 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -959,6 +959,23 @@ dochat() tx = u.ux+u.dx; ty = u.uy+u.dy; mtmp = m_at(tx, ty); + if ((!mtmp || mtmp->mundetected) && + (otmp = vobj_at(tx, ty)) && otmp->otyp == STATUE) { + + /* Talking to a statue */ + + if (!Blind) { + if (Hallucination) { + /* if you're hallucinating, you can't tell it's a statue */ + pline_The("%s seems not to notice you.", rndmonnam()); + } + else { + pline_The("statue seems not to notice you."); + } + } + return(0); + } + if (!mtmp || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE || mtmp->m_ap_type == M_AP_OBJECT) diff --git a/src/trap.c b/src/trap.c index 06a9c9d2f..6ff352103 100644 --- a/src/trap.c +++ b/src/trap.c @@ -508,6 +508,8 @@ int *fail_reason; (mon != shkp || carried(statue))) ? xname(statue) : "statue"); pline("%s %s!", upstart(statuename), comes_to_life); + } else if (Hallucination) { /* They don't know it's a statue */ + pline_The("%s suddenly seems more animated.", rndmonnam()); } else if (cause == ANIMATE_SHATTER) { if (cansee(x, y)) Sprintf(statuename, "%s%s", shk_your(tmpbuf, statue), diff --git a/src/zap.c b/src/zap.c index db7cc3f43..3d9103278 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1633,9 +1633,23 @@ struct obj *obj, *otmp; (the sound could be implicit) */ maybelearnit = cansee(obj->ox, obj->oy) || !Deaf; if (obj->otyp == BOULDER) { - fracture_rock(obj); - } else if (obj->otyp == STATUE) { - (void) break_statue(obj); + if (cansee(obj->ox, obj->oy)) + pline_The("boulder falls apart."); + else if (!Deaf) + You_hear("a crumbling sound."); + fracture_rock(obj); + } + else if (obj->otyp == STATUE) { + if (break_statue(obj)) { + if (cansee(obj->ox, obj->oy)) { + if (Hallucination) + pline_The("%s shatters.", rndmonnam()); + else + pline_The("statue shatters."); + } else if (!Deaf) { + You_hear("a crumbling sound."); + } + } } else { if (context.mon_moving ? !breaks(obj, obj->ox, obj->oy) : diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 46c5dc234..f0dac04c7 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -395,6 +395,12 @@ init_tilemap() tilenum++; } + /* statue patch: statues still use the same glyph as in vanilla */ + + for ( i = 0; i < NUMMONS; i++) { + tilemap[GLYPH_STATUE_OFF+i] = tilemap[GLYPH_OBJ_OFF+STATUE]; + } + lastothtile = tilenum - 1; }