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/>.
24 function SP_Lua_ConPrint(L
: PScriptContext
): Integer; cdecl;
25 function SP_Lua_PlaySound(L
: PScriptContext
): Integer; cdecl;
26 function SP_Lua_Message(L
: PScriptContext
): Integer; cdecl;
27 function SP_Lua_GetGameMode(L
: PScriptContext
): Integer; cdecl;
28 function SP_Lua_GetGameType(L
: PScriptContext
): Integer; cdecl;
29 function SP_Lua_GetTime(L
: PScriptContext
): Integer; cdecl;
31 function SP_Lua_PlayerGetKeys(L
: PScriptContext
): Integer; cdecl;
32 function SP_Lua_PlayerGetArmor(L
: PScriptContext
): Integer; cdecl;
33 function SP_Lua_PlayerGetTeam(L
: PScriptContext
): Integer; cdecl;
34 function SP_Lua_PlayerGetScore(L
: PScriptContext
): Integer; cdecl;
35 function SP_Lua_PlayerGetName(L
: PScriptContext
): Integer; cdecl;
37 function SP_Lua_ActorGetPos(L
: PScriptContext
): Integer; cdecl;
38 function SP_Lua_ActorGetHealth(L
: PScriptContext
): Integer; cdecl;
39 function SP_Lua_ActorGetState(L
: PScriptContext
): Integer; cdecl;
40 function SP_Lua_ActorGetType(L
: PScriptContext
): Integer; cdecl;
41 function SP_Lua_ActorNearest(L
: PScriptContext
): Integer; cdecl;
42 function SP_Lua_ActorFarthest(L
: PScriptContext
): Integer; cdecl;
43 function SP_Lua_ActorDamage(L
: PScriptContext
): Integer; cdecl;
44 function SP_Lua_ActorTeleport(L
: PScriptContext
): Integer; cdecl;
45 function SP_Lua_ActorPush(L
: PScriptContext
): Integer; cdecl;
47 function SP_Lua_TriggerActivate(L
: PScriptContext
): Integer; cdecl;
48 function SP_Lua_TriggerGetEnabled(L
: PScriptContext
): Integer; cdecl;
49 function SP_Lua_TriggerSetEnabled(L
: PScriptContext
): Integer; cdecl;
50 function SP_Lua_TriggerGetPos(L
: PScriptContext
): Integer; cdecl;
51 function SP_Lua_TriggerSetPos(L
: PScriptContext
): Integer; cdecl;
53 function SP_Lua_PanelGetType(L
: PScriptContext
): Integer; cdecl;
54 function SP_Lua_PanelGetPos(L
: PScriptContext
): Integer; cdecl;
55 function SP_Lua_PanelGetSize(L
: PScriptContext
): Integer; cdecl;
56 function SP_Lua_PanelSetPos(L
: PScriptContext
): Integer; cdecl;
57 function SP_Lua_PanelSwitchTexture(L
: PScriptContext
): Integer; cdecl;
59 function SP_Lua_DoorGetState(L
: PScriptContext
): Integer; cdecl;
60 function SP_Lua_DoorOpen(L
: PScriptContext
): Integer; cdecl;
61 function SP_Lua_DoorClose(L
: PScriptContext
): Integer; cdecl;
62 function SP_Lua_DoorToggle(L
: PScriptContext
): Integer; cdecl;
63 function SP_Lua_DoorCloseTrap(L
: PScriptContext
): Integer; cdecl;
64 function SP_Lua_LiftSetDir(L
: PScriptContext
): Integer; cdecl;
65 function SP_Lua_LiftGetDir(L
: PScriptContext
): Integer; cdecl;
67 function SP_Lua_SpawnShot(L
: PScriptContext
): Integer; cdecl;
68 function SP_Lua_SpawnEffect(L
: PScriptContext
): Integer; cdecl;
69 function SP_Lua_SpawnMonster(L
: PScriptContext
): Integer; cdecl;
70 function SP_Lua_SpawnItem(L
: PScriptContext
): Integer; cdecl;
76 g_player
, g_map
, Math
, g_gfx
, g_game
, g_textures
,
77 g_console
, g_monsters
, g_items
, g_phys
, g_weapons
,
78 g_main
, SysUtils
, e_log
, g_language
, g_basic
,
79 g_options
, g_net
, g_netmsg
, g_triggers
, g_panel
,
82 function CheckArgs(L
: PScriptContext
; MinArgs
: Integer; Error
: Boolean = True): Boolean; inline;
85 if lua_gettop(L
) < MinArgs
then
87 if Error
then g_Console_Add('SCRIPT: ERROR: expected at least ' + IntToStr(MinArgs
) + ' argument(s)');
94 function SP_Lua_ConPrint(L
: PScriptContext
): Integer; cdecl;
95 // game.con_print(text)
100 if not CheckArgs(L
, MINARGS
) then Exit
;
101 g_Console_Add(luaL_checkstring(L
, 1));
104 function SP_Lua_Message(L
: PScriptContext
): Integer; cdecl;
105 // game.message(type, text, channel[, uid=0, timeout=144])
110 MChan
, MKind
, MID
, MTime
: Integer;
113 if not CheckArgs(L
, MINARGS
) then exit
;
115 MKind
:= luaL_checkinteger(L
, 1);
116 MText
:= luaL_checkstring(L
, 2);
117 MChan
:= luaL_checkinteger(L
, 3);
119 MID
:= lua_tointeger(L
, 4);
120 MTime
:= lua_tointeger(L
, 5);
121 if MTime
= 0 then MTime
:= 144;
123 tr_Message(MKind
, MText
, MChan
, MTime
, MID
);
126 function SP_Lua_GetGameMode(L
: PScriptContext
): Integer; cdecl;
127 // game.get_gamemode()
132 lua_pushinteger(L
, gGameSettings
.GameMode
);
135 function SP_Lua_GetGameType(L
: PScriptContext
): Integer; cdecl;
136 // game.get_gametype()
141 lua_pushinteger(L
, gGameSettings
.GameType
);
144 function SP_Lua_GetTime(L
: PScriptContext
): Integer; cdecl;
150 lua_pushinteger(L
, gTime
);
153 function SP_Lua_PlaySound(L
: PScriptContext
): Integer; cdecl;
154 // game.sound(name[positional=false, x=0, y=0])
163 if not CheckArgs(L
, MINARGS
) then exit
;
165 SName
:= luaL_checkstring(L
, 1);
167 SPos
:= lua_toboolean(L
, 2);
168 SX
:= lua_tointeger(L
, 3);
169 SY
:= lua_tointeger(L
, 4);
172 g_Sound_PlayExAt(SName
, SX
, SY
)
174 g_Sound_PlayEx(SName
);
177 MH_SEND_Sound(SX
, SY
, SName
, SPos
);
182 function SP_Lua_PlayerGetKeys(L
: PScriptContext
): Integer; cdecl;
183 // game.player_get_keys(uid)
191 if not CheckArgs(L
, MINARGS
) then
197 UID
:= luaL_checkinteger(L
, 1);
199 if g_GetUIDType(UID
) <> UID_PLAYER
then
203 P
:= g_Player_Get(UID
);
209 lua_pushinteger(L
, P
.GetKeys
);
213 function SP_Lua_PlayerGetArmor(L
: PScriptContext
): Integer; cdecl;
214 // game.player_get_armor(uid)
222 if not CheckArgs(L
, MINARGS
) then
228 UID
:= luaL_checkinteger(L
, 1);
230 if g_GetUIDType(UID
) <> UID_PLAYER
then
234 P
:= g_Player_Get(UID
);
240 lua_pushinteger(L
, P
.Armor
);
244 function SP_Lua_PlayerGetName(L
: PScriptContext
): Integer; cdecl;
245 // game.player_get_name(uid)
253 if not CheckArgs(L
, MINARGS
) then
259 UID
:= luaL_checkinteger(L
, 1);
261 if g_GetUIDType(UID
) <> UID_PLAYER
then
265 P
:= g_Player_Get(UID
);
271 lua_pushstring(L
, P
.Name
);
275 function SP_Lua_PlayerGetTeam(L
: PScriptContext
): Integer; cdecl;
276 // game.player_get_team(uid)
284 if not CheckArgs(L
, MINARGS
) then
290 UID
:= luaL_checkinteger(L
, 1);
292 if g_GetUIDType(UID
) <> UID_PLAYER
then
296 P
:= g_Player_Get(UID
);
302 lua_pushinteger(L
, P
.Team
);
306 function SP_Lua_PlayerGetScore(L
: PScriptContext
): Integer; cdecl;
307 // game.player_get_score(uid)
315 if not CheckArgs(L
, MINARGS
) then
321 UID
:= luaL_checkinteger(L
, 1);
323 if g_GetUIDType(UID
) <> UID_PLAYER
then
327 P
:= g_Player_Get(UID
);
333 lua_pushinteger(L
, P
.Frags
);
339 function SP_Lua_ActorGetPos(L
: PScriptContext
): Integer; cdecl;
340 // game.uid_get_pos(uid)
349 if not CheckArgs(L
, MINARGS
) then
355 UID
:= luaL_checkinteger(L
, 1);
357 if g_GetUIDType(UID
) = UID_PLAYER
then
359 P
:= g_Player_Get(UID
);
366 lua_pushinteger(L
, P
.GameX
+ PLAYER_RECT_CX
);
367 lua_pushinteger(L
, P
.GameY
+ PLAYER_RECT_CY
);
369 else if g_GetUIDType(UID
) = UID_MONSTER
then
371 M
:= g_Monsters_Get(UID
);
378 lua_pushinteger(L
, M
.Obj
.X
+M
.Obj
.Rect
.X
+(M
.Obj
.Rect
.Width
div 2));
379 lua_pushinteger(L
, M
.Obj
.Y
+M
.Obj
.Rect
.Y
+(M
.Obj
.Rect
.Height
div 2));
388 function SP_Lua_ActorNearest(L
: PScriptContext
): Integer; cdecl;
389 // game.uid_nearest(x, y, [type=all, min, max])
393 i
, UID
, AType
: Integer;
394 X
, Y
, Dist
, MinDist
, MaxDist
, FMin
: Double;
397 if not CheckArgs(L
, MINARGS
) then
403 X
:= luaL_checkinteger(L
, 1);
404 Y
:= luaL_checkinteger(L
, 2);
406 AType
:= lua_tointeger(L
, 3);
407 MinDist
:= Sqr(lua_tonumber(L
, 4));
408 MaxDist
:= Sqr(lua_tonumber(L
, 5));
409 if MaxDist
< 0.01 then MaxDist
:= 1e15
;
410 if MinDist
< 0.01 then MinDist
:= 0;
414 if (AType
in [UID_GAME
, UID_PLAYER
]) and (gPlayers
<> nil) then
415 for i
:= 0 to High(gPlayers
) do
417 if gPlayers
[i
] = nil then continue
;
418 Dist
:= Sqr(X
- gPlayers
[i
].GameX
) + Sqr(Y
- gPlayers
[i
].GameY
);
419 if (Dist
> MinDist
) and (Dist
< FMin
) then
421 UID
:= gPlayers
[i
].UID
;
425 if (AType
in [UID_GAME
, UID_MONSTER
]) and (gMonsters
<> nil) then
426 for i
:= 0 to High(gMonsters
) do
428 if gMonsters
[i
] = nil then continue
;
429 Dist
:= Sqr(X
- gMonsters
[i
].GameX
) + Sqr(Y
- gMonsters
[i
].GameY
);
430 if (Dist
> MinDist
) and (Dist
< FMin
) then
432 UID
:= gMonsters
[i
].UID
;
437 lua_pushinteger(L
, UID
);
440 function SP_Lua_ActorFarthest(L
: PScriptContext
): Integer; cdecl;
441 // game.uid_farthest(x, y, [type=all, min, max])
445 i
, UID
, AType
: Integer;
446 X
, Y
, Dist
, MinDist
, MaxDist
, FMax
: Double;
449 if not CheckArgs(L
, MINARGS
) then
455 X
:= luaL_checkinteger(L
, 1);
456 Y
:= luaL_checkinteger(L
, 2);
458 AType
:= lua_tointeger(L
, 3);
459 MinDist
:= Sqr(lua_tonumber(L
, 4));
460 MaxDist
:= Sqr(lua_tonumber(L
, 5));
461 if MaxDist
< 0.01 then MaxDist
:= 1e15
;
462 if MinDist
< 0.01 then MinDist
:= 0;
466 if (AType
in [UID_GAME
, UID_PLAYER
]) and (gPlayers
<> nil) then
467 for i
:= 0 to High(gPlayers
) do
469 if gPlayers
[i
] = nil then continue
;
470 Dist
:= Sqr(X
- gPlayers
[i
].GameX
) + Sqr(Y
- gPlayers
[i
].GameY
);
471 if (Dist
< MaxDist
) and (Dist
> FMax
) then
473 UID
:= gPlayers
[i
].UID
;
477 if (AType
in [UID_GAME
, UID_MONSTER
]) and (gMonsters
<> nil) then
478 for i
:= 0 to High(gMonsters
) do
480 if gMonsters
[i
] = nil then continue
;
481 Dist
:= Sqr(X
- gMonsters
[i
].GameX
) + Sqr(Y
- gMonsters
[i
].GameY
);
482 if (Dist
< MaxDist
) and (Dist
> FMax
) then
484 UID
:= gMonsters
[i
].UID
;
489 lua_pushinteger(L
, UID
);
492 function SP_Lua_ActorGetType(L
: PScriptContext
): Integer; cdecl;
493 // game.uid_type(uid)
500 if not CheckArgs(L
, MINARGS
) then
506 UID
:= luaL_checkinteger(L
, 1);
507 if (UID
< 0) or (UID
> $FFFF) then
511 UType
:= g_GetUIDType(UID
);
512 if not (UType
in [UID_PLAYER
, UID_MONSTER
{*, UID_ITEM*}]) then
515 lua_pushinteger(L
, UType
);
519 function SP_Lua_ActorDamage(L
: PScriptContext
): Integer; cdecl;
520 // game.uid_damage(uid, amount[, hit_type=hit_some, vx=0, vy=0, attacker_uid=0])
524 UID
, AUID
, Dmg
, Atk
, VX
, VY
: Integer;
529 if not CheckArgs(L
, MINARGS
) then exit
;
531 UID
:= luaL_checkinteger(L
, 1);
532 Dmg
:= luaL_checkinteger(L
, 2);
534 Atk
:= lua_tointeger(L
, 3);
535 VX
:= lua_tointeger(L
, 4);
536 VY
:= lua_tointeger(L
, 5);
537 AUID
:= lua_tointeger(L
, 6);
539 if g_GetUIDType(UID
) = UID_PLAYER
then
541 P
:= g_Player_Get(UID
);
542 if P
= nil then exit
;
544 P
.Damage(Dmg
, AUID
, VX
, VY
, Atk
)
548 else if g_GetUIDType(UID
) = UID_MONSTER
then
550 M
:= g_Monsters_Get(UID
);
551 if M
= nil then exit
;
553 M
.Damage(Dmg
, AUID
, VX
, VY
, Atk
)
559 function SP_Lua_ActorGetHealth(L
: PScriptContext
): Integer; cdecl;
560 // game.uid_get_health(uid)
569 if not CheckArgs(L
, MINARGS
) then
575 UID
:= luaL_checkinteger(L
, 1);
577 if g_GetUIDType(UID
) = UID_PLAYER
then
579 P
:= g_Player_Get(UID
);
585 lua_pushinteger(L
, P
.Health
);
587 else if g_GetUIDType(UID
) = UID_MONSTER
then
589 M
:= g_Monsters_Get(UID
);
595 lua_pushinteger(L
, M
.MonsterHealth
);
601 function SP_Lua_ActorGetState(L
: PScriptContext
): Integer; cdecl;
602 // game.uid_get_state(uid)
611 if not CheckArgs(L
, MINARGS
) then
617 UID
:= luaL_checkinteger(L
, 1);
619 if g_GetUIDType(UID
) = UID_PLAYER
then
621 P
:= g_Player_Get(UID
);
628 lua_pushinteger(L
, 1)
629 else if P
.FSpectator
then
630 lua_pushinteger(L
, -1)
632 lua_pushinteger(L
, 0);
634 else if g_GetUIDType(UID
) = UID_MONSTER
then
636 M
:= g_Monsters_Get(UID
);
642 lua_pushinteger(L
, IfThen(M
.Live
, 1, 0));
648 function SP_Lua_ActorTeleport(L
: PScriptContext
): Integer; cdecl;
649 // game.uid_teleport(uid, to_x, to_y[, dir=left, silent=false, d2d_like=false])
653 D2D
, NoSound
: Boolean;
654 UID
, TX
, TY
: Integer;
658 if not CheckArgs(L
, MINARGS
) then exit
;
660 UID
:= luaL_checkinteger(L
, 1);
661 TX
:= luaL_checkinteger(L
, 2);
662 TY
:= luaL_checkinteger(L
, 3);
664 TDir
:= lua_tointeger(L
, 4) mod 2;
665 NoSound
:= lua_toboolean(L
, 5);
666 D2D
:= lua_toboolean(L
, 6);
668 tr_Teleport(UID
, TX
, TY
, TDir
, NoSound
, D2D
);
671 function SP_Lua_ActorPush(L
: PScriptContext
): Integer; cdecl;
672 // game.uid_push(uid, vx, vy[, reset_vel=false])
677 UID
, VX
, VY
: Integer;
680 if not CheckArgs(L
, MINARGS
) then exit
;
682 UID
:= luaL_checkinteger(L
, 1);
683 VX
:= luaL_checkinteger(L
, 2);
684 VY
:= luaL_checkinteger(L
, 3);
686 ResetVel
:= lua_toboolean(L
, 4);
688 tr_Push(UID
, VX
, VY
, ResetVel
);
693 function SP_Lua_TriggerSetEnabled(L
: PScriptContext
): Integer; cdecl;
694 // game.trigger_set_enabled(id, active)
702 if not CheckArgs(L
, MINARGS
) then exit
;
704 TID
:= luaL_checkinteger(L
, 1);
705 Enabled
:= lua_toboolean(L
, 2);
707 if (TID
< 0) or (TID
> High(gTriggers
)) then exit
;
708 if gTriggers
[TID
].TriggerType
= TRIGGER_NONE
then exit
;
709 gTriggers
[TID
].Enabled
:= Enabled
;
712 function SP_Lua_TriggerGetEnabled(L
: PScriptContext
): Integer; cdecl;
713 // game.trigger_get_enabled(id)
720 if not CheckArgs(L
, MINARGS
) then
726 TID
:= luaL_checkinteger(L
, 1);
728 if (TID
< 0) or (TID
> High(gTriggers
)) or (gTriggers
[TID
].TriggerType
= TRIGGER_NONE
) then
731 lua_pushboolean(L
, gTriggers
[TID
].Enabled
);
734 function SP_Lua_TriggerActivate(L
: PScriptContext
): Integer; cdecl;
735 // game.trigger_activate(id[, activate_type=custom, activator_uid=0])
743 if not CheckArgs(L
, MINARGS
) then exit
;
745 TID
:= luaL_checkinteger(L
, 1);
747 TAct
:= lua_tointeger(L
, 2);
748 if TAct
= 0 then TAct
:= 255;
749 UID
:= lua_tointeger(L
, 3);
751 if (TID
< 0) or (TID
> High(gTriggers
)) then exit
;
752 if gTriggers
[TID
].TriggerType
= TRIGGER_NONE
then exit
;
753 if ByteBool(gTriggers
[TID
].ActivateType
and TAct
) then
754 g_Triggers_Press(TID
, TAct
, UID
);
757 function SP_Lua_TriggerGetPos(L
: PScriptContext
): Integer; cdecl;
758 // game.trigger_get_pos(id)
765 if not CheckArgs(L
, MINARGS
) then
771 TID
:= luaL_checkinteger(L
, 1);
773 if (TID
< 0) or (TID
> High(gTriggers
)) or (gTriggers
[TID
].TriggerType
= TRIGGER_NONE
) then
780 lua_pushinteger(L
, gTriggers
[TID
].X
);
781 lua_pushinteger(L
, gTriggers
[TID
].Y
);
785 function SP_Lua_TriggerSetPos(L
: PScriptContext
): Integer; cdecl;
786 // game.trigger_set_pos(id, x, y)
793 if not CheckArgs(L
, MINARGS
) then exit
;
795 TID
:= luaL_checkinteger(L
, 1);
796 X
:= luaL_checkinteger(L
, 2);
797 Y
:= luaL_checkinteger(L
, 3);
799 if (TID
< 0) or (TID
> High(gTriggers
)) then exit
;
800 if gTriggers
[TID
].TriggerType
in [TRIGGER_NONE
, TRIGGER_SOUND
] then exit
;
801 gTriggers
[TID
].X
:= X
;
802 gTriggers
[TID
].Y
:= Y
;
807 function SP_Lua_PanelGetType(L
: PScriptContext
): Integer; cdecl;
808 // game.panel_get_type(panel_id)
816 if not CheckArgs(L
, MINARGS
) then
822 PID
:= luaL_checkinteger(L
, 1);
825 Pan
:= g_Map_PanelForPID(PID
, WID
);
829 lua_pushinteger(L
, Pan
^.PanelType
);
832 function SP_Lua_PanelGetPos(L
: PScriptContext
): Integer; cdecl;
833 // game.panel_get_pos(panel_id)
841 if not CheckArgs(L
, MINARGS
) then
847 PID
:= luaL_checkinteger(L
, 1);
850 Pan
:= g_Map_PanelForPID(PID
, WID
);
858 lua_pushinteger(L
, Pan
^.X
);
859 lua_pushinteger(L
, Pan
^.Y
);
863 function SP_Lua_PanelGetSize(L
: PScriptContext
): Integer; cdecl;
864 // game.panel_get_size(panel_id)
872 if not CheckArgs(L
, MINARGS
) then
878 PID
:= luaL_checkinteger(L
, 1);
881 Pan
:= g_Map_PanelForPID(PID
, WID
);
889 lua_pushinteger(L
, Pan
^.Width
);
890 lua_pushinteger(L
, Pan
^.Height
);
894 function SP_Lua_PanelSwitchTexture(L
: PScriptContext
): Integer; cdecl;
895 // game.panel_switch_texture(panel_id)
903 if not CheckArgs(L
, MINARGS
) then exit
;
905 PID
:= luaL_checkinteger(L
, 1);
908 Pan
:= g_Map_PanelForPID(PID
, WID
);
909 if (Pan
= nil) then exit
;
910 g_Map_SwitchTexture(Pan
^.PanelType
, WID
, 0);
913 function SP_Lua_PanelSetPos(L
: PScriptContext
): Integer; cdecl;
914 // game.panel_set_pos(panel_id, x, y)
918 PID
, WID
, X
, Y
: Integer;
922 if not CheckArgs(L
, MINARGS
) then exit
;
924 PID
:= luaL_checkinteger(L
, 1);
925 X
:= luaL_checkinteger(L
, 2);
926 Y
:= luaL_checkinteger(L
, 3);
929 Pan
:= g_Map_PanelForPID(PID
, WID
);
930 if (Pan
= nil) then exit
;
931 if not (Pan
.PanelType
in [PANEL_BACK
, PANEL_FORE
]) then
933 g_Console_Add('SCRIPT: panel_set_pos(): can only set pos for BACK and FORE right now');
939 MH_SEND_PanelState(Pan
^.PanelType
, WID
);
942 function SP_Lua_DoorGetState(L
: PScriptContext
): Integer; cdecl;
943 // game.door_get_open(panel_id)
951 if not CheckArgs(L
, MINARGS
) then
957 PID
:= luaL_checkinteger(L
, 1);
960 Pan
:= g_Map_PanelForPID(PID
, WID
);
961 if (Pan
= nil) or (not Pan
^.Door
) then
964 lua_pushboolean(L
, Pan
^.Enabled
);
967 function SP_Lua_LiftGetDir(L
: PScriptContext
): Integer; cdecl;
968 // game.lift_get_dir(panel_id)
976 if not CheckArgs(L
, MINARGS
) then
982 PID
:= luaL_checkinteger(L
, 1);
985 Pan
:= g_Map_PanelForPID(PID
, WID
);
986 if (Pan
= nil) or ((Pan
^.LiftType
= 0) and (Pan
^.PanelType
<> PANEL_LIFTUP
)) then
989 lua_pushinteger(L
, Pan
^.LiftType
);
992 function SP_Lua_DoorOpen(L
: PScriptContext
): Integer; cdecl;
993 // game.door_open(panel_id[, silent=false, d2d_like=false])
997 D2D
, NoSound
: Boolean;
1002 if not CheckArgs(L
, MINARGS
) then exit
;
1004 PID
:= luaL_checkinteger(L
, 1);
1005 NoSound
:= lua_toboolean(L
, 2);
1006 D2D
:= lua_toboolean(L
, 3);
1009 Pan
:= g_Map_PanelForPID(PID
, WID
);
1010 if (Pan
= nil) or (not Pan
^.Door
) then exit
;
1011 tr_OpenDoor(WID
, NoSound
, D2D
);
1014 function SP_Lua_DoorClose(L
: PScriptContext
): Integer; cdecl;
1015 // game.door_close(panel_id[, silent=false, d2d_like=false])
1019 D2D
, NoSound
: Boolean;
1024 if not CheckArgs(L
, MINARGS
) then exit
;
1026 PID
:= luaL_checkinteger(L
, 1);
1027 NoSound
:= lua_toboolean(L
, 2);
1028 D2D
:= lua_toboolean(L
, 3);
1031 Pan
:= g_Map_PanelForPID(PID
, WID
);
1032 if (Pan
= nil) or (not Pan
^.Door
) then exit
;
1033 tr_CloseDoor(WID
, NoSound
, D2D
);
1036 function SP_Lua_DoorToggle(L
: PScriptContext
): Integer; cdecl;
1037 // game.door_toggle(panel_id[, silent=false, d2d_like=false])
1041 D2D
, NoSound
: Boolean;
1046 if not CheckArgs(L
, MINARGS
) then exit
;
1048 PID
:= luaL_checkinteger(L
, 1);
1049 NoSound
:= lua_toboolean(L
, 2);
1050 D2D
:= lua_toboolean(L
, 3);
1053 Pan
:= g_Map_PanelForPID(PID
, WID
);
1054 if (Pan
= nil) or (not Pan
^.Door
) then exit
;
1055 if gWalls
[WID
].Enabled
then
1056 tr_OpenDoor(WID
, NoSound
, D2D
)
1058 tr_CloseDoor(WID
, NoSound
, D2D
);
1061 function SP_Lua_DoorCloseTrap(L
: PScriptContext
): Integer; cdecl;
1062 // game.door_close_trap(panel_id[, silent=false, d2d_like=false])
1066 D2D
, NoSound
: Boolean;
1071 if not CheckArgs(L
, MINARGS
) then exit
;
1073 PID
:= luaL_checkinteger(L
, 1);
1074 NoSound
:= lua_toboolean(L
, 2);
1075 D2D
:= lua_toboolean(L
, 3);
1078 Pan
:= g_Map_PanelForPID(PID
, WID
);
1079 if (Pan
= nil) or (not Pan
^.Door
) then exit
;
1080 tr_CloseTrap(WID
, NoSound
, D2D
);
1083 function SP_Lua_LiftSetDir(L
: PScriptContext
): Integer; cdecl;
1084 // game.lift_set_dir(panel_id, dir[, silent=false, d2d_like=false])
1088 D2D
, NoSound
: Boolean;
1089 PID
, WID
, Dir
: Integer;
1093 if not CheckArgs(L
, MINARGS
) then exit
;
1095 PID
:= luaL_checkinteger(L
, 1);
1096 Dir
:= luaL_checkinteger(L
, 2);
1097 NoSound
:= lua_toboolean(L
, 3);
1098 D2D
:= lua_toboolean(L
, 4);
1101 Pan
:= g_Map_PanelForPID(PID
, WID
);
1102 if (Pan
= nil) or ((Pan
^.LiftType
= 0) and (Pan
^.PanelType
<> PANEL_LIFTUP
)) then
1104 tr_SetLift(WID
, Dir
, NoSound
, D2D
);
1109 function SP_Lua_SpawnShot(L
: PScriptContext
): Integer; cdecl;
1110 // game.spawn_shot(type, x, y, vel_x, vel_y[, silent=false, target_id=0(noone)])
1114 wx
, wy
, dx
, dy
, ShotType
, ShotTarget
: Integer;
1119 if not CheckArgs(L
, MINARGS
) then
1125 ShotType
:= luaL_checkinteger(L
, 1);
1126 wx
:= luaL_checkinteger(L
, 2);
1127 wy
:= luaL_checkinteger(L
, 3);
1128 dx
:= luaL_checkinteger(L
, 4);
1129 dy
:= luaL_checkinteger(L
, 5);
1131 Silent
:= lua_toboolean(L
, 6);
1132 ShotTarget
:= lua_tointeger(L
, 7);
1134 if (ShotTarget
> 0) and (ShotTarget
< $FFFF) then
1135 ShotTargetW
:= ShotTarget
;
1137 lua_pushinteger(L
, tr_SpawnShot(ShotType
, wx
, wy
, dx
, dy
, not Silent
, ShotTargetW
));
1140 function SP_Lua_SpawnEffect(L
: PScriptContext
): Integer; cdecl;
1141 // game.spawn_effect(type, subtype, x, y, vel_x, vel_y[, silent=false, r=0, g=0, b=0])
1145 X
, Y
, VX
, VY
: Integer;
1146 EType
, ESubType
: Integer;
1147 ER
, EG
, EB
: Integer;
1151 if not CheckArgs(L
, MINARGS
) then exit
;
1153 EType
:= luaL_checkinteger(L
, 1);
1154 ESubType
:= luaL_checkinteger(L
, 2);
1155 X
:= luaL_checkinteger(L
, 3);
1156 Y
:= luaL_checkinteger(L
, 4);
1157 VX
:= luaL_checkinteger(L
, 5);
1158 VY
:= luaL_checkinteger(L
, 6);
1160 Silent
:= lua_toboolean(L
, 7);
1161 ER
:= lua_tointeger(L
, 8);
1162 EG
:= lua_tointeger(L
, 8);
1163 EB
:= lua_tointeger(L
, 8);
1165 tr_MakeEffect(X
, Y
, VX
, VY
, EType
, ESubType
, ER
, EG
, EB
, Silent
, True);
1168 function SP_Lua_SpawnMonster(L
: PScriptContext
): Integer; cdecl;
1169 // game.spawn_monster(type, x, y[, dir=left, awake=false, health=default, aitype=normal])
1175 MType
, MBType
, MHP
: Integer;
1180 if not CheckArgs(L
, MINARGS
) then
1186 MType
:= luaL_checkinteger(L
, 1);
1187 X
:= luaL_checkinteger(L
, 2);
1188 Y
:= luaL_checkinteger(L
, 3);
1190 Dir
:= TDirection(lua_tointeger(L
, 4) mod 2);
1191 MAwake
:= lua_toboolean(L
, 5);
1192 MHP
:= lua_tointeger(L
, 6);
1193 MBType
:= lua_tointeger(L
, 7);
1197 if MType
in [MONSTER_DEMON
..MONSTER_MAN
] then
1199 i
:= g_Monsters_Create(MType
, X
, Y
, Dir
, True);
1202 gMonsters
[i
].SetHealth(MHP
);
1203 gMonsters
[i
].MonsterBehaviour
:= MBType
;
1204 gMonsters
[i
].FNoRespawn
:= True;
1205 if g_Game_IsNet
then
1206 MH_SEND_MonsterSpawn(gMonsters
[i
].UID
);
1208 gMonsters
[i
].WakeUp();
1209 if MType
<> MONSTER_BARREL
then Inc(gTotalMonsters
);
1210 if g_Game_IsNet
then
1212 SetLength(gMonstersSpawned
, Length(gMonstersSpawned
)+1);
1213 gMonstersSpawned
[High(gMonstersSpawned
)] := gMonsters
[i
].UID
;
1214 MH_SEND_GameStats();
1215 MH_SEND_CoopStats();
1217 MID
:= gMonsters
[i
].UID
;
1220 lua_pushinteger(L
, MID
);
1223 function SP_Lua_SpawnItem(L
: PScriptContext
): Integer; cdecl;
1224 // game.spawn_item(type, x, y[, falls=false])
1234 if not CheckArgs(L
, MINARGS
) then
1240 IType
:= luaL_checkinteger(L
, 1);
1241 X
:= luaL_checkinteger(L
, 2);
1242 Y
:= luaL_checkinteger(L
, 3);
1244 IFalls
:= lua_toboolean(L
, 4);
1247 if IType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
1249 i
:= g_Items_Create(X
, Y
, IType
, IFalls
, False, True);
1250 if g_Game_IsNet
then
1251 MH_SEND_ItemSpawn(True, i
);
1254 lua_pushinteger(L
, i
);