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 p.Production = game.ProductionNone.AsType(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 }