From 15b7e221b799ef107dec44ecdb294026dfd3d059 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 24 Jun 2026 22:55:35 -0400 Subject: refactor: pulled techs out to yaml files, unified numerous combat functions, broke up game object --- internal/game/safespot_manager.go | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 internal/game/safespot_manager.go (limited to 'internal/game/safespot_manager.go') diff --git a/internal/game/safespot_manager.go b/internal/game/safespot_manager.go new file mode 100644 index 0000000..1520bc7 --- /dev/null +++ b/internal/game/safespot_manager.go @@ -0,0 +1,85 @@ +package game + +import "sync" + +// SafespotState tracks a player's active safespot (cover) in a room. +type SafespotState struct { + Active bool + ObjectDefID string + ObjectIndex int + RoomID int + HideCountdown int +} + +// SafespotManager owns the per-player safespot state map and its mutex. +// Callers receive value copies via Get/Peek so they cannot mutate state +// outside the lock — this avoids the lock-copy-pointer-unlock anti-pattern. +type SafespotManager struct { + mu sync.Mutex + states map[string]*SafespotState +} + +func NewSafespotManager() *SafespotManager { + return &SafespotManager{states: make(map[string]*SafespotState)} +} + +// Get returns a value copy of the player's safespot state. +func (m *SafespotManager) Get(name string) (SafespotState, bool) { + m.mu.Lock() + defer m.mu.Unlock() + ss, ok := m.states[name] + if !ok { + return SafespotState{}, false + } + return *ss, true +} + +// Has reports whether any safespot state exists for the player. +func (m *SafespotManager) Has(name string) bool { + m.mu.Lock() + defer m.mu.Unlock() + _, ok := m.states[name] + return ok +} + +// IsActive reports whether the player has an active, fully-hidden safespot +// (hide countdown complete). +func (m *SafespotManager) IsActive(name string) bool { + m.mu.Lock() + defer m.mu.Unlock() + ss, ok := m.states[name] + return ok && ss.Active && ss.HideCountdown <= 0 +} + +// Set stores a safespot state for the player. +func (m *SafespotManager) Set(name string, ss SafespotState) { + m.mu.Lock() + defer m.mu.Unlock() + m.states[name] = &ss +} + +// Delete removes the player's safespot state. Returns true if a state existed. +func (m *SafespotManager) Delete(name string) bool { + m.mu.Lock() + defer m.mu.Unlock() + _, ok := m.states[name] + delete(m.states, name) + return ok +} + +// DecrementHideCountdown decrements the hide countdown for a player who is +// transitioning from hiding to hidden. Returns (newCountdown, ok). A return of +// ok=true with newCountdown > 0 means the player is still counting down; +// newCountdown == 0 means the safespot just activated. +func (m *SafespotManager) DecrementHideCountdown(name string) (int, bool) { + m.mu.Lock() + defer m.mu.Unlock() + ss, ok := m.states[name] + if !ok || !ss.Active { + return 0, false + } + if ss.HideCountdown > 0 { + ss.HideCountdown-- + } + return ss.HideCountdown, true +} -- cgit v1.2.3