108 lines
2.7 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|