root/src/game/lua_game.c @ 117:8021fffe95f1

Revision 117:8021fffe95f1, 5.7 kB (checked in by mdoison@…, 2 years ago)

* Fix a bug : a null entity must not be able call a build callback
* Fix a bug : player package crash game at startup
* Add game hooks
* Add a time() function in luagame api

Line 
1/*
2===========================================================================
3Copyright (C) 2006 Robert Beckebans <trebor_7@users.sourceforge.net>
4
5This file is part of Tremulous source code.
6
7Tremulous source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12Tremulous source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with Tremulous source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20===========================================================================
21*/
22// lua_game.c -- qagame library for Lua
23
24
25#ifdef USE_LUA
26#include <lua.h>
27#include <lauxlib.h>
28#include <lualib.h>
29#endif
30
31#include "g_local.h"
32
33int G_CallGameHooks(const char *event)
34{
35#ifdef USE_LUA
36  lua_State *L = g_luaState;
37  int ret;
38
39  lua_getglobal(L, "game");
40
41  lua_pushnil(L);
42
43  ret = G_CallHooks(event);
44
45  lua_pop(L, 2);
46
47  return ret;
48#else
49  return 1;
50#endif
51}
52
53#ifdef USE_LUA
54static int game_AddHook(lua_State *L)
55{
56  lua_getglobal(L, "game");
57  G_AddHook(L, lua_tostring(L, -3));
58
59  return 0;
60}
61
62static int game_Time(lua_State * L)
63{
64        lua_pushinteger(L, level.time - level.startTime);
65
66        return 1;
67}
68
69static int game_StartTime(lua_State * L)
70{
71        lua_pushinteger(L, level.startTime);
72
73        return 1;
74}
75
76static int game_Print(lua_State * L)
77{
78        int             i;
79        char            buf[MAX_STRING_CHARS];
80        int             n = lua_gettop(L);      // number of arguments
81
82        memset(buf, 0, sizeof(buf));
83
84        lua_getglobal(L, "tostring");
85        for(i = 1; i <= n; i++)
86        {
87                const char     *s;
88
89                lua_pushvalue(L, -1);   // function to be called
90                lua_pushvalue(L, i);    // value to print
91                lua_call(L, 1, 1);
92                s = lua_tostring(L, -1);        // get result
93
94                if(s == NULL)
95                        return luaL_error(L, "`tostring' must return a string to `print'");
96
97                Q_strcat(buf, sizeof(buf), s);
98
99                lua_pop(L, 1);                  // pop result
100        }
101
102        G_Printf("%s\n", buf);
103        return 0;
104}
105
106static int game_Cp(lua_State * L)
107{
108        int             i;
109        char            buf[MAX_STRING_CHARS];
110        int             n = lua_gettop(L);      // number of arguments
111
112        memset(buf, 0, sizeof(buf));
113
114        lua_getglobal(L, "tostring");
115        for(i = 1; i <= n; i++)
116        {
117                const char     *s;
118
119                lua_pushvalue(L, -1);   // function to be called
120                lua_pushvalue(L, i);    // value to print
121                lua_call(L, 1, 1);
122                s = lua_tostring(L, -1);        // get result
123
124                if(s == NULL)
125                        return luaL_error(L, "`tostring' must return a string to `print'");
126
127                Q_strcat(buf, sizeof(buf), s);
128
129                lua_pop(L, 1);                  // pop result
130        }
131
132        trap_SendServerCommand(-1, va("cp \"" S_COLOR_WHITE "%s\n\"", buf));
133        return 0;
134}
135
136static int game_Exec(lua_State * L)
137{
138        const char *s;
139
140        if(lua_gettop(L) != 1)
141                return luaL_error(L, "game.Exec: function take 1 argument");
142
143        s = lua_tostring(L, -1);
144        if(s == NULL)
145                return luaL_error(L, "game.Exec: invalid arguments");
146
147        trap_SendServerCommand(-1, s);
148
149        return 0;
150}
151
152static int game_CvarInteger(lua_State *L)
153{
154        const char *cvar;
155        lua_Integer lval;
156
157        if(lua_gettop(L) != 1)
158                return luaL_error(L, "game.CvarInt: function take 1 argument");
159
160        cvar = lua_tostring(L, -1);
161        if(cvar == NULL)
162                return luaL_error(L, "game.CvarInt: invalid arguments");
163
164        lua_pop(L, 1);
165
166        lval = trap_Cvar_VariableIntegerValue(cvar);
167        lua_pushinteger(L, lval);
168
169        return 1;
170}
171
172static int game_CvarString(lua_State *L)
173{
174        const char *cvar;
175        char buf[MAX_STRING_CHARS];
176
177        if(lua_gettop(L) != 1)
178                return luaL_error(L, "game.CvarString: function take 1 argument");
179
180        cvar = lua_tostring(L, -1);
181        if(cvar == NULL)
182                return luaL_error(L, "game.CvarString: invalid arguments");
183
184        lua_pop(L, 1);
185
186        trap_Cvar_VariableStringBuffer(cvar, buf, sizeof(buf));
187
188        lua_pushstring(L, buf);
189       
190        return 1;
191}
192
193static int game_CvarFloat(lua_State *L)
194{
195        const char *cvar;
196        lua_Number lval;
197
198        if(lua_gettop(L) != 1)
199                return luaL_error(L, "game.CvarFloat: function take 1 argument");
200
201        cvar = lua_tostring(L, -1);
202        if(cvar == NULL)
203                return luaL_error(L, "game.CvarFloat: invalid arguments");
204
205        lua_pop(L, 1);
206
207        lval = (lua_Number) trap_Cvar_VariableValue(cvar);
208
209        lua_pushvalue(L, lval);
210
211        return 1;
212}
213
214static int game_CvarSet(lua_State *L)
215{
216        const char *cvar;
217        const char *value;
218
219        if(lua_gettop(L) != 2)
220                return luaL_error(L, "game.CvarSet: function take 2 arguments");
221
222        cvar = lua_tostring(L, -2);
223
224        lua_getglobal(L, "tostring");
225        lua_pushvalue(L, -2);
226        lua_call(L, 1, 1);
227        value = lua_tostring(L, -1);
228
229        if(value == NULL)
230                return luaL_error(L, "game.CvarSet: function take 2 arguments");
231
232        trap_Cvar_Set(cvar, value);
233
234        return 0;
235}
236
237static const luaL_reg gamelib[] = {
238        {"AddHook", game_AddHook},
239        {"Print", game_Print},
240        {"Cp", game_Cp},
241        {"Exec", game_Exec},
242        {"CvarInteger", game_CvarInteger},
243        {"CvarString", game_CvarString},
244        {"CvarFloat", game_CvarFloat},
245        {"CvarSet", game_CvarSet},
246        {"Time", game_Time},
247        {"StartTime", game_StartTime},
248        {NULL, NULL}
249};
250
251int luaopen_game(lua_State * L)
252{
253        luaL_register(L, "game", gamelib);
254
255        lua_newtable(L);
256
257        G_CreateHooksTable(L, "on_think");
258        G_CreateHooksTable(L, "on_init");
259        G_CreateHooksTable(L, "on_exit");
260        G_CreateHooksTable(L, "on_shutdown");
261        G_CreateHooksTable(L, "on_player_connect");
262        G_CreateHooksTable(L, "on_player_disconnect");
263        G_CreateHooksTable(L, "on_player_begin");
264        G_CreateHooksTable(L, "on_stage_up");
265        G_CreateHooksTable(L, "on_sudden_death");
266
267        lua_setfield(L, -2, "hooks");
268
269        lua_pushliteral(L, "_GAMEVERSION");
270        lua_pushliteral(L, GAME_VERSION);
271
272        return 1;
273}
274#endif
Note: See TracBrowser for help on using the browser.