added new scripts and eup
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://nulledleaks.net/index.php
|
||||
@@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://nulledleaks.net/index.php
|
||||
@@ -0,0 +1,306 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
Game = {}
|
||||
Game.data = {}
|
||||
Game.__index = Game
|
||||
|
||||
local firstInit, total_stroke, inGame = true, 0, false
|
||||
allGame = {}
|
||||
c, s = nil, nil
|
||||
|
||||
setmetatable(Game, {
|
||||
__call = function(cls, index)
|
||||
self = Game.new(index)
|
||||
return self
|
||||
end
|
||||
})
|
||||
|
||||
function Game.new(hole)
|
||||
local self = setmetatable({}, Game)
|
||||
|
||||
self.hole = hole
|
||||
self.stroke = 0
|
||||
self.ped = assert(PlayerPedId)
|
||||
|
||||
self.ball = Object('prop_golf_ball', Config.golf_track[self.hole].start)
|
||||
self.club = Object('prop_golf_putter_01', Utils:getEntityCoords(self.ped()))
|
||||
|
||||
ApplyBallParams(self.ball.object)
|
||||
AttachEntityToEntity(self.club.object, self.ped(), GetPedBoneIndex(self.ped(), 28422), 0, 0, 0, 0.0, 0.0, 0.0, false, false, false, true, 0, true)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Game:addStroke()
|
||||
local hasMaxStroke = false
|
||||
|
||||
if self.stroke + 1 >= Config.max_stroke + 1 then
|
||||
self.stroke, hasMaxStroke = Config.max_stroke, true
|
||||
else
|
||||
self.stroke = self.stroke + 1
|
||||
end
|
||||
|
||||
for key, value in pairs(allGame) do
|
||||
if rawequal(value.hole, self.hole) then
|
||||
value.stroke = self.stroke
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if hasMaxStroke then
|
||||
DrawLineActive, self.ball, self.club = false, self.ball:delete(), self.club:delete()
|
||||
|
||||
Ui:displayNotification(translation["max_stroke"])
|
||||
|
||||
Utils:freezeEntity(c.ped(), false)
|
||||
ClearPedTasksImmediately(c.ped())
|
||||
|
||||
if self.hole + 1 < #Config.golf_track then
|
||||
self.hole = self.hole + 1
|
||||
TriggerEvent("mrw_minigolf:st_game", self.hole)
|
||||
else
|
||||
total_stroke = total_stroke + self.stroke
|
||||
|
||||
CreateThread(DisplayScaleform)
|
||||
s:addContent(translation["congrats"], ("%s %s %s"):format(translation["finish_game"], total_stroke, translation["stroke"]))
|
||||
|
||||
SetTimeout(2500, function()
|
||||
TriggerEvent("mrw_minigolf:cut_game")
|
||||
end)
|
||||
end
|
||||
|
||||
self, inGame = nil, false
|
||||
end
|
||||
|
||||
return hasMaxStroke
|
||||
end
|
||||
|
||||
function Game:shoot()
|
||||
|
||||
Utils:setEntityHeading(self.ball.object, 0.0)
|
||||
|
||||
local coords = Utils:getEntityCoords(self.ped())
|
||||
local power = getPower()
|
||||
local cam = camPosition()
|
||||
local offset = GetOffsetFromEntityGivenWorldCoords(self.ball.object, cam.x, cam.y, cam.z)
|
||||
|
||||
Utils:playAnimation("mini@golfai", "iron_swing_action", {coords.x - 0.6, coords.y + 0.2, coords.z}, 5000, 0)
|
||||
|
||||
SetTimeout(500, function()
|
||||
Utils:playSoundFromEntity("GOLF_SWING_FAIRWAY_IRON_LIGHT_MASTER")
|
||||
|
||||
FreezeEntityPosition(self.ball.object, false)
|
||||
SetEntityVelocity(self.ball.object, offset.x * power, offset.y * power, -0.1)
|
||||
ApplyForceToEntity(self.ball.object, 0, offset.x, offset.y, 0.0, 0.0, 0.0, 0.0, 0, false, false, false, false, true)
|
||||
|
||||
Utils:createCamera()
|
||||
|
||||
while true do Wait(100)
|
||||
if power > 0.00 then
|
||||
power = power - 0.01
|
||||
else
|
||||
local speed = GetEntitySpeed(self.ball.object)
|
||||
|
||||
if speed < 1.0 then
|
||||
SetEntityVelocity(self.ball.object, 0.0, 0.0, 0.0)
|
||||
FreezeEntityPosition(self.ball.object, true)
|
||||
|
||||
local material = Utils:groundMaterial()
|
||||
local objectAtCoords = DoesObjectOfTypeExistAtCoords(Config.golf_track[self.hole].hole, 0.1, `prop_golf_ball`, false)
|
||||
|
||||
Utils:deleteCamera()
|
||||
|
||||
if objectAtCoords then
|
||||
self:finishGame()
|
||||
return
|
||||
elseif not material then
|
||||
self:out()
|
||||
return
|
||||
else
|
||||
self:reroll()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Game:finishGame()
|
||||
CreateThread(DisplayScaleform)
|
||||
|
||||
total_stroke, DrawLineActive, self.ball, self.club = total_stroke + self.stroke, false, self.ball:delete(), self.club:delete()
|
||||
|
||||
--print('Total stroke :', total_stroke)
|
||||
|
||||
if self.hole == #Config.golf_track then
|
||||
s:addContent(translation["congrats"], ("%s %s %s"):format(translation["finish_game"], total_stroke, translation["stroke"]))
|
||||
|
||||
SetTimeout(2500, function()
|
||||
TriggerEvent("mrw_minigolf:cut_game")
|
||||
self = nil
|
||||
end)
|
||||
else
|
||||
self.hole = self.hole + 1
|
||||
|
||||
s:addContent(translation["congrats"], ("%s %s %s"):format(translation["round_win"], self.stroke, translation["stroke"]))
|
||||
|
||||
SetTimeout(2500, function()
|
||||
Utils:freezeEntity(self.ped(), false)
|
||||
TriggerEvent("mrw_minigolf:st_game", self.hole)
|
||||
self = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function Game:out()
|
||||
Ui:displayNotification(translation['off_side'])
|
||||
DrawLineActive = false
|
||||
|
||||
self:returnToStart()
|
||||
end
|
||||
|
||||
function Game:reroll()
|
||||
local hole = Config.golf_track[self.hole].hole
|
||||
local coords = self.ball:getPosition()
|
||||
local nx, ny = coords.x - hole.x, coords.y - hole.y
|
||||
local angle = Utils:deg(nx, ny)
|
||||
|
||||
Ui:fadeOut(500)
|
||||
|
||||
SetTimeout(1000, function()
|
||||
setCurrentPosition(coords)
|
||||
Utils:placePed(angle)
|
||||
Utils:playAnimation("mini@golfai", "wedge_idle_a", {}, -1, 1)
|
||||
Utils:freezeEntity(c.ped(), true)
|
||||
Ui:fadeIn()
|
||||
|
||||
CreateThread(DisplayDrawLine)
|
||||
CreateThread(ProcessThread)
|
||||
end)
|
||||
end
|
||||
|
||||
function Game:returnToStart()
|
||||
local data = Config.golf_track[self.hole]
|
||||
|
||||
Ui:fadeOut(500)
|
||||
|
||||
Wait(500)
|
||||
|
||||
Utils:freezeEntity(self.ped(), false)
|
||||
Utils:freezeEntity(self.ball.object, false)
|
||||
|
||||
setCurrentPosition(data.start)
|
||||
|
||||
self.ball:setPosition(data.start)
|
||||
self.ball:setHeading(0.0)
|
||||
PlaceObjectOnGroundProperly(self.ball.object)
|
||||
|
||||
Utils:placePed(data.heading)
|
||||
|
||||
SetTimeout(2000, function()
|
||||
|
||||
Utils:playAnimation("mini@golfai", "wedge_idle_a", {}, -1, 1)
|
||||
Utils:freezeEntity(self.ped(), true)
|
||||
Utils:freezeEntity(self.ball.object, true)
|
||||
|
||||
Ui:fadeIn()
|
||||
|
||||
CreateThread(DisplayDrawLine)
|
||||
CreateThread(ProcessThread)
|
||||
end)
|
||||
end
|
||||
|
||||
function Game:quit()
|
||||
Ui:displayNotification(translation['quit'])
|
||||
Utils:freezeEntity(c.ped(), false)
|
||||
ClearPedTasksImmediately(c.ped())
|
||||
TriggerEvent("mrw_minigolf:cut_game")
|
||||
self = nil
|
||||
end
|
||||
|
||||
RegisterNetEvent("mrw_minigolf:st_game")
|
||||
AddEventHandler("mrw_minigolf:st_game", function(index)
|
||||
local data = Config.golf_track[index]
|
||||
|
||||
if firstInit then
|
||||
RequestScriptAudioBank("GOLF_I", 0)
|
||||
s = Scaleform()
|
||||
|
||||
for i = 1, #Config.golf_track, 1 do
|
||||
table.insert(allGame, {hole = i, stroke = 0})
|
||||
end
|
||||
|
||||
firstInit = false
|
||||
end
|
||||
|
||||
setCurrentPosition(data.start)
|
||||
|
||||
Ui:fadeOut(500)
|
||||
|
||||
c = Game(index)
|
||||
|
||||
Wait(500)
|
||||
|
||||
Utils:placePed(data.heading)
|
||||
|
||||
SetTimeout(2000, function()
|
||||
Utils:playAnimation("mini@golfai", "wedge_idle_a", {}, -1, 1)
|
||||
Utils:freezeEntity(c.ped(), true)
|
||||
Ui:fadeIn()
|
||||
|
||||
CreateThread(DisplayDrawLine)
|
||||
CreateThread(ProcessThread)
|
||||
end)
|
||||
|
||||
inGame = true
|
||||
end)
|
||||
|
||||
RegisterNetEvent("mrw_minigolf:cut_game")
|
||||
AddEventHandler("mrw_minigolf:cut_game", function()
|
||||
ScaleformActive, DrawLineActive = false, false
|
||||
|
||||
Wait(1)
|
||||
|
||||
s:destruct()
|
||||
|
||||
if c.ball and c.club then
|
||||
c.ball, c.club = c.ball:delete(), c.club:delete()
|
||||
end
|
||||
|
||||
total_stroke, inGame, firstInit, allGame, c, s = 0, false, true, {}, nil, nil
|
||||
end)
|
||||
|
||||
AddEventHandler("onResourceStop", function(name)
|
||||
if GetCurrentResourceName() == name then
|
||||
if c then
|
||||
c.ball = c.ball:delete()
|
||||
c.club = c.club:delete()
|
||||
c = nil
|
||||
end
|
||||
|
||||
if s then
|
||||
s:destruct()
|
||||
s = nil
|
||||
end
|
||||
|
||||
if inGame then
|
||||
local ped = PlayerPedId()
|
||||
|
||||
DetachEntity(ped, true, true)
|
||||
FreezeEntityPosition(ped, false)
|
||||
ClearPedTasksImmediately(ped)
|
||||
|
||||
if IsScreenFadedOut() then
|
||||
DoScreenFadeIn(100)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--[[
|
||||
RegisterCommand('st-golf', function(s,a)
|
||||
TriggerEvent('mrw_minigolf:st_game', 1)
|
||||
end)
|
||||
]]
|
||||
@@ -0,0 +1,57 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
Object = {}
|
||||
Object.__index = Object
|
||||
|
||||
setmetatable(Object, {
|
||||
__call = function(cls, m, p)
|
||||
self = Object.new(m, p)
|
||||
return self
|
||||
end
|
||||
})
|
||||
|
||||
function ApplyBallParams(entity)
|
||||
SetEntityLoadCollisionFlag(entity, true)
|
||||
SetEntityCollision(entity, true, true)
|
||||
SetEntityRecordsCollisions(entity, true)
|
||||
SetEntityHasGravity(entity, true)
|
||||
FreezeEntityPosition(entity, true)
|
||||
SetEntityHeading(entity, 0.0)
|
||||
SetEntityMaxSpeed(entity, 10.0)
|
||||
PlaceObjectOnGroundProperly(entity)
|
||||
end
|
||||
|
||||
function Object.new(model, position)
|
||||
local self = setmetatable({}, Object)
|
||||
local model = model
|
||||
local hash = GetHashKey(model)
|
||||
|
||||
RequestModel(model)
|
||||
|
||||
while not HasModelLoaded(model) do
|
||||
Wait(1)
|
||||
end
|
||||
|
||||
self.object = CreateObject(hash, position, true, false, false)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Object:getPosition()
|
||||
return GetEntityCoords(self.object)
|
||||
end
|
||||
|
||||
function Object:setPosition(position)
|
||||
SetEntityCoords(self.object, position, false, false, false, false)
|
||||
end
|
||||
|
||||
function Object:setHeading(h)
|
||||
SetEntityHeading(self.object, h)
|
||||
end
|
||||
|
||||
function Object:delete()
|
||||
DeleteObject(self.object)
|
||||
self = nil
|
||||
return self
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
Scaleform = {}
|
||||
Scaleform.__index = Scaleform
|
||||
|
||||
setmetatable(Scaleform, {
|
||||
__call = function(cls)
|
||||
self = Scaleform.new()
|
||||
return self
|
||||
end
|
||||
})
|
||||
|
||||
function Scaleform.new()
|
||||
local self = setmetatable({}, Scaleform)
|
||||
|
||||
if HasScaleformMovieLoaded("MP_BIG_MESSAGE_FREEMODE") then
|
||||
return
|
||||
end
|
||||
|
||||
self.scaleform = RequestScaleformMovie("MP_BIG_MESSAGE_FREEMODE")
|
||||
|
||||
while not HasScaleformMovieLoaded(self.scaleform) do
|
||||
Wait(1)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Scaleform:display()
|
||||
DrawScaleformMovieFullscreen(self.scaleform, 255, 255, 255, 255, 0)
|
||||
end
|
||||
|
||||
function Scaleform:destruct()
|
||||
SetScaleformMovieAsNoLongerNeeded(self.scaleform)
|
||||
self = nil
|
||||
end
|
||||
|
||||
function Scaleform:addContent(t, str)
|
||||
BeginScaleformMovieMethod(self.scaleform, 'SHOW_SHARD_WASTED_MP_MESSAGE')
|
||||
PushScaleformMovieMethodParameterString(t)
|
||||
PushScaleformMovieMethodParameterString(str)
|
||||
EndScaleformMovieMethod()
|
||||
|
||||
SetTimeout(2500, function()
|
||||
ScaleformActive = false
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,140 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
local currentPosition, ScoreboardIsOpen, power, gameCamPosition = nil, false, 0.0, nil
|
||||
DrawLineActive, ScaleformActive = false, false
|
||||
|
||||
function setCurrentPosition(p)
|
||||
currentPosition = p
|
||||
end
|
||||
|
||||
function getPower()
|
||||
return power
|
||||
end
|
||||
|
||||
function camPosition()
|
||||
return gameCamPosition
|
||||
end
|
||||
|
||||
function ZoneThread()
|
||||
while true do
|
||||
local d = 500
|
||||
local pcoords = Utils:getEntityCoords(PlayerPedId())
|
||||
local distance = #(pcoords - Config.locate_club)
|
||||
|
||||
if distance <= 1.5 then
|
||||
d = 1
|
||||
|
||||
Ui:displayHelpNotification({
|
||||
translation['locate_club']
|
||||
})
|
||||
|
||||
if IsControlJustPressed(0, 38) then
|
||||
TriggerServerEvent("mrw_minigolf:locateClub")
|
||||
end
|
||||
end
|
||||
|
||||
Wait(d)
|
||||
end
|
||||
end
|
||||
|
||||
function ProcessThread()
|
||||
power, gameCamPosition = 0.0, nil
|
||||
|
||||
local totalStroke = c:addStroke()
|
||||
|
||||
if c.stroke > 0 then
|
||||
Ui:displayNotification(('%s : %s'):format(translation["play_your"], c.stroke))
|
||||
end
|
||||
|
||||
if totalStroke then return end
|
||||
|
||||
while true do
|
||||
local d = 500
|
||||
local pcoords = Utils:getEntityCoords(c.ped())
|
||||
local distance = #(pcoords - currentPosition)
|
||||
|
||||
if distance <= 1.5 then
|
||||
d = 1
|
||||
|
||||
Ui:displayHelpNotification({
|
||||
translation["other_params"],
|
||||
translation["rotate_params"],
|
||||
translation["games_params"]
|
||||
})
|
||||
|
||||
if IsControlJustPressed(0, 121) and not ScoreboardIsOpen then
|
||||
Ui:displayScoreboard(true)
|
||||
ScoreboardIsOpen = not ScoreboardIsOpen
|
||||
|
||||
elseif IsControlJustReleased(0, 121) and ScoreboardIsOpen then
|
||||
Ui:displayScoreboard(false)
|
||||
ScoreboardIsOpen = not ScoreboardIsOpen
|
||||
|
||||
elseif IsControlPressed(0, 24) and power < 1.0 then
|
||||
power = power + 0.01
|
||||
Ui:displayPowerBar(true, power)
|
||||
|
||||
elseif IsControlPressed(0, 174) then
|
||||
local baseHeading = Utils:getEntityHeading(c.ped())
|
||||
|
||||
if not IsEntityAttached(c.ped()) then
|
||||
AttachEntityToEntity(c.ped(), c.ball.object, 20, 0.14, -0.62, 0.99, 0.0, 0.0, 0.0, false, false, false, false, 1, true)
|
||||
end
|
||||
|
||||
Utils:setEntityHeading(c.ball.object, baseHeading + 1.0)
|
||||
DetachEntity(c.ped(), true, true)
|
||||
|
||||
elseif IsControlPressed(0, 175) then
|
||||
local baseHeading = Utils:getEntityHeading(c.ped())
|
||||
|
||||
if not IsEntityAttached(c.ped()) then
|
||||
AttachEntityToEntity(c.ped(), c.ball.object, 20, 0.14, -0.62, 0.99, 0.0, 0.0, 0.0, false, false, false, false, 1, true)
|
||||
end
|
||||
|
||||
Utils:setEntityHeading(c.ball.object, baseHeading - 1.0)
|
||||
DetachEntity(c.ped(), true, true)
|
||||
|
||||
elseif IsControlJustPressed(0, 178) then
|
||||
c:quit()
|
||||
return
|
||||
elseif IsControlJustPressed(0, 82) then
|
||||
c:returnToStart()
|
||||
return
|
||||
elseif IsControlJustReleased(0, 24) then
|
||||
Ui:displayPowerBar(false, 0)
|
||||
gameCamPosition, DrawLineActive = Utils:rayCastGamePlayCamera(90.0), false
|
||||
c:shoot()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Wait(d)
|
||||
end
|
||||
end
|
||||
|
||||
function DisplayDrawLine()
|
||||
if not DrawLineActive then DrawLineActive = true end
|
||||
|
||||
while DrawLineActive do Wait(1)
|
||||
|
||||
if c.ball == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local bcoords = Utils:getEntityCoords(c.ball.object)
|
||||
local direction = Utils:rayCastGamePlayCamera(50.0)
|
||||
|
||||
Ui:drawLine(bcoords, direction)
|
||||
end
|
||||
end
|
||||
|
||||
function DisplayScaleform()
|
||||
if not ScaleformActive then ScaleformActive = true end
|
||||
|
||||
while ScaleformActive do Wait(1)
|
||||
s:display()
|
||||
end
|
||||
end
|
||||
|
||||
CreateThread(ZoneThread)
|
||||
@@ -0,0 +1,75 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
-- Credit for research
|
||||
-- https://github.com/Sainan/GTA-V-Decompiled-Scripts/blob/master/decompiled_scripts/golf_mp.c
|
||||
-- https://www.vespura.com/fivem/scaleform/
|
||||
|
||||
Ui = {}
|
||||
Ui.__index = Ui
|
||||
|
||||
function Ui:displayNotification(str)
|
||||
BeginTextCommandThefeedPost("STRING")
|
||||
AddTextComponentString(str)
|
||||
EndTextCommandThefeedPostTicker(false, true)
|
||||
end
|
||||
|
||||
function Ui:displayHelpNotification(request)
|
||||
BeginTextCommandDisplayHelp("THREESTRINGS")
|
||||
|
||||
for i = 1,#request,1 do
|
||||
AddTextComponentSubstringPlayerName(request[i])
|
||||
end
|
||||
|
||||
EndTextCommandDisplayHelp(0, false, true, request.duration or 5000)
|
||||
end
|
||||
|
||||
function Ui:fadeOut(time)
|
||||
CreateThread(function()
|
||||
if not IsScreenFadedOut() then
|
||||
DoScreenFadeOut(time)
|
||||
else
|
||||
DoScreenFadeIn(100)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Ui:fadeIn()
|
||||
DoScreenFadeIn(150)
|
||||
end
|
||||
|
||||
function Ui:drawLine(coords, coords2)
|
||||
DrawLine(coords.x, coords.y, coords.z, coords2.x, coords2.y, coords2.z, 255, 0, 0, 0.8)
|
||||
end
|
||||
|
||||
function Ui:displayScoreboard(display)
|
||||
if display then
|
||||
SendNuiMessage(json.encode({
|
||||
status = true,
|
||||
data = allGame,
|
||||
ui = 'Scoreboard'
|
||||
}))
|
||||
else
|
||||
SendNuiMessage(json.encode({
|
||||
status = false,
|
||||
ui = 'Scoreboard'
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
function Ui:displayPowerBar(display, power)
|
||||
if display then
|
||||
SendNuiMessage(json.encode({
|
||||
status = true,
|
||||
ui = 'Power',
|
||||
data = tonumber(power * 100)
|
||||
}))
|
||||
|
||||
else
|
||||
SendNuiMessage(json.encode({
|
||||
status = false,
|
||||
ui = 'Power',
|
||||
data = 0
|
||||
}))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,140 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
-- list of materials https://pastebin.com/PBE6wQSG
|
||||
|
||||
Utils = {}
|
||||
Utils.materials = {-840216541, -1693813558, -754997699, -1469616465, 1926285543, -1369136684}
|
||||
Utils.__index = Utils
|
||||
|
||||
local cam = nil
|
||||
|
||||
function Utils:getEntityCoords(entity)
|
||||
return GetEntityCoords(entity)
|
||||
end
|
||||
|
||||
function Utils:setEntityCoords(entity, new_coords)
|
||||
SetEntityCoords(entity, new_coords, false, false, false, false)
|
||||
end
|
||||
|
||||
function Utils:getEntityHeading(entity)
|
||||
return GetEntityHeading(entity)
|
||||
end
|
||||
|
||||
function Utils:setEntityHeading(entity, new_heading)
|
||||
SetEntityHeading(entity, new_heading)
|
||||
end
|
||||
|
||||
function Utils:freezeEntity(entity, toggle)
|
||||
FreezeEntityPosition(entity, toggle)
|
||||
end
|
||||
|
||||
function Utils:placePed(h)
|
||||
SetEntityHeading(c.ball.object, h+360.0)
|
||||
AttachEntityToEntity(c.ped(), c.ball.object, 20, 0.14, -0.62, 0.99, 0.0, 0.0, 0.0, false, false, false, false, 1, true)
|
||||
DetachEntity(c.ped(), true, true)
|
||||
SetEntityHeading(c.ball.object, 0.0)
|
||||
end
|
||||
|
||||
function Utils:createCamera()
|
||||
cam = CreateCam("DEFAULT_SCRIPTED_FLY_CAMERA", true)
|
||||
RenderScriptCams(true, false, 0, true, true)
|
||||
SetCamFov(cam, 90.0)
|
||||
AttachCamToEntity(cam, c.ball.object, -0.2, 0.0, 1.0099, false)
|
||||
end
|
||||
|
||||
function Utils:deleteCamera()
|
||||
if cam then
|
||||
DestroyCam(cam, true)
|
||||
RenderScriptCams(false, false, 0, true, true)
|
||||
cam = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Utils:playAnimation(dict, anim, coords, duration, loop)
|
||||
RequestAnimDict(dict)
|
||||
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Wait(1)
|
||||
end
|
||||
|
||||
if HasAnimDictLoaded(dict) then
|
||||
local x, y, z = false, false, false
|
||||
|
||||
if coords then
|
||||
x = coords.x
|
||||
y = coords.y
|
||||
z = coords.z
|
||||
end
|
||||
|
||||
TaskPlayAnim(PlayerPedId(), dict, anim, 8.0, -8.0, duration or -1, loop or 0, 0, x, y, z)
|
||||
end
|
||||
end
|
||||
|
||||
function Utils:playSoundFromEntity(sound)
|
||||
PlaySoundFromEntity(-1, sound, PlayerPedId(), 0, 0, 0)
|
||||
end
|
||||
|
||||
function Utils:groundMaterial()
|
||||
local ballCoords = self:getEntityCoords(c.ball.object)
|
||||
local shape = StartShapeTestCapsule(ballCoords.x, ballCoords.y, ballCoords.z + 4, ballCoords.x, ballCoords.y, ballCoords.z - 0.03, 2, -1, c.ball.object, 7)
|
||||
local result, hit, endCoords, surfaceNormal, materialHash, entityHit = GetShapeTestResultIncludingMaterial(shape)
|
||||
|
||||
if materialHash == 0 then
|
||||
materialHash = GetLastMaterialHitByEntity(c.ball.object)
|
||||
end
|
||||
|
||||
for i = 1, #self.materials, 1 do
|
||||
local material = self.materials[i]
|
||||
--print(material, materialHash)
|
||||
if material == materialHash or materialHash == 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Utils:deg(x, y)
|
||||
local heading = math.atan2(x, y)
|
||||
|
||||
if heading < 0 then
|
||||
heading = math.deg(math.abs(heading))
|
||||
else
|
||||
heading = math.deg(2 * math.pi - heading)
|
||||
end
|
||||
|
||||
heading = heading + 90.0
|
||||
|
||||
return heading
|
||||
end
|
||||
|
||||
function Utils:rotationToDirection(rotation)
|
||||
local adjustedRotation =
|
||||
{
|
||||
x = (math.pi / 180) * rotation.x,
|
||||
y = (math.pi / 180) * rotation.y,
|
||||
z = (math.pi / 180) * rotation.z
|
||||
}
|
||||
local direction =
|
||||
{
|
||||
x = -math.sin(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)),
|
||||
y = math.cos(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)),
|
||||
z = math.sin(adjustedRotation.x)
|
||||
}
|
||||
return direction
|
||||
end
|
||||
|
||||
function Utils:rayCastGamePlayCamera(distance)
|
||||
local cameraRotation = GetGameplayCamRot()
|
||||
local cameraCoord = GetGameplayCamCoord()
|
||||
local direction = self:rotationToDirection(cameraRotation)
|
||||
local destination =
|
||||
{
|
||||
x = cameraCoord.x + direction.x * distance,
|
||||
y = cameraCoord.y + direction.y * distance,
|
||||
z = cameraCoord.z + direction.z * distance
|
||||
}
|
||||
local a, b, c, d, e = GetShapeTestResult(StartShapeTestRay(cameraCoord.x, cameraCoord.y, cameraCoord.z, destination.x, destination.y, destination.z, -1, -1, 1))
|
||||
return c
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
fx_version 'cerulean'
|
||||
game'gta5'
|
||||
name 'mrw_minigolf'
|
||||
description 'script for patoche golf mapping'
|
||||
author 'Morow'
|
||||
|
||||
client_scripts{
|
||||
'client/*.lua'
|
||||
}
|
||||
|
||||
server_script{
|
||||
'server/*.lua'
|
||||
}
|
||||
|
||||
shared_scripts{
|
||||
'shared/*.lua',
|
||||
'shared/translation/*.lua'
|
||||
}
|
||||
|
||||
files{
|
||||
'ui/ui.html',
|
||||
'ui/script/app.js',
|
||||
'ui/css/app.css',
|
||||
'ui/font/*.woff'
|
||||
}
|
||||
|
||||
ui_page 'ui/ui.html'
|
||||
@@ -0,0 +1,10 @@
|
||||
# MRW_MINIGOLF
|
||||
## Script for Patoche minigolf mapping
|
||||
|
||||
# [EN]
|
||||
### the config file locate is /shared/shared.lua
|
||||
### the translation file locate is /shared/translation/en.lua
|
||||
|
||||
# [FR]
|
||||
### Le fichier config se trouve ici /shared/shared.lua
|
||||
### Le fichier de traduction se trouve ici /shared/translation/fr.lua
|
||||
@@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://nulledleaks.net/index.php
|
||||
@@ -0,0 +1,27 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
if Config.USE_ESX then
|
||||
ESX = nil
|
||||
TriggerEvent('esx:getSharedObject', function( obj ) ESX = obj end)
|
||||
end
|
||||
|
||||
RegisterNetEvent("mrw_minigolf:locateClub")
|
||||
AddEventHandler("mrw_minigolf:locateClub", function()
|
||||
local x_source = source
|
||||
|
||||
if Config.USE_ESX then
|
||||
local xPlayer = ESX.GetPlayerFromId(x_source)
|
||||
local getPlayerMoney = xPlayer.getMoney()
|
||||
|
||||
if getPlayerMoney >= Config.club_price then
|
||||
TriggerClientEvent("mrw_minigolf:st_game", x_source, 1)
|
||||
else
|
||||
TriggerClientEvent("mrw_golf:Notification", x_source, translation["no_money"])
|
||||
end
|
||||
else
|
||||
-- IF USE YOUR CUSTOM FRAMEWORK !!
|
||||
-- ADD YOUR LINE FOR COMPARE PLAYER MONEY
|
||||
TriggerClientEvent("mrw_minigolf:st_game", x_source, 1)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://nulledleaks.net/index.php
|
||||
@@ -0,0 +1,81 @@
|
||||
-- Author : Morow
|
||||
-- Github : https://github.com/Morow73
|
||||
|
||||
_G.language = "en" -- change translation, 'en' or 'fr'
|
||||
_G.translation = {}
|
||||
|
||||
if IsDuplicityVersion() then
|
||||
Config = {}
|
||||
Config.__index = Config
|
||||
|
||||
Config.USE_ESX = true -- use ESX or not ?
|
||||
Config.club_price = 200 -- minigolf price
|
||||
else
|
||||
Config = {}
|
||||
Config.__index = Config
|
||||
|
||||
Config.max_stroke = 10 -- max stroke
|
||||
Config.locate_club = vector3(-1734.24, -1135.17, 12.79) -- locate club position
|
||||
Config.golf_track = {
|
||||
[1] = {
|
||||
start = vector3(-1753.32, -1166.31, 12.79), -- fisrt position
|
||||
hole = vector3(-1744.81, -1150.25, 11.96), -- hole position
|
||||
heading = 240.0 -- heading for first position
|
||||
},
|
||||
[2] = {
|
||||
start = vector3(-1743.29, -1182.03, 12.79),
|
||||
hole = vector3(-1738.33, -1164.27, 11.96),
|
||||
heading = 244.0
|
||||
},
|
||||
[3] = {
|
||||
start = vector3(-1730.49, -1179.09, 12.79),
|
||||
hole = vector3(-1723.03, -1181.61, 11.96),
|
||||
heading = 282.0
|
||||
},
|
||||
[4] = {
|
||||
start = vector3(-1713.28, -1167.88, 12.79),
|
||||
hole = vector3(-1716.87, -1172.23, 11.96),
|
||||
heading = 290.0
|
||||
},
|
||||
[5] = {
|
||||
start = vector3(-1760.85, -1190.26, 12.79),
|
||||
hole = vector3(-1769.87, -1177.45, 11.96),
|
||||
heading = 227.0
|
||||
},
|
||||
[6] = {
|
||||
start = vector3(-1772.51, -1220.72, 12.79),
|
||||
hole = vector3(-1769.00, -1224.46, 11.96),
|
||||
heading = 263.0
|
||||
},
|
||||
[7] = {
|
||||
start = vector3(-1746.66, -1192.76, 12.79),
|
||||
hole = vector3(-1747.94, -1194.80, 11.96),
|
||||
heading = 130.0
|
||||
},
|
||||
[8] = {
|
||||
start = vector3(-1752.10, -1225.11, 12.79),
|
||||
hole = vector3(-1748.39, -1217.06, 11.96),
|
||||
heading = 245.0
|
||||
},
|
||||
[9] = {
|
||||
start = vector3(-1741.43, -1238.41, 12.79),
|
||||
hole = vector3(-1743.40, -1240.87, 11.78),
|
||||
heading = 224.0
|
||||
},
|
||||
[10] = {
|
||||
start = vector3(-1729.42, -1210.54, 12.79),
|
||||
hole = vector3(-1730.75, -1206.63, 11.80),
|
||||
heading = 281.0
|
||||
},
|
||||
[11] = {
|
||||
start = vector3(-1719.01, -1209.35, 12.79),
|
||||
hole = vector3(-1704.51, -1192.00, 11.78),
|
||||
heading = 222.0
|
||||
},
|
||||
[12] = {
|
||||
start = vector3(-1694.93, -1172.71, 12.79),
|
||||
hole = vector3(-1690.35, -1184.38, 11.96),
|
||||
heading = 250.0
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
if language == "en" then
|
||||
translation = {
|
||||
["congrats"] = "Felicidades",
|
||||
["round_win"] = "Terminaste este hoyo con ",
|
||||
["finish_game"] = "Se acabo el juego, hiciste un total de : ",
|
||||
["stroke"] = "Tiro",
|
||||
["locate_club"] = "~INPUT_CONTEXT~ para rentar palos por $200 !",
|
||||
["other_params"] = "~INPUT_ATTACK~ para cargar el golpe !\n ~INPUT_VEH_FLY_ATTACK_CAMERA~ mostrar los puntos ! \n",
|
||||
["rotate_params"] = "~INPUT_CELLPHONE_LEFT~ ~INPUT_CELLPHONE_RIGHT~ rotar alrededor de la bola !\n",
|
||||
["games_params"] = "~INPUT_VEH_PREV_RADIO~ para reiniciar el nivel !\n ~INPUT_CELLPHONE_OPTION~ quitar el juego !",
|
||||
["no_money"] = "No tienes fondos !",
|
||||
["max_stroke"] = "Superaste el maximo de golpes en este round",
|
||||
["quit"] = "Saliste del juego",
|
||||
["off_side"] = "La bola salio del campo",
|
||||
["play_your"] = "Total de Tiros: "
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
if language == "fr" then
|
||||
translation = {
|
||||
["congrats"] = "Félicitation",
|
||||
["round_win"] = "Manche gagné en ",
|
||||
["finish_game"] = "La partie est terminé, vous avez fait un total de : ",
|
||||
["stroke"] = "coups",
|
||||
["locate_club"] = "~INPUT_CONTEXT~ pour accéder aux location de clubs !",
|
||||
["other_params"] = "~INPUT_ATTACK~ pour charger le tir !\n ~INPUT_VEH_FLY_ATTACK_CAMERA~ pour afficher les scores ! \n",
|
||||
["rotate_params"] = "~INPUT_CELLPHONE_LEFT~ ~INPUT_CELLPHONE_RIGHT~ pour tourner autour de la balle !\n",
|
||||
["games_params"] = "~INPUT_VEH_PREV_RADIO~ pour relancer le niveau !\n ~INPUT_CELLPHONE_OPTION~ pour quitter la partie !",
|
||||
["no_money"] = "Vous n'avez pas les fonds !",
|
||||
["max_stroke"] = "Vous avez atteind le nombre de coups maximum par tour",
|
||||
["quit"] = "Vous avez quitté la partie",
|
||||
["off_side"] = "La balle est sortit hors du terrain",
|
||||
["play_your"] = "Vous jouez votre coups n°"
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://nulledleaks.net/index.php
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
@font-face {
|
||||
font-family: 'Segoe UI Regular';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Segoe UI Regular'), url('Segoe UI.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Segoe UI Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Segoe UI Italic'), url('Segoe UI Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Segoe UI Bold';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Segoe UI Bold'), url('Segoe UI Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Segoe UI Bold Italic';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: local('Segoe UI Bold Italic'), url('Segoe UI Bold Italic.woff') format('woff');
|
||||
}
|
||||
|
||||
html, body{
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
right: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
}
|
||||
|
||||
#Scoreboard{
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 45%;
|
||||
background-color: #14213d;
|
||||
border-radius: 5px;
|
||||
opacity: 0.9;
|
||||
box-shadow: 10px 5px 5px black;
|
||||
position: absolute;
|
||||
bottom: 60%;
|
||||
}
|
||||
|
||||
.Scoreboard-header{
|
||||
color: #fca311;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 20%;
|
||||
font-family: 'Segoe UI Bold';
|
||||
}
|
||||
|
||||
#Scoreboard-grid-hole{
|
||||
height: 30%;
|
||||
width: 100%;
|
||||
border-top: 1px solid white;
|
||||
border-bottom: 1px solid white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.Scoreboard-grid-hole-header{
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
border-right: 1px solid white;
|
||||
}
|
||||
|
||||
.Scoreboard-grid-hole-header-content{
|
||||
margin-top: 25%;
|
||||
color: #fca311;
|
||||
font-family: 'Segoe UI Bold';
|
||||
}
|
||||
|
||||
.Scoreboard-grid-hole-hole{
|
||||
height: 100%;
|
||||
width: 5%;
|
||||
border-right: 1px solid white;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-family: 'Segoe UI Regular';
|
||||
}
|
||||
|
||||
.Scoreboard-grid-hole-hole p{
|
||||
margin-top: 40%;
|
||||
}
|
||||
|
||||
#Scoreboard-grid-score{
|
||||
height: 30%;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.Scoreboard-grid-score-header{
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
border-right: 1px solid white;
|
||||
}
|
||||
|
||||
.Scoreboard-grid-score-header-content{
|
||||
margin-top: 25%;
|
||||
color: #fca311;
|
||||
font-family: 'Segoe UI Bold';
|
||||
}
|
||||
|
||||
.Scoreboard-grid-score-score{
|
||||
height: 100%;
|
||||
width: 5%;
|
||||
border-right: 1px solid white;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-family: 'Segoe UI Regular';
|
||||
}
|
||||
|
||||
.Scoreboard-grid-score-score p{
|
||||
margin-top: 40%;
|
||||
}
|
||||
|
||||
#Bar{
|
||||
display: none;
|
||||
width: 50%;
|
||||
height: 5%;
|
||||
border-radius: 5px;
|
||||
background-color: white;
|
||||
opacity: 0.9;
|
||||
box-shadow: 10px 5px 5px black;
|
||||
margin-top: 70%;
|
||||
margin-left: 25%;
|
||||
}
|
||||
|
||||
#PowerBar{
|
||||
width: 10%;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
background-color: red;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,51 @@
|
||||
const Scoreboard = document.getElementById("Scoreboard")
|
||||
const ScoreboardGridHole = document.getElementById("Scoreboard-grid-hole")
|
||||
const ScoreboardGridScore = document.getElementById("Scoreboard-grid-score")
|
||||
const Bar = document.getElementById("Bar")
|
||||
const BarContent = document.getElementById("PowerBar")
|
||||
|
||||
let baseWidth = 0
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
const item = event.data;
|
||||
const status = item.status;
|
||||
const ui = item.ui
|
||||
|
||||
if (ui === 'Scoreboard'){
|
||||
Scoreboard.style.display = (status ? "block" : "none");
|
||||
|
||||
if (item.data == undefined) return;
|
||||
|
||||
const deleteIfDivExist = function(className){
|
||||
const divs = document.getElementsByClassName(className);
|
||||
|
||||
if (divs == null) return;
|
||||
|
||||
for (var i = divs.length-1; i >= 0; i--) {
|
||||
divs[i].remove();
|
||||
}
|
||||
}
|
||||
|
||||
deleteIfDivExist("Scoreboard-grid-hole-hole")
|
||||
deleteIfDivExist("Scoreboard-grid-score-score")
|
||||
|
||||
for (let index = 0; index < item.data.length; index++) {
|
||||
const element = item.data[index];
|
||||
|
||||
ScoreboardGridHole.innerHTML = ScoreboardGridHole.innerHTML + `<div id="hole" class="Scoreboard-grid-hole-hole">
|
||||
<p>${element.hole}</p>
|
||||
</div>`;
|
||||
|
||||
ScoreboardGridScore.innerHTML = ScoreboardGridScore.innerHTML + `<div id="score" class="Scoreboard-grid-score-score">
|
||||
<p>${element.stroke}</p>
|
||||
</div>`;
|
||||
};
|
||||
}else{
|
||||
Bar.style.display = (status ? "block" : "none");
|
||||
|
||||
if (item.data == undefined) return;
|
||||
if (item.data > 100) return;
|
||||
|
||||
BarContent.setAttribute('style', `width:${item.data}%`)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scoreboard</title>
|
||||
<link rel="stylesheet" href="css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="Scoreboard">
|
||||
<div class="Scoreboard-header">Portside Minigolf</div>
|
||||
|
||||
<div id="Scoreboard-grid-hole">
|
||||
|
||||
<div class="Scoreboard-grid-hole-header">
|
||||
<div class="Scoreboard-grid-hole-header-content">Hoyo</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="Scoreboard-grid-score">
|
||||
|
||||
<div class="Scoreboard-grid-score-header">
|
||||
<div class="Scoreboard-grid-score-header-content">Puntuacion</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="Bar">
|
||||
<div id="PowerBar"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="script/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user