diff --git a/game.go b/game.go index ffd3162..b196299 100644 --- a/game.go +++ b/game.go @@ -2,6 +2,7 @@ package main import ( "bitbucket.org/hackerbots/bot" + v "bitbucket.org/hackerbots/vector" "log" "sort" "time" @@ -70,6 +71,9 @@ func (g *game) run() { delete(g.spectators, s) close(s.send) case <-time.Tick(time.Duration(*tick) * time.Millisecond): + // XXX: This is very racy!! It was at bottom of loop and empty + // stuff was going out + payload.EmptySlices() if started && len(g.players) == 0 { g.kill <- true } @@ -91,6 +95,7 @@ func (g *game) run() { for p := range g.players { if p.Robot.Health > 0 { robots_remaining++ + // TODO: measure if this would be better to go and wait ... p.scan(g.players) p.nudge() if p.Robot.FireAt != nil { @@ -104,10 +109,9 @@ func (g *game) run() { } sort.Sort(bot.RobotSorter{Robots: payload.Robots}) - for p := range g.projectiles { - // XXX: p.nudge() - payload.Projectiles = append(payload.Projectiles, *p) - } + payload.Projectiles = append(payload.Projectiles, + g.nudgeProjectiles()..., + ) for s := range g.splosions { // XXX: s.tick() @@ -144,8 +148,54 @@ func (g *game) run() { if *verbose { log.Printf("Sent Payload %v\n", t1.Sub(t0)) } - - payload.EmptySlices() } } } + +func (g *game) nudgeProjectiles() (rprojectiles []bot.Projectile) { + for p := range g.projectiles { + newPos := v.Move(p.Position, p.MoveTo, float64(p.Speed), delta) + + hit_player := false + for player := range g.players { + if player.Robot.Id == p.Id { + continue + } + dist := v.Distance(player.Robot.Position, p.Position) + if dist < 5.0 { + hit_player = true + } + } + + if v.Distance(p.Position, p.MoveTo) < 5 || hit_player { + delete(g.projectiles, p) + + // Spawn a splosion + splo := &bot.Splosion{ + Id: p.Id, + Position: p.Position, + Radius: p.Radius, + MaxDamage: 10, + MinDamage: 5, + Lifespan: 8, + } + g.splosions[splo] = true + + for player := range g.players { + dist := v.Distance(player.Robot.Position, p.Position) + if dist < float64(p.Radius) { + + // TODO map damage Max to Min based on distance from explosion + if player.Robot.Health > 0 { + player.Robot.Health -= p.Damage + if player.Robot.Health <= 0 { + } + } + } + } + } + p.Position.X = newPos.X + p.Position.Y = newPos.Y + } + return +} diff --git a/player.go b/player.go index 647f14a..e50a377 100644 --- a/player.go +++ b/player.go @@ -12,13 +12,7 @@ type player struct { ws *websocket.Conn Robot bot.Robot send chan *bot.Boardstate - Instruction instruction -} - -type instruction struct { - MoveTo *v.Point2d `json:"move_to,omitempty"` - FireAt *v.Point2d `json:"fire_at,omitempty"` - Stats bot.Stats `json:"stats"` + Instruction bot.Instruction } func (p *player) sender() { @@ -36,7 +30,7 @@ func (p *player) recv() { for { // XXX: need to mark myself as having received something, also binding // such action to a particular game turn ID - var msg instruction + var msg bot.Instruction err := websocket.JSON.Receive(p.ws, &msg) if err != nil { // TODO: perhaps we could be a bit more precise in the handling of @@ -62,6 +56,7 @@ func (p *player) recv() { } func (p *player) nudge() { + // XXX: we must take into account going past our p.Robot.MoveTo ... newPos := v.Move(p.Robot.Position, *p.Robot.MoveTo, p.Robot.Stats.Speed, delta) p.Robot.Position.X = newPos.X p.Robot.Position.Y = newPos.Y diff --git a/robot.go b/robot.go deleted file mode 100644 index f3ca888..0000000 --- a/robot.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -// XXX: this needs to go into game somehow -// func (p *bot.Projectile) nudge() { -// newPos := move(p.Position, p.MoveTo, float64(p.Speed), delta) -// -// hit_player := false -// for player := range p.game.players { -// if player.Robot.Id == p.Id { -// continue -// } -// dist := distance(player.Robot.Position, p.Position) -// if dist < 5.0 { -// hit_player = true -// } -// } -// -// if distance(p.Position, p.MoveTo) < 5 || hit_player { -// delete(p.game.projectiles, p) -// -// // Spawn a splosion -// splo := &splosion{ -// Id: p.Id, -// Position: p.Position, -// Radius: p.Radius, -// MaxDamage: 10, -// MinDamage: 5, -// Lifespan: 8, -// } -// p.game.splosions[splo] = true -// -// for player := range p.game.players { -// dist := distance(player.Robot.Position, p.Position) -// if dist < float64(p.Radius) { -// -// // TODO map damage Max to Min based on distance from explosion -// if player.Robot.Health > 0 { -// player.Robot.Health -= p.Damage -// if player.Robot.Health <= 0 { -// } -// } -// } -// } -// } -// p.Position.X = newPos.X -// p.Position.Y = newPos.Y -// }