1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 RESET_SRV
= RESET_SRV_BIT
or RESET_WAD_BIT
or RESET_MAP_BIT
;
30 RESET_WAD
= RESET_WAD_BIT
or RESET_MAP_BIT
;
31 RESET_MAP
= RESET_MAP_BIT
;
35 PScriptContext
= Plua_State
;
36 PScriptProc
= lua_CFunction
;
39 gScriptCtx
: PScriptContext
= nil;
40 gScriptInit
: Boolean = False;
42 function g_Scripts_Init(): Boolean;
43 procedure g_Scripts_Reset(What
: Byte);
44 function g_Scripts_ProcExec(PName
: string; const Args
: array of const; Namespace
: string = ''): Integer;
45 function g_Scripts_ProcExists(PName
: string): Boolean;
46 function g_Scripts_ProcInstall(PName
: string; PPtr
: PScriptProc
): Boolean;
47 function g_Scripts_Load(Text: string): Boolean;
48 procedure g_Scripts_Free();
53 SysUtils
, g_console
, g_scriptprocs
;
62 LUA_LIBS
: array [0..6] of TLuaReg
= (
63 (name
: ''; func
: luaopen_base
),
64 (name
: LUA_LOADLIBNAME
; func
: luaopen_package
),
65 (name
: LUA_TABLIBNAME
; func
: luaopen_table
),
66 (name
: LUA_STRLIBNAME
; func
: luaopen_string
),
67 (name
: LUA_MATHLIBNAME
; func
: luaopen_math
),
68 (name
: LUA_OSLIBNAME
; func
: luaopen_os
), // TODO: something to restrict these two
69 (name
: LUA_IOLIBNAME
; func
: luaopen_io
)
72 function LuaInstallGameFuncs(): Boolean;
76 if not g_Scripts_ProcInstall('conprint', SP_Lua_ConPrint
) then Exit
;
77 if not g_Scripts_ProcInstall('message', SP_Lua_Message
) then Exit
;
78 if not g_Scripts_ProcInstall('sound', SP_Lua_PlaySound
) then Exit
;
79 if not g_Scripts_ProcInstall('get_gamemode', SP_Lua_GetGameMode
) then Exit
;
80 if not g_Scripts_ProcInstall('get_gametype', SP_Lua_GetGameType
) then Exit
;
81 if not g_Scripts_ProcInstall('get_time', SP_Lua_GetTime
) then Exit
;
83 if not g_Scripts_ProcInstall('player_get_keys', SP_Lua_PlayerGetKeys
) then Exit
;
84 if not g_Scripts_ProcInstall('player_get_armor', SP_Lua_PlayerGetArmor
) then Exit
;
85 if not g_Scripts_ProcInstall('player_get_score', SP_Lua_PlayerGetScore
) then Exit
;
86 if not g_Scripts_ProcInstall('player_get_name', SP_Lua_PlayerGetName
) then Exit
;
87 if not g_Scripts_ProcInstall('player_get_team', SP_Lua_PlayerGetTeam
) then Exit
;
89 if not g_Scripts_ProcInstall('uid_get_health', SP_Lua_ActorGetHealth
) then Exit
;
90 if not g_Scripts_ProcInstall('uid_get_pos', SP_Lua_ActorGetPos
) then Exit
;
91 if not g_Scripts_ProcInstall('uid_get_state', SP_Lua_ActorGetState
) then Exit
;
92 if not g_Scripts_ProcInstall('uid_get_type', SP_Lua_ActorGetType
) then Exit
;
93 if not g_Scripts_ProcInstall('uid_nearest', SP_Lua_ActorNearest
) then Exit
;
94 if not g_Scripts_ProcInstall('uid_farthest', SP_Lua_ActorFarthest
) then Exit
;
95 if not g_Scripts_ProcInstall('uid_damage', SP_Lua_ActorDamage
) then Exit
;
96 if not g_Scripts_ProcInstall('uid_push', SP_Lua_ActorPush
) then Exit
;
97 if not g_Scripts_ProcInstall('uid_teleport', SP_Lua_ActorTeleport
) then Exit
;
99 if not g_Scripts_ProcInstall('trigger_get_enabled', SP_Lua_TriggerGetEnabled
) then Exit
;
100 if not g_Scripts_ProcInstall('trigger_set_enabled', SP_Lua_TriggerSetEnabled
) then Exit
;
101 if not g_Scripts_ProcInstall('trigger_activate', SP_Lua_TriggerActivate
) then Exit
;
102 if not g_Scripts_ProcInstall('trigger_get_pos', SP_Lua_TriggerGetPos
) then Exit
;
103 if not g_Scripts_ProcInstall('trigger_set_pos', SP_Lua_TriggerSetPos
) then Exit
;
105 if not g_Scripts_ProcInstall('panel_get_type', SP_Lua_PanelGetType
) then Exit
;
106 if not g_Scripts_ProcInstall('panel_get_pos', SP_Lua_PanelGetPos
) then Exit
;
107 if not g_Scripts_ProcInstall('panel_get_size', SP_Lua_PanelGetSize
) then Exit
;
108 if not g_Scripts_ProcInstall('panel_set_pos', SP_Lua_PanelSetPos
) then Exit
;
109 if not g_Scripts_ProcInstall('panel_switch_texture', SP_Lua_PanelSwitchTexture
) then Exit
;
111 if not g_Scripts_ProcInstall('door_get_open', SP_Lua_DoorGetState
) then Exit
;
112 if not g_Scripts_ProcInstall('door_close', SP_Lua_DoorClose
) then Exit
;
113 if not g_Scripts_ProcInstall('door_close_trap', SP_Lua_DoorCloseTrap
) then Exit
;
114 if not g_Scripts_ProcInstall('door_open', SP_Lua_DoorOpen
) then Exit
;
115 if not g_Scripts_ProcInstall('door_toggle', SP_Lua_DoorToggle
) then Exit
;
116 if not g_Scripts_ProcInstall('lift_get_dir', SP_Lua_LiftGetDir
) then Exit
;
117 if not g_Scripts_ProcInstall('lift_set_dir', SP_Lua_LiftSetDir
) then Exit
;
119 if not g_Scripts_ProcInstall('spawn_item', SP_Lua_SpawnItem
) then Exit
;
120 if not g_Scripts_ProcInstall('spawn_shot', SP_Lua_SpawnShot
) then Exit
;
121 if not g_Scripts_ProcInstall('spawn_effect', SP_Lua_SpawnEffect
) then Exit
;
122 if not g_Scripts_ProcInstall('spawn_monster', SP_Lua_SpawnMonster
) then Exit
;
127 function g_Scripts_Init(): Boolean;
132 if gScriptInit
then Exit
;
134 gScriptCtx
:= luaL_newstate();
135 if gScriptCtx
= nil then Exit
;
137 // don't open all the libs
138 for i
:= 0 to High(LUA_LIBS
) do
140 lua_pushcfunction(gScriptCtx
, LUA_LIBS
[i
].func
);
141 lua_pushstring(gScriptCtx
, LUA_LIBS
[i
].name
);
142 lua_call(gScriptCtx
, 1, 0);
145 // create a table for game-related functions
146 lua_newtable(gScriptCtx
);
147 lua_setglobal(gScriptCtx
, 'game');
149 // create game-related tables
150 g_Scripts_Reset(RESET_ALL
);
153 // try to install game-related shit
154 if not LuaInstallGameFuncs() then
156 g_Console_Add('SCRIPT: Could not init game callbacks');
157 lua_close(gScriptCtx
);
159 gScriptInit
:= False;
166 // TODO: maybe actually put some fields into these?
167 procedure g_Scripts_Reset(What
: Byte);
169 if not gScriptInit
then Exit
;
170 if LongBool(What
and RESET_SRV_BIT
) then
172 lua_newtable(gScriptCtx
);
173 lua_setglobal(gScriptCtx
, 'srv');
175 if LongBool(What
and RESET_WAD_BIT
) then
177 lua_newtable(gScriptCtx
);
178 lua_setglobal(gScriptCtx
, 'wad');
180 if LongBool(What
and RESET_MAP_BIT
) then
182 lua_newtable(gScriptCtx
);
183 lua_setglobal(gScriptCtx
, 'map');
185 // disable io and os modules on any kind of reset
186 lua_pushnil(gScriptCtx
);
187 lua_pushnil(gScriptCtx
);
188 lua_setglobal(gScriptCtx
, 'os');
189 lua_setglobal(gScriptCtx
, 'io');
193 function g_Scripts_ProcInstall(PName
: string; PPtr
: PScriptProc
): Boolean;
196 if not gScriptInit
then Exit
;
198 if g_Scripts_ProcExists(PName
) then
200 g_Console_Add('SCRIPT: ProcInstall(' + PName
+ '): function already exists');
204 lua_getglobal(gScriptCtx
, 'game');
205 lua_pushstring(gScriptCtx
, PName
);
206 lua_pushcfunction(gScriptCtx
, PPtr
);
207 lua_settable(gScriptCtx
, -3);
208 lua_setglobal(gScriptCtx
, 'game');
213 function g_Scripts_ProcExists(PName
: string): Boolean;
216 if not gScriptInit
then Exit
;
218 lua_getglobal(gScriptCtx
, 'game');
219 lua_pushstring(gScriptCtx
, PName
);
220 lua_gettable(gScriptCtx
, -2);
222 if lua_isfunction(gScriptCtx
, -1) then
226 function g_Scripts_ProcExec(PName
: string; const Args
: array of const; Namespace
: string = ''): Integer;
231 if not gScriptInit
then Exit
;
233 if Namespace
= '' then
234 lua_getglobal(gScriptCtx
, PChar(PName
))
237 lua_getglobal(gScriptCtx
, PChar(Namespace
));
238 lua_pushstring(gScriptCtx
, PName
);
239 lua_gettable(gScriptCtx
, -2);
242 if not lua_isfunction(gScriptCtx
, -1) then
244 g_Console_Add('SCRIPT: ProcExec(' + Namespace
+ '.' + PName
+ ') error: no such function');
248 for i
:= 0 to High(Args
) do
252 vtInteger
: lua_pushinteger(gScriptCtx
, vInteger
);
253 vtBoolean
: lua_pushboolean(gScriptCtx
, vBoolean
);
254 vtString
: lua_pushstring(gScriptCtx
, vString
^);
255 vtAnsiString
: lua_pushstring(gScriptCtx
, PAnsiString(vAnsiString
)^);
256 vtExtended
: lua_pushnumber(gScriptCtx
, vExtended
^);
260 if lua_pcall(gScriptCtx
, Length(Args
), 1, 0) <> 0 then
262 g_Console_Add('SCRIPT: ProcExec(' + Namespace
+ '.' + PName
+ ') error: ' + lua_tostring(gScriptCtx
, -1));
267 if lua_isnumber(gScriptCtx
, -1) then
269 Result
:= lua_tointeger(gScriptCtx
, -1);
270 lua_pop(gScriptCtx
, 1);
274 function g_Scripts_Load(Text: string): Boolean;
277 if not gScriptInit
then Exit
;
279 if lua_dostring(gScriptCtx
, PChar(Text)) <> 0 then
281 g_Console_Add('SCRIPT: Load() error: ' + lua_tostring(gScriptCtx
, -1));
288 procedure g_Scripts_Free();
290 if not gScriptInit
then Exit
;
291 lua_close(gScriptCtx
);
292 gScriptInit
:= False;