120 lines
3.1 KiB
Go
120 lines
3.1 KiB
Go
package controller
|
|
|
|
import (
|
|
e "github.com/iliadenisov/galaxy/internal/error"
|
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
|
"github.com/iliadenisov/galaxy/internal/util"
|
|
)
|
|
|
|
func (c *Controller) SendGroup(raceName string, groupIndex, planetNumber, quantity uint) error {
|
|
ri, err := c.Cache.raceIndex(raceName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return c.Cache.SendGroup(ri, groupIndex, planetNumber, quantity)
|
|
}
|
|
|
|
func (c *Cache) SendGroup(ri int, groupIndex, planetNumber, quantity uint) error {
|
|
c.validateRaceIndex(ri)
|
|
|
|
sgi, ok := c.raceShipGroupIndex(ri, groupIndex)
|
|
if !ok {
|
|
return e.NewEntityNotExistsError("group #%d", groupIndex)
|
|
}
|
|
st := c.ShipGroupShipClass(sgi)
|
|
|
|
if st.DriveBlockMass() == 0 {
|
|
return e.NewSendShipHasNoDrivesError()
|
|
}
|
|
|
|
sourcePlanet, ok := c.ShipGroup(sgi).OnPlanet()
|
|
if !ok {
|
|
return e.NewShipsBusyError()
|
|
}
|
|
|
|
if c.ShipGroup(sgi).Number < quantity {
|
|
return e.NewBeakGroupNumberNotEnoughError("%d<%d", c.ShipGroup(sgi).Number, quantity)
|
|
}
|
|
|
|
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 := util.ShortDistance(c.g.Map.Width, c.g.Map.Height, p1.X, p1.Y, p2.X, p2.Y)
|
|
if rangeToDestination > c.g.Race[ri].FlightDistance() {
|
|
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
|
|
}
|
|
|
|
if quantity > 0 && quantity < c.ShipGroup(sgi).Number {
|
|
nsgi, err := c.breakGroupSafe(ri, groupIndex, quantity)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sgi = nsgi
|
|
}
|
|
|
|
if p1.Number == p2.Number {
|
|
c.UnsendShips(c.ShipGroup(sgi))
|
|
c.JoinEqualGroups(ri)
|
|
return nil
|
|
}
|
|
|
|
c.LaunchShips(c.ShipGroup(sgi), planetNumber)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Cache) LaunchShips(sg *game.ShipGroup, destination uint) *game.ShipGroup {
|
|
for i := range c.ShipGroupsIndex() {
|
|
if c.ShipGroup(i).OwnerID == sg.OwnerID && c.ShipGroup(i).Index == sg.Index {
|
|
state := c.ShipGroup(i).State()
|
|
var p *game.Planet
|
|
switch 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[i] = LaunchShips(*sg, destination, p.X, p.Y)
|
|
return &c.g.ShipGroups[i]
|
|
}
|
|
}
|
|
panic("ship group not found")
|
|
}
|
|
|
|
func (c *Cache) UnsendShips(sg *game.ShipGroup) *game.ShipGroup {
|
|
for i := range c.ShipGroupsIndex() {
|
|
if c.ShipGroup(i).OwnerID == sg.OwnerID && c.ShipGroup(i).Index == sg.Index {
|
|
state := c.ShipGroup(i).State()
|
|
if state != game.StateLaunched {
|
|
panic("state invalid")
|
|
}
|
|
c.g.ShipGroups[i] = UnsendShips(*sg)
|
|
return &c.g.ShipGroups[i]
|
|
}
|
|
}
|
|
panic("ship group not found")
|
|
}
|
|
|
|
func LaunchShips(sg game.ShipGroup, destination uint, originX, originY float64) game.ShipGroup {
|
|
sg.StateInSpace = &game.InSpace{
|
|
Origin: sg.Destination,
|
|
X: originX,
|
|
Y: originY,
|
|
}
|
|
sg.Destination = destination
|
|
return sg
|
|
}
|
|
|
|
func UnsendShips(sg game.ShipGroup) game.ShipGroup {
|
|
sg.Destination = sg.StateInSpace.Origin
|
|
sg.StateInSpace = nil
|
|
return sg
|
|
}
|