131 lines
3.8 KiB
Go
131 lines
3.8 KiB
Go
package controller
|
|
|
|
import (
|
|
"github.com/google/uuid"
|
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
|
)
|
|
|
|
type BombingReport struct {
|
|
Planets []BombingPlanetReport `json:"planets"`
|
|
}
|
|
|
|
type BombingPlanetReport struct {
|
|
ID uuid.UUID `json:"id"`
|
|
Planet string `json:"name"`
|
|
Number uint `json:"number"`
|
|
Owner string `json:"owner"`
|
|
Attacker string `json:"attacker"`
|
|
Production string `json:"production"`
|
|
Industry float64 `json:"industry"` // I - Промышленность
|
|
Population float64 `json:"population"` // P - Население
|
|
Colonists float64 `json:"colonists"` // COL C - Количество колонистов
|
|
Capital float64 `json:"capital"` // CAP $ - Запасы промышленности
|
|
Material float64 `json:"material"` // MAT M - Запасы ресурсов / сырья
|
|
AttackPower float64 `json:"attack"`
|
|
Wiped bool `json:"wiped"`
|
|
}
|
|
|
|
func (c *Cache) bombingReport(p *game.Planet, ri int, groups []int) BombingPlanetReport {
|
|
attackPower := 0.
|
|
for _, i := range groups {
|
|
sg := c.ShipGroup(i)
|
|
st := c.ShipGroupShipClass(i)
|
|
attackPower += sg.BombingPower(st)
|
|
}
|
|
r := &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,
|
|
Population: p.Population,
|
|
Colonists: p.Colonists,
|
|
Capital: p.Capital,
|
|
Material: p.Material,
|
|
AttackPower: attackPower,
|
|
}
|
|
bombPlanet(p, attackPower)
|
|
r.Wiped = p.Population == 0
|
|
return *r
|
|
}
|
|
|
|
func (c *Cache) ProduceBombings() []BombingPlanetReport {
|
|
report := make([]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
|
|
clear(p.Route)
|
|
} else {
|
|
// Если на планете остались также и колонисты, то они превращаются в население,
|
|
// а накопленная промышленность возмещает потери производства.
|
|
p.UnpackCOLtoPOP()
|
|
p.UnpackCAPtoIND()
|
|
}
|
|
}
|
|
return report
|
|
}
|
|
|
|
func bombPlanet(p *game.Planet, power float64) {
|
|
// Уничтожается население и колонисты в количестве равном [суммарной] мощности бомбардировки
|
|
if power > p.Population {
|
|
p.Population = 0
|
|
} else {
|
|
p.Population -= power
|
|
}
|
|
if power > p.Colonists {
|
|
p.Colonists = 0
|
|
} else {
|
|
p.Colonists -= power
|
|
}
|
|
// Такое же количество промышленности превращается в сырье
|
|
if power > p.Industry {
|
|
p.Material += p.Industry
|
|
p.Industry = 0
|
|
} else {
|
|
p.Material += power
|
|
p.Industry -= 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
|
|
}
|