From: Pasi Kallinen Date: Mon, 30 Jan 2023 15:07:40 +0000 (+0200) Subject: Helltweaks: improve lava river X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=744d64487b87112bd408b14c98e96696555192a0;p=nethack Helltweaks: improve lava river The lava river will now draw another river, until a certain amount of map locations have been turned into lava, so you don't get a teensy "river" made out of 2 lava pools. Add a lua selection method to count the number of locations in the selection. --- diff --git a/dat/nhlib.lua b/dat/nhlib.lua index 9ec107a6e..fc05c6c8d 100644 --- a/dat/nhlib.lua +++ b/dat/nhlib.lua @@ -57,6 +57,7 @@ end function hell_tweaks(protected_area) local liquid = "L"; local ground = "."; + local n_prot = protected_area:numpoints(); local prot = protected_area:negate(); -- random pools @@ -82,24 +83,38 @@ function hell_tweaks(protected_area) -- river if (percent(50)) then - local floor = selection.match(ground); - local a = selection.rndcoord(floor); - local b = selection.rndcoord(floor); - local lavariver = selection.randline(selection.new(), a.x, a.y, b.x, b.y, 10); - - if (percent(50)) then - lavariver = selection.grow(lavariver, "north"); - end - if (percent(50)) then - lavariver = selection.grow(lavariver, "west"); - end - if (percent(25)) then - local riverbanks = selection.grow(lavariver); + local allrivers = selection.new(); + local reqpts = ((nhc.COLNO * nhc.ROWNO) - n_prot) / 12; -- # of lava pools required + local rpts = 0; + local rivertries = 0; + + repeat + local floor = selection.match(ground); + local a = selection.rndcoord(floor); + local b = selection.rndcoord(floor); + local lavariver = selection.randline(selection.new(), a.x, a.y, b.x, b.y, 10); + + if (percent(50)) then + lavariver = selection.grow(lavariver, "north"); + end + if (percent(50)) then + lavariver = selection.grow(lavariver, "west"); + end + allrivers = allrivers | lavariver; + allrivers = allrivers & prot; + + rpts = allrivers:numpoints(); + rivertries = rivertries + 1; + until ((rpts > reqpts) or (rivertries > 7)); + + if (percent(60)) then + local prc = 10 * math.random(1, 6); + local riverbanks = selection.grow(allrivers); riverbanks = riverbanks & prot; - des.terrain(selection.percentage(riverbanks, 50), ground); + des.terrain(selection.percentage(riverbanks, prc), ground); end - lavariver = lavariver & prot; - des.terrain(lavariver, liquid); + + des.terrain(allrivers, liquid); end -- replacing some walls with boulders diff --git a/doc/lua.adoc b/doc/lua.adoc index 51bf77897..1e5628bb6 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -1153,6 +1153,15 @@ Example: local s = selection.negate(); +=== numpoints + +Return the number of points in the selection. + +Example: + + local n = sel:numpoints(); + + === percentage Each selected location has a percentage chance of being selected in the new selection. diff --git a/src/nhlsel.c b/src/nhlsel.c index 1097b1d48..e3c86e39e 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -12,6 +12,7 @@ static struct selectionvar *l_selection_push_new(lua_State *); /* lua_CFunction prototypes */ static int l_selection_new(lua_State *); static int l_selection_clone(lua_State *); +static int l_selection_numpoints(lua_State *); static int l_selection_getpoint(lua_State *); static int l_selection_setpoint(lua_State *); static int l_selection_filter_percent(lua_State *); @@ -195,6 +196,27 @@ l_selection_setpoint(lua_State *L) return 1; } +/* local numpoints = selection.numpoints(sel); */ +static int +l_selection_numpoints(lua_State *L) +{ + struct selectionvar *sel = l_selection_check(L, 1); + coordxy x, y; + int ret = 0; + NhRect rect; + + selection_getbounds(sel, &rect); + + for (x = rect.lx; x <= rect.hx; x++) + for (y = rect.ly; y <= rect.hy; y++) + if (selection_getpoint(x, y, sel)) + ret++; + + lua_settop(L, 0); + lua_pushinteger(L, ret); + return 1; +} + /* local value = selection.get(sel, x, y); */ static int l_selection_getpoint(lua_State *L) @@ -911,6 +933,7 @@ static const struct luaL_Reg l_selection_methods[] = { { "clone", l_selection_clone }, { "get", l_selection_getpoint }, { "set", l_selection_setpoint }, + { "numpoints", l_selection_numpoints }, { "negate", l_selection_not }, { "percentage", l_selection_filter_percent }, { "rndcoord", l_selection_rndcoord }, diff --git a/test/test_sel.lua b/test/test_sel.lua index cc6d98ae9..e96b9be71 100644 --- a/test/test_sel.lua +++ b/test/test_sel.lua @@ -495,6 +495,34 @@ function test_sel_map() sel_are_equal(sela, selb, __func__); end +function test_sel_numpoints() + local __func__ = "test_sel_numpoints"; + des.reset_level(); + des.level_init({ style = "solidfill", fg = " " }); + + local sela = selection.new(); + local npts = sela:numpoints(); + if (npts ~= 0) then + error(string.format("numpoints reported %i, should have been 0", npts)); + end + + des.terrain(5,5, "."); + + local selb = selection.match("."); + local npts = selb:numpoints(); + if (npts ~= 1) then + error(string.format("numpoints reported %i, should have been 1", npts)); + end + + des.terrain(6,5, "."); + + local selc = selection.match("."); + local npts = selc:numpoints(); + if (npts ~= 2) then + error(string.format("numpoints reported %i, should have been 2", npts)); + end +end + nh.debug_flags({mongen = false, hunger = false, overwrite_stairs = true }); test_selection_params(); test_sel_negate(); @@ -515,3 +543,4 @@ test_sel_match(); test_sel_iterate(); test_sel_bounds(); test_sel_map(); +test_sel_numpoints();