server/src/bind_gmtool.c

253 lines
6.0 KiB
C
Raw Normal View History

2010-08-08 10:06:34 +02:00
#include <platform.h>
#include <curses.h>
2010-08-08 10:06:34 +02:00
#include "bind_gmtool.h"
#include "gmtool.h"
#include "gmtool_structs.h"
2010-08-08 10:06:34 +02:00
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <modules/autoseed.h>
#include <util/log.h>
#include <tolua.h>
#include <string.h>
2011-03-07 08:02:35 +01:00
static int tolua_run_mapper(lua_State * L)
2010-08-08 10:06:34 +02:00
{
run_mapper();
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_highlight_region(lua_State * L)
2010-08-08 10:06:34 +02:00
{
region *r = (region *)tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
int select = tolua_toboolean(L, 2, 0);
highlight_region(r, select);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_current_region(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
map_region *mr =
cursor_region(&current_state->display, &current_state->cursor);
tolua_pushusertype(L, mr ? mr->r : NULL, TOLUA_CAST "region");
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_select_coordinate(lua_State * L)
2010-08-08 10:06:34 +02:00
{
int nx = (int)tolua_tonumber(L, 1, 0);
int ny = (int)tolua_tonumber(L, 2, 0);
int select = tolua_toboolean(L, 3, 0);
if (current_state) {
select_coordinate(current_state->selected, nx, ny, select);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_select_region(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
region *r = tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
int select = tolua_toboolean(L, 2, 0);
if (current_state && r) {
select_coordinate(current_state->selected, r->x, r->y, select);
}
return 0;
}
typedef struct tag_iterator {
2011-03-07 08:02:35 +01:00
selection *list;
tag *node;
region *r;
2010-08-08 10:06:34 +02:00
int hash;
} tag_iterator;
2011-03-07 08:02:35 +01:00
void tag_advance(tag_iterator * iter)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
while (iter->hash != MAXTHASH) {
2010-08-08 10:06:34 +02:00
if (iter->node) {
iter->node = iter->node->nexthash;
}
while (!iter->node && iter->hash != MAXTHASH) {
if (++iter->hash != MAXTHASH) {
iter->node = iter->list->tags[iter->hash];
}
}
if (iter->node) {
iter->r = findregion(iter->node->coord.x, iter->node->coord.y);
if (iter->r) {
break;
}
}
}
}
2011-03-07 08:02:35 +01:00
void tag_rewind(tag_iterator * iter)
2010-08-08 10:06:34 +02:00
{
if (iter->list) {
iter->r = NULL;
iter->node = iter->list->tags[0];
iter->hash = 0;
if (iter->node) {
iter->r = findregion(iter->node->coord.x, iter->node->coord.y);
}
if (!iter->r) {
tag_advance(iter);
}
} else {
iter->node = 0;
iter->hash = MAXTHASH;
}
}
2011-03-07 08:02:35 +01:00
static int tolua_tags_next(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
tag_iterator *iter = (tag_iterator *) lua_touserdata(L, lua_upvalueindex(1));
2010-08-08 10:06:34 +02:00
if (iter->node) {
2011-03-07 08:02:35 +01:00
tolua_pushusertype(L, (void *)iter->r, TOLUA_CAST "region");
2010-08-08 10:06:34 +02:00
tag_advance(iter);
return 1;
2011-03-07 08:02:35 +01:00
} else {
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
}
2011-03-07 08:02:35 +01:00
static int tolua_selected_regions(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
tag_iterator *iter =
(tag_iterator *) lua_newuserdata(L, sizeof(tag_iterator));
2010-08-08 10:06:34 +02:00
luaL_getmetatable(L, "tag_iterator");
lua_setmetatable(L, -2);
iter->list = current_state->selected;
tag_rewind(iter);
lua_pushcclosure(L, tolua_tags_next, 1);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_state_open(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unused_arg(L);
2010-08-08 10:06:34 +02:00
state_open();
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_state_close(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unused_arg(L);
2010-08-08 10:06:34 +02:00
state_close(current_state);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_make_island(lua_State * L)
2010-08-08 10:06:34 +02:00
{
int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0);
int s = (int)tolua_tonumber(L, 3, 0);
int n = (int)tolua_tonumber(L, 4, s / 3);
n = build_island_e3(x, y, n, s);
tolua_pushnumber(L, n);
return 1;
}
static int paint_handle;
2011-03-07 08:02:35 +01:00
static struct lua_State *paint_state;
static void lua_paint_info(struct window *wnd, const struct state *st)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
struct lua_State *L = paint_state;
2010-08-08 10:06:34 +02:00
int nx = st->cursor.x, ny = st->cursor.y;
pnormalize(&nx, &ny, st->cursor.pl);
lua_rawgeti(L, LUA_REGISTRYINDEX, paint_handle);
tolua_pushnumber(L, nx);
tolua_pushnumber(L, ny);
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("paint function failed: %s\n", error);
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
tolua_error(L, TOLUA_CAST "event handler call failed", NULL);
} else {
2011-03-07 08:02:35 +01:00
const char *result = lua_tostring(L, -1);
WINDOW *win = wnd->handle;
int size = getmaxx(win) - 2;
int line = 0, maxline = getmaxy(win) - 2;
const char *str = result;
2010-08-08 10:06:34 +02:00
wxborder(win);
2011-03-07 08:02:35 +01:00
while (*str && line < maxline) {
const char *end = strchr(str, '\n');
if (!end)
break;
2010-08-08 10:06:34 +02:00
else {
2011-03-07 08:02:35 +01:00
size_t len = end - str;
2014-03-16 05:03:17 +01:00
int bytes = _min((int)len, size);
2010-08-08 10:06:34 +02:00
mvwaddnstr(win, line++, 1, str, bytes);
wclrtoeol(win);
str = end + 1;
}
}
}
}
2011-03-07 08:02:35 +01:00
static int tolua_set_display(lua_State * L)
2010-08-08 10:06:34 +02:00
{
int type = lua_type(L, 1);
2011-03-07 08:02:35 +01:00
if (type == LUA_TFUNCTION) {
2010-08-08 10:06:34 +02:00
lua_pushvalue(L, 1);
paint_handle = luaL_ref(L, LUA_REGISTRYINDEX);
paint_state = L;
set_info_function(&lua_paint_info);
} else {
set_info_function(NULL);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_make_block(lua_State * L)
2010-08-08 10:06:34 +02:00
{
int x = (int)tolua_tonumber(L, 1, 0);
int y = (int)tolua_tonumber(L, 2, 0);
int r = (int)tolua_tonumber(L, 3, 6);
2011-03-07 08:02:35 +01:00
const char *str = tolua_tostring(L, 4, TOLUA_CAST "ocean");
const struct terrain_type *ter = get_terrain(str);
2010-08-08 10:06:34 +02:00
make_block(x, y, r, ter);
return 0;
}
2011-03-07 08:02:35 +01:00
void tolua_gmtool_open(lua_State * L)
2010-08-08 10:06:34 +02:00
{
/* register user types */
tolua_usertype(L, TOLUA_CAST "tag_iterator");
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
tolua_module(L, TOLUA_CAST "gmtool", 0);
tolua_beginmodule(L, TOLUA_CAST "gmtool");
{
tolua_function(L, TOLUA_CAST "open", &tolua_state_open);
tolua_function(L, TOLUA_CAST "close", &tolua_state_close);
tolua_function(L, TOLUA_CAST "editor", &tolua_run_mapper);
tolua_function(L, TOLUA_CAST "get_selection", &tolua_selected_regions);
tolua_function(L, TOLUA_CAST "get_cursor", &tolua_current_region);
tolua_function(L, TOLUA_CAST "highlight", &tolua_highlight_region);
tolua_function(L, TOLUA_CAST "select", &tolua_select_region);
tolua_function(L, TOLUA_CAST "select_at", &tolua_select_coordinate);
tolua_function(L, TOLUA_CAST "set_display", &tolua_set_display);
tolua_function(L, TOLUA_CAST "make_block", &tolua_make_block);
tolua_function(L, TOLUA_CAST "make_island", &tolua_make_island);
}
tolua_endmodule(L);
}
tolua_endmodule(L);
}