├── README.md ├── client └── cl_main.lua ├── fxmanifest.lua └── shared └── config.lua /README.md: -------------------------------------------------------------------------------- 1 | ## Requirements 2 | 3 | - ox_lib 4 | 5 | ## Support 6 | 7 | - Discord: https://discord.gg/AeCVP2F8h7 8 | - Website : https://snipe.tebex.io 9 | 10 | ## Showcase 11 | 12 | https://streamable.com/rvgh2n -------------------------------------------------------------------------------- /client/cl_main.lua: -------------------------------------------------------------------------------- 1 | -----------------For support, scripts, and more---------------- 2 | --------------- https://discord.gg/AeCVP2F8h7 ------------- 3 | --------------------------------------------------------------- 4 | 5 | local ped = nil 6 | local sitting = false 7 | local oldCamView = nil 8 | 9 | local txt = { 10 | '-- Sit -- \n', 11 | '[E] Sit \n', 12 | '[X / Right Click] Cancel \n', 13 | '[G] Next Animation \n', 14 | '[H] Previous Animation \n', 15 | '[Up/Down Arrows] Height \n', 16 | '[SCROLL] Rotate \n', 17 | } 18 | 19 | local currentAnimIndex = 1 20 | 21 | local function CycleAnimations(direction) 22 | if direction == "next" then 23 | currentAnimIndex = currentAnimIndex + 1 24 | if currentAnimIndex > #Config.Anims then 25 | currentAnimIndex = 1 26 | end 27 | elseif direction == "previous" then 28 | currentAnimIndex = currentAnimIndex - 1 29 | if currentAnimIndex < 1 then 30 | currentAnimIndex = #Config.Anims 31 | end 32 | end 33 | end 34 | 35 | local function StartSittingThread() 36 | sitting = true 37 | lib.showTextUI("Press [Q] to cancel") 38 | CreateThread(function () 39 | while sitting do 40 | Wait(1) 41 | if IsControlJustPressed(0, 44) then 42 | sitting = false 43 | lib.hideTextUI() 44 | ClearPedTasksImmediately(PlayerPedId()) 45 | return 46 | end 47 | end 48 | end) 49 | end 50 | 51 | local function MakePedSitDown(coords, heading, animData) 52 | stopPlacing() 53 | TaskGoToCoordAnyMeans(PlayerPedId(), coords.x, coords.y, coords.z, 1.0, 0, 0, 786603, 0xbf800000) 54 | local PlayerCoords = GetEntityCoords(PlayerPedId()) 55 | lib.showTextUI("Press [Right Click] to cancel") 56 | while #(PlayerCoords - coords) > 1.5 do 57 | Wait(1) 58 | PlayerCoords = GetEntityCoords(PlayerPedId()) 59 | if IsControlJustPressed(0, 177) then 60 | lib.hideTextUI() 61 | ClearPedTasksImmediately(PlayerPedId()) 62 | return 63 | end 64 | end 65 | lib.hideTextUI() 66 | SetEntityCoords(PlayerPedId(), coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, false) 67 | TaskPlayAnimAdvanced(PlayerPedId(), animData.dict, animData.anim, coords.x, coords.y, coords.z, 0, 0, heading, 3.0, 3.0, -1, 2, 1.0, false, false) 68 | StartSittingThread() 69 | end 70 | 71 | local function PlacingThread(animData) 72 | if ped == nil then 73 | local playerPed = PlayerPedId() 74 | ped = ClonePed(playerPed, false, false, false) 75 | FreezeEntityPosition(ped, true) 76 | SetEntityAlpha(ped, 0) 77 | 78 | local animToUse = Config.Anims[currentAnimIndex] 79 | 80 | if not animToUse then 81 | lib.notify({ type = "error", description = "No animation found." }) 82 | return 83 | end 84 | 85 | lib.requestAnimDict(animData.dict) 86 | TaskPlayAnim(ped, animData.dict, animData.anim, 8.0, 8.0, -1, 1, 0, false, false, false) 87 | SetEntityCollision(ped, false, false) 88 | SetEntityAlpha(ped, 100) 89 | if Config.SetToFirstPerson then 90 | oldCamView = GetFollowPedCamViewMode() 91 | SetFollowPedCamViewMode(3) 92 | SetCamViewModeForContext(0, 4) 93 | end 94 | SetBlockingOfNonTemporaryEvents(ped, true) 95 | heading = GetEntityHeading(playerPed) + 90.0 96 | lib.showTextUI(table.concat(txt)) 97 | CreateThread(function () 98 | local currentCoordsZ = 0 99 | while ped ~= nil do 100 | Wait(1) 101 | DisableControlAction(0, 22, true) 102 | startPlacing() 103 | if currentCoords then 104 | SetEntityCoords(ped, currentCoords.x, currentCoords.y, currentCoords.z + currentCoordsZ) 105 | SetEntityHeading(ped, heading) 106 | end 107 | if IsDisabledControlJustPressed(0, 14) then 108 | heading = heading + 5 109 | if heading > 360 then heading = 0.0 end 110 | end 111 | if IsDisabledControlPressed(0, 27) then 112 | currentCoordsZ = currentCoordsZ + 0.01 113 | end 114 | if IsDisabledControlPressed(0, 173) then 115 | currentCoordsZ = currentCoordsZ - 0.01 116 | end 117 | if IsDisabledControlJustPressed(0, 15) then 118 | heading = heading - 5 119 | if heading < 0 then heading = 360.0 end 120 | end 121 | if IsControlJustPressed(0, 38) then 122 | if #(GetEntityCoords(PlayerPedId()) - currentCoords) < 5.0 then 123 | MakePedSitDown(GetEntityCoords(ped), GetEntityHeading(ped), animToUse) 124 | else 125 | lib.notify({type = "error", description = "You are too far"}) 126 | end 127 | end 128 | 129 | if IsControlJustPressed(0, 47) then -- G 130 | CycleAnimations("next") 131 | animToUse = Config.Anims[currentAnimIndex] 132 | 133 | if not animToUse then 134 | lib.notify({ type = "error", description = "No animation found." }) 135 | return 136 | end 137 | 138 | lib.requestAnimDict(animToUse.dict) 139 | TaskPlayAnim(ped, animToUse.dict, animToUse.anim, 8.0, 8.0, -1, 1, 0, false, false, false) 140 | end 141 | 142 | if IsControlJustPressed(0, 74) then -- H 143 | CycleAnimations("previous") 144 | animToUse = Config.Anims[currentAnimIndex] 145 | 146 | if not animToUse then 147 | lib.notify({ type = "error", description = "No animation found." }) 148 | return 149 | end 150 | 151 | lib.requestAnimDict(animToUse.dict) 152 | TaskPlayAnim(ped, animToUse.dict, animToUse.anim, 8.0, 8.0, -1, 1, 0, false, false, false) 153 | end 154 | 155 | if IsControlJustPressed(0, 177) then 156 | stopPlacing() 157 | end 158 | end 159 | end) 160 | else 161 | DeleteObject(ped) 162 | ped = nil 163 | stopPlacing() 164 | return 165 | end 166 | end 167 | 168 | function GetForwardVector(rotation) 169 | local rot = (math.pi / 180.0) * rotation 170 | return vector3(-math.sin(rot.z) * math.abs(math.cos(rot.x)), math.cos(rot.z) * math.abs(math.cos(rot.x)), 171 | math.sin(rot.x)) 172 | end 173 | 174 | 175 | local function RotationToDirection(rotation) 176 | local adjustedRotation = 177 | { 178 | x = (math.pi / 180) * rotation.x, 179 | y = (math.pi / 180) * rotation.y, 180 | z = (math.pi / 180) * rotation.z 181 | } 182 | local direction = 183 | { 184 | x = -math.sin(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 185 | y = math.cos(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 186 | z = math.sin(adjustedRotation.x) 187 | } 188 | return direction 189 | end 190 | 191 | function Camera(ped) 192 | local cameraRotation = GetGameplayCamRot() 193 | local cameraCoord = GetGameplayCamCoord() 194 | local direction = RotationToDirection(cameraRotation) 195 | local destination = 196 | { 197 | x = cameraCoord.x + direction.x * 10.0, 198 | y = cameraCoord.y + direction.y * 10.0, 199 | z = cameraCoord.z + direction.z * 10.0 200 | } 201 | 202 | local sphereCast = StartShapeTestSweptSphere( 203 | cameraCoord.x, 204 | cameraCoord.y, 205 | cameraCoord.z, 206 | destination.x, 207 | destination.y, 208 | destination.z, 209 | 0.2, 210 | 339, 211 | ped, 212 | 4 213 | ); 214 | return GetShapeTestResultIncludingMaterial(sphereCast); 215 | end 216 | 217 | function startPlacing() 218 | local _, hit, endCoords, _, _, _ = Camera(ped) 219 | if hit then 220 | currentCoords = endCoords 221 | end 222 | end 223 | 224 | function stopPlacing() 225 | if ped then 226 | DeleteEntity(ped) 227 | end 228 | ped = nil 229 | heading = 0.0 230 | currentCoords = nil 231 | lib.hideTextUI() 232 | if Config.SetToFirstPerson then 233 | SetFollowPedCamViewMode(oldCamView) 234 | oldCamView = nil 235 | end 236 | end 237 | 238 | RegisterCommand("sit", function(source, args) 239 | local animToUse = Config.Anims[currentAnimIndex] 240 | 241 | if not animToUse then 242 | lib.notify({ type = "error", description = "No animation found." }) 243 | return 244 | end 245 | 246 | PlacingThread(animToUse) 247 | end) 248 | 249 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | 2 | -----------------For support, scripts, and more---------------- 3 | --------------- https://discord.gg/AeCVP2F8h7 ------------- 4 | --------------------------------------------------------------- 5 | 6 | fx_version 'cerulean' 7 | game 'gta5' 8 | 9 | description 'Sitting Script' 10 | version '1.0.0' 11 | author 'Snipe' 12 | 13 | lua54 'yes' 14 | 15 | shared_scripts{ 16 | '@ox_lib/init.lua', 17 | 'shared/**/*.lua' 18 | } 19 | 20 | client_scripts{ 21 | 'client/**/*.lua', 22 | } 23 | -------------------------------------------------------------------------------- /shared/config.lua: -------------------------------------------------------------------------------- 1 | 2 | -----------------For support, scripts, and more---------------- 3 | --------------- https://discord.gg/AeCVP2F8h7 ------------- 4 | --------------------------------------------------------------- 5 | 6 | Config = {} 7 | Config.SetToFirstPerson = true 8 | 9 | -- you can add more sitting animations here. 10 | Config.Anims = { 11 | { 12 | dict = "timetable@maid@couch@", 13 | anim = "base", 14 | }, 15 | { 16 | dict = "anim@heists@fleeca_bank@ig_7_jetski_owner", 17 | anim = "owner_idle", 18 | }, 19 | { 20 | dict = "rcm_barry3", 21 | anim = "barry_3_sit_loop", 22 | }, 23 | { 24 | dict = "amb@world_human_picnic@male@idle_a", 25 | anim = "idle_a", 26 | }, 27 | { 28 | dict = "amb@world_human_picnic@female@idle_a", 29 | anim = "idle_a", 30 | }, 31 | { 32 | dict = "anim@heists@fleeca_bank@ig_7_jetski_owner", 33 | anim = "owner_idle", 34 | }, 35 | { 36 | dict = "timetable@jimmy@mics3_ig_15@", 37 | anim = "idle_a_jimmy", 38 | }, 39 | { 40 | dict = "anim@amb@nightclub@lazlow@lo_alone@", 41 | anim = "lowalone_base_laz", 42 | }, 43 | { 44 | dict = "timetable@jimmy@mics3_ig_15@", 45 | anim = "mics3_15_base_jimmy", 46 | }, 47 | { 48 | dict = "amb@world_human_stupor@male@idle_a", 49 | anim = "idle_a", 50 | }, 51 | { 52 | dict = "timetable@ron@ig_5_p3", 53 | anim = "ig_5_p3_base", 54 | }, 55 | { 56 | dict = "timetable@reunited@ig_10", 57 | anim = "base_amanda", 58 | }, 59 | { 60 | dict = "timetable@ron@ig_3_couch", 61 | anim = "base", 62 | }, 63 | { 64 | dict = "timetable@jimmy@mics3_ig_15@", 65 | anim = "mics3_15_base_tracy", 66 | }, 67 | { 68 | dict = "timetable@maid@couch@", 69 | anim = "base", 70 | }, 71 | { 72 | dict = "timetable@ron@ig_5_p3", 73 | anim = "ig_5_p3_base", 74 | }, 75 | { 76 | dict = "timetable@reunited@ig_10", 77 | anim = "base_amanda", 78 | }, 79 | { 80 | dict = "timetable@ron@ig_3_couch", 81 | anim = "base", 82 | }, 83 | { 84 | dict = "timetable@jimmy@mics3_ig_15@", 85 | anim = "mics3_15_base_tracy", 86 | }, 87 | { 88 | dict = "timetable@ron@ron_ig_2_alt1", 89 | anim = "ig_2_alt1_base", 90 | }, 91 | { 92 | dict = "anim@gangops@morgue@table@", 93 | anim = "body_search", 94 | } 95 | } 96 | 97 | --------------------------------------------------------------------------------