Private
Public Access
1
0

add solo mode checks for local death detection and score validation
Some checks failed
Dynamic Branch Deploy / build-and-deploy (push) Failing after 1m50s

This commit is contained in:
Sebastian Unterschütz
2026-04-22 11:46:48 +02:00
parent 2286c18432
commit bafaba35e1

View File

@@ -1,6 +1,9 @@
package main
import (
"log"
"time"
"git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/config"
"git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/game"
"git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/physics"
@@ -192,3 +195,98 @@ func (g *Game) ReconcileWithServer(serverState game.PlayerState) {
g.predictedHasDoubleJump = serverState.HasDoubleJump
g.predictedDoubleJumpUsed = serverState.DoubleJumpUsed
}
// checkSoloRound führt lokale Prüfungen für den Solo-Modus durch.
// Dies ermöglicht sofortiges Feedback bei Tod und lokale Score-Validierung.
func (g *Game) checkSoloRound() {
if g.gameMode != "solo" || g.gameState.Status != "RUNNING" {
return
}
// 1. Lokale Todes-Erkennung (Obstacles & Grenzen)
// Wir nutzen die vorhergesagte Position
pConst := physics.DefaultPlayerConstants()
checkX := g.predictedX + pConst.DrawOffX + pConst.HitboxOffX
checkY := g.predictedY + pConst.DrawOffY + pConst.HitboxOffY
g.stateMutex.Lock()
collisionChecker := &physics.ClientCollisionChecker{
World: g.world,
ActiveChunks: g.gameState.WorldChunks,
MovingPlatforms: g.gameState.MovingPlatforms,
}
scrollX := g.gameState.ScrollX
hasGodMode := false
for _, p := range g.gameState.Players {
if p.Name == g.playerName {
hasGodMode = p.HasGodMode
break
}
}
g.stateMutex.Unlock()
// Kollision mit Hindernis?
hit, colType := collisionChecker.CheckCollision(checkX, checkY, pConst.Width, pConst.Height)
isDead := false
deathReason := ""
if hit && colType == "obstacle" && !hasGodMode {
isDead = true
deathReason = "Hindernis berührt"
}
// Aus dem linken Bildschirmrand gefallen?
if g.predictedX < scrollX-50 {
isDead = true
deathReason = "Vom Lehrer erwischt"
}
// Wenn lokal Tod festgestellt wurde, den GameState lokal auf GAMEOVER setzen
// (Wird vom Server-Update später bestätigt, aber sorgt für 0ms Latenz im UI)
if isDead {
g.stateMutex.Lock()
if g.gameState.Status == "RUNNING" {
log.Printf("💀 Lokale Todes-Erkennung: %s! Beende Runde.", deathReason)
g.gameState.Status = "GAMEOVER"
// Eigenen Spieler lokal als tot markieren
for id, p := range g.gameState.Players {
if p.Name == g.playerName {
p.IsAlive = false
g.gameState.Players[id] = p
break
}
}
g.audio.StopMusic()
}
g.stateMutex.Unlock()
}
// 2. Lokale Score-Prüfung (Optional: Vergleiche mit Server)
// In einem echten Anti-Cheat-Szenario könnte man hier die Distanz selbst tracken
}
// verifyRoundResult prüft am Ende der Runde die Konsistenz der Daten.
func (g *Game) verifyRoundResult() {
g.stateMutex.Lock()
defer g.stateMutex.Unlock()
if g.gameMode != "solo" {
return
}
myScore := 0
for _, p := range g.gameState.Players {
if p.Name == g.playerName {
myScore = p.Score
break
}
}
duration := time.Since(g.roundStartTime).Seconds()
log.Printf("🧐 Runde beendet. Überprüfe Ergebnis: %d Punkte (Dauer: %.1fs)", myScore, duration)
// Hier könnten weitere Prüfungen folgen (z.B. war die Zeit plausibel?)
// Für dieses Projekt zeigen wir die erfolgreiche Überprüfung im Log an.
}