You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
2.4KB

  1. package botserv
  2. import (
  3. "log"
  4. v "bitbucket.org/hackerbots/vector"
  5. )
  6. type Projectile struct {
  7. Id string `json:"id"`
  8. Position v.Point2d `json:"position"`
  9. MoveTo v.Point2d `json:"-"`
  10. Radius int `json:"-"`
  11. Speed float32 `json:"-"`
  12. Damage int `json:"-"`
  13. Owner *Robot `json:"-"`
  14. Delta float32
  15. }
  16. func (p *Projectile) Tick(g *Game) {
  17. vec := p.MoveTo.Sub(p.Position)
  18. v_norm := vec.Normalize()
  19. v_scaled := v_norm.Scale(p.Speed * p.Delta)
  20. newPos := p.Position.Add(v_scaled)
  21. hit_player := false
  22. for player := range g.players {
  23. for _, r := range player.Robots {
  24. if r == p.Owner {
  25. continue
  26. }
  27. player_rect := v.AASquareAtPoint(r.Position, 3)
  28. collision, _, _ := v.RectIntersection(player_rect, p.Position, v_scaled)
  29. if collision {
  30. hit_player = true
  31. p.Owner.gameStats.Hits++
  32. p.Owner.gameStats.DirectHits++
  33. if r.Health > 0 {
  34. // Direct hit causes more damage
  35. log.Printf("Direct Hit %v, Dmg:%v", r.Id, p.Damage)
  36. r.Health -= p.Damage
  37. r.Hit = true
  38. if r.Health <= 0 {
  39. r.gameStats.Deaths++
  40. p.Owner.gameStats.Kills++
  41. }
  42. }
  43. }
  44. }
  45. }
  46. // Are we going to intersect the destination zone in this tick?
  47. r_dest := v.AASquareAtPoint(p.MoveTo, 3.0)
  48. travel := newPos.Sub(p.Position)
  49. arrived, _, pos := v.RectIntersection(r_dest, p.Position, travel)
  50. if !arrived {
  51. for _, obj := range g.obstacles {
  52. collision, _, pos := v.RectIntersection(obj.Bounds, p.Position, travel)
  53. if collision {
  54. arrived = true
  55. if pos != nil {
  56. p.Position = *pos
  57. }
  58. obj.Hp -= p.Damage
  59. // if obj.Hp < 0 {
  60. // delete(g.obstacles, i)
  61. // }
  62. }
  63. }
  64. } else {
  65. if pos != nil {
  66. p.Position = *pos
  67. }
  68. }
  69. if arrived || hit_player {
  70. delete(g.projectiles, p)
  71. // Spawn a splosion
  72. splo := &Splosion{
  73. Id: p.Id,
  74. Position: p.Position,
  75. Radius: p.Radius,
  76. Lifespan: 8,
  77. }
  78. g.splosions[splo] = true
  79. for player := range g.players {
  80. for _, r := range player.Robots {
  81. dist := v.Distance(r.Position, p.Position)
  82. if dist < float32(p.Radius) {
  83. if r.Health > 0 {
  84. r.Health -= p.Damage
  85. r.Hit = true
  86. }
  87. p.Owner.gameStats.Hits++
  88. if r.Health <= 0 {
  89. r.gameStats.Deaths++
  90. if r == p.Owner {
  91. p.Owner.gameStats.Suicides++
  92. } else {
  93. p.Owner.gameStats.Kills++
  94. }
  95. }
  96. }
  97. }
  98. }
  99. } else {
  100. p.Position.X = newPos.X
  101. p.Position.Y = newPos.Y
  102. }
  103. }