ship.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package main
  2. import "fmt"
  3. type Ship struct {
  4. node *Node // Node pointer, for Update
  5. Model string
  6. Name string
  7. Sprite Sprite // TODO: Make this a struct
  8. Thumbnail string
  9. UUID string // We should not allow this to be changed (it might be significant to Endless Sky)
  10. Attributes Attributes
  11. Outfits OutfitList
  12. Crew int
  13. Fuel int
  14. Shields int
  15. Hull int
  16. Pos Vec2
  17. Engines []Engine
  18. Guns []Gun
  19. Turrets []Turret
  20. Leak []string // TODO: Make this a struct
  21. Explode []string // TODO: Make this a struct
  22. Location Location
  23. }
  24. func (s *Ship) Type() string {
  25. return "Ship"
  26. }
  27. func (s *Ship) Parse(node *Node) error {
  28. if node.Key() != "ship" {
  29. return fmt.Errorf("expected 'ship' node, invalid node")
  30. }
  31. s.node = node
  32. s.Model = node.Value()
  33. s.Attributes = Attributes{
  34. Others: make(map[string]float64),
  35. }
  36. s.Engines = []Engine{}
  37. s.Guns = []Gun{}
  38. s.Turrets = []Turret{}
  39. s.Outfits = OutfitList{}
  40. for _, kid := range node.Children {
  41. switch kid.Key() {
  42. case "name":
  43. s.Name = kid.Value()
  44. case "sprite":
  45. err := s.Sprite.Parse(kid)
  46. if err != nil {
  47. return err
  48. }
  49. case "thumbnail":
  50. s.Thumbnail = kid.Value()
  51. case "uuid":
  52. s.UUID = kid.Value()
  53. case "attributes":
  54. err := s.Attributes.Parse(kid)
  55. if err != nil {
  56. return err
  57. }
  58. case "outfits":
  59. err := s.Outfits.Parse(kid)
  60. if err != nil {
  61. return err
  62. }
  63. case "crew":
  64. s.Crew = kid.ValueInt()
  65. case "fuel":
  66. s.Fuel = kid.ValueInt()
  67. case "shields":
  68. s.Shields = kid.ValueInt()
  69. case "hull":
  70. s.Hull = kid.ValueInt()
  71. case "position":
  72. err := s.Pos.Parse(kid.Value())
  73. if err != nil {
  74. return err
  75. }
  76. case "engine":
  77. e := Engine{}
  78. err := e.Parse(kid)
  79. if err != nil {
  80. return err
  81. }
  82. s.Engines = append(s.Engines, e)
  83. case "gun":
  84. g := Gun{}
  85. err := g.Parse(kid)
  86. if err != nil {
  87. return err
  88. }
  89. s.Guns = append(s.Guns, g)
  90. case "turret":
  91. t := Turret{}
  92. err := t.Parse(kid)
  93. if err != nil {
  94. return err
  95. }
  96. s.Turrets = append(s.Turrets, t)
  97. case "leak":
  98. s.Leak = append(s.Leak, kid.Value())
  99. case "explode":
  100. s.Explode = append(s.Explode, kid.Value())
  101. case "system":
  102. if s.Location.System == "" {
  103. s.Location.Parse(kid)
  104. }
  105. case "planet":
  106. if s.Location.Planet == "" {
  107. s.Location.Parse(kid)
  108. }
  109. }
  110. }
  111. return nil
  112. }
  113. func (s *Ship) Update() error {
  114. if s.node == nil {
  115. return fmt.Errorf("no node, ship")
  116. }
  117. s.node.SetValue(s.Model)
  118. err := s.Location.Update()
  119. if err != nil {
  120. return fmt.Errorf("ship, %v", err)
  121. }
  122. for _, kid := range s.node.Children {
  123. switch kid.Key() {
  124. case "name":
  125. kid.SetValue(s.Name)
  126. case "sprite":
  127. err := s.Sprite.Update()
  128. if err != nil {
  129. return err
  130. }
  131. case "thumbnail":
  132. kid.SetValue(s.Thumbnail)
  133. case "attributes":
  134. err := s.Attributes.Update()
  135. if err != nil {
  136. return err
  137. }
  138. case "outfits":
  139. err := s.Outfits.Update()
  140. if err != nil {
  141. return err
  142. }
  143. case "crew":
  144. kid.SetValue(s.Crew)
  145. case "fuel":
  146. kid.SetValue(s.Fuel)
  147. case "shields":
  148. kid.SetValue(s.Shields)
  149. case "hull":
  150. kid.SetValue(s.Hull)
  151. case "position":
  152. kid.SetValue(s.Pos.String())
  153. case "engine":
  154. _, err := kid.DetachFromParent()
  155. if err != nil {
  156. return err
  157. }
  158. case "gun":
  159. _, err := kid.DetachFromParent()
  160. if err != nil {
  161. return err
  162. }
  163. case "turret":
  164. _, err := kid.DetachFromParent()
  165. if err != nil {
  166. return err
  167. }
  168. }
  169. }
  170. for _, e := range s.Engines {
  171. n := s.node.NewChild()
  172. n.Set(e.Kind, e.Pos.String())
  173. n1 := n.NewChild()
  174. n1.Set("zoom", e.Zoom)
  175. n1 = n.NewChild()
  176. n1.Set("angle", e.Angle)
  177. if e.Over {
  178. n1 = n.NewChild()
  179. n1.Line = "over"
  180. } else {
  181. n1 = n.NewChild()
  182. n1.Line = "under"
  183. }
  184. }
  185. for _, g := range s.Guns {
  186. n := s.node.NewChild()
  187. if g.Mount != "" {
  188. n.Set("gun", fmt.Sprintf("%s %s", g.Pos.String(), g.Mount))
  189. } else {
  190. n.Set("gun", g.Pos.String())
  191. }
  192. if g.Over {
  193. n1 := n.NewChild()
  194. n1.Line = "over"
  195. } else {
  196. n1 := n.NewChild()
  197. n1.Line = "under"
  198. }
  199. }
  200. for _, t := range s.Turrets {
  201. n := s.node.NewChild()
  202. if t.Mount != "" {
  203. n.Set("turret", fmt.Sprintf("%s %s", t.Pos.String(), t.Mount))
  204. } else {
  205. n.Set("turret", t.Pos.String())
  206. }
  207. if t.Over {
  208. n1 := n.NewChild()
  209. n1.Line = "over"
  210. } else {
  211. n1 := n.NewChild()
  212. n1.Line = "under"
  213. }
  214. }
  215. return nil
  216. }