feat: produce ships

This commit is contained in:
Ilia Denisov
2026-01-20 13:33:53 +02:00
parent 40b2cb27f6
commit 7e73601bce
7 changed files with 96 additions and 43 deletions
+39 -29
View File
@@ -78,11 +78,11 @@ func (c *Cache) PlanetProduction(ri int, number int, prod game.ProductionType, s
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 {
@@ -90,6 +90,7 @@ func (c *Cache) PlanetProduction(ri int, number int, prod game.ProductionType, s
}
subjectID = &c.g.Race[ri].Sciences[i].ID
}
if prod == game.ProductionShip {
st, _, ok := c.ShipClass(ri, subj)
if !ok {
@@ -102,30 +103,24 @@ func (c *Cache) PlanetProduction(ri int, number int, prod game.ProductionType, s
return nil
}
subjectID = &st.ID
}
if p.Production.Type == game.ProductionShip && (prod != game.ProductionShip || *subjectID != *p.Production.SubjectID) {
mat, _ := c.MustShipType(ri, *p.Production.SubjectID).ProductionCost()
p.Material += mat * (*p.Production.Progress)
*p.Production.Progress = 0.
} else if prod == game.ProductionShip {
// new ship class to produce; otherwise we must have been returned from the func earlier
var progress float64 = 0.
c.g.Map.Planet[i].Production.Progress = &progress
} else {
c.g.Map.Planet[i].Production.Progress = nil
p.Production.Progress = &progress
}
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
if prod != game.ProductionShip {
p.Production.Progress = nil
}
c.g.Map.Planet[i].Production.Type = prod
c.g.Map.Planet[i].Production.SubjectID = subjectID
p.Production.Type = prod
p.Production.SubjectID = subjectID
return nil
}
@@ -201,6 +196,23 @@ 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 {
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))
}
}
}
}
// Internal funcs
func (c *Cache) putPopulation(pn uint, v float64) {
@@ -230,16 +242,14 @@ func ProduceShip(p *game.Planet, shipMass float64) int {
if CAP_deficit := p.Capital - CAP_perShip; CAP_deficit < 0 {
productionExtraCAP = -CAP_deficit
}
ship_prod := productionExtraCAP + productionForMass
if productionAvailable >= ship_prod {
productionAvailable -= ship_prod
productionCost := productionExtraCAP + productionForMass
if productionAvailable >= productionCost {
productionAvailable -= productionCost
p.Capital = p.Capital - (CAP_perShip - productionExtraCAP)
ships++
} else {
progress := productionAvailable / ship_prod
productionAvailable -= ship_prod * progress
progress := productionAvailable / productionCost
productionAvailable -= productionCost * progress
p.Production.Progress = &progress
break
}