Lephisto/src/llua.c

298 lines
6.4 KiB
C

#include "lauxlib.h"
#include "log.h"
#include "lephisto.h"
#include "rng.h"
#include "ltime.h"
#include "toolkit.h"
#include "space.h"
#include "land.h"
#include "lluadef.h"
#include "llua.h"
// -- Libraries. --
// Lephisto.
static int lephisto_lang(lua_State* L);
static const luaL_reg lephisto_methods[] = {
{ "lang", lephisto_lang },
{ 0, 0 }
};
// Space.
static int space_getPlanet(lua_State* L);
static int space_getSystem(lua_State* L);
static int space_landName(lua_State* L);
static int space_systemName(lua_State* L);
static int space_jumpDist(lua_State* L);
static const luaL_reg space_methods[] = {
{ "getPlanet", space_getPlanet },
{ "getSystem", space_getSystem },
{ "landName", space_landName },
{ "system", space_systemName },
{ "jumpDist", space_jumpDist },
{ 0, 0 }
};
// Time.
static int time_get(lua_State* L);
static int time_str(lua_State* L);
static int time_units(lua_State* L);
static const luaL_reg time_methods[] = {
{ "get", time_get },
{ "str", time_str },
{ "units", time_units },
{0, 0}
};
// RND.
static int rnd_int(lua_State*L);
static const luaL_reg rnd_methods[] = {
{ "int", rnd_int },
{ 0, 0 }
};
// Toolkit.
static int tk_msg(lua_State* L);
static int tk_yesno(lua_State* L);
static int tk_input(lua_State* L);
static const luaL_reg tk_methods[] = {
{ "msg", tk_msg },
{ "yesno", tk_yesno },
{ "input", tk_input },
{ 0, 0 }
};
// Individual libraries.
int lua_loadLephisto(lua_State* L) {
luaL_register(L, "lephisto", lephisto_methods);
return 0;
}
int lua_loadSpace(lua_State* L, int readonly) {
(void)readonly;
luaL_register(L, "space", space_methods);
return 0;
}
int lua_loadTime(lua_State* L, int readonly) {
(void)readonly;
luaL_register(L, "time", time_methods);
return 0;
}
int lua_loadRnd(lua_State* L) {
luaL_register(L, "rnd", rnd_methods);
return 0;
}
int lua_loadTk(lua_State* L) {
luaL_register(L, "tk", tk_methods);
return 0;
}
// -- Lephisto. --
static int lephisto_lang(lua_State* L) {
// TODO: multilanguage stuff.
lua_pushstring(L, "en");
return 1;
}
// -- Space. --
static int space_getPlanet(lua_State* L) {
int i;
int *factions;
int nfactions;
char** planets;
int nplanets;
char* rndplanet;
if(lua_gettop(L) == 0) {
// Get random planet.
lua_pushstring(L, space_getRndPlanet());
return 1;
}
else if(lua_isnumber(L, -1)) {
i = lua_tonumber(L, -1);
planets = space_getFactionPlanet(&nplanets, &i, 1);
}
else if(lua_isstring(L, -1)) {
i = faction_get((char*) lua_tostring(L, -1));
planets = space_getFactionPlanet(&nplanets, &i, 1);
}
else if(lua_istable(L, -1)) {
// Load up the table.
lua_pushnil(L);
nfactions = (int) lua_gettop(L);
factions = malloc(sizeof(int) * nfactions);
i = 0;
while(lua_next(L, -2) != 0) {
factions[i++] = (int) lua_tonumber(L, -1);
lua_pop(L, 1);
}
// Get the planets.
planets = space_getFactionPlanet(&nplanets, factions, nfactions);
free(factions);
}
else return 0; // Nothing useful.
// Choose random planet.
if(nplanets == 0) {
// No suitable planet.
free(planets);
return 0;
}
rndplanet = planets[RNG(0, nplanets-1)];
free(planets);
lua_pushstring(L, rndplanet);
return 1;
}
static int space_getSystem(lua_State* L) {
LLUA_MIN_ARGS(1);
char* planetname, *system;
if(lua_isstring(L, -1)) planetname = (char*) lua_tostring(L, -1);
else return 0;
system = planet_getSystem(planetname);
lua_pushstring(L, system);
return 1;
}
static int space_landName(lua_State* L) {
if(landed) {
lua_pushstring(L, land_planet->name);
return 1;
}
return 0;
}
static int space_systemName(lua_State* L) {
lua_pushstring(L, cur_system->name);
return 1;
}
static int space_jumpDist(lua_State* L) {
LLUA_MIN_ARGS(1);
StarSystem** s;
int jumps;
char* start, *goal;
if(lua_isstring(L, -1))
start = (char*)lua_tostring(L, -1);
else LLUA_INVALID_PARAMETER();
if((lua_gettop(L) > 1) && lua_isstring(L, -2))
goal = (char*) lua_tostring(L, -2);
else
goal = cur_system->name;
s = system_getJumpPath(&jumps, start, goal);
free(s);
lua_pushnumber(L, jumps);
return 1;
}
// -- Time. --
static int time_get(lua_State* L) {
lua_pushnumber(L, ltime_get());
return 1;
}
static int time_str(lua_State* L) {
char* lt;
if((lua_gettop(L) > 0) && (lua_isnumber(L, -1)))
lt = ltime_pretty((unsigned int) lua_tonumber(L, -1));
else
lt = ltime_pretty(ltime_get());
lua_pushstring(L, lt);
free(lt);
return 1;
}
static int time_units(lua_State* L) {
if((lua_gettop(L) > 0) && (lua_isnumber(L, -1)))
lua_pushnumber(L, (unsigned int) lua_tonumber(L, -1) * LTIME_UNIT_LENGTH);
else
lua_pushnumber(L, LTIME_UNIT_LENGTH);
return 1;
}
// -- RND. --
static int rnd_int(lua_State* L) {
int o;
o = lua_gettop(L);
if(o == 0) lua_pushnumber(L, RNGF()); // Random double o <= x <= 1.
else if(o == 1) {
// Random int 0 <= x <= param.
if(lua_isnumber(L, -1))
lua_pushnumber(L, RNG(0, (int)lua_tonumber(L, -1)));
else return 0;
}
else if(o >= 2) {
// Random int param 1 <= x <= param 2.
if(lua_isnumber(L, -1) && lua_isnumber(L, -2))
lua_pushnumber(L, RNG((int)lua_tonumber(L, -2), (int)lua_tonumber(L, -1)));
else return 0;
}
else return 0;
// Unless it's returned 0 already it'll always return param.
return 1;
}
// -- Toolkit. --
static int tk_msg(lua_State* L) {
char* title, *str;
LLUA_MIN_ARGS(2);
if(lua_isstring(L, -2)) title = (char*) lua_tostring(L, -2);
else return 0;
if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1);
else return 0;
dialogue_msg(title, str);
return 0;
}
static int tk_yesno(lua_State* L) {
int ret;
char* title, *str;
LLUA_MIN_ARGS(2);
if(lua_isstring(L, -2)) title = (char*) lua_tostring(L, -2);
else return 0;
if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1);
else return 0;
ret = dialogue_YesNo(title, str);
lua_pushboolean(L, ret);
return 1;
}
static int tk_input(lua_State* L) {
char* title, *str;
int min, max;
LLUA_MIN_ARGS(4);
if(lua_isstring(L, -4)) title = (char*) lua_tostring(L, -4);
else return 0;
if(lua_isnumber(L, -3)) min = (int) lua_tonumber(L, -3);
else return 0;
if(lua_isnumber(L, -2)) max = (int) lua_tonumber(L, -2);
else return 0;
if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1);
else return 0;
dialogue_input(title, min, max, str);
return 0;
}