feat: order processing

feat: order commands result save/load
This commit is contained in:
Ilia Denisov
2026-02-20 17:44:41 +02:00
committed by GitHub
parent 0c0df976bd
commit 233c9ebc2a
26 changed files with 2028 additions and 385 deletions
+90
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"iter"
"maps"
"math/rand/v2"
"slices"
"github.com/google/uuid"
@@ -295,6 +296,95 @@ func (c *Cache) shipGroupUnload(ri int, groupID uuid.UUID, quantity float64) err
return nil
}
func (c *Cache) shipGroupUnloadColonistChallenge(groupIDs []uuid.UUID, quantites []float64) error {
if len(groupIDs) != len(quantites) {
e.NewGameStateError("challenge group unload: groups=%d quantities=%d", len(groupIDs), len(quantites))
}
if len(groupIDs) == 0 {
return nil
}
type challenger struct {
ri int
sgi int
quantity float64
}
challenge := make(map[uint]map[int][]challenger, 0)
for i, gid := range groupIDs {
sgi, ok := c.shipGroupIndexByID(gid)
if !ok {
return e.NewGameStateError("challenge group unload: group not found: %v", gid)
}
sg := c.ShipGroup(sgi)
pn, ok := sg.AtPlanet()
if !ok || sg.CargoType == nil {
continue
}
p := c.MustPlanet(pn)
ri := c.ShipGroupOwnerRaceIndex(sgi)
if p.Owned() || *sg.CargoType != game.CargoColonist {
if err := c.shipGroupUnload(ri, gid, quantites[i]); err != nil {
return err
}
}
if _, ok := challenge[pn]; !ok {
challenge[pn] = make(map[int][]challenger)
}
challenge[pn][ri] = append(challenge[pn][ri], challenger{ri: ri, sgi: sgi, quantity: quantites[i]})
}
for pn := range challenge {
if len(challenge[pn]) < 2 {
for _, v := range challenge[pn] {
for _, ch := range v {
if err := c.shipGroupUnload(ch.ri, c.ShipGroup(ch.sgi).ID, ch.quantity); err != nil {
return err
}
}
}
continue
}
sum := make(map[int]float64)
races := slices.Collect(maps.Keys(challenge[pn]))
for ri, groups := range challenge[pn] {
for i := range groups {
sum[ri] = sum[ri] + groups[i].quantity
}
c.listProducingPlanets()
}
slices.SortFunc(races, func(ria, rib int) int {
return cmp.Or(
// Наибольшее количество выгружаемых колонистов
cmp.Compare(sum[rib], sum[ria]),
// Наибольшее количество населения расы (они же голоса)
cmp.Compare(c.g.Race[rib].Votes, c.g.Race[ria].Votes),
// Случайный выбор претендента
cmp.Compare(rand.Float64(), rand.Float64()),
// in theoty, unreacheable option, but let's randomize again
cmp.Compare(rand.Float64(), rand.Float64()),
)
})
for _, ch := range challenge[pn][races[0]] {
if err := c.shipGroupUnload(ch.ri, c.ShipGroup(ch.sgi).ID, ch.quantity); err != nil {
return err
}
}
}
return nil
}
func (c *Cache) shipGroupIndexByID(id uuid.UUID) (int, bool) {
for sgi := range c.g.ShipGroups {
if c.g.ShipGroups[sgi].ID == id {
return sgi, true
}
}
return -1, false
}
func (c *Cache) unsafeUnloadCargo(sgi int, q float64) {
if q <= 0 {
return