Files
SkyBot/SkyBot/Commands/RP/Marriage.cs
2026-04-29 03:06:12 +01:00

222 lines
9.7 KiB
C#

using SkyBot.Helpers;
using SkyBot.Models;
using SkyBot.Services;
namespace SkyBot.Commands
{
public class Marriage : ICommand
{
public string Name => "marriage";
public string[] Aliases => ["marry"];
public string Description => "Marriage system — propose, check status, or divorce.";
public string Category => "RP";
public string Usage => "marriage <sub>";
public string[] SubCommands => ["propose", "status", "divorce", "force"];
public async Task Execute(CommandContext ctx)
{
switch (ctx.Args.ElementAtOrDefault(0)?.ToLower())
{
case "propose":
await HandlePropose(ctx);
break;
case "force":
await HandleForce(ctx);
break;
case "divorce":
await HandleDivorce(ctx);
break;
case "status":
await HandleStatus(ctx);
break;
default:
await MessageHelper.ReplyAsync(ctx, $"Usage: `{Config.Prefix}marriage <propose|status|divorce>`");
break;
}
}
private static async Task HandlePropose(CommandContext ctx)
{
long propserId = ctx.Member.UserId;
string sender = ctx.Member.Nickname ?? ctx.Member.User?.Name ?? "Unknown";
long? targetUserId = null;
string? targetMention = null;
if (ctx.Message.ReplyToId is not null)
{
var replied = await ctx.Message.FetchReplyMessageAsync();
if (replied is null) return;
var author = await replied.FetchAuthorAsync();
if (author is null) return;
targetUserId = author.Id;
targetMention = $"«@u-{author.Id}»";
}
if (targetUserId is null && ctx.Message.Mentions is not null && ctx.Message.Mentions.Any())
{
long memberId = ctx.Message.Mentions.First().TargetId;
var mentioned = await ctx.Planet.FetchMemberAsync(memberId);
if (mentioned is null) return;
targetUserId = mentioned.UserId;
targetMention = $"«@u-{mentioned.UserId}»";
}
if (targetUserId is null)
{
await MessageHelper.ReplyAsync(ctx, $"Please reply to someone's message or mention them. Usage: `{Config.Prefix}marriage propose <reply|@user>");
return;
}
var result = MarriageService.Propose(propserId, targetUserId.Value);
switch (result)
{
case MarriageService.ProposeResult.SelfPropose:
await MessageHelper.ReplyAsync(ctx, "You can't propose to yourself.");
break;
case MarriageService.ProposeResult.AlreadyMarried:
await MessageHelper.ReplyAsync(ctx, $"You are already married, {sender}. You'd need to `{Config.Prefix}marriage divorce` first.");
break;
case MarriageService.ProposeResult.TargetAlreadyMarried:
await MessageHelper.ReplyAsync(ctx, $"{targetMention} is already married.");
break;
case MarriageService.ProposeResult.AlreadyProposed:
await MessageHelper.ReplyAsync(ctx, $"You've already proposed to {targetMention}! Waiting for thsir reponse");
break;
case MarriageService.ProposeResult.Ok:
await MessageHelper.ReplyAsync(ctx, $"💍 {sender} gets down on one knee and proposes to {targetMention}\n{targetMention}, type `{Config.Prefix}accept` or `{Config.Prefix}decline`. This proposal expires in 5 minutes.");
break;
}
}
private static async Task HandleDivorce(CommandContext ctx)
{
long userId = ctx.Member.UserId;
string name = ctx.Member.Nickname ?? ctx.Member.User?.Name ?? "Unknown";
long? partnerId = MarriageService.GetMarriage(userId)?.SpouseId;
if (partnerId is null)
{
await MessageHelper.ReplyAsync(ctx, $"You're not married, {name}.");
return;
}
MarriageService.RequestDivorceConfirmation(userId);
await MessageHelper.ReplyAsync(ctx, $"Are you sure you want to divorce «@u-{partnerId}»?\nType `{Config.Prefix}confirm` within 60 seconds to confirm, or `{Config.Prefix}cancel` to cancel.");
}
private static async Task HandleStatus(CommandContext ctx)
{
long userId = ctx.Member.UserId;
string name = ctx.Member.Nickname ?? ctx.Member.User?.Name ?? "Unknown";
if (ctx.Message.Mentions is not null && ctx.Message.Mentions.Any())
{
long memberId = ctx.Message.Mentions.First().TargetId;
var mentioned = await ctx.Planet.FetchMemberAsync(memberId);
if (mentioned is null) return;
userId = mentioned.UserId;
name = mentioned.Nickname ?? mentioned.User?.Name ?? "Unknown";
}
MarriageModel? marriage = MarriageService.GetMarriage(userId);
if (marriage is null)
{
await MessageHelper.ReplyAsync(ctx, $"{name} is not currently married.");
}
else
{
long partnerId = marriage.SpouseId;
DateTimeOffset dt = DateTimeOffset.FromUnixTimeMilliseconds(marriage.MarriedAt);
string marriedAt = $"{dt.OrdinalDay()} {dt:MMMM yyyy HH:mm} UTC";
await MessageHelper.ReplyAsync(ctx, $"{name} is married to «@u-{partnerId}»!\nThey got married: {marriedAt}");
}
}
private static async Task HandleForce(CommandContext ctx)
{
if (!PermissionHelper.IsOwner(ctx.Member))
{
await MessageHelper.ReplyAsync(ctx, "You don't have permission to use this command.");
return;
}
string action = ctx.Args.ElementAtOrDefault(1)?.ToLower() ?? "";
var mentions = ctx.Message.Mentions ?? [];
switch (action)
{
case "marry":
{
if (mentions.Count < 2)
{
await MessageHelper.ReplyAsync(ctx, $"Please mention two users. Usage: `{Config.Prefix}marriage force marry @user1 @user2`");
return;
}
var member1 = await ctx.Planet.FetchMemberAsync(mentions[0].TargetId);
var member2 = await ctx.Planet.FetchMemberAsync(mentions[1].TargetId);
if (member1 is null || member2 is null)
{
await MessageHelper.ReplyAsync(ctx, "Could not find one or both of those members.");
return;
}
var result = await MarriageService.ForceMarryAsync(member1.UserId, member2.UserId);
switch (result)
{
case MarriageService.ForceMarryResult.SameUser:
await MessageHelper.ReplyAsync(ctx, "You can't marry someone to themselves!");
break;
case MarriageService.ForceMarryResult.User1AlreadyMarried:
await MessageHelper.ReplyAsync(ctx, $"«@u-{member1.UserId}» is already married.");
break;
case MarriageService.ForceMarryResult.User2AlreadyMarried:
await MessageHelper.ReplyAsync(ctx, $"«@u-{member2.UserId}» is already married.");
break;
case MarriageService.ForceMarryResult.Ok:
await MessageHelper.ReplyAsync(ctx, $"💒 «@u-{member1.UserId}» and «@u-{member2.UserId}» are now married! 🎉");
break;
}
break;
}
case "divorce":
{
if (mentions.Count < 1)
{
await MessageHelper.ReplyAsync(ctx, $"Please mention a user. Usage: `{Config.Prefix}marriage force divorce @user`");
return;
}
var member = await ctx.Planet.FetchMemberAsync(mentions[0].TargetId);
if (member is null)
{
await MessageHelper.ReplyAsync(ctx, "Could not find that member.");
return;
}
var (result, partnerId) = await MarriageService.ForceDivorceAsync(member.UserId);
switch (result)
{
case MarriageService.DivorceResult.NotMarried:
await MessageHelper.ReplyAsync(ctx, $"«@u-{member.UserId}» is not married.");
break;
case MarriageService.DivorceResult.Ok:
await MessageHelper.ReplyAsync(ctx, $"💔 «@u-{member.UserId}» and «@u-{partnerId}» have been forcefully divorced.");
break;
}
break;
}
default:
await MessageHelper.ReplyAsync(ctx, $"Usage: `{Config.Prefix}marriage force marry @user1 @user2` or `{Config.Prefix}marriage force divorce @user`");
break;
}
}
}
}