X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_scriptprocs.pas;h=a4297041048e8c1a8c9c140798e033b7db56a5ef;hp=082346e666d3ff1decb4ff74e1ee7cbdaf6f7405;hb=00c73a7e4b162b8adb061e4b4715ee35ba9a2df5;hpb=0aed9f9d49f034aad7d8856db00fe42f3303826d diff --git a/src/game/g_scriptprocs.pas b/src/game/g_scriptprocs.pas index 082346e..a429704 100644 --- a/src/game/g_scriptprocs.pas +++ b/src/game/g_scriptprocs.pas @@ -22,16 +22,1236 @@ uses g_scripts; function SP_Lua_ConPrint(L: PScriptContext): Integer; cdecl; +function SP_Lua_PlaySound(L: PScriptContext): Integer; cdecl; +function SP_Lua_Message(L: PScriptContext): Integer; cdecl; +function SP_Lua_GetGameMode(L: PScriptContext): Integer; cdecl; +function SP_Lua_GetGameType(L: PScriptContext): Integer; cdecl; +function SP_Lua_GetTime(L: PScriptContext): Integer; cdecl; + +function SP_Lua_PlayerGetKeys(L: PScriptContext): Integer; cdecl; +function SP_Lua_PlayerGetArmor(L: PScriptContext): Integer; cdecl; +function SP_Lua_PlayerGetTeam(L: PScriptContext): Integer; cdecl; +function SP_Lua_PlayerGetScore(L: PScriptContext): Integer; cdecl; +function SP_Lua_PlayerGetName(L: PScriptContext): Integer; cdecl; + +function SP_Lua_ActorGetPos(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorGetHealth(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorGetState(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorGetType(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorNearest(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorFarthest(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorDamage(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorTeleport(L: PScriptContext): Integer; cdecl; +function SP_Lua_ActorPush(L: PScriptContext): Integer; cdecl; + +function SP_Lua_TriggerActivate(L: PScriptContext): Integer; cdecl; +function SP_Lua_TriggerGetEnabled(L: PScriptContext): Integer; cdecl; +function SP_Lua_TriggerSetEnabled(L: PScriptContext): Integer; cdecl; +function SP_Lua_TriggerGetPos(L: PScriptContext): Integer; cdecl; +function SP_Lua_TriggerSetPos(L: PScriptContext): Integer; cdecl; + +function SP_Lua_PanelGetType(L: PScriptContext): Integer; cdecl; +function SP_Lua_PanelGetPos(L: PScriptContext): Integer; cdecl; +function SP_Lua_PanelGetSize(L: PScriptContext): Integer; cdecl; +function SP_Lua_PanelSetPos(L: PScriptContext): Integer; cdecl; +function SP_Lua_PanelSwitchTexture(L: PScriptContext): Integer; cdecl; + +function SP_Lua_DoorGetState(L: PScriptContext): Integer; cdecl; +function SP_Lua_DoorOpen(L: PScriptContext): Integer; cdecl; +function SP_Lua_DoorClose(L: PScriptContext): Integer; cdecl; +function SP_Lua_DoorToggle(L: PScriptContext): Integer; cdecl; +function SP_Lua_DoorCloseTrap(L: PScriptContext): Integer; cdecl; +function SP_Lua_LiftSetDir(L: PScriptContext): Integer; cdecl; +function SP_Lua_LiftGetDir(L: PScriptContext): Integer; cdecl; + +function SP_Lua_SpawnShot(L: PScriptContext): Integer; cdecl; +function SP_Lua_SpawnEffect(L: PScriptContext): Integer; cdecl; +function SP_Lua_SpawnMonster(L: PScriptContext): Integer; cdecl; +function SP_Lua_SpawnItem(L: PScriptContext): Integer; cdecl; implementation uses - lua, g_console; + lua, lauxlib, + g_player, g_map, Math, g_gfx, g_game, g_textures, + g_console, g_monsters, g_items, g_phys, g_weapons, + g_main, SysUtils, e_log, g_language, g_basic, + g_options, g_net, g_netmsg, g_triggers, g_panel, + g_sound, MAPDEF; + +function CheckArgs(L: PScriptContext; MinArgs: Integer; Error: Boolean = True): Boolean; inline; +begin + Result := True; + if lua_gettop(L) < MinArgs then + begin + if Error then g_Console_Add('SCRIPT: ERROR: expected at least ' + IntToStr(MinArgs) + ' argument(s)'); + Result := False; + end; +end; + +// system // function SP_Lua_ConPrint(L: PScriptContext): Integer; cdecl; +// game.con_print(text) +const + MINARGS = 1; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then Exit; + g_Console_Add(luaL_checkstring(L, 1)); +end; + +function SP_Lua_Message(L: PScriptContext): Integer; cdecl; +// game.message(type, text, channel[, uid=0, timeout=144]) +const + MINARGS = 3; +var + MText: string; + MChan, MKind, MID, MTime: Integer; begin - g_Console_Add(lua_tostring(L, -1)); Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + MKind := luaL_checkinteger(L, 1); + MText := luaL_checkstring(L, 2); + MChan := luaL_checkinteger(L, 3); + + MID := lua_tointeger(L, 4); + MTime := lua_tointeger(L, 5); + if MTime = 0 then MTime := 144; + + tr_Message(MKind, MText, MChan, MTime, MID); +end; + +function SP_Lua_GetGameMode(L: PScriptContext): Integer; cdecl; +// game.get_gamemode() +const + MINARGS = 0; +begin + Result := 1; + lua_pushinteger(L, gGameSettings.GameMode); +end; + +function SP_Lua_GetGameType(L: PScriptContext): Integer; cdecl; +// game.get_gametype() +const + MINARGS = 0; +begin + Result := 1; + lua_pushinteger(L, gGameSettings.GameType); +end; + +function SP_Lua_GetTime(L: PScriptContext): Integer; cdecl; +// game.get_time() +const + MINARGS = 0; +begin + Result := 1; + lua_pushinteger(L, gTime); +end; + +function SP_Lua_PlaySound(L: PScriptContext): Integer; cdecl; +// game.sound(name[positional=false, x=0, y=0]) +const + MINARGS = 1; +var + SName: string; + SPos: Boolean; + SX, SY: Integer; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + SName := luaL_checkstring(L, 1); + + SPos := lua_toboolean(L, 2); + SX := lua_tointeger(L, 3); + SY := lua_tointeger(L, 4); + + if SPos then + g_Sound_PlayExAt(SName, SX, SY) + else + g_Sound_PlayEx(SName); + + if g_Game_IsNet then + MH_SEND_Sound(SX, SY, SName, SPos); +end; + +// players // + +function SP_Lua_PlayerGetKeys(L: PScriptContext): Integer; cdecl; +// game.player_get_keys(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) <> UID_PLAYER then + lua_pushnil(L) + else + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.GetKeys); + end; +end; + +function SP_Lua_PlayerGetArmor(L: PScriptContext): Integer; cdecl; +// game.player_get_armor(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) <> UID_PLAYER then + lua_pushnil(L) + else + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.Armor); + end; +end; + +function SP_Lua_PlayerGetName(L: PScriptContext): Integer; cdecl; +// game.player_get_name(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) <> UID_PLAYER then + lua_pushnil(L) + else + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushstring(L, P.Name); + end; +end; + +function SP_Lua_PlayerGetTeam(L: PScriptContext): Integer; cdecl; +// game.player_get_team(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) <> UID_PLAYER then + lua_pushnil(L) + else + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.Team); + end; +end; + +function SP_Lua_PlayerGetScore(L: PScriptContext): Integer; cdecl; +// game.player_get_score(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) <> UID_PLAYER then + lua_pushnil(L) + else + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.Frags); + end; +end; + +// actors // + +function SP_Lua_ActorGetPos(L: PScriptContext): Integer; cdecl; +// game.uid_get_pos(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; + M: TMonster; +begin + Result := 2; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) = UID_PLAYER then + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.GameX + PLAYER_RECT_CX); + lua_pushinteger(L, P.GameY + PLAYER_RECT_CY); + end + else if g_GetUIDType(UID) = UID_MONSTER then + begin + M := g_Monsters_Get(UID); + if M = nil then + begin + lua_pushnil(L); + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, M.Obj.X+M.Obj.Rect.X+(M.Obj.Rect.Width div 2)); + lua_pushinteger(L, M.Obj.Y+M.Obj.Rect.Y+(M.Obj.Rect.Height div 2)); + end + else + begin + lua_pushnil(L); + lua_pushnil(L); + end; +end; + +function SP_Lua_ActorNearest(L: PScriptContext): Integer; cdecl; +// game.uid_nearest(x, y, [type=all, min, max]) +const + MINARGS = 2; +var + i, UID, AType: Integer; + X, Y, Dist, MinDist, MaxDist, FMin: Double; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + X := luaL_checkinteger(L, 1); + Y := luaL_checkinteger(L, 2); + + AType := lua_tointeger(L, 3); + MinDist := Sqr(lua_tonumber(L, 4)); + MaxDist := Sqr(lua_tonumber(L, 5)); + if MaxDist < 0.01 then MaxDist := 1e15; + if MinDist < 0.01 then MinDist := 0; + FMin := MaxDist; + UID := -1; + + if (AType in [UID_GAME, UID_PLAYER]) and (gPlayers <> nil) then + for i := 0 to High(gPlayers) do + begin + if gPlayers[i] = nil then continue; + Dist := Sqr(X - gPlayers[i].GameX) + Sqr(Y - gPlayers[i].GameY); + if (Dist > MinDist) and (Dist < FMin) then + begin + UID := gPlayers[i].UID; + FMin := Dist; + end; + end; + if (AType in [UID_GAME, UID_MONSTER]) and (gMonsters <> nil) then + for i := 0 to High(gMonsters) do + begin + if gMonsters[i] = nil then continue; + Dist := Sqr(X - gMonsters[i].GameX) + Sqr(Y - gMonsters[i].GameY); + if (Dist > MinDist) and (Dist < FMin) then + begin + UID := gMonsters[i].UID; + FMin := Dist; + end; + end; + + lua_pushinteger(L, UID); +end; + +function SP_Lua_ActorFarthest(L: PScriptContext): Integer; cdecl; +// game.uid_farthest(x, y, [type=all, min, max]) +const + MINARGS = 2; +var + i, UID, AType: Integer; + X, Y, Dist, MinDist, MaxDist, FMax: Double; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + X := luaL_checkinteger(L, 1); + Y := luaL_checkinteger(L, 2); + + AType := lua_tointeger(L, 3); + MinDist := Sqr(lua_tonumber(L, 4)); + MaxDist := Sqr(lua_tonumber(L, 5)); + if MaxDist < 0.01 then MaxDist := 1e15; + if MinDist < 0.01 then MinDist := 0; + FMax := MinDist; + UID := -1; + + if (AType in [UID_GAME, UID_PLAYER]) and (gPlayers <> nil) then + for i := 0 to High(gPlayers) do + begin + if gPlayers[i] = nil then continue; + Dist := Sqr(X - gPlayers[i].GameX) + Sqr(Y - gPlayers[i].GameY); + if (Dist < MaxDist) and (Dist > FMax) then + begin + UID := gPlayers[i].UID; + FMax := Dist; + end; + end; + if (AType in [UID_GAME, UID_MONSTER]) and (gMonsters <> nil) then + for i := 0 to High(gMonsters) do + begin + if gMonsters[i] = nil then continue; + Dist := Sqr(X - gMonsters[i].GameX) + Sqr(Y - gMonsters[i].GameY); + if (Dist < MaxDist) and (Dist > FMax) then + begin + UID := gMonsters[i].UID; + FMax := Dist; + end; + end; + + lua_pushinteger(L, UID); +end; + +function SP_Lua_ActorGetType(L: PScriptContext): Integer; cdecl; +// game.uid_type(uid) +const + MINARGS = 2; +var + UID, UType: Integer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + if (UID < 0) or (UID > $FFFF) then + lua_pushnil(L) + else + begin + UType := g_GetUIDType(UID); + if not (UType in [UID_PLAYER, UID_MONSTER{*, UID_ITEM*}]) then + lua_pushnil(L) + else + lua_pushinteger(L, UType); + end; +end; + +function SP_Lua_ActorDamage(L: PScriptContext): Integer; cdecl; +// game.uid_damage(uid, amount[, hit_type=hit_some, vx=0, vy=0, attacker_uid=0]) +const + MINARGS = 2; +var + UID, AUID, Dmg, Atk, VX, VY: Integer; + P: TPlayer; + M: TMonster; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + UID := luaL_checkinteger(L, 1); + Dmg := luaL_checkinteger(L, 2); + + Atk := lua_tointeger(L, 3); + VX := lua_tointeger(L, 4); + VY := lua_tointeger(L, 5); + AUID := lua_tointeger(L, 6); + + if g_GetUIDType(UID) = UID_PLAYER then + begin + P := g_Player_Get(UID); + if P = nil then exit; + if Dmg >= 0 then + P.Damage(Dmg, AUID, VX, VY, Atk) + else + P.Heal(-Dmg, False); + end + else if g_GetUIDType(UID) = UID_MONSTER then + begin + M := g_Monsters_Get(UID); + if M = nil then exit; + if Dmg >= 0 then + M.Damage(Dmg, AUID, VX, VY, Atk) + else + M.Heal(-Dmg); + end; +end; + +function SP_Lua_ActorGetHealth(L: PScriptContext): Integer; cdecl; +// game.uid_get_health(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; + M: TMonster; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) = UID_PLAYER then + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, P.Health); + end + else if g_GetUIDType(UID) = UID_MONSTER then + begin + M := g_Monsters_Get(UID); + if M = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, M.MonsterHealth); + end + else + lua_pushnil(L); +end; + +function SP_Lua_ActorGetState(L: PScriptContext): Integer; cdecl; +// game.uid_get_state(uid) +const + MINARGS = 1; +var + UID: Integer; + P: TPlayer; + M: TMonster; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + UID := luaL_checkinteger(L, 1); + + if g_GetUIDType(UID) = UID_PLAYER then + begin + P := g_Player_Get(UID); + if P = nil then + begin + lua_pushnil(L); + exit; + end; + if P.Live then + lua_pushinteger(L, 1) + else if P.FSpectator then + lua_pushinteger(L, -1) + else + lua_pushinteger(L, 0); + end + else if g_GetUIDType(UID) = UID_MONSTER then + begin + M := g_Monsters_Get(UID); + if M = nil then + begin + lua_pushnil(L); + exit; + end; + lua_pushinteger(L, IfThen(M.Live, 1, 0)); + end + else + lua_pushnil(L); +end; + +function SP_Lua_ActorTeleport(L: PScriptContext): Integer; cdecl; +// game.uid_teleport(uid, to_x, to_y[, dir=left, silent=false, d2d_like=false]) +const + MINARGS = 3; +var + D2D, NoSound: Boolean; + UID, TX, TY: Integer; + TDir: Integer; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + UID := luaL_checkinteger(L, 1); + TX := luaL_checkinteger(L, 2); + TY := luaL_checkinteger(L, 3); + + TDir := lua_tointeger(L, 4) mod 2; + NoSound := lua_toboolean(L, 5); + D2D := lua_toboolean(L, 6); + + tr_Teleport(UID, TX, TY, TDir, NoSound, D2D); +end; + +function SP_Lua_ActorPush(L: PScriptContext): Integer; cdecl; +// game.uid_push(uid, vx, vy[, reset_vel=false]) +const + MINARGS = 3; +var + ResetVel: Boolean; + UID, VX, VY: Integer; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + UID := luaL_checkinteger(L, 1); + VX := luaL_checkinteger(L, 2); + VY := luaL_checkinteger(L, 3); + + ResetVel := lua_toboolean(L, 4); + + tr_Push(UID, VX, VY, ResetVel); +end; + +// triggers // + +function SP_Lua_TriggerSetEnabled(L: PScriptContext): Integer; cdecl; +// game.trigger_set_enabled(id, active) +const + MINARGS = 2; +var + TID: Integer; + Enabled: Boolean; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + TID := luaL_checkinteger(L, 1); + Enabled := lua_toboolean(L, 2); + + if (TID < 0) or (TID > High(gTriggers)) then exit; + if gTriggers[TID].TriggerType = TRIGGER_NONE then exit; + gTriggers[TID].Enabled := Enabled; +end; + +function SP_Lua_TriggerGetEnabled(L: PScriptContext): Integer; cdecl; +// game.trigger_get_enabled(id) +const + MINARGS = 1; +var + TID: Integer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + TID := luaL_checkinteger(L, 1); + + if (TID < 0) or (TID > High(gTriggers)) or (gTriggers[TID].TriggerType = TRIGGER_NONE) then + lua_pushnil(L) + else + lua_pushboolean(L, gTriggers[TID].Enabled); +end; + +function SP_Lua_TriggerActivate(L: PScriptContext): Integer; cdecl; +// game.trigger_activate(id[, activate_type=custom, activator_uid=0]) +const + MINARGS = 1; +var + TID, UID: Integer; + TAct: Byte; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + TID := luaL_checkinteger(L, 1); + + TAct := lua_tointeger(L, 2); + if TAct = 0 then TAct := 255; + UID := lua_tointeger(L, 3); + + if (TID < 0) or (TID > High(gTriggers)) then exit; + if gTriggers[TID].TriggerType = TRIGGER_NONE then exit; + if ByteBool(gTriggers[TID].ActivateType and TAct) then + g_Triggers_Press(TID, TAct, UID); +end; + +function SP_Lua_TriggerGetPos(L: PScriptContext): Integer; cdecl; +// game.trigger_get_pos(id) +const + MINARGS = 1; +var + TID: Integer; +begin + Result := 2; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + TID := luaL_checkinteger(L, 1); + + if (TID < 0) or (TID > High(gTriggers)) or (gTriggers[TID].TriggerType = TRIGGER_NONE) then + begin + lua_pushnil(L); + lua_pushnil(L); + end + else + begin + lua_pushinteger(L, gTriggers[TID].X); + lua_pushinteger(L, gTriggers[TID].Y); + end; +end; + +function SP_Lua_TriggerSetPos(L: PScriptContext): Integer; cdecl; +// game.trigger_set_pos(id, x, y) +const + MINARGS = 3; +var + TID, X, Y: Integer; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + TID := luaL_checkinteger(L, 1); + X := luaL_checkinteger(L, 2); + Y := luaL_checkinteger(L, 3); + + if (TID < 0) or (TID > High(gTriggers)) then exit; + if gTriggers[TID].TriggerType in [TRIGGER_NONE, TRIGGER_SOUND] then exit; + gTriggers[TID].X := X; + gTriggers[TID].Y := Y; +end; + +// doors & panels // + +function SP_Lua_PanelGetType(L: PScriptContext): Integer; cdecl; +// game.panel_get_type(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) then + lua_pushnil(L) + else + lua_pushinteger(L, Pan^.PanelType); +end; + +function SP_Lua_PanelGetPos(L: PScriptContext): Integer; cdecl; +// game.panel_get_pos(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 2; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) then + begin + lua_pushnil(L); + lua_pushnil(L); + end + else + begin + lua_pushinteger(L, Pan^.X); + lua_pushinteger(L, Pan^.Y); + end; +end; + +function SP_Lua_PanelGetSize(L: PScriptContext): Integer; cdecl; +// game.panel_get_size(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 2; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) then + begin + lua_pushnil(L); + lua_pushnil(L); + end + else + begin + lua_pushinteger(L, Pan^.Width); + lua_pushinteger(L, Pan^.Height); + end; +end; + +function SP_Lua_PanelSwitchTexture(L: PScriptContext): Integer; cdecl; +// game.panel_switch_texture(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) then exit; + g_Map_SwitchTexture(Pan^.PanelType, WID, 0); +end; + +function SP_Lua_PanelSetPos(L: PScriptContext): Integer; cdecl; +// game.panel_set_pos(panel_id, x, y) +const + MINARGS = 3; +var + PID, WID, X, Y: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + X := luaL_checkinteger(L, 2); + Y := luaL_checkinteger(L, 3); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) then exit; + if not (Pan.PanelType in [PANEL_BACK, PANEL_FORE]) then + begin + g_Console_Add('SCRIPT: panel_set_pos(): can only set pos for BACK and FORE right now'); + exit; + end; + Pan^.X := X; + Pan^.Y := Y; + if g_Game_IsNet then + MH_SEND_PanelState(Pan^.PanelType, WID); +end; + +function SP_Lua_DoorGetState(L: PScriptContext): Integer; cdecl; +// game.door_get_open(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or (not Pan^.Door) then + lua_pushnil(L) + else + lua_pushboolean(L, Pan^.Enabled); +end; + +function SP_Lua_LiftGetDir(L: PScriptContext): Integer; cdecl; +// game.lift_get_dir(panel_id) +const + MINARGS = 1; +var + PID, WID: Integer; + Pan: PPanel; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + PID := luaL_checkinteger(L, 1); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or ((Pan^.LiftType = 0) and (Pan^.PanelType <> PANEL_LIFTUP)) then + lua_pushnil(L) + else + lua_pushinteger(L, Pan^.LiftType); +end; + +function SP_Lua_DoorOpen(L: PScriptContext): Integer; cdecl; +// game.door_open(panel_id[, silent=false, d2d_like=false]) +const + MINARGS = 1; +var + D2D, NoSound: Boolean; + PID, WID: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + NoSound := lua_toboolean(L, 2); + D2D := lua_toboolean(L, 3); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or (not Pan^.Door) then exit; + tr_OpenDoor(WID, NoSound, D2D); +end; + +function SP_Lua_DoorClose(L: PScriptContext): Integer; cdecl; +// game.door_close(panel_id[, silent=false, d2d_like=false]) +const + MINARGS = 1; +var + D2D, NoSound: Boolean; + PID, WID: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + NoSound := lua_toboolean(L, 2); + D2D := lua_toboolean(L, 3); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or (not Pan^.Door) then exit; + tr_CloseDoor(WID, NoSound, D2D); +end; + +function SP_Lua_DoorToggle(L: PScriptContext): Integer; cdecl; +// game.door_toggle(panel_id[, silent=false, d2d_like=false]) +const + MINARGS = 1; +var + D2D, NoSound: Boolean; + PID, WID: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + NoSound := lua_toboolean(L, 2); + D2D := lua_toboolean(L, 3); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or (not Pan^.Door) then exit; + if gWalls[WID].Enabled then + tr_OpenDoor(WID, NoSound, D2D) + else + tr_CloseDoor(WID, NoSound, D2D); +end; + +function SP_Lua_DoorCloseTrap(L: PScriptContext): Integer; cdecl; +// game.door_close_trap(panel_id[, silent=false, d2d_like=false]) +const + MINARGS = 1; +var + D2D, NoSound: Boolean; + PID, WID: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + NoSound := lua_toboolean(L, 2); + D2D := lua_toboolean(L, 3); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or (not Pan^.Door) then exit; + tr_CloseTrap(WID, NoSound, D2D); +end; + +function SP_Lua_LiftSetDir(L: PScriptContext): Integer; cdecl; +// game.lift_set_dir(panel_id, dir[, silent=false, d2d_like=false]) +const + MINARGS = 2; +var + D2D, NoSound: Boolean; + PID, WID, Dir: Integer; + Pan: PPanel; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + PID := luaL_checkinteger(L, 1); + Dir := luaL_checkinteger(L, 2); + NoSound := lua_toboolean(L, 3); + D2D := lua_toboolean(L, 4); + + WID := -1; + Pan := g_Map_PanelForPID(PID, WID); + if (Pan = nil) or ((Pan^.LiftType = 0) and (Pan^.PanelType <> PANEL_LIFTUP)) then + exit; + tr_SetLift(WID, Dir, NoSound, D2D); +end; + +// spawners // + +function SP_Lua_SpawnShot(L: PScriptContext): Integer; cdecl; +// game.spawn_shot(type, x, y, vel_x, vel_y[, silent=false, target_id=0(noone)]) +const + MINARGS = 5; +var + wx, wy, dx, dy, ShotType, ShotTarget: Integer; + Silent: Boolean; + ShotTargetW: Word; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + ShotType := luaL_checkinteger(L, 1); + wx := luaL_checkinteger(L, 2); + wy := luaL_checkinteger(L, 3); + dx := luaL_checkinteger(L, 4); + dy := luaL_checkinteger(L, 5); + + Silent := lua_toboolean(L, 6); + ShotTarget := lua_tointeger(L, 7); + ShotTargetW := 0; + if (ShotTarget > 0) and (ShotTarget < $FFFF) then + ShotTargetW := ShotTarget; + + lua_pushinteger(L, tr_SpawnShot(ShotType, wx, wy, dx, dy, not Silent, ShotTargetW, DWORD(-1))); +end; + +function SP_Lua_SpawnEffect(L: PScriptContext): Integer; cdecl; +// game.spawn_effect(type, subtype, x, y, vel_x, vel_y[, silent=false, r=0, g=0, b=0]) +const + MINARGS = 6; +var + X, Y, VX, VY: Integer; + EType, ESubType: Integer; + ER, EG, EB: Integer; + Silent: Boolean; +begin + Result := 0; + if not CheckArgs(L, MINARGS) then exit; + + EType := luaL_checkinteger(L, 1); + ESubType := luaL_checkinteger(L, 2); + X := luaL_checkinteger(L, 3); + Y := luaL_checkinteger(L, 4); + VX := luaL_checkinteger(L, 5); + VY := luaL_checkinteger(L, 6); + + Silent := lua_toboolean(L, 7); + ER := lua_tointeger(L, 8); + EG := lua_tointeger(L, 8); + EB := lua_tointeger(L, 8); + + tr_MakeEffect(X, Y, VX, VY, EType, ESubType, ER, EG, EB, Silent, True); +end; + +function SP_Lua_SpawnMonster(L: PScriptContext): Integer; cdecl; +// game.spawn_monster(type, x, y[, dir=left, awake=false, health=default, aitype=normal]) +const + MINARGS = 3; +var + X, Y: Integer; + Dir: TDirection; + MType, MBType, MHP: Integer; + MAwake: Boolean; + MID, i: Integer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + MType := luaL_checkinteger(L, 1); + X := luaL_checkinteger(L, 2); + Y := luaL_checkinteger(L, 3); + + Dir := TDirection(lua_tointeger(L, 4) mod 2); + MAwake := lua_toboolean(L, 5); + MHP := lua_tointeger(L, 6); + MBType := lua_tointeger(L, 7); + + MID := -1; + + if MType in [MONSTER_DEMON..MONSTER_MAN] then + begin + i := g_Monsters_Create(MType, X, Y, Dir, True); + if i < 0 then exit; + if MHP > 0 then + gMonsters[i].SetHealth(MHP); + gMonsters[i].MonsterBehaviour := MBType; + gMonsters[i].FNoRespawn := True; + if g_Game_IsNet then + MH_SEND_MonsterSpawn(gMonsters[i].UID); + if MAwake then + gMonsters[i].WakeUp(); + if MType <> MONSTER_BARREL then Inc(gTotalMonsters); + if g_Game_IsNet then + begin + SetLength(gMonstersSpawned, Length(gMonstersSpawned)+1); + gMonstersSpawned[High(gMonstersSpawned)] := gMonsters[i].UID; + MH_SEND_GameStats(); + MH_SEND_CoopStats(); + end; + MID := gMonsters[i].UID; + end; + + lua_pushinteger(L, MID); +end; + +function SP_Lua_SpawnItem(L: PScriptContext): Integer; cdecl; +// game.spawn_item(type, x, y[, falls=false]) +const + MINARGS = 3; +var + X, Y: Integer; + IType: Integer; + IFalls: Boolean; + i: Integer; +begin + Result := 1; + if not CheckArgs(L, MINARGS) then + begin + Result := 0; + exit; + end; + + IType := luaL_checkinteger(L, 1); + X := luaL_checkinteger(L, 2); + Y := luaL_checkinteger(L, 3); + + IFalls := lua_toboolean(L, 4); + + i := -1; + if IType in [ITEM_MEDKIT_SMALL..ITEM_MAX] then + begin + i := g_Items_Create(X, Y, IType, IFalls, False, True); + if g_Game_IsNet then + MH_SEND_ItemSpawn(True, i); + end; + + lua_pushinteger(L, i); end; end.