forked from Simnation/Main
Merge branch 'master' of https://git.evolution-state-life.de/Evolution-State-Life/Main
This commit is contained in:
commit
07685eab3e
3 changed files with 113 additions and 59 deletions
|
@ -74,29 +74,30 @@ end)
|
|||
RegisterNetEvent('force-sling:client:syncWeapons')
|
||||
AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action)
|
||||
if not Sling then return end
|
||||
if playerId == cache.serverId then return end -- Ignoriere eigene Events
|
||||
if playerId == cache.serverId then return end
|
||||
|
||||
if action == 'attach' then
|
||||
local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId))
|
||||
if not targetPed or not DoesEntityExist(targetPed) then return end
|
||||
|
||||
-- Erstelle einen eindeutigen Key für die Waffe des anderen Spielers
|
||||
local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName
|
||||
local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName
|
||||
|
||||
otherPlayersWeapons[playerId] = otherPlayersWeapons[playerId] or {}
|
||||
|
||||
-- Verwende den eindeutigen Key für die Waffe
|
||||
Utils:CreateAndAttachWeapon(
|
||||
uniqueWeaponKey, -- Eindeutiger Key
|
||||
weaponData.weaponVal,
|
||||
weaponData.coords,
|
||||
targetPed,
|
||||
true -- Flag für andere Spieler
|
||||
)
|
||||
otherPlayersWeapons[playerId][uniqueWeaponKey] = true
|
||||
if not otherPlayersWeapons[playerId][uniqueWeaponKey] then
|
||||
Utils:CreateAndAttachWeapon(
|
||||
uniqueWeaponKey,
|
||||
weaponData.weaponVal,
|
||||
weaponData.coords,
|
||||
targetPed,
|
||||
true -- Flag für andere Spieler
|
||||
)
|
||||
otherPlayersWeapons[playerId][uniqueWeaponKey] = true
|
||||
end
|
||||
|
||||
elseif action == 'detach' then
|
||||
local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName
|
||||
local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName
|
||||
if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then
|
||||
Utils:DeleteWeapon(uniqueWeaponKey)
|
||||
otherPlayersWeapons[playerId][uniqueWeaponKey] = nil
|
||||
|
@ -104,6 +105,7 @@ AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData,
|
|||
end
|
||||
end)
|
||||
|
||||
|
||||
RegisterNetEvent('force-sling:client:cleanupPlayerWeapons')
|
||||
AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId)
|
||||
if not Sling then return end
|
||||
|
|
|
@ -106,7 +106,6 @@ function Sling:WeaponThread()
|
|||
Sling.cachedAttachments[weaponName] = {}
|
||||
end
|
||||
|
||||
-- Erweiterte Checks für Spielerzustände
|
||||
local isInVehicle = IsPedInAnyVehicle(playerPed, false)
|
||||
local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR")
|
||||
local isRagdoll = IsPedRagdoll(playerPed)
|
||||
|
@ -115,23 +114,14 @@ function Sling:WeaponThread()
|
|||
if weapon == weaponVal.name or shouldHideWeapons then
|
||||
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
||||
Utils:DeleteWeapon(weaponName)
|
||||
if shouldHideWeapons then
|
||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||
end
|
||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||
end
|
||||
else
|
||||
if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
||||
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or
|
||||
{ coords = { x = 0.0, y = -0.15, z = 0.0 }, rot = { x = 0.0, y = 0.0, z = 0.0 }, boneId = DEFAULT_BONE }
|
||||
Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed)
|
||||
if not shouldHideWeapons then
|
||||
Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
|
||||
end
|
||||
else
|
||||
if not IsEntityAttachedToEntity(Sling.cachedAttachments[weaponName].placeholder, playerPed) then
|
||||
Utils:DeleteWeapon(weaponName)
|
||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||
end
|
||||
Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed, false)
|
||||
Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -152,43 +142,34 @@ function Sling:WeaponThread()
|
|||
ragdoll = IsPedRagdoll(playerPed)
|
||||
}
|
||||
|
||||
-- Überprüfe, ob sich der Zustand geändert hat
|
||||
local stateChanged = lastState.inVehicle ~= currentState.inVehicle or
|
||||
lastState.sitting ~= currentState.sitting or
|
||||
lastState.ragdoll ~= currentState.ragdoll
|
||||
|
||||
if stateChanged then
|
||||
-- Aktualisiere den letzten Status
|
||||
lastState = Utils:DeepCopy(currentState)
|
||||
|
||||
local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll
|
||||
|
||||
if shouldHideWeapons then
|
||||
-- Entferne alle Waffen
|
||||
for weaponName, _ in pairs(Sling.cachedAttachments) do
|
||||
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
||||
-- Nur eigene Waffen verarbeiten
|
||||
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
||||
if shouldHideWeapons then
|
||||
if DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
|
||||
Utils:DeleteWeapon(weaponName)
|
||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Füge Waffen wieder hinzu
|
||||
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
||||
else
|
||||
if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
|
||||
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or
|
||||
{ coords = { x = 0.0, y = -0.15, z = 0.0 }, rot = { x = 0.0, y = 0.0, z = 0.0 }, boneId = DEFAULT_BONE }
|
||||
Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed)
|
||||
Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed, false)
|
||||
Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while Sling.inPositioning do
|
||||
Wait(1000)
|
||||
end
|
||||
|
||||
if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then
|
||||
-- Nur eigene Waffen verarbeiten
|
||||
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
||||
handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon)
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ local positions = {}
|
|||
local presets = {}
|
||||
local positionsFile = 'positions.json'
|
||||
local presetsFile = 'presets.json'
|
||||
local attachedWeapons = {}
|
||||
|
||||
-- Load saved positions from JSON file
|
||||
local function LoadPositions()
|
||||
|
@ -29,19 +30,44 @@ local function SavePresets()
|
|||
SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1)
|
||||
end
|
||||
|
||||
-- Überprüfe ob ein Spieler eine Waffe besitzt
|
||||
local function DoesPlayerHaveWeapon(source, weaponName)
|
||||
if Config.Framework.name == "qbcore" then
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if Player then
|
||||
for _, item in pairs(Player.PlayerData.items) do
|
||||
if item.name == weaponName then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif Config.Framework.name == "esx" then
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
if xPlayer then
|
||||
local hasWeapon = xPlayer.hasWeapon(weaponName)
|
||||
return hasWeapon
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Load data when resource starts
|
||||
CreateThread(function()
|
||||
LoadPositions()
|
||||
LoadPresets()
|
||||
end)
|
||||
|
||||
-- Weapon sync
|
||||
local attachedWeapons = {}
|
||||
|
||||
-- Weapon sync with verification
|
||||
RegisterNetEvent('force-sling:server:syncWeapons')
|
||||
AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action)
|
||||
local src = source
|
||||
|
||||
if action == 'attach' then
|
||||
-- Überprüfe ob der Spieler die Waffe besitzt
|
||||
if not DoesPlayerHaveWeapon(src, weaponData.weaponName) then
|
||||
return
|
||||
end
|
||||
|
||||
attachedWeapons[src] = attachedWeapons[src] or {}
|
||||
attachedWeapons[src][weaponData.weaponName] = weaponData
|
||||
elseif action == 'detach' then
|
||||
|
@ -55,7 +81,17 @@ end)
|
|||
|
||||
-- Callbacks
|
||||
lib.callback.register('force-sling:callback:getCachedPositions', function(source)
|
||||
return positions
|
||||
local src = source
|
||||
local playerPositions = {}
|
||||
|
||||
-- Filtere nur die Positionen für Waffen, die der Spieler besitzt
|
||||
for weaponName, posData in pairs(positions) do
|
||||
if DoesPlayerHaveWeapon(src, weaponName) then
|
||||
playerPositions[weaponName] = posData
|
||||
end
|
||||
end
|
||||
|
||||
return playerPositions
|
||||
end)
|
||||
|
||||
lib.callback.register('force-sling:callback:getCachedPresets', function(source)
|
||||
|
@ -64,23 +100,34 @@ end)
|
|||
|
||||
lib.callback.register('force-sling:callback:isPlayerAdmin', function(source)
|
||||
local src = source
|
||||
-- Add your admin check logic here
|
||||
-- Example for QBCore:
|
||||
-- local Player = QBCore.Functions.GetPlayer(src)
|
||||
-- return Player.PlayerData.admin or false
|
||||
|
||||
-- For testing, returning true
|
||||
return {isAdmin = true}
|
||||
if Config.Framework.name == "qbcore" then
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
return Player and Player.PlayerData.admin or false
|
||||
elseif Config.Framework.name == "esx" then
|
||||
local xPlayer = ESX.GetPlayerFromId(src)
|
||||
return xPlayer and xPlayer.getGroup() == 'admin' or false
|
||||
end
|
||||
return false
|
||||
end)
|
||||
|
||||
lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon)
|
||||
local src = source
|
||||
if weapon then
|
||||
positions[weapon] = nil
|
||||
if DoesPlayerHaveWeapon(src, weapon) then
|
||||
positions[weapon] = nil
|
||||
SavePositions()
|
||||
end
|
||||
else
|
||||
positions = {}
|
||||
-- Beim kompletten Reset nur die Positionen der Waffen löschen, die der Spieler besitzt
|
||||
local newPositions = {}
|
||||
for weaponName, posData in pairs(positions) do
|
||||
if not DoesPlayerHaveWeapon(src, weaponName) then
|
||||
newPositions[weaponName] = posData
|
||||
end
|
||||
end
|
||||
positions = newPositions
|
||||
SavePositions()
|
||||
end
|
||||
SavePositions()
|
||||
return positions
|
||||
end)
|
||||
|
||||
|
@ -94,11 +141,18 @@ AddEventHandler('force-sling:server:saveWeaponPosition', function(position, rota
|
|||
}
|
||||
|
||||
if isPreset then
|
||||
presets[weaponName] = data
|
||||
SavePresets()
|
||||
-- Nur Admins können Presets speichern
|
||||
local isAdmin = lib.callback.await('force-sling:callback:isPlayerAdmin', src)
|
||||
if isAdmin then
|
||||
presets[weaponName] = data
|
||||
SavePresets()
|
||||
end
|
||||
else
|
||||
positions[weaponName] = data
|
||||
SavePositions()
|
||||
-- Überprüfe ob der Spieler die Waffe besitzt
|
||||
if DoesPlayerHaveWeapon(src, weaponName) then
|
||||
positions[weaponName] = data
|
||||
SavePositions()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -110,3 +164,20 @@ AddEventHandler('playerDropped', function()
|
|||
attachedWeapons[src] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Periodische Überprüfung der angehängten Waffen
|
||||
CreateThread(function()
|
||||
while true do
|
||||
for playerId, weapons in pairs(attachedWeapons) do
|
||||
for weaponName, _ in pairs(weapons) do
|
||||
if not DoesPlayerHaveWeapon(playerId, weaponName) then
|
||||
-- Spieler hat die Waffe nicht mehr, entferne sie
|
||||
TriggerClientEvent('force-sling:client:syncWeapons', -1, playerId, {weaponName = weaponName}, 'detach')
|
||||
attachedWeapons[playerId][weaponName] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Wait(5000) -- Alle 5 Sekunden überprüfen
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue