]> granicus.if.org Git - nethack/commitdiff
Helltweaks: improve lava river
authorPasi Kallinen <paxed@alt.org>
Mon, 30 Jan 2023 15:07:40 +0000 (17:07 +0200)
committerPasi Kallinen <paxed@alt.org>
Mon, 30 Jan 2023 15:10:39 +0000 (17:10 +0200)
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.

dat/nhlib.lua
doc/lua.adoc
src/nhlsel.c
test/test_sel.lua

index 9ec107a6ed3070ba0b1233ec4736c53c38d86981..fc05c6c8d52dc8fe3f63d225671e8dced4c73a3a 100644 (file)
@@ -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
index 51bf778976af0b24843ae2f88c7dfd9d86eacc49..1e5628bb6d697c3cae3c5ad48c5a6de6a5d6d7aa 100644 (file)
@@ -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.
index 1097b1d48e8e984ae39e251dae9075e6902a803c..e3c86e39e83b8ecea6eec63b4788a7eecb3fbe31 100644 (file)
@@ -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 },
index cc6d98ae97b4afc23bbae6528126e3512db86259..e96b9be71d16dc8c61fafba8a966ad822db2d771 100644 (file)
@@ -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();