refactor: FleetState
This commit is contained in:
@@ -173,7 +173,7 @@ func SingleBattle(c *Cache, b *Battle) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if destroyed {
|
if destroyed {
|
||||||
c.ShipGroupNumber(defIdx, c.ShipGroup(defIdx).Number-1)
|
c.ShipGroupDestroyItem(defIdx)
|
||||||
}
|
}
|
||||||
if c.ShipGroup(defIdx).Number == 0 {
|
if c.ShipGroup(defIdx).Number == 0 {
|
||||||
delete(b.attacker, defIdx) // Eliminated group cant attack anyone
|
delete(b.attacker, defIdx) // Eliminated group cant attack anyone
|
||||||
|
|||||||
@@ -11,42 +11,74 @@ import (
|
|||||||
"github.com/iliadenisov/galaxy/internal/model/game"
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Cache) FleetState(fleetID uuid.UUID) (game.ShipGroupState, *uint, *game.InSpace) {
|
var fleetStateNil = game.ShipGroupState("-")
|
||||||
|
|
||||||
|
type FleetState struct {
|
||||||
|
State game.ShipGroupState
|
||||||
|
Destination uint
|
||||||
|
InSpace func() (game.InSpace, bool)
|
||||||
|
OnPlanet func() (uint, bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FleetState) inSpace() bool {
|
||||||
|
_, ok := fs.InSpace()
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs FleetState) OnSamePlanet(other FleetState) bool {
|
||||||
|
op1, ok := fs.OnPlanet()
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
op2, ok := other.OnPlanet()
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return op1 == op2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) FleetState(fleetID uuid.UUID) FleetState {
|
||||||
fi := c.MustFleetIndex(fleetID)
|
fi := c.MustFleetIndex(fleetID)
|
||||||
ri := c.RaceIndex(c.g.Fleets[fi].OwnerID)
|
ri := c.RaceIndex(c.g.Fleets[fi].OwnerID)
|
||||||
var state *game.ShipGroupState
|
fs := &FleetState{
|
||||||
var onPlanet *uint
|
State: fleetStateNil,
|
||||||
var is *game.InSpace
|
InSpace: func() (game.InSpace, bool) { return game.InSpace{}, false },
|
||||||
|
OnPlanet: func() (uint, bool) { return 0, false },
|
||||||
|
}
|
||||||
for sg := range c.FleetGroups(ri, fi) {
|
for sg := range c.FleetGroups(ri, fi) {
|
||||||
if state == nil {
|
if fs.State == fleetStateNil {
|
||||||
s := sg.State()
|
fs.State = sg.State()
|
||||||
state = &s
|
fs.Destination = sg.Destination
|
||||||
if planet, ok := sg.OnPlanet(); ok {
|
if planet, ok := sg.OnPlanet(); ok {
|
||||||
onPlanet = &planet
|
fs.OnPlanet = func() (uint, bool) { return planet, ok }
|
||||||
|
}
|
||||||
|
if sg.StateInSpace != nil {
|
||||||
|
fs.InSpace = func() (game.InSpace, bool) { return *sg.StateInSpace, true }
|
||||||
}
|
}
|
||||||
is = sg.StateInSpace
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if *state != sg.State() {
|
if fs.State != sg.State() {
|
||||||
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different states", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different states", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
||||||
}
|
}
|
||||||
if planet, ok := sg.OnPlanet(); ok && onPlanet != nil && *onPlanet != planet {
|
if fs.Destination != sg.Destination {
|
||||||
// for sg := range c.FleetGroups(ri, fi) {
|
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different destination", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
||||||
// fmt.Println("group", sg.Index, "fleet", sg.FleetID, c.g.Fleets[fi].Name, "state", sg.State(), "on", sg.Destination)
|
|
||||||
// }
|
|
||||||
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q are on different planets: %d <> %d", c.g.Race[ri].Name, c.g.Fleets[fi].Name, *onPlanet, planet))
|
|
||||||
}
|
}
|
||||||
if (is == nil && sg.StateInSpace != nil) || (is != nil && sg.StateInSpace == nil) {
|
if planet, ok := sg.OnPlanet(); ok {
|
||||||
|
if onPlanet, ok := fs.OnPlanet(); ok && onPlanet != planet {
|
||||||
|
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q are on different planets: %d <> %d", c.g.Race[ri].Name, c.g.Fleets[fi].Name, onPlanet, planet))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!fs.inSpace() && sg.StateInSpace != nil) || (fs.inSpace() && sg.StateInSpace == nil) {
|
||||||
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q on_planet and in_space at the same time", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q on_planet and in_space at the same time", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
||||||
}
|
}
|
||||||
if is != nil && sg.StateInSpace != nil && !is.Equal(*sg.StateInSpace) {
|
if is, ok := fs.InSpace(); ok && sg.StateInSpace != nil && !is.Equal(*sg.StateInSpace) {
|
||||||
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different is_space states", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
panic(fmt.Sprintf("FleetState: one or more ships in race's %q fleet %q has different is_space states", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if state == nil {
|
if fs.State == fleetStateNil {
|
||||||
panic(fmt.Sprintf("FleetState: race's %q fleet %q has no ships", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
panic(fmt.Sprintf("FleetState: race's %q fleet %q has no ships", c.g.Race[ri].Name, c.g.Fleets[fi].Name))
|
||||||
}
|
}
|
||||||
return *state, onPlanet, is
|
return *fs
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Hello! Wanna know fleet's speed? Good. Implement & test this func first.
|
// TODO: Hello! Wanna know fleet's speed? Good. Implement & test this func first.
|
||||||
@@ -109,8 +141,8 @@ func (c *Cache) JoinShipGroupToFleet(ri int, fleetName string, groupIndex, quant
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state, onPlanet, _ := c.FleetState(c.g.Fleets[fi].ID)
|
fleetState := c.FleetState(c.g.Fleets[fi].ID)
|
||||||
if state != game.StateInOrbit || *onPlanet != c.ShipGroup(sgi).Destination {
|
if onPlanet, ok := fleetState.OnPlanet(); (ok && onPlanet != c.ShipGroup(sgi).Destination) || fleetState.State != game.StateInOrbit {
|
||||||
return e.NewShipsNotOnSamePlanetError("fleet: %s", fleetName)
|
return e.NewShipsNotOnSamePlanetError("fleet: %s", fleetName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,11 +196,12 @@ func (c *Cache) JoinFleets(ri int, fleetSourceName, fleetTargetName string) (err
|
|||||||
if !ok {
|
if !ok {
|
||||||
return e.NewEntityNotExistsError("target fleet %s", fleetTargetName)
|
return e.NewEntityNotExistsError("target fleet %s", fleetTargetName)
|
||||||
}
|
}
|
||||||
srcState, planet1, _ := c.FleetState(c.g.Fleets[fiSource].ID)
|
stateSrc := c.FleetState(c.g.Fleets[fiSource].ID)
|
||||||
tgtState, planet2, _ := c.FleetState(c.g.Fleets[fiTarget].ID)
|
stateDst := c.FleetState(c.g.Fleets[fiTarget].ID)
|
||||||
if srcState != game.StateInOrbit || srcState != tgtState || *planet1 != *planet2 {
|
if !stateSrc.OnSamePlanet(stateDst) {
|
||||||
return e.NewShipsNotOnSamePlanetError()
|
return e.NewShipsNotOnSamePlanetError()
|
||||||
}
|
}
|
||||||
|
|
||||||
for sg := range c.listShipGroups(ri) {
|
for sg := range c.listShipGroups(ri) {
|
||||||
if sg.FleetID != nil && *sg.FleetID == c.g.Fleets[fiSource].ID {
|
if sg.FleetID != nil && *sg.FleetID == c.g.Fleets[fiSource].ID {
|
||||||
sg.FleetID = &c.g.Fleets[fiTarget].ID
|
sg.FleetID = &c.g.Fleets[fiTarget].ID
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ func (c *Controller) SendFleet(raceName, fleetName string, planetNumber uint) er
|
|||||||
func (c *Cache) SendFleet(ri, fi int, planetNumber uint) error {
|
func (c *Cache) SendFleet(ri, fi int, planetNumber uint) error {
|
||||||
c.validateRaceIndex(ri)
|
c.validateRaceIndex(ri)
|
||||||
c.validateFleetIndex(fi)
|
c.validateFleetIndex(fi)
|
||||||
state, sourcePlanet, _ := c.FleetState(c.g.Fleets[fi].ID)
|
fleetState := c.FleetState(c.g.Fleets[fi].ID)
|
||||||
if game.StateInOrbit != state && game.StateLaunched != state {
|
sourcePlanet, ok := fleetState.OnPlanet()
|
||||||
|
if !ok || game.StateInOrbit != fleetState.State && game.StateLaunched != fleetState.State {
|
||||||
return e.NewShipsBusyError()
|
return e.NewShipsBusyError()
|
||||||
}
|
}
|
||||||
|
|
||||||
p1, ok := c.Planet(*sourcePlanet)
|
p1, ok := c.Planet(sourcePlanet)
|
||||||
if !ok {
|
if !ok {
|
||||||
return e.NewGameStateError("source planet #%d does not exists", sourcePlanet)
|
return e.NewGameStateError("source planet #%d does not exists", sourcePlanet)
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,7 @@ func (c *Cache) SendFleet(ri, fi int, planetNumber uint) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *sourcePlanet == planetNumber {
|
if sourcePlanet == planetNumber {
|
||||||
c.UnsendFleet(ri, fi)
|
c.UnsendFleet(ri, fi)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,15 +70,15 @@ func TestSendFleet(t *testing.T) {
|
|||||||
e.GenericErrorText(e.ErrSendShipHasNoDrives))
|
e.GenericErrorText(e.ErrSendShipHasNoDrives))
|
||||||
|
|
||||||
assert.NoError(t, g.SendFleet(Race_0.Name, fleetSending, 2))
|
assert.NoError(t, g.SendFleet(Race_0.Name, fleetSending, 2))
|
||||||
state, _, _ := c.FleetState(c.MustFleetID(Race_0_idx, fleetSending))
|
fleetState := c.FleetState(c.MustFleetID(Race_0_idx, fleetSending))
|
||||||
assert.Equal(t, game.StateLaunched, state)
|
assert.Equal(t, game.StateLaunched, fleetState.State)
|
||||||
for sg := range c.FleetGroups(Race_0_idx, c.MustFleetIndex(c.MustFleetID(Race_0_idx, fleetSending))) {
|
for sg := range c.FleetGroups(Race_0_idx, c.MustFleetIndex(c.MustFleetID(Race_0_idx, fleetSending))) {
|
||||||
assert.Equal(t, game.StateLaunched, sg.State())
|
assert.Equal(t, game.StateLaunched, sg.State())
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, g.SendFleet(Race_0.Name, fleetSending, 0))
|
assert.NoError(t, g.SendFleet(Race_0.Name, fleetSending, 0))
|
||||||
state, _, _ = c.FleetState(c.MustFleetID(Race_0_idx, fleetSending))
|
fleetState = c.FleetState(c.MustFleetID(Race_0_idx, fleetSending))
|
||||||
assert.Equal(t, game.StateInOrbit, state)
|
assert.Equal(t, game.StateInOrbit, fleetState.State)
|
||||||
for sg := range c.FleetGroups(Race_0_idx, c.MustFleetIndex(c.MustFleetID(Race_0_idx, fleetSending))) {
|
for sg := range c.FleetGroups(Race_0_idx, c.MustFleetIndex(c.MustFleetID(Race_0_idx, fleetSending))) {
|
||||||
assert.Equal(t, game.StateInOrbit, sg.State())
|
assert.Equal(t, game.StateInOrbit, sg.State())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ func TestJoinShipGroupToFleet(t *testing.T) {
|
|||||||
gi := 0
|
gi := 0
|
||||||
assert.Len(t, fleets, 1)
|
assert.Len(t, fleets, 1)
|
||||||
assert.Equal(t, fleets[0].Name, fleetOne)
|
assert.Equal(t, fleets[0].Name, fleetOne)
|
||||||
state, _, _ := c.FleetState(fleets[0].ID)
|
fleetState := c.FleetState(fleets[0].ID)
|
||||||
assert.Equal(t, game.StateInOrbit, state)
|
assert.Equal(t, game.StateInOrbit, fleetState.State)
|
||||||
|
|
||||||
assert.NotNil(t, groups[gi].FleetID)
|
assert.NotNil(t, groups[gi].FleetID)
|
||||||
assert.Equal(t, fleets[0].ID, *groups[gi].FleetID)
|
assert.Equal(t, fleets[0].ID, *groups[gi].FleetID)
|
||||||
@@ -56,8 +56,8 @@ func TestJoinShipGroupToFleet(t *testing.T) {
|
|||||||
assert.Len(t, groups, 3)
|
assert.Len(t, groups, 3)
|
||||||
assert.Len(t, fleets, 2)
|
assert.Len(t, fleets, 2)
|
||||||
assert.Equal(t, fleets[1].Name, fleetTwo)
|
assert.Equal(t, fleets[1].Name, fleetTwo)
|
||||||
state, _, _ = c.FleetState(fleets[1].ID)
|
fleetState = c.FleetState(fleets[1].ID)
|
||||||
assert.Equal(t, game.StateInOrbit, state)
|
assert.Equal(t, game.StateInOrbit, fleetState.State)
|
||||||
|
|
||||||
gi = 2
|
gi = 2
|
||||||
assert.Len(t, groups, 3)
|
assert.Len(t, groups, 3)
|
||||||
@@ -78,8 +78,8 @@ func TestJoinShipGroupToFleet(t *testing.T) {
|
|||||||
groups = slices.Collect(c.RaceShipGroups(Race_0_idx))
|
groups = slices.Collect(c.RaceShipGroups(Race_0_idx))
|
||||||
assert.NotNil(t, groups[gi].FleetID)
|
assert.NotNil(t, groups[gi].FleetID)
|
||||||
assert.Equal(t, fleets[0].ID, *groups[gi].FleetID)
|
assert.Equal(t, fleets[0].ID, *groups[gi].FleetID)
|
||||||
state, _, _ = c.FleetState(fleets[0].ID)
|
fleetState = c.FleetState(fleets[0].ID)
|
||||||
assert.Equal(t, game.StateInOrbit, state)
|
assert.Equal(t, game.StateInOrbit, fleetState.State)
|
||||||
|
|
||||||
// group not In_Orbit
|
// group not In_Orbit
|
||||||
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 7))
|
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 7))
|
||||||
|
|||||||
@@ -585,15 +585,15 @@ func (c *Cache) ReportLocalFleet(ri int, rep *mr.Report) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
speed, _ := c.FleetSpeedAndMass(fi)
|
speed, _ := c.FleetSpeedAndMass(fi)
|
||||||
state, _, inSpace := c.FleetState(fl.ID)
|
fleetState := c.FleetState(fl.ID)
|
||||||
|
|
||||||
sliceIndexValidate(&rep.LocalFleet, i)
|
sliceIndexValidate(&rep.LocalFleet, i)
|
||||||
rep.LocalFleet[i].Name = fl.Name
|
rep.LocalFleet[i].Name = fl.Name
|
||||||
rep.LocalFleet[i].Groups = uint(len(gid))
|
rep.LocalFleet[i].Groups = uint(len(gid))
|
||||||
rep.LocalFleet[i].Speed = mr.F(speed)
|
rep.LocalFleet[i].Speed = mr.F(speed)
|
||||||
rep.LocalFleet[i].State = state.String()
|
rep.LocalFleet[i].State = fleetState.State.String()
|
||||||
rep.LocalFleet[i].Destination = c.ShipGroup(gid[0]).Destination // FIXME: get fleet destination with some nicer way
|
rep.LocalFleet[i].Destination = fleetState.Destination
|
||||||
if inSpace != nil {
|
if inSpace, ok := fleetState.InSpace(); ok {
|
||||||
rep.LocalFleet[i].Origin = &inSpace.Origin
|
rep.LocalFleet[i].Origin = &inSpace.Origin
|
||||||
p2 := c.MustPlanet(rep.LocalFleet[i].Destination)
|
p2 := c.MustPlanet(rep.LocalFleet[i].Destination)
|
||||||
rangeToDestination := mr.F(util.ShortDistance(c.g.Map.Width, c.g.Map.Height, inSpace.X.F(), inSpace.Y.F(), p2.X.F(), p2.Y.F()))
|
rangeToDestination := mr.F(util.ShortDistance(c.g.Map.Width, c.g.Map.Height, inSpace.X.F(), inSpace.Y.F(), p2.X.F(), p2.Y.F()))
|
||||||
|
|||||||
Reference in New Issue
Block a user