diff options
Diffstat (limited to 'internal/game/sys_safespot.go')
| -rw-r--r-- | internal/game/sys_safespot.go | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/internal/game/sys_safespot.go b/internal/game/sys_safespot.go index 539f69d..ce99610 100644 --- a/internal/game/sys_safespot.go +++ b/internal/game/sys_safespot.go @@ -104,6 +104,18 @@ func (g *Game) activateSafespot(sess *net.Session, p *player.Player, ss *Safespo return } + // Two players can start hiding in the same tick and both pass the cap check + // at hide time (the occupant is only appended here, when the countdown + // completes). Re-check the cap now so a max_occupants cover never ends with + // more occupants than it allows. + if cfg.MaxOccupants > 0 && len(st.SafespotOccupants) >= cfg.MaxOccupants { + g.safespot.Delete(p.Name) + sess.WriteLine("") + sess.WriteLine(fmt.Sprintf("%s already hiding there!", + joinSafespotOccupants(st.SafespotOccupants))) + return + } + st.SafespotOccupants = append(st.SafespotOccupants, p.Name) var msg string @@ -143,11 +155,22 @@ func (g *Game) safespotMaintenance(sess *net.Session, p *player.Player, ss *Safe return } + // Decay accumulation and the decay roll are per-object, not per-occupant: + // SafespotTick calls this once per occupant, so N players on one cover + // would otherwise advance the counter N times and roll decay N times per + // tick. The first occupant does the object-level work; the per-player + // UnsafeChance slip below stays per occupant. + isFirstOccupant := st.SafespotOccupants[0] == p.Name + if cfg.UnsafeChance > 0 && rand.Float64() < cfg.UnsafeChance { g.forceLeaveSafespot(sess, p, ss, "You slip and are no longer covered!") return } + if !isFirstOccupant { + return + } + levelIdx := st.SafespotLevel - 1 degraded := false |
