diff --git a/commands.go b/commands.go index e12987e..05b79a2 100644 --- a/commands.go +++ b/commands.go @@ -120,9 +120,7 @@ var scanCommand = &Command{ fmt.Fprintf(conn, "scanners are still recharging. Can scan again in %v\n", conn.NextScan()) return } - s := &scan{start: time.Now(), origin: conn.System()} - currentGame.Register(s) - + currentGame.Register(NewScan(conn.System())) conn.RecordScan() system := conn.System() log_info("scan sent from %s", system.name) diff --git a/game.go b/game.go index 60f63dc..ac8669c 100644 --- a/game.go +++ b/game.go @@ -118,6 +118,7 @@ func (g *Game) tick() { g.frame += 1 for elem := range g.elems { if elem.Dead() { + log_info("delete game object: %v", elem) delete(g.elems, elem) } } @@ -128,11 +129,5 @@ func (g *Game) tick() { type GameElement interface { Tick(frame int64) - Dead() Mortality -} - -type Mortality bool - -func (m Mortality) Dead() Mortality { - return m + Dead() bool } diff --git a/scan.go b/scan.go index e5efd60..b23c40e 100644 --- a/scan.go +++ b/scan.go @@ -1,30 +1,80 @@ package main import ( + "fmt" "time" ) type scan struct { - Mortality - start time.Time - origin *System - dist float64 - nextHitIndex int + start time.Time + origin *System + dist float64 + nextHitIndex int + nextEchoIndex int + results []scanResult +} + +type scanResult struct { + system *System + dist float64 + players map[*Connection]bool + colonizedBy *Connection +} + +func NewScan(origin *System) *scan { + return &scan{ + origin: origin, + start: time.Now(), + results: make([]scanResult, 0, len(origin.Distances())), + } } func (s *scan) Tick(frame int64) { s.dist += lightSpeed - for { + s.hits() + s.echos() +} + +func (s *scan) Dead() bool { + return s.nextEchoIndex >= len(s.origin.Distances()) +} + +func (s *scan) String() string { + return fmt.Sprintf("[scan origin: %s start_time: %v]", s.origin.name, s.start) +} + +func (s *scan) hits() { + for ; s.nextHitIndex < len(s.origin.Distances()); s.nextHitIndex += 1 { candidate := s.origin.Distances()[s.nextHitIndex] if s.dist < candidate.dist { break } + s.results = append(s.results, s.hitSystem(candidate.s, candidate.dist)) log_info("scan hit %v. Traveled %v in %v", candidate.s.name, candidate.dist, time.Since(s.start)) - s.nextHitIndex += 1 - if s.nextHitIndex >= len(s.origin.Distances()) { - s.Mortality = true - log_info("scan complete") + } +} + +func (s *scan) hitSystem(sys *System, dist float64) scanResult { + r := scanResult{ + system: sys, + colonizedBy: sys.colonizedBy, + dist: dist * 2.0, + } + if sys.players != nil { + r.players = make(map[*Connection]bool, len(sys.players)) + for k, v := range sys.players { + r.players[k] = v + } + } + return r +} + +func (s *scan) echos() { + for ; s.nextEchoIndex < len(s.results); s.nextEchoIndex += 1 { + res := s.results[s.nextEchoIndex] + if s.dist < res.dist { break } + log_info("echo from %v reached origin %v after %v", res.system.name, s.origin.name, time.Since(s.start)) } }