Files
2025-05-19 16:45:39 -07:00

306 lines
8.0 KiB
Lua

-- 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)
]]