package controller import ( "galaxy/calc" e "galaxy/error" "galaxy/game/internal/model/game" "github.com/google/uuid" ) func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber uint) error { c.validateRaceIndex(ri) sgi, ok := c.raceShipGroupIndex(ri, groupID) if !ok { return e.NewEntityNotExistsError("group %s", groupID) } st := c.ShipGroupShipClass(sgi) pcount := 0 for i := range c.g.Map.Planet { if c.g.Map.Planet[i].OwnedBy(c.g.Race[ri].ID) { pcount++ break } } if pcount == 0 { return e.NewSendShipOwnerHasNoPlanetsError() } if st.DriveBlockMass() == 0 { return e.NewSendShipHasNoDrivesError() } sourcePlanet, ok := c.ShipGroup(sgi).AtPlanet() if !ok { return e.NewShipsBusyError("state: %s", c.ShipGroup(sgi).State()) } p1, ok := c.Planet(sourcePlanet) if !ok { return e.NewGameStateError("source planet #%d does not exists", sourcePlanet) } p2, ok := c.Planet(planetNumber) if !ok { return e.NewEntityNotExistsError("destination planet #%d", planetNumber) } rangeToDestination := calc.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X.F(), p1.Y.F(), p2.X.F(), p2.Y.F()) if rangeToDestination > c.g.Race[ri].FlightDistance() { return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination) } if p1.Number == p2.Number { c.UnsendShips(sgi) c.shipGroupMerge(ri) return nil } c.LaunchShips(sgi, planetNumber) return nil } func (c *Cache) LaunchShips(sgi int, destination uint) *game.ShipGroup { sg := c.ShipGroup(sgi) var p *game.Planet switch sg.State() { case game.StateInOrbit: p = c.MustPlanet(sg.Destination) case game.StateLaunched: p = c.MustPlanet(sg.StateInSpace.Origin) default: panic("state invalid") } c.g.ShipGroups[sgi] = LaunchShips(*sg, destination, p.X.F(), p.Y.F()) return &c.g.ShipGroups[sgi] } func (c *Cache) UnsendShips(sgi int) *game.ShipGroup { sg := c.ShipGroup(sgi) if sg.State() != game.StateLaunched { panic("state invalid") } c.g.ShipGroups[sgi] = UnsendShips(*sg) return &c.g.ShipGroups[sgi] } func LaunchShips(sg game.ShipGroup, destination uint, originX, originY float64) game.ShipGroup { sg.StateInSpace = &game.InSpace{ Origin: sg.Destination, X: nil, Y: nil, } sg.Destination = destination return sg } func UnsendShips(sg game.ShipGroup) game.ShipGroup { sg.Destination = sg.StateInSpace.Origin sg.StateInSpace = nil return sg }