fishing
This commit is contained in:
parent
7e2451be50
commit
176f249885
23 changed files with 1323 additions and 0 deletions
303
resources/[jobs]/[civ]/wasabi_fishing/client/client.lua
Normal file
303
resources/[jobs]/[civ]/wasabi_fishing/client/client.lua
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
-----------------For support, scripts, and more----------------
|
||||
--------------- https://discord.gg/wasabiscripts -------------
|
||||
---------------------------------------------------------------
|
||||
local fishing = false
|
||||
|
||||
if Config.sellShop.enabled then
|
||||
CreateThread(function()
|
||||
local ped, textUI
|
||||
CreateBlip(Config.sellShop.coords, 356, 1, Strings.sell_shop_blip, 0.80)
|
||||
local point = lib.points.new({
|
||||
coords = Config.sellShop.coords,
|
||||
distance = 30
|
||||
})
|
||||
|
||||
function point:nearby()
|
||||
if self.currentDistance < self.distance then
|
||||
if not ped then
|
||||
lib.requestAnimDict('mini@strip_club@idles@bouncer@base', 100)
|
||||
lib.requestModel(Config.sellShop.ped, 100)
|
||||
ped = CreatePed(28, Config.sellShop.ped, Config.sellShop.coords.x, Config.sellShop.coords.y, Config.sellShop.coords.z, Config.sellShop.heading, false, false)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetEntityInvincible(ped, true)
|
||||
SetBlockingOfNonTemporaryEvents(ped, true)
|
||||
TaskPlayAnim(ped, 'mini@strip_club@idles@bouncer@base', 'base', 8.0, 0.0, -1, 1, 0, 0, 0, 0)
|
||||
end
|
||||
if self.currentDistance <= 1.8 then
|
||||
if not textUI then
|
||||
lib.showTextUI(Strings.sell_fish)
|
||||
textUI = true
|
||||
end
|
||||
if IsControlJustReleased(0, 38) then
|
||||
FishingSellItems()
|
||||
end
|
||||
elseif self.currentDistance >= 1.9 and textUI then
|
||||
lib.hideTextUI()
|
||||
textUI = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function point:onExit()
|
||||
if ped then
|
||||
local model = GetEntityModel(ped)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
DeletePed(ped)
|
||||
SetPedAsNoLongerNeeded(ped)
|
||||
RemoveAnimDict('mini@strip_club@idles@bouncer@base')
|
||||
ped = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Function to select bait from available options
|
||||
local function SelectBait()
|
||||
local availableBaits = {}
|
||||
|
||||
-- Check all bait types
|
||||
for _, bait in pairs(Config.bait.types) do
|
||||
local hasItem = lib.callback.await('wasabi_fishing:checkItem', 100, bait.itemName)
|
||||
if hasItem then
|
||||
table.insert(availableBaits, bait)
|
||||
end
|
||||
end
|
||||
|
||||
if #availableBaits == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- If only one bait type is available, use it directly
|
||||
if #availableBaits == 1 then
|
||||
return availableBaits[1]
|
||||
end
|
||||
|
||||
-- Create a menu for bait selection
|
||||
local options = {}
|
||||
for _, bait in pairs(availableBaits) do
|
||||
table.insert(options, {
|
||||
title = bait.label,
|
||||
description = 'Use as fishing bait',
|
||||
metadata = {
|
||||
{label = 'Catch Bonus', value = '+' .. bait.catchBonus .. '%'},
|
||||
{label = 'Loss Chance', value = bait.loseChance .. '%'}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local selectedIndex = lib.showContext('bait_selection_menu', {
|
||||
id = 'bait_selection_menu',
|
||||
title = 'Select Fishing Bait',
|
||||
options = options
|
||||
})
|
||||
|
||||
if selectedIndex then
|
||||
return availableBaits[selectedIndex]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to handle the fishing process
|
||||
local function StartFishingProcess(selectedBait, waterLoc)
|
||||
fishing = true
|
||||
|
||||
-- Create fishing rod prop
|
||||
local model = `prop_fishing_rod_01`
|
||||
lib.requestModel(model, 100)
|
||||
local pole = CreateObject(model, GetEntityCoords(cache.ped), true, false, false)
|
||||
AttachEntityToEntity(pole, cache.ped, GetPedBoneIndex(cache.ped, 18905), 0.1, 0.05, 0, 80.0, 120.0, 160.0, true, true, false, true, 1, true)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
|
||||
-- Load animations
|
||||
lib.requestAnimDict('mini@tennis', 100)
|
||||
lib.requestAnimDict('amb@world_human_stand_fishing@idle_a', 100)
|
||||
|
||||
-- Initial casting animation
|
||||
TaskPlayAnim(cache.ped, 'mini@tennis', 'forehand_ts_md_far', 1.0, -1.0, 1.0, 48, 0, 0, 0, 0)
|
||||
Wait(3000)
|
||||
TaskPlayAnim(cache.ped, 'amb@world_human_stand_fishing@idle_a', 'idle_c', 1.0, -1.0, 1.0, 11, 0, 0, 0, 0)
|
||||
|
||||
-- Main fishing loop
|
||||
while fishing do
|
||||
Wait(0)
|
||||
local unarmed = `WEAPON_UNARMED`
|
||||
SetCurrentPedWeapon(cache.ped, unarmed)
|
||||
ShowHelp(Strings.intro_instruction)
|
||||
DisableControlAction(0, 24, true)
|
||||
|
||||
-- Cast line
|
||||
if IsDisabledControlJustReleased(0, 24) then
|
||||
-- Casting animation
|
||||
TaskPlayAnim(cache.ped, 'mini@tennis', 'forehand_ts_md_far', 1.0, -1.0, 1.0, 48, 0, 0, 0, 0)
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.waiting_bite, Strings.waiting_bite_desc, 'inform')
|
||||
|
||||
-- Wait for fish to bite
|
||||
local waitTime = math.random(Config.timeForBite.min, Config.timeForBite.max)
|
||||
Wait(waitTime)
|
||||
|
||||
-- Check if player is still fishing
|
||||
if not fishing then
|
||||
break
|
||||
end
|
||||
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.got_bite, Strings.got_bite_desc, 'inform')
|
||||
Wait(1000)
|
||||
|
||||
-- Get fish data based on selected bait
|
||||
local fishData = lib.callback.await('wasabi_fishing:getFishData', 100, selectedBait.itemName)
|
||||
|
||||
-- Skill check to catch fish
|
||||
if lib.skillCheck(fishData.difficulty) then
|
||||
ClearPedTasks(cache.ped)
|
||||
TryFish(fishData)
|
||||
TaskPlayAnim(cache.ped, 'amb@world_human_stand_fishing@idle_a', 'idle_c', 1.0, -1.0, 1.0, 11, 0, 0, 0, 0)
|
||||
|
||||
-- Check for bait loss
|
||||
local loseChance = math.random(1,100)
|
||||
if loseChance <= selectedBait.loseChance then
|
||||
TriggerServerEvent('wasabi_fishing:loseBait', selectedBait.itemName)
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.bait_lost, Strings.bait_lost_desc, 'error')
|
||||
|
||||
-- Check if we still have bait
|
||||
local hasBait = lib.callback.await('wasabi_fishing:checkItem', 100, selectedBait.itemName)
|
||||
if not hasBait then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.no_more_bait, Strings.no_more_bait_desc, 'error')
|
||||
|
||||
-- Try to select a new bait
|
||||
local newBait = SelectBait()
|
||||
if newBait then
|
||||
selectedBait = newBait
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.new_bait, string.format(Strings.new_bait_desc, selectedBait.label), 'inform')
|
||||
else
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.no_bait, Strings.no_bait_desc, 'error')
|
||||
fishing = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Failed to catch fish
|
||||
local breakChance = math.random(1,100)
|
||||
if breakChance < Config.fishingRod.breakChance then
|
||||
TriggerServerEvent('wasabi_fishing:rodBroke')
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.rod_broke, Strings.rod_broke_desc, 'error')
|
||||
ClearPedTasks(cache.ped)
|
||||
fishing = false
|
||||
break
|
||||
end
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.failed_fish, Strings.failed_fish_desc, 'error')
|
||||
end
|
||||
elseif IsControlJustReleased(0, 194) then
|
||||
-- Cancel fishing with backspace
|
||||
ClearPedTasks(cache.ped)
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.fishing_canceled, Strings.fishing_canceled_desc, 'inform')
|
||||
break
|
||||
elseif #(GetEntityCoords(cache.ped) - waterLoc) > 30 then
|
||||
-- Too far from water
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.too_far, Strings.too_far_desc, 'error')
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Clean up
|
||||
fishing = false
|
||||
DeleteObject(pole)
|
||||
RemoveAnimDict('mini@tennis')
|
||||
RemoveAnimDict('amb@world_human_stand_fishing@idle_a')
|
||||
end
|
||||
|
||||
RegisterNetEvent('wasabi_fishing:startFishing', function()
|
||||
-- Check if player is in a valid state to fish
|
||||
if IsPedInAnyVehicle(cache.ped) or IsPedSwimming(cache.ped) then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.cannot_perform, Strings.cannot_perform_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if already fishing
|
||||
if fishing then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.already_fishing, Strings.already_fishing_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Check for water
|
||||
local water, waterLoc = WaterCheck()
|
||||
if not water then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.no_water, Strings.no_water_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Select bait
|
||||
local selectedBait = SelectBait()
|
||||
if not selectedBait then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.no_bait, Strings.no_bait_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Start fishing process
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.bait_selected, string.format(Strings.bait_selected_desc, selectedBait.label), 'inform')
|
||||
StartFishingProcess(selectedBait, waterLoc)
|
||||
end)
|
||||
|
||||
-- Process fish with knife
|
||||
RegisterNetEvent('wasabi_fishing:processFish', function(fishItem)
|
||||
-- Check if player has knife
|
||||
local hasKnife = lib.callback.await('wasabi_fishing:checkItem', 100, Config.processing.knifeItem)
|
||||
if not hasKnife then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.no_knife, Strings.no_knife_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Find processing data for this fish
|
||||
local processData = nil
|
||||
for _, data in pairs(Config.processing.products) do
|
||||
if data.sourceItem == fishItem then
|
||||
processData = data
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not processData then
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.cannot_process, Strings.cannot_process_desc, 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Start processing animation
|
||||
local playerPed = cache.ped
|
||||
local coords = GetEntityCoords(playerPed)
|
||||
|
||||
lib.requestAnimDict('anim@amb@business@coc@coc_unpack_cut@', 100)
|
||||
TaskPlayAnim(playerPed, 'anim@amb@business@coc@coc_unpack_cut@', 'fullcut_cycle_v6_cokecutter', 8.0, -8.0, -1, 1, 0, false, false, false)
|
||||
|
||||
-- Processing progress bar
|
||||
if lib.progressBar({
|
||||
duration = 5000,
|
||||
label = Strings.processing_fish,
|
||||
useWhileDead = false,
|
||||
canCancel = true,
|
||||
disable = {
|
||||
car = true,
|
||||
move = true,
|
||||
combat = true
|
||||
},
|
||||
anim = {
|
||||
dict = 'anim@amb@business@coc@coc_unpack_cut@',
|
||||
clip = 'fullcut_cycle_v6_cokecutter'
|
||||
},
|
||||
}) then
|
||||
-- Success - server handles the actual item processing
|
||||
TriggerServerEvent('wasabi_fishing:processItem', fishItem)
|
||||
else
|
||||
-- Cancelled
|
||||
TriggerEvent('wasabi_fishing:notify', Strings.canceled, Strings.canceled_desc, 'error')
|
||||
end
|
||||
|
||||
ClearPedTasks(playerPed)
|
||||
RemoveAnimDict('anim@amb@business@coc@coc_unpack_cut@')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('wasabi_fishing:interupt', function()
|
||||
fishing = false
|
||||
ClearPedTasks(cache.ped)
|
||||
end)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue