From: copperwater Date: Mon, 14 Mar 2022 15:14:46 +0000 (-0400) Subject: Implement selection addition and difference X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4a460f81b958ac451dcd675d34728bc8ac2be84;p=nethack Implement selection addition and difference 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. --- diff --git a/doc/lua.adoc b/doc/lua.adoc index 9b45c4419..b024a9d37 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -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>>. diff --git a/src/nhlsel.c b/src/nhlsel.c index 9f25c3297..e2059cbcc 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -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 }