namespace Aeshnidae.Enlightenment;
///
/// Read-only, on purpose.
///
/// The brief for this mod was "enlighten via an NPC", because an enlightenment
/// command had been abusable before. So nothing in this file grants, resets or
/// awards anything - the only route to is the Font's
/// emote, and there is no admin override here either. If one is ever wanted it
/// should be added deliberately, at AccessLevel.Admin, and logged; it should not
/// arrive by accident because a status command grew a second argument.
///
public static class Commands
{
[CommandHandler("enlighten", AccessLevel.Player, CommandHandlerFlag.RequiresWorld, 0,
"Show your progress towards enlightenment, and what it would cost.",
"/enlighten")]
public static void HandleEnlighten(Session session, params string[] parameters)
{
if (session?.Player is null)
return;
Reply(session, Requirements.Describe(session.Player));
}
///
/// The one write-capable command here, and it writes prerequisites, not results.
/// See Prep.cs. Targets yourself by default, or a named online player.
///
[CommandHandler("enlighten-prep", AccessLevel.Admin, CommandHandlerFlag.RequiresWorld, 0,
"TESTING: give a character every prerequisite for enlightenment (level, auras, society master). Does not enlighten.",
"/enlighten-prep [player name]")]
public static void HandlePrep(Session session, params string[] parameters)
{
var admin = session?.Player;
if (admin is null)
return;
var target = admin;
if (parameters.Length > 0)
{
var name = string.Join(" ", parameters);
target = PlayerManager.GetOnlinePlayer(name);
if (target is null)
{
Reply(session, $"No online player called '{name}'.");
return;
}
}
try
{
var report = Prep.Run(admin, target);
Reply(session, report);
if (target != admin)
target.SendMessage($"{admin.Name} has prepared you for enlightenment. /enlighten to see where you stand.");
}
catch (Exception ex)
{
ModManager.Log($"[{Mod.Name}] enlighten-prep failed for {target.Name}: {ex}", ModManager.LogLevel.Error);
Reply(session, $"Prep failed: {ex.Message}. See the server log.");
}
}
[CommandHandler("enlightenment-reload", AccessLevel.Admin, CommandHandlerFlag.None, 0,
"Restart Aeshnidae.Enlightenment, re-reading Settings.json.",
"/enlightenment-reload")]
public static void HandleReload(Session session, params string[] parameters)
{
var container = Mod.Container;
if (container is null)
{
Reply(session, $"{Mod.Name} is not loaded.");
return;
}
container.Restart();
Reply(session, $"{Mod.Name} restarted.");
}
[CommandHandler("enlightenment-rules", AccessLevel.Advocate, CommandHandlerFlag.None, 0,
"Print the enlightenment rules currently in force.",
"/enlightenment-rules")]
public static void HandleRules(Session session, params string[] parameters)
{
var settings = Mod.Settings;
var sb = new StringBuilder()
.AppendLine($"{Mod.Name} - {(settings.Enabled ? "active" : "disabled, retail rules in force")}")
.AppendLine($" level required : {settings.BaseLevelRequirement} +{settings.LevelRequirementPerEnlightenment} per enlightenment held")
.AppendLine($" maximum : {(settings.MaxEnlightenments > 0 ? settings.MaxEnlightenments.ToString() : "uncapped")}")
.AppendLine($" also required : {(settings.RequireSocietyMaster ? "society master" : "-")}, " +
$"{(settings.RequireAllLuminanceAuras ? "all luminance auras" : "-")}, " +
$"{settings.RequiredFreeInventorySlots} free slots")
.AppendLine($" keeps : society {On(settings.KeepSociety)}, auras {On(settings.KeepLuminanceAuras)}, " +
$"lum access {On(settings.KeepLuminanceAccess)}, lum balance {On(settings.KeepLuminanceBalance)}, " +
$"unassigned xp {On(settings.KeepUnassignedExperience)}, aetheria {On(settings.KeepAetheria)}")
.AppendLine($" resets : level {On(settings.ResetLevel)}, skills {On(settings.ResetSkills)}, " +
$"attributes {On(settings.ResetAttributes)}, dequip {On(settings.DequipAllItems)}")
.AppendLine($" grants : titles {On(settings.GrantTitles)} (five exist), " +
$"attribute certificate {On(settings.GrantAttributeResetCertificate)}, " +
$"broadcast {On(settings.BroadcastToServer)}")
.AppendLine($" re-entry guard : {settings.ReentryGuardSeconds:N0}s")
.AppendLine(" +1 all skills and +2 vitality per enlightenment come from ACE itself, not this mod.");
Reply(session, sb.ToString());
}
private static string On(bool value) => value ? "yes" : "no";
///
/// The client draws an embedded newline as a music note, so multi-line output
/// has to go one SendMessage per line.
///
private static void Reply(Session? session, string message)
{
if (session?.Player is null)
{
ModManager.Log(message);
return;
}
foreach (var line in (message ?? "").Split('\n'))
{
var text = line.TrimEnd('\r');
if (!string.IsNullOrWhiteSpace(text))
session.Player.SendMessage(text);
}
}
}