diff --git a/doc/lua.adoc b/doc/lua.adoc index cd08d5ebd..90ec18d2f 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -1090,11 +1090,23 @@ Example: === gradient -Create a "gradient" of selected positions. +Create a "gradient" of selected positions, radiating outward from a center point +or line. +x and y are required; x2 and y2 are not required. If they are provided and are +different from x and y, the center of the gradient will be a line; otherwise it +will be a point source at (x,y). +type is either "radial" or "square"; defaults to "radial" if not provided. +mindist is not required and is 0 by default. Points within (mindist) tiles of +the center will always be added to the selection. +maxdist is required. Points more than (maxdist) tiles from the center will never +be added to the selection. +For any given point between mindist and maxdist, there is a random chance it +will be added to the selection; this chance starts at 100% at mindist and +decreases linearly to 0% at maxdist. Example: - local s = selection.gradient({ type = "radial", x = 3, y = 5, x2 = 10, y2 = 12, mindist = 4, maxdist = 10, limited = false }); + local s = selection.gradient({ type = "radial", x = 3, y = 5, x2 = 10, y2 = 12, mindist = 4, maxdist = 10 }); === grow diff --git a/include/extern.h b/include/extern.h index 586b0e844..5e89e43ef 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2674,7 +2674,7 @@ extern void set_floodfillchk_match_under(coordxy); extern void selection_do_ellipse(struct selectionvar *, int, int, int, int, int); extern void selection_do_gradient(struct selectionvar *, long, long, long, - long, long, long, long, long); + long, long, long, long); extern int lspo_reset_level(lua_State *); extern int lspo_finalize_level(lua_State *); extern boolean get_coord(lua_State *, int, lua_Integer *, lua_Integer *); diff --git a/src/nhlsel.c b/src/nhlsel.c index e3c86e39e..52850d8f6 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -840,13 +840,10 @@ l_selection_gradient(lua_State *L) /* if x2 and y2 aren't set, the gradient has a single center point of x,y; * if they are set, the gradient is centered on a (x,y) to (x2,y2) line */ coordxy x = 0, y = 0, x2 = -1, y2 = -1; - /* points will not be added within mindist of the center; the chance for a + /* points are always added within mindist of the center; the chance for a * point between mindist and maxdist to be added to the selection starts at - * 0% at mindist and increases linearly to 100% at maxdist */ + * 100% at mindist and decreases linearly to 0% at maxdist */ coordxy mindist = 0, maxdist = 0; - /* if limited is true, no points farther than maxdist will be added; if - * false, all points farther than maxdist will be added */ - boolean limited = FALSE; long type = 0; static const char *const gradtypes[] = { "radial", "square", NULL @@ -862,17 +859,18 @@ l_selection_gradient(lua_State *L) y = (coordxy) get_table_int(L, "y"); x2 = (coordxy) get_table_int_opt(L, "x2", -1); y2 = (coordxy) get_table_int_opt(L, "y2", -1); + cvt_to_abscoord(&x, &y); + cvt_to_abscoord(&x2, &y2); /* maxdist is required because there's no obvious default value for it, * whereas mindist has an obvious defalt of 0 */ maxdist = get_table_int(L, "maxdist"); mindist = get_table_int_opt(L, "mindist", 0); - limited = get_table_boolean_opt(L, "limited", FALSE); lua_pop(L, 1); (void) l_selection_new(L); sel = l_selection_check(L, 1); } else { - nhl_error(L, "wrong parameters"); + nhl_error(L, "selection.gradient requires table argument"); /* NOTREACHED */ } @@ -885,7 +883,7 @@ l_selection_gradient(lua_State *L) y2 = y; } - selection_do_gradient(sel, x, y, x2, y2, type, mindist, maxdist, limited); + selection_do_gradient(sel, x, y, x2, y2, type, mindist, maxdist); lua_settop(L, 1); return 1; } diff --git a/src/sp_lev.c b/src/sp_lev.c index 916e713a4..7870d0b0a 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -4989,13 +4989,14 @@ line_dist_coord(long x1, long y1, long x2, long y2, long x3, long y3) return dist; } +/* guts of l_selection_gradient */ void selection_do_gradient( struct selectionvar *ov, long x, long y, long x2,long y2, long gtyp, - long mind, long maxd, long limit) + long mind, long maxd) { long dx, dy, dofs; @@ -5017,10 +5018,8 @@ selection_do_gradient( for (dx = 0; dx < COLNO; dx++) for (dy = 0; dy < ROWNO; dy++) { long d0 = line_dist_coord(x, y, x2, y2, dx, dy); - if (d0 >= mind && (!limit || d0 <= maxd)) { - if (d0 - mind > rn2(dofs)) - selection_setpoint(dx, dy, ov, 1); - } + if (d0 <= mind || (d0 <= maxd && d0 - mind < rn2(dofs))) + selection_setpoint(dx, dy, ov, 1); } break; } @@ -5034,10 +5033,8 @@ selection_do_gradient( long d5 = line_dist_coord(x, y, x2, y2, dx, dy); long d0 = min(d5, min(max(d1, d2), max(d3, d4))); - if (d0 >= mind && (!limit || d0 <= maxd)) { - if (d0 - mind > rn2(dofs)) - selection_setpoint(dx, dy, ov, 1); - } + if (d0 <= mind || (d0 <= maxd && d0 - mind < rn2(dofs))) + selection_setpoint(dx, dy, ov, 1); } break; } /*case*/