2012-08-04 10:54:37 +00:00
|
|
|
// game lib for lua
|
|
|
|
|
|
|
|
#include "g_lua.h"
|
|
|
|
|
|
|
|
#ifdef G_LUA
|
|
|
|
// game.Print(string text)
|
|
|
|
// Prints text to the server console
|
|
|
|
static int Game_Print(lua_State *L) {
|
|
|
|
int i;
|
|
|
|
char buf[MAX_STRING_CHARS];
|
|
|
|
int n = lua_gettop(L);
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
lua_getglobal(L, "tostring");
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_Print - start: ");
|
|
|
|
|
2012-11-10 01:42:10 +00:00
|
|
|
for(i = 1; i <= n; i++)
|
2012-08-04 10:54:37 +00:00
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
lua_pushvalue(L, -1);
|
|
|
|
lua_pushvalue(L, i);
|
|
|
|
lua_call(L, 1, 1);
|
|
|
|
s = lua_tostring(L, -1);
|
|
|
|
|
|
|
|
if(s == NULL)
|
|
|
|
{
|
|
|
|
LUA_DEBUG("Game_Print - return: no string");
|
|
|
|
return luaL_error(L, "'tostring' must return a string to 'print'");
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_strcat(buf, sizeof(buf), s);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
G_Printf("%s\n", buf);
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_Print - return: printed string");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.CenterPrint(integer clientNum, string text)
|
|
|
|
// Prints text to the center of the screen of the client with client number clientNum.
|
|
|
|
// If clientNum is -1 the text gets printed for all clients.
|
|
|
|
static int Game_CenterPrint(lua_State *L) {
|
|
|
|
int i;
|
|
|
|
char buf[MAX_STRING_CHARS];
|
|
|
|
int n = lua_gettop(L);
|
|
|
|
int clNum = luaL_checknumber(L, 1);
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
lua_getglobal(L, "tostring");
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_CenterPrint - start: ");
|
|
|
|
|
|
|
|
for(i = 1; i < n; i++)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
lua_pushvalue(L, -1);
|
|
|
|
lua_pushvalue(L, i);
|
|
|
|
lua_call(L, 1, 1);
|
|
|
|
s = lua_tostring(L, 2);
|
|
|
|
|
|
|
|
if(s == NULL)
|
|
|
|
{
|
|
|
|
LUA_DEBUG("Game_CenterPrint - return: no string");
|
|
|
|
return luaL_error(L, "'tostring' must return a string to 'print'");
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_strcat(buf, sizeof(buf), s);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
trap_SendServerCommand(clNum, va("servercprint \"" S_COLOR_WHITE "%s\n\"", buf));
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_CenterPrint - return: printed string");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.ClientPrint(integer clientNum, string text)
|
|
|
|
// Prints text to the clients console that has the client number clientNum.
|
|
|
|
// If clientNum is -1 the text gets printed to all clients consoles.
|
|
|
|
static int Game_ClientPrint(lua_State *L) {
|
|
|
|
int i;
|
|
|
|
char buf[MAX_STRING_CHARS];
|
|
|
|
int n = lua_gettop(L);
|
|
|
|
int clNum = luaL_checknumber(L, 1);
|
|
|
|
gentity_t *player;
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
lua_getglobal(L, "tostring");
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_ClientPrint - start: ");
|
|
|
|
|
|
|
|
for(i = 1; i < n; i++) {
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
lua_pushvalue(L, -1);
|
|
|
|
lua_pushvalue(L, i);
|
|
|
|
lua_call(L, 1, 1);
|
|
|
|
s = lua_tostring(L, 2);
|
|
|
|
|
|
|
|
if(s == NULL)
|
|
|
|
{
|
|
|
|
LUA_DEBUG("Game_ClientPrint - return: no string");
|
|
|
|
return luaL_error(L, "'tostring' must return a string to 'print'");
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_strcat(buf, sizeof(buf), s);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(clNum != -1) {
|
|
|
|
player = &g_entities[clNum];
|
|
|
|
if(player && player->client)
|
|
|
|
G_PrintfClient(player, "%s", buf);
|
|
|
|
} else
|
|
|
|
G_PrintfClientAll("%s", buf);
|
|
|
|
LUA_DEBUG("Game_ClientPrint - return: printed string");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.MessagePrint(integer clientNum, string text)
|
|
|
|
// Prints text to the lower right corner of the screen of the client with client number clientNum.
|
|
|
|
// If clientNum is -1 the text gets printed for all clients.
|
|
|
|
static int Game_MessagePrint(lua_State *L) {
|
|
|
|
int i;
|
|
|
|
char buf[MAX_STRING_CHARS];
|
|
|
|
int n = lua_gettop(L);
|
|
|
|
int clNum = luaL_checknumber(L, 1);
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
lua_getglobal(L, "tostring");
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_MessagePrint - start: ");
|
|
|
|
|
|
|
|
for(i = 1; i < n; i++)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
lua_pushvalue(L, -1);
|
|
|
|
lua_pushvalue(L, i);
|
|
|
|
lua_call(L, 1, 1);
|
|
|
|
s = lua_tostring(L, 2);
|
|
|
|
|
|
|
|
if(s == NULL)
|
|
|
|
{
|
|
|
|
LUA_DEBUG("Game_MessagePrint - return: no string");
|
|
|
|
return luaL_error(L, "'tostring' must return a string to 'print'");
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_strcat(buf, sizeof(buf), s);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
trap_SendServerCommand(clNum, va("servermsg \"" S_COLOR_WHITE "%s\n\"", buf));
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_MessagePrint - return: printed string");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.SetGlobal(string name, value)
|
|
|
|
// Sets a global Lua variable which is called name to value.
|
|
|
|
// Creates a new global variable if a variable of name does not exist.
|
|
|
|
// value can be of any type.
|
|
|
|
static int Game_SetGlobal(lua_State *L) {
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
name = (char *)luaL_checkstring(L, 1);
|
|
|
|
|
|
|
|
if(!name) return 0;
|
|
|
|
|
|
|
|
lua_pushvalue(L, 2);
|
|
|
|
lua_setglobal(L, name);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.GetGlobal(string name)
|
|
|
|
// Returns the value of the global variable name.
|
|
|
|
// Returns nil if the variable does not exist.
|
|
|
|
static int Game_GetGlobal(lua_State *L) {
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
name = (char *)luaL_checkstring(L, 1);
|
|
|
|
|
|
|
|
if(!name) return 0;
|
|
|
|
|
|
|
|
lua_getglobal(L, name);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Alert-Stuff... I don't know. I feel like removing this and stick to the entity spawning and setup.
|
|
|
|
// game.AlertSetup(entity ent, string greentarget, string yellowtarget, string redtarget, string bluetarget,
|
|
|
|
// string greensound, string yellowsound, string redsound, string bluesound, integer mode)
|
|
|
|
static int Game_AlertSetup(lua_State *L) {
|
|
|
|
|
|
|
|
if(luaAlertState) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
luaAlertState = (luaAlertState_t *)malloc(sizeof(luaAlertState_t));
|
|
|
|
if(!luaAlertState) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
luaAlertState->targets[0] = (char *)luaL_checkstring(L, 1);
|
|
|
|
luaAlertState->targets[1] = (char *)luaL_checkstring(L, 2);
|
|
|
|
luaAlertState->targets[2] = (char *)luaL_checkstring(L, 3);
|
|
|
|
luaAlertState->targets[3] = (char *)luaL_checkstring(L, 4);
|
|
|
|
|
|
|
|
luaAlertState->sounds[0] = (char *)luaL_checkstring(L, 5);
|
|
|
|
luaAlertState->sounds[1] = (char *)luaL_checkstring(L, 6);
|
|
|
|
luaAlertState->sounds[2] = (char *)luaL_checkstring(L, 7);
|
|
|
|
luaAlertState->sounds[3] = (char *)luaL_checkstring(L, 8);
|
|
|
|
|
|
|
|
luaAlertState->mode = luaL_checkint(L, 9);
|
|
|
|
|
|
|
|
luaAlertState->cond = 0;
|
|
|
|
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int Game_AlertAddShader(lua_State *L) {
|
|
|
|
int cond;
|
|
|
|
char *shader;
|
|
|
|
|
|
|
|
if(!luaAlertState) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cond = luaL_checkint(L, 1);
|
|
|
|
if(cond < 0 || cond > 3) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
shader = (char *)luaL_checkstring(L, 2);
|
|
|
|
if(!shader || (strlen(shader) + 1) > MAX_QPATH) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!luaAlertState->shaders[cond]) {
|
|
|
|
luaAlertState->shaders[cond] = (char *)malloc(sizeof(char) * (strlen(shader) + 1));
|
|
|
|
if(!luaAlertState->shaders[cond]) {
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
strncpy(luaAlertState->shaders[cond], shader, sizeof(luaAlertState->shaders[cond]));
|
|
|
|
} else {
|
|
|
|
void *tmp = realloc(luaAlertState->shaders[cond], sizeof(char) * (strlen(luaAlertState->shaders[cond]) +
|
|
|
|
strlen(shader) + 1));
|
|
|
|
if(!tmp){
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
luaAlertState->shaders[cond] = tmp;
|
2012-09-10 10:55:24 +00:00
|
|
|
Com_sprintf(luaAlertState->shaders[cond], sizeof(luaAlertState->shaders[cond]), "%s\n%s", luaAlertState->shaders[cond], shader);
|
2012-08-04 10:54:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.Alert(entity ent, integer target, boolean silent)
|
|
|
|
static int Game_Alert(lua_State *L) {
|
|
|
|
/*lent_t *lent;
|
|
|
|
int current, target;
|
|
|
|
qboolean silent;*/
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// game.LevelTime()
|
|
|
|
// Returns the current level time in milliseconds.
|
|
|
|
static int Game_Leveltime(lua_State * L)
|
|
|
|
{
|
|
|
|
lua_pushinteger(L, level.time);
|
|
|
|
|
|
|
|
LUA_DEBUG("Game_Leveltime - start/return: leveltime=%d", level.time);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int Game_Damage(lua_State *L) {
|
|
|
|
lent_t *lent;
|
|
|
|
gentity_t *targ = NULL, *inflictor = NULL, *attacker = NULL;
|
|
|
|
vec_t *dir = NULL, *point = NULL;
|
|
|
|
int damage = 0, dflags = 0, mod = 0;
|
|
|
|
|
|
|
|
lent = Lua_GetEntity(L, 1);
|
|
|
|
if(!lent || !lent->e) return 1;
|
|
|
|
targ = lent->e;
|
|
|
|
if(!lua_isnil(L, 2)) {
|
|
|
|
lent = Lua_GetEntity(L, 2);
|
|
|
|
if(lent && lent->e)
|
|
|
|
inflictor = lent->e;
|
|
|
|
}
|
|
|
|
if(!lua_isnil(L, 3)) {
|
|
|
|
lent = Lua_GetEntity(L, 3);
|
|
|
|
if(lent && lent->e)
|
|
|
|
attacker = lent->e;
|
|
|
|
}
|
|
|
|
if(!lua_isnil(L, 4))
|
|
|
|
dir = Lua_GetVector(L, 4);
|
|
|
|
if(!lua_isnil(L, 5))
|
|
|
|
point = Lua_GetVector(L, 5);
|
|
|
|
damage = (int)luaL_checknumber(L, 6);
|
|
|
|
dflags = (int)luaL_checknumber(L, 7);
|
|
|
|
mod = (int)luaL_checknumber(L, 8);
|
|
|
|
|
|
|
|
G_Damage(targ, inflictor, attacker, dir, point, damage, dflags, mod);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int Game_Repair(lua_State *L) {
|
|
|
|
lent_t *lent;
|
|
|
|
float rate;
|
|
|
|
|
|
|
|
lent = Lua_GetEntity(L, 1);
|
|
|
|
if(!lent || !lent->e) return 1;
|
|
|
|
|
|
|
|
rate = (float)luaL_checknumber(L, 2);
|
|
|
|
|
|
|
|
G_Repair(lent->e, NULL, rate); // FIXME ... trance ent?
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg lib_game[] = {
|
|
|
|
{"Damage", Game_Damage},
|
|
|
|
{"Repair", Game_Repair},
|
|
|
|
{"Print", Game_Print},
|
|
|
|
{"MessagePrint", Game_MessagePrint},
|
|
|
|
{"CenterPrint", Game_CenterPrint},
|
|
|
|
{"ClientPrint", Game_ClientPrint},
|
|
|
|
{"GetTime", Game_Leveltime},
|
|
|
|
|
|
|
|
{"AlertSetup", Game_AlertSetup},
|
|
|
|
{"AlertAddShader", Game_AlertAddShader},
|
|
|
|
{"Alert", Game_Alert},
|
|
|
|
|
|
|
|
{"SetGlobal", Game_SetGlobal},
|
|
|
|
{"GetGlobal", Game_GetGlobal},
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
int Luaopen_Game(lua_State *L) {
|
|
|
|
luaL_register(L, "game", lib_game);
|
|
|
|
lua_pushliteral(L, "_GAMEVERSION");
|
|
|
|
lua_pushliteral(L, GAMEVERSION);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|