elliebot/src/EllieBot/Modules/Games/Fish/FishItemCommands.cs
2025-04-02 14:57:53 +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 buy 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();
}
}
}