Files
galaxy-game/internal/controller/bombing.go
T
2026-02-02 13:14:57 +02:00

113 lines
3.1 KiB
Go

package controller
import (
"github.com/google/uuid"
"github.com/iliadenisov/galaxy/internal/model/game"
"github.com/iliadenisov/galaxy/internal/model/report"
)
func (c *Cache) bombingReport(p *game.Planet, ri int, groups []int) report.BombingPlanetReport {
attackPower := 0.
for _, i := range groups {
sg := c.ShipGroup(i)
st := c.ShipGroupShipClass(i)
attackPower += sg.BombingPower(st)
}
r := &report.BombingPlanetReport{
ID: uuid.New(),
Planet: p.Name,
Number: p.Number,
Owner: c.g.Race[c.RaceIndex(p.Owner)].Name,
Attacker: c.g.Race[ri].Name,
Production: c.PlanetProductionDisplayName(p.Number),
Industry: p.Industry.RF(),
Population: p.Population.RF(),
Colonists: p.Colonists.RF(),
Capital: p.Capital.RF(),
Material: p.Material.RF(),
AttackPower: game.RF(attackPower),
}
bombPlanet(p, attackPower)
r.Wiped = p.Population == 0
return *r
}
func (c *Cache) ProduceBombings() []report.BombingPlanetReport {
report := make([]report.BombingPlanetReport, 0)
for pn, enemies := range c.collectBombingGroups() {
p := c.MustPlanet(pn)
for ri, groups := range enemies {
br := c.bombingReport(p, ri, groups)
report = append(report, br)
if br.Wiped {
break
}
}
if p.Population == 0 {
// TODO: what aboul colonists left on planet?
p.Owner = uuid.Nil
p.Production = game.ProductionNone.AsType(uuid.Nil)
clear(p.Route)
} else {
// Если на планете остались также и колонисты, то они превращаются в население,
// а накопленная промышленность возмещает потери производства.
p.UnpackColonists()
p.UnpackCapital()
}
}
return report
}
func bombPlanet(p *game.Planet, power float64) {
// Уничтожается население и колонисты в количестве равном [суммарной] мощности бомбардировки
if power > p.Population.F() {
p.Pop(0)
} else {
p.Pop(p.Population.F() - power)
}
if power > p.Colonists.F() {
p.Col(0)
} else {
p.Col(p.Colonists.F() - power)
}
// Такое же количество промышленности превращается в сырье
if power > p.Industry.F() {
p.Mat(p.Material.F() + p.Industry.F())
p.Ind(0)
} else {
p.Mat(p.Material.F() + power)
p.Ind(p.Industry.F() - power)
}
}
// [planet_num] -> [enemy_race_id] -> []group_id
func (c *Cache) collectBombingGroups() map[uint]map[int][]int {
result := make(map[uint]map[int][]int)
for i := range c.ShipGroupsIndex() {
sg := c.ShipGroup(i)
if sg.State() != game.StateInOrbit {
continue
}
st := c.ShipGroupShipClass(i)
if st.WeaponsBlockMass() == 0 {
continue
}
p := c.MustPlanet(sg.Destination)
if p.Owner == sg.OwnerID || p.Owner == uuid.Nil {
continue
}
r1 := c.RaceIndex(sg.OwnerID)
r2 := c.RaceIndex(p.Owner)
if c.Relation(r1, r2) == game.RelationPeace {
continue
}
// add result
if _, ok := result[p.Number]; !ok {
result[p.Number] = make(map[int][]int)
}
result[p.Number][r1] = append(result[p.Number][r1], i)
}
return result
}