refactor: game funcs moved to controller
This commit is contained in:
+140
-22
@@ -2,29 +2,160 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
e "github.com/iliadenisov/galaxy/internal/error"
|
||||
"github.com/iliadenisov/galaxy/internal/model/game"
|
||||
)
|
||||
|
||||
func (c *Controller) RenamePlanet(raceName string, planetNumber int, typeName string) error {
|
||||
ri, err := c.Cache.raceIndex(raceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Cache.RenamePlanet(ri, planetNumber, typeName)
|
||||
}
|
||||
|
||||
func (c *Cache) RenamePlanet(ri int, number int, name string) error {
|
||||
n, ok := validateTypeName(name)
|
||||
if !ok {
|
||||
return e.NewEntityTypeNameValidationError("%q", n)
|
||||
}
|
||||
if number < 0 {
|
||||
return e.NewPlanetNumberError(number)
|
||||
}
|
||||
p, ok := c.Planet(uint(number))
|
||||
if !ok {
|
||||
return e.NewEntityNotExistsError("planet #%d", number)
|
||||
}
|
||||
if p.Owner != c.g.Race[ri].ID {
|
||||
return e.NewEntityNotOwnedError("planet #%d", number)
|
||||
}
|
||||
c.g.Map.Planet[c.MustPlanetIndex(p.Number)].Name = n
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) PlanetProduction(raceName string, planetNumber int, prodType, subject string) error {
|
||||
ri, err := c.Cache.raceIndex(raceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var prod game.ProductionType
|
||||
switch game.ProductionType(strings.ToUpper(prodType)) {
|
||||
case game.ProductionMaterial:
|
||||
prod = game.ProductionMaterial
|
||||
case game.ProductionCapital:
|
||||
prod = game.ProductionCapital
|
||||
case game.ResearchDrive:
|
||||
prod = game.ResearchDrive
|
||||
case game.ResearchWeapons:
|
||||
prod = game.ResearchWeapons
|
||||
case game.ResearchShields:
|
||||
prod = game.ResearchShields
|
||||
case game.ResearchCargo:
|
||||
prod = game.ResearchCargo
|
||||
case game.ResearchScience:
|
||||
prod = game.ResearchScience
|
||||
case game.ProductionShip:
|
||||
prod = game.ProductionShip
|
||||
default:
|
||||
return e.NewProductionInvalidError(prodType)
|
||||
}
|
||||
return c.Cache.PlanetProduction(ri, planetNumber, prod, subject)
|
||||
}
|
||||
|
||||
func (c *Cache) PlanetProduction(ri int, number int, prod game.ProductionType, subj string) error {
|
||||
c.validateRaceIndex(ri)
|
||||
if number < 0 {
|
||||
return e.NewPlanetNumberError(number)
|
||||
}
|
||||
p, ok := c.Planet(uint(number))
|
||||
if !ok {
|
||||
return e.NewEntityNotExistsError("planet #%d", number)
|
||||
}
|
||||
if p.Owner != c.g.Race[ri].ID {
|
||||
return e.NewEntityNotOwnedError("planet #%d", number)
|
||||
}
|
||||
i := c.MustPlanetIndex(p.Number)
|
||||
var subjectID *uuid.UUID
|
||||
if (prod == game.ResearchScience || prod == game.ProductionShip) && subj == "" {
|
||||
return e.NewEntityTypeNameValidationError("%s=%q", prod, subj)
|
||||
}
|
||||
if prod == game.ResearchScience {
|
||||
i := slices.IndexFunc(c.g.Race[ri].Sciences, func(s game.Science) bool { return s.Name == subj })
|
||||
if i < 0 {
|
||||
return e.NewEntityNotExistsError("science %q", subj)
|
||||
}
|
||||
subjectID = &c.g.Race[ri].Sciences[i].ID
|
||||
}
|
||||
if prod == game.ProductionShip {
|
||||
st, _, ok := c.ShipClass(ri, subj)
|
||||
if !ok {
|
||||
return e.NewEntityNotExistsError("ship type %q", subj)
|
||||
}
|
||||
if p.Production.Type == game.ProductionShip &&
|
||||
p.Production.SubjectID != nil &&
|
||||
*p.Production.SubjectID == st.ID {
|
||||
// Planet already produces this ship type, keeping progress intact
|
||||
return nil
|
||||
}
|
||||
subjectID = &st.ID
|
||||
var progress float64 = 0.
|
||||
c.g.Map.Planet[i].Production.Progress = &progress
|
||||
} else {
|
||||
c.g.Map.Planet[i].Production.Progress = nil
|
||||
}
|
||||
if p.Production.Type == game.ProductionShip && prod != game.ProductionShip {
|
||||
if p.Production.SubjectID == nil {
|
||||
return e.NewGameStateError("planet #%d produces ship but SubjectID is empty", p.Number)
|
||||
}
|
||||
s := *p.Production.SubjectID
|
||||
if p.Production.Progress == nil {
|
||||
return e.NewGameStateError("planet #%d produces ship but Progress is empty", p.Number)
|
||||
}
|
||||
progress := *p.Production.Progress
|
||||
st, ok := c.ShipType(ri, s)
|
||||
if !ok {
|
||||
return e.NewGameStateError("planet #%d produces ship but ShipType was not found for race %s", p.Number, c.g.Race[ri].Name)
|
||||
}
|
||||
mat, _ := st.ProductionCost()
|
||||
extra := mat * progress
|
||||
c.g.Map.Planet[i].Material += extra
|
||||
}
|
||||
c.g.Map.Planet[i].Production.Type = prod
|
||||
c.g.Map.Planet[i].Production.SubjectID = subjectID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cache) Planet(planetNumber uint) (*game.Planet, bool) {
|
||||
if c.planetByPlanetNumber == nil {
|
||||
c.planetByPlanetNumber = make(map[uint]*game.Planet)
|
||||
if c.cachePlanetByPlanetNumber == nil {
|
||||
c.cachePlanetByPlanetNumber = make(map[uint]*game.Planet)
|
||||
for p := range c.g.Map.Planet {
|
||||
c.planetByPlanetNumber[c.g.Map.Planet[p].Number] = &c.g.Map.Planet[p]
|
||||
c.cachePlanetByPlanetNumber[c.g.Map.Planet[p].Number] = &c.g.Map.Planet[p]
|
||||
}
|
||||
}
|
||||
if v, ok := c.planetByPlanetNumber[planetNumber]; ok {
|
||||
if v, ok := c.cachePlanetByPlanetNumber[planetNumber]; ok {
|
||||
return v, true
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) MustPlanet(planetNumber uint) *game.Planet {
|
||||
if v, ok := c.Planet(planetNumber); ok {
|
||||
func (c *Cache) MustPlanet(pn uint) *game.Planet {
|
||||
if v, ok := c.Planet(pn); ok {
|
||||
return v
|
||||
} else {
|
||||
panic(fmt.Sprintf("Planet: not found by number=%d", planetNumber))
|
||||
panic(fmt.Sprintf("planet not found by number=%d", pn))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) MustPlanetIndex(pn uint) int {
|
||||
if idx := slices.IndexFunc(c.g.Map.Planet, func(p game.Planet) bool { return p.Number == pn }); idx < 0 {
|
||||
panic(fmt.Sprintf("planet not found by number=%d", pn))
|
||||
} else {
|
||||
return idx
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,18 +164,14 @@ func (c *Cache) MustPlanet(planetNumber uint) *game.Planet {
|
||||
// за вычетом затрат, расходуемых в течение хода на модернизацию кораблей
|
||||
func (c *Cache) PlanetProductionCapacity(planetNumber uint) float64 {
|
||||
p := c.MustPlanet(planetNumber)
|
||||
// p, err := g.PlanetByNumber(planetNumber)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
var busyResources float64
|
||||
for sg := range c.g.ShipsInUpgrade(p.Number) {
|
||||
for sg := range c.shipGroupsInUpgrade(p.Number) {
|
||||
busyResources += sg.StateUpgrade.Cost()
|
||||
}
|
||||
return game.PlanetProduction(p.Industry, p.Population) - busyResources
|
||||
}
|
||||
|
||||
// Internal fincs
|
||||
// Internal funcs
|
||||
|
||||
func (c *Cache) putPopulation(pn uint, v float64) {
|
||||
c.MustPlanet(pn).Population = v
|
||||
@@ -57,12 +184,3 @@ func (c *Cache) putColonists(pn uint, v float64) {
|
||||
func (c *Cache) putMaterial(pn uint, v float64) {
|
||||
c.MustPlanet(pn).Material = v
|
||||
}
|
||||
|
||||
func UnloadColonists(p game.Planet, v float64) game.Planet {
|
||||
p.Population += v * 8
|
||||
if p.Population > p.Size {
|
||||
p.Colonists += (p.Population - p.Size) / 8
|
||||
p.Population = p.Size
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user