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')
|
RegisterNetEvent('force-sling:client:syncWeapons')
|
||||||
AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action)
|
AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData, action)
|
||||||
if not Sling then return end
|
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
|
if action == 'attach' then
|
||||||
local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId))
|
local targetPed = GetPlayerPed(GetPlayerFromServerId(playerId))
|
||||||
if not targetPed or not DoesEntityExist(targetPed) then return end
|
if not targetPed or not DoesEntityExist(targetPed) then return end
|
||||||
|
|
||||||
-- Erstelle einen eindeutigen Key für die Waffe des anderen Spielers
|
-- 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 {}
|
otherPlayersWeapons[playerId] = otherPlayersWeapons[playerId] or {}
|
||||||
|
|
||||||
-- Verwende den eindeutigen Key für die Waffe
|
if not otherPlayersWeapons[playerId][uniqueWeaponKey] then
|
||||||
Utils:CreateAndAttachWeapon(
|
Utils:CreateAndAttachWeapon(
|
||||||
uniqueWeaponKey, -- Eindeutiger Key
|
uniqueWeaponKey,
|
||||||
weaponData.weaponVal,
|
weaponData.weaponVal,
|
||||||
weaponData.coords,
|
weaponData.coords,
|
||||||
targetPed,
|
targetPed,
|
||||||
true -- Flag für andere Spieler
|
true -- Flag für andere Spieler
|
||||||
)
|
)
|
||||||
otherPlayersWeapons[playerId][uniqueWeaponKey] = true
|
otherPlayersWeapons[playerId][uniqueWeaponKey] = true
|
||||||
|
end
|
||||||
|
|
||||||
elseif action == 'detach' then
|
elseif action == 'detach' then
|
||||||
local uniqueWeaponKey = playerId .. '_' .. weaponData.weaponName
|
local uniqueWeaponKey = 'player_' .. playerId .. '_' .. weaponData.weaponName
|
||||||
if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then
|
if otherPlayersWeapons[playerId] and otherPlayersWeapons[playerId][uniqueWeaponKey] then
|
||||||
Utils:DeleteWeapon(uniqueWeaponKey)
|
Utils:DeleteWeapon(uniqueWeaponKey)
|
||||||
otherPlayersWeapons[playerId][uniqueWeaponKey] = nil
|
otherPlayersWeapons[playerId][uniqueWeaponKey] = nil
|
||||||
|
@ -104,6 +105,7 @@ AddEventHandler('force-sling:client:syncWeapons', function(playerId, weaponData,
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
RegisterNetEvent('force-sling:client:cleanupPlayerWeapons')
|
RegisterNetEvent('force-sling:client:cleanupPlayerWeapons')
|
||||||
AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId)
|
AddEventHandler('force-sling:client:cleanupPlayerWeapons', function(playerId)
|
||||||
if not Sling then return end
|
if not Sling then return end
|
||||||
|
|
|
@ -106,7 +106,6 @@ function Sling:WeaponThread()
|
||||||
Sling.cachedAttachments[weaponName] = {}
|
Sling.cachedAttachments[weaponName] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Erweiterte Checks für Spielerzustände
|
|
||||||
local isInVehicle = IsPedInAnyVehicle(playerPed, false)
|
local isInVehicle = IsPedInAnyVehicle(playerPed, false)
|
||||||
local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR")
|
local isSitting = IsPedUsingScenario(playerPed, "PROP_HUMAN_SEAT_CHAIR")
|
||||||
local isRagdoll = IsPedRagdoll(playerPed)
|
local isRagdoll = IsPedRagdoll(playerPed)
|
||||||
|
@ -115,23 +114,14 @@ function Sling:WeaponThread()
|
||||||
if weapon == weaponVal.name or shouldHideWeapons then
|
if weapon == weaponVal.name or shouldHideWeapons then
|
||||||
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
||||||
Utils:DeleteWeapon(weaponName)
|
Utils:DeleteWeapon(weaponName)
|
||||||
if shouldHideWeapons then
|
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
if not DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
||||||
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or
|
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 }
|
{ 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)
|
||||||
if not shouldHideWeapons then
|
Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -152,43 +142,34 @@ function Sling:WeaponThread()
|
||||||
ragdoll = IsPedRagdoll(playerPed)
|
ragdoll = IsPedRagdoll(playerPed)
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Überprüfe, ob sich der Zustand geändert hat
|
|
||||||
local stateChanged = lastState.inVehicle ~= currentState.inVehicle or
|
local stateChanged = lastState.inVehicle ~= currentState.inVehicle or
|
||||||
lastState.sitting ~= currentState.sitting or
|
lastState.sitting ~= currentState.sitting or
|
||||||
lastState.ragdoll ~= currentState.ragdoll
|
lastState.ragdoll ~= currentState.ragdoll
|
||||||
|
|
||||||
if stateChanged then
|
if stateChanged then
|
||||||
-- Aktualisiere den letzten Status
|
|
||||||
lastState = Utils:DeepCopy(currentState)
|
lastState = Utils:DeepCopy(currentState)
|
||||||
|
|
||||||
local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll
|
local shouldHideWeapons = currentState.inVehicle or currentState.sitting or currentState.ragdoll
|
||||||
|
|
||||||
if shouldHideWeapons then
|
-- Nur eigene Waffen verarbeiten
|
||||||
-- Entferne alle Waffen
|
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
||||||
for weaponName, _ in pairs(Sling.cachedAttachments) do
|
if shouldHideWeapons then
|
||||||
if DoesEntityExist(Sling.cachedAttachments[weaponName].obj) then
|
if DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
|
||||||
Utils:DeleteWeapon(weaponName)
|
Utils:DeleteWeapon(weaponName)
|
||||||
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
Sling:SyncWeaponAttachment(weaponName, nil, nil, 'detach')
|
||||||
end
|
end
|
||||||
end
|
else
|
||||||
else
|
|
||||||
-- Füge Waffen wieder hinzu
|
|
||||||
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
|
||||||
if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
|
if not DoesEntityExist(Sling.cachedAttachments[weaponName]?.obj) then
|
||||||
local coords = Sling.cachedPositions[weaponName] or Sling.cachedPresets[weaponName] or
|
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 }
|
{ 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')
|
Sling:SyncWeaponAttachment(weaponName, weaponVal, coords, 'attach')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
while Sling.inPositioning do
|
|
||||||
Wait(1000)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then
|
if not (currentState.inVehicle or currentState.sitting or currentState.ragdoll) then
|
||||||
|
-- Nur eigene Waffen verarbeiten
|
||||||
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
for weaponName, weaponVal in pairs(Sling.cachedWeapons) do
|
||||||
handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon)
|
handleWeaponAttachment(weaponName, weaponVal, playerPed, weapon)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ local positions = {}
|
||||||
local presets = {}
|
local presets = {}
|
||||||
local positionsFile = 'positions.json'
|
local positionsFile = 'positions.json'
|
||||||
local presetsFile = 'presets.json'
|
local presetsFile = 'presets.json'
|
||||||
|
local attachedWeapons = {}
|
||||||
|
|
||||||
-- Load saved positions from JSON file
|
-- Load saved positions from JSON file
|
||||||
local function LoadPositions()
|
local function LoadPositions()
|
||||||
|
@ -29,19 +30,44 @@ local function SavePresets()
|
||||||
SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1)
|
SaveResourceFile(GetCurrentResourceName(), 'json/' .. presetsFile, json.encode(presets), -1)
|
||||||
end
|
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
|
-- Load data when resource starts
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
LoadPositions()
|
LoadPositions()
|
||||||
LoadPresets()
|
LoadPresets()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Weapon sync
|
-- Weapon sync with verification
|
||||||
local attachedWeapons = {}
|
|
||||||
|
|
||||||
RegisterNetEvent('force-sling:server:syncWeapons')
|
RegisterNetEvent('force-sling:server:syncWeapons')
|
||||||
AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action)
|
AddEventHandler('force-sling:server:syncWeapons', function(weaponData, action)
|
||||||
local src = source
|
local src = source
|
||||||
|
|
||||||
if action == 'attach' then
|
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] = attachedWeapons[src] or {}
|
||||||
attachedWeapons[src][weaponData.weaponName] = weaponData
|
attachedWeapons[src][weaponData.weaponName] = weaponData
|
||||||
elseif action == 'detach' then
|
elseif action == 'detach' then
|
||||||
|
@ -55,7 +81,17 @@ end)
|
||||||
|
|
||||||
-- Callbacks
|
-- Callbacks
|
||||||
lib.callback.register('force-sling:callback:getCachedPositions', function(source)
|
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)
|
end)
|
||||||
|
|
||||||
lib.callback.register('force-sling:callback:getCachedPresets', function(source)
|
lib.callback.register('force-sling:callback:getCachedPresets', function(source)
|
||||||
|
@ -64,23 +100,34 @@ end)
|
||||||
|
|
||||||
lib.callback.register('force-sling:callback:isPlayerAdmin', function(source)
|
lib.callback.register('force-sling:callback:isPlayerAdmin', function(source)
|
||||||
local src = source
|
local src = source
|
||||||
-- Add your admin check logic here
|
if Config.Framework.name == "qbcore" then
|
||||||
-- Example for QBCore:
|
local Player = QBCore.Functions.GetPlayer(src)
|
||||||
-- local Player = QBCore.Functions.GetPlayer(src)
|
return Player and Player.PlayerData.admin or false
|
||||||
-- return Player.PlayerData.admin or false
|
elseif Config.Framework.name == "esx" then
|
||||||
|
local xPlayer = ESX.GetPlayerFromId(src)
|
||||||
-- For testing, returning true
|
return xPlayer and xPlayer.getGroup() == 'admin' or false
|
||||||
return {isAdmin = true}
|
end
|
||||||
|
return false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon)
|
lib.callback.register('force-sling:callback:resetWeaponPositions', function(source, weapon)
|
||||||
local src = source
|
local src = source
|
||||||
if weapon then
|
if weapon then
|
||||||
positions[weapon] = nil
|
if DoesPlayerHaveWeapon(src, weapon) then
|
||||||
|
positions[weapon] = nil
|
||||||
|
SavePositions()
|
||||||
|
end
|
||||||
else
|
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
|
end
|
||||||
SavePositions()
|
|
||||||
return positions
|
return positions
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -94,11 +141,18 @@ AddEventHandler('force-sling:server:saveWeaponPosition', function(position, rota
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPreset then
|
if isPreset then
|
||||||
presets[weaponName] = data
|
-- Nur Admins können Presets speichern
|
||||||
SavePresets()
|
local isAdmin = lib.callback.await('force-sling:callback:isPlayerAdmin', src)
|
||||||
|
if isAdmin then
|
||||||
|
presets[weaponName] = data
|
||||||
|
SavePresets()
|
||||||
|
end
|
||||||
else
|
else
|
||||||
positions[weaponName] = data
|
-- Überprüfe ob der Spieler die Waffe besitzt
|
||||||
SavePositions()
|
if DoesPlayerHaveWeapon(src, weaponName) then
|
||||||
|
positions[weaponName] = data
|
||||||
|
SavePositions()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -110,3 +164,20 @@ AddEventHandler('playerDropped', function()
|
||||||
attachedWeapons[src] = nil
|
attachedWeapons[src] = nil
|
||||||
end
|
end
|
||||||
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