No Description
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.

projectile.go 2.6KB

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