mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
N2/B1+B4+C4: tempering, the expedition achievement wing, arena seasons
B1 — tempering. `!adventure temper` pushes an owned magic item one rung up the rarity ladder at the blacksmith, capped at Legendary. Rarity lives on the registry definition, so an upgraded instance records its progress as a `temper` step count on its own row (adventure_inventory, magic_item_equipped) and effective rarity is derived on read. The stored base rarity is never written back, so an item cannot double-bump across a load/save round-trip. Effects flow through the existing rarity scalars — no new combat math, and the Legendary cap means this accelerates reaching the current ceiling rather than raising it. Costs mirror the crafting ladder (10k/25k/60k/150k, Foraging 15/20/25/30). Only the Legendary rung consumes a T5 material; gating the lower rungs on one would make tempering unreachable until a player already clears T5. Two plan anchors were wrong: thyraks_core and portal_fragment are not loot-note strings needing promotion — they are UniqueAlways slate entries that already materialize as inventory rows on every T5 clear. B4 — expedition achievement wing: first-clear and all-zones-cleared per tier (10), a quiet-clear for keeping peak threat under 50, and temper_legendary. The quiet-clear requires max_threat_seen to be *present*, not merely low: recordMaxThreat samples only on day rollover and never stores a zero, so an absent key means no threat history, not low threat. The plan's no-death-T4 achievement is not shipped — no per-expedition death counter exists — and pet-saved-my-life already ships as combat_pet_save. C4 — arena seasons. Standings are derived from arena_history.created_at per calendar quarter rather than wiping arena_stats: same visible reset, but lifetime totals survive for `!arena stats` and no destructive job can fire twice. Crowns archive to arena_season_titles rather than player_meta.title, which already carries the Survivalist milestone. Rollover rides the existing midnight ticker and self-dedups on the season key, so a bot that was down on the boundary catches up on its next wake.
This commit is contained in:
@@ -121,6 +121,7 @@ type AdvItem struct {
|
||||
Value int64
|
||||
Slot EquipmentSlot // non-empty for MasterworkGear
|
||||
SkillSource string // non-empty for MasterworkGear
|
||||
Temper int // rarity steps above base; magic_item rows only
|
||||
}
|
||||
|
||||
type AdvBuff struct {
|
||||
@@ -560,7 +561,7 @@ func saveAdvEquipment(userID id.UserID, eq *AdvEquipment) error {
|
||||
func loadAdvInventory(userID id.UserID) ([]AdvItem, error) {
|
||||
d := db.Get()
|
||||
rows, err := d.Query(`
|
||||
SELECT id, name, item_type, tier, value, slot, skill_source
|
||||
SELECT id, name, item_type, tier, value, slot, skill_source, temper
|
||||
FROM adventure_inventory WHERE user_id = ?
|
||||
ORDER BY tier DESC, value DESC`, string(userID))
|
||||
if err != nil {
|
||||
@@ -572,7 +573,7 @@ func loadAdvInventory(userID id.UserID) ([]AdvItem, error) {
|
||||
for rows.Next() {
|
||||
var it AdvItem
|
||||
var slot string
|
||||
if err := rows.Scan(&it.ID, &it.Name, &it.Type, &it.Tier, &it.Value, &slot, &it.SkillSource); err != nil {
|
||||
if err := rows.Scan(&it.ID, &it.Name, &it.Type, &it.Tier, &it.Value, &slot, &it.SkillSource, &it.Temper); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
it.Slot = EquipmentSlot(slot)
|
||||
@@ -584,9 +585,19 @@ func loadAdvInventory(userID id.UserID) ([]AdvItem, error) {
|
||||
func addAdvInventoryItem(userID id.UserID, item AdvItem) error {
|
||||
d := db.Get()
|
||||
_, err := d.Exec(`
|
||||
INSERT INTO adventure_inventory (user_id, name, item_type, tier, value, slot, skill_source)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
string(userID), item.Name, item.Type, item.Tier, item.Value, string(item.Slot), item.SkillSource)
|
||||
INSERT INTO adventure_inventory (user_id, name, item_type, tier, value, slot, skill_source, temper)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
string(userID), item.Name, item.Type, item.Tier, item.Value, string(item.Slot), item.SkillSource, item.Temper)
|
||||
return err
|
||||
}
|
||||
|
||||
// temperInventoryItem records a tempering step on an un-equipped magic item.
|
||||
// Tier and value move with the item's new effective rarity so it keeps sorting
|
||||
// and selling correctly.
|
||||
func temperInventoryItem(itemID int64, temper, tier int, value int64) error {
|
||||
_, err := db.Get().Exec(
|
||||
`UPDATE adventure_inventory SET temper = ?, tier = ?, value = ? WHERE id = ?`,
|
||||
temper, tier, value, itemID)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user