Level temperature

Allow setting a per-level "temperature": hot, cold, or temperate
via special level flags. Currently it only affects some messages
in Gehennom, but it could be expanded to ice melting, water freezing,
or monster generation, for example.

Invalidates saves and bones.
This commit is contained in:
Pasi Kallinen
2023-01-17 20:07:24 +02:00
parent 9df4a38d65
commit bb8c144809
8 changed files with 35 additions and 10 deletions

View File

@@ -231,7 +231,7 @@ hells = {
function ()
local cwid = math.random(4);
des.level_init({ style = "solidfill", fg = " ", lit = 0 });
des.level_flags("mazelevel", "noflip");
des.level_flags("mazelevel", "noflip", "cold");
des.level_init({ style = "maze", wallthick = 1, corrwid = cwid });
local outside_walls = selection.match(" ");
local icey = selection.negate():percentage(10):grow():filter_mapchar(".");

View File

@@ -7,7 +7,7 @@
des.level_init({ style = "solidfill", fg = " " });
des.level_flags("mazelevel", "noteleport", "hardfloor", "nommap");
des.level_flags("mazelevel", "noteleport", "hardfloor", "nommap", "temperate");
des.map([[
----------------------------------------------------------------------------

View File

@@ -1085,6 +1085,8 @@ slightly more interesting Gehennom filler levels
don't reveal color of potions, gems, or spellbooks that haven't been seen up
close (seeing faraway monster operate on an object counts as up close)
fix freeing a worn object when forced to drop it by falling down stairs
allow setting per-level "temperature": hot, cold, or temperate, currently
only affects some messages
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -532,6 +532,9 @@ Set flags for this level.
| noflip | Prevent flipping the level.
| noflipx | Prevent flipping the level horizontally.
| noflipy | Prevent flipping the level vertically.
| hot | Level is hot. Dungeon flag "hellish" automatically sets this.
| cold | Level is cold.
| temperate | Level is neither hot nor cold.
|===
Example:

View File

@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 69
#define EDITLEVEL 70
/*
* Development status possibilities.

View File

@@ -386,6 +386,7 @@ struct levelflags {
normal mode descendant of such) */
Bitfield(corrmaze, 1); /* Whether corridors are used for the maze
rather than ROOM */
schar temperature; /* +1 == hot, -1 == cold */
};
typedef struct {

View File

@@ -1360,6 +1360,7 @@ goto_level(
char *annotation;
int dist = depth(newlevel) - depth(&u.uz);
boolean do_fall_dmg = FALSE;
schar prev_temperature = gl.level.flags.temperature;
if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel))
newlevel->dlevel = dunlevs_in_dungeon(newlevel);
@@ -1711,8 +1712,7 @@ goto_level(
display_nhwindow(WIN_MESSAGE, FALSE);
#endif
You_hear("groans and moans everywhere.");
} else
hellish_smoke_mesg(); /* "It is hot here. You smell smoke..." */
}
record_achievement(ACH_HELL); /* reached Gehennom */
}
@@ -1759,9 +1759,6 @@ goto_level(
}
} else if (In_quest(&u.uz)) {
onquest(); /* might be reaching locate|goal level */
} else if (In_V_tower(&u.uz)) {
if (newdungeon && In_hell(&u.uz0))
pline_The("heat and smoke are gone.");
} else if (Is_knox(&u.uz)) {
/* alarm stops working once Croesus has died */
if (new || !gm.mvitals[PM_CROESUS].died) {
@@ -1803,6 +1800,17 @@ goto_level(
}
}
if (prev_temperature != gl.level.flags.temperature) {
if (gl.level.flags.temperature)
hellish_smoke_mesg();
else if (prev_temperature > 0)
pline_The("heat %s gone.",
In_hell(&u.uz0)
? "and smoke are" : "is");
else if (prev_temperature < 0)
You("are out of the cold.");
}
/* this was originally done earlier; moved here to be logged after
any achievement related to entering a dungeon branch
[TODO: if an achievement for receiving quest call from leader
@@ -1858,8 +1866,12 @@ RESTORE_WARNING_FORMAT_NONLITERAL
void
hellish_smoke_mesg(void)
{
if (Inhell && !Is_valley(&u.uz))
pline("It is hot here. You %s smoke...",
if (gl.level.flags.temperature)
pline("It is %s here.",
gl.level.flags.temperature > 0 ? "hot" : "cold");
if (In_hell(&u.uz) && gl.level.flags.temperature > 0)
pline("You %s smoke...",
olfaction(gy.youmonst.data) ? "smell" : "sense");
}

View File

@@ -3694,6 +3694,12 @@ lspo_level_flags(lua_State *L)
gc.coder->allow_flips &= ~1;
else if (!strcmpi(s, "noflip"))
gc.coder->allow_flips = 0;
else if (!strcmpi(s, "temperate"))
gl.level.flags.temperature = 0;
else if (!strcmpi(s, "hot"))
gl.level.flags.temperature = 1;
else if (!strcmpi(s, "cold"))
gl.level.flags.temperature = -1;
else {
char buf[BUFSZ];
Sprintf(buf, "Unknown level flag %s", s);
@@ -6798,6 +6804,7 @@ sp_level_coder_init(void)
(void) memset((genericptr_t) SpLev_Map, 0, sizeof SpLev_Map);
gl.level.flags.is_maze_lev = 0;
gl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0;
reset_xystart_size();