From 976610b1bb2e6ef41b1e8ccd1e63428951f2366d Mon Sep 17 00:00:00 2001 From: Rakeela Date: Wed, 19 Apr 2023 11:37:40 -0700 Subject: [PATCH] Food supply tweaks, new card --- koboldsim/cards.go | 186 +++++++++++++++++++++++++++++++++++++++++++-- koboldsim/stats.go | 9 ++- 2 files changed, 188 insertions(+), 7 deletions(-) diff --git a/koboldsim/cards.go b/koboldsim/cards.go index 1098d8f..aa8ade8 100644 --- a/koboldsim/cards.go +++ b/koboldsim/cards.go @@ -18,6 +18,7 @@ var cards = []Card{ p.Stats.ScavengingIncome += 0.01 p.Stats.WarExpense += 0.02 p.Stats.FoodSupply += 0.01 + p.Stats.ObesogenicFood -= 0.01 p.Stats.ForeignRelations -= 0.02 return cardsim.MsgStr("Kobolds are known to be born warriors."), nil }, @@ -26,6 +27,7 @@ var cards = []Card{ p.Stats.ScavengingIncome -= 0.01 p.Stats.WarExpense -= 0.02 p.Stats.FoodSupply -= 0.01 + p.Stats.ObesogenicFood += 0.01 p.Stats.ForeignRelations += 0.02 return nil }, @@ -37,18 +39,22 @@ var cards = []Card{ Do: func(p *Player) (cardsim.Message, error) { p.Stats.BasePopulation += 40 p.Stats.MiningIncome += 0.02 + p.Stats.ConstructionIncome += 0.01 + p.Stats.ManufacturingIncome += 0.01 p.Stats.BureaucracyExpense += 0.01 p.Stats.FoodSupply -= 0.01 - p.Stats.Secrecy += 0.02 + p.Stats.Secrecy += 0.03 p.Stats.PointOfDimReturns += 0.01 return cardsim.MsgStr("Kobolds are known to be cowards hiding in the dark."), nil }, Undo: func(p *Player) error { p.Stats.BasePopulation -= 40 p.Stats.MiningIncome -= 0.02 + p.Stats.ManufacturingIncome -= 0.01 + p.Stats.ConstructionIncome -= 0.01 p.Stats.BureaucracyExpense -= 0.01 p.Stats.FoodSupply += 0.01 - p.Stats.Secrecy -= 0.02 + p.Stats.Secrecy -= 0.03 p.Stats.PointOfDimReturns += 0.01 return nil }, @@ -122,10 +128,10 @@ var cards = []Card{ UnenactedDesc: cardsim.MsgStr(`Your Minister of Administration is practically jumping for joy. "This is our opportunity to prove that we're a prosperous society and attract some fresh blood! We need to raise salaries in the bureaucracy, grant some time off to our bureaucrats to make sure they can attend, and try to hire talent away from other nations. We'll forge productive trade relations by this, you'll see!`), EnactedDesc: cardsim.MsgStr("[current policy] Your bureaucrats are really looking forward to attending, where they can boast about how the festival boosted their salaries."), Do: func(p *Player) (cardsim.Message, error) { - p.Stats.BasePopulation += 80 + p.Stats.BasePopulation += 60 p.Stats.ScavengingIncome += 0.01 p.Stats.BureaucracyExpense += 0.03 - p.Stats.FoodSupply += 0.01 + p.Stats.FoodSupply += 0.02 p.Stats.PointOfDimReturns += 0.01 return cardsim.MsgStr("Bureaucrats are considered pillars of society."), nil }, @@ -133,7 +139,7 @@ var cards = []Card{ p.Stats.BasePopulation -= 80 p.Stats.ScavengingIncome -= 0.01 p.Stats.BureaucracyExpense -= 0.03 - p.Stats.FoodSupply -= 0.01 + p.Stats.FoodSupply -= 0.02 p.Stats.PointOfDimReturns -= 0.01 return nil }, @@ -286,6 +292,7 @@ var cards = []Card{ p.Stats.ScavengingIncome -= 0.01 p.Stats.Secrecy -= 0.10 p.Stats.ForeignRelations += 0.05 + p.Stats.FoodSupply += 0.03 p.Stats.PointOfDimReturns += 0.1 return cardsim.MsgStr("The economic planning office formally plans for attrition among its merchants."), nil }, @@ -304,6 +311,7 @@ var cards = []Card{ p.Stats.ScavengingIncome += 0.01 p.Stats.Secrecy += 0.10 p.Stats.ForeignRelations -= 0.05 + p.Stats.FoodSupply -= 0.03 p.Stats.PointOfDimReturns += 0.1 return nil }, @@ -510,6 +518,7 @@ var cards = []Card{ p.Stats.AgricultureIncome += 0.01 p.Stats.WarExpense += 0.02 p.Stats.FoodSupply += 0.06 + p.Stats.ObesogenicFood += 0.03 p.Stats.Secrecy -= 0.20 p.Stats.ForeignRelations -= 0.04 return cardsim.MsgStr("Some farmers fight like five kobolds, but few fight like forty."), nil @@ -519,6 +528,7 @@ var cards = []Card{ p.Stats.AgricultureIncome -= 0.01 p.Stats.WarExpense -= 0.02 p.Stats.FoodSupply -= 0.06 + p.Stats.ObesogenicFood -= 0.03 p.Stats.Secrecy += 0.20 p.Stats.ForeignRelations += 0.04 return nil @@ -786,6 +796,172 @@ var cards = []Card{ }, }, // end of "The Eyes that Break the Ground" policies }, // end of "The Eyes that Break the Ground" card + &SwitchingCard{ // Card 8 + Name: cardsim.MsgStr("Planar Targeting"), + Desc: cardsim.MsgStr("Now that you've established a planar harvesting industry and have begun to tap into the economic potential of other planes of existence, your magi are seeking guidance as to where they should direct their efforts."), + After: ShuffleIntoBottomHalf, + IsValid: func(c Card, p *Player) bool { + return p.Stats.PlanarIncome > 0 + }, + Policies: []Policy{ + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr(`A calm, graceful, and scrawny mage with a big floppy hat has presented an entry-level option. "We should be tapping into one of the basic energy planes. While somewhat lacking in ambition and creating a risk of immolating students, the risks are less than many extraplanar contacts. This option also doesn't require an extensive infrastructure to begin."`), + EnactedDesc: cardsim.MsgStr("[current policy] Your colonies have established contact with energy planes to power spellcasting and potioneering."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.BasePopulation -= 50 + p.Stats.PlanarIncome += 0.03 + p.Stats.AlchemyIncome += 0.01 + p.Stats.PointOfDimReturns += 0.06 + return cardsim.MsgStr("Surviving mage-students are really excited about their new curriculum."), nil + }, + Undo: func(p *Player) error { + p.Stats.BasePopulation += 50 + p.Stats.PlanarIncome -= 0.03 + p.Stats.AlchemyIncome -= 0.01 + p.Stats.PointOfDimReturns -= 0.06 + return nil + }, + CanDo: YesWeCan, + }, + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr(`A questionably sane mage wearing a robe of eyes insists, "We should tap the elder realms! It is the fastest way to accelerate our planar harvesting! Tapping into them requires little more than a willingness to try, and the scraps taken from the societies in those realms yield technology beyond our wildest dreams! Don't flinch from the hazard; it is a step towards world conquest!"`), + EnactedDesc: cardsim.MsgStr("[current policy] Your nation is locked in conflict with the lesser minions of elder horrors as it seeks to steal power from the mindbreaking realms."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.BasePopulation -= 250 + p.Stats.PlanarIncome += 0.10 + p.Stats.AlchemyIncome += 0.05 + p.Stats.GadgetryIncome += 0.05 + p.Stats.WarExpense += 0.05 + p.Stats.ResearchSubsExpense += 0.01 + p.Stats.PointOfDimReturns += 0.5 + p.Stats.HiddenRelPenalty += 0.02 + // TODO: Make the effects worse. This will increase crime rates later on. + return cardsim.MsgStr("Several caves have been abandoned to an infestation of eldritch horrors."), nil + }, + Undo: func(p *Player) error { + p.Stats.BasePopulation += 250 + p.Stats.PlanarIncome -= 0.10 + p.Stats.AlchemyIncome -= 0.05 + p.Stats.GadgetryIncome -= 0.05 + p.Stats.WarExpense -= 0.05 + p.Stats.ResearchSubsExpense -= 0.01 + p.Stats.PointOfDimReturns -= 0.5 + p.Stats.HiddenRelPenalty -= 0.02 + return nil + }, + CanDo: func(b *BasicPolicy, p *Player) bool { + return p.Stats.PlanarIncome < 0.2 + }, + }, + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr(`A stout kobold in a plain robe showed up to say, "Beware! Every planar connection leaks strange energies into the world. The safe connections, once we've the skill to make them, are to the well-ordered and benevolent realms. They have alchemical wonders and great wisdom, but moreover the energies that leak off the connection will make society more well-ordered rather than less."`), + EnactedDesc: cardsim.MsgStr("[current policy] Your planar explorers have been directed to the planes of law in hopes of finding the secret of a well-governed society."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.PlanarIncome += 0.03 + p.Stats.AlchemyIncome += 0.03 + p.Stats.BureaucracyExpense -= 0.01 + p.Stats.PointOfDimReturns += 0.25 + p.Stats.HiddenRelPenalty += 0.01 + // TODO: This will affect crime and corruption rates. + return cardsim.MsgStr("Planar explorers find their work boring."), nil + }, + Undo: func(p *Player) error { + p.Stats.PlanarIncome -= 0.03 + p.Stats.AlchemyIncome -= 0.03 + p.Stats.BureaucracyExpense += 0.01 + p.Stats.PointOfDimReturns -= 0.25 + p.Stats.HiddenRelPenalty -= 0.01 + return nil + }, + CanDo: func(b *BasicPolicy, p *Player) bool { + return p.Stats.PlanarIncome > 0.11 + }, + }, + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr(`Your Minister of Planar Studies crashed the meeting dressed like a wealthy scavenger. "Skip these esoteric planes! We want alternate material planes so we can steal stuff that's guaranteed to teach us more about how THIS reality works. If we start hunting, maybe we can even hit the real goldmine: a graveyard world whose gadgetry is post-ownership. Besides, uh... Meat is meat, mostly. We can hunt on other worlds. The alchemists can work with what we can't eat."`), + EnactedDesc: cardsim.MsgStr("[current policy] Your planar harvesters try to scan the multiverse for scavenging targets."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.AlchemyIncome += 0.01 + p.Stats.GadgetryIncome += 0.05 + p.Stats.ScavengingIncome += 0.05 + p.Stats.FoodSupply += 0.02 + return cardsim.MsgStr("Planes without kobolds tell stories of reptillian infiltrators."), nil + }, + Undo: func(p *Player) error { + p.Stats.AlchemyIncome -= 0.01 + p.Stats.GadgetryIncome -= 0.05 + p.Stats.ScavengingIncome -= 0.05 + p.Stats.FoodSupply -= 0.02 + return nil + }, + CanDo: func(b *BasicPolicy, p *Player) bool { + return p.Stats.PlanarIncome > 0.11 + }, + }, + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr(`The mage in the robe of eyes is in a celebratory mood, pouring glasses for anyone who'll take them from a bottle of some bluish-black liquid that you're pretty sure is dangerous. "Our planar harvesting potential has grown magnificently! If we target the elder planes, they'll... okay, they won't exactly fear us, but we can start taking some real treasures from them! Great spells! Exotic reagents! Unique treasures! Let's lean into the hazard!`), + EnactedDesc: cardsim.MsgStr("[current policy] Your nation is sacrificing safety and sanity in thievery attempts that only serve the plans of the elder gods."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.BasePopulation -= 350 + p.Stats.PlanarIncome += 0.15 + p.Stats.AlchemyIncome += 0.10 + p.Stats.GadgetryIncome += 0.10 + p.Stats.WarExpense += 0.05 + p.Stats.ResearchSubsExpense += 0.01 + p.Stats.PointOfDimReturns += 0.5 + p.Stats.ForeignRelations -= 0.05 + p.Stats.HiddenRelPenalty += 0.05 + // TODO: This will be a nightmare for crime and corruption! + return cardsim.MsgStr("Nobody dares touch the treasures in the national vault."), nil + }, + Undo: func(p *Player) error { + p.Stats.BasePopulation += 350 + p.Stats.PlanarIncome -= 0.15 + p.Stats.AlchemyIncome -= 0.10 + p.Stats.GadgetryIncome -= 0.10 + p.Stats.WarExpense -= 0.05 + p.Stats.ResearchSubsExpense -= 0.01 + p.Stats.PointOfDimReturns -= 0.5 + p.Stats.ForeignRelations += 0.05 + p.Stats.HiddenRelPenalty -= 0.05 + return nil + }, + CanDo: func(b *BasicPolicy, p *Player) bool { + return p.Stats.PlanarIncome >= 0.2 + }, + }, + &VerbosePolicy{ + Default: &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr("Rejecting the safety risks of extraplanar travels will call your entire planar harvesting industry into question, but it might be the safest option."), + EnactedDesc: cardsim.MsgStr("Persisting in your rejection of planar targeting will change nothing."), + Do: func(p *Player) (cardsim.Message, error) { + p.Stats.BasePopulation += 40 + p.Stats.PlanarIncome -= 0.01 + return cardsim.MsgStr("The nation recently gained a few immigrants reassured by the lack of planar portals."), nil + }, + Undo: func(p *Player) error { + p.Stats.BasePopulation -= 40 + p.Stats.PlanarIncome += 0.01 + return nil + }, + CanDo: YesWeCan, + }, + Variants: []Policy{ + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr("The energy planes are popular among students who survive accessing them. Student safety would benefit from rejecting planar targeting, but your economy would take a blow."), + }, + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr("People are begging you to close the eldritch portals. They'll take anything else. Literally anything else."), + }, + &DisabledPolicy{}, // There's no closing the plane to a portal of law save by choosing something else. + &DisabledPolicy{}, // Until I implement a downside for the planar scavengers, there's no closing this one either. + &BasicPolicy{ + UnenactedDesc: cardsim.MsgStr("People are begging you to close the eldritch portals. They'll take anything else. Literally anything else."), + }, + }, + }, + }, // end of "Planar Targeting" policies + }, // end of "Planar Targeting" card } // end of card list func initDeck(d *cardsim.Deck[*KoboldMine]) { diff --git a/koboldsim/stats.go b/koboldsim/stats.go index d098f99..3278fcb 100644 --- a/koboldsim/stats.go +++ b/koboldsim/stats.go @@ -40,6 +40,7 @@ type KoboldMine struct { FaithExpense float64 `cardsim:"stathidden" cardsim_name:"Faith Investment"` FoodSupply float64 `cardsim:"stathidden"` + ObesogenicFood float64 `cardsim:"stathidden"` ForeignRelations float64 `cardsim:"stathidden"` HiddenRelPenalty float64 `cardsim:"stathidden"` // Lower is better. Secrecy float64 `cardsim:"stathidden"` @@ -225,8 +226,12 @@ func (k *KoboldMine) DisplayedFoodSupply() float64 { return (k.FoodSupply - 1) * 100 } +func (k *KoboldMine) StatObesogenicity() float64 { + return (k.ObesogenicFood - 1) * 100 +} + func (k *KoboldMine) StatObesity() float64 { - return 100 / (2.3 + math.Exp(-0.04*(k.DisplayedFoodSupply()-37))) + return (100 / (2.3 + math.Exp(-0.04*(k.DisplayedFoodSupply()-37)))) + 100/(2.3+math.Exp(-0.04*(k.StatObesogenicity()-37))) } func (k *KoboldMine) TrueForeignRelations() float64 { @@ -384,7 +389,7 @@ func (k *KoboldMine) Stats() []cardsim.Stat { func NewKoboldMine() *KoboldMine { return &KoboldMine{ - BasePopulation: 1030, + BasePopulation: 1025, MiningIncome: 0.15, ScavengingIncome: 0.1, AlchemyIncome: 0.01,