mirror of
https://github.com/Michatec/ptelevision.git
synced 2026-04-01 07:56:29 +02:00
Compare commits
15 Commits
renderer_g
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67b71a8912 | ||
|
|
81e777ae9c | ||
|
|
acfc0b6232 | ||
|
|
d3ed042bdd | ||
|
|
081d452f49 | ||
|
|
969ce331e6 | ||
|
|
0f082b4114 | ||
|
|
95ec3294b8 | ||
|
|
42152a844e | ||
|
|
f67f8496df | ||
|
|
ee703e04d1 | ||
|
|
54fae17c32 | ||
|
|
fc55ac2d27 | ||
|
|
f4d70a0741 | ||
|
|
80b6fcf380 |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1 +0,0 @@
|
||||
ko_fi: picklemods
|
||||
11
README.md
11
README.md
@@ -1,5 +1,4 @@
|
||||
<div align='center'><img src='https://user-images.githubusercontent.com/111543470/198868741-d78353cf-0576-4f2e-8554-1f7e4ef4c986.png'/></div>
|
||||
<div align='center'><h3><a href='https://picklemods.com/'>More Information & Scripts can be found here!</a></h3></div>
|
||||
<div align='center'><img src='https://michatec.github.io/ptelevision_web/ptelevision.png'/></div>
|
||||
|
||||
## What is this?
|
||||
|
||||
@@ -16,12 +15,8 @@ With this resource, you will be able to do the following:
|
||||
|
||||
You will need the following for this script to work.
|
||||
|
||||
- [Ox Lib](https://github.com/overextended/ox_lib/releases) (works with any framework)
|
||||
- [Ox Lib](https://github.com/CommunityOx/ox_lib/releases) (works with any framework)
|
||||
|
||||
- [Renderer](https://forum.cfx.re/t/release-generic-dui-2d-3d-renderer/131208) (works with any framework)
|
||||
- [Renderer](https://github.com/Michatec/ptelevision/releases/tag/renderer_gfx) (works with any framework)
|
||||
|
||||
If you want to make a fork, please obtain permission with a valid reason.
|
||||
|
||||
## Need Support?
|
||||
|
||||
<a href='https://pickle-mods.tebex.io/contact'>Click here!</a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local scale = 1.5
|
||||
local screenWidth = math.floor(1920 / scale)
|
||||
local screenHeight = math.floor(1080 / scale)
|
||||
shouldDraw = false
|
||||
local shouldDraw = false
|
||||
|
||||
function SetInteractScreen(bool)
|
||||
if (not shouldDraw and bool) then
|
||||
@@ -19,7 +19,7 @@ function SetInteractScreen(bool)
|
||||
local minY, maxY = ((h - (h / 2)) / 2), (h - (h / 4))
|
||||
local totalY = minY - maxY
|
||||
|
||||
RequestTextureDictionary('fib_pc')
|
||||
lib.requestStreamedTextureDict('fib_pc')
|
||||
|
||||
-- Update controls while active
|
||||
while shouldDraw do
|
||||
@@ -27,7 +27,7 @@ function SetInteractScreen(bool)
|
||||
nY = GetControlNormal(0, 240) * screenHeight
|
||||
DisableControlAction(0, 1, true) -- Disable looking horizontally
|
||||
DisableControlAction(0, 2, true) -- Disable looking vertically
|
||||
DisablePlayerFiring(PlayerPedId(), true) -- Disable weapon firing
|
||||
DisablePlayerFiring(cache.ped, true) -- Disable weapon firing
|
||||
DisableControlAction(0, 142, true) -- Disable aiming
|
||||
DisableControlAction(0, 106, true) -- Disable in-game mouse controls
|
||||
-- Update mouse position when changed
|
||||
|
||||
@@ -12,28 +12,11 @@ function CreateNamedRenderTargetForModel(name, model)
|
||||
return handle
|
||||
end
|
||||
|
||||
function RequestTextureDictionary(dict)
|
||||
RequestStreamedTextureDict(dict)
|
||||
while not HasStreamedTextureDictLoaded(dict) do Wait(0) end
|
||||
return dict
|
||||
end
|
||||
|
||||
function LoadModel(model)
|
||||
if not IsModelInCdimage(model) then return end
|
||||
RequestModel(model)
|
||||
while not HasModelLoaded(model) do Wait(0) end
|
||||
return model
|
||||
end
|
||||
|
||||
function RenderScaleformTV(renderTarget, scaleform, entity)
|
||||
SetTextRenderId(renderTarget) -- set render target
|
||||
Set_2dLayer(4)
|
||||
SetScriptGfxDrawBehindPausemenu(1)
|
||||
--DrawRect(0.5, 0.5, 1.0, 0.5, 255, 0, 0, 255); -- WOAH!
|
||||
local coords = GetEntityCoords(entity)
|
||||
local rot = GetEntityRotation(entity)
|
||||
SetTextRenderId(renderTarget)
|
||||
SetScriptGfxDrawOrder(4)
|
||||
SetScriptGfxDrawBehindPausemenu(true)
|
||||
DrawSprite("ptelevision_b_dict", "ptelevision_b_txd", 0.5, 0.5, 1.0, 1.0, 0.0, 255, 255, 255, 255)
|
||||
SetTextRenderId(GetDefaultScriptRendertargetRenderId()) -- reset
|
||||
SetScriptGfxDrawBehindPausemenu(0)
|
||||
SetTextRenderId(GetDefaultScriptRendertargetRenderId())
|
||||
SetScriptGfxDrawBehindPausemenu(false)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
DEFAULT_URL = "https://cfx-nui-ptelevision/html/index.html"
|
||||
DEFAULT_URL = "https://michatec.github.io/ptelevision_web/index.html"
|
||||
duiUrl = DEFAULT_URL
|
||||
duiObj = nil
|
||||
tvObj = nil
|
||||
@@ -37,20 +37,9 @@ local height = 720
|
||||
local sfHandle = nil
|
||||
local txdHasBeenSet = false
|
||||
|
||||
|
||||
function loadScaleform(scaleform)
|
||||
local scaleformHandle = RequestScaleformMovie(scaleform)
|
||||
|
||||
while not HasScaleformMovieLoaded(scaleformHandle) do
|
||||
scaleformHandle = RequestScaleformMovie(scaleform)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
return scaleformHandle
|
||||
end
|
||||
|
||||
function ShowScreen(data)
|
||||
CURRENT_SCREEN = data
|
||||
sfHandle = loadScaleform(sfName)
|
||||
sfHandle = lib.requestScaleformMovie(sfName)
|
||||
runtimeTxd = 'ptelevision_b_dict'
|
||||
|
||||
local txd = CreateRuntimeTxd('ptelevision_b_dict')
|
||||
@@ -105,7 +94,7 @@ function ShowScreen(data)
|
||||
SetVolume(coords, modelData.DefaultVolume)
|
||||
end
|
||||
while duiObj do
|
||||
local pcoords = GetEntityCoords(PlayerPedId())
|
||||
local pcoords = GetEntityCoords(cache.ped)
|
||||
local dist = #(coords - pcoords)
|
||||
SendDuiMessage(duiObj, json.encode({
|
||||
setVolume = true,
|
||||
@@ -129,7 +118,7 @@ end
|
||||
function GetClosestScreen()
|
||||
local objPool = GetGamePool('CObject')
|
||||
local closest = {dist = -1}
|
||||
local pcoords = GetEntityCoords(PlayerPedId())
|
||||
local pcoords = GetEntityCoords(cache.ped)
|
||||
for i=1, #objPool do
|
||||
local entity = objPool[i]
|
||||
local model = GetEntityModel(entity)
|
||||
@@ -165,9 +154,9 @@ Citizen.CreateThread(function()
|
||||
local wait = 2500
|
||||
for i=1, #Locations do
|
||||
local data = Locations[i]
|
||||
local dist = #(GetEntityCoords(PlayerPedId()) - v3(data.Position))
|
||||
local dist = #(GetEntityCoords(cache.ped) - v3(data.Position))
|
||||
if not Locations[i].obj and dist < 20.0 then
|
||||
LoadModel(data.Model)
|
||||
lib.requestModel(data.Model)
|
||||
Locations[i].obj = CreateObject(data.Model, data.Position.x, data.Position.y, data.Position.z)
|
||||
SetEntityHeading(Locations[i].obj, data.Position.w)
|
||||
FreezeEntityPosition(Locations[i].obj, true)
|
||||
@@ -207,11 +196,9 @@ RegisterNetEvent("ptelevision:requestSync", function(coords, data)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
RegisterNUICallback("pageLoaded", function(cb)
|
||||
RegisterNUICallback("pageLoaded", function(data, cb)
|
||||
waitForLoad = false
|
||||
if cb then cb() end
|
||||
cb(1)
|
||||
end)
|
||||
|
||||
AddEventHandler('onResourceStop', function(name)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
TelevisionsLocal = {}
|
||||
local TelevisionsLocal = {}
|
||||
|
||||
function SetChannel(index)
|
||||
TriggerServerEvent("ptelevision:event", CURRENT_SCREEN, "ptv_status", {
|
||||
@@ -20,8 +20,8 @@ function GetChannelList()
|
||||
channel = status.channel
|
||||
end
|
||||
for index,value in pairs(Channels) do
|
||||
table.insert(channel_list, {index = index, url = value.url})
|
||||
table.insert(menu_list, "Channel #" .. index .. " (".. value.name ..")")
|
||||
channel_list[#channel_list+1] = {index = index, url = value.url}
|
||||
menu_list[#menu_list+1] = "Channel #" .. index .. " (".. value.name ..")"
|
||||
if channel ~= nil and channel == index then
|
||||
current = #channel_list
|
||||
end
|
||||
@@ -59,11 +59,17 @@ end
|
||||
|
||||
function VideoMenu()
|
||||
lib.hideMenu()
|
||||
local input = lib.inputDialog('Video Player', {'URL:'})
|
||||
local input = lib.inputDialog('Video Player', {
|
||||
{ type = 'input', label = 'Video URL' },
|
||||
{ type = 'checkbox', label = 'Loop Video' },
|
||||
{ type = 'checkbox', label = 'Show Video Controls' }
|
||||
})
|
||||
if input then
|
||||
TriggerServerEvent("ptelevision:event", CURRENT_SCREEN, "ptv_status", {
|
||||
type = "play",
|
||||
url = input[1]
|
||||
url = input[1],
|
||||
loop = input[2],
|
||||
showControls = input[3]
|
||||
})
|
||||
end
|
||||
Citizen.Wait(300)
|
||||
@@ -95,10 +101,6 @@ function OpenTVMenu()
|
||||
SetChannel(ChannelList.list[scrollIndex].index)
|
||||
end
|
||||
end,
|
||||
onSelected = function(selected, scrollIndex, args)
|
||||
end,
|
||||
onClose = function(keyPressed)
|
||||
end,
|
||||
options = {
|
||||
{label = 'Videos', description = 'Play a video or stream on the screen.'},
|
||||
{label = 'Web Browser', description = 'Access the web via your TV.'},
|
||||
@@ -185,7 +187,7 @@ RegisterNetEvent("ptelevision:event", function(data, index, key, value)
|
||||
if (index) then
|
||||
local event = value
|
||||
if (event.type == "play") then
|
||||
local data = { url = event.url }
|
||||
local data = { url = event.url, loop = event.loop, showControls = event.showControls }
|
||||
if (event.channel) then
|
||||
data = Channels[event.channel]
|
||||
data.channel = event.channel
|
||||
@@ -219,8 +221,9 @@ end)
|
||||
|
||||
RegisterCommand('tv', function()
|
||||
OpenTVMenu()
|
||||
end)
|
||||
end, false)
|
||||
|
||||
RegisterCommand("broadcast", function(source, args, raw)
|
||||
RegisterCommand('broadcast', function()
|
||||
BroadcastMenu()
|
||||
end)
|
||||
end, false)
|
||||
|
||||
|
||||
15
config.lua
15
config.lua
@@ -120,6 +120,20 @@ Config.Models = { -- Any TV Models used on the map or in locations must be defin
|
||||
Scale = 0.085,
|
||||
Offset = vector3(-1.02, -0.055, 1.04)
|
||||
},
|
||||
[-240931727] = { --Casino Penthouse Theater Room
|
||||
DefaultVolume = 0.5,
|
||||
Range = 20.0,
|
||||
Target = "tvscreen", -- Only use if prop has render-target name.
|
||||
Scale = 0.085,
|
||||
Offset = vector3(-1.02, -0.055, 1.04)
|
||||
},
|
||||
[`v_ilev_cin_screen`] = { --Cinema/Theater Screen
|
||||
DefaultVolume = 0.5,
|
||||
Range = 60.0,
|
||||
Target = "cinscreen", -- Only use if prop has render-target name.
|
||||
Scale = 0.085,
|
||||
Offset = vector3(-1.02, -0.055, 1.04)
|
||||
},
|
||||
}
|
||||
|
||||
Config.Locations = { -- REMOVE ALL IF NOT USING ONESYNC, OR IT SHALL BREAK.
|
||||
@@ -152,3 +166,4 @@ Config.Events = { -- Events for approving broadcasts / interactions (due to popu
|
||||
cb()
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fx_version "cerulean"
|
||||
game "gta5"
|
||||
author "Pickle Mods#0001"
|
||||
version "v1.2.5"
|
||||
author "Pickle Mods & Michatec"
|
||||
version "v1.2.6"
|
||||
ui_page "html/blank.html"
|
||||
|
||||
files {
|
||||
@@ -30,3 +30,4 @@ server_scripts {
|
||||
}
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
|
||||
161
html/main.js
161
html/main.js
@@ -1,110 +1,127 @@
|
||||
var player;
|
||||
var playerData;
|
||||
$(document).ready(function() {
|
||||
$.post("https://ptelevision/pageLoaded", JSON.stringify({}))
|
||||
})
|
||||
|
||||
function GetURLID(link) {
|
||||
if (link == null) return;
|
||||
let url = link.toString();
|
||||
var regExp = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
|
||||
var regExp =
|
||||
/^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
if (match && match[2].length == 11) {
|
||||
return {type: "youtube", id: match[2]};
|
||||
}
|
||||
else if (url.split("twitch.tv/").length > 1) {
|
||||
|
||||
return {type: "twitch", id: url.split("twitch.tv/")[1]};
|
||||
return { type: "youtube", id: match[2] };
|
||||
} else if (url.split("twitch.tv/").length > 1) {
|
||||
return { type: "twitch", id: url.split("twitch.tv/")[1] };
|
||||
}
|
||||
}
|
||||
|
||||
function ChannelDisplay(channel, channelFound) {
|
||||
if (channel) {
|
||||
var temp = 'CH<span style="font-size: 18pt !important;"> </span>'
|
||||
var temp = 'CH<span style="font-size: 18pt !important;"> </span>';
|
||||
if (channel > 9) {
|
||||
temp += channel
|
||||
temp += channel;
|
||||
} else {
|
||||
temp += "0" + channel;
|
||||
}
|
||||
else {
|
||||
temp += ("0" + channel)
|
||||
}
|
||||
$("#overlay span").show()
|
||||
$("#overlay span").html(temp)
|
||||
}
|
||||
else {
|
||||
$("#overlay span").show()
|
||||
$("#overlay span").html("")
|
||||
$("#overlay span").show();
|
||||
$("#overlay span").html(temp);
|
||||
} else {
|
||||
$("#overlay span").show();
|
||||
$("#overlay span").html("");
|
||||
}
|
||||
if (channelFound) {
|
||||
$("#tv-container").hide()
|
||||
}
|
||||
else {
|
||||
$("#tv-container").show()
|
||||
$("#tv-container").hide();
|
||||
} else {
|
||||
$("#tv-container").show();
|
||||
}
|
||||
}
|
||||
|
||||
function SetVideo(video_data) {
|
||||
var url = video_data.url;
|
||||
var channel = video_data.channel;
|
||||
var data = GetURLID(url)
|
||||
var loop = video_data.loop;
|
||||
var showControls = Number(video_data.showControls);
|
||||
var data = GetURLID(url);
|
||||
|
||||
playerData = data
|
||||
playerData = data;
|
||||
if (player) {
|
||||
player.destroy()
|
||||
player.destroy();
|
||||
player = null;
|
||||
}
|
||||
if (data) {
|
||||
if (data.type == "youtube") {
|
||||
player = new YT.Player('twitch-embed', {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
if (loop == true) {
|
||||
player = new YT.Player("twitch-embed", {
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
videoId: data.id,
|
||||
playerVars: {
|
||||
'playsinline': 1,
|
||||
playsinline: 1,
|
||||
loop: 1,
|
||||
playlist: data.id,
|
||||
controls: showControls,
|
||||
},
|
||||
events: {
|
||||
'onReady': function(event) {
|
||||
onReady: function (event) {
|
||||
event.target.playVideo();
|
||||
event.target.seekTo(video_data.time)
|
||||
event.target.seekTo(video_data.time);
|
||||
},
|
||||
'onStateChange': function(event) {
|
||||
onStateChange: function (event) {
|
||||
if (event.data == YT.PlayerState.PLAYING) {
|
||||
event.target.unMute();
|
||||
} else if (event.data == YT.PlayerState.PAUSED) {
|
||||
}
|
||||
else if (event.data == YT.PlayerState.PAUSED) {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
player = new YT.Player("twitch-embed", {
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
videoId: data.id,
|
||||
playerVars: {
|
||||
playsinline: 1,
|
||||
controls: showControls,
|
||||
},
|
||||
events: {
|
||||
onReady: function (event) {
|
||||
event.target.playVideo();
|
||||
event.target.seekTo(video_data.time);
|
||||
},
|
||||
onStateChange: function (event) {
|
||||
if (event.data == YT.PlayerState.PLAYING) {
|
||||
event.target.unMute();
|
||||
} else if (event.data == YT.PlayerState.PAUSED) {
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
else if (data.type == "twitch") {
|
||||
} else if (data.type == "twitch") {
|
||||
player = new Twitch.Player("twitch-embed", {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
channel: data.id,
|
||||
volume: 1.0
|
||||
volume: 1.0,
|
||||
});
|
||||
player.addEventListener(Twitch.Embed.VIDEO_READY, function() {
|
||||
player.addEventListener(Twitch.Embed.VIDEO_READY, function () {
|
||||
player.setMuted(false);
|
||||
});
|
||||
}
|
||||
|
||||
$("#overlay span").hide()
|
||||
$("#tv-container").hide()
|
||||
$("#overlay span").hide();
|
||||
$("#tv-container").hide();
|
||||
}
|
||||
if (channel) {
|
||||
ChannelDisplay(channel, url)
|
||||
ChannelDisplay(channel, url);
|
||||
}
|
||||
}
|
||||
|
||||
function SetVolume(volume) {
|
||||
|
||||
if (player && playerData && player.setVolume) {
|
||||
if (playerData.type == "twitch") {
|
||||
player.setMuted(false);
|
||||
player.setVolume(volume / 100.0);
|
||||
}
|
||||
else if (playerData.type == "youtube") {
|
||||
} else if (playerData.type == "youtube") {
|
||||
player.unMute();
|
||||
player.setVolume(volume);
|
||||
}
|
||||
@@ -112,33 +129,37 @@ function SetVolume(volume) {
|
||||
}
|
||||
|
||||
function ShowNotification(channel, data) {
|
||||
$("#tv-container").addClass("notify")
|
||||
$("#tv-container div").addClass("notify")
|
||||
var display = $('#tv-container').is(':visible')
|
||||
$('#tv-container').show()
|
||||
$("#tv-container div").html("Channel #" + channel + (data ? (" ("+data.name+")") : "") + " is now " + (data ? "live!" : "offline."))
|
||||
$("#tv-container").addClass("notify");
|
||||
$("#tv-container div").addClass("notify");
|
||||
var display = $("#tv-container").is(":visible");
|
||||
$("#tv-container").show();
|
||||
$("#tv-container div").html(
|
||||
"Channel #" +
|
||||
channel +
|
||||
(data ? " (" + data.name + ")" : "") +
|
||||
" is now " +
|
||||
(data ? "live!" : "offline.")
|
||||
);
|
||||
|
||||
setTimeout(function() {
|
||||
$("#tv-container").removeClass("notify")
|
||||
$("#tv-container div").removeClass("notify")
|
||||
$("#tv-container div").html("NO SIGNAL")
|
||||
setTimeout(function () {
|
||||
$("#tv-container").removeClass("notify");
|
||||
$("#tv-container div").removeClass("notify");
|
||||
$("#tv-container div").html("NO SIGNAL");
|
||||
if (!display) {
|
||||
$('#tv-container').hide()
|
||||
$("#tv-container").hide();
|
||||
}
|
||||
}, 3500)
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
window.addEventListener("message", function(ev) {
|
||||
window.addEventListener("message", function (ev) {
|
||||
if (ev.data.setVideo) {
|
||||
SetVideo(ev.data.data)
|
||||
SetVideo(ev.data.data);
|
||||
} else if (ev.data.setVolume) {
|
||||
SetVolume(ev.data.data);
|
||||
} else if (ev.data.showNotification) {
|
||||
ShowNotification(ev.data.channel, ev.data.data);
|
||||
}
|
||||
else if (ev.data.setVolume) {
|
||||
SetVolume(ev.data.data)
|
||||
}
|
||||
else if (ev.data.showNotification) {
|
||||
ShowNotification(ev.data.channel, ev.data.data)
|
||||
}
|
||||
})
|
||||
$(document).ready(function() {
|
||||
ChannelDisplay()
|
||||
})
|
||||
});
|
||||
$(document).ready(function () {
|
||||
ChannelDisplay();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user