1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-27 02:52:57 +02:00
parent bc2a683f6f
commit efaef09a83
2 changed files with 152 additions and 333 deletions

View file

@ -22,6 +22,16 @@ 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
-- Funktion zum Prüfen, ob der Spieler im Ragdoll-Zustand ist
function isPedInRagdoll(ped)
return IsPedRagdoll(ped) or IsPedFalling(ped) or IsPedDiving(ped)
end
-- Events
RegisterNetEvent('tdm:updateGamesList', function(games)
activeGames = games
@ -169,12 +179,15 @@ RegisterNetEvent('tdm:playerHit', function()
-- Benachrichtigung
lib.notify({
title = 'TeamDeathmatch',
description = 'Du wurdest getroffen! Respawn in 3 Sekunden...',
description = 'Du wurdest getroffen! Respawn in ' .. (Config.respawnDelay / 1000) .. ' Sekunden...',
type = 'error'
})
-- Verbesserte Respawn-Logik
SetTimeout(3000, function()
-- Optional: Ragdoll aktivieren
SetPedToRagdoll(ped, 2000, 2000, 0, true, true, false)
-- Verbesserte Respawn-Logik mit automatischem Teleport
SetTimeout(Config.respawnDelay, function()
if not inTDM then
debugPrint("Respawn abgebrochen - nicht mehr im TDM")
return
@ -209,7 +222,7 @@ RegisterNetEvent('tdm:playerHit', function()
-- Alle Animationen stoppen
ClearPedTasksImmediately(ped)
-- Teleport
-- Teleport direkt zum Spawn-Punkt
SetEntityCoords(ped, randomSpawn.x, randomSpawn.y, randomSpawn.z)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
@ -621,7 +634,7 @@ CreateThread(function()
end
end)
-- Verbesserte Damage Handler für korrekte Treffer-Registrierung
-- Verbesserte Damage Handler für Airsoft-Waffen
CreateThread(function()
while true do
if inTDM and not isHit then
@ -629,38 +642,52 @@ CreateThread(function()
-- Prüfe, ob der Spieler Schaden genommen hat
if HasEntityBeenDamagedByAnyPed(ped) then
debugPrint("Schaden erkannt - Identifiziere Angreifer")
debugPrint("Schaden erkannt - Identifiziere Angreifer und Waffe")
local damager = nil
local damagerPlayer = nil
local weaponHash = 0
-- Versuche den Angreifer zu identifizieren
-- Versuche den Angreifer und die Waffe zu identifizieren
for _, player in ipairs(GetActivePlayers()) do
local playerPed = GetPlayerPed(player)
if HasPedBeenDamagedBy(ped, playerPed) then
damager = playerPed
damagerPlayer = GetPlayerServerId(player)
debugPrint("Angreifer identifiziert: " .. damagerPlayer)
-- Versuche die Waffe zu ermitteln
weaponHash = GetSelectedPedWeapon(playerPed)
debugPrint("Angreifer identifiziert: " .. damagerPlayer .. " mit Waffe: " .. weaponHash)
break
end
end
-- Schaden zurücksetzen
ClearEntityLastDamageEntity(ped)
ClearPedLastWeaponDamage(ped)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
debugPrint("Getroffen von: " .. (damagerPlayer or "Unbekannt"))
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, damagerPlayer)
-- Warten um mehrfache Auslösung zu verhindern
Wait(500)
-- Prüfe, ob es eine Airsoft-Waffe ist oder alle Waffen als Airsoft behandelt werden
if isAirsoftWeapon(weaponHash) then
debugPrint("Airsoft-Treffer erkannt mit Waffe: " .. weaponHash)
-- Schaden zurücksetzen
ClearEntityLastDamageEntity(ped)
ClearPedLastWeaponDamage(ped)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
debugPrint("Getroffen von: " .. (damagerPlayer or "Unbekannt"))
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, damagerPlayer)
-- Warten um mehrfache Auslösung zu verhindern
Wait(500)
else
debugPrint("Keine Airsoft-Waffe erkannt: " .. weaponHash)
-- Schaden trotzdem zurücksetzen
ClearEntityLastDamageEntity(ped)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
end
end
Wait(0)
else
@ -676,6 +703,7 @@ AddEventHandler('gameEventTriggered', function(name, args)
local attackerId = args[2]
local isDead = args[4] == 1
local weaponHash = args[5]
local isMelee = args[10] == 1
if inTDM and not isHit and victimId == PlayerPedId() then
local attackerServerId = nil
@ -690,7 +718,8 @@ AddEventHandler('gameEventTriggered', function(name, args)
debugPrint("Schaden-Event erkannt: Angreifer=" .. (attackerServerId or "NPC/Unbekannt") .. ", Waffe=" .. weaponHash)
if attackerServerId then
-- Prüfe, ob es eine Airsoft-Waffe ist oder alle Waffen als Airsoft behandelt werden
if isAirsoftWeapon(weaponHash) and attackerServerId then
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
@ -705,328 +734,91 @@ AddEventHandler('gameEventTriggered', function(name, args)
end
end)
-- Death Handler
-- Direkter Waffen-Schaden Monitor für zusätzliche Zuverlässigkeit
CreateThread(function()
while true do
Wait(1000)
if inTDM then
Wait(0)
if inTDM and not isHit then
local ped = PlayerPedId()
if IsEntityDead(ped) then
debugPrint("Spieler ist tot!")
-- Prüfe auf Projektil-Treffer
if HasEntityBeenDamagedByWeapon(ped, 0, 2) then -- 2 = Projektilwaffen
debugPrint("Projektil-Treffer erkannt")
TriggerServerEvent('tdm:playerDied', currentGameId)
-- Schaden zurücksetzen
ClearEntityLastDamageEntity(ped)
ClearPedLastWeaponDamage(ped)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
lib.notify({
title = 'TeamDeathmatch',
description = 'Du bist ausgeschieden!',
type = 'error'
})
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
Wait(3000)
TriggerServerEvent('tdm:leaveGame')
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam)
-- Warten um mehrfache Auslösung zu verhindern
Wait(500)
end
end
end
end)
-- NPC Setup für alle Felder
CreateThread(function()
-- Für jedes Spielfeld Blip und NPC erstellen
for fieldId, fieldData in pairs(Config.gameFields) do
if fieldData.lobby and fieldData.lobby.pos and fieldData.lobby.npc then
local lobbyPos = fieldData.lobby.pos
local npcData = fieldData.lobby.npc
-- Blip erstellen
local blip = AddBlipForCoord(lobbyPos.x, lobbyPos.y, lobbyPos.z)
SetBlipSprite(blip, 432)
SetBlipDisplay(blip, 4)
SetBlipScale(blip, 0.8)
SetBlipColour(blip, 1)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString("TDM - " .. fieldData.name)
EndTextCommandSetBlipName(blip)
tdmBlips[fieldId] = blip
-- NPC erstellen
RequestModel(GetHashKey(npcData.model))
while not HasModelLoaded(GetHashKey(npcData.model)) do
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)
FreezeEntityPosition(npc, true)
SetBlockingOfNonTemporaryEvents(npc, true)
spawnedNPCs[fieldId] = npc
-- Target für diesen NPC
exports['qb-target']:AddTargetEntity(npc, {
options = {
{
type = "client",
event = "tdm:openFieldMenu",
icon = "fas fa-crosshairs",
label = "TeamDeathmatch - " .. fieldData.name,
fieldId = fieldId
},
},
distance = 2.5
})
debugPrint("NPC und Blip für Feld " .. fieldId .. " erstellt")
else
debugPrint("WARNUNG: Feld " .. fieldId .. " hat keine vollständige Lobby-Konfiguration!")
Wait(500)
end
end
end)
-- Event für Feld-spezifisches Menü
RegisterNetEvent('tdm:openFieldMenu', function(data)
if data and data.fieldId then
openMainMenu(data.fieldId)
else
lib.notify({
title = 'Fehler',
description = 'Keine Feld-ID übertragen!',
type = 'error'
})
end
end)
-- Chat Command zum Spiel verlassen
RegisterCommand('leavetdm', function()
if inTDM then
TriggerServerEvent('tdm:leaveGame')
lib.notify({
title = 'TeamDeathmatch',
description = 'Du hast das Spiel über Command verlassen!',
type = 'info'
})
else
lib.notify({
title = 'TeamDeathmatch',
description = 'Du bist in keinem Spiel!',
type = 'error'
})
end
end, false)
-- Keybind zum Spiel verlassen
RegisterKeyMapping('leavetdm', 'TeamDeathmatch verlassen', 'keyboard', 'F7')
-- Debug Command zum Testen der Config
RegisterCommand('debugtdm', function()
debugPrint("Aktuelle Werte:")
debugPrint("inTDM: " .. tostring(inTDM))
debugPrint("currentField: " .. tostring(currentField))
debugPrint("currentLobbyField: " .. tostring(currentLobbyField))
debugPrint("currentTeam: " .. tostring(currentTeam))
debugPrint("currentGameId: " .. tostring(currentGameId))
debugPrint("isHit: " .. tostring(isHit))
debugPrint("Hits: " .. playerStats.hits)
debugPrint("Deaths: " .. playerStats.deaths)
-- Ragdoll-Erkennung Thread
CreateThread(function()
local lastDamager = nil
local lastDamageTime = 0
debugPrint("Verfügbare Felder:")
for fieldId, fieldData in pairs(Config.gameFields) do
local hasLobby = fieldData.lobby and fieldData.lobby.pos and "" or ""
debugPrint("- " .. 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)
-- Debug-Funktion für Respawn
RegisterCommand('forcetdmrespawn', function()
if inTDM and currentTeam and currentField then
local ped = PlayerPedId()
local fieldConfig = Config.gameFields[currentField]
local spawnPoints = fieldConfig.teamSpawns[currentTeam]
local randomSpawn = spawnPoints[math.random(#spawnPoints)]
DoScreenFadeOut(500)
Wait(600)
ClearPedTasksImmediately(ped)
NetworkResurrectLocalPlayer(randomSpawn.x, randomSpawn.y, randomSpawn.z, 0.0, true, false)
SetEntityCoords(ped, randomSpawn.x, randomSpawn.y, randomSpawn.z)
SetEntityHealth(ped, GetEntityMaxHealth(ped))
isHit = false
while true do
Wait(100)
DoScreenFadeIn(500)
lib.notify({
title = 'Debug',
description = 'Manueller Respawn durchgeführt!',
type = 'success'
})
else
lib.notify({
title = 'Debug',
description = 'Du bist nicht in einem TDM-Spiel!',
type = 'error'
})
end
end, false)
-- Debug-Funktion für Stats
RegisterCommand('showstats', function()
if inTDM then
debugPrint("Lokale Stats:")
debugPrint("Hits: " .. playerStats.hits)
debugPrint("Deaths: " .. playerStats.deaths)
if currentGameId then
TriggerServerEvent('tdm:debugPlayerStats', currentGameId)
if inTDM and not isHit then
local ped = PlayerPedId()
-- Speichere den letzten Angreifer, wenn Schaden genommen wurde
if HasEntityBeenDamagedByAnyPed(ped) then
for _, player in ipairs(GetActivePlayers()) do
local playerPed = GetPlayerPed(player)
if HasPedBeenDamagedBy(ped, playerPed) then
lastDamager = GetPlayerServerId(player)
lastDamageTime = GetGameTimer()
debugPrint("Letzter Angreifer gespeichert: " .. lastDamager)
break
end
end
ClearEntityLastDamageEntity(ped)
end
-- Prüfe, ob der Spieler im Ragdoll-Zustand ist
if isPedInRagdoll(ped) then
debugPrint("Ragdoll-Zustand erkannt - Zählt als Tod")
-- Lokale Stats sofort updaten
playerStats.deaths = playerStats.deaths + 1
-- Bestimme den Angreifer (verwende den letzten Angreifer, wenn innerhalb von 3 Sekunden)
local attacker = nil
if lastDamager and (GetGameTimer() - lastDamageTime) < 3000 then
attacker = lastDamager
debugPrint("Ragdoll-Tod zugeordnet an Angreifer: " .. attacker)
else
debugPrint("Kein Angreifer für Ragdoll-Tod gefunden")
end
-- Treffer-Events auslösen
TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, attacker)
-- Zurücksetzen des letzten Angreifers
lastDamager = nil
-- Warten um mehrfache Auslösung zu verhindern
Wait(500)
end
else
Wait(500)
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)
-- Debug-Befehl zum Testen der Treffer-Registrierung
RegisterCommand('testtreffer', function()
if inTDM and currentGameId and currentTeam then
debugPrint("Teste Treffer-Registrierung")
-- Simuliere einen Treffer gegen sich selbst
local targetTeam = currentTeam == 'team1' and 'team2' or 'team1'
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, GetPlayerServerId(PlayerId()))
lib.notify({
title = 'Debug',
description = 'Test-Treffer gesendet!',
type = 'info'
})
else
lib.notify({
title = 'Debug',
description = 'Du musst in einem TDM-Spiel sein!',
type = 'error'
})
end
end, false)
-- Debug-Befehl zum Testen des Respawns
RegisterCommand('testrespawn', function()
if inTDM then
debugPrint("Teste Respawn-Funktion")
TriggerEvent('tdm:playerHit')
lib.notify({
title = 'Debug',
description = 'Test-Respawn ausgelöst!',
type = 'info'
})
else
lib.notify({
title = 'Debug',
description = 'Du musst in einem TDM-Spiel sein!',
type = 'error'
})
end
end, false)
-- Hilfsfunktion für table.count
table.count = function(tbl)
local count = 0
for _, _ in pairs(tbl) do
count = count + 1
end
return count
end
end)

View file

@ -156,6 +156,33 @@ Config.teamMasks = {
-- Game Settings
Config.maxGameTime = 600 -- 10 Minuten
Config.maxHits = 30 -- Spiel endet bei 30 Treffern
Config.respawnDelay = 3000 -- 3 Sekunden Respawn-Verzögerung
-- Airsoft-Einstellungen
Config.treatAllWeaponsAsAirsoft = true -- Alle Waffen als Airsoft behandeln
Config.airsoftDamageMultiplier = 0.1 -- Reduzierter Schaden für Airsoft-Waffen
-- Airsoft-Waffen (Hash-Werte)
Config.airsoftWeapons = {
-- Pistolen
[`WEAPON_AIRSOFTGLOCK20`] = true,
-- SMGs
[`WEAPON_AIRSFOTMIRCOUZI`] = true,
[`WEAPON_AIRSOFTMP5`] = true,
-- Gewehre
[`WEAPON_AIRSOFTM4`] = true,
[`WEAPON_AIRSOFTAK47`] = true,
[`WEAPON_AIRSOFTM249`] = true,
[`WEAPON_AIRSOFTG46C`] = true,
[`WEAPON_AIRSOFTR870`] = true,
-- Scharfschützengewehre
[`WEAPON_AIRSOFTR700`] = true,
}
-- Debug Settings
Config.debugMode = true -- Set to false in production
Config.debugMode = true -- Auf false setzen für Produktion