From 43dc8ab3f99b6ce2533c23e66bd14b0301f5d4cd Mon Sep 17 00:00:00 2001 From: IliaDenisov Date: Tue, 10 Feb 2026 21:14:15 +0300 Subject: [PATCH] fix: remove fleet when deleting last group --- internal/controller/controller_export_test.go | 4 +-- internal/controller/fleet.go | 8 +++--- internal/controller/planet.go | 2 +- internal/controller/route.go | 2 +- internal/controller/ship_group.go | 27 +++++++++++++------ internal/controller/ship_group_send.go | 2 +- internal/controller/ship_group_upgrade.go | 2 +- 7 files changed, 29 insertions(+), 18 deletions(-) diff --git a/internal/controller/controller_export_test.go b/internal/controller/controller_export_test.go index f50aca0..eeb8c0c 100644 --- a/internal/controller/controller_export_test.go +++ b/internal/controller/controller_export_test.go @@ -22,7 +22,7 @@ func (c *Cache) CreateShips(ri int, shipTypeName string, planetNumber uint, quan return e.NewEntityNotOwnedError("planet #%d", planetNumber) } - c.createShipsUnsafe(ri, class.ID, p.Number, uint(quantity)) + c.unsafeCreateShips(ri, class.ID, p.Number, uint(quantity)) return nil } @@ -137,7 +137,7 @@ func VotingWinners(calc []*VoteGroup, gameVotes float64) []int { } func (c *Cache) CreateShipsUnsafe_T(ri int, classID uuid.UUID, planet uint, quantity uint) { - c.createShipsUnsafe(ri, classID, planet, quantity) + c.unsafeCreateShips(ri, classID, planet, quantity) } func (c *Cache) WipeRace(ri int) { diff --git a/internal/controller/fleet.go b/internal/controller/fleet.go index c21ebff..9a5defa 100644 --- a/internal/controller/fleet.go +++ b/internal/controller/fleet.go @@ -140,7 +140,7 @@ func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID, } if quantity > 0 && quantity < c.ShipGroup(sgi).Number { - nsgi, err := c.breakGroupSafe(ri, groupID, quantity) + nsgi, err := c.breakGroup(ri, groupID, quantity) if err != nil { return err } @@ -162,7 +162,7 @@ func (c *Cache) ShipGroupJoinFleet(ri int, fleetName string, groupID uuid.UUID, if !ok { return e.NewGameStateError("old fleet index not found by ID=%v", *oldFleetID) } - if err := c.deleteFleetSafe(ri, c.g.Fleets[oldFleetIndex].Name); err != nil { + if err := c.deleteFleet(ri, c.g.Fleets[oldFleetIndex].Name); err != nil { return err } } @@ -191,7 +191,7 @@ func (c *Cache) fleetMerge(ri int, fleetSourceName, fleetTargetName string) (err sg.FleetID = &c.g.Fleets[fiTarget].ID } } - return c.deleteFleetSafe(ri, fleetSourceName) + return c.deleteFleet(ri, fleetSourceName) } func (c *Cache) createFleet(ri int, name string) (int, error) { @@ -217,7 +217,7 @@ func (c *Cache) createFleet(ri int, name string) (int, error) { return i, nil } -func (c *Cache) deleteFleetSafe(ri int, name string) error { +func (c *Cache) deleteFleet(ri int, name string) error { fi, ok := c.fleetIndex(ri, name) if !ok { return e.NewEntityNotExistsError("fleet %s", name) diff --git a/internal/controller/planet.go b/internal/controller/planet.go index 0256c84..83079c8 100644 --- a/internal/controller/planet.go +++ b/internal/controller/planet.go @@ -194,7 +194,7 @@ func (c *Cache) TurnPlanetProductions() { case game.ProductionShip: st := c.MustShipType(ri, *p.Production.SubjectID) if ships := ProduceShip(p, productionAvailable, st.EmptyMass()); ships > 0 { - c.createShipsUnsafe(ri, st.ID, p.Number, ships) + c.unsafeCreateShips(ri, st.ID, p.Number, ships) } case game.ResearchScience: sc := c.mustScience(ri, *p.Production.SubjectID) diff --git a/internal/controller/route.go b/internal/controller/route.go index 61dfdad..117ecb7 100644 --- a/internal/controller/route.go +++ b/internal/controller/route.go @@ -130,7 +130,7 @@ func (c *Cache) SendRoutedGroups() { if toLoad > sgCapacity { toLoad = sgCapacity } else if maxShips := uint(math.Ceil(toLoad / (sgCapacity / float64(ships)))); maxShips < ships { - newGroupIdx := c.breakGroupUnsafe(c.RaceIndex(sg.OwnerID), sgi, maxShips) + newGroupIdx := c.unsafeBreakGroup(c.RaceIndex(sg.OwnerID), sgi, maxShips) sgi = newGroupIdx sg = c.ShipGroup(newGroupIdx) } diff --git a/internal/controller/ship_group.go b/internal/controller/ship_group.go index d38292a..5d8ab10 100644 --- a/internal/controller/ship_group.go +++ b/internal/controller/ship_group.go @@ -174,7 +174,7 @@ func (c *Cache) shipGroupDismantle(ri int, groupIndex uuid.UUID, quantity uint) if quantity > 0 && quantity < c.ShipGroup(sgi).Number { // make new group for disassembly - nsgi, err := c.breakGroupSafe(ri, groupIndex, quantity) + nsgi, err := c.breakGroup(ri, groupIndex, quantity) if err != nil { return err } @@ -236,7 +236,7 @@ func (c *Cache) shipGroupLoad(ri int, groupID uuid.UUID, ct game.CargoType, ship return e.NewCargoLoadNotEqualError("cargo: %v", *c.ShipGroup(sgi).CargoType) } if ships > 0 && ships < c.ShipGroup(sgi).Number { - nsgi, err := c.breakGroupSafe(ri, groupID, ships) + nsgi, err := c.breakGroup(ri, groupID, ships) if err != nil { return err } @@ -305,7 +305,7 @@ func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, ships uint, quantity return e.NewEntityNotOwnedError("planet #%d unload %v", p.Number, ct) } if ships > 0 && ships < c.ShipGroup(sgi).Number { - nsgi, err := c.breakGroupSafe(ri, groupID, ships) + nsgi, err := c.breakGroup(ri, groupID, ships) if err != nil { return err } @@ -437,7 +437,7 @@ func (c *Cache) ShipGroupBreak(ri int, groupID uuid.UUID, quantity uint) error { if quantity == 0 || quantity == c.ShipGroup(sgi).Number { c.internalShipGroupJoinFleet(sgi, nil) } else { - if _, err := c.breakGroupSafe(ri, groupID, quantity); err != nil { + if _, err := c.breakGroup(ri, groupID, quantity); err != nil { return err } } @@ -445,7 +445,7 @@ func (c *Cache) ShipGroupBreak(ri int, groupID uuid.UUID, quantity uint) error { return nil } -func (c *Cache) breakGroupSafe(ri int, groupID uuid.UUID, newGroupShips uint) (int, error) { +func (c *Cache) breakGroup(ri int, groupID uuid.UUID, newGroupShips uint) (int, error) { c.validateRaceIndex(ri) sgi, ok := c.raceShipGroupIndex(ri, groupID) if !ok { @@ -454,10 +454,10 @@ func (c *Cache) breakGroupSafe(ri int, groupID uuid.UUID, newGroupShips uint) (i if c.ShipGroup(sgi).Number < newGroupShips { return -1, e.NewBreakGroupIllegalNumberError("group=%s ships: %d -> %d", c.ShipGroup(sgi).ID, c.ShipGroup(sgi).Number, newGroupShips) } - return c.breakGroupUnsafe(ri, sgi, newGroupShips), nil + return c.unsafeBreakGroup(ri, sgi, newGroupShips), nil } -func (c *Cache) breakGroupUnsafe(ri, sgi int, newGroupShips uint) int { +func (c *Cache) unsafeBreakGroup(ri, sgi int, newGroupShips uint) int { newGroup := *c.ShipGroup(sgi) if c.ShipGroup(sgi).CargoType != nil { newGroup.Load = game.F(float64(c.ShipGroup(sgi).Load) / float64(c.ShipGroup(sgi).Number) * float64(newGroupShips)) @@ -526,6 +526,17 @@ func (c *Cache) shipGroupsInUpgrade(planetNumber uint) iter.Seq[*game.ShipGroup] func (c *Cache) unsafeDeleteShipGroup(sgi int) { c.validateShipGroupIndex(sgi) + + sg := c.ShipGroup(sgi) + if sg.FleetID != nil { + fi := c.MustFleetIndex(*sg.FleetID) + fleetGroups := slices.Collect(c.fleetGroupIds(c.RaceIndex(sg.OwnerID), fi)) + if len(fleetGroups) == 1 { + // remove fleet when deleting last group in the fleet + c.unsafeDeleteFleet(fi) + } + } + c.g.ShipGroups = append(c.g.ShipGroups[:sgi], c.g.ShipGroups[sgi+1:]...) c.invalidateShipGroupCache() } @@ -536,7 +547,7 @@ func (c *Cache) validateShipGroupIndex(i int) { } } -func (c *Cache) createShipsUnsafe(ri int, classID uuid.UUID, planet uint, quantity uint) { +func (c *Cache) unsafeCreateShips(ri int, classID uuid.UUID, planet uint, quantity uint) { c.appendShipGroup(ri, &game.ShipGroup{ OwnerID: c.g.Race[ri].ID, TypeID: classID, diff --git a/internal/controller/ship_group_send.go b/internal/controller/ship_group_send.go index fad43a5..060b4b8 100644 --- a/internal/controller/ship_group_send.go +++ b/internal/controller/ship_group_send.go @@ -43,7 +43,7 @@ func (c *Cache) shipGroupSend(ri int, groupID uuid.UUID, planetNumber, quantity } if quantity > 0 && quantity < c.ShipGroup(sgi).Number { - nsgi, err := c.breakGroupSafe(ri, groupID, quantity) + nsgi, err := c.breakGroup(ri, groupID, quantity) if err != nil { return err } diff --git a/internal/controller/ship_group_upgrade.go b/internal/controller/ship_group_upgrade.go index d0e5576..1671dc4 100644 --- a/internal/controller/ship_group_upgrade.go +++ b/internal/controller/ship_group_upgrade.go @@ -118,7 +118,7 @@ func (c *Cache) shipGroupUpgrade(ri int, groupID uuid.UUID, techInput string, li // break group if needed if maxUpgradableShips < sg.Number { - nsgi, err := c.breakGroupSafe(ri, groupID, maxUpgradableShips) + nsgi, err := c.breakGroup(ri, groupID, maxUpgradableShips) if err != nil { return err }