diff --git a/internal/plugin/adventure_babysit.go b/internal/plugin/adventure_babysit.go index 4a42e80..501bce2 100644 --- a/internal/plugin/adventure_babysit.go +++ b/internal/plugin/adventure_babysit.go @@ -277,7 +277,14 @@ func (p *AdventurePlugin) runBabysitDaily(char *AdventureCharacter) { result.TreasureFound = nil // Mark action taken (babysit always uses a harvest action) - char.HarvestActionsUsed++ + isHol, _ := isHolidayToday() + harvestMax := maxHarvestActions + if isHol { + harvestMax++ + } + if char.HarvestActionsUsed < harvestMax { + char.HarvestActionsUsed++ + } char.ActionTakenToday = true char.LastActionDate = time.Now().UTC().Format("2006-01-02") diff --git a/internal/plugin/adventure_holidays_test.go b/internal/plugin/adventure_holidays_test.go index fc005a4..7c099db 100644 --- a/internal/plugin/adventure_holidays_test.go +++ b/internal/plugin/adventure_holidays_test.go @@ -256,31 +256,6 @@ func TestFixedHolidays_NoDuplicateMonthDay(t *testing.T) { } } -func TestHolidaySecondPromptRender(t *testing.T) { - char := &AdventureCharacter{ - DisplayName: "TestPlayer", - CombatLevel: 5, - MiningSkill: 3, - ForagingSkill: 2, - } - equip := map[EquipmentSlot]*AdvEquipment{ - SlotWeapon: {Tier: 1, Condition: 100, Name: "Iron Sword"}, - } - bonuses := &AdvBonusSummary{} - - text := renderAdvHolidaySecondPrompt(char, equip, bonuses) - - if !strings.Contains(text, "Action 1 complete") { - t.Error("second prompt should mention action 1 complete") - } - if !strings.Contains(text, "second action") { - t.Error("second prompt should mention second action") - } - if !strings.Contains(text, "Dungeon") { - t.Error("second prompt should list Dungeon option") - } -} - func TestDailySummary_HolidayBlock(t *testing.T) { players := []AdvPlayerDaySummary{ {DisplayName: "Alice", Activity: "dungeon", Location: "Cellar", Outcome: "success", LootValue: 500, HolidayActions: 2}, diff --git a/internal/plugin/adventure_render.go b/internal/plugin/adventure_render.go index 1f4a559..c537562 100644 --- a/internal/plugin/adventure_render.go +++ b/internal/plugin/adventure_render.go @@ -202,11 +202,18 @@ func renderAdvCharacterSheet(char *AdventureCharacter, equip map[EquipmentSlot]* } // Today's actions - combatRemaining := maxCombatActions - char.CombatActionsUsed + isHolSheet, _ := isHolidayToday() + combatMax := maxCombatActions + harvestMax := maxHarvestActions + if isHolSheet { + combatMax++ + harvestMax++ + } + combatRemaining := combatMax - char.CombatActionsUsed if combatRemaining < 0 { combatRemaining = 0 } - harvestRemaining := maxHarvestActions - char.HarvestActionsUsed + harvestRemaining := harvestMax - char.HarvestActionsUsed if harvestRemaining < 0 { harvestRemaining = 0 } @@ -336,57 +343,6 @@ func renderAdvMorningDM(char *AdventureCharacter, equip map[EquipmentSlot]*AdvEq return sb.String() } -// ── Holiday Second Action Prompt ────────────────────────────────────────────── - -func renderAdvHolidaySecondPrompt(char *AdventureCharacter, equip map[EquipmentSlot]*AdvEquipment, bonuses *AdvBonusSummary) string { - var sb strings.Builder - - sb.WriteString("✅ Action 1 complete.\n\nNow choose your **second action**:\n\n") - - sb.WriteString("**1️⃣ Dungeon:**\n") - for _, el := range advEligibleLocations(char, equip, AdvActivityDungeon, bonuses) { - warn := "" - if el.InPenaltyZone { - warn = " ⚠️" - } - sb.WriteString(fmt.Sprintf(" • %s (Tier %d, ~%.0f%% death%s)\n", el.Location.Name, el.Location.Tier, el.DeathPct, warn)) - } - - sb.WriteString("**2️⃣ Mine:**\n") - for _, el := range advEligibleLocations(char, equip, AdvActivityMining, bonuses) { - warn := "" - if el.InPenaltyZone { - warn = " ⚠️" - } - sb.WriteString(fmt.Sprintf(" • %s (Tier %d, ~%.0f%% death%s)\n", el.Location.Name, el.Location.Tier, el.DeathPct, warn)) - } - - sb.WriteString("**3️⃣ Forage:**\n") - for _, el := range advEligibleLocations(char, equip, AdvActivityForaging, bonuses) { - warn := "" - if el.InPenaltyZone { - warn = " ⚠️" - } - sb.WriteString(fmt.Sprintf(" • %s (Tier %d, ~%.0f%% death%s)\n", el.Location.Name, el.Location.Tier, el.DeathPct, warn)) - } - - sb.WriteString("**4️⃣ Fish:**\n") - for _, el := range advEligibleLocations(char, equip, AdvActivityFishing, bonuses) { - warn := "" - if el.InPenaltyZone { - warn = " ⚠️" - } - sb.WriteString(fmt.Sprintf(" • %s (Tier %d, ~%.0f%% death%s)\n", el.Location.Name, el.Location.Tier, el.DeathPct, warn)) - } - - sb.WriteString("**5️⃣ Shop** — buy/sell gear and loot\n") - sb.WriteString("**6️⃣ Blacksmith** — repair damaged equipment\n") - sb.WriteString("**7️⃣ Rest** — skip the second action\n\n") - sb.WriteString("Reply with the number and location, e.g: `1 Soggy Cellar`") - - return sb.String() -} - // ── Resolution DM ──────────────────────────────────────────────────────────── func renderAdvResolutionDM(result *AdvActionResult, char *AdventureCharacter) string {