elliebot/src/EllieBot/Modules/Games/Fish/FishItemCommands.cs
Toastie 0a1797700c
.fishop and .finv
You can list items in `.fishop`
Buy with `.fibuy`
See your inventory with `.finv`
Equip with `.fiuse`
Items are defined in items: array at the bottom of fish.yml
Items will show up in your .fili and bonuses will show up when you do .fish
The migrations for quests were meant to be sorted in 4c2b42ab7f but it kind of decided to be very stupid.
2025-03-29 20:33:25 +13:00

240 lines
No EOL
8.2 KiB
C#

using EllieBot.Modules.Games.Fish.Db;
namespace EllieBot.Modules.Games;
public partial class Games
{
public class FishItemCommands(FishItemService fis, ICurrencyProvider cp) : EllieModule
{
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task FishShop()
{
var items = fis.GetItems();
await Response()
.Paginated()
.Items(items)
.PageSize(9)
.CurrentPage(0)
.Page((pageItems, i) =>
{
var eb = CreateEmbed()
.WithTitle(GetText(strs.fish_items_title))
.WithFooter("`.fibuy <id>` to by an item")
.WithOkColor();
foreach (var item in pageItems)
{
var description = GetItemDescription(item);
eb.AddField($"{item.Id}",
$"""
{description}
""",
true);
}
return eb;
})
.AddFooter(false)
.SendAsync();
}
private string GetItemDescription(FishItem item, UserFishItem? userItem = null)
{
var multiplierInfo = GetMultiplierInfo(item);
var priceText = userItem is null
? $"【 **{CurrencyHelper.N(item.Price, Culture, cp.GetCurrencySign())}** 】"
: "";
return $"""
《 **{item.Name}** 》
{GetEmoji(item.ItemType)} `{item.ItemType.ToString().ToLower()}` {priceText}
{item.Description}
{GetItemNotes(item, userItem)}
{multiplierInfo}
""";
}
private string GetItemNotes(FishItem item, UserFishItem? userItem)
{
var stats = new List<string>();
if (item.Uses.HasValue)
stats.Add($"**Uses:** {userItem?.UsesLeft ?? item.Uses}");
if (item.DurationMinutes.HasValue)
stats.Add($"**Duration:** {userItem?.ExpiryFromNowInMinutes() ?? item.DurationMinutes}m");
var toReturn = stats.Count > 0 ? string.Join(" | ", stats) + "\n" : "\n";
return "\n" + toReturn;
}
public static string GetEmoji(FishItemType itemType)
=> itemType switch
{
FishItemType.Pole => @"\🎣",
FishItemType.Boat => @"\⛵",
FishItemType.Bait => @"\🍥",
FishItemType.Potion => @"\🍷",
_ => ""
};
private string GetMultiplierInfo(FishItem item)
{
var multipliers = new FishMultipliers()
{
FishMultiplier = item.FishMultiplier ?? 1,
TrashMultiplier = item.TrashMultiplier ?? 1,
RareMultiplier = item.RareMultiplier ?? 1,
StarMultiplier = item.MaxStarMultiplier ?? 1,
FishingSpeedMultiplier = item.FishingSpeedMultiplier ?? 1
};
return GetMultiplierInfo(multipliers);
}
public static string GetMultiplierInfo(FishMultipliers item)
{
var multipliers = new List<string>();
if (item.FishMultiplier is not 1.0d)
multipliers.Add($"{AsPercent(item.FishMultiplier)} chance to catch fish");
if (item.TrashMultiplier is not 1.0d)
multipliers.Add($"{AsPercent(item.TrashMultiplier)} chance to catch trash");
if (item.RareMultiplier is not 1.0d)
multipliers.Add($"{AsPercent(item.RareMultiplier)} chance to catch rare fish");
if (item.StarMultiplier is not 1.0d)
multipliers.Add($"{AsPercent(item.StarMultiplier)} to max star rating");
if (item.FishingSpeedMultiplier is not 1.0d)
multipliers.Add($"{AsPercent(item.FishingSpeedMultiplier)} fishing speed");
return multipliers.Count > 0
? $"{string.Join("\n", multipliers)}\n"
: "";
}
private static string AsPercent(double multiplier)
{
var percentage = (int)((multiplier - 1.0f) * 100);
return percentage >= 0 ? $"**+{percentage}%**" : $"**{percentage}%**";
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task FishBuy(int itemId)
{
var res = await fis.BuyItemAsync(ctx.User.Id, itemId);
if (res.TryPickT1(out var err, out var eqItem))
{
if (err == BuyResult.InsufficientFunds)
await Response().Error(strs.not_enough(cp.GetCurrencySign())).SendAsync();
else
await Response().Error(strs.fish_item_not_found).SendAsync();
return;
}
var embed = CreateEmbed()
.WithDescription(GetText(strs.fish_buy_success))
.AddField(eqItem.Name, GetMultiplierInfo(eqItem));
await Response()
.Embed(embed)
.Interaction(_inter.Create(ctx.User.Id,
new ButtonBuilder("Inventory", Guid.NewGuid().ToString(), ButtonStyle.Secondary),
(smc) => FishInv()))
.SendAsync();
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task FishUse(int index)
{
var eqItem = await fis.EquipItemAsync(ctx.User.Id, index);
if (eqItem is null)
{
await Response().Error(strs.fish_item_not_found).SendAsync();
return;
}
var embed = CreateEmbed()
.WithDescription(GetText(strs.fish_use_success))
.AddField(eqItem.Name, GetMultiplierInfo(eqItem));
await Response().Embed(embed).SendAsync();
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task FishUnequip(FishItemType itemType)
{
var res = await fis.UnequipItemAsync(ctx.User.Id, itemType);
if (res == UnequipResult.Success)
await Response().Confirm(strs.fish_unequip_success).SendAsync();
else if (res == UnequipResult.NotFound)
await Response().Error(strs.fish_item_not_found).SendAsync();
else
await Response().Error(strs.fish_cant_uneq_potion).SendAsync();
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task FishInv()
{
var userItems = await fis.GetUserItemsAsync(ctx.User.Id);
await Response()
.Paginated()
.Items(userItems)
.PageSize(9)
.Page((items, page) =>
{
page += 1;
var eb = CreateEmbed()
.WithAuthor(ctx.User)
.WithTitle(GetText(strs.fish_inv_title))
.WithFooter($"`.fiuse <num>` to use/equip an item")
.WithOkColor();
for (var i = 0; i < items.Count; i++)
{
var (userItem, item) = items[i];
var isEquipped = userItem.IsEquipped;
if (item is null)
{
eb.AddField($"{(page * 9) + i + 1} | Item not found", $"ID: {userItem.Id}", true);
continue;
}
var description = GetItemDescription(item, userItem);
if (isEquipped)
description = "🫴 **IN USE**\n" + description;
eb.AddField($"{i + 1} | {item.Name} ",
$"""
{description}
""",
true);
}
return eb;
})
.AddFooter(false)
.SendAsync();
}
}
}