package controller import ( "fmt" "iter" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/game" ) func (c *Cache) CreateShips(ri int, shipTypeName string, planetNumber uint, quantity int) error { class, _, ok := c.ShipClass(ri, shipTypeName) if !ok { return e.NewEntityNotExistsError("ship class %w", shipTypeName) } p, ok := c.Planet(planetNumber) if !ok { return e.NewEntityNotExistsError("planet #%d", planetNumber) } if p.Owner != c.g.Race[ri].ID { return e.NewEntityNotOwnedError("planet #%d", planetNumber) } nextIndex := c.ShipGroupMaxIndex(ri) + 1 c.g.ShipGroups = append(c.g.ShipGroups, game.ShipGroup{ Index: nextIndex, OwnerID: c.g.Race[ri].ID, TypeID: class.ID, Destination: p.Number, Number: uint(quantity), Tech: map[game.Tech]float64{ game.TechDrive: c.g.Race[ri].TechLevel(game.TechDrive), game.TechWeapons: c.g.Race[ri].TechLevel(game.TechWeapons), game.TechShields: c.g.Race[ri].TechLevel(game.TechShields), game.TechCargo: c.g.Race[ri].TechLevel(game.TechCargo), }, }) if c.raceIndexByShipGroupIndex != nil { c.raceIndexByShipGroupIndex[len(c.g.ShipGroups)-1] = ri } if c.shipClassByShipGroupIndex != nil { c.shipClassByShipGroupIndex[len(c.g.ShipGroups)-1] = class } return nil } // ShipGroup is a proxy func, nothing to cache func (c *Cache) ShipGroup(groupIndex int) *game.ShipGroup { c.validateShipGroupIndex(groupIndex) return &c.g.ShipGroups[groupIndex] } func (c *Cache) ShipGroupsIndex() iter.Seq[int] { return func(yield func(int) bool) { for i := range c.g.ShipGroups { if !yield(i) { return } } } } func (c *Cache) ShipGroupMaxIndex(ri int) uint { var max uint = 0 for i := range c.g.ShipGroups { if r := c.ShipGroupOwnerRaceIndex(i); r == ri && c.ShipGroup(i).Index > max { max = c.ShipGroup(i).Index } } return max } func (c *Cache) ShipGroupOwnerRaceIndex(groupIndex int) int { if c.raceIndexByShipGroupIndex == nil { c.fillShipsAndGroups() } c.validateShipGroupIndex(groupIndex) if v, ok := c.raceIndexByShipGroupIndex[groupIndex]; ok { return v } else { panic(fmt.Sprintf("ShipGroupRace: group not found by index=%v", groupIndex)) } } func (c *Cache) ShipGroupOwnerRace(groupIndex int) *game.Race { return &c.g.Race[c.ShipGroupOwnerRaceIndex(groupIndex)] } func (c *Cache) ShipGroupNumber(i int, n uint) { c.validateShipGroupIndex(i) c.g.ShipGroups[i].Number = n } func (c *Cache) DeleteShipGroup(i int) { c.validateShipGroupIndex(i) c.unsafeDeleteShipGroup(i) } func (c *Cache) DeleteKilledShipGroups() { for i := len(c.g.ShipGroups) - 1; i >= 0; i-- { if c.g.ShipGroups[i].Number == 0 { c.unsafeDeleteShipGroup(i) } } }