mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 00:32:40 +00:00
Fix arena gear lockout, extend DM window, scrub mining flavor
Arena helmet auto-equip now preserves the existing helmet to inventory
(or stashes the new drop if the existing piece is strictly higher tier),
and arena gear can be re-equipped via !adventure equip. Shop only blocks
swaps that aren't an upgrade over current arena tier. DM response window
bumped from 15m to 3h so NPC/treasure/shop prompts don't expire while
players are AFK. MiningSuccess flavor pools no longer name specific ores
in prose — uses {ore}/{location}/{tool} placeholders so the narration
matches the actual loot.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ func (p *AdventurePlugin) advUserLock(userID id.UserID) *sync.Mutex {
|
||||
return val.(*sync.Mutex)
|
||||
}
|
||||
|
||||
const advDMResponseWindow = 15 * time.Minute
|
||||
const advDMResponseWindow = 3 * time.Hour
|
||||
|
||||
// advMarkMenuSent records that an actionable adventure menu was DM'd to the user.
|
||||
// Only bare-number DM replies within this window will be treated as adventure choices.
|
||||
@@ -1108,7 +1108,7 @@ func (p *AdventurePlugin) checkTreasureDrop(userID id.UserID, char *AdventureCha
|
||||
NewTreasure: drop.Def,
|
||||
Existing: existing,
|
||||
},
|
||||
ExpiresAt: time.Now().Add(5 * time.Minute),
|
||||
ExpiresAt: time.Now().Add(advDMResponseWindow),
|
||||
})
|
||||
|
||||
text := renderAdvTreasureDiscardPrompt(drop.Def, existing)
|
||||
|
||||
@@ -1040,6 +1040,15 @@ func arenaGearByTier(tier int) *ArenaGearSet {
|
||||
return &arenaGearSets[tier-1]
|
||||
}
|
||||
|
||||
func arenaGearByName(name string) *ArenaGearSet {
|
||||
for i := range arenaGearSets {
|
||||
if arenaGearSets[i].HelmetName == name {
|
||||
return &arenaGearSets[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// arenaRollHelmetDrop checks if a helmet should drop and equips it if the player
|
||||
// doesn't already have an arena helmet at this tier or higher. If they do, the
|
||||
// drop is silently discarded (no duplicate drops).
|
||||
@@ -1063,14 +1072,49 @@ func (p *AdventurePlugin) arenaRollHelmetDrop(userID id.UserID, tier int) *Arena
|
||||
}
|
||||
|
||||
helmet, hasHelmet := equip[SlotHelmet]
|
||||
if hasHelmet && (helmet.ArenaTier >= tier || helmet.Tier > tier) {
|
||||
// Already has same-or-better arena helmet, or a higher-tier normal helmet — discard
|
||||
hasRealHelmet := hasHelmet && helmet.Tier > 0
|
||||
|
||||
// Discard only if existing is a same-or-better arena helmet (duplicate suppression).
|
||||
if hasRealHelmet && helmet.ArenaTier >= tier {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equip the arena helmet
|
||||
// If existing is a strictly better non-arena helmet, stash the drop in inventory
|
||||
// so the player can equip it later via !adventure equip rather than overwriting.
|
||||
if hasRealHelmet && helmet.ArenaTier == 0 && helmet.Tier > tier {
|
||||
if err := addAdvInventoryItem(userID, AdvItem{
|
||||
Name: gear.HelmetName,
|
||||
Type: "ArenaGear",
|
||||
Tier: tier,
|
||||
Slot: SlotHelmet,
|
||||
}); err != nil {
|
||||
slog.Error("arena: failed to stash arena helmet drop", "user", userID, "err", err)
|
||||
return nil
|
||||
}
|
||||
return gear
|
||||
}
|
||||
|
||||
// Auto-equip: move the old helmet to inventory first (preserving its flavor)
|
||||
// so the player doesn't silently lose it.
|
||||
if hasRealHelmet {
|
||||
oldType := "ShopGear"
|
||||
if helmet.Masterwork {
|
||||
oldType = "MasterworkGear"
|
||||
} else if helmet.ArenaTier > 0 {
|
||||
oldType = "ArenaGear"
|
||||
}
|
||||
if err := addAdvInventoryItem(userID, AdvItem{
|
||||
Name: helmet.Name,
|
||||
Type: oldType,
|
||||
Tier: helmet.Tier,
|
||||
Slot: SlotHelmet,
|
||||
SkillSource: helmet.SkillSource,
|
||||
}); err != nil {
|
||||
slog.Error("arena: failed to move old helmet to inventory", "user", userID, "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !hasHelmet {
|
||||
// Shouldn't happen (all slots created at character creation), but be safe
|
||||
helmet = &AdvEquipment{Slot: SlotHelmet}
|
||||
}
|
||||
helmet.Tier = tier
|
||||
@@ -1079,6 +1123,8 @@ func (p *AdventurePlugin) arenaRollHelmetDrop(userID id.UserID, tier int) *Arena
|
||||
helmet.ActionsUsed = 0
|
||||
helmet.ArenaTier = tier
|
||||
helmet.ArenaSet = gear.SetKey
|
||||
helmet.Masterwork = false
|
||||
helmet.SkillSource = ""
|
||||
|
||||
if err := saveAdvEquipment(userID, helmet); err != nil {
|
||||
slog.Error("arena: failed to save arena helmet drop", "user", userID, "err", err)
|
||||
|
||||
@@ -363,9 +363,9 @@ var MiningSuccess = map[int][]string{
|
||||
|
||||
"In and out. {ore}, €{value}, zero cave-ins, one bat that thought about it " +
|
||||
"and decided not to. Your {tool} is slightly worse. Everything else is better. " +
|
||||
"By Surface Pits standards, a professional operation.",
|
||||
"By {location} standards, a professional operation.",
|
||||
|
||||
"The copper vein ran further than the map suggested. Further and richer. " +
|
||||
"The seam ran further than the map suggested. Further and richer. " +
|
||||
"You took {ore} worth €{value} and left more than you could carry. " +
|
||||
"This is the correct response to a rich vein. Come back tomorrow. " +
|
||||
"Bring a bigger bag. Bring a better pickaxe.",
|
||||
@@ -380,68 +380,69 @@ var MiningSuccess = map[int][]string{
|
||||
"and the rock rewarded you for it. This is the entire transaction. " +
|
||||
"It is, when it works, genuinely satisfying.",
|
||||
|
||||
"The tin seam yielded more than expected and the coal beneath it " +
|
||||
"turned out to have a copper pocket behind it " +
|
||||
"The upper seam yielded more than expected and the layer beneath it " +
|
||||
"turned out to have a pocket behind it " +
|
||||
"that wasn't on any map because nobody had gone that far before. " +
|
||||
"You went that far. {ore} total, €{value}. " +
|
||||
"The {tool} is worse. The discovery is better.",
|
||||
},
|
||||
|
||||
2: {
|
||||
"Iron Ridge delivered today. {ore} extracted, €{value} assessed, " +
|
||||
"{location} delivered today. {ore} extracted, €{value} assessed, " +
|
||||
"cave troll acknowledged and navigated around with something approaching grace. " +
|
||||
"The {tool} performed admirably. Your back has filed a formal complaint. " +
|
||||
"The back's complaint is noted and will not change the outcome.",
|
||||
|
||||
"A good seam. A real seam — proper iron, " +
|
||||
"the kind where the rock splits cleanly and the ore sits in it " +
|
||||
"like it's been waiting. {ore} worth €{value}. {xp} XP. " +
|
||||
"A good seam. A real seam — the kind where the rock splits cleanly " +
|
||||
"and the ore sits in it like it's been waiting. " +
|
||||
"{ore} worth €{value}. {xp} XP. " +
|
||||
"This is what mining is supposed to feel like. " +
|
||||
"Remember it for the days it doesn't.",
|
||||
|
||||
"The lead pocket was deeper than the iron, which meant going deeper " +
|
||||
"than planned, which meant more exposure to everything Iron Ridge contains. " +
|
||||
"The deeper pocket was further in than the surface yield suggested, " +
|
||||
"which meant going deeper than planned, " +
|
||||
"which meant more exposure to everything {location} contains. " +
|
||||
"You made it. {ore} worth €{value}. The depth was worth it. " +
|
||||
"The {tool} has opinions about the depth. The opinions are structural.",
|
||||
},
|
||||
|
||||
3: {
|
||||
"Silver. Real silver, properly embedded, not quartz, not illusion, " +
|
||||
"not iron-coloured rock lying about its nature. Silver. " +
|
||||
"Whatever you came down here for, you took it. No illusions, no " +
|
||||
"iron-coloured rock lying about its nature. " +
|
||||
"{ore} worth €{value}. {xp} XP. Your {tool} is a real tool " +
|
||||
"and this was a real seam and you extracted the silver. " +
|
||||
"and this was a real seam and you extracted what was in it. " +
|
||||
"That's the whole job. Today the whole job got done.",
|
||||
|
||||
"The Silver Seam at depth, past the quartz formations, " +
|
||||
"{location} at depth, past the decorative formations, " +
|
||||
"past the section that looks better than it is, " +
|
||||
"down to where the silver sits in the rock like an argument for effort. " +
|
||||
"down to where the yield sits in the rock like an argument for effort. " +
|
||||
"{ore}, €{value}, {xp} XP, home by sunset. " +
|
||||
"A good day. In a mine. Those exist.",
|
||||
},
|
||||
|
||||
4: {
|
||||
"Deeprock gold. Actual gold, not pyrite, not gold-coloured copper, " +
|
||||
"not optimism in mineral form. Gold. {ore} worth €{value}. " +
|
||||
"The Deeprock tried to discourage you with atmosphere and pressure. " +
|
||||
"You brought a Mithril Pickaxe and ignored the atmosphere.",
|
||||
"Proper haul. No pyrite, no gold-coloured copper, " +
|
||||
"no optimism in mineral form. {ore} worth €{value}. " +
|
||||
"{location} tried to discourage you with atmosphere and pressure. " +
|
||||
"You brought a {tool} and ignored the atmosphere.",
|
||||
|
||||
"You went to the fourth level of the Deeprock and you came back " +
|
||||
"You went to the fourth level of {location} and you came back " +
|
||||
"with {ore} worth €{value} and {xp} XP and a story " +
|
||||
"that mostly involves how far down the fourth level is. " +
|
||||
"It is very far down. The ore was worth being very far down. Today.",
|
||||
},
|
||||
|
||||
5: {
|
||||
"Mythril. You found mythril and extracted mythril " +
|
||||
"and brought mythril home and mythril is worth €{value} per unit. " +
|
||||
"The {ore} you're carrying is worth €{value} total. " +
|
||||
"{xp} XP. The Diamond Pickaxe is a Diamond Pickaxe for a reason. " +
|
||||
"You found the seam and you extracted the seam " +
|
||||
"and brought the seam home. " +
|
||||
"{ore} worth €{value} total. " +
|
||||
"{xp} XP. The {tool} is a {tool} for a reason. " +
|
||||
"Today you proved the reason.",
|
||||
|
||||
"The Voidstone was present but passive today. " +
|
||||
"The Dragon Crystals were warm but not hostile. " +
|
||||
"The mythril seam was open and you took {ore} worth €{value} from it. " +
|
||||
"{xp} XP. The Mythril Caverns had a good day at the same time you did. " +
|
||||
"The seam was open and you took {ore} worth €{value} from it. " +
|
||||
"{xp} XP. {location} had a good day at the same time you did. " +
|
||||
"This does not happen often. Don't examine it. Take the ore home.",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ func thomShopView(char *AdventureCharacter, balance float64) string {
|
||||
sb.WriteString(fmt.Sprintf(" Closing costs (5%%): €%d\n", int(float64(def.BasePrice)*0.05)))
|
||||
sb.WriteString(fmt.Sprintf(" Realtor fees (6%%): €%d\n", int(float64(def.BasePrice)*0.06)))
|
||||
sb.WriteString(fmt.Sprintf(" **Total: €%d**\n\n", total))
|
||||
sb.WriteString(fmt.Sprintf("Reply `buy` to purchase, or `buy <amount>` for a down payment.\n"))
|
||||
sb.WriteString(fmt.Sprintf("`!thom buy` to purchase outright, or `!thom buy <amount>` for a down payment.\n"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,16 +333,16 @@ func (p *AdventurePlugin) handleEquipCmd(ctx MessageContext) error {
|
||||
return p.SendDM(ctx.Sender, "Failed to load inventory.")
|
||||
}
|
||||
|
||||
// Filter to masterwork items only
|
||||
// Filter to special gear (Masterwork + Arena) items only
|
||||
var mwItems []AdvItem
|
||||
for _, it := range items {
|
||||
if it.Type == "MasterworkGear" {
|
||||
if it.Type == "MasterworkGear" || it.Type == "ArenaGear" {
|
||||
mwItems = append(mwItems, it)
|
||||
}
|
||||
}
|
||||
|
||||
if len(mwItems) == 0 {
|
||||
return p.SendDM(ctx.Sender, "You have no Masterwork gear waiting to be equipped. Go find some.")
|
||||
return p.SendDM(ctx.Sender, "You have no special gear waiting to be equipped. Go find some.")
|
||||
}
|
||||
|
||||
equip, err := loadAdvEquipment(ctx.Sender)
|
||||
@@ -352,7 +352,7 @@ func (p *AdventurePlugin) handleEquipCmd(ctx MessageContext) error {
|
||||
|
||||
// Build listing
|
||||
var sb strings.Builder
|
||||
sb.WriteString("⭐ **Your unequipped Masterwork gear:**\n\n")
|
||||
sb.WriteString("⭐ **Your unequipped special gear:**\n\n")
|
||||
|
||||
for i, it := range mwItems {
|
||||
current := equip[it.Slot]
|
||||
@@ -366,8 +366,12 @@ func (p *AdventurePlugin) handleEquipCmd(ctx MessageContext) error {
|
||||
}
|
||||
currentDesc = fmt.Sprintf("%s (%s)", current.Name, tag)
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf("%d. %s (T%d %s) — currently: %s\n",
|
||||
i+1, it.Name, it.Tier, slotTitle(it.Slot), currentDesc))
|
||||
marker := "⭐"
|
||||
if it.Type == "ArenaGear" {
|
||||
marker = "⚔️"
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf("%d. %s %s (T%d %s) — currently: %s\n",
|
||||
i+1, marker, it.Name, it.Tier, slotTitle(it.Slot), currentDesc))
|
||||
}
|
||||
|
||||
sb.WriteString("\nReply with a number to equip, or \"cancel\".")
|
||||
@@ -375,7 +379,7 @@ func (p *AdventurePlugin) handleEquipCmd(ctx MessageContext) error {
|
||||
p.pending.Store(string(ctx.Sender), &advPendingInteraction{
|
||||
Type: "masterwork_equip",
|
||||
Data: &advPendingMasterworkEquip{Items: mwItems},
|
||||
ExpiresAt: time.Now().Add(5 * time.Minute),
|
||||
ExpiresAt: time.Now().Add(advDMResponseWindow),
|
||||
})
|
||||
|
||||
return p.SendDM(ctx.Sender, sb.String())
|
||||
@@ -430,17 +434,22 @@ func (p *AdventurePlugin) handleMasterworkEquipReply(ctx MessageContext, interac
|
||||
p.pending.Store(string(ctx.Sender), &advPendingInteraction{
|
||||
Type: "masterwork_equip_confirm",
|
||||
Data: &advPendingMasterworkConfirm{Item: selected},
|
||||
ExpiresAt: time.Now().Add(5 * time.Minute),
|
||||
ExpiresAt: time.Now().Add(advDMResponseWindow),
|
||||
})
|
||||
|
||||
def := masterworkDefFor(slotToActivity(selected.Slot), selected.Tier)
|
||||
bonusDesc := ""
|
||||
if def != nil {
|
||||
bonusDesc = fmt.Sprintf("\n%s gives 1.25x %s effectiveness and +5%% %s success.\n", selected.Name, slotTitle(selected.Slot), def.SkillSource)
|
||||
marker := "⭐"
|
||||
if selected.Type == "ArenaGear" {
|
||||
marker = "⚔️"
|
||||
} else {
|
||||
def := masterworkDefFor(slotToActivity(selected.Slot), selected.Tier)
|
||||
if def != nil {
|
||||
bonusDesc = fmt.Sprintf("\n%s gives 1.25x %s effectiveness and +5%% %s success.\n", selected.Name, slotTitle(selected.Slot), def.SkillSource)
|
||||
}
|
||||
}
|
||||
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("Equip **%s** (T%d ⭐ %s)?%s\nThis replaces your %s. The old item goes to inventory.%s\nReply \"yes\" to confirm.",
|
||||
selected.Name, selected.Tier, slotTitle(selected.Slot), warning, currentName, bonusDesc))
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("Equip **%s** (T%d %s %s)?%s\nThis replaces your %s. The old item goes to inventory.%s\nReply \"yes\" to confirm.",
|
||||
selected.Name, selected.Tier, marker, slotTitle(selected.Slot), warning, currentName, bonusDesc))
|
||||
}
|
||||
|
||||
func (p *AdventurePlugin) handleMasterworkEquipConfirm(ctx MessageContext, interaction *advPendingInteraction) error {
|
||||
@@ -488,10 +497,21 @@ func (p *AdventurePlugin) handleMasterworkEquipConfirm(ctx MessageContext, inter
|
||||
eq.Condition = 100
|
||||
eq.Name = selected.Name
|
||||
eq.ActionsUsed = 0
|
||||
eq.ArenaTier = 0
|
||||
eq.ArenaSet = ""
|
||||
eq.Masterwork = true
|
||||
eq.SkillSource = selected.SkillSource
|
||||
|
||||
if selected.Type == "ArenaGear" {
|
||||
eq.Masterwork = false
|
||||
eq.SkillSource = ""
|
||||
eq.ArenaTier = selected.Tier
|
||||
eq.ArenaSet = ""
|
||||
if gs := arenaGearByName(selected.Name); gs != nil {
|
||||
eq.ArenaSet = gs.SetKey
|
||||
}
|
||||
} else {
|
||||
eq.ArenaTier = 0
|
||||
eq.ArenaSet = ""
|
||||
eq.Masterwork = true
|
||||
eq.SkillSource = selected.SkillSource
|
||||
}
|
||||
|
||||
if err := saveAdvEquipment(ctx.Sender, eq); err != nil {
|
||||
return p.SendDM(ctx.Sender, "Failed to save equipment. Try again.")
|
||||
@@ -502,7 +522,11 @@ func (p *AdventurePlugin) handleMasterworkEquipConfirm(ctx MessageContext, inter
|
||||
slog.Error("adventure: failed to remove equipped item from inventory", "user", ctx.Sender, "err", err)
|
||||
}
|
||||
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("**%s** equipped. ⭐ Masterwork %s, Tier %d.", selected.Name, slotTitle(selected.Slot), selected.Tier))
|
||||
kind := "⭐ Masterwork"
|
||||
if selected.Type == "ArenaGear" {
|
||||
kind = "⚔️ Arena"
|
||||
}
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("**%s** equipped. %s %s, Tier %d.", selected.Name, kind, slotTitle(selected.Slot), selected.Tier))
|
||||
}
|
||||
|
||||
// slotToActivity converts an EquipmentSlot to the activity that drops masterwork for it.
|
||||
|
||||
@@ -158,7 +158,7 @@ func (p *AdventurePlugin) npcFireEncounter(userID id.UserID, npc string) {
|
||||
p.pending.Store(string(userID), &advPendingInteraction{
|
||||
Type: "npc_encounter",
|
||||
Data: npc,
|
||||
ExpiresAt: time.Now().Add(5 * time.Minute),
|
||||
ExpiresAt: time.Now().Add(advDMResponseWindow),
|
||||
})
|
||||
|
||||
if err := p.SendDM(userID, prompt); err != nil {
|
||||
|
||||
@@ -417,10 +417,10 @@ func (p *AdventurePlugin) resolveShopItemChoice(ctx MessageContext, interaction
|
||||
// Check Arena/Masterwork block — only block if shop item isn't clearly better.
|
||||
// Arena gear always blocks (1.5x multiplier, earned through combat).
|
||||
// Masterwork blocks only if the shop item's tier doesn't exceed the MW effective tier.
|
||||
if current != nil && current.ArenaTier > 0 {
|
||||
if current != nil && current.ArenaTier > 0 && def.Tier <= current.ArenaTier {
|
||||
p.pending.Store(string(ctx.Sender), interaction)
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("You have **%s** (Arena gear) in that slot. A shop item can't replace that. You earned it.\n\nPick something else, or \"back\" to return.",
|
||||
current.Name))
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("You have **%s** (Arena gear, T%d) in that slot. That T%d shop item isn't an upgrade.\n\nPick something else, or \"back\" to return.",
|
||||
current.Name, current.ArenaTier, def.Tier))
|
||||
}
|
||||
if current != nil && current.Masterwork && float64(def.Tier) <= advEffectiveTier(current) {
|
||||
p.pending.Store(string(ctx.Sender), interaction)
|
||||
@@ -479,8 +479,8 @@ func (p *AdventurePlugin) resolveShopConfirm(ctx MessageContext, interaction *ad
|
||||
current := equip[data.Slot]
|
||||
|
||||
// Re-check Arena/Masterwork block.
|
||||
if current != nil && current.ArenaTier > 0 {
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("Your **%s** is Arena gear. Luigi won't overwrite it.", current.Name))
|
||||
if current != nil && current.ArenaTier > 0 && def.Tier <= current.ArenaTier {
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("Your **%s** (Arena gear T%d) is not worse than that T%d shop item.", current.Name, current.ArenaTier, def.Tier))
|
||||
}
|
||||
if current != nil && current.Masterwork && float64(def.Tier) <= advEffectiveTier(current) {
|
||||
return p.SendDM(ctx.Sender, fmt.Sprintf("Your **%s** (Masterwork ⭐) is better than that T%d shop item.", current.Name, def.Tier))
|
||||
@@ -510,6 +510,8 @@ func (p *AdventurePlugin) resolveShopConfirm(ctx MessageContext, interaction *ad
|
||||
if current.Masterwork {
|
||||
itemType = "MasterworkGear"
|
||||
// Masterwork has no resale value (it's special, not shop-priced)
|
||||
} else if current.ArenaTier > 0 {
|
||||
itemType = "ArenaGear"
|
||||
} else if current.Tier < len(equipmentTiers[data.Slot]) {
|
||||
resaleValue = int64(equipmentTiers[data.Slot][current.Tier].Price * 0.3)
|
||||
}
|
||||
@@ -682,10 +684,9 @@ func (p *AdventurePlugin) advBuyEquipment(userID id.UserID, slot EquipmentSlot,
|
||||
}
|
||||
// Block shop purchases that would overwrite arena gear (always) or
|
||||
// masterwork gear (only if shop item isn't clearly better).
|
||||
if current != nil && current.ArenaTier > 0 {
|
||||
return fmt.Sprintf("You already have **%s** (Arena gear). A shop item cannot replace this. "+
|
||||
"You earned that. Don't throw it away.",
|
||||
current.Name)
|
||||
if current != nil && current.ArenaTier > 0 && def.Tier <= current.ArenaTier {
|
||||
return fmt.Sprintf("You already have **%s** (Arena gear T%d). That T%d shop item isn't an upgrade.",
|
||||
current.Name, current.ArenaTier, def.Tier)
|
||||
}
|
||||
if current != nil && current.Masterwork && float64(def.Tier) <= advEffectiveTier(current) {
|
||||
return fmt.Sprintf("You already have **%s** (Masterwork ⭐ T%d). That T%d shop item isn't an upgrade.",
|
||||
@@ -714,6 +715,8 @@ func (p *AdventurePlugin) advBuyEquipment(userID id.UserID, slot EquipmentSlot,
|
||||
var resaleValue int64
|
||||
if current.Masterwork {
|
||||
itemType = "MasterworkGear"
|
||||
} else if current.ArenaTier > 0 {
|
||||
itemType = "ArenaGear"
|
||||
} else if current.Tier < len(equipmentTiers[slot]) {
|
||||
resaleValue = int64(equipmentTiers[slot][current.Tier].Price * 0.3)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user