server/projectile.go

91 lines
1.9 KiB
Go

package main
import (
v "bitbucket.org/hackerbots/vector"
"log"
)
type Projectile struct {
Id string `json:"id"`
Position v.Point2d `json:"position"`
MoveTo v.Point2d `json:"-"`
Radius int `json:"-"`
Speed float32 `json:"-"`
Damage int `json:"-"`
Owner *player `json:"-"`
}
func (p *Projectile) Tick(g *game) {
vec := p.MoveTo.Sub(p.Position)
v_norm := vec.Normalize()
v_scaled := v_norm.Scale(p.Speed * delta)
newPos := p.Position.Add(v_scaled)
hit_player := false
for player := range g.players {
if player == p.Owner {
continue
}
player_rect := v.RectFromPoint(player.Robot.Position, 3)
collision, _, _ := v.RectIntersection(player_rect, p.Position, v_scaled)
if collision {
hit_player = true
if player.Robot.Health > 0 {
// Direct hit causes more damage
log.Printf("Direct Hit %v, Dmg:%v", player.Robot.Id, p.Damage)
player.Robot.Health -= p.Damage
}
}
}
// Are we going to intersect the destination zone in this tick?
r_dest := v.RectFromPoint(p.MoveTo, 3.0)
travel := newPos.Sub(p.Position)
arrived, _, pos := v.RectIntersection(r_dest, p.Position, travel)
if !arrived {
for _, obj := range g.obstacles {
collision, _, pos := v.RectIntersection(obj.Bounds, p.Position, travel)
if collision {
arrived = true
p.Position = pos
}
}
} else {
p.Position = pos
}
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 {
dist := v.Distance(player.Robot.Position, p.Position)
if dist < float32(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 {
}
}
}
}
} else {
p.Position.X = newPos.X
p.Position.Y = newPos.Y
}
}