From 8063b9344061eb62df75ef8123baa694c40dd436 Mon Sep 17 00:00:00 2001 From: Jim Shield Date: Tue, 6 May 2025 22:46:11 +0100 Subject: [PATCH] Upload main files of the script --- client/camera.lua | 44 ++++++++ client/controls.lua | 249 +++++++++++++++++++++++++++++++++++++++++ client/showOff.lua | 68 +++++++++++ client/skateboard.lua | 208 ++++++++++++++++++++++++++++++++++ client/surfboard.lua | 219 ++++++++++++++++++++++++++++++++++++ config.lua | 53 ++++++++- server/usableItems.lua | 11 ++ shared/functions.lua | 57 ++++++++++ 8 files changed, 906 insertions(+), 3 deletions(-) create mode 100644 client/camera.lua create mode 100644 client/controls.lua create mode 100644 client/showOff.lua create mode 100644 client/skateboard.lua create mode 100644 client/surfboard.lua create mode 100644 server/usableItems.lua create mode 100644 shared/functions.lua diff --git a/client/camera.lua b/client/camera.lua new file mode 100644 index 0000000..080b15e --- /dev/null +++ b/client/camera.lua @@ -0,0 +1,44 @@ +RegisterKeyMapping('skatecam', locale("info", "lockcam"), 'keyboard', 'H') +RegisterCommand('skatecam', function() + if Attached then + SetCamActive(customCam, not IsCamActive(customCam)) + RenderScriptCams(IsCamActive(customCam), true, 500, true, true) + --updateCamLoc() + end +end) +RegisterKeyMapping('+flipcam', locale("info", "flipCam"), 'keyboard', 'C') +RegisterCommand('+flipcam', function() + if Attached then + AttachCamToEntity(customCam, skateboard.Bike, 0.25, 2.0, 1.5, true) + flipCam = true + end +end) +RegisterCommand('-flipcam', function() + if Attached then + AttachCamToEntity(customCam, skateboard.Bike, 0.25, -2.0, 1.0, true) + flipCam = false + end +end) +function updateCamLoc() + CreateThread(function() + local ped = PlayerPedId() + while Attached do + makeInstructionalButtons({ + { text = surfboard and locale("info", "getoffSurf") or locale("info", "getoff"), keys = { 47 } }, + { text = locale("info", "lockcam")..": "..(toggleCam and "On" or "Off"), keys = { 74} }, + (not surfboard and { text = locale("info", "jump"), keys = { 102 } } or nil), + }) + local coord = GetOffsetFromEntityInWorldCoords(ped, 0.0, flipCam and -5.0 or 5.0, 0.0) + if customCam == nil then + customCam = createTempCam(coord, coord) + AttachCamToEntity(customCam, skateboard.Driver, 0.25, -2.0, 1.0, true) + end + + PointCamAtEntity(customCam, skateboard.Skate, 0, 0, 1.7) + Wait(0) + end + RenderScriptCams(false, true, 500, true, true) + DestroyAllCams() + customCam = nil + end) +end \ No newline at end of file diff --git a/client/controls.lua b/client/controls.lua new file mode 100644 index 0000000..9110a6b --- /dev/null +++ b/client/controls.lua @@ -0,0 +1,249 @@ +RegisterKeyMapping('skategetoff', locale("keyMaps", "getOff"), 'keyboard', 'G') +RegisterCommand('skategetoff', function() + if Attached then + if not IsEntityInAir(skateboard.Bike) then + stopTempCam() + DetachEntity(PlayerPedId(), false, false) + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 100) + Attached = false + Dir = {} + ClearPedTasks(PlayerPedId()) + end + end +end) + +RegisterKeyMapping('+skateforward', locale("keyMaps", "forward"), 'keyboard', 'W') +RegisterCommand('+skateforward', function() + if Attached and not overSpeed then + CreateThread(function() + if not Dir.forward then + Dir.forward = true + while Dir.forward do + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, ((Dir.left == true and 7) or (Dir.right == true and 8) or 9), 0.1) + Wait(50) + end + else return end + end) + end +end) +RegisterCommand('-skateforward', function() if Attached then Dir.forward = nil TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 1) end end) + +RegisterKeyMapping('+skatebackward', locale("keyMaps", "backward"), 'keyboard', 'S') +RegisterCommand('+skatebackward', function() + if Attached and not overSpeed then + CreateThread(function() + if not Dir.backward then + Dir.backward = true + while Dir.backward do + if surfboard then + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 0.1) + else + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, ((Dir.left == true and 13) or (Dir.right == true and 14) or 22), 0.1) + end + Wait(50) + end + else return end + end) + end +end) +RegisterCommand('-skatebackward', function() if Attached then Dir.backward = nil TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 1) end end) + +local pressed = false +RegisterKeyMapping('+skateleft', locale("keyMaps", "left"), 'keyboard', 'A') +RegisterCommand('+skateleft', function() + if Attached and not overSpeed then + if surfboard then + surfBoardRotate(false) + else + Dir.left = true + end + end +end) +RegisterCommand('-skateleft', function() + if Attached then + pressed = false + Dir.left = nil + end +end) + +RegisterKeyMapping('+skateright', locale("keyMaps", "right"), 'keyboard', 'D') +RegisterCommand('+skateright', function() + if Attached and not overSpeed then + if surfboard then + surfBoardRotate(true) + else + Dir.right = true + end + end +end) +RegisterCommand('-skateright', function() + if Attached then + pressed = false + Dir.right = nil + end +end) + +function surfBoardRotate(right) + if not pressed then pressed = true end + CreateThread(function() + while pressed do + local getRot = GetEntityRotation(skateboard.Bike, 2) + if right then + SetEntityRotation(skateboard.Bike, getRot.x, getRot.y, getRot.z-1, 2) + else + SetEntityRotation(skateboard.Bike, getRot.x, getRot.y, getRot.z+1, 2) + end + Wait(0) + end + end) +end + +RegisterKeyMapping('skatejump', locale("keyMaps", "jump"), 'keyboard', 'SPACE') +RegisterCommand('skatejump', function() local Ped = PlayerPedId() + if Attached and not surfboard then + if not IsEntityInAir(skateboard.Bike) then + if isCat then + playAnim("creatures@cat@move", "idle_dwn", -1, 1) + elseif (isDog or isCoyote) then + -- + else + playAnim("move_crouch_proto", "idle_intro", -1, 1) + end + local duration = 0 + local boost = 0 + local manual = false + while IsControlPressed(0, 22) do + Wait(10) + duration += 10.0 + + if duration > 1500 and not manual then + manual = true + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.45, 0.0, -40.0, 90.0, false, true, true, true, 0, true) + + if isCat then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, -0.10, -0.82, 40.04, 0.0, 0.0, true, true, false, true, 1, true) + elseif (isDog or isCoyote) then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.0, -0.45, 40.4, 0.0, 0.0, true, true, false, true, 1, true) + else + stopAnim("move_crouch_proto", "idle_intro") + playAnim("move_strafe@stealth", "idle", -1, 1) + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, -0.5, -0.1, 40.0, 0.0, 0.0, true, true, false, true, 1, true) + end + end + end + boost = 6.0 * duration / 250.0 + if boost > 6.0 then boost = 6.0 end + local vel = GetEntityVelocity(skateboard.Bike) + + manual = false + --Reset if changes + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, 0.0, 90.0, -15.0, true, true, true, 2, true) + if isCat then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.10, -0.78, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + playAnim("creatures@cat@move", "idle_upp", -1, 1) + elseif (isDog or isCoyote) then + if notSmallDog then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.30, -0.55, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + else + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.40, -0.70, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + else + playAnim("move_strafe@stealth", "idle", -1, 1) + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.15, 0.05, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + + SetEntityVelocity(skateboard.Bike, vel.x, vel.y, vel.z + boost) + if isCat then + stopAnim("move_crouch_proto", "idle_dwn") + playAnim("creatures@cat@move", "idle_upp", -1, 1) + + elseif (isDog or isCoyote) then + -- + else + stopAnim("move_crouch_proto", "idle_intro") + playAnim("move_strafe@stealth", "idle", -1, 1) + end + else + if trick then return else trick = true end + local chance = math.random(1, 3) + + local skill = 0 + if isStarted("jim-skills") then + jsonPrint(exports["jim-skills"]:GetCurrentSkill("Skateboarding")) + skill = exports["jim-skills"]:GetCurrentSkill("Skateboarding").TimeReduction or 0 + end + --triggerNotify(nil, "Trick "..chance, "success") + if chance == 1 then + CreateThread(function() + local origHeading = GetEntityHeading(skateboard.Bike) + local speed = 8 + local spinChance = math.random(1, 2) + for i = 1, (360 / speed) do + if IsEntityInAir(skateboard.Bike) then + SetEntityHeading(skateboard.Bike, spinChance == 1 and (origHeading + (i * speed)) or (origHeading - (i * speed))) + Wait(5 - (5 * (skill * 5))) + else + --triggerNotify(nil, (i * speed).."° full cab", "success") + if isStarted("jim-skills") then + exports["jim-skills"]:UpdateSkill("Skateboarding", (i * speed) / 100) + end + trick = false + break + end + end + --triggerNotify(nil, "Full 360° full cab", "success") + trick = false + if isStarted("jim-skills") then + exports["jim-skills"]:UpdateSkill("Skateboarding", 3.6) + end + end) + end + if chance == 2 then + CreateThread(function() + local origRot = 0.0 + local speed = 8 + local spinChance = math.random(1, 2) + for i = 1, (360 / speed) do + if IsEntityInAir(skateboard.Bike) then + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, spinChance == 1 and (origRot + (i * speed)) or (origRot - (i * speed)), 90.0, false, true, true, true, 1, true) + Wait(5 - (5 * skill)) + else + DetachEntity(Ped, false, false) + SetPedToRagdoll(Ped, 5000, 4000, 0, true, true, false) + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, 0.0, 90.0, false, true, true, true, 1, true) + if isStarted("jim-skills") then exports["jim-skills"]:UpdateSkill("Skateboarding", (i * speed) / 100) end + trick = false + break + end + end + trick = false + if isStarted("jim-skills") then exports["jim-skills"]:UpdateSkill("Skateboarding", 3.6) end + end) + end + if chance == 3 then + CreateThread(function() + local origRot = 90.0 + local speed = 8 + local spinChance = math.random(1, 2) + for i = 1, (360 / speed) do + if IsEntityInAir(skateboard.Bike) then + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, 0.0, spinChance == 1 and (origRot + (i * speed)) or (origRot - (i * speed)), -15.0, true, true, true, 2, true) + Wait(5 - (5 * skill)) + else + DetachEntity(Ped, false, false) + SetPedToRagdoll(Ped, 5000, 4000, 0, true, true, false) + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, 0.0, 90.0, false, true, true, true, 1, true) + if isStarted("jim-skills") then exports["jim-skills"]:UpdateSkill("Skateboarding", (i * speed) / 100) end + trick = false + break + end + end + trick = false + if isStarted("jim-skills") then exports["jim-skills"]:UpdateSkill("Skateboarding", 3.6) end + end) + end + end + end +end) + +RegisterCommand('fixstuckskateboard', removeBoard) \ No newline at end of file diff --git a/client/showOff.lua b/client/showOff.lua new file mode 100644 index 0000000..1196245 --- /dev/null +++ b/client/showOff.lua @@ -0,0 +1,68 @@ +function showOff(data) + --exports.ox_inventory:closeInventory() + local showProp = nil + local animTable = { + { animDict = "molly@boombox1", anim = "boombox1_clip", bone = 60309, pos = vec3(-0.0050, 0.0320, 0.1640), rot = vec3(44.6076, -112.2983, -86.1199) }, + { animDict = "beachanims@molly", anim = "beachanim_surf_clip", bone = 28422, pos = vec3(-0.1020, 0.2240, 0.0840), rot = vec3(5.6655, 175.3526, 49.7964) }, + { animDict = "chocoholic@skate4", anim = "skate4_clip", bone = 28422, pos = vec3(0.2780, -0.0200, -0.0700), rot = vec3(-180.0000, 28.0000, 0.0) }, + } + local Menu = {} + for i = 1, #animTable do + Menu[#Menu+1] = { + header = locale("menus", "holdUp").." "..i, + onSelect = function() + if not data.skip then + TriggerEvent(getScript()..":Skateboard:PickPlace", data) + Wait(1500) + end + showProp = makeProp({ prop = data.prop, coords = vec4(0, 0, 0, 0) }, true, true) + AttachEntityToEntity(showProp, PlayerPedId(), GetPedBoneIndex(PlayerPedId(), animTable[i].bone), animTable[i].pos.x, animTable[i].pos.y, animTable[i].pos.z, animTable[i].rot.x, animTable[i].rot.y, animTable[i].rot.z, true, true, false, true, 1, true ) + loadAnimDict(animTable[i].animDict) + playAnim(animTable[i].animDict, animTable[i].anim, -1, 11) + hold = true + drawText(nil, { locale("info", "putDown") }) + lockInv(true) + while hold do + Wait(0) + if IsControlJustReleased(0, 202) then + hold = false + break + end + end + lockInv(false) + hideText() + stopAnim(animTable[i].animDict, animTable[i].anim) + if not data.skip then + TriggerEvent(getScript()..":Skateboard:PickPlace", data) + end + DeleteEntity(showProp) + showProp = nil + end + } + end + openMenu(Menu, { header = locale("info", "header"), }) +end + +function holdBoard(data) + local showProp = nil + TriggerEvent(getScript()..":Skateboard:PickPlace", data) + Wait(1500) + showProp = makeProp({ prop = data.prop, coords = vec4(0, 0, 0, 0) }, true, true) + AttachEntityToEntity(showProp, PlayerPedId(), GetPedBoneIndex(PlayerPedId(), 28422), 0.17, -0.04, 0.08, 205.0, 29.0, 258.0,true,true, false, true, 1, true ) + hold = true + drawText(nil, { locale("info", "putDown") }) + while hold do + Wait(0) + if IsControlJustReleased(0, 202) then + hold = false + break + end + end + hideText() + TriggerEvent(getScript()..":Skateboard:PickPlace", data) + DeleteEntity(showProp) + showProp = nil +end + +RegisterNetEvent(getScript()..":client:showoff", showOff) +RegisterNetEvent(getScript()..":client:holdBoard", holdBoard) \ No newline at end of file diff --git a/client/skateboard.lua b/client/skateboard.lua new file mode 100644 index 0000000..bff7388 --- /dev/null +++ b/client/skateboard.lua @@ -0,0 +1,208 @@ +onPlayerLoaded(function() + Wait(1000) + local Ped = PlayerPedId() + local pedModel = GetEntityModel(Ped) + isCat = (isCat() or pedModel == `ft-raccoon`) and (pedModel ~= `ft-sphynx`) + isDog, notSmallDog = isDog() + if isDog and pedModel == `a_c_coyote` then isDog = false end + isCoyote = (pedModel == `ft-sphynx` or pedModel == `a_c_coyote`) + if pedModel == `ft-capmonkey2` then isDog = true end +end, true) + +onResourceStop(function() + removeBoard() +end, true) + +function makeFakeSkateboard(Ped, remove, model) -- The animation for picking up and placing the board + lastModel = model + local prop = makeProp({ prop = model, coords = vec4(0, 0, 0, 0), false, true}) + if isCat then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 31086), 0.18, -0.14, 0.0, -87.0, -100.0, 1.0, true, true, false, false, 1, true) + ClearPedTasks(Ped) + elseif isDog then + if notSmallDog then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 65068), 0.29, 0.02, -0.18, 0.0, 0.0, 100.0, true, true, false, false, 1, true) + else + end + elseif isCoyote then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 39317), 0.11, 0.0, -0.3, -10.0, 40.0, -90.0, true, true, false, false, 1, true) + else + playAnim("pickup_object", "pickup_low", -1, 0) + if remove then Wait(700) end + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 57005), 0.3, 0.08, 0.09, -86.0, -60.0, 50.0, true, true, false, false, 1, true) + end + if remove then + removeBoard() + end + Wait(900) + destroyProp(prop) +end + +RegisterNetEvent(getScript()..":Skateboard:PickPlace", function(data) + if not data.prop then + data.prop = SkateboardItemModels[data.name] + end + if not IsModelValid(GetHashKey(data.prop)) then + print("^1Error^7: ^1Can't currently place this model, try another location") + return + end + jsonPrint(data) + local Ped = PlayerPedId() + if not IsPedSittingInAnyVehicle(Ped) then + if DoesEntityExist(skateboard.Bike) then + Attached = false + Wait(100) + stopTempCam() + makeFakeSkateboard(Ped, true, data.prop) -- pick up animation + currentToken = triggerCallback(AuthEvent) + addItem(lastItem, 1) + skateboard = {} + Dir = {} + else + local pedCoords = GetOffsetFromEntityInWorldCoords(Ped, 0.0, 0.5, 0.5) + skateboard.Bike = makeVeh("tribike3", vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)) + skateboard.Skate = makeProp({ prop = data.prop, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0) }, 1, 1) + while not DoesEntityExist(skateboard.Bike) or not DoesEntityExist(skateboard.Skate) do Wait(5) end + + SetEntityNoCollisionEntity(skateboard.Bike, Ped, false) + SetEntityNoCollisionEntity(skateboard.Skate, Ped, false) + + Wait(500) + + configureSkateboard(skateboard.Bike) + + SetEntityCompletelyDisableCollision(skateboard.Bike, true, true) + SetEntityCompletelyDisableCollision(skateboard.Skate, true, true) + + SetEntityVisible(skateboard.Bike, false, 0) + + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, -0.60, 0.0, 0.0, 90.0, false, true, true, true, 1, true) + + skateboard.Driver = makePed("a_c_chimp", vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0), 0, 1, nil, nil) -- change to chimp, dies on ragdoll, doesnt talk, might be best model for it + + while not DoesEntityExist(skateboard.Driver) do Wait(0) end + SetEntityCoords(skateboard.Driver, pedCoords.x, pedCoords.y, pedCoords.z, true) + SetEntityNoCollisionEntity(skateboard.Driver, Ped, false) + SetEntityCompletelyDisableCollision(skateboard.Driver, true, true) + + SetPedCanBeTargetted(skateboard.Driver, false) + SetBlockingOfNonTemporaryEvents(skateboard.Driver, true) + SetPedDiesWhenInjured(skateboard.Driver, false) + SetPedCanRagdollFromPlayerImpact(skateboard.Driver, false) + + while not IsPedSittingInAnyVehicle(skateboard.Driver) do + SetEntityVisible(skateboard.Driver, false, 0) + TaskWarpPedIntoVehicle(skateboard.Driver, skateboard.Bike, -1) + Wait(10) + end + + SetEnableHandcuffs(skateboard.Driver, true) + SetEntityInvincible(skateboard.Driver, true) + FreezeEntityPosition(skateboard.Driver, true) + + local options = { + { action = function() TriggerEvent(getScript()..":Skateboard:GetOn", { board = skateboard.Skate, item = data.item, prop = data.prop }) end, + icon = "fas fa-car", label = locale("targets", "getOn"), }, + { action = function() TriggerEvent(getScript()..":Skateboard:PickPlace", { board = skateboard.Skate, item = data.item, prop = data.prop }) end, + icon = "fas fa-hand-holding", label = locale("targets", "pickUp"), }, + { action = function() TriggerEvent(getScript()..":client:showoff", data) end, + icon = "far fa-user", label = locale("targets", "showOff"), }, + { action = function() TriggerEvent(getScript()..":client:holdBoard", data) end, + icon = "fas fa-hands-holding", label = locale("targets", "hold"), }, + } + createEntityTarget(skateboard.Skate, options, 2.5) + createEntityTarget(skateboard.Driver, options, 2.5) + createEntityTarget(skateboard.Bike, options, 2.5) + + makeFakeSkateboard(Ped, false, data.prop) + + DisableCamCollisionForEntity(Ped) + DisableCamCollisionForEntity(skateboard.Bike) + DisableCamCollisionForEntity(skateboard.Skate) + DisableCamCollisionForEntity(skateboard.Driver) + SetVehicleDoorsLocked(skateboard.Bike, 10) + storedVariables = skateboard + SetEntityCoords(skateboard.Bike, GetOffsetFromEntityInWorldCoords(Ped, 0.0, 0.5, 1.5)) + SetEntityHeading(skateboard.Bike, GetEntityHeading(Ped)+90) + lastItem = data.name + if hasItem(data.name, 1) then + removeItem(data.name, 1) + end + Dir = {} + end + end +end) + +RegisterNetEvent(getScript()..":Skateboard:GetOn", function() + local Ped = PlayerPedId() + surfboard = false + + if isCat then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.10, -0.78, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + playAnim("creatures@cat@move", "idle_upp", -1, 1) + elseif isDog or isCoyote then + if notSmallDog then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.30, -0.55, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + else + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.40, -0.70, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + else + playAnim("move_strafe@stealth", "idle", -1, 1) + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.15, 0.05, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + SetEntityCollision(Ped, true, true) + Attached = true + updateCamLoc() + + CreateThread(function() + while Attached do + overSpeed = (GetEntitySpeed(skateboard.Bike)*3.6) > 90 + local getRot = GetEntityRotation(skateboard.Bike) + if (-80.0 < getRot.x and getRot.x > 80.0) or (-80.0 < getRot.y and getRot.y > 80.0) then + DetachEntity(Ped, false, false) + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 1) + Attached = false + Dir = {} + SetPedToRagdoll(Ped, 5000, 4000, 0, true, true, false) + end + + if not IsEntityAttachedToEntity(Ped, skateboard.Bike) then + DetachEntity(Ped, false, false) + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 6, 2000) + Attached = false + Dir = {} + if isCat then + stopAnim("creatures@cat@move", "idle_upp") + stopAnim("creatures@cat@move", "idle_dwn") + elseif (isDog or isCoyote) then + -- + else + stopAnim("move_strafe@stealth", "idle") + end + end + Wait(1000) + end + end) + CreateThread(function() + -- Extra separate check to see if the Entity Exists + -- Moved from above because if you get ejected from the bike, and its flipped + while DoesEntityExist(skateboard.Driver) and DoesEntityExist(skateboard.Bike) and GetPedInVehicleSeat(skateboard.Bike, -1) == skateboard.Driver and not IsEntityDead(skateboard.Driver) do + Wait(2000) + end + if Attached then + makeFakeSkateboard(Ped, true, lastModel) + removeEntityTarget(skateboard.Skate) + removeEntityTarget(skateboard.Bike) + removeEntityTarget(skateboard.Driver) + Attached = false + Wait(100) + currentToken = triggerCallback(AuthEvent) + addItem(lastItem, 1) + skateboard = {} + Dir = {} + end + end) +end) \ No newline at end of file diff --git a/client/surfboard.lua b/client/surfboard.lua new file mode 100644 index 0000000..ac5b213 --- /dev/null +++ b/client/surfboard.lua @@ -0,0 +1,219 @@ +function makeFakeSurfboard(Ped, remove, model) -- The animation for picking up and placing the board + lastModel = model + local prop = makeProp({ prop = model, coords = vec4(0, 0, 0, 0), false, true}) + if isCat then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 31086), 0.18, -0.14, 0.0, -87.0, -100.0, 1.0, true, true, false, false, 1, true) + ClearPedTasks(Ped) + elseif isDog then + if notSmallDog then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 65068), 0.29, 0.02, -0.18, 0.0, 0.0, 100.0, true, true, false, false, 1, true) + else + end + elseif isCoyote then + SetPedCanRagdoll(Ped, false) + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 39317), 0.11, 0.0, -0.3, -10.0, 40.0, -90.0, true, true, false, false, 1, true) + else + playAnim("pickup_object", "pickup_low", -1, 0) + if remove then Wait(700) end + AttachEntityToEntity(prop, Ped, GetPedBoneIndex(Ped, 57005), 0.22, 0.11, 0.17, -105.0, -80.0, 10.0, true, true, false, false, 1, true) + end + if remove then + removeBoard() + end + Wait(900) + destroyProp(prop) +end + +RegisterNetEvent(getScript()..":SurfBoard:PickPlace", function(data) + if not data.prop then + data.prop = SurfboardItemModels[data.name] + end + if not IsModelValid(GetHashKey(data.prop)) then + print("^1Error^7: ^1Can't place this model, try another location") + return + end + surfboard = true + local Ped = PlayerPedId() + if not IsPedSittingInAnyVehicle(Ped) then + if DoesEntityExist(skateboard.Bike) then + Attached = false + Wait(100) + stopTempCam() + makeFakeSurfboard(Ped, true, data.prop) -- pick up animation + currentToken = triggerCallback(AuthEvent) + addItem(lastItem, 1) + skateboard = {} + Dir = {} + else + local pedCoords = GetOffsetFromEntityInWorldCoords(Ped, 0.0, 0.5, -40.5) + skateboard.Bike = makeVeh("seashark3", vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)) + SetEntityCoords(skateboard.Bike, pedCoords) + skateboard.Skate = makeProp({ prop = data.prop, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0) }, 1, 1) + while not DoesEntityExist(skateboard.Bike) or not DoesEntityExist(skateboard.Skate) do Wait(5) end + SetEntityVisible(skateboard.Bike, false, 0) + pushVehicle(skateboard.Bike) + -- Set the engine sound volume to 0 (may affect nearby same models too) + ForceVehicleEngineAudio(skateboard.Bike, "NULL") -- Sometimes works for audio style + -- Optionally mute all sounds from this vehicle + SetVehicleAudioEngineDamageFactor(skateboard.Bike, 0.0) + + SetBoatAnchor(skateboard.Bike, true) + SetBoatFrozenWhenAnchored(skateboard.Bike, true) + + SetEntityNoCollisionEntity(skateboard.Bike, Ped, false) + SetEntityNoCollisionEntity(skateboard.Skate, Ped, false) + + Wait(500) + + configureSurfboard(skateboard.Bike) + + SetEntityCompletelyDisableCollision(skateboard.Bike, true, true) + SetEntityCompletelyDisableCollision(skateboard.Skate, true, true) + + SetVehicleSilent(skateboard.Bike, true) + ForceUseAudioGameObject(skateboard.Bike, "RAIDEN") + SetVehicleEngineOn(skateboard.Bike, false, false, true) + SetVehicleAudioEngineDamageFactor(skateboard.Bike, 0.0) + SetVehicleAudioBodyDamageFactor(skateboard.Bike, 0.0) + + AttachEntityToEntity(skateboard.Skate, skateboard.Bike, nil, 0.0, 0.0, 0.15, 270.0, 270.0, 270.0, false, true, true, true, 2, true) + + skateboard.Driver = makePed("a_c_chimp", vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0), 0, 1, nil, nil) + + while not DoesEntityExist(skateboard.Driver) do Wait(0) end + SetEntityCoords(skateboard.Driver, pedCoords.x, pedCoords.y, pedCoords.z, true) + SetEntityNoCollisionEntity(skateboard.Driver, Ped, false) + SetEntityCompletelyDisableCollision(skateboard.Driver, true, true) + + SetPedCanBeTargetted(skateboard.Driver, false) + SetBlockingOfNonTemporaryEvents(skateboard.Driver, true) + SetPedDiesWhenInjured(skateboard.Driver, false) + SetPedCanRagdollFromPlayerImpact(skateboard.Driver, false) + + SetEnableHandcuffs(skateboard.Driver, true) + SetEntityInvincible(skateboard.Driver, true) + FreezeEntityPosition(skateboard.Driver, true) + + while not IsPedSittingInAnyVehicle(skateboard.Driver) do + SetEntityVisible(skateboard.Driver, false, 0) + TaskWarpPedIntoVehicle(skateboard.Driver, skateboard.Bike, -1) + Wait(10) + end + + local options = { + { action = function() TriggerEvent(getScript()..":Surfboard:GetOn", { board = skateboard.Skate, item = data.item, prop = data.prop }) end, + icon = "fas fa-car", label = locale("targets", "getOn"), }, + { action = function() TriggerEvent(getScript()..":SurfBoard:PickPlace", { board = skateboard.Skate, item = data.item, prop = data.prop }) end, + icon = "fas fa-hand-holding", label = locale("targets", "pickUp"), }, + } + + createEntityTarget(skateboard.Skate, options, 2.5) + createEntityTarget(skateboard.Driver, options, 2.5) + createEntityTarget(skateboard.Bike, options, 2.5) + + makeFakeSurfboard(Ped, false, data.prop) + + DisableCamCollisionForEntity(Ped) + DisableCamCollisionForEntity(skateboard.Bike) + DisableCamCollisionForEntity(skateboard.Skate) + DisableCamCollisionForEntity(skateboard.Driver) + SetVehicleDoorsLocked(skateboard.Bike, 10) + storedVariables = skateboard + SetEntityCoords(skateboard.Bike, GetOffsetFromEntityInWorldCoords(Ped, 0.0, 0.8, 0.0)) + SetEntityHeading(skateboard.Bike, GetEntityHeading(Ped)+90) + lastItem = data.name + if hasItem(data.name, 1) then + removeItem(data.name, 1) + end + Dir = {} + end + end +end) + +RegisterNetEvent(getScript()..":Surfboard:GetOn", function() local Ped = PlayerPedId() + + SetBoatAnchor(skateboard.Bike, false) + + if isCat then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.10, 0.78, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + playAnim("creatures@cat@move", "idle_upp", -1, 1) + elseif isDog or isCoyote then + if notSmallDog then + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.30, 0.55, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + else + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.40, 0.70, 0.4, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + else + playAnim("move_strafe@stealth", "idle", -1, 1) + AttachEntityToEntity(Ped, skateboard.Bike, 20, 0.0, 0.0, 1.15, 0.0, 0.0, -15.0, true, true, false, true, 1, true) + end + SetEntityCollision(Ped, true, true) + Attached = true + updateCamLoc() + + CreateThread(function() + while Attached do + overSpeed = (GetEntitySpeed(skateboard.Bike)*3.6) > 90 + if (GetEntitySpeed(skateboard.Bike)*3.6) > 10 then + if not IsEntityPlayingAnim(Ped, "move_strafe@stealth", "idle", 3) then + playAnim("move_strafe@stealth", "idle", -1, 1) + end + else + if not IsEntityPlayingAnim(Ped, "move_crouch_proto", "idle", 3) then + playAnim("move_crouch_proto", "idle", -1, 0) + end + end + local getRot = GetEntityRotation(skateboard.Bike) + if (-80.0 < getRot.x and getRot.x > 80.0) or (-80.0 < getRot.y and getRot.y > 80.0) then + DetachEntity(Ped, false, false) + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 1, 1) + Attached = false + Dir = {} + SetPedToRagdoll(Ped, 5000, 4000, 0, true, true, false) + end + + if not IsEntityAttachedToEntity(Ped, skateboard.Bike) then + DetachEntity(Ped, false, false) + TaskVehicleTempAction(skateboard.Driver, skateboard.Bike, 6, 2000) + Attached = false + Dir = {} + if isCat then + stopAnim("creatures@cat@move", "idle_upp") + stopAnim("creatures@cat@move", "idle_dwn") + elseif (isDog or isCoyote) then + -- + else + stopAnim("move_strafe@stealth", "idle") + end + SetBoatAnchor(skateboard.Bike, true) + end + Wait(700) + end + end) + + CreateThread(function() + -- Extra separate check to see if the Entity Exists + -- Moved from above because if you get ejected from the bike, and its flipped + while DoesEntityExist(skateboard.Driver) and DoesEntityExist(skateboard.Bike) and GetPedInVehicleSeat(skateboard.Bike, -1) == skateboard.Driver and not IsEntityDead(skateboard.Driver) do + Wait(2000) + end + if Attached then + makeFakeSkateboard(Ped, true, lastModel) + removeEntityTarget(skateboard.Skate) + removeEntityTarget(skateboard.Bike) + removeEntityTarget(skateboard.Driver) + Attached = false + Wait(100) + currentToken = triggerCallback(AuthEvent) + addItem(lastItem, 1) + skateboard = {} + Dir = {} + end + end) +end) + +if debugMode then + RegisterCommand("surf", function() TriggerEvent(getScript()..":SurfBoard:PickPlace", { item = "skateboard", prop = `prop_surf_board_01` }) end) +end \ No newline at end of file diff --git a/config.lua b/config.lua index 80ec5e5..5c60937 100644 --- a/config.lua +++ b/config.lua @@ -1,11 +1,58 @@ Config = { Lan = "en", System = { - Debug = false, + Debug = true, + EventDebug = false, - drawText = "gta", + Menu = "qb", + Notify = "gta", }, Crafting = { craftCam = true, } -} \ No newline at end of file +} + +SkateboardItemModels = { + skateboard_01 = "v_res_skateboard" +} +SurfboardItemModels = { + surfboard_01 = "prop_surf_board_01", + surfboard_02 = "prop_surf_board_02", + surfboard_03 = "prop_surf_board_03", + surfboard_04 = "prop_surf_board_04", + surfboard_05 = "prop_beach_lg_surf", +} + + +skateboard = {} +Dir = {} +storedVariables = {} + +hold = false +Attached = false +trick = false +toggleCam = false +flipCam = false + +lastModel = nil +customCam = nil +lastItem = nil + +isCat = false +isDog = false +isCoyote = false +notSmallDog = false + +surfboard = false + +function locale(section, string) + if not string then + print(section, "string is nil") + end + if not Config.Lan or Config.Lan == "" then return print("Error, no langauge set") end + local localTable = Loc[Config.Lan] + if not localTable then return "Locale Table Not Found" end + if not localTable[section] then return "["..section.."] Invalid" end + if not localTable[section][string] then return "["..string.."] Invalid" end + return localTable[section][string] +end \ No newline at end of file diff --git a/server/usableItems.lua b/server/usableItems.lua new file mode 100644 index 0000000..ac01fe1 --- /dev/null +++ b/server/usableItems.lua @@ -0,0 +1,11 @@ +for k, v in pairs(SkateboardItemModels) do + createUseableItem(k, function(source, item) + TriggerClientEvent(getScript()..":Skateboard:PickPlace", source, { name = k }) + end) +end + +for k, v in pairs(SurfboardItemModels) do + createUseableItem(k, function(source, item) + TriggerClientEvent(getScript()..":SurfBoard:PickPlace", source, { name = k }) + end) +end diff --git a/shared/functions.lua b/shared/functions.lua new file mode 100644 index 0000000..1783b4d --- /dev/null +++ b/shared/functions.lua @@ -0,0 +1,57 @@ +function configureSkateboard(entity) + print("Configuring skateboard") + for k, v in pairs({ + ["fSteeringLock"] = 9.0, + ["fDriveInertia"] = 0.05, + ["fMass"] = 1800.0, + ["fPercentSubmerged"] = 105.0, + ["fDriveBiasFront"] = 0.0, + ["fInitialDriveForce"] = 0.25, + ["fInitialDriveMaxFlatVel"] = 135.0, + ["fTractionCurveMax"] = 2.2, + ["fTractionCurveMin"] = 2.12, + ["fTractionCurveLateral"] = 22.5, + ["fTractionSpringDeltaMax"] = 0.1, + ["fLowSpeedTractionLossMult"] = 0.7, + ["fCamberStiffnesss"] = 0.0, + ["fTractionBiasFront"] = 0.478, + ["fTractionLossMult"] = 0.0, + ["fSuspensionForce"] = 1.2, + ["fSuspensionReboundDamp"] = 1.7, + ["fSuspensionUpperLimit"] = 0.1, + ["fSuspensionLowerLimit"] = -0.3, + ["fSuspensionRaise"] = 0.0, + ["fSuspensionBiasFront"] = 0.5, + ["fAntiRollBarForce"] = 0.0, + ["fAntiRollBarBiasFront"] = 0.65, + ["fBrakeForce"] = 0.53 + }) do + SetVehicleHandlingFloat(entity, "CHandlingData", k, v) + end +end + +function configureSurfboard(entity) + ModifyVehicleTopSpeed(entity, -40.0) -- Negative values reduce top speed + SetVehicleEnginePowerMultiplier(entity, -20.0) -- Negative values reduce power +end + +function removeBoard() + --Clean up targets + removeEntityTarget(storedVariables.Skate) + removeEntityTarget(storedVariables.Driver) + removeEntityTarget(storedVariables.Bike) + removeEntityTarget(skateboard.Skate) + removeEntityTarget(skateboard.Driver) + removeEntityTarget(skateboard.Bike) + --Remove entities + DeleteVehicle(storedVariables.Bike) + destroyProp(storedVariables.Skate) + DeletePed(storedVariables.Driver) + DeleteVehicle(skateboard.Bike) + destroyProp(skateboard.Skate) + DeletePed(skateboard.Driver) + --Make sure tables are flushed + surfboard = false + storedVariables = {} + skateboard = {} +end \ No newline at end of file