130 lines
2.7 KiB
Go
130 lines
2.7 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"git.zb-server.de/ZB-Server/EscapeFromTeacher/pkg/game"
|
|
)
|
|
|
|
// CheckCoinCollision prüft ob Spieler Coins einsammelt
|
|
func (r *Room) CheckCoinCollision(p *ServerPlayer) {
|
|
if !p.IsAlive || p.IsSpectator {
|
|
return
|
|
}
|
|
|
|
playerHitbox := game.Rect{
|
|
OffsetX: p.X + r.pDrawOffX + r.pHitboxOffX,
|
|
OffsetY: p.Y + r.pDrawOffY + r.pHitboxOffY,
|
|
W: r.pW,
|
|
H: r.pH,
|
|
}
|
|
|
|
// Durch alle aktiven Chunks iterieren
|
|
for _, activeChunk := range r.ActiveChunks {
|
|
chunkDef, exists := r.World.ChunkLibrary[activeChunk.ChunkID]
|
|
if !exists {
|
|
continue
|
|
}
|
|
|
|
// Durch alle Objekte im Chunk
|
|
for objIdx, obj := range chunkDef.Objects {
|
|
assetDef, ok := r.World.Manifest.Assets[obj.AssetID]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
// Nur Coins prüfen
|
|
if assetDef.Type != "coin" {
|
|
continue
|
|
}
|
|
|
|
// Eindeutiger Key für diesen Coin
|
|
coinKey := fmt.Sprintf("%s_%d", activeChunk.ChunkID, objIdx)
|
|
|
|
// Wurde bereits eingesammelt?
|
|
if r.CollectedCoins[coinKey] {
|
|
continue
|
|
}
|
|
|
|
// Coin-Hitbox
|
|
coinHitbox := game.Rect{
|
|
OffsetX: activeChunk.X + obj.X + assetDef.Hitbox.OffsetX,
|
|
OffsetY: obj.Y + assetDef.Hitbox.OffsetY,
|
|
W: assetDef.Hitbox.W,
|
|
H: assetDef.Hitbox.H,
|
|
}
|
|
|
|
// Kollision?
|
|
if game.CheckRectCollision(playerHitbox, coinHitbox) {
|
|
// Coin einsammeln!
|
|
r.CollectedCoins[coinKey] = true
|
|
p.Score += 200
|
|
log.Printf("💰 %s hat Coin eingesammelt! Score: %d", p.Name, p.Score)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// UpdateDistanceScore aktualisiert Distanz-basierte Punkte
|
|
func (r *Room) UpdateDistanceScore() {
|
|
if r.Status != "RUNNING" {
|
|
return
|
|
}
|
|
|
|
// Anzahl lebender Spieler zählen
|
|
aliveCount := 0
|
|
for _, p := range r.Players {
|
|
if p.IsAlive && !p.IsSpectator {
|
|
aliveCount++
|
|
}
|
|
}
|
|
|
|
if aliveCount == 0 {
|
|
return
|
|
}
|
|
|
|
// Multiplier = Anzahl lebender Spieler
|
|
multiplier := float64(aliveCount)
|
|
|
|
// Akkumulator erhöhen: multiplier Punkte pro Sekunde
|
|
// Bei 60 FPS: multiplier / 60.0 Punkte pro Tick
|
|
r.ScoreAccum += multiplier / 60.0
|
|
|
|
// Wenn Akkumulator >= 1.0, Punkte vergeben
|
|
if r.ScoreAccum >= 1.0 {
|
|
pointsToAdd := int(r.ScoreAccum)
|
|
r.ScoreAccum -= float64(pointsToAdd)
|
|
|
|
for _, p := range r.Players {
|
|
if p.IsAlive && !p.IsSpectator {
|
|
p.Score += pointsToAdd
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// KillPlayer markiert Spieler als tot
|
|
func (r *Room) KillPlayer(p *ServerPlayer) {
|
|
if !p.IsAlive {
|
|
return
|
|
}
|
|
|
|
p.IsAlive = false
|
|
p.IsSpectator = true
|
|
log.Printf("💀 %s ist gestorben! Final Score: %d", p.Name, p.Score)
|
|
|
|
// Prüfen ob alle tot sind
|
|
aliveCount := 0
|
|
for _, pl := range r.Players {
|
|
if pl.IsAlive && !pl.IsSpectator {
|
|
aliveCount++
|
|
}
|
|
}
|
|
|
|
if aliveCount == 0 && r.Status == "RUNNING" {
|
|
log.Printf("🏁 Alle Spieler tot - Game Over!")
|
|
r.Status = "GAMEOVER"
|
|
}
|
|
}
|