feat(ui): Phase 30 ship-class calculator with goal-seek and reach circles
Fuse the standalone ship-class designer (Phases 17/18) into a sidebar calculator: live mass/speed/attack/defence/bombing results, a planet build-rate readout, single-target goal-seek, a modernization-cost mode, and auto reach circles on the map for the selected planet. pkg/calc becomes the single source for the new math (no mirroring): extract BombingPower from the engine model and the per-turn ship-production loop from controller.ProduceShip into pkg/calc (engine now delegates), and add inverse goal-seek solvers in pkg/calc/solve.go. Thin-bridge the combat, planet-build, and solver functions through ui/core/calc + ui/wasm and rebuild core.wasm. Remove the standalone designer view/route; the ship-classes table and the view/bottom menus open the calculator via a shared request store. Docs: rewrite ui/PLAN.md Phase 30, adjust Phase 34 (realistic forecast + CAP/COL ownership), add ui/docs/calculator-ux.md, extend calc-bridge.md, fix navigation.md; remove ui/CALCULATOR.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -272,29 +272,19 @@ func ProduceShip(p *game.Planet, productionAvailable, shipMass float64) uint {
|
||||
if productionAvailable <= 0 {
|
||||
return 0
|
||||
}
|
||||
ships := uint(0)
|
||||
pa := productionAvailable
|
||||
var MATneed, totalCost float64
|
||||
for {
|
||||
MATneed = shipMass - float64(p.Material)
|
||||
if MATneed < 0 {
|
||||
MATneed = 0
|
||||
}
|
||||
totalCost = calc.ShipBuildCost(shipMass, float64(p.Material), float64(p.Resources))
|
||||
if pa < totalCost {
|
||||
progress := pa / totalCost
|
||||
pval := game.F(progress)
|
||||
if p.Production.Progress != nil {
|
||||
pval += *p.Production.Progress
|
||||
}
|
||||
p.Production.Progress = &pval
|
||||
fval := game.F(pa)
|
||||
p.Production.ProdUsed = &fval
|
||||
return ships
|
||||
} else {
|
||||
pa -= totalCost
|
||||
p.Mat(float64(p.Material) - shipMass + MATneed)
|
||||
ships += 1
|
||||
}
|
||||
ships, materialLeft, productionUsed, progress := calc.ProduceShipsInTurn(
|
||||
productionAvailable,
|
||||
float64(p.Material),
|
||||
float64(p.Resources),
|
||||
shipMass,
|
||||
)
|
||||
p.Mat(materialLeft)
|
||||
pval := game.F(progress)
|
||||
if p.Production.Progress != nil {
|
||||
pval += *p.Production.Progress
|
||||
}
|
||||
p.Production.Progress = &pval
|
||||
used := game.F(productionUsed)
|
||||
p.Production.ProdUsed = &used
|
||||
return ships
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package game
|
||||
import (
|
||||
"fmt"
|
||||
"galaxy/calc"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -208,11 +207,12 @@ func (sg ShipGroup) Speed(st *ShipType) float64 {
|
||||
|
||||
// Мощность бомбардировки
|
||||
func (sg ShipGroup) BombingPower(st *ShipType) float64 {
|
||||
return (math.Sqrt(st.Weapons.F()*sg.TechLevel(TechWeapons).F())/10. + 1.) *
|
||||
st.Weapons.F() *
|
||||
sg.TechLevel(TechWeapons).F() *
|
||||
float64(st.Armament) *
|
||||
float64(sg.Number)
|
||||
return calc.BombingPower(
|
||||
st.Weapons.F(),
|
||||
sg.TechLevel(TechWeapons).F(),
|
||||
float64(st.Armament),
|
||||
float64(sg.Number),
|
||||
)
|
||||
}
|
||||
|
||||
func (sg ShipGroup) CargoString() string {
|
||||
|
||||
Reference in New Issue
Block a user