feat: produce on planets, unload on routes
This commit is contained in:
@@ -2,6 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@@ -196,23 +197,78 @@ func (c *Cache) PlanetProductionCapacity(planetNumber uint) float64 {
|
||||
return p.ProductionCapacity() - busyResources
|
||||
}
|
||||
|
||||
func (c *Cache) ProduceShips() {
|
||||
for pl := range c.g.Map.Planet {
|
||||
p := c.MustPlanet(c.g.Map.Planet[pl].Number)
|
||||
if p.Owner == uuid.Nil || p.Production.Type != game.ProductionShip {
|
||||
func (c *Cache) TurnPlanetProductions() {
|
||||
for pn := range c.listProducingPlanets() {
|
||||
p := c.MustPlanet(pn)
|
||||
ri := c.RaceIndex(p.Owner)
|
||||
r := &c.g.Race[ri]
|
||||
|
||||
switch pt := p.Production.Type; pt {
|
||||
case game.ProductionShip:
|
||||
st := c.MustShipType(ri, *p.Production.SubjectID)
|
||||
if ships := ProduceShip(p, st.EmptyMass()); ships > 0 {
|
||||
c.createShipsUnsafe(ri, st.ID, p.Number, ships)
|
||||
}
|
||||
case game.ResearchScience:
|
||||
sc := c.mustScience(ri, *p.Production.SubjectID)
|
||||
IncreaseTech(r, p, sc.Drive, sc.Weapons, sc.Shields, sc.Cargo)
|
||||
case game.ResearchDrive:
|
||||
IncreaseTech(r, p, 1., 0, 0, 0)
|
||||
case game.ResearchWeapons:
|
||||
IncreaseTech(r, p, 0, 1., 0, 0)
|
||||
case game.ResearchShields:
|
||||
IncreaseTech(r, p, 0, 0, 1., 0)
|
||||
case game.ResearchCargo:
|
||||
IncreaseTech(r, p, 0, 0, 0, 1.)
|
||||
case game.ProductionMaterial:
|
||||
p.IncreaseMaterial()
|
||||
case game.ProductionCapital:
|
||||
p.IncreaseIndustry()
|
||||
default:
|
||||
panic(fmt.Sprintf("unprocessed production type: %v", pt))
|
||||
}
|
||||
|
||||
p.IncreasePopulation()
|
||||
}
|
||||
c.TurnMergeEqualShipGroups()
|
||||
}
|
||||
|
||||
// listProducingPlanets iterates over all inhabited planet numbers with production not set to None.
|
||||
// Planets producing ships guaranteed to be iterated first for correct turn actions order.
|
||||
func (c *Cache) listProducingPlanets() iter.Seq[uint] {
|
||||
ordered := make([]int, 0)
|
||||
for i := range c.g.Map.Planet {
|
||||
if c.g.Map.Planet[i].Owner == uuid.Nil || c.g.Map.Planet[i].Production.Type == game.ProductionNone {
|
||||
continue
|
||||
}
|
||||
ri := c.RaceIndex(p.Owner)
|
||||
st := c.MustShipType(ri, *p.Production.SubjectID)
|
||||
ships := ProduceShip(p, st.EmptyMass())
|
||||
if ships > 0 {
|
||||
if err := c.CreateShips(ri, st.Name, p.Number, ships); err != nil {
|
||||
panic(fmt.Sprintf("ProduceShips: CreateShip: %s", err))
|
||||
ordered = append(ordered, i)
|
||||
}
|
||||
slices.SortFunc(ordered, func(l, r int) int {
|
||||
if c.g.Map.Planet[l].Production.Type == game.ProductionShip && c.g.Map.Planet[r].Production.Type != game.ProductionShip {
|
||||
return -1
|
||||
}
|
||||
if c.g.Map.Planet[l].Production.Type != game.ProductionShip && c.g.Map.Planet[r].Production.Type == game.ProductionShip {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return func(yield func(uint) bool) {
|
||||
for _, i := range ordered {
|
||||
if !yield(c.g.Map.Planet[i].Number) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func IncreaseTech(r *game.Race, p *game.Planet, d, w, s, c float64) {
|
||||
increment := 5000. / p.ProductionCapacity()
|
||||
r.Tech.Set(game.TechDrive, r.Tech.Value(game.TechDrive)+increment*d)
|
||||
r.Tech.Set(game.TechWeapons, r.Tech.Value(game.TechWeapons)+increment*w)
|
||||
r.Tech.Set(game.TechShields, r.Tech.Value(game.TechShields)+increment*s)
|
||||
r.Tech.Set(game.TechCargo, r.Tech.Value(game.TechCargo)+increment*c)
|
||||
}
|
||||
|
||||
// Internal funcs
|
||||
|
||||
func (c *Cache) putPopulation(pn uint, v float64) {
|
||||
@@ -227,14 +283,14 @@ func (c *Cache) putMaterial(pn uint, v float64) {
|
||||
c.MustPlanet(pn).Material = v
|
||||
}
|
||||
|
||||
func ProduceShip(p *game.Planet, shipMass float64) int {
|
||||
func ProduceShip(p *game.Planet, shipMass float64) uint {
|
||||
productionAvailable := p.ProductionCapacity()
|
||||
if productionAvailable <= 0 {
|
||||
return 0
|
||||
}
|
||||
CAP_perShip := shipMass / p.Resources
|
||||
productionForMass := shipMass * 10.
|
||||
ships := 0
|
||||
ships := uint(0)
|
||||
flZero := 0.
|
||||
p.Production.Progress = &flZero
|
||||
for productionAvailable > 0 {
|
||||
|
||||
Reference in New Issue
Block a user