1
0
Fork 0
forked from Simnation/Main

Update client.lua

This commit is contained in:
Nordi98 2025-07-26 07:24:05 +02:00
parent 79e5103db6
commit 123e2c98c3

View file

@ -3,12 +3,12 @@ local inTDM = false
local currentTeam = nil local currentTeam = nil
local currentGameId = nil local currentGameId = nil
local currentField = nil local currentField = nil
local currentLobbyField = nil -- Neue Variable für aktuelle Lobby local currentLobbyField = nil
local tdmBlips = {} -- Mehrere Blips local tdmBlips = {}
local teamZoneBlips = {} local teamZoneBlips = {}
local isHit = false local isHit = false
local activeGames = {} local activeGames = {}
local spawnedNPCs = {} -- Gespawnte NPCs verwalten local spawnedNPCs = {}
-- Spieler Statistiken -- Spieler Statistiken
local playerStats = { local playerStats = {
@ -17,7 +17,7 @@ local playerStats = {
gamesPlayed = 0 gamesPlayed = 0
} }
-- Events (gleich wie vorher, nur leaveGame angepasst) -- Events
RegisterNetEvent('tdm:updateGamesList', function(games) RegisterNetEvent('tdm:updateGamesList', function(games)
activeGames = games activeGames = games
end) end)
@ -63,21 +63,32 @@ RegisterNetEvent('tdm:leaveGame', function()
currentField = nil currentField = nil
isHit = false isHit = false
-- Zurück zur entsprechenden Lobby (falls vorher in einem Spiel) -- Sichere Rückkehr zur Lobby
if previousField and Config.gameFields[previousField] then local lobbyPos = nil
local lobbyPos = Config.gameFields[previousField].lobby.pos
SetEntityCoords(PlayerPedId(), lobbyPos.x, lobbyPos.y, lobbyPos.z) -- Versuche zuerst die vorherige Feld-Lobby
elseif currentLobbyField and Config.gameFields[currentLobbyField] then if previousField and Config.gameFields[previousField] and Config.gameFields[previousField].lobby then
-- Zurück zur aktuellen Lobby lobbyPos = Config.gameFields[previousField].lobby.pos
local lobbyPos = Config.gameFields[currentLobbyField].lobby.pos -- Dann die aktuelle Lobby-Feld
elseif currentLobbyField and Config.gameFields[currentLobbyField] and Config.gameFields[currentLobbyField].lobby then
lobbyPos = Config.gameFields[currentLobbyField].lobby.pos
-- Fallback zur ersten verfügbaren Lobby
else
for fieldId, fieldData in pairs(Config.gameFields) do
if fieldData.lobby and fieldData.lobby.pos then
lobbyPos = fieldData.lobby.pos
break
end
end
end
-- Teleport zur Lobby (mit Fallback-Position)
if lobbyPos then
SetEntityCoords(PlayerPedId(), lobbyPos.x, lobbyPos.y, lobbyPos.z) SetEntityCoords(PlayerPedId(), lobbyPos.x, lobbyPos.y, lobbyPos.z)
else else
-- Fallback zur ersten Lobby -- Notfall-Fallback Position (anpassen an deine Map)
local firstField = next(Config.gameFields) SetEntityCoords(PlayerPedId(), -1042.4, -2745.8, 21.4)
if firstField then print("^3[TDM WARNING]^7 Keine Lobby gefunden, Fallback-Position verwendet!")
local lobbyPos = Config.gameFields[firstField].lobby.pos
SetEntityCoords(PlayerPedId(), lobbyPos.x, lobbyPos.y, lobbyPos.z)
end
end end
-- Maske entfernen -- Maske entfernen
@ -95,7 +106,6 @@ RegisterNetEvent('tdm:leaveGame', function()
}) })
end) end)
-- Alle anderen Events bleiben gleich...
RegisterNetEvent('tdm:joinRequest', function(gameId, playerName, playerId) RegisterNetEvent('tdm:joinRequest', function(gameId, playerName, playerId)
local alert = lib.alertDialog({ local alert = lib.alertDialog({
header = 'Join Anfrage', header = 'Join Anfrage',
@ -219,7 +229,7 @@ RegisterNetEvent('tdm:gameEnded', function(winnerTeam, team1Score, team2Score)
TriggerServerEvent('tdm:leaveGame') TriggerServerEvent('tdm:leaveGame')
end) end)
-- Angepasste setTeamMask Funktion -- Funktionen
function setTeamMask(team) function setTeamMask(team)
local ped = PlayerPedId() local ped = PlayerPedId()
local maskData = Config.teamMasks[team] local maskData = Config.teamMasks[team]
@ -236,64 +246,66 @@ function setTeamMask(team)
end end
end end
-- Alternative Methode über QBCore Player Data function createTeamZoneBlip(team, fieldConfig)
function setTeamMaskQB(team) local zone = fieldConfig.teamZones[team]
local ped = PlayerPedId()
local Player = QBCore.Functions.GetPlayerData()
local maskData = Config.teamMasks[team]
if maskData and Player.charinfo then local blip = AddBlipForRadius(zone.center.x, zone.center.y, zone.center.z, zone.radius)
-- Geschlecht aus QBCore Charinfo SetBlipHighDetail(blip, true)
local playerGender = Player.charinfo.gender == 1 and "female" or "male" SetBlipColour(blip, team == 'team1' and 1 or 3)
SetBlipAlpha(blip, 128)
-- Entsprechende Maske setzen
local genderMask = maskData[playerGender] teamZoneBlips[team] = blip
if genderMask then end
SetPedComponentVariation(ped, genderMask.component, genderMask.drawable, genderMask.texture, 0)
function removeTeamZoneBlips()
for team, blip in pairs(teamZoneBlips) do
if DoesBlipExist(blip) then
RemoveBlip(blip)
end end
end end
teamZoneBlips = {}
end
function highlightTeamZone(team)
if teamZoneBlips[team] and DoesBlipExist(teamZoneBlips[team]) then
SetBlipFlashes(teamZoneBlips[team], true)
end
end end
-- Erweiterte Funktion mit Fallback function showHitMarker()
function setTeamMaskAdvanced(team) CreateThread(function()
local ped = PlayerPedId() local startTime = GetGameTimer()
local maskData = Config.teamMasks[team]
if not maskData then return end
local playerGender = "male" -- Default
-- Methode 1: Über Ped Model
if GetEntityModel(ped) == GetHashKey("mp_f_freemode_01") then
playerGender = "female"
end
-- Methode 2: Über QBCore (Fallback)
if playerGender == "male" then
local Player = QBCore.Functions.GetPlayerData()
if Player.charinfo and Player.charinfo.gender == 1 then
playerGender = "female"
end
end
-- Maske setzen
local genderMask = maskData[playerGender]
if genderMask then
SetPedComponentVariation(ped, genderMask.component, genderMask.drawable, genderMask.texture, 0)
lib.notify({ while GetGameTimer() - startTime < 500 do
title = 'TeamDeathmatch', Wait(0)
description = 'Team-Maske (' .. playerGender .. ') angelegt!',
type = 'info', DrawRect(0.5, 0.5, 0.02, 0.002, 255, 0, 0, 255)
duration = 2000 DrawRect(0.5, 0.5, 0.002, 0.02, 255, 0, 0, 255)
})
end SetTextFont(4)
SetTextProportional(1)
SetTextScale(0.5, 0.5)
SetTextColour(255, 0, 0, 255)
SetTextEntry("STRING")
AddTextComponentString("TREFFER!")
SetTextCentre(true)
DrawText(0.5, 0.45)
end
end)
end end
-- Angepasste Menü-Funktionen
function openMainMenu(fieldId) function openMainMenu(fieldId)
currentLobbyField = fieldId -- Aktuelle Lobby merken -- Sicherheitscheck
if not fieldId or not Config.gameFields[fieldId] then
lib.notify({
title = 'Fehler',
description = 'Ungültiges Spielfeld!',
type = 'error'
})
return
end
currentLobbyField = fieldId
TriggerServerEvent('tdm:requestGamesList') TriggerServerEvent('tdm:requestGamesList')
Wait(100) Wait(100)
@ -341,6 +353,15 @@ function openMainMenu(fieldId)
end end
function openCreateGameMenu(fieldId) function openCreateGameMenu(fieldId)
if not fieldId or not Config.gameFields[fieldId] then
lib.notify({
title = 'Fehler',
description = 'Ungültiges Spielfeld!',
type = 'error'
})
return
end
local fieldData = Config.gameFields[fieldId] local fieldData = Config.gameFields[fieldId]
local input = lib.inputDialog('Neues Spiel erstellen - ' .. fieldData.name, { local input = lib.inputDialog('Neues Spiel erstellen - ' .. fieldData.name, {
@ -381,6 +402,15 @@ function openCreateGameMenu(fieldId)
end end
function openJoinGameMenu(fieldId) function openJoinGameMenu(fieldId)
if not fieldId or not Config.gameFields[fieldId] then
lib.notify({
title = 'Fehler',
description = 'Ungültiges Spielfeld!',
type = 'error'
})
return
end
TriggerServerEvent('tdm:requestGamesList') TriggerServerEvent('tdm:requestGamesList')
Wait(200) Wait(200)
@ -450,7 +480,7 @@ function openJoinGameMenu(fieldId)
lib.showContext('tdm_join_menu_' .. fieldId) lib.showContext('tdm_join_menu_' .. fieldId)
end end
-- Alle Threads bleiben gleich... -- Zone Checker Thread
CreateThread(function() CreateThread(function()
while true do while true do
Wait(500) Wait(500)
@ -480,6 +510,7 @@ CreateThread(function()
end end
end) end)
-- Zone Marker Renderer
CreateThread(function() CreateThread(function()
while true do while true do
Wait(0) Wait(0)
@ -515,6 +546,7 @@ CreateThread(function()
end end
end) end)
-- Damage Handler
CreateThread(function() CreateThread(function()
while true do while true do
Wait(100) Wait(100)
@ -541,6 +573,7 @@ CreateThread(function()
end end
end) end)
-- Death Handler
CreateThread(function() CreateThread(function()
while true do while true do
Wait(1000) Wait(1000)
@ -564,58 +597,70 @@ CreateThread(function()
end end
end) end)
-- Angepasstes NPC Setup für alle Felder -- NPC Setup für alle Felder
CreateThread(function() CreateThread(function()
-- Für jedes Spielfeld Blip und NPC erstellen -- Für jedes Spielfeld Blip und NPC erstellen
for fieldId, fieldData in pairs(Config.gameFields) do for fieldId, fieldData in pairs(Config.gameFields) do
local lobbyPos = fieldData.lobby.pos if fieldData.lobby and fieldData.lobby.pos and fieldData.lobby.npc then
local npcData = fieldData.lobby.npc local lobbyPos = fieldData.lobby.pos
local npcData = fieldData.lobby.npc
-- Blip erstellen
local blip = AddBlipForCoord(lobbyPos.x, lobbyPos.y, lobbyPos.z) -- Blip erstellen
SetBlipSprite(blip, 432) local blip = AddBlipForCoord(lobbyPos.x, lobbyPos.y, lobbyPos.z)
SetBlipDisplay(blip, 4) SetBlipSprite(blip, 432)
SetBlipScale(blip, 0.8) SetBlipDisplay(blip, 4)
SetBlipColour(blip, 1) SetBlipScale(blip, 0.8)
SetBlipAsShortRange(blip, true) SetBlipColour(blip, 1)
BeginTextCommandSetBlipName("STRING") SetBlipAsShortRange(blip, true)
AddTextComponentString("TDM - " .. fieldData.name) BeginTextCommandSetBlipName("STRING")
EndTextCommandSetBlipName(blip) AddTextComponentString("TDM - " .. fieldData.name)
EndTextCommandSetBlipName(blip)
tdmBlips[fieldId] = blip
tdmBlips[fieldId] = blip
-- NPC erstellen
RequestModel(GetHashKey(npcData.model)) -- NPC erstellen
while not HasModelLoaded(GetHashKey(npcData.model)) do RequestModel(GetHashKey(npcData.model))
Wait(1) while not HasModelLoaded(GetHashKey(npcData.model)) do
end Wait(1)
end
local npc = CreatePed(4, GetHashKey(npcData.model), npcData.coords.x, npcData.coords.y, npcData.coords.z, npcData.coords.w, false, true)
SetEntityInvincible(npc, true) local npc = CreatePed(4, GetHashKey(npcData.model), npcData.coords.x, npcData.coords.y, npcData.coords.z, npcData.coords.w, false, true)
FreezeEntityPosition(npc, true) SetEntityInvincible(npc, true)
SetBlockingOfNonTemporaryEvents(npc, true) FreezeEntityPosition(npc, true)
SetBlockingOfNonTemporaryEvents(npc, true)
spawnedNPCs[fieldId] = npc
spawnedNPCs[fieldId] = npc
-- Target für diesen NPC
exports['qb-target']:AddTargetEntity(npc, { -- Target für diesen NPC
options = { exports['qb-target']:AddTargetEntity(npc, {
{ options = {
type = "client", {
event = "tdm:openFieldMenu", type = "client",
icon = "fas fa-crosshairs", event = "tdm:openFieldMenu",
label = "TeamDeathmatch - " .. fieldData.name, icon = "fas fa-crosshairs",
fieldId = fieldId label = "TeamDeathmatch - " .. fieldData.name,
fieldId = fieldId
},
}, },
}, distance = 2.5
distance = 2.5 })
}) else
print("^3[TDM WARNING]^7 Feld " .. fieldId .. " hat keine vollständige Lobby-Konfiguration!")
end
end end
end) end)
-- Event für Feld-spezifisches Menü -- Event für Feld-spezifisches Menü
RegisterNetEvent('tdm:openFieldMenu', function(data) RegisterNetEvent('tdm:openFieldMenu', function(data)
openMainMenu(data.fieldId) if data and data.fieldId then
openMainMenu(data.fieldId)
else
lib.notify({
title = 'Fehler',
description = 'Keine Feld-ID übertragen!',
type = 'error'
})
end
end) end)
-- Chat Command zum Spiel verlassen -- Chat Command zum Spiel verlassen
@ -638,3 +683,62 @@ end, false)
-- Keybind zum Spiel verlassen -- Keybind zum Spiel verlassen
RegisterKeyMapping('leavetdm', 'TeamDeathmatch verlassen', 'keyboard', 'F7') RegisterKeyMapping('leavetdm', 'TeamDeathmatch verlassen', 'keyboard', 'F7')
-- Debug Command zum Testen der Config
RegisterCommand('debugtdm', function()
print("^2[TDM DEBUG]^7 Aktuelle Werte:")
print("inTDM: " .. tostring(inTDM))
print("currentField: " .. tostring(currentField))
print("currentLobbyField: " .. tostring(currentLobbyField))
print("currentTeam: " .. tostring(currentTeam))
print("^2[TDM DEBUG]^7 Verfügbare Felder:")
for fieldId, fieldData in pairs(Config.gameFields) do
local hasLobby = fieldData.lobby and fieldData.lobby.pos and "" or ""
print("- " .. fieldId .. ": " .. fieldData.name .. " " .. hasLobby)
end
end, false)
-- Debug Commands für Masken
RegisterCommand('testmask', function(source, args)
if not args[1] or not args[2] then
lib.notify({
title = 'Debug',
description = 'Verwendung: /testmask [team1/team2] [male/female]',
type = 'error'
})
return
end
local team = args[1]
local gender = args[2]
if Config.teamMasks[team] and Config.teamMasks[team][gender] then
local maskData = Config.teamMasks[team][gender]
local ped = PlayerPedId()
SetPedComponentVariation(ped, maskData.component, maskData.drawable, maskData.texture, 0)
lib.notify({
title = 'Debug',
description = 'Maske gesetzt: ' .. team .. ' (' .. gender .. ')',
type = 'success'
})
else
lib.notify({
title = 'Debug',
description = 'Maske nicht gefunden!',
type = 'error'
})
end
end, false)
-- Command zum Entfernen der Maske
RegisterCommand('removemask', function()
SetPedComponentVariation(PlayerPedId(), 1, 0, 0, 0)
lib.notify({
title = 'Debug',
description = 'Maske entfernt!',
type = 'info'
})
end, false)