diff --git a/resources/[standalone]/nordi_tdm/client.lua b/resources/[standalone]/nordi_tdm/client.lua index 033213c24..025e20953 100644 --- a/resources/[standalone]/nordi_tdm/client.lua +++ b/resources/[standalone]/nordi_tdm/client.lua @@ -17,6 +17,11 @@ local playerStats = { gamesPlayed = 0 } +-- Debug-Funktion für Konsole +local function debugPrint(message) + print("^2[TDM DEBUG]^7 " .. message) +end + -- Events RegisterNetEvent('tdm:updateGamesList', function(games) activeGames = games @@ -53,6 +58,8 @@ RegisterNetEvent('tdm:joinGame', function(gameId, team, fieldId) description = 'Du bist dem Spiel beigetreten! Team: ' .. team, type = 'success' }) + + debugPrint("Spiel beigetreten: " .. gameId .. ", Team: " .. team .. ", Feld: " .. fieldId) end) RegisterNetEvent('tdm:leaveGame', function() @@ -104,6 +111,8 @@ RegisterNetEvent('tdm:leaveGame', function() description = 'Du hast das Spiel verlassen!', type = 'error' }) + + debugPrint("Spiel verlassen") end) RegisterNetEvent('tdm:joinRequest', function(gameId, playerName, playerId) @@ -142,67 +151,79 @@ RegisterNetEvent('tdm:joinRequestResult', function(approved, gameName) end) RegisterNetEvent('tdm:playerHit', function() - if not inTDM or isHit then return end + if not inTDM then + print("^3[TDM WARNING]^7 Hit-Event empfangen, aber nicht im TDM!") + return + end + + if isHit then + print("^3[TDM WARNING]^7 Hit-Event empfangen, aber bereits getroffen!") + return + end isHit = true local ped = PlayerPedId() - -- Animation für kurze Zeit - RequestAnimDict("random@mugging3") - while not HasAnimDictLoaded("random@mugging3") do - Wait(1) - end - - TaskPlayAnim(ped, "random@mugging3", "handsup_standing_base", 8.0, -8.0, -1, 50, 0, false, false, false) - + -- Benachrichtigung lib.notify({ title = 'TeamDeathmatch', description = 'Du wurdest getroffen! Respawn in 3 Sekunden...', type = 'error' }) - -- Nach 3 Sekunden automatisch respawnen - CreateThread(function() - Wait(3000) + -- Vereinfachter Respawn ohne Animation + SetTimeout(3000, function() + if not inTDM then return end - if inTDM and isHit and currentTeam and currentField then - -- Respawn zum Team Spawn - local fieldConfig = Config.gameFields[currentField] - local spawnPoints = fieldConfig.teamSpawns[currentTeam] - local randomSpawn = spawnPoints[math.random(#spawnPoints)] - - -- Bildschirm ausblenden für sauberen Teleport - DoScreenFadeOut(500) - Wait(500) - - -- Animation stoppen - ClearPedTasks(ped) - - -- Teleport zum Spawn - SetEntityCoords(ped, randomSpawn.x, randomSpawn.y, randomSpawn.z) - - -- Spieler ist wieder aktiv - isHit = false - - -- Zone Blip Flash stoppen - if teamZoneBlips[currentTeam] and DoesBlipExist(teamZoneBlips[currentTeam]) then - SetBlipFlashes(teamZoneBlips[currentTeam], false) - end - - -- Bildschirm wieder einblenden - Wait(100) - DoScreenFadeIn(500) - - lib.notify({ - title = 'TeamDeathmatch', - description = 'Du bist wieder im Spiel!', - type = 'success' - }) + -- Debug-Nachricht + debugPrint("Respawn wird ausgeführt...") + + -- Respawn zum Team Spawn + local fieldConfig = Config.gameFields[currentField] + if not fieldConfig then + print("^1[TDM ERROR]^7 Feldkonfiguration nicht gefunden!") + return end + + local spawnPoints = fieldConfig.teamSpawns[currentTeam] + if not spawnPoints or #spawnPoints == 0 then + print("^1[TDM ERROR]^7 Keine Spawn-Punkte gefunden!") + return + end + + local randomSpawn = spawnPoints[math.random(#spawnPoints)] + + -- Teleport zum Spawn mit Fade + DoScreenFadeOut(500) + Wait(600) + + -- Alle Animationen stoppen + ClearPedTasksImmediately(ped) + + -- Teleport + SetEntityCoords(ped, randomSpawn.x, randomSpawn.y, randomSpawn.z) + + -- Spieler ist wieder aktiv + isHit = false + + Wait(100) + DoScreenFadeIn(500) + + lib.notify({ + title = 'TeamDeathmatch', + description = 'Du bist wieder im Spiel!', + type = 'success' + }) end) end) RegisterNetEvent('tdm:updateScore', function(team1Score, team2Score, gameStats) + -- Debug-Ausgabe + debugPrint("Score Update empfangen: Team1=" .. team1Score .. ", Team2=" .. team2Score) + if gameStats then + debugPrint("GameStats: Hits=" .. (gameStats.hits or "nil") .. ", Deaths=" .. (gameStats.deaths or "nil")) + end + -- Verwende gameStats falls verfügbar, sonst lokale Stats local myHits = gameStats and gameStats.hits or playerStats.hits local myDeaths = gameStats and gameStats.deaths or playerStats.deaths @@ -234,14 +255,22 @@ RegisterNetEvent('tdm:hitRegistered', function() showHitMarker() -- Score sofort aktualisieren - TriggerServerEvent('tdm:requestScoreUpdate', currentGameId) + if currentGameId then + TriggerServerEvent('tdm:requestScoreUpdate', currentGameId) + end + + debugPrint("Treffer registriert! Neue Hits: " .. playerStats.hits) end) RegisterNetEvent('tdm:deathRegistered', function() playerStats.deaths = playerStats.deaths + 1 -- Score sofort aktualisieren - TriggerServerEvent('tdm:requestScoreUpdate', currentGameId) + if currentGameId then + TriggerServerEvent('tdm:requestScoreUpdate', currentGameId) + end + + debugPrint("Tod registriert! Neue Deaths: " .. playerStats.deaths) end) RegisterNetEvent('tdm:gameEnded', function(winnerTeam, team1Score, team2Score) @@ -276,6 +305,8 @@ RegisterNetEvent('tdm:gameEnded', function(winnerTeam, team1Score, team2Score) Wait(5000) TriggerServerEvent('tdm:leaveGame') + + debugPrint("Spiel beendet! Gewinner: " .. (winnerTeam or "Unentschieden")) end) -- Funktionen @@ -291,7 +322,12 @@ function setTeamMask(team) local genderMask = maskData[playerGender] if genderMask then SetPedComponentVariation(ped, genderMask.component, genderMask.drawable, genderMask.texture, 0) + debugPrint("Maske gesetzt: " .. team .. " (" .. playerGender .. ")") + else + debugPrint("Keine Maske für " .. team .. " (" .. playerGender .. ") gefunden!") end + else + debugPrint("Keine Masken-Daten für Team " .. team .. " gefunden!") end end @@ -304,6 +340,7 @@ function createTeamZoneBlip(team, fieldConfig) SetBlipAlpha(blip, 128) teamZoneBlips[team] = blip + debugPrint("Team Zone Blip erstellt für " .. team) end function removeTeamZoneBlips() @@ -313,6 +350,7 @@ function removeTeamZoneBlips() end end teamZoneBlips = {} + debugPrint("Team Zone Blips entfernt") end function highlightTeamZone(team) @@ -459,6 +497,7 @@ function openJoinGameMenu(fieldId) }) return end + TriggerServerEvent('tdm:requestGamesList') Wait(200) @@ -573,25 +612,14 @@ CreateThread(function() local ped = PlayerPedId() if HasEntityBeenDamagedByAnyPed(ped) then - local damager = NetworkGetEntityKillerOfPlayer(PlayerId()) + local damager = GetPedSourceOfDeath(ped) local damagerPlayer = nil -- Versuche den Angreifer zu identifizieren - if damager > 0 then - damagerPlayer = NetworkGetPlayerIndexFromPed(damager) - if damagerPlayer then - damagerPlayer = GetPlayerServerId(damagerPlayer) - end - end - - -- Alternativ über alle Spieler suchen - if not damagerPlayer then - for _, player in ipairs(GetActivePlayers()) do - local playerPed = GetPlayerPed(player) - if playerPed == GetPedSourceOfDeath(ped) then - damagerPlayer = GetPlayerServerId(player) - break - end + for _, player in ipairs(GetActivePlayers()) do + if GetPlayerPed(player) == damager then + damagerPlayer = GetPlayerServerId(player) + break end end @@ -600,6 +628,8 @@ CreateThread(function() -- Lokale Stats sofort updaten playerStats.deaths = playerStats.deaths + 1 + debugPrint("Getroffen von: " .. (damagerPlayer or "Unbekannt")) + TriggerEvent('tdm:playerHit') TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, damagerPlayer) end @@ -616,6 +646,8 @@ CreateThread(function() local ped = PlayerPedId() if IsEntityDead(ped) then + debugPrint("Spieler ist tot!") + TriggerServerEvent('tdm:playerDied', currentGameId) lib.notify({ @@ -678,6 +710,8 @@ CreateThread(function() }, distance = 2.5 }) + + debugPrint("NPC und Blip für Feld " .. fieldId .. " erstellt") else print("^3[TDM WARNING]^7 Feld " .. fieldId .. " hat keine vollständige Lobby-Konfiguration!") end @@ -725,6 +759,10 @@ RegisterCommand('debugtdm', function() print("currentField: " .. tostring(currentField)) print("currentLobbyField: " .. tostring(currentLobbyField)) print("currentTeam: " .. tostring(currentTeam)) + print("currentGameId: " .. tostring(currentGameId)) + print("isHit: " .. tostring(isHit)) + print("Hits: " .. playerStats.hits) + print("Deaths: " .. playerStats.deaths) print("^2[TDM DEBUG]^7 Verfügbare Felder:") for fieldId, fieldData in pairs(Config.gameFields) do @@ -786,15 +824,18 @@ RegisterCommand('forcetdmrespawn', function() local randomSpawn = spawnPoints[math.random(#spawnPoints)] DoScreenFadeOut(500) - Wait(500) + Wait(600) - ClearPedTasks(ped) + ClearPedTasksImmediately(ped) SetEntityCoords(ped, randomSpawn.x, randomSpawn.y, randomSpawn.z) isHit = false Wait(100) DoScreenFadeIn(500) + lib.notify({ + title = 'Debug', + description = 'Manueller Respawn durchgeführt lib.notify({ title = 'Debug', description = 'Manueller Respawn durchgeführt!', @@ -808,4 +849,64 @@ RegisterCommand('forcetdmrespawn', function() }) end end, false) - + +-- Debug-Funktion für Stats +RegisterCommand('showstats', function() + if inTDM then + print("^2[TDM DEBUG]^7 Lokale Stats:") + print("Hits: " .. playerStats.hits) + print("Deaths: " .. playerStats.deaths) + + if currentGameId then + TriggerServerEvent('tdm:debugPlayerStats', currentGameId) + end + + lib.notify({ + title = 'Debug', + description = 'Lokale Stats - Hits: ' .. playerStats.hits .. ', Deaths: ' .. playerStats.deaths, + type = 'info' + }) + else + lib.notify({ + title = 'Debug', + description = 'Du bist nicht in einem TDM-Spiel!', + type = 'error' + }) + end +end, false) + +-- Debug-Funktion für manuellen Hit +RegisterCommand('testhit', function() + if inTDM then + TriggerEvent('tdm:playerHit') + lib.notify({ + title = 'Debug', + description = 'Test-Hit ausgelöst!', + type = 'info' + }) + else + lib.notify({ + title = 'Debug', + description = 'Du bist nicht in einem TDM-Spiel!', + type = 'error' + }) + end +end, false) + +-- Debug-Funktion für manuellen Treffer +RegisterCommand('testtreff', function() + if inTDM then + TriggerEvent('tdm:hitRegistered') + lib.notify({ + title = 'Debug', + description = 'Test-Treffer registriert!', + type = 'info' + }) + else + lib.notify({ + title = 'Debug', + description = 'Du bist nicht in einem TDM-Spiel!', + type = 'error' + }) + end +end, false) diff --git a/resources/[standalone]/nordi_tdm/server.lua b/resources/[standalone]/nordi_tdm/server.lua index 26d71216a..e404ab179 100644 --- a/resources/[standalone]/nordi_tdm/server.lua +++ b/resources/[standalone]/nordi_tdm/server.lua @@ -4,6 +4,11 @@ local QBCore = exports['qb-core']:GetCoreObject() local activeGames = {} local gameIdCounter = 1 +-- Debug-Funktion für Konsole +local function debugPrint(message) + print("^2[TDM SERVER]^7 " .. message) +end + -- Events RegisterNetEvent('tdm:createGame', function(gameName, fieldId, gameType, password) local src = source @@ -45,6 +50,7 @@ RegisterNetEvent('tdm:createGame', function(gameName, fieldId, gameType, passwor TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. typeText .. ' Spiel "' .. gameName .. '" wurde erstellt!', 'success') updateGamesListForAll() + debugPrint("Spiel erstellt: " .. gameId .. " von " .. Player.PlayerData.name) end) RegisterNetEvent('tdm:requestGamesList', function() @@ -136,7 +142,10 @@ end) RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, attackerId) local victim = source - if not activeGames[gameId] then return end + if not activeGames[gameId] then + debugPrint("Hit registriert, aber Spiel " .. gameId .. " existiert nicht!") + return + end local game = activeGames[gameId] @@ -159,6 +168,9 @@ RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, attackerId) if attackerId then game.playerStats[attackerId].hits = (game.playerStats[attackerId].hits or 0) + 1 TriggerClientEvent('tdm:hitRegistered', attackerId) + debugPrint("Treffer von " .. attackerId .. " gegen " .. victim) + else + debugPrint("Treffer gegen " .. victim .. " von unbekanntem Angreifer") end -- Team Score erhöhen @@ -193,6 +205,18 @@ RegisterNetEvent('tdm:requestScoreUpdate', function(gameId) end end) +RegisterNetEvent('tdm:debugPlayerStats', function(gameId) + local src = source + if activeGames[gameId] and activeGames[gameId].playerStats and activeGames[gameId].playerStats[src] then + local stats = activeGames[gameId].playerStats[src] + TriggerClientEvent('QBCore:Notify', src, 'Server Stats - Hits: ' .. (stats.hits or 0) .. ', Deaths: ' .. (stats.deaths or 0), 'info') + debugPrint("Stats für Spieler " .. src .. ": Hits=" .. (stats.hits or 0) .. ", Deaths=" .. (stats.deaths or 0)) + else + TriggerClientEvent('QBCore:Notify', src, 'Keine Stats gefunden!', 'error') + debugPrint("Keine Stats für Spieler " .. src .. " in Spiel " .. gameId) + end +end) + -- Funktionen function joinPlayerToGame(playerId, gameId) local game = activeGames[gameId] @@ -222,6 +246,8 @@ function joinPlayerToGame(playerId, gameId) TriggerClientEvent('tdm:joinGame', playerId, gameId, team, game.fieldId) updateScoreForGame(gameId) updateGamesListForAll() + + debugPrint("Spieler " .. playerId .. " ist Spiel " .. gameId .. " beigetreten (Team: " .. team .. ")") end function removePlayerFromGame(playerId, gameId) @@ -232,6 +258,7 @@ function removePlayerFromGame(playerId, gameId) for i, id in ipairs(game.team1) do if id == playerId then table.remove(game.team1, i) + debugPrint("Spieler " .. playerId .. " aus Team 1 entfernt") break end end @@ -239,6 +266,7 @@ function removePlayerFromGame(playerId, gameId) for i, id in ipairs(game.team2) do if id == playerId then table.remove(game.team2, i) + debugPrint("Spieler " .. playerId .. " aus Team 2 entfernt") break end end @@ -279,7 +307,9 @@ function endGame(gameId, winnerTeam, reason) end) if reason then - print('[TDM] Spiel ' .. gameId .. ' beendet: ' .. reason) + debugPrint("Spiel " .. gameId .. " beendet: " .. reason) + else + debugPrint("Spiel " .. gameId .. " beendet. Gewinner: " .. (winnerTeam or "Unentschieden")) end end @@ -291,9 +321,16 @@ function startGameTimer(gameId) local maxTime = game.maxTime local startTime = os.time() + debugPrint("Timer für Spiel " .. gameId .. " gestartet. Maximale Zeit: " .. maxTime .. " Sekunden") + while game and game.status == 'active' and (os.time() - startTime) < maxTime do Wait(1000) game = activeGames[gameId] -- Refresh game data + + -- Alle 30 Sekunden Debug-Info + if (os.time() - startTime) % 30 == 0 then + debugPrint("Spiel " .. gameId .. " läuft seit " .. (os.time() - startTime) .. " Sekunden") + end end -- Zeit abgelaufen @@ -316,6 +353,7 @@ function checkGameEnd(gameId) elseif totalPlayers == 0 then activeGames[gameId] = nil updateGamesListForAll() + debugPrint("Spiel " .. gameId .. " gelöscht (keine Spieler)") end end @@ -323,6 +361,8 @@ function updateScoreForGame(gameId) local game = activeGames[gameId] if not game then return end + debugPrint("Score Update für Spiel " .. gameId .. ": Team1=" .. game.score.team1 .. ", Team2=" .. game.score.team2) + for _, playerId in ipairs(game.team1) do local playerStats = game.playerStats[playerId] or {hits = 0, deaths = 0} TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, { @@ -354,6 +394,8 @@ AddEventHandler('playerDropped', function() for gameId, game in pairs(activeGames) do removePlayerFromGame(src, gameId) end + + debugPrint("Spieler " .. src .. " hat den Server verlassen - aus allen Spielen entfernt") end) -- Server Start - Games Liste leeren @@ -361,7 +403,7 @@ AddEventHandler('onResourceStart', function(resourceName) if GetCurrentResourceName() == resourceName then activeGames = {} gameIdCounter = 1 - print('[TDM] TeamDeathmatch System gestartet!') + debugPrint("TeamDeathmatch System gestartet!") end end) @@ -383,6 +425,6 @@ AddEventHandler('onResourceStop', function(resourceName) end activeGames = {} - print('[TDM] TeamDeathmatch System gestoppt!') + debugPrint("TeamDeathmatch System gestoppt!") end end)