server/projectile.go

123 lines
2.6 KiB
Go
Raw Normal View History

2014-04-23 14:28:13 -07:00
package server
import (
"log"
v "hackerbots.us/vector"
)
2014-04-14 00:26:41 -07:00
// Projectile are the things robots can shoot at eachother.
type Projectile struct {
Id string `json:"id"`
Position v.Point2d `json:"position"`
MoveTo v.Point2d `json:"-"`
2013-11-06 20:32:56 -08:00
Radius int `json:"-"`
2014-04-26 14:56:12 -07:00
Speed float64 `json:"-"`
Damage int `json:"-"`
2013-11-08 21:25:42 -08:00
Owner *Robot `json:"-"`
2014-04-26 14:56:12 -07:00
Delta float64
}
2014-04-14 00:26:41 -07:00
// Projectile.Tick is called every game tick and moves projectiles along,
// determines when they should blow up, and how damaage is propagated to
// players.
func (p *Projectile) Tick(g *Game) {
vec := p.MoveTo.Sub(p.Position)
v_norm := vec.Normalize()
v_scaled := v_norm.Scale(p.Speed * p.Delta)
newPos := p.Position.Add(v_scaled)
hit_player := false
for player := range g.players {
2013-11-08 21:25:42 -08:00
for _, r := range player.Robots {
2013-11-08 22:26:56 -08:00
if r == p.Owner {
2013-11-08 21:25:42 -08:00
continue
}
2014-01-07 21:17:41 -08:00
player_rect := v.AASquareAtPoint(r.Position, 3)
2013-11-08 21:25:42 -08:00
collision, _, _ := v.RectIntersection(player_rect, p.Position, v_scaled)
if collision {
hit_player = true
2014-01-16 00:13:02 -08:00
p.Owner.gameStats.Hits++
p.Owner.gameStats.DirectHits++
2013-11-08 21:25:42 -08:00
if r.Health > 0 {
// Direct hit causes more damage
log.Printf("Direct Hit %v, Dmg:%v", r.Id, p.Damage)
2013-11-08 21:25:42 -08:00
r.Health -= p.Damage
r.Hit = true
2014-01-16 00:13:02 -08:00
if r.Health <= 0 {
r.gameStats.Deaths++
p.Owner.gameStats.Kills++
}
2013-11-08 21:25:42 -08:00
}
}
}
}
// Are we going to intersect the destination zone in this tick?
2014-01-07 21:17:41 -08:00
r_dest := v.AASquareAtPoint(p.MoveTo, 3.0)
travel := newPos.Sub(p.Position)
2013-10-28 07:54:49 -07:00
arrived, _, pos := v.RectIntersection(r_dest, p.Position, travel)
2013-10-25 22:30:15 -07:00
if !arrived {
for _, obj := range g.obstacles {
2013-10-28 07:54:49 -07:00
collision, _, pos := v.RectIntersection(obj.Bounds, p.Position, travel)
2013-10-25 22:30:15 -07:00
if collision {
arrived = true
if pos != nil {
p.Position = *pos
}
obj.Hp -= p.Damage
// if obj.Hp < 0 {
// delete(g.obstacles, i)
// }
2013-10-25 22:30:15 -07:00
}
}
2013-10-28 07:54:49 -07:00
} else {
if pos != nil {
p.Position = *pos
}
2013-10-25 22:30:15 -07:00
}
if arrived || hit_player {
delete(g.projectiles, p)
// Spawn a splosion
splo := &Splosion{
Id: p.Id,
Position: p.Position,
Radius: p.Radius,
Lifespan: 8,
}
g.splosions[splo] = true
for player := range g.players {
2013-11-08 21:25:42 -08:00
for _, r := range player.Robots {
dist := v.Distance(r.Position, p.Position)
2014-04-26 14:56:12 -07:00
if dist < float64(p.Radius) {
2013-11-08 21:25:42 -08:00
if r.Health > 0 {
r.Health -= p.Damage
r.Hit = true
}
2014-01-16 00:13:02 -08:00
p.Owner.gameStats.Hits++
if r.Health <= 0 {
r.gameStats.Deaths++
2014-01-23 21:20:43 -08:00
if r == p.Owner {
p.Owner.gameStats.Suicides++
} else {
p.Owner.gameStats.Kills++
}
2014-01-16 00:13:02 -08:00
}
}
}
}
} else {
p.Position.X = newPos.X
p.Position.Y = newPos.Y
}
}