package main import ( "fmt" "math/rand" ) type PlanetType uint8 func (p PlanetType) String() string { switch p { case EarthLike: return "Earth-Like" case Mountain: return "Mountain" case Ocean: return "Oceanic" case Volcanic: return "Volcanic" case Glacial: return "Glacial" default: return "" } } func (p PlanetType) Symbol() string { switch p { case EarthLike: return "E" case Mountain: return "M" case Ocean: return "O" case Volcanic: return "V" case Glacial: return "G" default: return "" } } func (p PlanetType) ProductionOre() int { switch p { case EarthLike: return 6 case Mountain: return 4 case Ocean: return 8 case Volcanic: return 3 case Glacial: return 10 default: return -1 } } func (p PlanetType) ProductionOrg() int { switch p { case EarthLike: return 5 case Mountain: return 8 case Ocean: return 3 case Volcanic: return -1 case Glacial: return -1 default: return -1 } } func (p PlanetType) ProductionEqu() int { switch p { case EarthLike: return 8 case Mountain: return 6 case Ocean: return 7 case Volcanic: return -1 case Glacial: return 10 default: return -1 } } func (p PlanetType) ProductionFig() int { switch p { case EarthLike: return 10 case Mountain: return 7 case Ocean: return 4 case Volcanic, Glacial: return 12 default: return -1 } } func (p PlanetType) ProductionShield() int { switch p { case EarthLike: return 25 case Mountain: return 20 case Ocean: return 28 case Volcanic: return 29 case Glacial: return 30 default: return -1 } } const ( // Production: The Ratio is 1:X where X is the number of population designated (This excludes Fighters and Shields, which are total population) EarthLike PlanetType = iota // Production: Ore=1:6, Org=1:5, Equ=1:8, Fig=1:10, Shields=1:25 Mountain // Production: Ore=1:4, Org=1:8, Equ=1:6, Fig=1:7, Shields=1:20 Ocean // Production: Ore=1:8, Org=1:3, Equ=1:6, Fig=1:4, Shields=1:28 Volcanic // Production: Ore=1:3, Org=NA, Equ=NA, Fig=1:12, Shields=1:29 Glacial // Production: Ore=1:10, Org=NA, Equ=1:10, Fig=1:12, Shields=1:30 ) type Planet struct { ID ID Name string Owner ID CorpOwned bool Type PlanetType CitadelLvl uint16 // Lvl1 Unlocks Fighter Defense and Bank, Lvl2 Unlocks Planetary Cannon, Lvl3 Unlocks Production for Shields, Lvl4 Unlocks Teleport and TeleportShip, Lvl5 Unlocks Warp TeleportDist uint64 // Beam the player to another ship TeleportShipDist uint64 // Beam the player in the current ship WarpDist uint64 // Move the planet Credits uint64 Shields uint64 // Planetary Cannon Settings CannonSector uint8 // Percentage of fuel Ore too consume per shot when a non-corp or hostile ship enters the sector (1 ore to 5 damage) CannonLanding uint8 // Percentage of fuel Ore too consume per shot when a non-corp or hostile ship attempts to land on the planet (1 ore to 10 damage) // Planetary Defense (Fighter) Settings FighterLanding uint8 // Percentage of fighters too attack a non-corp or hostile ship when they attempt to land on the planet (fighter odds 1:2, essentially double damage) // Inventory Population uint64 // Population in supposed 1,000s Ore uint64 // Per Ton MaxOre uint64 Org uint64 MaxOrg uint64 Equ uint64 MaxEqu uint64 Fighters uint64 // Per Unit // Production Settings ProductOre uint64 // Population placed for fuel Ore production (based on planet type) ProductOrg uint64 // Organics production ProductEqu uint64 // Equipment production } func (p *Planet) Produce() string { out := "" if p.Type.ProductionOre() != -1 { ore := p.ProductOre / uint64(p.Type.ProductionOre()) if p.Ore+ore > p.MaxOre { over := p.MaxOre - (p.Ore + ore) out += fmt.Sprintf("Ore Produced: %d (%d over)", ore, over) p.Ore += ore - over } else { out += fmt.Sprintf("Ore Produced: %d", ore) p.Ore += ore } } if p.Type.ProductionOrg() != -1 { org := p.ProductOrg / uint64(p.Type.ProductionOrg()) if len(out) != 0 { out += "\r\n" } if p.Org+org > p.MaxOrg { over := p.MaxOrg - (p.Org + org) out += fmt.Sprintf("Organics Produced: %d (%d over)", org, over) p.Org += org - over } else { out += fmt.Sprintf("Organics Produced: %d", org) p.Org += org } } if p.Type.ProductionEqu() != -1 { equ := p.ProductEqu / uint64(p.Type.ProductionEqu()) if len(out) != 0 { out += "\r\n" } if p.Equ+equ > p.MaxEqu { over := p.MaxEqu - (p.Equ + equ) out += fmt.Sprintf("Equipment Produced: %d (%d over)", equ, over) p.Equ += equ - over } else { out += fmt.Sprintf("Equipment Produced: %d", equ) p.Equ += equ } } if p.Type.ProductionFig() != -1 { amt := p.Population / uint64(p.Type.ProductionFig()) if len(out) != 0 { out += "\r\n" } out += fmt.Sprintf("Fighters Produced: %d", amt) p.Fighters += amt } if p.Type.ProductionShield() != -1 { amt := p.Population / uint64(p.Type.ProductionShield()) if len(out) != 0 { out += "\r\n" } out += fmt.Sprintf("Shields Produced: %d", amt) p.Shields += amt } // TODO: Refine Population growth and declines // Right now it's a 1d20 anything higher than 12 growth, lower than is decline // Also the amount grown or declined is random of the same base math (out of ever 100 pop, so best to keep your planets at even 100s and nothing will ever happen!?!) if p.Population >= 100 && rand.Intn(21)+1 >= 12 { perc := int64(p.Population % 100) amt := uint64(rand.Int63n(perc + 1)) if amt == 0 { out += "\r\n" return out } if len(out) != 0 { out += "\r\n" } out += fmt.Sprintf("Population Growth: %d", amt) p.Population += amt } else if p.Population >= 100 { perc := int64(p.Population % 100) amt := uint64(rand.Int63n(perc + 1)) if amt == 0 { out += "\r\n" return out } if len(out) != 0 { out += "\r\n" } if p.Population < amt { amt = p.Population } out += fmt.Sprintf("Population Decline: %d", amt) p.Population -= amt if p.Population == 0 { out += "\r\nNo Population!" } } out += "\r\n" return out }