2024-08-25 17:10:57 -04:00
|
|
|
local spectate = {}
|
|
|
|
|
2024-08-28 13:54:05 +03:00
|
|
|
local gui = GuiCreate()
|
|
|
|
|
2024-08-26 15:02:50 -04:00
|
|
|
local camera_player
|
2024-08-25 17:10:57 -04:00
|
|
|
|
2024-08-26 15:02:50 -04:00
|
|
|
local re_cam = false
|
|
|
|
|
|
|
|
local camera_player_id
|
2024-08-26 12:25:16 -04:00
|
|
|
|
2024-08-25 17:10:57 -04:00
|
|
|
local camera_target
|
|
|
|
|
2024-08-26 12:25:16 -04:00
|
|
|
local cam_target
|
|
|
|
|
2024-08-25 17:10:57 -04:00
|
|
|
local inventory_target
|
|
|
|
|
2024-08-26 12:25:16 -04:00
|
|
|
local left_held = false
|
|
|
|
|
|
|
|
local right_held = false
|
|
|
|
|
2024-08-28 12:18:40 -04:00
|
|
|
local was_notplayer = false
|
|
|
|
|
2024-08-26 15:02:50 -04:00
|
|
|
local function get_me()
|
|
|
|
local i = 0
|
|
|
|
for peer_id, _ in pairs(ctx.players) do
|
|
|
|
i = i + 1
|
|
|
|
if peer_id == ctx.my_id then
|
|
|
|
return i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-08-26 12:25:16 -04:00
|
|
|
local function target()
|
2024-08-28 15:58:23 -04:00
|
|
|
if cam_target.entity == ctx.my_player.entity and not EntityHasTag(ctx.my_player.entity, "ew_notplayer") then
|
2024-08-26 12:25:16 -04:00
|
|
|
GameSetCameraFree(false)
|
|
|
|
if camera_target == nil then
|
2024-08-28 15:58:23 -04:00
|
|
|
camera_target = ctx.my_player
|
|
|
|
elseif camera_target.entity ~= ctx.my_player.entity then
|
|
|
|
local audio = EntityGetFirstComponent(camera_target.entity, "AudioListenerComponent")
|
|
|
|
local audio_n = EntityAddComponent2(cam_target.entity, "AudioListenerComponent")
|
2024-08-28 12:18:40 -04:00
|
|
|
ComponentSetValue2(audio_n, "z", ComponentGetValue2(audio, "z"))
|
2024-08-28 15:58:23 -04:00
|
|
|
local keep_alive = EntityGetFirstComponent(camera_target.entity, "StreamingKeepAliveComponent")
|
|
|
|
EntityRemoveComponent(camera_target.entity, audio)
|
|
|
|
EntityRemoveComponent(camera_target.entity, keep_alive)
|
|
|
|
EntityRemoveComponent(camera_target.entity, inventory_target)
|
2024-08-26 12:25:16 -04:00
|
|
|
camera_target = cam_target
|
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
GameSetCameraFree(true)
|
2024-08-28 15:58:23 -04:00
|
|
|
if not EntityGetIsAlive(cam_target.entity) then
|
2024-08-28 15:03:21 -04:00
|
|
|
return
|
|
|
|
end
|
2024-08-28 15:58:23 -04:00
|
|
|
local t_x, t_y = EntityGetFirstHitboxCenter(cam_target.entity)
|
2024-08-26 12:25:16 -04:00
|
|
|
if t_x == nil then
|
2024-08-28 15:58:23 -04:00
|
|
|
t_x, t_y = EntityGetTransform(cam_target.entity)
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
|
|
|
GameSetCameraPos(t_x, t_y)
|
|
|
|
if camera_target == nil then
|
2024-08-28 15:58:23 -04:00
|
|
|
camera_target = ctx.my_player
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
2024-08-28 15:58:23 -04:00
|
|
|
if camera_target.entity ~= cam_target.entity then
|
|
|
|
if ctx.my_player.entity ~= camera_target.entity and inventory_target ~= nil then
|
|
|
|
EntityRemoveComponent(camera_target.entity, inventory_target)
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
inventory_target = nil
|
2024-08-28 15:58:23 -04:00
|
|
|
if ctx.my_player.entity ~= cam_target.entity then
|
|
|
|
inventory_target = EntityAddComponent2(cam_target.entity, "InventoryGuiComponent")
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
2024-08-28 15:58:23 -04:00
|
|
|
local audio = EntityGetFirstComponent(camera_target.entity, "AudioListenerComponent")
|
|
|
|
local keep_alive = EntityGetFirstComponent(camera_target.entity, "StreamingKeepAliveComponent")
|
2024-08-26 12:25:16 -04:00
|
|
|
if audio ~= nil then
|
2024-08-28 15:58:23 -04:00
|
|
|
local audio_n = EntityAddComponent2(cam_target.entity, "AudioListenerComponent")
|
2024-08-28 12:18:40 -04:00
|
|
|
ComponentSetValue2(audio_n, "z", ComponentGetValue2(audio, "z"))
|
2024-08-28 15:58:23 -04:00
|
|
|
EntityRemoveComponent(camera_target.entity, audio)
|
|
|
|
if camera_target.entity ~= ctx.my_player.entity then
|
|
|
|
EntityRemoveComponent(camera_target.entity, keep_alive)
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
2024-08-28 15:58:23 -04:00
|
|
|
if cam_target.entity ~= ctx.my_player.entity then
|
|
|
|
EntityAddComponent2(cam_target.entity, "StreamingKeepAliveComponent")
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
camera_target = cam_target
|
|
|
|
end
|
|
|
|
|
2024-08-25 17:10:57 -04:00
|
|
|
local function set_camera_pos()
|
2024-08-26 15:02:50 -04:00
|
|
|
if cam_target == nil or re_cam then
|
|
|
|
local i = 0
|
2024-08-26 12:25:16 -04:00
|
|
|
for peer_id, potential_target in pairs(ctx.players) do
|
|
|
|
i = i + 1
|
2024-08-26 18:10:50 -04:00
|
|
|
if i == camera_player then
|
2024-08-28 15:58:23 -04:00
|
|
|
cam_target = potential_target
|
2024-08-26 12:25:16 -04:00
|
|
|
camera_player = i
|
2024-08-26 15:02:50 -04:00
|
|
|
re_cam = false
|
2024-08-26 12:25:16 -04:00
|
|
|
camera_player_id = peer_id
|
|
|
|
break
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
end
|
2024-08-26 15:02:50 -04:00
|
|
|
if cam_target == nil then
|
|
|
|
camera_player = get_me()
|
|
|
|
camera_player_id = ctx.my_id
|
|
|
|
re_cam = true
|
2024-08-26 12:25:16 -04:00
|
|
|
set_camera_pos()
|
|
|
|
else
|
|
|
|
target()
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
2024-08-26 12:25:16 -04:00
|
|
|
else
|
|
|
|
target()
|
|
|
|
end
|
|
|
|
end
|
2024-08-25 17:10:57 -04:00
|
|
|
|
2024-08-26 12:25:16 -04:00
|
|
|
local function update_i()
|
2024-08-26 15:02:50 -04:00
|
|
|
local i = 0
|
2024-08-26 12:25:16 -04:00
|
|
|
for peer_id, _ in pairs(ctx.players) do
|
|
|
|
i = i + 1
|
|
|
|
if peer_id == camera_player_id then
|
|
|
|
camera_player = i
|
2024-08-26 15:02:50 -04:00
|
|
|
re_cam = true
|
|
|
|
return
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
end
|
2024-08-26 18:10:50 -04:00
|
|
|
camera_player = get_me()
|
|
|
|
camera_player_id = ctx.my_id
|
2024-08-26 15:02:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
local function number_of_players()
|
|
|
|
local i = 0
|
|
|
|
for _, _ in pairs(ctx.players) do
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
return i
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
|
2024-08-26 12:25:16 -04:00
|
|
|
local last_len
|
2024-08-25 17:10:57 -04:00
|
|
|
|
|
|
|
function spectate.on_world_update()
|
2024-08-28 12:18:40 -04:00
|
|
|
if EntityHasTag(ctx.my_player.entity, "ew_notplayer") then
|
|
|
|
was_notplayer = true
|
|
|
|
elseif was_notplayer then
|
|
|
|
was_notplayer = false
|
|
|
|
camera_player = get_me()
|
|
|
|
camera_player_id = ctx.my_id
|
|
|
|
re_cam = true
|
|
|
|
end
|
2024-08-26 15:02:50 -04:00
|
|
|
if camera_player == nil then
|
|
|
|
camera_player = get_me()
|
|
|
|
camera_player_id = ctx.my_id
|
2024-08-28 12:18:40 -04:00
|
|
|
re_cam = true
|
2024-08-26 15:02:50 -04:00
|
|
|
end
|
2024-08-26 12:25:16 -04:00
|
|
|
if last_len == nil then
|
2024-08-26 15:02:50 -04:00
|
|
|
last_len = number_of_players()
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
2024-08-28 15:58:23 -04:00
|
|
|
if last_len ~= number_of_players() or (cam_target ~= nil and not EntityGetIsAlive(cam_target.entity)) then
|
2024-08-26 12:25:16 -04:00
|
|
|
update_i()
|
2024-08-26 15:02:50 -04:00
|
|
|
last_len = number_of_players()
|
2024-08-26 12:25:16 -04:00
|
|
|
end
|
|
|
|
|
2024-08-25 17:10:57 -04:00
|
|
|
if InputIsKeyDown(54) then
|
|
|
|
if not left_held then
|
|
|
|
camera_player = camera_player - 1
|
2024-08-26 15:02:50 -04:00
|
|
|
if camera_player < 1 then
|
|
|
|
camera_player = last_len
|
|
|
|
end
|
2024-08-25 17:10:57 -04:00
|
|
|
left_held = true
|
2024-08-26 15:02:50 -04:00
|
|
|
re_cam = true
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
elseif InputIsKeyDown(55) then
|
|
|
|
if not right_held then
|
|
|
|
camera_player = camera_player + 1
|
2024-08-26 15:02:50 -04:00
|
|
|
if camera_player > last_len then
|
|
|
|
camera_player = 1
|
|
|
|
end
|
2024-08-25 17:10:57 -04:00
|
|
|
right_held = true
|
2024-08-26 15:02:50 -04:00
|
|
|
re_cam = true
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
else
|
|
|
|
left_held = false
|
|
|
|
right_held = false
|
|
|
|
end
|
|
|
|
set_camera_pos()
|
2024-08-27 19:54:54 +03:00
|
|
|
ctx.spectating_over_peer_id = camera_player_id
|
2024-08-28 13:54:05 +03:00
|
|
|
|
|
|
|
GuiStartFrame(gui)
|
|
|
|
GuiZSet(gui, 11)
|
|
|
|
if GameHasFlagRun("ew_flag_notplayer_active") then
|
|
|
|
local w, h = GuiGetScreenDimensions(gui)
|
|
|
|
local text = "Use ',' and '.' keys to spectate over other players."
|
|
|
|
local tw, th = GuiGetTextDimensions(gui, text)
|
|
|
|
GuiText(gui, w-2-tw, h-1-th, text)
|
|
|
|
end
|
2024-08-28 18:53:18 -04:00
|
|
|
if cam_target.entity ~= ctx.my_player.entity then
|
|
|
|
local inv_spec = EntityGetFirstComponent(cam_target.entity, "InventoryGuiComponent")
|
|
|
|
local inv_me = EntityGetFirstComponent(ctx.my_player.entity, "InventoryGuiComponent")
|
2024-08-29 11:22:07 -04:00
|
|
|
if inv_spec ~= nil then
|
|
|
|
ComponentSetValue2(inv_spec, "mActive", false)
|
|
|
|
end
|
2024-08-28 18:53:18 -04:00
|
|
|
ComponentSetValue2(inv_me, "mActive", false)
|
|
|
|
end
|
2024-08-25 17:10:57 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
return spectate
|