1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-28 00:09:15 +02:00
parent 4485cc31df
commit 3afa513b4a
22 changed files with 1331 additions and 575 deletions

View file

@ -25,19 +25,6 @@ local function debugPrint(message)
print("^2[TDM DEBUG]^7 " .. message)
end
-- Funktion zum Prüfen, ob eine Waffe eine Airsoft-Waffe ist
function isAirsoftWeapon(weaponHash)
return Config.airsoftWeapons[weaponHash] or Config.treatAllWeaponsAsAirsoft
end
-- Enhanced function to check if a player is in ragdoll state
function isPedInRagdoll(ped)
return IsPedRagdoll(ped) or
IsPedFalling(ped) or
IsPedDiving(ped) or
(not IsPedStill(ped) and IsPedOnFoot(ped) and not IsPedWalking(ped) and not IsPedRunning(ped) and not IsPedSprinting(ped))
end
-- Helper function to dump tables for debugging
function dumpTable(table, indent)
if not indent then indent = 0 end
@ -52,6 +39,19 @@ function dumpTable(table, indent)
end
end
-- Funktion zum Prüfen, ob eine Waffe eine Airsoft-Waffe ist
function isAirsoftWeapon(weaponHash)
return Config.airsoftWeapons[weaponHash] or Config.treatAllWeaponsAsAirsoft
end
-- Enhanced function to check if a player is in ragdoll state
function isPedInRagdoll(ped)
return IsPedRagdoll(ped) or
IsPedFalling(ped) or
IsPedDiving(ped) or
(not IsPedStill(ped) and IsPedOnFoot(ped) and not IsPedWalking(ped) and not IsPedRunning(ped) and not IsPedSprinting(ped))
end
-- Events
RegisterNetEvent('tdm:updateGamesList', function(games)
activeGames = games
@ -791,570 +791,189 @@ CreateThread(function()
if inTDM and not isHit then
local ped = PlayerPedId()
-- Prüfe, ob der Spieler im Ragdoll-Zustand ist
if
-- Prüfe, ob der Spieler im Ragdoll-Zustand ist
if isPedInRagdoll(ped) then
-- Bestimme den Angreifer (verwende den letzten Angreifer, wenn innerhalb von 3 Sekunden)
local attacker = nil
if lastDamager and (GetGameTimer() -
local QBCore = exports['qb-core']:GetCoreObject()
-- Game Management
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
local Player = QBCore.Functions.GetPlayer(src)
if not Player then
debugPrint("Spielerstellung fehlgeschlagen - Spieler nicht gefunden: " .. src)
return
end
-- Prüfen ob Spielfeld bereits belegt
for gameId, gameData in pairs(activeGames) do
if gameData.fieldId == fieldId then
debugPrint("Spielerstellung abgelehnt - Feld bereits belegt: " .. fieldId)
TriggerClientEvent('QBCore:Notify', src, 'Dieses Spielfeld ist bereits belegt!', 'error')
return
end
end
local gameId = 'game_' .. gameIdCounter
gameIdCounter = gameIdCounter + 1
activeGames[gameId] = {
id = gameId,
name = gameName,
fieldId = fieldId,
admin = src,
adminName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
gameType = gameType,
password = password,
hasPassword = password ~= nil,
status = 'waiting',
team1 = {},
team2 = {},
score = {team1 = 0, team2 = 0},
startTime = nil,
maxTime = Config.maxGameTime,
maxHits = Config.maxHits,
playerStats = {} -- Spieler-Statistiken initialisieren
}
local typeText = gameType == 'public' and 'öffentliches' or 'privates'
TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. typeText .. ' Spiel "' .. gameName .. '" wurde erstellt!', 'success')
updateGamesListForAll()
debugPrint("Spiel erstellt: " .. gameId .. " von " .. Player.PlayerData.name .. " (Feld: " .. fieldId .. ")")
end)
RegisterNetEvent('tdm:requestGamesList', function()
local src = source
debugPrint("Spiele-Liste angefordert von: " .. src)
TriggerClientEvent('tdm:updateGamesList', src, activeGames)
end)
RegisterNetEvent('tdm:requestJoinGame', function(gameId, password)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player or not activeGames[gameId] then
debugPrint("Spielbeitritt fehlgeschlagen - Spieler oder Spiel nicht gefunden: " .. src .. ", " .. gameId)
return
end
local game = activeGames[gameId]
local playerName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
debugPrint("Beitrittsanfrage von " .. playerName .. " (ID: " .. src .. ") für Spiel " .. gameId)
-- Passwort prüfen falls vorhanden
if game.hasPassword and game.password ~= password then
debugPrint("Beitritt abgelehnt - Falsches Passwort")
TriggerClientEvent('QBCore:Notify', src, 'Falsches Passwort!', 'error')
return
end
-- Spieler bereits im Spiel?
for _, playerId in ipairs(game.team1) do
if playerId == src then
debugPrint("Beitritt abgelehnt - Spieler bereits in Team 1")
TriggerClientEvent('QBCore:Notify', src, 'Du bist bereits in diesem Spiel!', 'error')
return
end
end
for _, playerId in ipairs(game.team2) do
if playerId == src then
debugPrint("Beitritt abgelehnt - Spieler bereits in Team 2")
TriggerClientEvent('QBCore:Notify', src, 'Du bist bereits in diesem Spiel!', 'error')
return
end
end
-- Max Spieler erreicht?
local currentPlayers = #game.team1 + #game.team2
local maxPlayers = Config.gameFields[game.fieldId].maxPlayers
if currentPlayers >= maxPlayers then
debugPrint("Beitritt abgelehnt - Spiel ist voll")
TriggerClientEvent('QBCore:Notify', src, 'Spiel ist voll!', 'error')
return
end
-- Prüfen ob Admin online ist (für private Spiele)
if game.gameType == 'private' then
local AdminPlayer = QBCore.Functions.GetPlayer(game.admin)
if not AdminPlayer then
debugPrint("Beitritt abgelehnt - Admin nicht online")
TriggerClientEvent('QBCore:Notify', src, 'Der Spiel-Admin ist nicht online!', 'error')
return
end
end
-- Join Logic basierend auf Spiel Typ
if game.gameType == 'public' then
debugPrint("Öffentliches Spiel - Direkter Beitritt")
joinPlayerToGame(src, gameId)
TriggerClientEvent('QBCore:Notify', src, 'Du bist dem öffentlichen Spiel beigetreten!', 'success')
else
debugPrint("Privates Spiel - Sende Anfrage an Admin")
TriggerClientEvent('tdm:joinRequest', game.admin, gameId, playerName, src)
TriggerClientEvent('QBCore:Notify', src, 'Join-Anfrage gesendet an ' .. game.adminName, 'info')
end
end)
RegisterNetEvent('tdm:approveJoinRequest', function(gameId, playerId, approved)
local src = source
local game = activeGames[gameId]
if not game or game.admin ~= src then
debugPrint("Join-Anfrage Bearbeitung fehlgeschlagen - Ungültiges Spiel oder nicht Admin")
return
end
if approved then
debugPrint("Join-Anfrage genehmigt für Spieler " .. playerId .. " in Spiel " .. gameId)
joinPlayerToGame(playerId, gameId)
TriggerClientEvent('tdm:joinRequestResult', playerId, true, game.name)
else
debugPrint("Join-Anfrage abgelehnt für Spieler " .. playerId .. " in Spiel " .. gameId)
TriggerClientEvent('tdm:joinRequestResult', playerId, false, game.name)
end
end)
RegisterNetEvent('tdm:leaveGame', function()
local src = source
debugPrint("Spieler " .. src .. " möchte alle Spiele verlassen")
for gameId, game in pairs(activeGames) do
removePlayerFromGame(src, gameId)
end
TriggerClientEvent('tdm:leaveGame', src)
end)
RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, attackerId)
local victim = source
if not activeGames[gameId] then
debugPrint("Hit registriert, aber Spiel " .. gameId .. " existiert nicht!")
return
end
local game = activeGames[gameId]
debugPrint("Hit registriert - Opfer: " .. victim .. " (Team: " .. victimTeam .. "), Angreifer: " .. (attackerId or "Unbekannt"))
-- Spieler Stats initialisieren falls nicht vorhanden
if not game.playerStats then
game.playerStats = {}
end
if not game.playerStats[victim] then
game.playerStats[victim] = {hits = 0, deaths = 0}
end
-- Wichtig: Nur wenn ein Angreifer identifiziert wurde, zähle den Kill
if attackerId then
if not game.playerStats[attackerId] then
game.playerStats[attackerId] = {hits = 0, deaths = 0}
end
-- Stats updaten
game.playerStats[victim].deaths = (game.playerStats[victim].deaths or 0) + 1
game.playerStats[attackerId].hits = (game.playerStats[attackerId].hits or 0) + 1
-- Benachrichtigung an den Angreifer senden
TriggerClientEvent('tdm:hitRegistered', attackerId)
debugPrint("Treffer von " .. attackerId .. " gegen " .. victim .. " registriert")
-- Team Score erhöhen
if victimTeam == 'team1' then
game.score.team2 = game.score.team2 + 1
debugPrint("Punkt für Team 2 - Neuer Score: " .. game.score.team2)
if lastDamager and (GetGameTimer() - lastDamageTime) < 3000 then
attacker = lastDamager
-- Prüfe ob die Waffe eine Airsoft-Waffe ist
if isAirsoftWeapon(lastDamageWeapon) then
debugPrint("Ragdoll durch Airsoft-Waffe - Zählt als Tod durch: " .. attacker)
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, attacker)
-- Zurücksetzen des letzten Angreifers
lastDamager = nil
lastDamageWeapon = 0
-- Warten um mehrfache Auslösung zu verhindern
Wait(1000)
end
end
end
else
game.score.team1 = game.score.team1 + 1
debugPrint("Punkt für Team 1 - Neuer Score: " .. game.score.team1)
end
else
debugPrint("Treffer gegen " .. victim .. " von unbekanntem Angreifer registriert - Kein Punkt vergeben")
end
TriggerClientEvent('tdm:deathRegistered', victim)
-- Score an alle Spieler senden
updateScoreForGame(gameId)
-- Spiel beenden prüfen
if game.score.team1 >= game.maxHits or game.score.team2 >= game.maxHits then
local winnerTeam = game.score.team1 >= game.maxHits and 'team1' or 'team2'
debugPrint("Max Punkte erreicht - Beende Spiel. Gewinner: " .. winnerTeam)
endGame(gameId, winnerTeam)
end
end)
RegisterNetEvent('tdm:playerDied', function(gameId)
local src = source
debugPrint("Spieler " .. src .. " ist gestorben in Spiel " .. gameId)
removePlayerFromGame(src, gameId)
end)
RegisterNetEvent('tdm:requestScoreUpdate', function(gameId)
local src = source
if activeGames[gameId] then
debugPrint("Score-Update angefordert von " .. src .. " für Spiel " .. gameId)
updateScoreForGame(gameId)
else
debugPrint("Score-Update fehlgeschlagen - Spiel " .. gameId .. " nicht gefunden")
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]
debugPrint("Stats für Spieler " .. src .. ": Hits=" .. (stats.hits or 0) .. ", Deaths=" .. (stats.deaths or 0))
TriggerClientEvent('QBCore:Notify', src, 'Server Stats - Hits: ' .. (stats.hits or 0) .. ', Deaths: ' .. (stats.deaths or 0), 'info')
else
debugPrint("Keine Stats gefunden für Spieler " .. src .. " in Spiel " .. gameId)
TriggerClientEvent('QBCore:Notify', src, 'Keine Stats gefunden!', 'error')
end
end)
-- Funktionen
function joinPlayerToGame(playerId, gameId)
local game = activeGames[gameId]
if not game then
debugPrint("Spielbeitritt fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
return
end
-- Team mit weniger Spielern wählen
local team = #game.team1 <= #game.team2 and 'team1' or 'team2'
table.insert(game[team], playerId)
-- Spieler-Stats initialisieren
if not game.playerStats then
game.playerStats = {}
end
game.playerStats[playerId] = {hits = 0, deaths = 0}
-- Spiel starten wenn mindestens 2 Spieler
if #game.team1 + #game.team2 >= 2 and game.status == 'waiting' then
game.status = 'active'
game.startTime = os.time()
debugPrint("Spiel " .. gameId .. " gestartet - Mindestens 2 Spieler erreicht")
-- Game Timer starten
startGameTimer(gameId)
end
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)
local game = activeGames[gameId]
if not game then return end
-- Spieler aus Teams entfernen
local removed = false
for i, id in ipairs(game.team1) do
if id == playerId then
table.remove(game.team1, i)
debugPrint("Spieler " .. playerId .. " aus Team 1 entfernt")
removed = true
break
Wait(500)
end
end
if not removed then
for i, id in ipairs(game.team2) do
if id == playerId then
table.remove(game.team2, i)
debugPrint("Spieler " .. playerId .. " aus Team 2 entfernt")
removed = true
break
end
end
end
if not removed then
debugPrint("Spieler " .. playerId .. " nicht in Spiel " .. gameId .. " gefunden")
return
end
-- Wenn Admin das Spiel verlässt, Spiel beenden
if game.admin == playerId then
debugPrint("Admin hat das Spiel verlassen - Beende Spiel " .. gameId)
endGame(gameId, nil, 'Admin hat das Spiel verlassen')
return
end
checkGameEnd(gameId)
updateGamesListForAll()
end
end)
function endGame(gameId, winnerTeam, reason)
local game = activeGames[gameId]
if not game then
debugPrint("Spielende fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
return
end
game.status = 'finished'
local allPlayers = {}
for _, playerId in ipairs(game.team1) do
table.insert(allPlayers, playerId)
end
for _, playerId in ipairs(game.team2) do
table.insert(allPlayers, playerId)
end
-- Game End Event an alle Spieler
for _, playerId in ipairs(allPlayers) do
debugPrint("Sende Spielende-Event an Spieler " .. playerId)
TriggerClientEvent('tdm:gameEnded', playerId, winnerTeam, game.score.team1, game.score.team2)
end
-- Spiel nach 10 Sekunden löschen
SetTimeout(10000, function()
activeGames[gameId] = nil
updateGamesListForAll()
debugPrint("Spiel " .. gameId .. " aus der Liste entfernt")
end)
if reason then
debugPrint("Spiel " .. gameId .. " beendet: " .. reason)
else
debugPrint("Spiel " .. gameId .. " beendet. Gewinner: " .. (winnerTeam or "Unentschieden"))
end
end
function startGameTimer(gameId)
CreateThread(function()
local game = activeGames[gameId]
if not game then return end
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
-- Direkter Waffen-Schaden Monitor für zusätzliche Zuverlässigkeit
CreateThread(function()
while true do
Wait(0)
if inTDM and not isHit then
local ped = PlayerPedId()
-- Alle 30 Sekunden Debug-Info
if (os.time() - startTime) % 30 == 0 then
debugPrint("Spiel " .. gameId .. " läuft seit " .. (os.time() - startTime) .. " Sekunden")
-- Prüfe auf Projektil-Treffer
if HasEntityBeenDamagedByWeapon(ped, 0, 2) then -- 2 = Projektilwaffen
debugPrint("Projektil-Treffer erkannt")
-- Schaden zurücksetzen
ClearEntityLastDamageEntity(ped)
ClearPedLastWeaponDamage(ped)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, lastDamager)
-- Warten um mehrfache Auslösung zu verhindern
Wait(500)
end
else
Wait(500)
end
-- Zeit abgelaufen
if game and game.status == 'active' then
local winnerTeam = game.score.team1 > game.score.team2 and 'team1' or
game.score.team2 > game.score.team1 and 'team2' or nil
debugPrint("Spielzeit abgelaufen - Beende Spiel " .. gameId)
endGame(gameId, winnerTeam, 'Zeit abgelaufen')
end
end)
end
function checkGameEnd(gameId)
local game = activeGames[gameId]
if not game then return end
local totalPlayers = #game.team1 + #game.team2
if totalPlayers < 2 and game.status == 'active' then
debugPrint("Zu wenig Spieler - Beende Spiel " .. gameId)
endGame(gameId, nil, 'Zu wenig Spieler')
elseif totalPlayers == 0 then
activeGames[gameId] = nil
updateGamesListForAll()
debugPrint("Spiel " .. gameId .. " gelöscht (keine Spieler)")
end
end
function updateScoreForGame(gameId)
local game = activeGames[gameId]
if not game then
debugPrint("Score-Update fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
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, {
hits = playerStats.hits or 0,
deaths = playerStats.deaths or 0
})
end
for _, playerId in ipairs(game.team2) do
local playerStats = game.playerStats[playerId] or {hits = 0, deaths = 0}
TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, {
hits = playerStats.hits or 0,
deaths = playerStats.deaths or 0
})
end
end
function updateGamesListForAll()
local players = QBCore.Functions.GetPlayers()
for _, playerId in pairs(players) do
TriggerClientEvent('tdm:updateGamesList', playerId, activeGames)
end
end
-- Player Disconnect Handler
AddEventHandler('playerDropped', function()
local src = source
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
AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() == resourceName then
activeGames = {}
gameIdCounter = 1
debugPrint("TeamDeathmatch System gestartet!")
end
end)
-- Function to spawn NPCs for all fields
function spawnFieldNPCs()
for fieldId, fieldData in pairs(Config.gameFields) do
if fieldData.lobby and fieldData.lobby.npc then
local npcData = fieldData.lobby.npc
local model = GetHashKey(npcData.model)
-- Request the model
RequestModel(model)
while not HasModelLoaded(model) do
Wait(10)
end
-- Create the NPC
local npc = CreatePed(4, model, npcData.coords.x, npcData.coords.y, npcData.coords.z, npcData.coords.w, false, true)
SetEntityAsMissionEntity(npc, true, true)
SetBlockingOfNonTemporaryEvents(npc, true)
FreezeEntityPosition(npc, true)
SetEntityInvincible(npc, true)
-- Add to spawned NPCs table
table.insert(spawnedNPCs, npc)
-- Add target interaction
exports['qb-target']:AddTargetEntity(npc, {
options = {
{
type = "client",
event = "tdm:openMenu",
icon = "fas fa-gamepad",
label = "TeamDeathmatch Menu",
fieldId = fieldId
}
},
distance = 2.0
})
debugPrint("Spawned NPC for field: " .. fieldId)
end
end
end
-- Register event handler for NPC interaction
RegisterNetEvent('tdm:openMenu', function(data)
if data.fieldId then
openMainMenu(data.fieldId)
end
end)
-- Spawn NPCs when resource starts
CreateThread(function()
Wait(1000) -- Wait for everything to load
spawnFieldNPCs()
end)
-- Function to create blips for all TDM lobbies
function createTDMBlips()
for fieldId, fieldData in pairs(Config.gameFields) do
if fieldData.lobby and fieldData.lobby.pos then
local blip = AddBlipForCoord(fieldData.lobby.pos.x, fieldData.lobby.pos.y, fieldData.lobby.pos.z)
SetBlipSprite(blip, 156) -- You can change this to any appropriate sprite
SetBlipDisplay(blip, 4)
SetBlipScale(blip, 0.8)
SetBlipColour(blip, 3)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString("TDM: " .. fieldData.name)
EndTextCommandSetBlipName(blip)
table.insert(tdmBlips, blip)
debugPrint("Created blip for TDM field: " .. fieldId)
end
end
end
-- Call this function when the resource starts
CreateThread(function()
Wait(2000) -- Wait for everything to load
createTDMBlips()
end)
-- Cleanup function
function cleanupResources()
-- Remove NPCs
for _, npc in ipairs(spawnedNPCs) do
if DoesEntityExist(npc) then
DeleteEntity(npc)
end
end
spawnedNPCs = {}
-- Remove blips
for _, blip in ipairs(tdmBlips) do
if DoesBlipExist(blip) then
RemoveBlip(blip)
end
end
tdmBlips = {}
debugPrint("Cleaned up all NPCs and blips")
end
-- Register cleanup when resource stops
AddEventHandler('onResourceStop', function(resourceName)
if GetCurrentResourceName() == resourceName then
-- Alle Spieler aus TDM entfernen
for gameId, game in pairs(activeGames) do
local allPlayers = {}
for _, playerId in ipairs(game.team1) do
table.insert(allPlayers, playerId)
end
for _, playerId in ipairs(game.team2) do
table.insert(allPlayers, playerId)
end
for _, playerId in ipairs(allPlayers) do
TriggerClientEvent('tdm:leaveGame', playerId)
end
end
activeGames = {}
debugPrint("TeamDeathmatch System gestoppt!")
cleanupResources()
end
end)
-- Admin-Befehle
RegisterCommand('tdmreset', function(source, args)
local src = source
if src > 0 then -- Spieler
local Player = QBCore.Functions.GetPlayer(src)
if not Player or not Player.PlayerData.job or Player.PlayerData.job.name ~= 'admin' then
TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung!', 'error')
return
-- Helper function for table.count
if not table.count then
table.count = function(tbl)
local count = 0
for _, _ in pairs(tbl) do
count = count + 1
end
return count
end
-- Alle Spieler aus TDM entfernen
for gameId, game in pairs(activeGames) do
local allPlayers = {}
for _, playerId in ipairs(game.team1) do
table.insert(allPlayers, playerId)
end
for _, playerId in ipairs(game.team2) do
table.insert(allPlayers, playerId)
end
for _, playerId in ipairs(allPlayers) do
TriggerClientEvent('tdm:leaveGame', playerId)
end
end
activeGames = {}
gameIdCounter = 1
debugPrint("TeamDeathmatch System zurückgesetzt!")
if src > 0 then
TriggerClientEvent('QBCore:Notify', src, 'TDM System zurückgesetzt!', 'success')
end
end, true)
-- Debug-Befehl für Server-Status
RegisterCommand('tdmstatus', function(source, args)
local src = source
if src > 0 then -- Spieler
local Player = QBCore.Functions.GetPlayer(src)
if not Player or not Player.PlayerData.job or Player.PlayerData.job.name ~= 'admin' then
TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung!', 'error')
return
end
end
debugPrint("=== TDM STATUS ===")
debugPrint("Aktive Spiele: " .. table.count(activeGames))
for gameId, game in pairs(activeGames) do
debugPrint("Spiel: " .. gameId .. " - " .. game.name)
debugPrint(" Status: " .. game.status)
debugPrint(" Feld: " .. game.fieldId)
debugPrint(" Team 1: " .. #game.team1 .. " Spieler, Score: " .. game.score.team1)
debugPrint(" Team 2: " .. #game.team2 .. " Spieler, Score: " .. game.score.team2)
end
if src > 0 then
TriggerClientEvent('QBCore:Notify', src, 'TDM Status in Server-Konsole', 'info')
end
end, true)
-- Hilfsfunktion für table.count
table.count = function(tbl)
local count = 0
for _, _ in pairs(tbl) do
count = count + 1
end
return count
end

View file

@ -183,28 +183,30 @@ RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, attackerId)
game.playerStats[victim] = {hits = 0, deaths = 0}
end
if attackerId and not game.playerStats[attackerId] then
game.playerStats[attackerId] = {hits = 0, deaths = 0}
end
-- Stats updaten
game.playerStats[victim].deaths = (game.playerStats[victim].deaths or 0) + 1
-- Wichtig: Nur wenn ein Angreifer identifiziert wurde, zähle den Kill
if attackerId then
if not game.playerStats[attackerId] then
game.playerStats[attackerId] = {hits = 0, deaths = 0}
end
-- Stats updaten
game.playerStats[victim].deaths = (game.playerStats[victim].deaths or 0) + 1
game.playerStats[attackerId].hits = (game.playerStats[attackerId].hits or 0) + 1
-- Benachrichtigung an den Angreifer senden
TriggerClientEvent('tdm:hitRegistered', attackerId)
debugPrint("Treffer von " .. attackerId .. " gegen " .. victim .. " registriert")
-- Team Score erhöhen
if victimTeam == 'team1' then
game.score.team2 = game.score.team2 + 1
debugPrint("Punkt für Team 2 - Neuer Score: " .. game.score.team2)
else
game.score.team1 = game.score.team1 + 1
debugPrint("Punkt für Team 1 - Neuer Score: " .. game.score.team1)
end
else
debugPrint("Treffer gegen " .. victim .. " von unbekanntem Angreifer registriert")
end
-- Team Score erhöhen
if victimTeam == 'team1' then
game.score.team2 = game.score.team2 + 1
debugPrint("Punkt für Team 2 - Neuer Score: " .. game.score.team2)
else
game.score.team1 = game.score.team1 + 1
debugPrint("Punkt für Team 1 - Neuer Score: " .. game.score.team1)
debugPrint("Treffer gegen " .. victim .. " von unbekanntem Angreifer registriert - Kein Punkt vergeben")
end
TriggerClientEvent('tdm:deathRegistered', victim)