Use lua for special level files
Game is playable, and should compile on linux and Windows. Assumes you have a lua 5.3 library available. Removes level compiler and associated files. Replaces special level des-files with lua scripts. Exposes some NetHack internals to lua: - des-table with commands to create special levels - nh-table with NetHack core commands - nhc-table with some constants - u-table with some player-specific data (u-struct) - selection userdata Adds some rudimentary tests. Adds new extended command #wizloadlua to run a specific script, and #wizloaddes to run a specific level-creation script. nhlib.lua is loaded for every lua script. Download and untar lua: mkdir lib cd lib curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz tar zxf lua-5.3.5.tar.gz Then make nethack normally.
This commit is contained in:
723
src/nhlsel.c
Normal file
723
src/nhlsel.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/* NetHack 3.6 nhlua.c $NHDT-Date: 1524287226 2018/04/21 05:07:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */
|
||||
/* Copyright (c) 2018 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
#include "sp_lev.h"
|
||||
|
||||
/* lua_CFunction prototypes */
|
||||
STATIC_DCL int FDECL(l_selection_new, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_clone, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_getpoint, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_setpoint, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_not, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_filter_percent, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_rndcoord, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_line, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_randline, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_rect, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_fillrect, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_fillrect, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_grow, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_filter_mapchar, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_flood, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_circle, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_ellipse, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_gradient, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_iterate, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_gc, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_not, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_and, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_or, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_xor, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_not, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_add, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_sub, (lua_State *));
|
||||
STATIC_DCL int FDECL(l_selection_ipairs, (lua_State *));
|
||||
|
||||
struct selectionvar *
|
||||
l_selection_check(L, index)
|
||||
lua_State *L;
|
||||
int index;
|
||||
{
|
||||
struct selectionvar *sel;
|
||||
|
||||
luaL_checktype(L, index, LUA_TUSERDATA);
|
||||
sel = (struct selectionvar *)luaL_checkudata(L, index, "selection");
|
||||
if (!sel)
|
||||
nhl_error(L, "Selection error");
|
||||
return sel;
|
||||
}
|
||||
|
||||
static int
|
||||
l_selection_gc(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
if (sel)
|
||||
selection_free(sel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct selectionvar *
|
||||
l_selection_to(L, index)
|
||||
lua_State *L;
|
||||
int index;
|
||||
{
|
||||
struct selectionvar *sel = (struct selectionvar *)lua_touserdata(L, index);
|
||||
if (!sel)
|
||||
nhl_error(L, "Selection error");
|
||||
return sel;
|
||||
}
|
||||
|
||||
static struct selectionvar *
|
||||
l_selection_push(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *tmp = selection_new();
|
||||
struct selectionvar *sel = (struct selectionvar *)lua_newuserdata(L, sizeof(struct selectionvar));
|
||||
luaL_getmetatable(L, "selection");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
sel->wid = tmp->wid;
|
||||
sel->hei = tmp->hei;
|
||||
sel->map = dupstr(tmp->map);
|
||||
selection_free(tmp);
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
/* local sel = selection.new(); */
|
||||
static int
|
||||
l_selection_new(L)
|
||||
lua_State *L;
|
||||
{
|
||||
(void) l_selection_push(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local sel = selection.clone(sel); */
|
||||
static int
|
||||
l_selection_clone(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
struct selectionvar *tmp;
|
||||
/* int x,y; */ /* REVIEW: unreferenced */
|
||||
lua_pop(L, 1);
|
||||
(void) l_selection_new(L);
|
||||
tmp = l_selection_check(L, 1);
|
||||
if (tmp->map)
|
||||
free(tmp->map);
|
||||
tmp->map = dupstr(sel->map);
|
||||
tmp->wid = sel->wid;
|
||||
tmp->hei = sel->hei;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* selection.set(sel, x, y); */
|
||||
/* selection.set(sel, x, y, value); */
|
||||
/* local sel = selection.set(); */
|
||||
/* local sel = sel:set(); */
|
||||
/* local sel = selection.set(sel); */
|
||||
/* TODO: allow setting multiple coordinates at once: set({x,y}, {x,y}, ...); */
|
||||
static int
|
||||
l_selection_setpoint(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = (struct selectionvar *) 0;
|
||||
/* REVIEW: initializer added */
|
||||
schar x = -1, y = -1;
|
||||
int val = 1;
|
||||
int argc = lua_gettop(L);
|
||||
long coord;
|
||||
|
||||
if (argc == 0) {
|
||||
(void) l_selection_new(L);
|
||||
} else if (argc == 1) {
|
||||
sel = l_selection_check(L, 1);
|
||||
} else if (argc == 2) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
lua_pop(L, 2);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
} else {
|
||||
sel = l_selection_check(L, 1);
|
||||
x = (schar) luaL_checkinteger(L, 2);
|
||||
y = (schar) luaL_checkinteger(L, 3);
|
||||
val = (int) luaL_optinteger(L, 4, 1);
|
||||
}
|
||||
|
||||
if (!sel || !sel->map) {
|
||||
nhl_error(L, "Selection setpoint error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x == -1 && y == -1)
|
||||
coord = SP_COORD_PACK_RANDOM(0);
|
||||
else
|
||||
coord = SP_COORD_PACK(x,y);
|
||||
get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, coord);
|
||||
selection_setpoint(x, y, sel, val);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local value = selection.get(sel, x, y); */
|
||||
static int
|
||||
l_selection_getpoint(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
schar x = (schar) luaL_checkinteger(L, 2);
|
||||
schar y = (schar) luaL_checkinteger(L, 3);
|
||||
int val;
|
||||
long coord;
|
||||
|
||||
if (x == -1 && y == -1)
|
||||
coord = SP_COORD_PACK_RANDOM(0);
|
||||
else
|
||||
coord = SP_COORD_PACK(x,y);
|
||||
get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, coord);
|
||||
|
||||
val = selection_getpoint(x, y, sel);
|
||||
lua_settop(L, 0);
|
||||
lua_pushnumber(L, val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.negate(sel); */
|
||||
/* local s = selection.negate(); */
|
||||
static int
|
||||
l_selection_not(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel;
|
||||
|
||||
if (argc == 0)
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
selection_not(sel);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local sel = selection.area(4,5, 40,10) & selection.rect(7,8, 60,14); */
|
||||
static int
|
||||
l_selection_and(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int x,y;
|
||||
struct selectionvar *sela = l_selection_check(L, 1);
|
||||
struct selectionvar *selb = l_selection_check(L, 2);
|
||||
|
||||
for (x = 0; x < sela->wid; x++)
|
||||
for (y = 0; y < sela->hei; y++) {
|
||||
int val = selection_getpoint(x, y, sela) & selection_getpoint(x, y, selb);
|
||||
selection_setpoint(x, y, sela, val);
|
||||
}
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local sel = selection.area(4,5, 40,10) | selection.rect(7,8, 60,14); */
|
||||
static int
|
||||
l_selection_or(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int x,y;
|
||||
struct selectionvar *sela = l_selection_check(L, 1);
|
||||
struct selectionvar *selb = l_selection_check(L, 2);
|
||||
|
||||
for (x = 0; x < sela->wid; x++)
|
||||
for (y = 0; y < sela->hei; y++) {
|
||||
int val = selection_getpoint(x, y, sela) | selection_getpoint(x, y, selb);
|
||||
selection_setpoint(x, y, sela, val);
|
||||
}
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local sel = selection.area(4,5, 40,10) ~ selection.rect(7,8, 60,14); */
|
||||
static int
|
||||
l_selection_xor(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int x,y;
|
||||
struct selectionvar *sela = l_selection_check(L, 1);
|
||||
struct selectionvar *selb = l_selection_check(L, 2);
|
||||
|
||||
for (x = 0; x < sela->wid; x++)
|
||||
for (y = 0; y < sela->hei; y++) {
|
||||
int val = selection_getpoint(x, y, sela) ^ selection_getpoint(x, y, selb);
|
||||
selection_setpoint(x, y, sela, val);
|
||||
}
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* local s = selection.percentage(sel, 50); */
|
||||
static int
|
||||
l_selection_filter_percent(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
int p = (int) luaL_checkinteger(L, 2);
|
||||
selection_filter_percent(sel, p);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local x,y = selection.rndcoord(sel); */
|
||||
/* local x,y = selection.rndcoord(sel, 1); */
|
||||
static int
|
||||
l_selection_rndcoord(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
int removeit = (int) luaL_optinteger(L, 2, 0);
|
||||
schar x, y;
|
||||
selection_rndcoord(sel, &x, &y, removeit);
|
||||
update_croom();
|
||||
if (g.coder && g.coder->croom) {
|
||||
x -= g.coder->croom->lx;
|
||||
y -= g.coder->croom->ly;
|
||||
} else {
|
||||
x -= g.xstart;
|
||||
y -= g.ystart;
|
||||
}
|
||||
lua_settop(L, 0);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* local s = selection.line(sel, x1,y1, x2,y2); */
|
||||
/* local s = selection.line(x1,y1, x2,y2); */
|
||||
/* s:line(x1,y1, x2,y2); */
|
||||
static int
|
||||
l_selection_line(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel;
|
||||
schar x1;
|
||||
schar y1;
|
||||
schar x2;
|
||||
schar y2;
|
||||
|
||||
if (argc == 4) {
|
||||
(void) l_selection_new(L);
|
||||
x1 = (schar) luaL_checkinteger(L, 1);
|
||||
y1 = (schar) luaL_checkinteger(L, 2);
|
||||
x2 = (schar) luaL_checkinteger(L, 3);
|
||||
y2 = (schar) luaL_checkinteger(L, 4);
|
||||
sel = l_selection_check(L, 5);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
} else {
|
||||
sel = l_selection_check(L, 1);
|
||||
x1 = (schar) luaL_checkinteger(L, 2);
|
||||
y1 = (schar) luaL_checkinteger(L, 3);
|
||||
x2 = (schar) luaL_checkinteger(L, 4);
|
||||
y2 = (schar) luaL_checkinteger(L, 5);
|
||||
}
|
||||
|
||||
get_location_coord(&x1, &y1, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1,y1));
|
||||
get_location_coord(&x2, &y2, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2,y2));
|
||||
|
||||
selection_do_line(x1,y1,x2,y2, sel);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.rect(sel, x1,y1, x2,y2); */
|
||||
static int
|
||||
l_selection_rect(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel;
|
||||
schar x1;
|
||||
schar y1;
|
||||
schar x2;
|
||||
schar y2;
|
||||
|
||||
if (argc == 4) {
|
||||
(void) l_selection_new(L);
|
||||
x1 = (schar) luaL_checkinteger(L, 1);
|
||||
y1 = (schar) luaL_checkinteger(L, 2);
|
||||
x2 = (schar) luaL_checkinteger(L, 3);
|
||||
y2 = (schar) luaL_checkinteger(L, 4);
|
||||
sel = l_selection_check(L, 5);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
} else {
|
||||
sel = l_selection_check(L, 1);
|
||||
x1 = (schar) luaL_checkinteger(L, 2);
|
||||
y1 = (schar) luaL_checkinteger(L, 3);
|
||||
x2 = (schar) luaL_checkinteger(L, 4);
|
||||
y2 = (schar) luaL_checkinteger(L, 5);
|
||||
}
|
||||
|
||||
get_location_coord(&x1, &y1, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1,y1));
|
||||
get_location_coord(&x2, &y2, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2,y2));
|
||||
|
||||
selection_do_line(x1,y1,x2,y1, sel);
|
||||
selection_do_line(x1,y1,x1,y2, sel);
|
||||
selection_do_line(x2,y1,x2,y2, sel);
|
||||
selection_do_line(x1,y2,x2,y2, sel);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.fillrect(sel, x1,y1, x2,y2); */
|
||||
/* local s = selection.fillrect(x1,y1, x2,y2); */
|
||||
/* s:fillrect(x1,y1, x2,y2); */
|
||||
/* selection.area(x1,y1, x2,y2); */
|
||||
static int
|
||||
l_selection_fillrect(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel;
|
||||
int y;
|
||||
schar x1;
|
||||
schar y1;
|
||||
schar x2;
|
||||
schar y2;
|
||||
|
||||
if (argc == 4) {
|
||||
(void) l_selection_new(L);
|
||||
x1 = (schar) luaL_checkinteger(L, 1);
|
||||
y1 = (schar) luaL_checkinteger(L, 2);
|
||||
x2 = (schar) luaL_checkinteger(L, 3);
|
||||
y2 = (schar) luaL_checkinteger(L, 4);
|
||||
sel = l_selection_check(L, 5);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
lua_remove(L, 1);
|
||||
} else {
|
||||
sel = l_selection_check(L, 1);
|
||||
x1 = (schar) luaL_checkinteger(L, 2);
|
||||
y1 = (schar) luaL_checkinteger(L, 3);
|
||||
x2 = (schar) luaL_checkinteger(L, 4);
|
||||
y2 = (schar) luaL_checkinteger(L, 5);
|
||||
}
|
||||
|
||||
get_location_coord(&x1, &y1, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1,y1));
|
||||
get_location_coord(&x2, &y2, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2,y2));
|
||||
|
||||
if (x1 == x2) {
|
||||
for (y = y1; y <= y2; y++)
|
||||
selection_setpoint(x1, y, sel, 1);
|
||||
} else {
|
||||
for (y = y1; y <= y2; y++)
|
||||
selection_do_line(x1,y,x2,y, sel);
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.randline(sel, x1,y1, x2,y2, roughness); */
|
||||
/* local s = selection.randline(x1,y1, x2,y2, roughness); */
|
||||
/* TODO: selection.randline(x1,y1, x2,y2, roughness); */
|
||||
/* TODO: selection.randline({x1,y1}, {x2,y2}, roughness); */
|
||||
static int
|
||||
l_selection_randline(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel = (struct selectionvar *) 0;
|
||||
/* REVIEW: initializer added */
|
||||
schar x1, y1, x2, y2;
|
||||
int roughness = 7;
|
||||
|
||||
if (argc == 6) {
|
||||
sel = l_selection_check(L, 1);
|
||||
x1 = (schar) luaL_checkinteger(L, 2);
|
||||
y1 = (schar) luaL_checkinteger(L, 3);
|
||||
x2 = (schar) luaL_checkinteger(L, 4);
|
||||
y2 = (schar) luaL_checkinteger(L, 5);
|
||||
roughness = (int) luaL_checkinteger(L, 6);
|
||||
} else if (argc == 5 && lua_type(L, 1) == LUA_TNUMBER) {
|
||||
x1 = (schar) luaL_checkinteger(L, 1);
|
||||
y1 = (schar) luaL_checkinteger(L, 2);
|
||||
x2 = (schar) luaL_checkinteger(L, 3);
|
||||
y2 = (schar) luaL_checkinteger(L, 4);
|
||||
roughness = (int) luaL_checkinteger(L, 5);
|
||||
lua_pop(L, 5);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
}
|
||||
|
||||
get_location_coord(&x1, &y1, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x1,y1));
|
||||
get_location_coord(&x2, &y2, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x2,y2));
|
||||
|
||||
selection_do_randline(x1,y1, x2,y2, roughness, 12, sel);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.grow(sel); */
|
||||
/* local s = selection.grow(sel, "north"); */
|
||||
static int
|
||||
l_selection_grow(L)
|
||||
lua_State *L;
|
||||
{
|
||||
const char *const growdirs[] = { "all", "random", "north", "west", "east", "south", NULL };
|
||||
const int growdirs2i[] = { W_ANY, -1, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0 };
|
||||
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
int dir = growdirs2i[luaL_checkoption(L, 2, "all", growdirs)];
|
||||
selection_do_grow(sel, dir);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* local s = selection.filter_mapchar(sel, mapchar, lit); */
|
||||
static int
|
||||
l_selection_filter_mapchar(L)
|
||||
lua_State *L;
|
||||
{
|
||||
struct selectionvar *sel = l_selection_check(L, 1);
|
||||
char *mapchr = dupstr(luaL_checkstring(L, 2));
|
||||
xchar typ = check_mapchr(mapchr);
|
||||
int lit = (int) luaL_optinteger(L, 3, -2); /* TODO: special lit values */
|
||||
struct selectionvar *tmp = selection_filter_mapchar(sel, typ, lit);
|
||||
|
||||
if (typ == INVALID_TYPE)
|
||||
nhl_error(L, "Erroneous map char");
|
||||
|
||||
if (sel->map)
|
||||
free(sel->map);
|
||||
sel->map = tmp->map;
|
||||
if (tmp)
|
||||
free(tmp);
|
||||
if (mapchr)
|
||||
free(mapchr);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* local s = selection.floodfill(sel, x, y); */
|
||||
/* local s = selection.floodfill(x,y); */
|
||||
static int
|
||||
l_selection_flood(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel = (struct selectionvar *) 0;
|
||||
/* REVIEW: initializer added */
|
||||
schar x, y;
|
||||
|
||||
if (argc == 3) {
|
||||
sel = l_selection_check(L, 1);
|
||||
x = (schar) luaL_checkinteger(L, 2);
|
||||
y = (schar) luaL_checkinteger(L, 3);
|
||||
} else if (argc == 2) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
lua_pop(L, 2);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
} else {
|
||||
nhl_error(L, "wrong parameters");
|
||||
}
|
||||
|
||||
get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y));
|
||||
|
||||
if (isok(x,y)) {
|
||||
set_floodfillchk_match_under(levl[x][y].typ);
|
||||
selection_floodfill(sel, x, y, FALSE);
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* local s = selection.circle(x,y, radius); */
|
||||
/* local s = selection.circle(x, y, radius, filled); */
|
||||
/* local s = selection.circle(sel, x, y, radius); */
|
||||
/* local s = selection.circle(sel, x, y, radius, filled); */
|
||||
static int
|
||||
l_selection_circle(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel = (struct selectionvar *) 0;
|
||||
/* REVIEW: initializer added */
|
||||
schar x, y;
|
||||
int r, filled = 0;
|
||||
|
||||
if (argc == 3) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
r = (int) luaL_checkinteger(L, 3);
|
||||
lua_pop(L, 3);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
filled = 0;
|
||||
} else if (argc == 4 && lua_type(L, 1) == LUA_TNUMBER) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
r = (int) luaL_checkinteger(L, 3);
|
||||
filled = (int) luaL_checkinteger(L, 4); /* TODO: boolean*/
|
||||
lua_pop(L, 4);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
} else if (argc == 4 || argc == 5) {
|
||||
sel = l_selection_check(L, 1);
|
||||
x = (schar) luaL_checkinteger(L, 2);
|
||||
y = (schar) luaL_checkinteger(L, 3);
|
||||
r = (int) luaL_checkinteger(L, 4);
|
||||
filled = (int) luaL_optinteger(L, 5, 0); /* TODO: boolean */
|
||||
} else {
|
||||
nhl_error(L, "wrong parameters");
|
||||
}
|
||||
|
||||
get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y));
|
||||
|
||||
selection_do_ellipse(sel, x,y, r,r, !filled);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* local s = selection.ellipse(x, y, radius1, radius2); */
|
||||
/* local s = selection.ellipse(x, y, radius1, radius2, filled); */
|
||||
/* local s = selection.ellipse(sel, x, y, radius1, radius2); */
|
||||
/* local s = selection.ellipse(sel, x, y, radius1, radius2, filled); */
|
||||
static int
|
||||
l_selection_ellipse(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
struct selectionvar *sel = (struct selectionvar *) 0;
|
||||
/* REVIEW: initializer added */
|
||||
schar x, y;
|
||||
int r1, r2, filled = 0;
|
||||
|
||||
if (argc == 4) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
r1 = (int) luaL_checkinteger(L, 3);
|
||||
r2 = (int) luaL_checkinteger(L, 4);
|
||||
lua_pop(L, 4);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
filled = 0;
|
||||
} else if (argc == 5 && lua_type(L, 1) == LUA_TNUMBER) {
|
||||
x = (schar) luaL_checkinteger(L, 1);
|
||||
y = (schar) luaL_checkinteger(L, 2);
|
||||
r1 = (int) luaL_checkinteger(L, 3);
|
||||
r2 = (int) luaL_checkinteger(L, 4);
|
||||
filled = (int) luaL_optinteger(L, 5, 0); /* TODO: boolean */
|
||||
lua_pop(L, 5);
|
||||
(void) l_selection_new(L);
|
||||
sel = l_selection_check(L, 1);
|
||||
} else if (argc == 5 || argc == 6) {
|
||||
sel = l_selection_check(L, 1);
|
||||
x = (schar) luaL_checkinteger(L, 2);
|
||||
y = (schar) luaL_checkinteger(L, 3);
|
||||
r1 = (int) luaL_checkinteger(L, 4);
|
||||
r2 = (int) luaL_checkinteger(L, 5);
|
||||
filled = (int) luaL_optinteger(L, 6, 0); /* TODO: boolean */
|
||||
} else {
|
||||
nhl_error(L, "wrong parameters");
|
||||
}
|
||||
|
||||
get_location_coord(&x, &y, ANY_LOC, g.coder ? g.coder->croom : NULL, SP_COORD_PACK(x,y));
|
||||
|
||||
selection_do_ellipse(sel, x,y, r1,r2, !filled);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const struct luaL_Reg l_selection_methods[] = {
|
||||
{ "new", l_selection_new },
|
||||
{ "clone", l_selection_clone },
|
||||
{ "get", l_selection_getpoint },
|
||||
{ "set", l_selection_setpoint },
|
||||
{ "negate", l_selection_not },
|
||||
{ "percentage", l_selection_filter_percent },
|
||||
{ "rndcoord", l_selection_rndcoord },
|
||||
{ "line", l_selection_line },
|
||||
{ "randline", l_selection_randline },
|
||||
{ "rect", l_selection_rect },
|
||||
{ "fillrect", l_selection_fillrect },
|
||||
{ "area", l_selection_fillrect },
|
||||
{ "grow", l_selection_grow },
|
||||
{ "filter_mapchar", l_selection_filter_mapchar },
|
||||
{ "floodfill", l_selection_flood },
|
||||
{ "circle", l_selection_circle },
|
||||
{ "ellipse", l_selection_ellipse },
|
||||
/* TODO:
|
||||
{ "gradient", l_selection_gradient },
|
||||
{ "iterate", l_selection_iterate },
|
||||
*/
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg l_selection_meta[] = {
|
||||
{ "__gc", l_selection_gc },
|
||||
{ "__unm", l_selection_not },
|
||||
{ "__band", l_selection_and },
|
||||
{ "__bor", l_selection_or },
|
||||
{ "__bxor", l_selection_xor },
|
||||
{ "__bnot", l_selection_not },
|
||||
/* TODO: http://lua-users.org/wiki/MetatableEvents
|
||||
{ "__add", l_selection_add },
|
||||
{ "__sub", l_selection_sub },
|
||||
{ "__ipairs", l_selection_ipairs },
|
||||
*/
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int
|
||||
l_selection_register(L)
|
||||
lua_State *L;
|
||||
{
|
||||
int lib_id, meta_id;
|
||||
|
||||
/* newclass = {} */
|
||||
lua_createtable(L, 0, 0);
|
||||
lib_id = lua_gettop(L);
|
||||
|
||||
/* metatable = {} */
|
||||
luaL_newmetatable(L, "selection");
|
||||
meta_id = lua_gettop(L);
|
||||
luaL_setfuncs(L, l_selection_meta, 0);
|
||||
|
||||
/* metatable.__index = _methods */
|
||||
luaL_newlib(L, l_selection_methods);
|
||||
lua_setfield(L, meta_id, "__index");
|
||||
|
||||
/* metatable.__metatable = _meta */
|
||||
luaL_newlib(L, l_selection_meta);
|
||||
lua_setfield(L, meta_id, "__metatable");
|
||||
|
||||
/* class.__metatable = metatable */
|
||||
lua_setmetatable(L, lib_id);
|
||||
|
||||
/* _G["selection"] = newclass */
|
||||
lua_setglobal(L, "selection");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user