]> granicus.if.org Git - nethack/commitdiff
Implement selection addition and difference
authorcopperwater <aosdict@gmail.com>
Mon, 14 Mar 2022 15:14:46 +0000 (11:14 -0400)
committerPasi Kallinen <paxed@alt.org>
Mon, 14 Mar 2022 16:42:28 +0000 (18:42 +0200)
Selection difference is something I have found myself wanting a lot when
working on levels, and have had to defer to a clunkier xor-then-and
approach. This commit implements the TODO-ed addition and subtraction
operators on two sets.

I don't see how the addition operator would be any different from
logical or, so it just calls l_selection_or rather than implement a new
function.

doc/lua.adoc
src/nhlsel.c

index 9b45c4419ed8eb5ad6c74bd124ff5b3959a39b4a..b024a9d37cc331211091e9e76e20faa4d8842ca6 100644 (file)
@@ -793,11 +793,13 @@ Example:
 
 === Logical or
 
-Choose locations that are selected in either or both selections.
+Choose locations that are selected in either or both selections. The
+addition operator also does this.
 
 Example:
 
  local sel = selection.area(4,5, 40,10) | selection.rect(7,8, 60,14);
+ local sel = selection.area(4,5, 40,10) + selection.rect(7,8, 60,14);
 
 
 === Logical xor
@@ -809,6 +811,15 @@ Example:
  local sel = selection.area(4,5, 40,10) ~ selection.rect(7,8, 60,14);
 
 
+=== Logical difference
+
+Choose locations in the first selection but not in the second selection.
+
+Example:
+
+ local sel = selection.area(10,10, 20,20) - selection.area(14,14, 17,17);
+
+
 === area
 
 Alias for <<_fillrect>>.
index 9f25c3297380957216ac9215f3494c12b43f159f..e2059cbccd5f6db8ebeac683050784ec444b6d09 100644 (file)
@@ -33,6 +33,10 @@ static int l_selection_and(lua_State *);
 static int l_selection_or(lua_State *);
 static int l_selection_xor(lua_State *);
 static int l_selection_not(lua_State *);
+/* There doesn't seem to be a point in having a l_selection_add since it would
+ * do the same thing as l_selection_or. The addition operator is mapped to
+ * l_selection_or. */
+static int l_selection_sub(lua_State *);
 #if 0
 /* the following do not appear to currently be
    used and because they are static, the OSX
@@ -40,8 +44,6 @@ static int l_selection_not(lua_State *);
    if ifdef'd out the prototype here and the
    function body below.
  */
-static int l_selection_add(lua_State *);
-static int l_selection_sub(lua_State *);
 static int l_selection_ipairs(lua_State *);
 static struct selectionvar *l_selection_to(lua_State *, int);
 #endif
@@ -277,6 +279,29 @@ l_selection_xor(lua_State *L)
     return 1;
 }
 
+/* local sel = selection.area(10,10, 20,20) - selection.area(14,14, 17,17)
+ *   - i.e. points that are in A but not in B */
+static int
+l_selection_sub(lua_State *L)
+{
+    int x,y;
+    struct selectionvar *sela = l_selection_check(L, 1);
+    struct selectionvar *selb = l_selection_check(L, 2);
+    struct selectionvar *selr = l_selection_push(L);
+
+    for (x = 0; x < selr->wid; x++) {
+        for (y = 0; y < selr->hei; y++) {
+            xchar a_pt = selection_getpoint(x, y, sela);
+            xchar b_pt = selection_getpoint(x, y, selb);
+            int val = (a_pt ^ b_pt) & a_pt;
+            selection_setpoint(x, y, selr, val);
+        }
+    }
+
+    lua_remove(L, 1);
+    lua_remove(L, 1);
+    return 1;
+}
 
 /* local s = selection.percentage(sel, 50); */
 static int
@@ -822,9 +847,9 @@ static const luaL_Reg l_selection_meta[] = {
     { "__bor", l_selection_or },
     { "__bxor", l_selection_xor },
     { "__bnot", l_selection_not },
+    { "__add", l_selection_or }, /* this aliases + to be the same as | */
+    { "__sub", l_selection_sub },
     /* TODO: http://lua-users.org/wiki/MetatableEvents
-       { "__add", l_selection_add },
-       { "__sub", l_selection_sub },
        { "__ipairs", l_selection_ipairs },
     */
     { NULL, NULL }