b3011579f0c93c159dbb56a9cbd200bc621c1c35
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/>.
32 PScriptContext
= Plua_State
;
33 PScriptProc
= lua_CFunction
;
36 gScriptCtx
: PScriptContext
= nil;
37 gScriptInit
: Boolean = False;
39 function g_Scripts_Init(): Boolean;
40 procedure g_Scripts_Reset(What
: Integer);
41 function g_Scripts_ProcExec(PName
: string; const Args
: array of const; Namespace
: string = ''): Integer;
42 function g_Scripts_ProcExists(PName
: string): Boolean;
43 function g_Scripts_ProcInstall(PName
: string; PPtr
: PScriptProc
): Boolean;
44 function g_Scripts_Load(Text: string): Boolean;
45 procedure g_Scripts_Free();
50 SysUtils
, g_console
, g_scriptprocs
;
53 POpenFunc
= function(L
: Plua_State
): LongBool; cdecl;
60 LUA_LIBS
: array [0..3] of TLuaReg
= (
61 (name
: ''; func
: luaopen_base
),
62 (name
: LUA_TABLIBNAME
; func
: luaopen_table
),
63 (name
: LUA_STRLINAME
; func
: luaopen_string
), // STRLINAME is actually a typo in fpc's lua module
64 (name
: LUA_MATHLIBNAME
; func
: luaopen_math
)
67 function LuaInstallGameFuncs(): Boolean;
71 if not g_Scripts_ProcInstall('conprint', SP_Lua_ConPrint
) then Exit
;
72 if not g_Scripts_ProcInstall('message', SP_Lua_Message
) then Exit
;
73 if not g_Scripts_ProcInstall('sound', SP_Lua_PlaySound
) then Exit
;
74 if not g_Scripts_ProcInstall('get_gamemode', SP_Lua_GetGameMode
) then Exit
;
75 if not g_Scripts_ProcInstall('get_gametype', SP_Lua_GetGameType
) then Exit
;
76 if not g_Scripts_ProcInstall('get_time', SP_Lua_GetTime
) then Exit
;
78 if not g_Scripts_ProcInstall('player_get_keys', SP_Lua_PlayerGetKeys
) then Exit
;
79 if not g_Scripts_ProcInstall('player_get_armor', SP_Lua_PlayerGetArmor
) then Exit
;
80 if not g_Scripts_ProcInstall('player_get_score', SP_Lua_PlayerGetScore
) then Exit
;
81 if not g_Scripts_ProcInstall('player_get_name', SP_Lua_PlayerGetName
) then Exit
;
82 if not g_Scripts_ProcInstall('player_get_team', SP_Lua_PlayerGetTeam
) then Exit
;
84 if not g_Scripts_ProcInstall('uid_get_health', SP_Lua_ActorGetHealth
) then Exit
;
85 if not g_Scripts_ProcInstall('uid_get_pos', SP_Lua_ActorGetPos
) then Exit
;
86 if not g_Scripts_ProcInstall('uid_get_state', SP_Lua_ActorGetState
) then Exit
;
87 if not g_Scripts_ProcInstall('uid_get_type', SP_Lua_ActorGetType
) then Exit
;
88 if not g_Scripts_ProcInstall('uid_nearest', SP_Lua_ActorNearest
) then Exit
;
89 if not g_Scripts_ProcInstall('uid_farthest', SP_Lua_ActorFarthest
) then Exit
;
90 if not g_Scripts_ProcInstall('uid_damage', SP_Lua_ActorDamage
) then Exit
;
91 if not g_Scripts_ProcInstall('uid_push', SP_Lua_ActorPush
) then Exit
;
92 if not g_Scripts_ProcInstall('uid_teleport', SP_Lua_ActorTeleport
) then Exit
;
94 if not g_Scripts_ProcInstall('trigger_get_enabled', SP_Lua_TriggerGetEnabled
) then Exit
;
95 if not g_Scripts_ProcInstall('trigger_set_enabled', SP_Lua_TriggerSetEnabled
) then Exit
;
96 if not g_Scripts_ProcInstall('trigger_activate', SP_Lua_TriggerActivate
) then Exit
;
97 if not g_Scripts_ProcInstall('trigger_get_pos', SP_Lua_TriggerGetPos
) then Exit
;
98 if not g_Scripts_ProcInstall('trigger_set_pos', SP_Lua_TriggerSetPos
) then Exit
;
100 if not g_Scripts_ProcInstall('panel_get_type', SP_Lua_PanelGetType
) then Exit
;
101 if not g_Scripts_ProcInstall('panel_get_pos', SP_Lua_PanelGetPos
) then Exit
;
102 if not g_Scripts_ProcInstall('panel_get_size', SP_Lua_PanelGetSize
) then Exit
;
103 if not g_Scripts_ProcInstall('panel_set_pos', SP_Lua_PanelSetPos
) then Exit
;
104 if not g_Scripts_ProcInstall('panel_switch_texture', SP_Lua_PanelSwitchTexture
) then Exit
;
106 if not g_Scripts_ProcInstall('door_get_open', SP_Lua_DoorGetState
) then Exit
;
107 if not g_Scripts_ProcInstall('door_close', SP_Lua_DoorClose
) then Exit
;
108 if not g_Scripts_ProcInstall('door_close_trap', SP_Lua_DoorCloseTrap
) then Exit
;
109 if not g_Scripts_ProcInstall('door_open', SP_Lua_DoorOpen
) then Exit
;
110 if not g_Scripts_ProcInstall('door_toggle', SP_Lua_DoorToggle
) then Exit
;
111 if not g_Scripts_ProcInstall('lift_get_dir', SP_Lua_LiftGetDir
) then Exit
;
112 if not g_Scripts_ProcInstall('lift_set_dir', SP_Lua_LiftSetDir
) then Exit
;
114 if not g_Scripts_ProcInstall('spawn_item', SP_Lua_SpawnItem
) then Exit
;
115 if not g_Scripts_ProcInstall('spawn_shot', SP_Lua_SpawnShot
) then Exit
;
116 if not g_Scripts_ProcInstall('spawn_effect', SP_Lua_SpawnEffect
) then Exit
;
117 if not g_Scripts_ProcInstall('spawn_monster', SP_Lua_SpawnMonster
) then Exit
;
122 function g_Scripts_Init(): Boolean;
127 if gScriptInit
then Exit
;
129 gScriptCtx
:= luaL_newstate();
130 if gScriptCtx
= nil then Exit
;
132 // don't open all the libs
133 for i
:= 0 to High(LUA_LIBS
) do
135 //lua_pushcfunction(gScriptCtx, LUA_LIBS[i].func);
136 lua_pushstring(gScriptCtx
, LUA_LIBS
[i
].name
);
137 //lua_call(gScriptCtx, 1, 0);
138 LUA_LIBS
[i
].func(gScriptCtx
);
141 // create a table for game-related functions
142 lua_newtable(gScriptCtx
);
143 lua_setglobal(gScriptCtx
, 'game');
145 // create game-related tables
146 g_Scripts_Reset(RESET_ALL
);
149 // try to install game-related shit
150 if not LuaInstallGameFuncs() then
152 g_Console_Add('SCRIPT: Could not init game callbacks');
153 lua_close(gScriptCtx
);
155 gScriptInit
:= False;
162 // TODO: maybe actually put some fields into these?
163 procedure g_Scripts_Reset(What
: Integer);
165 if not gScriptInit
then Exit
;
166 if What
in [RESET_ALL
, RESET_SRV
] then
168 lua_newtable(gScriptCtx
);
169 lua_setglobal(gScriptCtx
, 'srv');
171 if What
in [RESET_ALL
, RESET_WAD
] then
173 lua_newtable(gScriptCtx
);
174 lua_setglobal(gScriptCtx
, 'wad');
176 if What
in [RESET_ALL
, RESET_MAP
] then
178 lua_newtable(gScriptCtx
);
179 lua_setglobal(gScriptCtx
, 'map');
183 function g_Scripts_ProcInstall(PName
: string; PPtr
: PScriptProc
): Boolean;
186 if not gScriptInit
then Exit
;
188 if g_Scripts_ProcExists(PName
) then
190 g_Console_Add('SCRIPT: ProcInstall(' + PName
+ '): function already exists');
194 lua_getglobal(gScriptCtx
, 'game');
195 lua_pushstring(gScriptCtx
, PName
);
196 lua_pushcfunction(gScriptCtx
, PPtr
);
197 lua_settable(gScriptCtx
, -3);
198 lua_setglobal(gScriptCtx
, 'game');
203 function g_Scripts_ProcExists(PName
: string): Boolean;
206 if not gScriptInit
then Exit
;
208 lua_getglobal(gScriptCtx
, 'game');
209 lua_pushstring(gScriptCtx
, PName
);
210 lua_gettable(gScriptCtx
, -2);
212 if lua_isfunction(gScriptCtx
, -1) then
216 function g_Scripts_ProcExec(PName
: string; const Args
: array of const; Namespace
: string = ''): Integer;
221 if not gScriptInit
then Exit
;
223 if Namespace
= '' then
224 lua_getglobal(gScriptCtx
, PChar(PName
))
227 lua_getglobal(gScriptCtx
, PChar(Namespace
));
228 lua_pushstring(gScriptCtx
, PName
);
229 lua_gettable(gScriptCtx
, -2);
232 if not lua_isfunction(gScriptCtx
, -1) then
234 g_Console_Add('SCRIPT: ProcExec(' + Namespace
+ '.' + PName
+ ') error: no such function');
238 for i
:= 0 to High(Args
) do
242 vtInteger
: lua_pushinteger(gScriptCtx
, vInteger
);
243 vtBoolean
: lua_pushboolean(gScriptCtx
, vBoolean
);
244 vtString
: lua_pushstring(gScriptCtx
, vString
^);
245 vtAnsiString
: lua_pushstring(gScriptCtx
, PAnsiString(vAnsiString
)^);
246 vtExtended
: lua_pushnumber(gScriptCtx
, vExtended
^);
250 if lua_pcall(gScriptCtx
, Length(Args
), 1, 0) <> 0 then
252 g_Console_Add('SCRIPT: ProcExec(' + Namespace
+ '.' + PName
+ ') error: ' + lua_tostring(gScriptCtx
, -1));
257 if lua_isnumber(gScriptCtx
, -1) then
259 Result
:= lua_tointeger(gScriptCtx
, -1);
260 lua_pop(gScriptCtx
, 1);
264 function g_Scripts_Load(Text: string): Boolean;
267 if not gScriptInit
then Exit
;
269 if lua_dostring(gScriptCtx
, PChar(Text)) <> 0 then
271 g_Console_Add('SCRIPT: Load() error: ' + lua_tostring(gScriptCtx
, -1));
278 procedure g_Scripts_Free();
280 if not gScriptInit
then Exit
;
281 lua_close(gScriptCtx
);
282 gScriptInit
:= False;