728 lines
18 KiB
Go
728 lines
18 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// RegisterPlayerCommands registers all player-level commands
|
|
func RegisterPlayerCommands(cm *CommandManager) error {
|
|
commands := []*Command{
|
|
// Communication commands
|
|
{
|
|
Name: "say",
|
|
Type: CommandTypePlayer,
|
|
Description: "Says something to nearby players",
|
|
Usage: "/say <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleSay,
|
|
},
|
|
{
|
|
Name: "tell",
|
|
Type: CommandTypePlayer,
|
|
Description: "Sends a private message to a player",
|
|
Usage: "/tell <player> <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleTell,
|
|
},
|
|
{
|
|
Name: "yell",
|
|
Type: CommandTypePlayer,
|
|
Description: "Yells something to a wider area",
|
|
Usage: "/yell <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleYell,
|
|
},
|
|
{
|
|
Name: "shout",
|
|
Type: CommandTypePlayer,
|
|
Description: "Shouts something zone-wide",
|
|
Usage: "/shout <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleShout,
|
|
},
|
|
{
|
|
Name: "ooc",
|
|
Type: CommandTypePlayer,
|
|
Description: "Sends an out-of-character message",
|
|
Usage: "/ooc <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleOOC,
|
|
},
|
|
{
|
|
Name: "emote",
|
|
Type: CommandTypePlayer,
|
|
Description: "Performs an emote",
|
|
Usage: "/emote <action>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleEmote,
|
|
},
|
|
|
|
// Group commands
|
|
{
|
|
Name: "group",
|
|
Type: CommandTypePlayer,
|
|
Description: "Group management commands",
|
|
Usage: "/group <invite|leave|kick|disband> [player]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleGroup,
|
|
},
|
|
{
|
|
Name: "groupsay",
|
|
Type: CommandTypePlayer,
|
|
Description: "Says something to your group",
|
|
Usage: "/groupsay <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleGroupSay,
|
|
},
|
|
{
|
|
Name: "gsay",
|
|
Type: CommandTypePlayer,
|
|
Description: "Says something to your group (short form)",
|
|
Usage: "/gsay <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleGroupSay,
|
|
},
|
|
|
|
// Guild commands
|
|
{
|
|
Name: "guild",
|
|
Type: CommandTypePlayer,
|
|
Description: "Guild management commands",
|
|
Usage: "/guild <invite|leave|promote|demote|kick> [player]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleGuild,
|
|
},
|
|
{
|
|
Name: "guildsay",
|
|
Type: CommandTypePlayer,
|
|
Description: "Says something to your guild",
|
|
Usage: "/guildsay <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleGuildSay,
|
|
},
|
|
{
|
|
Name: "officersay",
|
|
Type: CommandTypePlayer,
|
|
Description: "Says something to guild officers",
|
|
Usage: "/officersay <message>",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleOfficerSay,
|
|
},
|
|
|
|
// Character commands
|
|
{
|
|
Name: "who",
|
|
Type: CommandTypePlayer,
|
|
Description: "Lists players online",
|
|
Usage: "/who [name pattern]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleWho,
|
|
},
|
|
{
|
|
Name: "time",
|
|
Type: CommandTypePlayer,
|
|
Description: "Shows current game time",
|
|
Usage: "/time",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleTime,
|
|
},
|
|
{
|
|
Name: "afk",
|
|
Type: CommandTypePlayer,
|
|
Description: "Toggles AFK status",
|
|
Usage: "/afk [message]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleAFK,
|
|
},
|
|
{
|
|
Name: "anon",
|
|
Type: CommandTypePlayer,
|
|
Description: "Toggles anonymous status",
|
|
Usage: "/anon",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleAnonymous,
|
|
},
|
|
{
|
|
Name: "lfg",
|
|
Type: CommandTypePlayer,
|
|
Description: "Toggles looking for group status",
|
|
Usage: "/lfg",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleLFG,
|
|
},
|
|
{
|
|
Name: "location",
|
|
Type: CommandTypePlayer,
|
|
Description: "Shows current location",
|
|
Usage: "/location",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleLocation,
|
|
},
|
|
|
|
// Item commands
|
|
{
|
|
Name: "inventory",
|
|
Type: CommandTypePlayer,
|
|
Description: "Shows inventory information",
|
|
Usage: "/inventory",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleInventory,
|
|
},
|
|
{
|
|
Name: "consider",
|
|
Type: CommandTypePlayer,
|
|
Description: "Considers a target",
|
|
Usage: "/consider [target]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleConsider,
|
|
},
|
|
|
|
// Trade commands
|
|
{
|
|
Name: "trade",
|
|
Type: CommandTypePlayer,
|
|
Description: "Trade management",
|
|
Usage: "/trade <start|accept|reject|cancel> [player]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleTrade,
|
|
},
|
|
|
|
// Quest commands
|
|
{
|
|
Name: "quest",
|
|
Type: CommandTypePlayer,
|
|
Description: "Quest management",
|
|
Usage: "/quest <list|abandon|share> [quest_id]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleQuest,
|
|
},
|
|
|
|
// Misc commands
|
|
{
|
|
Name: "help",
|
|
Type: CommandTypePlayer,
|
|
Description: "Shows available commands",
|
|
Usage: "/help [command]",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleHelp,
|
|
},
|
|
{
|
|
Name: "quit",
|
|
Type: CommandTypePlayer,
|
|
Description: "Safely logs out of the game",
|
|
Usage: "/quit",
|
|
RequiredLevel: AdminLevelPlayer,
|
|
Handler: HandleQuit,
|
|
},
|
|
}
|
|
|
|
for _, cmd := range commands {
|
|
if err := cm.Register(cmd); err != nil {
|
|
return fmt.Errorf("failed to register command %s: %w", cmd.Name, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleSay handles the /say command
|
|
func HandleSay(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /say <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
|
|
// TODO: Implement actual zone-wide say broadcast
|
|
// For now, just confirm to the player
|
|
ctx.AddMessage(ChannelSay, ColorWhite, fmt.Sprintf("You say, \"%s\"", message))
|
|
|
|
// TODO: Send to nearby players in zone
|
|
// zone.SendNearbyMessage(ctx.Player.GetPosition(), ChannelSay,
|
|
// fmt.Sprintf("%s says, \"%s\"", playerName, message))
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleTell handles the /tell command
|
|
func HandleTell(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(2, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /tell <player> <message>")
|
|
return nil
|
|
}
|
|
|
|
targetName := ctx.Arguments[0]
|
|
message := ctx.GetRemainingArguments(1)
|
|
|
|
// TODO: Implement actual tell system
|
|
// For now, just show what would be sent
|
|
ctx.AddMessage(ChannelPrivateTell, ColorWhite,
|
|
fmt.Sprintf("You tell %s, \"%s\"", targetName, message))
|
|
|
|
// TODO: Find target player and send message
|
|
// if targetPlayer := world.FindPlayerByName(targetName); targetPlayer != nil {
|
|
// targetPlayer.SendMessage(ChannelPrivateTell,
|
|
// fmt.Sprintf("%s tells you, \"%s\"", playerName, message))
|
|
// } else {
|
|
// ctx.AddErrorMessage(fmt.Sprintf("Player '%s' not found", targetName))
|
|
// }
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleYell handles the /yell command
|
|
func HandleYell(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /yell <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
|
|
ctx.AddMessage(ChannelYell, ColorWhite, fmt.Sprintf("You yell, \"%s\"", message))
|
|
|
|
// TODO: Send to wider area in zone
|
|
return nil
|
|
}
|
|
|
|
// HandleShout handles the /shout command
|
|
func HandleShout(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /shout <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
|
|
ctx.AddMessage(ChannelShout, ColorWhite, fmt.Sprintf("You shout, \"%s\"", message))
|
|
|
|
// TODO: Send zone-wide
|
|
return nil
|
|
}
|
|
|
|
// HandleOOC handles the /ooc command
|
|
func HandleOOC(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /ooc <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
playerName := ctx.GetPlayerName()
|
|
|
|
ctx.AddMessage(ChannelOutOfCharacter, ColorWhite,
|
|
fmt.Sprintf("[OOC] %s: %s", playerName, message))
|
|
|
|
// TODO: Send to zone OOC channel
|
|
return nil
|
|
}
|
|
|
|
// HandleEmote handles the /emote command
|
|
func HandleEmote(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /emote <action>")
|
|
return nil
|
|
}
|
|
|
|
action := ctx.RawArguments
|
|
playerName := ctx.GetPlayerName()
|
|
|
|
ctx.AddMessage(ChannelEmote, ColorWhite, fmt.Sprintf("%s %s", playerName, action))
|
|
|
|
// TODO: Send emote to nearby players
|
|
return nil
|
|
}
|
|
|
|
// HandleGroup handles the /group command
|
|
func HandleGroup(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if ctx.ArgumentCount() == 0 {
|
|
ctx.AddErrorMessage("Usage: /group <invite|leave|kick|disband> [player]")
|
|
return nil
|
|
}
|
|
|
|
subCommand := strings.ToLower(ctx.Arguments[0])
|
|
|
|
switch subCommand {
|
|
case "invite":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /group invite <player>")
|
|
return nil
|
|
}
|
|
targetName := ctx.Arguments[1]
|
|
// TODO: Implement group invite
|
|
ctx.AddStatusMessage(fmt.Sprintf("Invited %s to group", targetName))
|
|
|
|
case "leave":
|
|
// TODO: Implement group leave
|
|
ctx.AddStatusMessage("Left group")
|
|
|
|
case "kick":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /group kick <player>")
|
|
return nil
|
|
}
|
|
targetName := ctx.Arguments[1]
|
|
// TODO: Implement group kick
|
|
ctx.AddStatusMessage(fmt.Sprintf("Kicked %s from group", targetName))
|
|
|
|
case "disband":
|
|
// TODO: Implement group disband
|
|
ctx.AddStatusMessage("Disbanded group")
|
|
|
|
default:
|
|
ctx.AddErrorMessage("Usage: /group <invite|leave|kick|disband> [player]")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleGroupSay handles the /groupsay and /gsay commands
|
|
func HandleGroupSay(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /groupsay <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
playerName := ctx.GetPlayerName()
|
|
|
|
// TODO: Check if player is in a group
|
|
ctx.AddMessage(ChannelGroupSay, ColorWhite,
|
|
fmt.Sprintf("[Group] %s: %s", playerName, message))
|
|
|
|
// TODO: Send to group members
|
|
return nil
|
|
}
|
|
|
|
// HandleGuild handles the /guild command
|
|
func HandleGuild(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if ctx.ArgumentCount() == 0 {
|
|
// TODO: Show guild information
|
|
ctx.AddStatusMessage("Guild information (not yet implemented)")
|
|
return nil
|
|
}
|
|
|
|
subCommand := strings.ToLower(ctx.Arguments[0])
|
|
|
|
switch subCommand {
|
|
case "invite":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /guild invite <player>")
|
|
return nil
|
|
}
|
|
targetName := ctx.Arguments[1]
|
|
// TODO: Implement guild invite
|
|
ctx.AddStatusMessage(fmt.Sprintf("Invited %s to guild", targetName))
|
|
|
|
case "leave":
|
|
// TODO: Implement guild leave
|
|
ctx.AddStatusMessage("Left guild")
|
|
|
|
default:
|
|
ctx.AddErrorMessage("Usage: /guild <invite|leave|promote|demote|kick> [player]")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleGuildSay handles the /guildsay command
|
|
func HandleGuildSay(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /guildsay <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
playerName := ctx.GetPlayerName()
|
|
|
|
// TODO: Check if player is in a guild
|
|
ctx.AddMessage(ChannelGuildSay, ColorWhite,
|
|
fmt.Sprintf("[Guild] %s: %s", playerName, message))
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleOfficerSay handles the /officersay command
|
|
func HandleOfficerSay(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ctx.ValidateArgumentCount(1, -1); err != nil {
|
|
ctx.AddErrorMessage("Usage: /officersay <message>")
|
|
return nil
|
|
}
|
|
|
|
message := ctx.RawArguments
|
|
playerName := ctx.GetPlayerName()
|
|
|
|
// TODO: Check if player is guild officer
|
|
ctx.AddMessage(ChannelOfficerSay, ColorWhite,
|
|
fmt.Sprintf("[Officer] %s: %s", playerName, message))
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleWho handles the /who command
|
|
func HandleWho(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Implement player listing
|
|
ctx.AddMessage(ChannelWho, ColorWhite, "Players online:")
|
|
ctx.AddMessage(ChannelWho, ColorWhite, fmt.Sprintf(" %s (You)", ctx.GetPlayerName()))
|
|
ctx.AddMessage(ChannelWho, ColorWhite, "Total: 1 player online")
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleTime handles the /time command
|
|
func HandleTime(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Implement game time system
|
|
ctx.AddStatusMessage("Game time: 12:00 PM (not yet implemented)")
|
|
return nil
|
|
}
|
|
|
|
// HandleAFK handles the /afk command
|
|
func HandleAFK(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
afkMessage := ""
|
|
if ctx.ArgumentCount() > 0 {
|
|
afkMessage = ctx.RawArguments
|
|
}
|
|
|
|
// TODO: Toggle AFK status
|
|
if afkMessage != "" {
|
|
ctx.AddStatusMessage(fmt.Sprintf("AFK status set with message: %s", afkMessage))
|
|
} else {
|
|
ctx.AddStatusMessage("AFK status toggled")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleAnonymous handles the /anon command
|
|
func HandleAnonymous(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Toggle anonymous status
|
|
ctx.AddStatusMessage("Anonymous status toggled")
|
|
return nil
|
|
}
|
|
|
|
// HandleLFG handles the /lfg command
|
|
func HandleLFG(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Toggle LFG status
|
|
ctx.AddStatusMessage("Looking for group status toggled")
|
|
return nil
|
|
}
|
|
|
|
// HandleLocation handles the /location command
|
|
func HandleLocation(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Get actual player position
|
|
zoneName := ctx.GetZoneName()
|
|
ctx.AddStatusMessage(fmt.Sprintf("Location: %s (coordinates not yet implemented)", zoneName))
|
|
return nil
|
|
}
|
|
|
|
// HandleInventory handles the /inventory command
|
|
func HandleInventory(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: Show inventory information
|
|
ctx.AddStatusMessage("Inventory information (not yet implemented)")
|
|
return nil
|
|
}
|
|
|
|
// HandleConsider handles the /consider command
|
|
func HandleConsider(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
targetName := ctx.GetTargetName()
|
|
if targetName == "No Target" && ctx.ArgumentCount() > 0 {
|
|
targetName = ctx.Arguments[0]
|
|
}
|
|
|
|
if targetName == "No Target" {
|
|
ctx.AddErrorMessage("You must target something or specify a target name")
|
|
return nil
|
|
}
|
|
|
|
// TODO: Implement consider system
|
|
ctx.AddStatusMessage(fmt.Sprintf("You consider %s... (not yet implemented)", targetName))
|
|
return nil
|
|
}
|
|
|
|
// HandleTrade handles the /trade command
|
|
func HandleTrade(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if ctx.ArgumentCount() == 0 {
|
|
ctx.AddErrorMessage("Usage: /trade <start|accept|reject|cancel> [player]")
|
|
return nil
|
|
}
|
|
|
|
subCommand := strings.ToLower(ctx.Arguments[0])
|
|
|
|
switch subCommand {
|
|
case "start":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /trade start <player>")
|
|
return nil
|
|
}
|
|
targetName := ctx.Arguments[1]
|
|
ctx.AddStatusMessage(fmt.Sprintf("Trade initiated with %s", targetName))
|
|
|
|
case "accept":
|
|
ctx.AddStatusMessage("Trade accepted")
|
|
|
|
case "reject":
|
|
ctx.AddStatusMessage("Trade rejected")
|
|
|
|
case "cancel":
|
|
ctx.AddStatusMessage("Trade cancelled")
|
|
|
|
default:
|
|
ctx.AddErrorMessage("Usage: /trade <start|accept|reject|cancel> [player]")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleQuest handles the /quest command
|
|
func HandleQuest(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if ctx.ArgumentCount() == 0 {
|
|
ctx.AddErrorMessage("Usage: /quest <list|abandon|share> [quest_id]")
|
|
return nil
|
|
}
|
|
|
|
subCommand := strings.ToLower(ctx.Arguments[0])
|
|
|
|
switch subCommand {
|
|
case "list":
|
|
// TODO: List active quests
|
|
ctx.AddStatusMessage("Active quests (not yet implemented)")
|
|
|
|
case "abandon":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /quest abandon <quest_id>")
|
|
return nil
|
|
}
|
|
questID := ctx.Arguments[1]
|
|
ctx.AddStatusMessage(fmt.Sprintf("Abandoned quest %s", questID))
|
|
|
|
case "share":
|
|
if ctx.ArgumentCount() < 2 {
|
|
ctx.AddErrorMessage("Usage: /quest share <quest_id>")
|
|
return nil
|
|
}
|
|
questID := ctx.Arguments[1]
|
|
ctx.AddStatusMessage(fmt.Sprintf("Shared quest %s", questID))
|
|
|
|
default:
|
|
ctx.AddErrorMessage("Usage: /quest <list|abandon|share> [quest_id]")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleHelp handles the /help command
|
|
func HandleHelp(ctx *CommandContext) error {
|
|
// TODO: Show available commands based on admin level
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "Available commands:")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/say <message> - Say something to nearby players")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/tell <player> <message> - Send private message")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/who - List online players")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/time - Show game time")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/location - Show current location")
|
|
ctx.AddMessage(ChannelCommands, ColorWhite, "/help - Show this help")
|
|
|
|
return nil
|
|
}
|
|
|
|
// HandleQuit handles the /quit command
|
|
func HandleQuit(ctx *CommandContext) error {
|
|
if err := ctx.RequirePlayer(); err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx.AddStatusMessage("Logging out safely...")
|
|
|
|
// TODO: Implement safe logout
|
|
// if ctx.Client != nil {
|
|
// ctx.Client.Disconnect()
|
|
// }
|
|
|
|
return nil
|
|
}
|