package controller import ( "github.com/google/uuid" "github.com/iliadenisov/galaxy/server/internal/model/game" ) func (c *Cache) ProduceBombings() []*game.Bombing { report := make([]*game.Bombing, 0) for pn, enemies := range c.collectBombingGroups() { p := c.MustPlanet(pn) if !p.Owned() { continue } for ri, groups := range enemies { br := c.bombingReport(p, ri, groups) report = append(report, br) if br.Wiped { break } } if p.Population == 0 { p.Free() } else { // Если на планете остались также и колонисты, то они превращаются в население, // а накопленная промышленность возмещает потери производства. p.UnpackColonists() p.UnpackCapital() } } return report } func (c *Cache) bombingReport(p *game.Planet, ri int, groups []int) *game.Bombing { attackPower := 0. for _, i := range groups { sg := c.ShipGroup(i) st := c.ShipGroupShipClass(i) attackPower += sg.BombingPower(st) } r := &game.Bombing{ ID: uuid.New(), PlanetOwnedID: *p.Owner, 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: game.F(attackPower), } bombPlanet(p, attackPower) r.Wiped = p.Population == 0 return r } 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.OwnedBy(sg.OwnerID) || !p.Owned() { 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 }