123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- package main
- import "fmt"
- type Ship struct {
- node *Node // Node pointer, for Update
- Model string
- Name string
- Sprite Sprite // TODO: Make this a struct
- Thumbnail string
- UUID string // We should not allow this to be changed (it might be significant to Endless Sky)
- Attributes Attributes
- Outfits OutfitList
- Crew int
- Fuel int
- Shields int
- Hull int
- Pos Vec2
- Engines []Engine
- Guns []Gun
- Turrets []Turret
- Leak []string // TODO: Make this a struct
- Explode []string // TODO: Make this a struct
- Location Location
- }
- func (s *Ship) Type() string {
- return "Ship"
- }
- func (s *Ship) Parse(node *Node) error {
- if node.Key() != "ship" {
- return fmt.Errorf("expected 'ship' node, invalid node")
- }
- s.node = node
- s.Model = node.Value()
- s.Attributes = Attributes{
- Others: make(map[string]float64),
- }
- s.Engines = []Engine{}
- s.Guns = []Gun{}
- s.Turrets = []Turret{}
- s.Outfits = OutfitList{}
- for _, kid := range node.Children {
- switch kid.Key() {
- case "name":
- s.Name = kid.Value()
- case "sprite":
- err := s.Sprite.Parse(kid)
- if err != nil {
- return err
- }
- case "thumbnail":
- s.Thumbnail = kid.Value()
- case "uuid":
- s.UUID = kid.Value()
- case "attributes":
- err := s.Attributes.Parse(kid)
- if err != nil {
- return err
- }
- case "outfits":
- err := s.Outfits.Parse(kid)
- if err != nil {
- return err
- }
- case "crew":
- s.Crew = kid.ValueInt()
- case "fuel":
- s.Fuel = kid.ValueInt()
- case "shields":
- s.Shields = kid.ValueInt()
- case "hull":
- s.Hull = kid.ValueInt()
- case "position":
- err := s.Pos.Parse(kid.Value())
- if err != nil {
- return err
- }
- case "engine":
- e := Engine{}
- err := e.Parse(kid)
- if err != nil {
- return err
- }
- s.Engines = append(s.Engines, e)
- case "gun":
- g := Gun{}
- err := g.Parse(kid)
- if err != nil {
- return err
- }
- s.Guns = append(s.Guns, g)
- case "turret":
- t := Turret{}
- err := t.Parse(kid)
- if err != nil {
- return err
- }
- s.Turrets = append(s.Turrets, t)
- case "leak":
- s.Leak = append(s.Leak, kid.Value())
- case "explode":
- s.Explode = append(s.Explode, kid.Value())
- case "system":
- if s.Location.System == "" {
- s.Location.Parse(kid)
- }
- case "planet":
- if s.Location.Planet == "" {
- s.Location.Parse(kid)
- }
- }
- }
- return nil
- }
- func (s *Ship) Update() error {
- if s.node == nil {
- return fmt.Errorf("no node, ship")
- }
- s.node.SetValue(s.Model)
- err := s.Location.Update()
- if err != nil {
- return fmt.Errorf("ship, %v", err)
- }
- for _, kid := range s.node.Children {
- switch kid.Key() {
- case "name":
- kid.SetValue(s.Name)
- case "sprite":
- err := s.Sprite.Update()
- if err != nil {
- return err
- }
- case "thumbnail":
- kid.SetValue(s.Thumbnail)
- case "attributes":
- err := s.Attributes.Update()
- if err != nil {
- return err
- }
- case "outfits":
- err := s.Outfits.Update()
- if err != nil {
- return err
- }
- case "crew":
- kid.SetValue(s.Crew)
- case "fuel":
- kid.SetValue(s.Fuel)
- case "shields":
- kid.SetValue(s.Shields)
- case "hull":
- kid.SetValue(s.Hull)
- case "position":
- kid.SetValue(s.Pos.String())
- case "engine":
- _, err := kid.DetachFromParent()
- if err != nil {
- return err
- }
- case "gun":
- _, err := kid.DetachFromParent()
- if err != nil {
- return err
- }
- case "turret":
- _, err := kid.DetachFromParent()
- if err != nil {
- return err
- }
- }
- }
- for _, e := range s.Engines {
- n := s.node.NewChild()
- n.Set(e.Kind, e.Pos.String())
- n1 := n.NewChild()
- n1.Set("zoom", e.Zoom)
- n1 = n.NewChild()
- n1.Set("angle", e.Angle)
- if e.Over {
- n1 = n.NewChild()
- n1.Line = "over"
- } else {
- n1 = n.NewChild()
- n1.Line = "under"
- }
- }
- for _, g := range s.Guns {
- n := s.node.NewChild()
- if g.Mount != "" {
- n.Set("gun", fmt.Sprintf("%s %s", g.Pos.String(), g.Mount))
- } else {
- n.Set("gun", g.Pos.String())
- }
- if g.Over {
- n1 := n.NewChild()
- n1.Line = "over"
- } else {
- n1 := n.NewChild()
- n1.Line = "under"
- }
- }
- for _, t := range s.Turrets {
- n := s.node.NewChild()
- if t.Mount != "" {
- n.Set("turret", fmt.Sprintf("%s %s", t.Pos.String(), t.Mount))
- } else {
- n.Set("turret", t.Pos.String())
- }
- if t.Over {
- n1 := n.NewChild()
- n1.Line = "over"
- } else {
- n1 := n.NewChild()
- n1.Line = "under"
- }
- }
- return nil
- }
|