mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 00:52:40 +00:00
N4/E1: T3 housing payoffs + a home-rest "well-rested" buff
Turn the dead top housing tiers into something worth buying. All three
land without a schema bump, and TestCombatCharacterization stays
byte-identical (the balance corpus never sets the new fields).
T3 trophy room: treasure cap 3->4 at HouseTier>=3 (maxTreasuresForTier).
Enforced at the save gate only -- HouseTier is never written downward,
so a held 4th treasure below tier 3 is unreachable and a load-time cap in
computeAdvBonuses would just add a query for an impossible state. The
all-irreplaceable manual discard prompt now lists the 4th slot too.
T3 workshop: +5% craft success at HouseTier>=3, lifting the cap 0.95->0.98
so a maxed forager still gains. craftingSuccessRate takes a workshopBonus,
threaded through autoCraftConsumables and renderRecipesKnown.
Well-rested buff (replaces the plan's T4 "inn-quality rest", a verified
no-op -- home rest already equals inn rest). Home-only (the inn and a
tier-1 shack grant nothing), starts at T2 and grows through T4, expires at
the next long rest:
- Temp HP cushion (8/12/16% of MaxHP). TempHP was a dormant field; wired
into applyDnDHPScaling as MaxHP headroom -- additive and golden-safe.
- Bonus spell slots (+1/+2/+3 at the caster's highest slot level), the
real reward, lifting casters who trail on spell-pool richness.
applyLongRestSpellSlots resets the pool to base then folds in the
bonus; expiry is stateless (next rest's reset drops it).
Magnitudes are tunable defaults; revisit against the post-parties
re-baseline.
Claude-Session: https://claude.ai/code/session_017mEwUmmS7aQTP2NQXj6rUa
This commit is contained in:
@@ -346,15 +346,34 @@ var craftingRecipes = []CraftingRecipe{
|
||||
{Result: "Voidstone Shard", Ingredients: []string{"Voidstone", "Mythril Ore"}, MinForaging: 30, Tier: 5},
|
||||
}
|
||||
|
||||
// craftingSuccessRate returns the success chance for a recipe given foraging level.
|
||||
// Base rate is 50% at minimum level, +3% per 5 levels above minimum, capped at 95%.
|
||||
func craftingSuccessRate(foragingLevel, minForaging int) float64 {
|
||||
// houseTierWorkshop is the T3 "Comfortable" house that unlocks the workshop —
|
||||
// a flat craft-success bonus while crafting at home.
|
||||
const houseTierWorkshop = 3
|
||||
|
||||
// homeWorkshopCraftBonus returns the additive craft-success bonus from a T3+
|
||||
// home workshop. Tier 1/2 and no house grant none.
|
||||
func homeWorkshopCraftBonus(houseTier int) float64 {
|
||||
if houseTier >= houseTierWorkshop {
|
||||
return 0.05
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// craftingSuccessRate returns the success chance for a recipe given foraging
|
||||
// level. Base rate is 50% at minimum level, +3% per 5 levels above minimum,
|
||||
// capped at 95%. A T3+ home workshop adds workshopBonus on top and lifts the
|
||||
// cap to 98%, so a maxed forager still gains a little from the bench.
|
||||
func craftingSuccessRate(foragingLevel, minForaging int, workshopBonus float64) float64 {
|
||||
base := 0.50
|
||||
levelsAbove := foragingLevel - minForaging
|
||||
bonus := float64(levelsAbove) / 5.0 * 0.03
|
||||
rate := base + bonus
|
||||
if rate > 0.95 {
|
||||
return 0.95
|
||||
rate := base + bonus + workshopBonus
|
||||
cap := 0.95
|
||||
if workshopBonus > 0 {
|
||||
cap = 0.98
|
||||
}
|
||||
if rate > cap {
|
||||
return cap
|
||||
}
|
||||
return rate
|
||||
}
|
||||
@@ -369,7 +388,7 @@ type CraftResult struct {
|
||||
// their current foraging level, plus a teaser line for the next unlock
|
||||
// threshold. Hides exact ingredient lists for recipes the player hasn't
|
||||
// unlocked — only the count of locked recipes is shown.
|
||||
func renderRecipesKnown(foragingLevel int) string {
|
||||
func renderRecipesKnown(foragingLevel int, workshopBonus float64) string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("🧪 **Crafting Recipes** — Foraging Lv.%d\n\n", foragingLevel))
|
||||
|
||||
@@ -377,6 +396,9 @@ func renderRecipesKnown(foragingLevel int) string {
|
||||
sb.WriteString("_Auto-crafting unlocks at Foraging Lv.10. Keep gathering._")
|
||||
return sb.String()
|
||||
}
|
||||
if workshopBonus > 0 {
|
||||
sb.WriteString(fmt.Sprintf("_🔨 Home workshop: +%.0f%% craft success._\n\n", workshopBonus*100))
|
||||
}
|
||||
|
||||
// Group recipes by tier, list those known.
|
||||
known := map[int][]CraftingRecipe{}
|
||||
@@ -402,7 +424,7 @@ func renderRecipesKnown(foragingLevel int) string {
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf("**Tier %d** (Foraging %d+)\n", tier, recipes[0].MinForaging))
|
||||
for _, r := range recipes {
|
||||
rate := craftingSuccessRate(foragingLevel, r.MinForaging) * 100
|
||||
rate := craftingSuccessRate(foragingLevel, r.MinForaging, workshopBonus) * 100
|
||||
sb.WriteString(fmt.Sprintf(" • %s — %s (%.0f%% success)\n",
|
||||
r.Result, strings.Join(r.Ingredients, " + "), rate))
|
||||
}
|
||||
@@ -433,7 +455,7 @@ var craftXPFailure = map[int]int{1: 3, 2: 5, 3: 8, 4: 12, 5: 18}
|
||||
//
|
||||
// Side effects: grants foraging XP per attempt (success > failure) and bumps
|
||||
// the player's CraftsSucceeded counter on each success.
|
||||
func autoCraftConsumables(userID id.UserID, items []AdvItem, foragingLevel int) ([]CraftResult, []AdvItem) {
|
||||
func autoCraftConsumables(userID id.UserID, items []AdvItem, foragingLevel int, workshopBonus float64) ([]CraftResult, []AdvItem) {
|
||||
if foragingLevel < 10 {
|
||||
return nil, items
|
||||
}
|
||||
@@ -452,7 +474,7 @@ func autoCraftConsumables(userID id.UserID, items []AdvItem, foragingLevel int)
|
||||
break
|
||||
}
|
||||
|
||||
rate := craftingSuccessRate(foragingLevel, bestRecipe.MinForaging)
|
||||
rate := craftingSuccessRate(foragingLevel, bestRecipe.MinForaging, workshopBonus)
|
||||
success := rand.Float64() < rate
|
||||
|
||||
if success {
|
||||
|
||||
Reference in New Issue
Block a user