feat: remove instant group breaking

This commit is contained in:
Ilia Denisov
2026-02-11 09:35:33 +02:00
parent 1515bc8599
commit 6e84cc3c51
17 changed files with 223 additions and 403 deletions
+16 -16
View File
@@ -78,7 +78,7 @@ func (c *Controller) ShipClassRemove(actor, typeName string) error {
return c.Cache.shipClassRemove(ri, typeName) return c.Cache.shipClassRemove(ri, typeName)
} }
func (c *Controller) ShipGroupLoad(actor string, groupID uuid.UUID, cargoType string, ships uint, quantity float64) error { func (c *Controller) ShipGroupLoad(actor string, groupID uuid.UUID, cargoType string, quantity float64) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
@@ -87,31 +87,31 @@ func (c *Controller) ShipGroupLoad(actor string, groupID uuid.UUID, cargoType st
if !ok { if !ok {
return e.NewCargoTypeInvalidError(cargoType) return e.NewCargoTypeInvalidError(cargoType)
} }
return c.Cache.shipGroupLoad(ri, groupID, ct, ships, quantity) return c.Cache.shipGroupLoad(ri, groupID, ct, quantity)
} }
func (c *Controller) ShipGroupUnload(actor string, groupID uuid.UUID, ships uint, quantity float64) error { func (c *Controller) ShipGroupUnload(actor string, groupID uuid.UUID, quantity float64) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.shipGroupUnload(ri, groupID, ships, quantity) return c.Cache.shipGroupUnload(ri, groupID, quantity)
} }
func (c *Controller) ShipGroupSend(actor string, groupID uuid.UUID, planetNumber, quantity uint) error { func (c *Controller) ShipGroupSend(actor string, groupID uuid.UUID, planetNumber uint) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.shipGroupSend(ri, groupID, planetNumber, quantity) return c.Cache.shipGroupSend(ri, groupID, planetNumber)
} }
func (c *Controller) ShipGroupUpgrade(actor string, groupID uuid.UUID, techInput string, limitShips uint, limitLevel float64) error { func (c *Controller) ShipGroupUpgrade(actor string, groupID uuid.UUID, techInput string, limitLevel float64) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.shipGroupUpgrade(ri, groupID, techInput, limitShips, limitLevel) return c.Cache.shipGroupUpgrade(ri, groupID, techInput, limitLevel)
} }
func (c *Controller) ShipGroupMerge(actor string) error { func (c *Controller) ShipGroupMerge(actor string) error {
@@ -123,23 +123,23 @@ func (c *Controller) ShipGroupMerge(actor string) error {
return nil return nil
} }
func (c *Controller) ShipGroupBreak(actor string, groupID uuid.UUID, quantity uint) error { func (c *Controller) ShipGroupBreak(actor string, groupID, newID uuid.UUID, quantity uint) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.ShipGroupBreak(ri, groupID, quantity) return c.Cache.ShipGroupBreak(ri, groupID, newID, quantity)
} }
func (c *Controller) ShipGroupDismantle(actor string, groupID uuid.UUID, quantity uint) error { func (c *Controller) ShipGroupDismantle(actor string, groupID uuid.UUID) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.shipGroupDismantle(ri, groupID, quantity) return c.Cache.shipGroupDismantle(ri, groupID)
} }
func (c *Controller) ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID, quantity uint) error { func (c *Controller) ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
@@ -148,15 +148,15 @@ func (c *Controller) ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID
if err != nil { if err != nil {
return err return err
} }
return c.Cache.shipGroupTransfer(ri, riAccept, groupID, quantity) return c.Cache.shipGroupTransfer(ri, riAccept, groupID)
} }
func (c *Controller) ShipGroupJoinFleet(actor, fleetName string, groupID uuid.UUID, quantity uint) error { func (c *Controller) ShipGroupJoinFleet(actor, fleetName string, groupID uuid.UUID) error {
ri, err := c.Cache.validActor(actor) ri, err := c.Cache.validActor(actor)
if err != nil { if err != nil {
return err return err
} }
return c.Cache.ShipGroupJoinFleet(ri, fleetName, groupID, quantity) return c.Cache.ShipGroupJoinFleet(ri, fleetName, groupID)
} }
func (c *Controller) FleetMerge(actor, fleetSourceName, fleetTargetName string) error { func (c *Controller) FleetMerge(actor, fleetSourceName, fleetTargetName string) error {
+8 -8
View File
@@ -51,15 +51,15 @@ type Ctrl interface {
ShipClassCreate(actor, typeName string, drive float64, ammo int, weapons, shileds, cargo float64) error ShipClassCreate(actor, typeName string, drive float64, ammo int, weapons, shileds, cargo float64) error
ShipClassMerge(actor, name, targetName string) error ShipClassMerge(actor, name, targetName string) error
ShipClassRemove(actor, typeName string) error ShipClassRemove(actor, typeName string) error
ShipGroupLoad(actor string, groupID uuid.UUID, cargoType string, ships uint, quantity float64) error ShipGroupLoad(actor string, groupID uuid.UUID, cargoType string, quantity float64) error
ShipGroupUnload(actor string, groupID uuid.UUID, ships uint, quantity float64) error ShipGroupUnload(actor string, groupID uuid.UUID, quantity float64) error
ShipGroupSend(actor string, groupID uuid.UUID, planetNumber, quantity uint) error ShipGroupSend(actor string, groupID uuid.UUID, planetNumber uint) error
ShipGroupUpgrade(actor string, groupID uuid.UUID, techInput string, limitShips uint, limitLevel float64) error ShipGroupUpgrade(actor string, groupID uuid.UUID, techInput string, limitLevel float64) error
ShipGroupBreak(actor string, groupID uuid.UUID, quantity uint) error ShipGroupBreak(actor string, groupID, newID uuid.UUID, quantity uint) error
ShipGroupMerge(actor string) error ShipGroupMerge(actor string) error
ShipGroupDismantle(actor string, groupID uuid.UUID, quantity uint) error ShipGroupDismantle(actor string, groupID uuid.UUID) error
ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID, quantity uint) error ShipGroupTransfer(actor, acceptor string, groupID uuid.UUID) error
ShipGroupJoinFleet(actor, fleetName string, groupID uuid.UUID, count uint) error ShipGroupJoinFleet(actor, fleetName string, groupID uuid.UUID) error
FleetMerge(actor, fleetSourceName, fleetTargetName string) error FleetMerge(actor, fleetSourceName, fleetTargetName string) error
FleetSend(actor, fleetName string, planetNumber uint) error FleetSend(actor, fleetName string, planetNumber uint) error
ScienceCreate(actor, typeName string, drive, weapons, shields, cargo float64) error ScienceCreate(actor, typeName string, drive, weapons, shields, cargo float64) error
+1 -13
View File
@@ -101,7 +101,7 @@ func (c *Cache) FleetSpeedAndMass(fi int) (float64, float64) {
return speed, mass return speed, mass
} }
func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID, quantity uint) (err error) { func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID) (err error) {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
name, ok := util.ValidateTypeName(fleetName) name, ok := util.ValidateTypeName(fleetName)
if !ok { if !ok {
@@ -116,10 +116,6 @@ func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID,
return e.NewShipsBusyError("state: %s", state) return e.NewShipsBusyError("state: %s", state)
} }
if c.ShipGroup(sgi).Number < quantity {
return e.NewJoinFleetGroupNumberNotEnoughError("%d<%d", c.ShipGroup(sgi).Number, quantity)
}
var oldFleetID *uuid.UUID var oldFleetID *uuid.UUID
if c.ShipGroup(sgi).FleetID != nil { if c.ShipGroup(sgi).FleetID != nil {
fID := *c.ShipGroup(sgi).FleetID fID := *c.ShipGroup(sgi).FleetID
@@ -139,14 +135,6 @@ func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID,
} }
} }
if quantity > 0 && quantity < c.ShipGroup(sgi).Number {
nsgi, err := c.breakGroup(ri, groupID, quantity)
if err != nil {
return err
}
sgi = nsgi
}
c.internalShipGroupJoinFleet(sgi, &c.g.Fleets[fi].ID) c.internalShipGroupJoinFleet(sgi, &c.g.Fleets[fi].ID)
if oldFleetID != nil { if oldFleetID != nil {
+6 -6
View File
@@ -29,22 +29,22 @@ func TestFleetSend(t *testing.T) {
fleetUnmovable := "R0_Fleet_unmovable" fleetUnmovable := "R0_Fleet_unmovable"
fleetUnmovable2 := "R0_Fleet_unmovable2" fleetUnmovable2 := "R0_Fleet_unmovable2"
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSending, c.ShipGroup(0).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSending, c.ShipGroup(0).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSending, c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSending, c.ShipGroup(2).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetInSpace, c.ShipGroup(1).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetInSpace, c.ShipGroup(1).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 2) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 2)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable, c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable, c.ShipGroup(2).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 3) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 3)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable2, c.ShipGroup(3).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable2, c.ShipGroup(3).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 4)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable, c.ShipGroup(3).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetUnmovable, c.ShipGroup(3).ID))
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 3) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 3)
// group #2 - in_space // group #2 - in_space
+25 -33
View File
@@ -19,11 +19,11 @@ func TestShipGroupJoinFleet(t *testing.T) {
fleetTwo := "R0_Fleet_two" fleetTwo := "R0_Fleet_two"
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_0.Name, BadEntityName, groupIndex, 0), g.ShipGroupJoinFleet(Race_0.Name, BadEntityName, groupIndex),
e.GenericErrorText(e.ErrInputEntityTypeNameInvalid)) e.GenericErrorText(e.ErrInputEntityTypeNameInvalid))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_0.Name, "Unnamed", groupIndex, 0), g.ShipGroupJoinFleet(Race_0.Name, "Unnamed", groupIndex),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
// creating ShipGroup // creating ShipGroup
@@ -31,20 +31,16 @@ func TestShipGroupJoinFleet(t *testing.T) {
groupIndex = c.ShipGroup(0).ID groupIndex = c.ShipGroup(0).ID
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(UnknownRace, fleetOne, groupIndex, 0), g.ShipGroupJoinFleet(UnknownRace, fleetOne, groupIndex),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_Extinct.Name, fleetOne, groupIndex, 0), g.ShipGroupJoinFleet(Race_Extinct.Name, fleetOne, groupIndex),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_0.Name, "Unnamed", groupIndex, 6),
e.GenericErrorText(e.ErrJoinFleetGroupNumberNotEnough))
// ensure race has no Fleets // ensure race has no Fleets
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 0) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 0)
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOne, groupIndex, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOne, groupIndex))
fleets := slices.Collect(c.ListFleets(Race_0_idx)) fleets := slices.Collect(c.ListFleets(Race_0_idx))
groups := slices.Collect(c.RaceShipGroups(Race_0_idx)) groups := slices.Collect(c.RaceShipGroups(Race_0_idx))
assert.Len(t, groups, 1) assert.Len(t, groups, 1)
@@ -60,29 +56,25 @@ func TestShipGroupJoinFleet(t *testing.T) {
// create another ShipGroup // create another ShipGroup
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 3)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 3))
groupIndex = c.ShipGroup(1).ID groupIndex = c.ShipGroup(1).ID
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetTwo, groupIndex, 2)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetTwo, groupIndex))
fleets = slices.Collect(c.ListFleets(Race_0_idx)) fleets = slices.Collect(c.ListFleets(Race_0_idx))
groups = slices.Collect(c.RaceShipGroups(Race_0_idx)) groups = slices.Collect(c.RaceShipGroups(Race_0_idx))
assert.Len(t, groups, 3) assert.Len(t, groups, 2)
assert.Len(t, fleets, 2) assert.Len(t, fleets, 2)
assert.Equal(t, fleets[1].Name, fleetTwo) assert.Equal(t, fleets[1].Name, fleetTwo)
fleetState = c.FleetState(fleets[1].ID) fleetState = c.FleetState(fleets[1].ID)
assert.Equal(t, game.StateInOrbit, fleetState.State) assert.Equal(t, game.StateInOrbit, fleetState.State)
gi = 2 gi = 1
assert.Len(t, groups, 3) assert.Len(t, groups, 2)
assert.NotNil(t, groups[gi].FleetID) assert.NotNil(t, groups[gi].FleetID)
assert.Equal(t, fleets[1].ID, *groups[gi].FleetID) assert.Equal(t, fleets[1].ID, *groups[gi].FleetID)
assert.Equal(t, uint(2), groups[gi].Number) assert.Equal(t, uint(3), groups[gi].Number)
gi = 1
assert.Nil(t, groups[gi].FleetID)
assert.Equal(t, uint(1), groups[gi].Number)
groupIndex = groups[gi].ID groupIndex = groups[gi].ID
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOne, groupIndex, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOne, groupIndex))
fleets = slices.Collect(c.ListFleets(Race_0_idx)) fleets = slices.Collect(c.ListFleets(Race_0_idx))
assert.Len(t, fleets, 2) assert.Len(t, fleets, 1)
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)
@@ -91,10 +83,10 @@ func TestShipGroupJoinFleet(t *testing.T) {
// 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))
gi = 3 gi = 2
c.ShipGroup(gi).StateInSpace = &InSpace c.ShipGroup(gi).StateInSpace = &InSpace
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_0.Name, fleetOne, c.ShipGroup(gi).ID, 0), g.ShipGroupJoinFleet(Race_0.Name, fleetOne, c.ShipGroup(gi).ID),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
c.ShipGroup(gi).StateInSpace = nil c.ShipGroup(gi).StateInSpace = nil
@@ -102,7 +94,7 @@ func TestShipGroupJoinFleet(t *testing.T) {
c.ShipGroup(0).StateInSpace = &InSpace c.ShipGroup(0).StateInSpace = &InSpace
c.ShipGroup(1).StateInSpace = c.ShipGroup(0).StateInSpace c.ShipGroup(1).StateInSpace = c.ShipGroup(0).StateInSpace
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_0.Name, fleetOne, c.ShipGroup(gi).ID, 0), g.ShipGroupJoinFleet(Race_0.Name, fleetOne, c.ShipGroup(gi).ID),
e.GenericErrorText(e.ErrShipsNotOnSamePlanet)) e.GenericErrorText(e.ErrShipsNotOnSamePlanet))
} }
@@ -133,21 +125,21 @@ func TestFleetMerge(t *testing.T) {
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(UnknownRace, fleetSourceOne, c.ShipGroup(0).ID, 0), g.ShipGroupJoinFleet(UnknownRace, fleetSourceOne, c.ShipGroup(0).ID),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupJoinFleet(Race_Extinct.Name, fleetSourceOne, c.ShipGroup(0).ID, 0), g.ShipGroupJoinFleet(Race_Extinct.Name, fleetSourceOne, c.ShipGroup(0).ID),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSourceOne, c.ShipGroup(0).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetSourceOne, c.ShipGroup(0).ID))
assert.ErrorContains(t, assert.ErrorContains(t,
g.FleetMerge(Race_0.Name, fleetSourceOne, fleetTargetTwo), g.FleetMerge(Race_0.Name, fleetSourceOne, fleetTargetTwo),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetTargetTwo, c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetTargetTwo, c.ShipGroup(2).ID))
assert.NoError(t, g.FleetMerge(Race_0.Name, fleetSourceOne, fleetTargetTwo)) assert.NoError(t, g.FleetMerge(Race_0.Name, fleetSourceOne, fleetTargetTwo))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOnPlanet2, c.ShipGroup(1).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleetOnPlanet2, c.ShipGroup(1).ID))
assert.ErrorContains(t, assert.ErrorContains(t,
g.FleetMerge(Race_0.Name, fleetOnPlanet2, fleetTargetTwo), g.FleetMerge(Race_0.Name, fleetOnPlanet2, fleetTargetTwo),
@@ -168,12 +160,12 @@ func TestFleetSpeedAndMass(t *testing.T) {
m := c.ShipGroup(0).FullMass(c.MustShipClass(Race_0_idx, Race_0_Gunship)) m := c.ShipGroup(0).FullMass(c.MustShipClass(Race_0_idx, Race_0_Gunship))
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) // 2 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) // 2
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(1).ID, "MAT", 10., 0)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(1).ID, "MAT", 10.))
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 7)) // 3 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 7)) // 3
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(2).ID, "CAP", 10., 0)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(2).ID, "CAP", 10.))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(0).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(0).ID))
fleetIndex := 0 fleetIndex := 0
speed, mass = c.FleetSpeedAndMass(fleetIndex) speed, mass = c.FleetSpeedAndMass(fleetIndex)
assert.Equal(t, s, speed) assert.Equal(t, s, speed)
@@ -182,7 +174,7 @@ func TestFleetSpeedAndMass(t *testing.T) {
s = math.Min(s, c.ShipGroup(1).Speed(c.MustShipClass(Race_0_idx, Race_0_Freighter))) s = math.Min(s, c.ShipGroup(1).Speed(c.MustShipClass(Race_0_idx, Race_0_Freighter)))
m += c.ShipGroup(1).FullMass(c.MustShipClass(Race_0_idx, Race_0_Freighter)) m += c.ShipGroup(1).FullMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(1).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(1).ID))
speed, mass = c.FleetSpeedAndMass(fleetIndex) speed, mass = c.FleetSpeedAndMass(fleetIndex)
assert.Equal(t, s, speed) assert.Equal(t, s, speed)
assert.Equal(t, m, mass) assert.Equal(t, m, mass)
@@ -190,7 +182,7 @@ func TestFleetSpeedAndMass(t *testing.T) {
s = math.Min(s, c.ShipGroup(2).Speed(c.MustShipClass(Race_0_idx, Race_0_Freighter))) s = math.Min(s, c.ShipGroup(2).Speed(c.MustShipClass(Race_0_idx, Race_0_Freighter)))
m += c.ShipGroup(2).FullMass(c.MustShipClass(Race_0_idx, Race_0_Freighter)) m += c.ShipGroup(2).FullMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(2).ID))
speed, mass = c.FleetSpeedAndMass(fleetIndex) speed, mass = c.FleetSpeedAndMass(fleetIndex)
assert.Equal(t, s, speed) assert.Equal(t, s, speed)
assert.Equal(t, m, mass) assert.Equal(t, m, mass)
+2 -2
View File
@@ -191,8 +191,8 @@ func TestProduceShips(t *testing.T) {
c.MustPlanet(R0_Planet_2_num).Population = 100 c.MustPlanet(R0_Planet_2_num).Population = 100
c.MustPlanet(R0_Planet_2_num).Industry = 100 c.MustPlanet(R0_Planet_2_num).Industry = 100
c.RaceTechLevel(Race_0_idx, game.TechDrive, 1.5) c.RaceTechLevel(Race_0_idx, game.TechDrive, 1.5)
assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(1).ID, "Drive", 0, 0)) assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(1).ID, "Drive", 0))
assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "Drive", 0, 0)) assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "Drive", 0))
assert.Equal(t, game.StateUpgrade, c.ShipGroup(0).State()) assert.Equal(t, game.StateUpgrade, c.ShipGroup(0).State())
assert.Equal(t, game.StateUpgrade, c.ShipGroup(1).State()) assert.Equal(t, game.StateUpgrade, c.ShipGroup(1).State())
+3 -3
View File
@@ -118,11 +118,11 @@ func TestListRoutedSendGroupIds(t *testing.T) {
// Foreign group -> idx 1 // Foreign group -> idx 1
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10))
assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(4).ID, 0)) assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(4).ID))
// 5: idx = 4 / Part of the Fleet // 5: idx = 4 / Part of the Fleet
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(5).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(5).ID))
planet_0_groups := slices.Collect(c.ListRoutedSendGroupIds(0)) planet_0_groups := slices.Collect(c.ListRoutedSendGroupIds(0))
assert.Len(t, planet_0_groups, 1) assert.Len(t, planet_0_groups, 1)
@@ -283,7 +283,7 @@ func TestListRoutedUnloadShipGroupIds(t *testing.T) {
// 5: idx = 4 / Part of the Fleet // 5: idx = 4 / Part of the Fleet
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(4).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(4).ID))
assert.NoError(t, g.PlanetRouteSet(Race_0.Name, "COL", R0_Planet_0_num, R0_Planet_2_num)) assert.NoError(t, g.PlanetRouteSet(Race_0.Name, "COL", R0_Planet_0_num, R0_Planet_2_num))
for _, rt := range game.RouteTypeSet { for _, rt := range game.RouteTypeSet {
+11 -48
View File
@@ -96,6 +96,7 @@ func (c *Cache) TurnMergeEqualShipGroups() {
} }
func (c *Cache) transferPendingGroups(ri int) { func (c *Cache) transferPendingGroups(ri int) {
c.validateRaceIndex(ri)
for sg := range c.listShipGroups(ri) { for sg := range c.listShipGroups(ri) {
if sg.State() == game.StateTransfer { if sg.State() == game.StateTransfer {
sg.StateTransfer = false sg.StateTransfer = false
@@ -146,7 +147,8 @@ func (c *Cache) shipGroupMerge(ri int) {
} }
} }
func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID, quantity uint) error { func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID) error {
c.validateRaceIndex(ri)
sgi, ok := c.raceShipGroupIndex(ri, groupIndex) sgi, ok := c.raceShipGroupIndex(ri, groupIndex)
if !ok { if !ok {
return e.NewEntityNotExistsError("group #%d", groupIndex) return e.NewEntityNotExistsError("group #%d", groupIndex)
@@ -156,10 +158,6 @@ func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID, quantity uint)
return e.NewShipsBusyError("state: %s", state) return e.NewShipsBusyError("state: %s", state)
} }
if c.ShipGroup(sgi).Number < quantity {
return e.NewBeakGroupNumberNotEnoughError("%d<%d", c.ShipGroup(sgi).Number, quantity)
}
pl, ok := c.Planet(c.ShipGroup(sgi).Destination) pl, ok := c.Planet(c.ShipGroup(sgi).Destination)
if !ok { if !ok {
return e.NewGameStateError("planet #%d", c.ShipGroup(sgi).Destination) return e.NewGameStateError("planet #%d", c.ShipGroup(sgi).Destination)
@@ -168,15 +166,6 @@ func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID, quantity uint)
st := c.ShipGroupShipClass(sgi) st := c.ShipGroupShipClass(sgi)
if quantity > 0 && quantity < c.ShipGroup(sgi).Number {
// make new group for disassembly
nsgi, err := c.breakGroup(ri, groupIndex, quantity)
if err != nil {
return err
}
sgi = nsgi
}
if c.ShipGroup(sgi).CargoType != nil { if c.ShipGroup(sgi).CargoType != nil {
ct := *c.ShipGroup(sgi).CargoType ct := *c.ShipGroup(sgi).CargoType
load := c.ShipGroup(sgi).Load.F() load := c.ShipGroup(sgi).Load.F()
@@ -204,10 +193,8 @@ func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID, quantity uint)
// Корабль может нести только один тип груза одновременно. // Корабль может нести только один тип груза одновременно.
// Возможные типы груза - это колонисты, сырье и промышленность. // Возможные типы груза - это колонисты, сырье и промышленность.
// Груз может быть доставлен на борт корабля с Вашей или не занятой планеты, на которой он имеется. // Груз может быть доставлен на борт корабля с Вашей или не занятой планеты, на которой он имеется.
func (c *Cache) shipGroupLoad(ri int, groupID uuid.UUID, ct game.CargoType, ships uint, quantity float64) error { func (c *Cache) shipGroupLoad(ri int, groupID uuid.UUID, ct game.CargoType, quantity float64) error {
if ships == 0 && quantity > 0 { c.validateRaceIndex(ri)
return e.NewCargoQuantityWithoutGroupBreakError()
}
sgi, ok := c.raceShipGroupIndex(ri, groupID) sgi, ok := c.raceShipGroupIndex(ri, groupID)
if !ok { if !ok {
return e.NewEntityNotExistsError("group %s", groupID) return e.NewEntityNotExistsError("group %s", groupID)
@@ -231,13 +218,7 @@ func (c *Cache) shipGroupLoad(ri int, groupID uuid.UUID, ct game.CargoType, ship
if c.ShipGroup(sgi).CargoType != nil && *c.ShipGroup(sgi).CargoType != ct { if c.ShipGroup(sgi).CargoType != nil && *c.ShipGroup(sgi).CargoType != ct {
return e.NewCargoLoadNotEqualError("cargo: %v", *c.ShipGroup(sgi).CargoType) return e.NewCargoLoadNotEqualError("cargo: %v", *c.ShipGroup(sgi).CargoType)
} }
if ships > 0 && ships < c.ShipGroup(sgi).Number {
nsgi, err := c.breakGroup(ri, groupID, ships)
if err != nil {
return err
}
sgi = nsgi
}
capacity := c.ShipGroup(sgi).CargoCapacity(st) capacity := c.ShipGroup(sgi).CargoCapacity(st)
freeShipGroupCargoLoad := capacity - float64(c.ShipGroup(sgi).Load) freeShipGroupCargoLoad := capacity - float64(c.ShipGroup(sgi).Load)
if freeShipGroupCargoLoad == 0 { if freeShipGroupCargoLoad == 0 {
@@ -274,11 +255,8 @@ func (c *Cache) shipGroupLoad(ri int, groupID uuid.UUID, ct game.CargoType, ship
// Промышленность и Сырье могут быть выгружены на любой планете. // Промышленность и Сырье могут быть выгружены на любой планете.
// Колонисты могут быть высажены только на планеты, принадлежащие Вам или на необитаемые планеты. // Колонисты могут быть высажены только на планеты, принадлежащие Вам или на необитаемые планеты.
func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, ships uint, quantity float64) error { func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, quantity float64) error {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
if ships == 0 && quantity > 0 {
return e.NewCargoQuantityWithoutGroupBreakError()
}
sgi, ok := c.raceShipGroupIndex(ri, groupID) sgi, ok := c.raceShipGroupIndex(ri, groupID)
if !ok { if !ok {
return e.NewEntityNotExistsError("group %s", groupID) return e.NewEntityNotExistsError("group %s", groupID)
@@ -300,13 +278,6 @@ func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, ships uint, quantity
if ct == game.CargoColonist && p.Owned() && !p.OwnedBy(c.g.Race[ri].ID) { if ct == game.CargoColonist && p.Owned() && !p.OwnedBy(c.g.Race[ri].ID) {
return e.NewEntityNotOwnedError("planet #%d unload %v", p.Number, ct) return e.NewEntityNotOwnedError("planet #%d unload %v", p.Number, ct)
} }
if ships > 0 && ships < c.ShipGroup(sgi).Number {
nsgi, err := c.breakGroup(ri, groupID, ships)
if err != nil {
return err
}
sgi = nsgi
}
toBeUnloaded := quantity toBeUnloaded := quantity
if quantity == 0 { if quantity == 0 {
@@ -356,7 +327,8 @@ func (c *Cache) unsafeUnloadCargo(sgi int, q float64) {
p.UnpackCapital() p.UnpackCapital()
} }
func (c *Cache) shipGroupTransfer(ri, riAccept int, groupID uuid.UUID, quantity uint) (err error) { func (c *Cache) shipGroupTransfer(ri, riAccept int, groupID uuid.UUID) (err error) {
c.validateRaceIndex(ri)
if ri == riAccept { if ri == riAccept {
return e.NewSameRaceError(c.g.Race[riAccept].Name) return e.NewSameRaceError(c.g.Race[riAccept].Name)
} }
@@ -369,9 +341,6 @@ func (c *Cache) shipGroupTransfer(ri, riAccept int, groupID uuid.UUID, quantity
if state == game.StateTransfer { if state == game.StateTransfer {
return e.NewShipsBusyError("state: %s", state) return e.NewShipsBusyError("state: %s", state)
} }
if sg.Number < quantity {
return e.NewBeakGroupNumberNotEnoughError("%d<%d", sg.Number, quantity)
}
st := c.ShipGroupShipClass(sgi) st := c.ShipGroupShipClass(sgi)
@@ -402,19 +371,13 @@ func (c *Cache) shipGroupTransfer(ri, riAccept int, groupID uuid.UUID, quantity
newGroup.StateTransfer = true newGroup.StateTransfer = true
} }
if quantity == 0 || quantity == sg.Number {
c.unsafeDeleteShipGroup(sgi)
} else {
newGroup.Number = quantity
sg.Number -= quantity
}
c.appendShipGroup(riAccept, &newGroup) c.appendShipGroup(riAccept, &newGroup)
c.unsafeDeleteShipGroup(sgi)
return nil return nil
} }
func (c *Cache) ShipGroupBreak(ri int, groupID uuid.UUID, quantity uint) error { func (c *Cache) ShipGroupBreak(ri int, groupID, newID uuid.UUID, quantity uint) error {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
sgi, ok := c.raceShipGroupIndex(ri, groupID) sgi, ok := c.raceShipGroupIndex(ri, groupID)
if !ok { if !ok {
+3 -3
View File
@@ -19,8 +19,8 @@ func TestListMoveableGroupIds(t *testing.T) {
// 3: idx = 2 / [v] In-Fleet group // 3: idx = 2 / [v] In-Fleet group
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(1).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(1).ID))
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(2).ID))
// 4: idx = 3 / [v] In_Space // 4: idx = 3 / [v] In_Space
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 7)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 7))
@@ -34,7 +34,7 @@ func TestListMoveableGroupIds(t *testing.T) {
// 6: idx = 5 / [v] Just launched group // 6: idx = 5 / [v] Just launched group
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10))
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(5).ID, R0_Planet_2_num, 0)) assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(5).ID, R0_Planet_2_num))
movableGroups := slices.Collect(c.ListMoveableGroupIds()) movableGroups := slices.Collect(c.ListMoveableGroupIds())
assert.Len(t, movableGroups, 5) assert.Len(t, movableGroups, 5)
+1 -13
View File
@@ -7,7 +7,7 @@ import (
"github.com/iliadenisov/galaxy/internal/util" "github.com/iliadenisov/galaxy/internal/util"
) )
func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber, quantity uint) error { func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber uint) error {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
sgi, ok := c.raceShipGroupIndex(ri, groupID) sgi, ok := c.raceShipGroupIndex(ri, groupID)
@@ -25,10 +25,6 @@ func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber, quantity
return e.NewShipsBusyError("state: %s", c.ShipGroup(sgi).State()) return e.NewShipsBusyError("state: %s", c.ShipGroup(sgi).State())
} }
if c.ShipGroup(sgi).Number < quantity {
return e.NewBeakGroupNumberNotEnoughError("%d<%d", c.ShipGroup(sgi).Number, quantity)
}
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)
@@ -42,14 +38,6 @@ func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber, quantity
return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination) return e.NewSendUnreachableDestinationError("range=%.03f", rangeToDestination)
} }
if quantity > 0 && quantity < c.ShipGroup(sgi).Number {
nsgi, err := c.breakGroup(ri, groupID, quantity)
if err != nil {
return err
}
sgi = nsgi
}
if p1.Number == p2.Number { if p1.Number == p2.Number {
c.UnsendShips(sgi) c.UnsendShips(sgi)
c.shipGroupMerge(ri) c.shipGroupMerge(ri)
+14 -42
View File
@@ -1,7 +1,6 @@
package controller_test package controller_test
import ( import (
"slices"
"testing" "testing"
"github.com/google/uuid" "github.com/google/uuid"
@@ -17,66 +16,39 @@ func TestShipGroupSend(t *testing.T) {
assert.NoError(t, c.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 10)) assert.NoError(t, c.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 10))
// group #2 - in_space // group #2 - in_space
assert.NoError(t, c.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 1)) assert.NoError(t, c.CreateShips(Race_0_idx, ShipType_Cruiser, R0_Planet_0_num, 1))
// g.ShipGroups[1].StateInSpace = &game.InSpace{Origin: 2, Range: 1.23}
c.ShipGroup(1).StateInSpace = &InSpace c.ShipGroup(1).StateInSpace = &InSpace
// group #3 - in_orbit, unmovable // group #3 - in_orbit, unmovable
g.ShipClassCreate(Race_0.Name, "Fortress", 0, 50, 30, 100, 0) g.ShipClassCreate(Race_0.Name, "Fortress", 0, 50, 30, 100, 0)
assert.NoError(t, c.CreateShips(Race_0_idx, "Fortress", R0_Planet_0_num, 1)) assert.NoError(t, c.CreateShips(Race_0_idx, "Fortress", R0_Planet_0_num, 1))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(UnknownRace, c.ShipGroup(0).ID, 2, 0), g.ShipGroupSend(UnknownRace, c.ShipGroup(0).ID, 2),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_Extinct.Name, c.ShipGroup(0).ID, 2, 0), g.ShipGroupSend(Race_Extinct.Name, c.ShipGroup(0).ID, 2),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, uuid.New(), 2, 0), g.ShipGroupSend(Race_0.Name, uuid.New(), 2),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, 222, 0), g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, 222),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, c.ShipGroup(1).ID, 1, 0), g.ShipGroupSend(Race_0.Name, c.ShipGroup(1).ID, 1),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, c.ShipGroup(2).ID, 2, 0), g.ShipGroupSend(Race_0.Name, c.ShipGroup(2).ID, 2),
e.GenericErrorText(e.ErrSendShipHasNoDrives)) e.GenericErrorText(e.ErrSendShipHasNoDrives))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, 2, 100), g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, 3),
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
assert.ErrorContains(t,
g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, 3, 0),
e.GenericErrorText(e.ErrSendUnreachableDestination)) e.GenericErrorText(e.ErrSendUnreachableDestination))
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, R0_Planet_2_num, 3)) // send 3 of 10 assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, R0_Planet_2_num)) // send #0
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(7), c.ShipGroup(0).Number)
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
assert.Equal(t, uint(3), c.ShipGroup(3).Number)
assert.Equal(t, game.StateLaunched, c.ShipGroup(3).State())
assert.NotNil(t, c.ShipGroup(3).StateInSpace)
assert.Nil(t, c.ShipGroup(3).StateInSpace.X)
assert.Nil(t, c.ShipGroup(3).StateInSpace.Y)
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(3).ID, R0_Planet_0_num, 2)) // un-send 2 of 3
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(9), c.ShipGroup(0).Number)
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
assert.Equal(t, uint(1), c.ShipGroup(3).Number)
assert.Equal(t, game.StateLaunched, c.ShipGroup(3).State())
assert.NotNil(t, c.ShipGroup(3).StateInSpace)
assert.Nil(t, c.ShipGroup(3).StateInSpace.X)
assert.Nil(t, c.ShipGroup(3).StateInSpace.Y)
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(3).ID, R0_Planet_0_num, 0)) // un-send the rest 1
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Equal(t, uint(10), c.ShipGroup(0).Number)
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, R0_Planet_2_num, 0))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Equal(t, uint(10), c.ShipGroup(0).Number)
assert.Equal(t, game.StateLaunched, c.ShipGroup(0).State()) assert.Equal(t, game.StateLaunched, c.ShipGroup(0).State())
assert.NotNil(t, c.ShipGroup(0).StateInSpace)
assert.Nil(t, c.ShipGroup(0).StateInSpace.X)
assert.Nil(t, c.ShipGroup(0).StateInSpace.Y)
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(0).ID, R0_Planet_0_num)) // un-send #0
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
} }
+108 -166
View File
@@ -105,29 +105,29 @@ func TestShipGroupBreak(t *testing.T) {
c.ShipGroup(1).StateInSpace = &InSpace c.ShipGroup(1).StateInSpace = &InSpace
fleet := "R0_Fleet" fleet := "R0_Fleet"
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(0).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, fleet, c.ShipGroup(0).ID))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupBreak(UnknownRace, c.ShipGroup(0).ID, 0), g.ShipGroupBreak(UnknownRace, c.ShipGroup(0).ID, uuid.New(), 1),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupBreak(Race_Extinct.Name, c.ShipGroup(0).ID, 0), g.ShipGroupBreak(Race_Extinct.Name, c.ShipGroup(0).ID, uuid.New(), 1),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupBreak(Race_0.Name, uuid.New(), 0), g.ShipGroupBreak(Race_0.Name, uuid.New(), uuid.New(), 1),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupBreak(Race_0.Name, c.ShipGroup(0).ID, 17), g.ShipGroupBreak(Race_0.Name, c.ShipGroup(0).ID, uuid.New(), 17),
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough)) e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupBreak(Race_0.Name, c.ShipGroup(1).ID, 0), g.ShipGroupBreak(Race_0.Name, c.ShipGroup(1).ID, uuid.New(), 1),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2)
assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1) assert.Len(t, slices.Collect(c.ListFleets(Race_0_idx)), 1)
// group #1 -> group #3 (5 new, 8 left) // group #1 -> group #3 (5 new, 8 left)
assert.NoError(t, c.ShipGroupBreak(Race_0_idx, c.ShipGroup(0).ID, 5)) // group #3 (2) assert.NoError(t, c.ShipGroupBreak(Race_0_idx, c.ShipGroup(0).ID, uuid.New(), 5)) // group #3 (2)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Equal(t, uint(8), c.ShipGroup(0).Number) assert.Equal(t, uint(8), c.ShipGroup(0).Number)
assert.NotNil(t, c.ShipGroup(0).FleetID) assert.NotNil(t, c.ShipGroup(0).FleetID)
@@ -138,15 +138,15 @@ func TestShipGroupBreak(t *testing.T) {
// group #1 -> group #4 (2 new, 6 left) // group #1 -> group #4 (2 new, 6 left)
c.ShipGroup(0).CargoType = game.CargoColonist.Ref() c.ShipGroup(0).CargoType = game.CargoColonist.Ref()
c.ShipGroup(0).Load = 32.8 // 8 ships c.ShipGroup(0).Load = 32.8 // 8 ships
assert.NoError(t, c.ShipGroupBreak(Race_0_idx, c.ShipGroup(0).ID, 2)) // group #4 (3) assert.NoError(t, c.ShipGroupBreak(Race_0_idx, c.ShipGroup(0).ID, uuid.New(), 2)) // group #4 (3)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(6), c.ShipGroup(0).Number) assert.Equal(t, uint(6), c.ShipGroup(0).Number)
assert.NotNil(t, c.ShipGroup(0).FleetID) assert.NotNil(t, c.ShipGroup(0).FleetID)
assert.Equal(t, uint(2), c.ShipGroup(3).Number) assert.Equal(t, uint(2), c.ShipGroup(3).Number)
// assert.Equal(t, uint(4), c.ShipGroup(3).Index) // assert.Equal(t, uint(4), c.ShipGroup(3).Index)
assert.Nil(t, c.ShipGroup(3).FleetID) assert.Nil(t, c.ShipGroup(3).FleetID)
assert.NoError(t, c.ShipGroupJoinFleet(Race_0_idx, fleet, c.ShipGroup(3).ID, 0)) assert.NoError(t, c.ShipGroupJoinFleet(Race_0_idx, fleet, c.ShipGroup(3).ID))
assert.NotNil(t, c.ShipGroup(3).FleetID) assert.NotNil(t, c.ShipGroup(3).FleetID)
assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(0).CargoType) assert.Equal(t, game.CargoColonist.Ref(), c.ShipGroup(0).CargoType)
@@ -155,13 +155,13 @@ func TestShipGroupBreak(t *testing.T) {
assert.Equal(t, 8.2, number.Fixed3(c.ShipGroup(3).Load.F())) assert.Equal(t, 8.2, number.Fixed3(c.ShipGroup(3).Load.F()))
// group #1 -> MAX 6 off the fleet // group #1 -> MAX 6 off the fleet
assert.NoError(t, g.ShipGroupBreak(Race_0.Name, c.ShipGroup(0).ID, 6)) // group #1 (0) assert.NoError(t, g.ShipGroupBreak(Race_0.Name, c.ShipGroup(0).ID, uuid.New(), 6)) // group #1 (0)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(6), c.ShipGroup(0).Number) assert.Equal(t, uint(6), c.ShipGroup(0).Number)
assert.Nil(t, c.ShipGroup(0).FleetID) assert.Nil(t, c.ShipGroup(0).FleetID)
// group #4 -> ALL off the fleet // group #4 -> ALL off the fleet
assert.NoError(t, g.ShipGroupBreak(Race_0.Name, c.ShipGroup(3).ID, 0)) // group #1 (0) assert.NoError(t, g.ShipGroupBreak(Race_0.Name, c.ShipGroup(3).ID, uuid.New(), 0)) // group #1 (0)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(2), c.ShipGroup(3).Number) assert.Equal(t, uint(2), c.ShipGroup(3).Number)
assert.Nil(t, c.ShipGroup(3).FleetID) assert.Nil(t, c.ShipGroup(3).FleetID)
@@ -173,7 +173,7 @@ func TestShipGroupTransfer(t *testing.T) {
assert.NoError(t, c.CreateShips(Race_1_idx, ShipType_Cruiser, R1_Planet_1_num, 23)) // group #2 (1) assert.NoError(t, c.CreateShips(Race_1_idx, ShipType_Cruiser, R1_Planet_1_num, 23)) // group #2 (1)
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 17)) // group #3 (2) - In_Space assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 17)) // group #3 (2) - In_Space
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "R0_Fleet", c.ShipGroup(2).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "R0_Fleet", c.ShipGroup(2).ID))
assert.NotNil(t, c.ShipGroup(2).FleetID) assert.NotNil(t, c.ShipGroup(2).FleetID)
c.ShipGroup(2).StateInSpace = &InSpace c.ShipGroup(2).StateInSpace = &InSpace
c.ShipGroup(2).CargoType = game.CargoMaterial.Ref() c.ShipGroup(2).CargoType = game.CargoMaterial.Ref()
@@ -183,74 +183,71 @@ func TestShipGroupTransfer(t *testing.T) {
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 1) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 1)
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(UnknownRace, Race_1.Name, c.ShipGroup(1).ID, 0), g.ShipGroupTransfer(UnknownRace, Race_1.Name, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, UnknownRace, c.ShipGroup(1).ID, 0), g.ShipGroupTransfer(Race_0.Name, UnknownRace, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, Race_Extinct.Name, c.ShipGroup(1).ID, 0), g.ShipGroupTransfer(Race_0.Name, Race_Extinct.Name, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_Extinct.Name, Race_1.Name, c.ShipGroup(1).ID, 0), g.ShipGroupTransfer(Race_Extinct.Name, Race_1.Name, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, Race_0.Name, c.ShipGroup(1).ID, 0), g.ShipGroupTransfer(Race_0.Name, Race_0.Name, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrInputSameRace)) e.GenericErrorText(e.ErrInputSameRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, Race_1.Name, uuid.New(), 0), g.ShipGroupTransfer(Race_0.Name, Race_1.Name, uuid.New()),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(2).ID, 18), g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(0).ID),
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
assert.ErrorContains(t,
g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(0).ID, 0),
e.GenericErrorText(e.ErrGiveawayGroupShipsTypeNotEqual)) e.GenericErrorText(e.ErrGiveawayGroupShipsTypeNotEqual))
assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(2).ID, 11)) // group #2 (3) orig := *c.ShipGroup(2)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2) assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(2).ID)) // group #2 (3)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 1)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 2) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 2)
newSg := c.ShipGroup(2)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Name, c.MustShipClass(Race_0_idx, Race_0_Gunship).Name) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Name, c.MustShipClass(Race_0_idx, Race_0_Gunship).Name)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Drive, c.MustShipClass(Race_0_idx, Race_0_Gunship).Drive) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Drive, c.MustShipClass(Race_0_idx, Race_0_Gunship).Drive)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Weapons, c.MustShipClass(Race_0_idx, Race_0_Gunship).Weapons) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Weapons, c.MustShipClass(Race_0_idx, Race_0_Gunship).Weapons)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Shields, c.MustShipClass(Race_0_idx, Race_0_Gunship).Shields) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Shields, c.MustShipClass(Race_0_idx, Race_0_Gunship).Shields)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Cargo, c.MustShipClass(Race_0_idx, Race_0_Gunship).Cargo) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Cargo, c.MustShipClass(Race_0_idx, Race_0_Gunship).Cargo)
assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Armament, c.MustShipClass(Race_0_idx, Race_0_Gunship).Armament) assert.Equal(t, c.MustShipClass(Race_1_idx, Race_0_Gunship).Armament, c.MustShipClass(Race_0_idx, Race_0_Gunship).Armament)
assert.Equal(t, c.ShipGroup(2).State(), c.ShipGroup(3).State()) assert.Equal(t, orig.State(), newSg.State())
assert.Equal(t, c.ShipGroup(2).CargoType, c.ShipGroup(3).CargoType) assert.Equal(t, orig.CargoType, newSg.CargoType)
assert.Equal(t, c.ShipGroup(2).Load, c.ShipGroup(3).Load) assert.Equal(t, orig.Load, newSg.Load)
assert.Equal(t, c.ShipGroup(2).TechLevel(game.TechDrive), c.ShipGroup(3).TechLevel(game.TechDrive)) assert.Equal(t, orig.TechLevel(game.TechDrive), newSg.TechLevel(game.TechDrive))
assert.Equal(t, c.ShipGroup(2).TechLevel(game.TechWeapons), c.ShipGroup(3).TechLevel(game.TechWeapons)) assert.Equal(t, orig.TechLevel(game.TechWeapons), newSg.TechLevel(game.TechWeapons))
assert.Equal(t, c.ShipGroup(2).TechLevel(game.TechShields), c.ShipGroup(3).TechLevel(game.TechShields)) assert.Equal(t, orig.TechLevel(game.TechShields), newSg.TechLevel(game.TechShields))
assert.Equal(t, c.ShipGroup(2).TechLevel(game.TechCargo), c.ShipGroup(3).TechLevel(game.TechCargo)) assert.Equal(t, orig.TechLevel(game.TechCargo), newSg.TechLevel(game.TechCargo))
assert.Equal(t, c.ShipGroup(2).Destination, c.ShipGroup(3).Destination) assert.Equal(t, orig.Destination, newSg.Destination)
assert.Equal(t, c.ShipGroup(2).StateInSpace, c.ShipGroup(3).StateInSpace) assert.Equal(t, orig.StateInSpace, newSg.StateInSpace)
assert.Equal(t, c.ShipGroup(2).StateUpgrade, c.ShipGroup(3).StateUpgrade) assert.Equal(t, orig.StateUpgrade, newSg.StateUpgrade)
assert.Equal(t, c.ShipGroup(2).StateTransfer, c.ShipGroup(3).StateTransfer) assert.Equal(t, orig.StateTransfer, newSg.StateTransfer)
assert.Equal(t, c.ShipGroup(3).OwnerID, Race_1_ID) assert.Equal(t, newSg.TypeID, c.MustShipClass(Race_1_idx, Race_0_Gunship).ID)
assert.Equal(t, c.ShipGroup(3).TypeID, c.MustShipClass(Race_1_idx, Race_0_Gunship).ID) assert.Equal(t, orig.Number, newSg.Number)
assert.Equal(t, c.ShipGroup(3).Number, uint(11)) assert.Equal(t, Race_1_ID, newSg.OwnerID)
assert.Nil(t, c.ShipGroup(3).FleetID) assert.Nil(t, newSg.FleetID)
assert.NoError(t, g.ShipGroupTransfer(Race_1.Name, Race_0.Name, c.ShipGroup(3).ID, 11))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 1)
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 1)) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 1))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2)
assert.Equal(t, game.StateInOrbit, c.ShipGroup(4).State()) sg := c.ShipGroup(3)
assert.NoError(t, g.ShipGroupSend(Race_0.Name, c.ShipGroup(4).ID, R0_Planet_2_num, 0)) assert.Equal(t, game.StateInOrbit, sg.State())
assert.Equal(t, game.StateLaunched, c.ShipGroup(4).State()) assert.NoError(t, g.ShipGroupSend(Race_0.Name, sg.ID, R0_Planet_2_num))
assert.Equal(t, c.ShipGroup(4).OwnerID, Race_0_ID) assert.Equal(t, game.StateLaunched, sg.State())
assert.Equal(t, sg.OwnerID, Race_0_ID)
assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, c.ShipGroup(4).ID, 0)) assert.NoError(t, g.ShipGroupTransfer(Race_0.Name, Race_1.Name, sg.ID))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3) sg = c.ShipGroup(3)
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 2) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 1)
assert.Equal(t, game.StateTransfer, c.ShipGroup(4).State()) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 3)
assert.Equal(t, c.ShipGroup(4).OwnerID, Race_1_ID) assert.Equal(t, game.StateTransfer, sg.State())
assert.Equal(t, sg.OwnerID, Race_1_ID)
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupTransfer(Race_1.Name, Race_0.Name, c.ShipGroup(4).ID, 0), g.ShipGroupTransfer(Race_1.Name, Race_0.Name, sg.ID),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
} }
@@ -280,98 +277,84 @@ func TestShipGroupLoad(t *testing.T) {
// tests // tests
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(UnknownRace, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(UnknownRace, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_Extinct.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_Extinct.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, "GOLD", 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, "GOLD", 0),
e.GenericErrorText(e.ErrInputCargoTypeInvalid)) e.GenericErrorText(e.ErrInputCargoTypeInvalid))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, uuid.New(), game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, uuid.New(), game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(2).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(2).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(4).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(4).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputEntityNotOwned)) e.GenericErrorText(e.ErrInputEntityNotOwned))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(1).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(1).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputNoCargoBay)) e.GenericErrorText(e.ErrInputNoCargoBay))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(3).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(3).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputCargoLoadNotEqual)) e.GenericErrorText(e.ErrInputCargoLoadNotEqual))
// initial planet is empty // initial planet is empty
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputCargoLoadNotEnough)) e.GenericErrorText(e.ErrInputCargoLoadNotEnough))
// add cargo to planet // add cargo to planet
c.PutMaterial(R0_Planet_0_num, 100) c.PutMaterial(R0_Planet_0_num, 100)
// not enough on the planet // not enough on the planet
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 11, 101), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 101),
e.GenericErrorText(e.ErrInputCargoLoadNotEnough)) e.GenericErrorText(e.ErrInputCargoLoadNotEnough))
// quantity > ships
assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 1),
e.GenericErrorText(e.ErrInputCargoQuantityWithoutGroupBreak))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 5) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 5)
// break group and load maximum // load maximum
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 2, 0)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0))
assert.Equal(t, 58.0, c.MustPlanet(R0_Planet_0_num).Material.F()) assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 6) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
assert.Nil(t, c.ShipGroup(0).CargoType) assert.Equal(t, 100.0, c.ShipGroup(0).Load.F())
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
assert.Equal(t, uint(9), c.ShipGroup(0).Number)
assert.Equal(t, 0.0, c.ShipGroup(0).Load.F())
assert.Equal(t, uint(2), c.ShipGroup(5).Number)
assert.Equal(t, 42.0, c.ShipGroup(5).Load.F())
// break group and load limited assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0))
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 2, 18))
assert.Equal(t, 40.0, c.MustPlanet(R0_Planet_0_num).Material.F()) // load limited
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 18))
assert.Nil(t, c.ShipGroup(0).CargoType) assert.Equal(t, 82.0, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(6).CargoType) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
assert.Equal(t, uint(7), c.ShipGroup(0).Number) assert.Equal(t, 18.0, c.ShipGroup(0).Load.F())
assert.Equal(t, 0.0, c.ShipGroup(0).Load.F())
assert.Equal(t, uint(2), c.ShipGroup(6).Number) assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0))
assert.Equal(t, 18.0, c.ShipGroup(6).Load.F())
// add cargo to planet // add cargo to planet
c.PutMaterial(R0_Planet_0_num, 100) c.PutMaterial(R0_Planet_0_num, 100)
// loading all available cargo // loading all available cargo
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 0)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material.F()) assert.Equal(t, 0.0, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Equal(t, 100.0, c.ShipGroup(0).Load.F()) // free: 131.0 assert.Equal(t, 100.0, c.ShipGroup(0).Load.F()) // free: 131.0
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
// add cargo to planet // add cargo to planet
c.PutMaterial(R0_Planet_0_num, 200) c.PutMaterial(R0_Planet_0_num, 200)
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 11, 31)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 31))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
assert.Equal(t, 169.0, c.MustPlanet(R0_Planet_0_num).Material.F()) assert.Equal(t, 169.0, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Equal(t, 131.0, c.ShipGroup(0).Load.F()) // free: 100.0 assert.Equal(t, 131.0, c.ShipGroup(0).Load.F()) // free: 100.0
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
// load to maximum cargo space left // load to maximum cargo space left
assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 11, 0)) assert.NoError(t, g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7) assert.Equal(t, 69.0, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Equal(t, 153.0, c.MustPlanet(R0_Planet_0_num).Material.F()) assert.Equal(t, 231.0, c.ShipGroup(0).Load.F()) // free: 0.0
assert.Equal(t, 147.0, c.ShipGroup(0).Load.F()) // free: 0.0
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(0).CargoType)
// ship group is full // ship group is full
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0, 0), g.ShipGroupLoad(Race_0.Name, c.ShipGroup(0).ID, game.CargoMaterial.String(), 0),
e.GenericErrorText(e.ErrInputCargoLoadNoSpaceLeft)) e.GenericErrorText(e.ErrInputCargoLoadNoSpaceLeft))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
} }
func TestShipGroupUnload(t *testing.T) { func TestShipGroupUnload(t *testing.T) {
@@ -408,67 +391,51 @@ func TestShipGroupUnload(t *testing.T) {
// tests // tests
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(UnknownRace, c.ShipGroup(0).ID, 0, 0), g.ShipGroupUnload(UnknownRace, c.ShipGroup(0).ID, 0),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_Extinct.Name, c.ShipGroup(0).ID, 0, 0), g.ShipGroupUnload(Race_Extinct.Name, c.ShipGroup(0).ID, 0),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, uuid.New(), 0, 0), g.ShipGroupUnload(Race_0.Name, uuid.New(), 0),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(2).ID, 0, 0), g.ShipGroupUnload(Race_0.Name, c.ShipGroup(2).ID, 0),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(1).ID, 0, 0), g.ShipGroupUnload(Race_0.Name, c.ShipGroup(1).ID, 0),
e.GenericErrorText(e.ErrInputNoCargoBay)) e.GenericErrorText(e.ErrInputNoCargoBay))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0, 0), g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0),
e.GenericErrorText(e.ErrInputCargoUnloadEmpty)) e.GenericErrorText(e.ErrInputCargoUnloadEmpty))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(4).ID, 0, 0), g.ShipGroupUnload(Race_0.Name, c.ShipGroup(4).ID, 0),
e.GenericErrorText(e.ErrInputEntityNotOwned)) e.GenericErrorText(e.ErrInputEntityNotOwned))
c.ShipGroup(0).CargoType = game.CargoColonist.Ref() c.ShipGroup(0).CargoType = game.CargoColonist.Ref()
c.ShipGroup(0).Load = 100 c.ShipGroup(0).Load = 100
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 11, 101), g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 101),
e.GenericErrorText(e.ErrInputCargoUnoadNotEnough)) e.GenericErrorText(e.ErrInputCargoUnoadNotEnough))
assert.ErrorContains(t,
g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0, 1),
e.GenericErrorText(e.ErrInputCargoQuantityWithoutGroupBreak))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 6) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 6)
// unload MAT on foreign planet / break group // unload MAT on foreign planet / limited
assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(5).ID, 3, 0)) assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(5).ID, 20.1))
assert.Equal(t, 27.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F())) assert.Equal(t, 20.1, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F()))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 7)
assert.Equal(t, uint(3), c.ShipGroup(6).Number)
assert.Equal(t, 0., c.ShipGroup(6).Load.F())
assert.Nil(t, c.ShipGroup(6).CargoType)
assert.Equal(t, 0.0, c.ShipGroup(6).Load.F())
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType) assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
assert.Equal(t, uint(8), c.ShipGroup(5).Number) assert.Equal(t, 79.9, number.Fixed3(c.ShipGroup(5).Load.F()))
assert.Equal(t, 72.727, number.Fixed3(c.ShipGroup(5).Load.F()))
// unload MAT on foreign planet / break group / limited MAT // unload MAT on foreign planet / ALL
assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(5).ID, 3, 20.0)) assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(5).ID, 0))
assert.Equal(t, 47.273, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F())) assert.Equal(t, 100.0, number.Fixed3(c.MustPlanet(R1_Planet_1_num).Material.F()))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8) assert.Equal(t, 0.0, number.Fixed3(c.ShipGroup(5).Load.F()))
assert.Equal(t, uint(3), c.ShipGroup(7).Number) assert.Nil(t, c.ShipGroup(5).CargoType)
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(7).CargoType)
assert.Equal(t, 7.273, number.Fixed3(c.ShipGroup(7).Load.F()))
assert.Equal(t, game.CargoMaterial.Ref(), c.ShipGroup(5).CargoType)
assert.Equal(t, uint(5), c.ShipGroup(5).Number)
assert.Equal(t, 45.455, number.Fixed3(c.ShipGroup(5).Load.F()))
// unload ALL // unload ALL
assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0, 0)) assert.NoError(t, g.ShipGroupUnload(Race_0.Name, c.ShipGroup(0).ID, 0))
assert.Equal(t, 100.0, number.Fixed3(c.MustPlanet(R0_Planet_0_num).Colonists.F())) assert.Equal(t, 100.0, number.Fixed3(c.MustPlanet(R0_Planet_0_num).Colonists.F()))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 8)
assert.Equal(t, uint(10), c.ShipGroup(0).Number)
assert.Nil(t, c.ShipGroup(0).CargoType)
assert.Equal(t, 0.0, number.Fixed3(c.ShipGroup(0).Load.F())) assert.Equal(t, 0.0, number.Fixed3(c.ShipGroup(0).Load.F()))
assert.Nil(t, c.ShipGroup(0).CargoType)
} }
func TestShipGroupDismantle(t *testing.T) { func TestShipGroupDismantle(t *testing.T) {
@@ -502,26 +469,23 @@ func TestShipGroupDismantle(t *testing.T) {
// tests // tests
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupDismantle(UnknownRace, c.ShipGroup(0).ID, 0), g.ShipGroupDismantle(UnknownRace, c.ShipGroup(0).ID),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupDismantle(Race_Extinct.Name, c.ShipGroup(0).ID, 0), g.ShipGroupDismantle(Race_Extinct.Name, c.ShipGroup(0).ID),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupDismantle(Race_0.Name, uuid.New(), 0), g.ShipGroupDismantle(Race_0.Name, uuid.New()),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(1).ID, 0), g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(1).ID),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.ErrorContains(t,
g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(2).ID, 12),
e.GenericErrorText(e.ErrBeakGroupNumberNotEnough))
groupEmptyMass := c.ShipGroup(4).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter)) groupEmptyMass := c.ShipGroup(4).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
planetMAT := c.MustPlanet(R1_Planet_1_num).Material.F() planetMAT := c.MustPlanet(R1_Planet_1_num).Material.F()
planetCOL := c.MustPlanet(R1_Planet_1_num).Colonists.F() planetCOL := c.MustPlanet(R1_Planet_1_num).Colonists.F()
assert.NoError(t, g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(4).ID, 0)) assert.NoError(t, g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(4).ID))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R1_Planet_1_num).Material.F()) assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R1_Planet_1_num).Material.F())
assert.Equal(t, planetCOL, c.MustPlanet(R1_Planet_1_num).Colonists.F()) assert.Equal(t, planetCOL, c.MustPlanet(R1_Planet_1_num).Colonists.F())
@@ -529,31 +493,9 @@ func TestShipGroupDismantle(t *testing.T) {
groupEmptyMass = c.ShipGroup(3).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter)) groupEmptyMass = c.ShipGroup(3).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
groupLoadMAT := c.ShipGroup(3).Load.F() groupLoadMAT := c.ShipGroup(3).Load.F()
planetMAT = c.MustPlanet(R1_Planet_1_num).Material.F() planetMAT = c.MustPlanet(R1_Planet_1_num).Material.F()
assert.NoError(t, g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(3).ID, 0)) assert.NoError(t, g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(3).ID))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Equal(t, planetMAT+groupEmptyMass+groupLoadMAT, c.MustPlanet(R1_Planet_1_num).Material.F()) assert.Equal(t, planetMAT+groupEmptyMass+groupLoadMAT, c.MustPlanet(R1_Planet_1_num).Material.F())
groupEmptyMass = c.ShipGroup(2).EmptyMass(c.MustShipClass(Race_0_idx, Race_0_Freighter))
planetMAT = c.MustPlanet(R0_Planet_0_num).Material.F()
planetCOL = c.MustPlanet(R0_Planet_0_num).Colonists.F()
planetPOP := 90.0
c.PutPopulation(R0_Planet_0_num, planetPOP)
assert.Equal(t, planetPOP, c.MustPlanet(R0_Planet_0_num).Population.F())
var quantity uint = 3
groupEmptyMass = groupEmptyMass / float64(c.ShipGroup(2).Number) * float64(quantity)
newGroupUnloadedCOL := c.ShipGroup(2).Load.F() / float64(c.ShipGroup(2).Number) * float64(quantity)
expectPOPIncrease := newGroupUnloadedCOL * 8
freePOPLeft := c.MustPlanet(R0_Planet_0_num).Size.F() - c.MustPlanet(R0_Planet_0_num).Population.F()
expectAddedCOL := (expectPOPIncrease - freePOPLeft) / 8
expectAddedPOP := freePOPLeft
assert.NoError(t, g.ShipGroupDismantle(Race_0.Name, c.ShipGroup(2).ID, quantity))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
assert.Equal(t, planetCOL+expectAddedCOL, c.MustPlanet(R0_Planet_0_num).Colonists.F())
assert.Equal(t, planetPOP+expectAddedPOP, c.MustPlanet(R0_Planet_0_num).Population.F())
assert.Equal(t, planetMAT+groupEmptyMass, c.MustPlanet(R0_Planet_0_num).Material.F())
assert.Equal(t, uint(7), c.ShipGroup(2).Number)
assert.Equal(t, 56.0, c.ShipGroup(2).Load.F())
} }
func TestShipGroupDestroyItem(t *testing.T) { func TestShipGroupDestroyItem(t *testing.T) {
@@ -578,7 +520,7 @@ func TestUnsafeDeleteShipGroup(t *testing.T) {
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 3)) // 0 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 3)) // 0
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_2_num, 5)) // 1 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_2_num, 5)) // 1
assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(0).ID, 0)) assert.NoError(t, g.ShipGroupJoinFleet(Race_0.Name, "Fleet", c.ShipGroup(0).ID))
assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_2_num, 7)) // 2 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_2_num, 7)) // 2
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 3)
+1 -6
View File
@@ -10,7 +10,7 @@ import (
"github.com/iliadenisov/galaxy/internal/model/game" "github.com/iliadenisov/galaxy/internal/model/game"
) )
func (c *Cache) shipGroupUpgrade(ri int, groupID uuid.UUID, techInput string, limitShips uint, limitLevel float64) error { func (c *Cache) shipGroupUpgrade(ri int, groupID uuid.UUID, techInput string, limitLevel float64) error {
c.validateRaceIndex(ri) c.validateRaceIndex(ri)
sgi, ok := c.raceShipGroupIndex(ri, groupID) sgi, ok := c.raceShipGroupIndex(ri, groupID)
if !ok { if !ok {
@@ -77,11 +77,6 @@ func (c *Cache) shipGroupUpgrade(ri int, groupID uuid.UUID, techInput string, li
} }
shipsToUpgrade := sg.Number shipsToUpgrade := sg.Number
// НЕ БОЛЕЕ УКАЗАННОГО
if limitShips > 0 && shipsToUpgrade > limitShips {
shipsToUpgrade = limitShips
}
maxUpgradableShips := uc.UpgradeMaxShips(productionCapacity) maxUpgradableShips := uc.UpgradeMaxShips(productionCapacity)
/* /*
+18 -17
View File
@@ -1,7 +1,6 @@
package controller_test package controller_test
import ( import (
"slices"
"testing" "testing"
"github.com/google/uuid" "github.com/google/uuid"
@@ -126,50 +125,52 @@ func TestShipGroupUpgrade(t *testing.T) {
c.ShipGroup(2).Destination = R1_Planet_1_num c.ShipGroup(2).Destination = R1_Planet_1_num
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(UnknownRace, c.ShipGroup(0).ID, "DRIVE", 0, 0), g.ShipGroupUpgrade(UnknownRace, c.ShipGroup(0).ID, "DRIVE", 0),
e.GenericErrorText(e.ErrInputUnknownRace)) e.GenericErrorText(e.ErrInputUnknownRace))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_Extinct.Name, c.ShipGroup(0).ID, "DRIVE", 0, 0), g.ShipGroupUpgrade(Race_Extinct.Name, c.ShipGroup(0).ID, "DRIVE", 0),
e.GenericErrorText(e.ErrRaceExinct)) e.GenericErrorText(e.ErrRaceExinct))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, uuid.New(), "DRIVE", 0, 0), g.ShipGroupUpgrade(Race_0.Name, uuid.New(), "DRIVE", 0),
e.GenericErrorText(e.ErrInputEntityNotExists)) e.GenericErrorText(e.ErrInputEntityNotExists))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(1).ID, "DRIVE", 0, 0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(1).ID, "DRIVE", 0),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(2).ID, "DRIVE", 0, 0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(2).ID, "DRIVE", 0),
e.GenericErrorText(e.ErrInputEntityNotOwned)) e.GenericErrorText(e.ErrInputEntityNotOwned))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "GUN", 0, 0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "GUN", 0),
e.GenericErrorText(e.ErrInputTechUnknown)) e.GenericErrorText(e.ErrInputTechUnknown))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "CARGO", 0, 0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "CARGO", 0),
e.GenericErrorText(e.ErrInputUpgradeShipTechNotUsed)) e.GenericErrorText(e.ErrInputUpgradeShipTechNotUsed))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "ALL", 0, 2.0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "ALL", 2.0),
e.GenericErrorText(e.ErrInputUpgradeParameterNotAllowed)) e.GenericErrorText(e.ErrInputUpgradeParameterNotAllowed))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 0, 2.0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 2.0),
e.GenericErrorText(e.ErrInputUpgradeTechLevelInsufficient)) e.GenericErrorText(e.ErrInputUpgradeTechLevelInsufficient))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 0, 1.1), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 1.1),
e.GenericErrorText(e.ErrInputUpgradeShipsAlreadyUpToDate)) e.GenericErrorText(e.ErrInputUpgradeShipsAlreadyUpToDate))
c.RaceTechLevel(Race_0_idx, game.TechDrive, 10.0) c.RaceTechLevel(Race_0_idx, game.TechDrive, 10.0)
assert.Equal(t, 10.0, c.Race(Race_0_idx).TechLevel(game.TechDrive)) assert.Equal(t, 10.0, c.Race(Race_0_idx).TechLevel(game.TechDrive))
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 0, 10.0), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 10.0),
e.GenericErrorText(e.ErrUpgradeInsufficientResources)) e.GenericErrorText(e.ErrUpgradeInsufficientResources))
assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 2, 1.2)) assert.NoError(t, g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(0).ID, "DRIVE", 1.3))
assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 4)
assert.Equal(t, uint(8), c.ShipGroup(0).Number)
assert.Equal(t, uint(2), c.ShipGroup(3).Number)
assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State()) assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State())
assert.Equal(t, uint(6), c.ShipGroup(0).Number)
assert.Equal(t, game.StateUpgrade, c.ShipGroup(3).State()) assert.Equal(t, game.StateUpgrade, c.ShipGroup(3).State())
assert.Equal(t, uint(4), c.ShipGroup(3).Number)
assert.NotNil(t, c.ShipGroup(3).StateUpgrade)
assert.Equal(t, 1.3, c.ShipGroup(3).StateUpgrade.UpgradeTech[0].Level.F())
assert.Equal(t, "DRIVE", c.ShipGroup(3).StateUpgrade.UpgradeTech[0].Tech.String())
assert.ErrorContains(t, assert.ErrorContains(t,
g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(3).ID, "DRIVE", 1, 1.3), g.ShipGroupUpgrade(Race_0.Name, c.ShipGroup(3).ID, "DRIVE", 1.3),
e.GenericErrorText(e.ErrShipsBusy)) e.GenericErrorText(e.ErrShipsBusy))
} }
-6
View File
@@ -18,7 +18,6 @@ const (
ErrDeleteShipTypePlanetProduction = 5001 ErrDeleteShipTypePlanetProduction = 5001
ErrDeleteSciencePlanetProduction = 5002 ErrDeleteSciencePlanetProduction = 5002
ErrMergeShipTypeNotEqual = 5003 ErrMergeShipTypeNotEqual = 5003
ErrJoinFleetGroupNumberNotEnough = 5004
ErrBeakGroupNumberNotEnough = 5005 ErrBeakGroupNumberNotEnough = 5005
ErrEntityInUse = 5006 ErrEntityInUse = 5006
ErrShipsBusy = 5007 ErrShipsBusy = 5007
@@ -51,7 +50,6 @@ const (
ErrInputScienceSumValues ErrInputScienceSumValues
ErrInputProductionInvalid ErrInputProductionInvalid
ErrInputCargoTypeInvalid ErrInputCargoTypeInvalid
ErrInputCargoQuantityWithoutGroupBreak
ErrInputCargoLoadNotEnough ErrInputCargoLoadNotEnough
ErrInputCargoLoadNotEqual ErrInputCargoLoadNotEqual
ErrInputNoCargoBay ErrInputNoCargoBay
@@ -123,8 +121,6 @@ func GenericErrorText(code int) string {
return "Invalid Production type" return "Invalid Production type"
case ErrInputCargoTypeInvalid: case ErrInputCargoTypeInvalid:
return "Invalid cargo type" return "Invalid cargo type"
case ErrInputCargoQuantityWithoutGroupBreak:
return "Cargo quantity should be specified only for a new group number of ships"
case ErrInputCargoLoadNotEnough: case ErrInputCargoLoadNotEnough:
return "Not enough cargo to load" return "Not enough cargo to load"
case ErrInputCargoLoadNotEqual: case ErrInputCargoLoadNotEqual:
@@ -141,8 +137,6 @@ func GenericErrorText(code int) string {
return "Illegal ships number to make new group" return "Illegal ships number to make new group"
case ErrMergeShipTypeNotEqual: case ErrMergeShipTypeNotEqual:
return "Source and target ship types are not the same" return "Source and target ship types are not the same"
case ErrJoinFleetGroupNumberNotEnough:
return "Not enough ships in the group to join a fleet"
case ErrBeakGroupNumberNotEnough: case ErrBeakGroupNumberNotEnough:
return "Not enough ships in the group to make a separate group" return "Not enough ships in the group to make a separate group"
case ErrShipsBusy: case ErrShipsBusy:
-8
View File
@@ -80,10 +80,6 @@ func NewCargoTypeInvalidError(arg ...any) error {
return newGenericError(ErrInputCargoTypeInvalid, arg...) return newGenericError(ErrInputCargoTypeInvalid, arg...)
} }
func NewCargoQuantityWithoutGroupBreakError(arg ...any) error {
return newGenericError(ErrInputCargoQuantityWithoutGroupBreak, arg...)
}
func NewCargoLoadNotEnoughError(arg ...any) error { func NewCargoLoadNotEnoughError(arg ...any) error {
return newGenericError(ErrInputCargoLoadNotEnough, arg...) return newGenericError(ErrInputCargoLoadNotEnough, arg...)
} }
@@ -116,10 +112,6 @@ func NewMergeShipTypeNotEqualError(arg ...any) error {
return newGenericError(ErrMergeShipTypeNotEqual, arg...) return newGenericError(ErrMergeShipTypeNotEqual, arg...)
} }
func NewJoinFleetGroupNumberNotEnoughError(arg ...any) error {
return newGenericError(ErrJoinFleetGroupNumberNotEnough, arg...)
}
func NewBeakGroupNumberNotEnoughError(arg ...any) error { func NewBeakGroupNumberNotEnoughError(arg ...any) error {
return newGenericError(ErrBeakGroupNumberNotEnough, arg...) return newGenericError(ErrBeakGroupNumberNotEnough, arg...)
} }
+6 -13
View File
@@ -87,14 +87,12 @@ type CommandShipGroupLoad struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Cargo string `json:"cargo" binding:"required,notblank,oneof=COL MAT CAP"` Cargo string `json:"cargo" binding:"required,notblank,oneof=COL MAT CAP"`
Ships int `json:"ships" binding:"gte=0"`
Quantity float64 `json:"quantity" binding:"gte=0"` Quantity float64 `json:"quantity" binding:"gte=0"`
} }
type CommandShipGroupUnload struct { type CommandShipGroupUnload struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Ships int `json:"ships" binding:"gte=0"`
Quantity float64 `json:"quantity" binding:"gte=0"` Quantity float64 `json:"quantity" binding:"gte=0"`
} }
@@ -102,15 +100,13 @@ type CommandShipGroupSend struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Destination int `json:"planetNumber" binding:"gte=0"` Destination int `json:"planetNumber" binding:"gte=0"`
Quantity int `json:"quantity" binding:"gte=0"`
} }
type CommandShipGroupUpgrade struct { type CommandShipGroupUpgrade struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Tech string `json:"tech" binding:"oneof=ALL DRIVE WEAPONS SHIELDS CARGO"` Tech string `json:"tech" binding:"oneof=ALL DRIVE WEAPONS SHIELDS CARGO"`
MaxShips int `json:"maxShips" binding:"gte=0"` Level int `json:"level" binding:"gte=1"`
Level int `json:"level" binding:"gte=1"`
} }
type CommandShipGroupMerge struct { type CommandShipGroupMerge struct {
@@ -125,22 +121,19 @@ type CommandShipGroupBreak struct {
type CommandShipGroupDismantle struct { type CommandShipGroupDismantle struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Quantity int `json:"quantity" binding:"gte=0"`
} }
type CommandShipGroupTransfer struct { type CommandShipGroupTransfer struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Acceptor string `json:"acceptor" binding:"required,notblank"` Acceptor string `json:"acceptor" binding:"required,notblank"`
Quantity int `json:"quantity" binding:"gte=0"`
} }
type CommandShipGroupJoinFleet struct { type CommandShipGroupJoinFleet struct {
CommandMeta CommandMeta
ID string `json:"id" binding:"required,uuid_rfc4122"` ID string `json:"id" binding:"required,uuid_rfc4122"`
Name string `json:"name" binding:"required,notblank,entity"` Name string `json:"name" binding:"required,notblank,entity"`
Quantity int `json:"quantity" binding:"gte=0"`
} }
type CommandFleetMerge struct { type CommandFleetMerge struct {