Files
galaxy-game/internal/controller/ship_group.go
T
2026-01-14 14:40:04 +02:00

108 lines
2.7 KiB
Go

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)
}
}
}