1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-26 06:36:06 +02:00
parent eec7910283
commit 7def30a2ec
2 changed files with 216 additions and 109 deletions

View file

@ -8,6 +8,13 @@ local teamZoneBlips = {}
local isHit = false local isHit = false
local activeGames = {} local activeGames = {}
-- Spieler Statistiken
local playerStats = {
hits = 0,
deaths = 0,
gamesPlayed = 0
}
-- Events -- Events
RegisterNetEvent('tdm:updateGamesList', function(games) RegisterNetEvent('tdm:updateGamesList', function(games)
activeGames = games activeGames = games
@ -20,6 +27,11 @@ RegisterNetEvent('tdm:joinGame', function(gameId, team, fieldId)
inTDM = true inTDM = true
isHit = false isHit = false
-- Stats zurücksetzen
playerStats.hits = 0
playerStats.deaths = 0
playerStats.gamesPlayed = playerStats.gamesPlayed + 1
local fieldConfig = Config.gameFields[fieldId] local fieldConfig = Config.gameFields[fieldId]
-- Teleport zu Team Spawn -- Teleport zu Team Spawn
@ -57,6 +69,8 @@ RegisterNetEvent('tdm:leaveGame', function()
-- Zone Blips entfernen -- Zone Blips entfernen
removeTeamZoneBlips() removeTeamZoneBlips()
lib.hideTextUI()
lib.notify({ lib.notify({
title = 'TeamDeathmatch', title = 'TeamDeathmatch',
description = 'Du hast das Spiel verlassen!', description = 'Du hast das Spiel verlassen!',
@ -123,19 +137,64 @@ RegisterNetEvent('tdm:playerHit', function()
highlightTeamZone(currentTeam) highlightTeamZone(currentTeam)
end) end)
RegisterNetEvent('tdm:updateScore', function(team1Score, team2Score) RegisterNetEvent('tdm:updateScore', function(team1Score, team2Score, gameStats)
lib.showTextUI('[Team 1: ' .. team1Score .. '] VS [Team 2: ' .. team2Score .. ']', { local displayText = string.format(
'[Team 1: %d] VS [Team 2: %d] | Deine Treffer: %d | Tode: %d',
team1Score,
team2Score,
playerStats.hits,
playerStats.deaths
)
lib.showTextUI(displayText, {
position = "top-center", position = "top-center",
icon = 'crosshairs' icon = 'crosshairs'
}) })
end) end)
RegisterNetEvent('tdm:hitRegistered', function()
playerStats.hits = playerStats.hits + 1
lib.notify({
title = 'Treffer!',
description = 'Du hast einen Gegner getroffen! (+1 Punkt)',
type = 'success',
duration = 2000
})
showHitMarker()
end)
RegisterNetEvent('tdm:deathRegistered', function()
playerStats.deaths = playerStats.deaths + 1
end)
RegisterNetEvent('tdm:gameEnded', function(winnerTeam, team1Score, team2Score) RegisterNetEvent('tdm:gameEnded', function(winnerTeam, team1Score, team2Score)
lib.hideTextUI() lib.hideTextUI()
local wonGame = (currentTeam == 'team1' and winnerTeam == 'team1') or (currentTeam == 'team2' and winnerTeam == 'team2')
local resultText = wonGame and '🏆 GEWONNEN!' or '💀 VERLOREN!'
local statsText = string.format(
'%s\n\n' ..
'Endergebnis:\n' ..
'Team 1: %d Punkte\n' ..
'Team 2: %d Punkte\n\n' ..
'Deine Statistiken:\n' ..
'🎯 Treffer: %d\n' ..
'💀 Tode: %d\n' ..
'📊 K/D: %.2f',
resultText,
team1Score,
team2Score,
playerStats.hits,
playerStats.deaths,
playerStats.deaths > 0 and (playerStats.hits / playerStats.deaths) or playerStats.hits
)
local alert = lib.alertDialog({ local alert = lib.alertDialog({
header = 'Spiel beendet!', header = 'Spiel beendet!',
content = 'Team ' .. winnerTeam .. ' hat gewonnen!\n\nTeam 1: ' .. team1Score .. '\nTeam 2: ' .. team2Score, content = statsText,
centered = true, centered = true,
cancel = false cancel = false
}) })
@ -180,10 +239,34 @@ function highlightTeamZone(team)
end end
end end
function showHitMarker()
CreateThread(function()
local startTime = GetGameTimer()
while GetGameTimer() - startTime < 500 do
Wait(0)
-- Rotes X in der Mitte des Bildschirms
DrawRect(0.5, 0.5, 0.02, 0.002, 255, 0, 0, 255) -- Horizontale Linie
DrawRect(0.5, 0.5, 0.002, 0.02, 255, 0, 0, 255) -- Vertikale Linie
-- Text
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
function openMainMenu() function openMainMenu()
TriggerServerEvent('tdm:requestGamesList') TriggerServerEvent('tdm:requestGamesList')
Wait(100) -- Kurz warten für Server Response Wait(100)
local options = { local options = {
{ {
@ -228,7 +311,6 @@ end
function openCreateGameMenu() function openCreateGameMenu()
local fieldOptions = {} local fieldOptions = {}
-- Spielfelder zu Options hinzufügen
for fieldId, fieldData in pairs(Config.gameFields) do for fieldId, fieldData in pairs(Config.gameFields) do
table.insert(fieldOptions, { table.insert(fieldOptions, {
value = fieldId, value = fieldId,
@ -273,7 +355,7 @@ function openCreateGameMenu()
local gameName = input[1] local gameName = input[1]
local fieldId = input[2] local fieldId = input[2]
local gameType = input[3] -- 'public' oder 'private' local gameType = input[3]
local password = input[4] and input[4] ~= '' and input[4] or nil local password = input[4] and input[4] ~= '' and input[4] or nil
if gameName and fieldId and gameType then if gameName and fieldId and gameType then
@ -348,7 +430,6 @@ function openJoinGameMenu()
lib.showContext('tdm_join_menu') lib.showContext('tdm_join_menu')
end end
-- Zone Checker Thread -- Zone Checker Thread
CreateThread(function() CreateThread(function()
while true do while true do
@ -424,9 +505,19 @@ CreateThread(function()
local ped = PlayerPedId() local ped = PlayerPedId()
if HasEntityBeenDamagedByAnyPed(ped) then if HasEntityBeenDamagedByAnyPed(ped) then
local damager = GetPedSourceOfDeath(ped)
local damagerPlayer = nil
for _, player in pairs(GetActivePlayers()) do
if GetPlayerPed(player) == damager then
damagerPlayer = GetPlayerServerId(player)
break
end
end
ClearEntityLastDamageEntity(ped) ClearEntityLastDamageEntity(ped)
TriggerEvent('tdm:playerHit') TriggerEvent('tdm:playerHit')
TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam) TriggerServerEvent('tdm:playerWasHit', currentGameId, currentTeam, damagerPlayer)
end end
end end
end end

View file

@ -28,10 +28,10 @@ RegisterNetEvent('tdm:createGame', function(gameName, fieldId, gameType, passwor
fieldId = fieldId, fieldId = fieldId,
admin = src, admin = src,
adminName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname, adminName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
gameType = gameType, -- 'public' oder 'private' gameType = gameType,
password = password, password = password,
hasPassword = password ~= nil, hasPassword = password ~= nil,
status = 'waiting', -- waiting, active, finished status = 'waiting',
team1 = {}, team1 = {},
team2 = {}, team2 = {},
score = {team1 = 0, team2 = 0}, score = {team1 = 0, team2 = 0},
@ -43,10 +43,14 @@ RegisterNetEvent('tdm:createGame', function(gameName, fieldId, gameType, passwor
local typeText = gameType == 'public' and 'öffentliches' or 'privates' local typeText = gameType == 'public' and 'öffentliches' or 'privates'
TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. typeText .. ' Spiel "' .. gameName .. '" wurde erstellt!', 'success') TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. typeText .. ' Spiel "' .. gameName .. '" wurde erstellt!', 'success')
-- Games Liste an alle senden
updateGamesListForAll() updateGamesListForAll()
end) end)
RegisterNetEvent('tdm:requestGamesList', function()
local src = source
TriggerClientEvent('tdm:updateGamesList', src, activeGames)
end)
RegisterNetEvent('tdm:requestJoinGame', function(gameId, password) RegisterNetEvent('tdm:requestJoinGame', function(gameId, password)
local src = source local src = source
local Player = QBCore.Functions.GetPlayer(src) local Player = QBCore.Functions.GetPlayer(src)
@ -96,17 +100,14 @@ RegisterNetEvent('tdm:requestJoinGame', function(gameId, password)
-- Join Logic basierend auf Spiel Typ -- Join Logic basierend auf Spiel Typ
if game.gameType == 'public' then if game.gameType == 'public' then
-- Öffentliches Spiel - automatisch beitreten
joinPlayerToGame(src, gameId) joinPlayerToGame(src, gameId)
TriggerClientEvent('QBCore:Notify', src, 'Du bist dem öffentlichen Spiel beigetreten!', 'success') TriggerClientEvent('QBCore:Notify', src, 'Du bist dem öffentlichen Spiel beigetreten!', 'success')
else else
-- Privates Spiel - Join Request an Admin senden
TriggerClientEvent('tdm:joinRequest', game.admin, gameId, playerName, src) TriggerClientEvent('tdm:joinRequest', game.admin, gameId, playerName, src)
TriggerClientEvent('QBCore:Notify', src, 'Join-Anfrage gesendet an ' .. game.adminName, 'info') TriggerClientEvent('QBCore:Notify', src, 'Join-Anfrage gesendet an ' .. game.adminName, 'info')
end end
end) end)
RegisterNetEvent('tdm:approveJoinRequest', function(gameId, playerId, approved) RegisterNetEvent('tdm:approveJoinRequest', function(gameId, playerId, approved)
local src = source local src = source
local game = activeGames[gameId] local game = activeGames[gameId]
@ -124,7 +125,6 @@ end)
RegisterNetEvent('tdm:leaveGame', function() RegisterNetEvent('tdm:leaveGame', function()
local src = source local src = source
-- Spieler aus allen Spielen entfernen
for gameId, game in pairs(activeGames) do for gameId, game in pairs(activeGames) do
removePlayerFromGame(src, gameId) removePlayerFromGame(src, gameId)
end end
@ -132,29 +132,50 @@ RegisterNetEvent('tdm:leaveGame', function()
TriggerClientEvent('tdm:leaveGame', src) TriggerClientEvent('tdm:leaveGame', src)
end) end)
RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam) RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, shooterId)
local src = source local src = source
local game = activeGames[gameId] local game = activeGames[gameId]
if not game then return end if not game then return end
-- Punkt für das andere Team local shooterTeam = nil
local scoringTeam = victimTeam == 'team1' and 'team2' or 'team1' if shooterId then
game.score[scoringTeam] = game.score[scoringTeam] + 1 for _, playerId in ipairs(game.team1) do
if playerId == shooterId then
shooterTeam = 'team1'
break
end
end
if not shooterTeam then
for _, playerId in ipairs(game.team2) do
if playerId == shooterId then
shooterTeam = 'team2'
break
end
end
end
end
-- Score Update an alle Spieler if shooterTeam and shooterTeam ~= victimTeam then
updateScoreForGame(gameId) game.score[shooterTeam] = game.score[shooterTeam] + 1
-- Prüfen ob Spiel gewonnen if shooterId then
if game.score[scoringTeam] >= game.maxHits then TriggerClientEvent('tdm:hitRegistered', shooterId)
endGame(gameId, scoringTeam) end
TriggerClientEvent('tdm:deathRegistered', src)
updateScoreForGame(gameId)
if game.score[shooterTeam] >= game.maxHits then
endGame(gameId, shooterTeam)
end
end end
end) end)
RegisterNetEvent('tdm:playerDied', function(gameId) RegisterNetEvent('tdm:playerDied', function(gameId)
local src = source local src = source
removePlayerFromGame(src, gameId) removePlayerFromGame(src, gameId)
checkGameEnd(gameId)
end) end)
-- Funktionen -- Funktionen
@ -167,20 +188,25 @@ function joinPlayerToGame(playerId, gameId)
table.insert(game[team], playerId) table.insert(game[team], playerId)
-- Spiel starten wenn mindestens 2 Spieler
if #game.team1 + #game.team2 >= 2 and game.status == 'waiting' then
game.status = 'active'
game.startTime = os.time()
-- Game Timer starten
startGameTimer(gameId)
end
TriggerClientEvent('tdm:joinGame', playerId, gameId, team, game.fieldId) TriggerClientEvent('tdm:joinGame', playerId, gameId, team, game.fieldId)
-- Spiel starten wenn genug Spieler
checkGameStart(gameId)
updateGamesListForAll()
updateScoreForGame(gameId) updateScoreForGame(gameId)
updateGamesListForAll()
end end
function removePlayerFromGame(playerId, gameId) function removePlayerFromGame(playerId, gameId)
local game = activeGames[gameId] local game = activeGames[gameId]
if not game then return end if not game then return end
-- Aus Team 1 entfernen -- Spieler aus Teams entfernen
for i, id in ipairs(game.team1) do for i, id in ipairs(game.team1) do
if id == playerId then if id == playerId then
table.remove(game.team1, i) table.remove(game.team1, i)
@ -188,7 +214,6 @@ function removePlayerFromGame(playerId, gameId)
end end
end end
-- Aus Team 2 entfernen
for i, id in ipairs(game.team2) do for i, id in ipairs(game.team2) do
if id == playerId then if id == playerId then
table.remove(game.team2, i) table.remove(game.team2, i)
@ -206,90 +231,58 @@ function removePlayerFromGame(playerId, gameId)
updateGamesListForAll() updateGamesListForAll()
end end
function checkGameStart(gameId)
local game = activeGames[gameId]
if not game then return end
local totalPlayers = #game.team1 + #game.team2
if totalPlayers >= 2 and game.status == 'waiting' then
startGame(gameId)
end
end
function startGame(gameId)
local game = activeGames[gameId]
if not game then return end
game.status = 'active'
game.startTime = os.time()
game.score = {team1 = 0, team2 = 0}
-- Nachricht an alle Spieler
for _, playerId in ipairs(game.team1) do
TriggerClientEvent('QBCore:Notify', playerId, 'Spiel gestartet!', 'success')
end
for _, playerId in ipairs(game.team2) do
TriggerClientEvent('QBCore:Notify', playerId, 'Spiel gestartet!', 'success')
end
updateScoreForGame(gameId)
updateGamesListForAll()
-- Game Timer
CreateThread(function()
while activeGames[gameId] and activeGames[gameId].status == 'active' do
Wait(1000)
local currentTime = os.time()
local elapsed = currentTime - game.startTime
if elapsed >= game.maxTime then
local winnerTeam = game.score.team1 > game.score.team2 and 'team1' or 'team2'
endGame(gameId, winnerTeam, 'Zeit abgelaufen')
break
end
end
end)
end
function endGame(gameId, winnerTeam, reason) function endGame(gameId, winnerTeam, reason)
local game = activeGames[gameId] local game = activeGames[gameId]
if not game then return end if not game then return end
game.status = 'finished' game.status = 'finished'
local message = reason or (winnerTeam and ('Team ' .. winnerTeam .. ' hat gewonnen!') or 'Spiel beendet') local allPlayers = {}
-- Nachricht an alle Spieler
for _, playerId in ipairs(game.team1) do for _, playerId in ipairs(game.team1) do
if winnerTeam then table.insert(allPlayers, playerId)
TriggerClientEvent('tdm:gameEnded', playerId, winnerTeam, game.score.team1, game.score.team2)
else
TriggerClientEvent('QBCore:Notify', playerId, message, 'error')
TriggerClientEvent('tdm:leaveGame', playerId)
end
end end
for _, playerId in ipairs(game.team2) do for _, playerId in ipairs(game.team2) do
if winnerTeam then table.insert(allPlayers, playerId)
TriggerClientEvent('tdm:gameEnded', playerId, winnerTeam, game.score.team1, game.score.team2)
else
TriggerClientEvent('QBCore:Notify', playerId, message, 'error')
TriggerClientEvent('tdm:leaveGame', playerId)
end
end end
-- Spiel nach 15 Sekunden löschen -- Game End Event an alle Spieler
CreateThread(function() for _, playerId in ipairs(allPlayers) do
Wait(15000) TriggerClientEvent('tdm:gameEnded', playerId, winnerTeam, game.score.team1, game.score.team2)
end
-- Spiel nach 10 Sekunden löschen
SetTimeout(10000, function()
activeGames[gameId] = nil activeGames[gameId] = nil
updateGamesListForAll() updateGamesListForAll()
end) end)
if reason then
print('[TDM] Spiel ' .. gameId .. ' beendet: ' .. reason)
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()
while game and game.status == 'active' and (os.time() - startTime) < maxTime do
Wait(1000)
game = activeGames[gameId] -- Refresh game data
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
endGame(gameId, winnerTeam, 'Zeit abgelaufen')
end
end)
end end
function checkGameEnd(gameId)
local game = activeGames[gameId]
if not game then return end
function checkGameEnd(gameId) function checkGameEnd(gameId)
local game = activeGames[gameId] local game = activeGames[gameId]
if not game then return end if not game then return end
@ -299,7 +292,6 @@ function checkGameEnd(gameId)
if totalPlayers < 2 and game.status == 'active' then if totalPlayers < 2 and game.status == 'active' then
endGame(gameId, nil, 'Zu wenig Spieler') endGame(gameId, nil, 'Zu wenig Spieler')
elseif totalPlayers == 0 then elseif totalPlayers == 0 then
-- Spiel löschen wenn keine Spieler mehr da sind
activeGames[gameId] = nil activeGames[gameId] = nil
updateGamesListForAll() updateGamesListForAll()
end end
@ -309,17 +301,20 @@ function updateScoreForGame(gameId)
local game = activeGames[gameId] local game = activeGames[gameId]
if not game then return end if not game then return end
-- Score an alle Spieler des Spiels senden local gameStats = {
totalHits = game.score.team1 + game.score.team2,
gameTime = game.startTime and (os.time() - game.startTime) or 0
}
for _, playerId in ipairs(game.team1) do for _, playerId in ipairs(game.team1) do
TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2) TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, gameStats)
end end
for _, playerId in ipairs(game.team2) do for _, playerId in ipairs(game.team2) do
TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2) TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, gameStats)
end end
end end
function updateGamesListForAll() function updateGamesListForAll()
-- Games Liste an alle Spieler senden
local players = QBCore.Functions.GetPlayers() local players = QBCore.Functions.GetPlayers()
for _, playerId in pairs(players) do for _, playerId in pairs(players) do
TriggerClientEvent('tdm:updateGamesList', playerId, activeGames) TriggerClientEvent('tdm:updateGamesList', playerId, activeGames)
@ -330,7 +325,6 @@ end
AddEventHandler('playerDropped', function() AddEventHandler('playerDropped', function()
local src = source local src = source
-- Spieler aus allen Spielen entfernen
for gameId, game in pairs(activeGames) do for gameId, game in pairs(activeGames) do
removePlayerFromGame(src, gameId) removePlayerFromGame(src, gameId)
end end
@ -341,7 +335,29 @@ AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() == resourceName then if GetCurrentResourceName() == resourceName then
activeGames = {} activeGames = {}
gameIdCounter = 1 gameIdCounter = 1
print('[TDM] TeamDeathmatch System gestartet!')
end end
end) end)
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 = {}
print('[TDM] TeamDeathmatch System gestoppt!')
end
end)