4543 lines
129 KiB
Lua
4543 lines
129 KiB
Lua
MESSAGE_SCROLLBUTTON_INITIAL_DELAY = 0;
|
|
MESSAGE_SCROLLBUTTON_SCROLL_DELAY = 0.05;
|
|
CHAT_BUTTON_FLASH_TIME = 0.5;
|
|
CHAT_TELL_ALERT_TIME = 300;
|
|
NUM_CHAT_WINDOWS = 10;
|
|
DEFAULT_CHAT_FRAME = ChatFrame1;
|
|
NUM_REMEMBERED_TELLS = 10;
|
|
MAX_WOW_CHAT_CHANNELS = 10;
|
|
|
|
CHAT_TIMESTAMP_FORMAT = nil; -- gets set from Interface Options
|
|
CHAT_SHOW_IME = false;
|
|
|
|
MAX_CHARACTER_NAME_BYTES = 48;
|
|
|
|
--DEBUG FIXME FOR TESTING
|
|
CHAT_OPTIONS = {
|
|
ONE_EDIT_AT_A_TIME = "old"
|
|
};
|
|
|
|
-- Table for event indexed chatFilters.
|
|
-- Format ["CHAT_MSG_SYSTEM"] = { function1, function2, function3 }
|
|
-- filter, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 = function1 (self, event, ...) if filter then return true end return false, ... end
|
|
local chatFilters = {};
|
|
|
|
-- These hash tables are to improve performance of common lookups
|
|
-- if you change what these tables point to (ie slash command, emote, chat)
|
|
-- then you need to invalidate the entry in the hash table
|
|
local hash_SecureCmdList = {}
|
|
hash_SlashCmdList = {}
|
|
hash_EmoteTokenList = {}
|
|
hash_ChatTypeInfoList = {}
|
|
|
|
ChatTypeInfo = { };
|
|
ChatTypeInfo["SYSTEM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["SAY"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["PARTY"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RAID"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["GUILD"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["OFFICER"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["YELL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["WHISPER"] = { sticky = 1, flashTab = true, flashTabOnGeneral = true };
|
|
ChatTypeInfo["WHISPER_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["REPLY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["TEXT_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["MONSTER_SAY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["MONSTER_PARTY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["MONSTER_YELL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["MONSTER_WHISPER"] = { sticky = 0, flashTab = true, flashTabOnGeneral = true };
|
|
ChatTypeInfo["MONSTER_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL_JOIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL_LEAVE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL_LIST"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL_NOTICE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL_NOTICE_USER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["TARGETICONS"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["AFK"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["DND"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["IGNORED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["SKILL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["LOOT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["MONEY"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["OPENING"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["TRADESKILLS"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["PET_INFO"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["COMBAT_MISC_INFO"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["COMBAT_XP_GAIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["COMBAT_HONOR_GAIN"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["COMBAT_FACTION_CHANGE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BG_SYSTEM_NEUTRAL"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BG_SYSTEM_ALLIANCE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BG_SYSTEM_HORDE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RAID_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RAID_WARNING"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RAID_BOSS_WHISPER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RAID_BOSS_EMOTE"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["FILTERED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BATTLEGROUND"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BATTLEGROUND_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["RESTRICTED"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL1"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL2"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL3"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL4"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL5"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL6"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL7"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL8"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL9"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["CHANNEL10"] = { sticky = 1, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["ACHIEVEMENT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["GUILD_ACHIEVEMENT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["PARTY_LEADER"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_WHISPER"] = { sticky = 1, flashTab = true, flashTabOnGeneral = true };
|
|
ChatTypeInfo["BN_WHISPER_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_CONVERSATION"] = { sticky = 1, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_CONVERSATION_NOTICE"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_CONVERSATION_LIST"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_ALERT"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_BROADCAST"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_BROADCAST_INFORM"] = { sticky = 0, flashTab = false, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_INLINE_TOAST_ALERT"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_INLINE_TOAST_BROADCAST"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_INLINE_TOAST_BROADCAST_INFORM"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
ChatTypeInfo["BN_INLINE_TOAST_CONVERSATION"] = { sticky = 0, flashTab = true, flashTabOnGeneral = false };
|
|
|
|
ChatTypeGroup = {};
|
|
ChatTypeGroup["SYSTEM"] = {
|
|
"CHAT_MSG_SYSTEM",
|
|
"TIME_PLAYED_MSG",
|
|
"PLAYER_LEVEL_UP",
|
|
"CHARACTER_POINTS_CHANGED",
|
|
};
|
|
ChatTypeGroup["SAY"] = {
|
|
"CHAT_MSG_SAY",
|
|
};
|
|
ChatTypeGroup["EMOTE"] = {
|
|
"CHAT_MSG_EMOTE",
|
|
"CHAT_MSG_TEXT_EMOTE",
|
|
};
|
|
ChatTypeGroup["YELL"] = {
|
|
"CHAT_MSG_YELL",
|
|
};
|
|
ChatTypeGroup["WHISPER"] = {
|
|
"CHAT_MSG_WHISPER",
|
|
"CHAT_MSG_WHISPER_INFORM",
|
|
"CHAT_MSG_AFK",
|
|
"CHAT_MSG_DND",
|
|
};
|
|
ChatTypeGroup["PARTY"] = {
|
|
"CHAT_MSG_PARTY",
|
|
"CHAT_MSG_MONSTER_PARTY",
|
|
};
|
|
ChatTypeGroup["PARTY_LEADER"] = {
|
|
"CHAT_MSG_PARTY_LEADER",
|
|
};
|
|
ChatTypeGroup["RAID"] = {
|
|
"CHAT_MSG_RAID",
|
|
};
|
|
ChatTypeGroup["RAID_LEADER"] = {
|
|
"CHAT_MSG_RAID_LEADER",
|
|
};
|
|
ChatTypeGroup["RAID_WARNING"] = {
|
|
"CHAT_MSG_RAID_WARNING",
|
|
};
|
|
ChatTypeGroup["BATTLEGROUND"] = {
|
|
"CHAT_MSG_BATTLEGROUND",
|
|
};
|
|
ChatTypeGroup["BATTLEGROUND_LEADER"] = {
|
|
"CHAT_MSG_BATTLEGROUND_LEADER",
|
|
};
|
|
ChatTypeGroup["GUILD"] = {
|
|
"CHAT_MSG_GUILD",
|
|
"GUILD_MOTD",
|
|
};
|
|
ChatTypeGroup["OFFICER"] = {
|
|
"CHAT_MSG_OFFICER",
|
|
};
|
|
ChatTypeGroup["MONSTER_SAY"] = {
|
|
"CHAT_MSG_MONSTER_SAY",
|
|
};
|
|
ChatTypeGroup["MONSTER_YELL"] = {
|
|
"CHAT_MSG_MONSTER_YELL",
|
|
};
|
|
ChatTypeGroup["MONSTER_EMOTE"] = {
|
|
"CHAT_MSG_MONSTER_EMOTE",
|
|
};
|
|
ChatTypeGroup["MONSTER_WHISPER"] = {
|
|
"CHAT_MSG_MONSTER_WHISPER",
|
|
};
|
|
ChatTypeGroup["MONSTER_BOSS_EMOTE"] = {
|
|
"CHAT_MSG_RAID_BOSS_EMOTE",
|
|
};
|
|
ChatTypeGroup["MONSTER_BOSS_WHISPER"] = {
|
|
"CHAT_MSG_RAID_BOSS_WHISPER",
|
|
};
|
|
ChatTypeGroup["ERRORS"] = {
|
|
"CHAT_MSG_RESTRICTED",
|
|
"CHAT_MSG_FILTERED",
|
|
};
|
|
ChatTypeGroup["AFK"] = {
|
|
"CHAT_MSG_AFK",
|
|
};
|
|
ChatTypeGroup["DND"] = {
|
|
"CHAT_MSG_DND",
|
|
};
|
|
ChatTypeGroup["IGNORED"] = {
|
|
"CHAT_MSG_IGNORED",
|
|
};
|
|
ChatTypeGroup["BG_HORDE"] = {
|
|
"CHAT_MSG_BG_SYSTEM_HORDE",
|
|
};
|
|
ChatTypeGroup["BG_ALLIANCE"] = {
|
|
"CHAT_MSG_BG_SYSTEM_ALLIANCE",
|
|
};
|
|
ChatTypeGroup["BG_NEUTRAL"] = {
|
|
"CHAT_MSG_BG_SYSTEM_NEUTRAL",
|
|
};
|
|
ChatTypeGroup["COMBAT_XP_GAIN"] = {
|
|
"CHAT_MSG_COMBAT_XP_GAIN";
|
|
}
|
|
ChatTypeGroup["COMBAT_HONOR_GAIN"] = {
|
|
"CHAT_MSG_COMBAT_HONOR_GAIN";
|
|
}
|
|
ChatTypeGroup["COMBAT_FACTION_CHANGE"] = {
|
|
"CHAT_MSG_COMBAT_FACTION_CHANGE";
|
|
};
|
|
ChatTypeGroup["SKILL"] = {
|
|
"CHAT_MSG_SKILL",
|
|
};
|
|
ChatTypeGroup["LOOT"] = {
|
|
"CHAT_MSG_LOOT",
|
|
};
|
|
ChatTypeGroup["MONEY"] = {
|
|
"CHAT_MSG_MONEY",
|
|
};
|
|
ChatTypeGroup["OPENING"] = {
|
|
"CHAT_MSG_OPENING";
|
|
};
|
|
ChatTypeGroup["TRADESKILLS"] = {
|
|
"CHAT_MSG_TRADESKILLS";
|
|
};
|
|
ChatTypeGroup["PET_INFO"] = {
|
|
"CHAT_MSG_PET_INFO";
|
|
};
|
|
ChatTypeGroup["COMBAT_MISC_INFO"] = {
|
|
"CHAT_MSG_COMBAT_MISC_INFO";
|
|
};
|
|
ChatTypeGroup["ACHIEVEMENT"] = {
|
|
"CHAT_MSG_ACHIEVEMENT";
|
|
};
|
|
ChatTypeGroup["GUILD_ACHIEVEMENT"] = {
|
|
"CHAT_MSG_GUILD_ACHIEVEMENT";
|
|
};
|
|
ChatTypeGroup["CHANNEL"] = {
|
|
"CHAT_MSG_CHANNEL_JOIN",
|
|
"CHAT_MSG_CHANNEL_LEAVE",
|
|
"CHAT_MSG_CHANNEL_NOTICE",
|
|
"CHAT_MSG_CHANNEL_NOTICE_USER",
|
|
"CHAT_MSG_CHANNEL_LIST",
|
|
};
|
|
ChatTypeGroup["TARGETICONS"] = {
|
|
"CHAT_MSG_TARGETICONS"
|
|
};
|
|
ChatTypeGroup["BN_WHISPER"] = {
|
|
"CHAT_MSG_BN_WHISPER",
|
|
"CHAT_MSG_BN_WHISPER_INFORM",
|
|
};
|
|
ChatTypeGroup["BN_CONVERSATION"] = {
|
|
"CHAT_MSG_BN_CONVERSATION",
|
|
"CHAT_MSG_BN_CONVERSATION_NOTICE",
|
|
"CHAT_MSG_BN_CONVERSATION_LIST",
|
|
};
|
|
ChatTypeGroup["BN_INLINE_TOAST_ALERT"] = {
|
|
"CHAT_MSG_BN_INLINE_TOAST_ALERT",
|
|
"CHAT_MSG_BN_INLINE_TOAST_BROADCAST",
|
|
"CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM",
|
|
"CHAT_MSG_BN_INLINE_TOAST_CONVERSATION",
|
|
};
|
|
ChatTypeGroupInverted = {};
|
|
for group, values in pairs(ChatTypeGroup) do
|
|
for _, value in pairs(values) do
|
|
ChatTypeGroupInverted[value] = group;
|
|
end
|
|
end
|
|
|
|
CHAT_CATEGORY_LIST = {
|
|
PARTY = { "PARTY_LEADER", "PARTY_GUIDE", "MONSTER_PARTY" },
|
|
RAID = { "RAID_LEADER", "RAID_WARNING" },
|
|
GUILD = { "GUILD_ACHIEVEMENT" },
|
|
WHISPER = { "WHISPER_INFORM", "AFK", "DND" },
|
|
CHANNEL = { "CHANNEL_JOIN", "CHANNEL_LEAVE", "CHANNEL_NOTICE", "CHANNEL_USER" },
|
|
BATTLEGROUND = { "BATTLEGROUND_LEADER" },
|
|
BN_WHISPER = { "BN_WHISPER_INFORM" },
|
|
BN_CONVERSATION = { "BN_CONVERSATION_NOTICE", "BN_CONVERSATION_LIST" },
|
|
};
|
|
|
|
CHAT_INVERTED_CATEGORY_LIST = {};
|
|
for category, sublist in pairs(CHAT_CATEGORY_LIST) do
|
|
for _, item in pairs(sublist) do
|
|
CHAT_INVERTED_CATEGORY_LIST[item] = category;
|
|
end
|
|
end
|
|
|
|
function Chat_GetChatCategory(chatType)
|
|
return CHAT_INVERTED_CATEGORY_LIST[chatType] or chatType;
|
|
end
|
|
|
|
ChannelMenuChatTypeGroups = {};
|
|
ChannelMenuChatTypeGroups[1] = "SAY";
|
|
ChannelMenuChatTypeGroups[2] = "YELL";
|
|
ChannelMenuChatTypeGroups[3] = "GUILD";
|
|
ChannelMenuChatTypeGroups[4] = "WHISPER";
|
|
ChannelMenuChatTypeGroups[5] = "PARTY";
|
|
|
|
CombatLogMenuChatTypeGroups = {};
|
|
CombatLogMenuChatTypeGroups[1] = "OPENING";
|
|
CombatLogMenuChatTypeGroups[2] = "TRADESKILLS";
|
|
CombatLogMenuChatTypeGroups[3] = "PET_INFO";
|
|
CombatLogMenuChatTypeGroups[4] = "COMBAT_MISC_INFO";
|
|
CombatLogMenuChatTypeGroups[5] = "COMBAT_XP_GAIN";
|
|
CombatLogMenuChatTypeGroups[6] = "COMBAT_HONOR_GAIN";
|
|
CombatLogMenuChatTypeGroups[7] = "COMBAT_FACTION_CHANGE";
|
|
|
|
OtherMenuChatTypeGroups = {};
|
|
OtherMenuChatTypeGroups[1] = "CREATURE";
|
|
OtherMenuChatTypeGroups[2] = "SKILL";
|
|
OtherMenuChatTypeGroups[3] = "LOOT";
|
|
|
|
-- list of text emotes that we want to show on the Emote submenu (these have anims)
|
|
EmoteList = {
|
|
"WAVE",
|
|
"BOW",
|
|
"DANCE",
|
|
"APPLAUD",
|
|
"BEG",
|
|
"CHICKEN",
|
|
"CRY",
|
|
"EAT",
|
|
"FLEX",
|
|
"KISS",
|
|
"LAUGH",
|
|
"POINT",
|
|
"ROAR",
|
|
"RUDE",
|
|
"SALUTE",
|
|
"SHY",
|
|
"TALK",
|
|
"STAND",
|
|
"SIT",
|
|
"SLEEP",
|
|
"KNEEL",
|
|
};
|
|
|
|
-- list of text emotes that we want to show on the Speech submenu (these have sounds)
|
|
TextEmoteSpeechList = {
|
|
"HELPME",
|
|
"INCOMING",
|
|
"CHARGE",
|
|
"FLEE",
|
|
"ATTACKMYTARGET",
|
|
"OOM",
|
|
"FOLLOW",
|
|
"WAIT",
|
|
"HEALME",
|
|
"CHEER",
|
|
"OPENFIRE",
|
|
"RASP",
|
|
"HELLO",
|
|
"BYE",
|
|
"NOD",
|
|
"NO",
|
|
"THANK",
|
|
"WELCOME",
|
|
"CONGRATULATE",
|
|
"FLIRT",
|
|
"JOKE",
|
|
"TRAIN",
|
|
};
|
|
|
|
-- These are text emote tokens - add new ones at the bottom of the list!
|
|
EMOTE1_TOKEN = "AGREE";
|
|
EMOTE2_TOKEN = "AMAZE";
|
|
EMOTE3_TOKEN = "ANGRY";
|
|
EMOTE4_TOKEN = "APOLOGIZE";
|
|
EMOTE5_TOKEN = "APPLAUD";
|
|
EMOTE6_TOKEN = "BASHFUL";
|
|
EMOTE7_TOKEN = "BECKON";
|
|
EMOTE8_TOKEN = "BEG";
|
|
EMOTE9_TOKEN = "BITE";
|
|
EMOTE10_TOKEN = "BLEED";
|
|
EMOTE11_TOKEN = "BLINK";
|
|
EMOTE12_TOKEN = "BLUSH";
|
|
EMOTE13_TOKEN = "BONK";
|
|
EMOTE14_TOKEN = "BORED";
|
|
EMOTE15_TOKEN = "BOUNCE";
|
|
EMOTE16_TOKEN = "BRB";
|
|
EMOTE17_TOKEN = "BOW";
|
|
EMOTE18_TOKEN = "BURP";
|
|
EMOTE19_TOKEN = "BYE";
|
|
EMOTE20_TOKEN = "CACKLE";
|
|
EMOTE21_TOKEN = "CHEER";
|
|
EMOTE22_TOKEN = "CHICKEN";
|
|
EMOTE23_TOKEN = "CHUCKLE";
|
|
EMOTE24_TOKEN = "CLAP";
|
|
EMOTE25_TOKEN = "CONFUSED";
|
|
EMOTE26_TOKEN = "CONGRATULATE";
|
|
EMOTE27_TOKEN = "UNUSED";
|
|
EMOTE28_TOKEN = "COUGH";
|
|
EMOTE29_TOKEN = "COWER";
|
|
EMOTE30_TOKEN = "CRACK";
|
|
EMOTE31_TOKEN = "CRINGE";
|
|
EMOTE32_TOKEN = "CRY";
|
|
EMOTE33_TOKEN = "CURIOUS";
|
|
EMOTE34_TOKEN = "CURTSEY";
|
|
EMOTE35_TOKEN = "DANCE";
|
|
EMOTE36_TOKEN = "DRINK";
|
|
EMOTE37_TOKEN = "DROOL";
|
|
EMOTE38_TOKEN = "EAT";
|
|
EMOTE39_TOKEN = "EYE";
|
|
EMOTE40_TOKEN = "FART";
|
|
EMOTE41_TOKEN = "FIDGET";
|
|
EMOTE42_TOKEN = "FLEX";
|
|
EMOTE43_TOKEN = "FROWN";
|
|
EMOTE44_TOKEN = "GASP";
|
|
EMOTE45_TOKEN = "GAZE";
|
|
EMOTE46_TOKEN = "GIGGLE";
|
|
EMOTE47_TOKEN = "GLARE";
|
|
EMOTE48_TOKEN = "GLOAT";
|
|
EMOTE49_TOKEN = "GREET";
|
|
EMOTE50_TOKEN = "GRIN";
|
|
EMOTE51_TOKEN = "GROAN";
|
|
EMOTE52_TOKEN = "GROVEL";
|
|
EMOTE53_TOKEN = "GUFFAW";
|
|
EMOTE54_TOKEN = "HAIL";
|
|
EMOTE55_TOKEN = "HAPPY";
|
|
EMOTE56_TOKEN = "HELLO";
|
|
EMOTE57_TOKEN = "HUG";
|
|
EMOTE58_TOKEN = "HUNGRY";
|
|
EMOTE59_TOKEN = "KISS";
|
|
EMOTE60_TOKEN = "KNEEL";
|
|
EMOTE61_TOKEN = "LAUGH";
|
|
EMOTE62_TOKEN = "LAYDOWN";
|
|
EMOTE63_TOKEN = "MASSAGE";
|
|
EMOTE64_TOKEN = "MOAN";
|
|
EMOTE65_TOKEN = "MOON";
|
|
EMOTE66_TOKEN = "MOURN";
|
|
EMOTE67_TOKEN = "NO";
|
|
EMOTE68_TOKEN = "NOD";
|
|
EMOTE69_TOKEN = "NOSEPICK";
|
|
EMOTE70_TOKEN = "PANIC";
|
|
EMOTE71_TOKEN = "PEER";
|
|
EMOTE72_TOKEN = "PLEAD";
|
|
EMOTE73_TOKEN = "POINT";
|
|
EMOTE74_TOKEN = "POKE";
|
|
EMOTE75_TOKEN = "PRAY";
|
|
EMOTE76_TOKEN = "ROAR";
|
|
EMOTE77_TOKEN = "ROFL";
|
|
EMOTE78_TOKEN = "RUDE";
|
|
EMOTE79_TOKEN = "SALUTE";
|
|
EMOTE80_TOKEN = "SCRATCH";
|
|
EMOTE81_TOKEN = "SEXY";
|
|
EMOTE82_TOKEN = "SHAKE";
|
|
EMOTE83_TOKEN = "SHOUT";
|
|
EMOTE84_TOKEN = "SHRUG";
|
|
EMOTE85_TOKEN = "SHY";
|
|
EMOTE86_TOKEN = "SIGH";
|
|
EMOTE87_TOKEN = "SIT";
|
|
EMOTE88_TOKEN = "SLEEP";
|
|
EMOTE89_TOKEN = "SNARL";
|
|
EMOTE90_TOKEN = "SPIT";
|
|
EMOTE91_TOKEN = "STARE";
|
|
EMOTE92_TOKEN = "SURPRISED";
|
|
EMOTE93_TOKEN = "SURRENDER";
|
|
EMOTE94_TOKEN = "TALK";
|
|
EMOTE95_TOKEN = "TALKEX";
|
|
EMOTE96_TOKEN = "TALKQ";
|
|
EMOTE97_TOKEN = "TAP";
|
|
EMOTE98_TOKEN = "THANK";
|
|
EMOTE99_TOKEN = "THREATEN";
|
|
EMOTE100_TOKEN = "TIRED";
|
|
EMOTE101_TOKEN = "VICTORY";
|
|
EMOTE102_TOKEN = "WAVE";
|
|
EMOTE103_TOKEN = "WELCOME";
|
|
EMOTE104_TOKEN = "WHINE";
|
|
EMOTE105_TOKEN = "WHISTLE";
|
|
EMOTE106_TOKEN = "WORK";
|
|
EMOTE107_TOKEN = "YAWN";
|
|
EMOTE108_TOKEN = "BOGGLE";
|
|
EMOTE109_TOKEN = "CALM";
|
|
EMOTE110_TOKEN = "COLD";
|
|
EMOTE111_TOKEN = "COMFORT";
|
|
EMOTE112_TOKEN = "CUDDLE";
|
|
EMOTE113_TOKEN = "DUCK";
|
|
EMOTE114_TOKEN = "INSULT";
|
|
EMOTE115_TOKEN = "INTRODUCE";
|
|
EMOTE116_TOKEN = "JK";
|
|
EMOTE117_TOKEN = "LICK";
|
|
EMOTE118_TOKEN = "LISTEN";
|
|
EMOTE119_TOKEN = "LOST";
|
|
EMOTE120_TOKEN = "MOCK";
|
|
EMOTE121_TOKEN = "PONDER";
|
|
EMOTE122_TOKEN = "POUNCE";
|
|
EMOTE123_TOKEN = "PRAISE";
|
|
EMOTE124_TOKEN = "PURR";
|
|
EMOTE125_TOKEN = "PUZZLE";
|
|
EMOTE126_TOKEN = "RAISE";
|
|
EMOTE127_TOKEN = "READY";
|
|
EMOTE128_TOKEN = "SHIMMY";
|
|
EMOTE129_TOKEN = "SHIVER";
|
|
EMOTE130_TOKEN = "SHOO";
|
|
EMOTE131_TOKEN = "SLAP";
|
|
EMOTE132_TOKEN = "SMIRK";
|
|
EMOTE133_TOKEN = "SNIFF";
|
|
EMOTE134_TOKEN = "SNUB";
|
|
EMOTE135_TOKEN = "SOOTHE";
|
|
EMOTE136_TOKEN = "STINK";
|
|
EMOTE137_TOKEN = "TAUNT";
|
|
EMOTE138_TOKEN = "TEASE";
|
|
EMOTE139_TOKEN = "THIRSTY";
|
|
EMOTE140_TOKEN = "VETO";
|
|
EMOTE141_TOKEN = "SNICKER";
|
|
EMOTE142_TOKEN = "TICKLE";
|
|
EMOTE143_TOKEN = "STAND";
|
|
EMOTE144_TOKEN = "VIOLIN";
|
|
EMOTE145_TOKEN = "SMILE";
|
|
EMOTE146_TOKEN = "RASP";
|
|
EMOTE147_TOKEN = "GROWL";
|
|
EMOTE148_TOKEN = "BARK";
|
|
EMOTE149_TOKEN = "PITY";
|
|
EMOTE150_TOKEN = "SCARED";
|
|
EMOTE151_TOKEN = "FLOP";
|
|
EMOTE152_TOKEN = "LOVE";
|
|
EMOTE153_TOKEN = "MOO";
|
|
EMOTE154_TOKEN = "COMMEND";
|
|
EMOTE155_TOKEN = "TRAIN";
|
|
EMOTE156_TOKEN = "HELPME";
|
|
EMOTE157_TOKEN = "INCOMING";
|
|
EMOTE158_TOKEN = "OPENFIRE";
|
|
EMOTE159_TOKEN = "CHARGE";
|
|
EMOTE160_TOKEN = "FLEE";
|
|
EMOTE161_TOKEN = "ATTACKMYTARGET";
|
|
EMOTE162_TOKEN = "OOM";
|
|
EMOTE163_TOKEN = "FOLLOW";
|
|
EMOTE164_TOKEN = "WAIT";
|
|
EMOTE165_TOKEN = "FLIRT";
|
|
EMOTE166_TOKEN = "HEALME";
|
|
EMOTE167_TOKEN = "JOKE";
|
|
EMOTE168_TOKEN = "WINK";
|
|
EMOTE169_TOKEN = "PAT";
|
|
EMOTE170_TOKEN = "GOLFCLAP";
|
|
EMOTE171_TOKEN = "MOUNTSPECIAL";
|
|
EMOTE304_TOKEN = "INCOMING";
|
|
EMOTE306_TOKEN = "FLEE";
|
|
EMOTE368_TOKEN = "BLAME"
|
|
EMOTE369_TOKEN = "BLANK"
|
|
EMOTE370_TOKEN = "BRANDISH"
|
|
EMOTE371_TOKEN = "BREATH"
|
|
EMOTE372_TOKEN = "DISAGREE"
|
|
EMOTE373_TOKEN = "DOUBT"
|
|
EMOTE374_TOKEN = "EMBARRASS"
|
|
EMOTE375_TOKEN = "ENCOURAGE"
|
|
EMOTE376_TOKEN = "ENEMY"
|
|
EMOTE377_TOKEN = "EYEBROW"
|
|
EMOTE380_TOKEN = "HIGHFIVE"
|
|
EMOTE381_TOKEN = "ABSENT"
|
|
EMOTE382_TOKEN = "ARM"
|
|
EMOTE383_TOKEN = "AWE"
|
|
EMOTE384_TOKEN = "BACKPACK"
|
|
EMOTE385_TOKEN = "BADFEELING"
|
|
EMOTE386_TOKEN = "CHALLENGE"
|
|
EMOTE387_TOKEN = "CHUG"
|
|
EMOTE389_TOKEN = "DING"
|
|
EMOTE390_TOKEN = "FACEPALM"
|
|
EMOTE391_TOKEN = "FAINT"
|
|
EMOTE392_TOKEN = "GO"
|
|
EMOTE393_TOKEN = "GOING"
|
|
EMOTE394_TOKEN = "GLOWER"
|
|
EMOTE395_TOKEN = "HEADACHE"
|
|
EMOTE396_TOKEN = "HICCUP"
|
|
EMOTE398_TOKEN = "HISS"
|
|
EMOTE399_TOKEN = "HOLDHAND"
|
|
EMOTE401_TOKEN = "HURRY"
|
|
EMOTE402_TOKEN = "IDEA"
|
|
EMOTE403_TOKEN = "JEALOUS"
|
|
EMOTE404_TOKEN = "LUCK"
|
|
EMOTE405_TOKEN = "MAP"
|
|
EMOTE406_TOKEN = "MERCY"
|
|
EMOTE407_TOKEN = "MUTTER"
|
|
EMOTE408_TOKEN = "NERVOUS"
|
|
EMOTE409_TOKEN = "OFFER"
|
|
EMOTE410_TOKEN = "PET"
|
|
EMOTE411_TOKEN = "PINCH"
|
|
EMOTE413_TOKEN = "PROUD"
|
|
EMOTE414_TOKEN = "PROMISE"
|
|
EMOTE415_TOKEN = "PULSE"
|
|
EMOTE416_TOKEN = "PUNCH"
|
|
EMOTE417_TOKEN = "POUT"
|
|
EMOTE418_TOKEN = "REGRET"
|
|
EMOTE420_TOKEN = "REVENGE"
|
|
EMOTE421_TOKEN = "ROLLEYES"
|
|
EMOTE422_TOKEN = "RUFFLE"
|
|
EMOTE423_TOKEN = "SAD"
|
|
EMOTE424_TOKEN = "SCOFF"
|
|
EMOTE425_TOKEN = "SCOLD"
|
|
EMOTE426_TOKEN = "SCOWL"
|
|
EMOTE427_TOKEN = "SEARCH"
|
|
EMOTE428_TOKEN = "SHAKEFIST"
|
|
EMOTE429_TOKEN = "SHIFTY"
|
|
EMOTE430_TOKEN = "SHUDDER"
|
|
EMOTE431_TOKEN = "SIGNAL"
|
|
EMOTE432_TOKEN = "SILENCE"
|
|
EMOTE433_TOKEN = "SING"
|
|
EMOTE434_TOKEN = "SMACK"
|
|
EMOTE435_TOKEN = "SNEAK"
|
|
EMOTE436_TOKEN = "SNEEZE"
|
|
EMOTE437_TOKEN = "SNORT"
|
|
EMOTE438_TOKEN = "SQUEAL"
|
|
EMOTE440_TOKEN = "SUSPICIOUS"
|
|
EMOTE441_TOKEN = "THINK"
|
|
EMOTE442_TOKEN = "TRUCE"
|
|
EMOTE443_TOKEN = "TWIDDLE"
|
|
EMOTE444_TOKEN = "WARN"
|
|
EMOTE445_TOKEN = "SNAP"
|
|
EMOTE446_TOKEN = "CHARM"
|
|
EMOTE447_TOKEN = "COVEREARS"
|
|
EMOTE448_TOKEN = "CROSSARMS"
|
|
EMOTE449_TOKEN = "LOOK"
|
|
EMOTE450_TOKEN = "OBJECT"
|
|
EMOTE451_TOKEN = "SWEAT"
|
|
EMOTE452_TOKEN = "YW"
|
|
local MAXEMOTEINDEX = 452;
|
|
|
|
|
|
ICON_LIST = {
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_2:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_3:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_4:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_5:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_6:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_7:",
|
|
"|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_8:",
|
|
}
|
|
|
|
--Links tags from Global Strings to indicies for entries in ICON_LIST. This way addons can easily replace icons
|
|
ICON_TAG_LIST =
|
|
{
|
|
[strlower(ICON_TAG_RAID_TARGET_STAR1)] = 1,
|
|
[strlower(ICON_TAG_RAID_TARGET_STAR2)] = 1,
|
|
[strlower(ICON_TAG_RAID_TARGET_CIRCLE1)] = 2,
|
|
[strlower(ICON_TAG_RAID_TARGET_CIRCLE2)] = 2,
|
|
[strlower(ICON_TAG_RAID_TARGET_DIAMOND1)] = 3,
|
|
[strlower(ICON_TAG_RAID_TARGET_DIAMOND2)] = 3,
|
|
[strlower(ICON_TAG_RAID_TARGET_TRIANGLE1)] = 4,
|
|
[strlower(ICON_TAG_RAID_TARGET_TRIANGLE2)] = 4,
|
|
[strlower(ICON_TAG_RAID_TARGET_MOON1)] = 5,
|
|
[strlower(ICON_TAG_RAID_TARGET_MOON2)] = 5,
|
|
[strlower(ICON_TAG_RAID_TARGET_SQUARE1)] = 6,
|
|
[strlower(ICON_TAG_RAID_TARGET_SQUARE2)] = 6,
|
|
[strlower(ICON_TAG_RAID_TARGET_CROSS1)] = 7,
|
|
[strlower(ICON_TAG_RAID_TARGET_CROSS2)] = 7,
|
|
[strlower(ICON_TAG_RAID_TARGET_SKULL1)] = 8,
|
|
[strlower(ICON_TAG_RAID_TARGET_SKULL2)] = 8,
|
|
[strlower(RAID_TARGET_1)] = 1,
|
|
[strlower(RAID_TARGET_2)] = 2,
|
|
[strlower(RAID_TARGET_3)] = 3,
|
|
[strlower(RAID_TARGET_4)] = 4,
|
|
[strlower(RAID_TARGET_5)] = 5,
|
|
[strlower(RAID_TARGET_6)] = 6,
|
|
[strlower(RAID_TARGET_7)] = 7,
|
|
[strlower(RAID_TARGET_8)] = 8,
|
|
}
|
|
|
|
-- Arena Team Helper Function
|
|
function ArenaTeam_GetTeamSizeID(teamsizearg)
|
|
local teamname, teamsize, id;
|
|
for i=1, MAX_ARENA_TEAMS do
|
|
teamname, teamsize = GetArenaTeam(i)
|
|
if ( teamsizearg == teamsize ) then
|
|
id = i;
|
|
end
|
|
end
|
|
return id;
|
|
end
|
|
|
|
--
|
|
-- CastSequence support
|
|
--
|
|
|
|
local CastSequenceManager;
|
|
local CastSequenceTable = {};
|
|
local CastSequenceFreeList = {};
|
|
|
|
local function CreateCanonicalActions(entry, ...)
|
|
entry.spells = {};
|
|
entry.spellNames = {};
|
|
entry.items = {};
|
|
for i=1, select("#", ...) do
|
|
local action = strlower(strtrim((select(i, ...))));
|
|
if ( GetItemInfo(action) or select(3, SecureCmdItemParse(action)) ) then
|
|
entry.items[i] = action;
|
|
entry.spells[i] = strlower(GetItemSpell(action) or "");
|
|
entry.spellNames[i] = entry.spells[i];
|
|
else
|
|
entry.spells[i] = action;
|
|
entry.spellNames[i] = gsub(action, "!*(.*)", "%1");
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetCastSequenceIndex(entry, index)
|
|
entry.index = index;
|
|
entry.pending = nil;
|
|
end
|
|
|
|
local function ResetCastSequence(sequence, entry)
|
|
SetCastSequenceIndex(entry, 1);
|
|
CastSequenceFreeList[sequence] = entry;
|
|
CastSequenceTable[sequence] = nil;
|
|
end
|
|
|
|
local function SetNextCastSequence(sequence, entry)
|
|
if ( entry.index == #entry.spells ) then
|
|
ResetCastSequence(sequence, entry);
|
|
else
|
|
SetCastSequenceIndex(entry, entry.index + 1);
|
|
end
|
|
end
|
|
|
|
local function CastSequenceManager_OnEvent(self, event, ...)
|
|
|
|
-- Reset all sequences when the player dies
|
|
if ( event == "PLAYER_DEAD" ) then
|
|
for sequence, entry in pairs(CastSequenceTable) do
|
|
ResetCastSequence(sequence, entry);
|
|
end
|
|
return;
|
|
end
|
|
|
|
-- Increment sequences for spells which succeed.
|
|
if ( event == "UNIT_SPELLCAST_SENT" or
|
|
event == "UNIT_SPELLCAST_SUCCEEDED" or
|
|
event == "UNIT_SPELLCAST_INTERRUPTED" or
|
|
event == "UNIT_SPELLCAST_FAILED" or
|
|
event == "UNIT_SPELLCAST_FAILED_QUIET" ) then
|
|
local unit, name, rank = ...;
|
|
|
|
if ( not name ) then
|
|
-- This was a server-side only spell affecting the player somehow, don't do anything with cast sequencing, just bail.
|
|
return;
|
|
end
|
|
|
|
if ( unit == "player" or unit == "pet" ) then
|
|
name, rank = strlower(name), strlower(rank);
|
|
local nameplus = name.."()";
|
|
local fullname = name.."("..rank..")";
|
|
for sequence, entry in pairs(CastSequenceTable) do
|
|
local entryName = entry.spellNames[entry.index];
|
|
if ( entryName == name or entryName == nameplus or entryName == fullname ) then
|
|
if ( event == "UNIT_SPELLCAST_SENT" ) then
|
|
entry.pending = 1;
|
|
else
|
|
entry.pending = nil;
|
|
if ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
|
|
SetNextCastSequence(sequence, entry);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return;
|
|
end
|
|
|
|
-- Handle reset events
|
|
local reset = "";
|
|
if ( event == "PLAYER_TARGET_CHANGED" ) then
|
|
reset = "target";
|
|
elseif ( event == "PLAYER_REGEN_ENABLED" ) then
|
|
reset = "combat";
|
|
end
|
|
for sequence, entry in pairs(CastSequenceTable) do
|
|
if ( strfind(entry.reset, reset, 1, true) ) then
|
|
ResetCastSequence(sequence, entry);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function CastSequenceManager_OnUpdate(self, elapsed)
|
|
elapsed = self.elapsed + elapsed;
|
|
if ( elapsed < 1 ) then
|
|
self.elapsed = elapsed;
|
|
return;
|
|
end
|
|
for sequence, entry in pairs(CastSequenceTable) do
|
|
if ( entry.timeout ) then
|
|
if ( elapsed >= entry.timeout ) then
|
|
ResetCastSequence(sequence, entry);
|
|
else
|
|
entry.timeout = entry.timeout - elapsed;
|
|
end
|
|
end
|
|
end
|
|
self.elapsed = 0;
|
|
end
|
|
|
|
local function ExecuteCastSequence(sequence, target)
|
|
if ( not CastSequenceManager ) then
|
|
CastSequenceManager = CreateFrame("Frame");
|
|
CastSequenceManager.elapsed = 0;
|
|
CastSequenceManager:RegisterEvent("PLAYER_DEAD");
|
|
CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_SENT");
|
|
CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
|
|
CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
|
|
CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_FAILED");
|
|
CastSequenceManager:RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET");
|
|
CastSequenceManager:RegisterEvent("PLAYER_TARGET_CHANGED");
|
|
CastSequenceManager:RegisterEvent("PLAYER_REGEN_ENABLED");
|
|
CastSequenceManager:SetScript("OnEvent", CastSequenceManager_OnEvent);
|
|
CastSequenceManager:SetScript("OnUpdate", CastSequenceManager_OnUpdate);
|
|
end
|
|
|
|
local entry = CastSequenceTable[sequence];
|
|
if ( not entry ) then
|
|
entry = CastSequenceFreeList[sequence];
|
|
if ( not entry ) then
|
|
local reset, spells = strmatch(sequence, "^reset=([^%s]+)%s*(.*)");
|
|
if ( not reset ) then
|
|
spells = sequence;
|
|
end
|
|
entry = {};
|
|
CreateCanonicalActions(entry, strsplit(",", spells));
|
|
entry.reset = strlower(reset or "");
|
|
end
|
|
CastSequenceTable[sequence] = entry;
|
|
entry.index = 1;
|
|
end
|
|
|
|
-- Don't do anything if this entry is still pending
|
|
if ( entry.pending ) then
|
|
return;
|
|
end
|
|
|
|
-- See if modified click restarts the sequence
|
|
if ( (IsShiftKeyDown() and strfind(entry.reset, "shift", 1, true)) or
|
|
(IsControlKeyDown() and strfind(entry.reset, "ctrl", 1, true)) or
|
|
(IsAltKeyDown() and strfind(entry.reset, "alt", 1, true)) ) then
|
|
SetCastSequenceIndex(entry, 1);
|
|
end
|
|
|
|
-- Reset the timeout each time the sequence is used
|
|
local timeout = strmatch(entry.reset, "(%d+)");
|
|
if ( timeout ) then
|
|
entry.timeout = CastSequenceManager.elapsed + tonumber(timeout);
|
|
end
|
|
|
|
-- Execute the sequence!
|
|
local item, spell = entry.items[entry.index], entry.spells[entry.index];
|
|
if ( item ) then
|
|
local name, bag, slot = SecureCmdItemParse(item);
|
|
if ( slot ) then
|
|
if ( name ) then
|
|
spell = strlower(GetItemSpell(name) or "");
|
|
else
|
|
spell = "";
|
|
end
|
|
entry.spellNames[entry.index] = spell;
|
|
end
|
|
if ( IsEquippableItem(name) and not IsEquippedItem(name) ) then
|
|
EquipItemByName(name);
|
|
else
|
|
SecureCmdUseItem(name, bag, slot, target);
|
|
end
|
|
else
|
|
CastSpellByName(spell, target);
|
|
end
|
|
if ( spell == "" ) then
|
|
SetNextCastSequence(sequence, entry);
|
|
end
|
|
end
|
|
|
|
function QueryCastSequence(sequence)
|
|
local index = 1;
|
|
local item, spell;
|
|
local entry = CastSequenceTable[sequence];
|
|
if ( entry ) then
|
|
if ( (IsShiftKeyDown() and strfind(entry.reset, "shift", 1, true)) or
|
|
(IsControlKeyDown() and strfind(entry.reset, "ctrl", 1, true)) or
|
|
(IsAltKeyDown() and strfind(entry.reset, "alt", 1, true)) ) then
|
|
index = 1;
|
|
else
|
|
index = entry.index;
|
|
end
|
|
item, spell = entry.items[index], entry.spells[index];
|
|
else
|
|
entry = CastSequenceFreeList[sequence];
|
|
if ( entry ) then
|
|
item, spell = entry.items[index], entry.spells[index];
|
|
else
|
|
local reset, spells = strmatch(sequence, "^reset=([^%s]+)%s*(.*)");
|
|
if ( not reset ) then
|
|
spells = sequence;
|
|
end
|
|
local action = strlower(strtrim((strsplit(",", spells))));
|
|
if ( GetItemInfo(action) or select(3, SecureCmdItemParse(action)) ) then
|
|
item, spell = action, strlower(GetItemSpell(action) or "");
|
|
else
|
|
item, spell = nil, action;
|
|
end
|
|
end
|
|
end
|
|
if ( item ) then
|
|
local name, bag, slot = SecureCmdItemParse(item);
|
|
if ( slot ) then
|
|
if ( name ) then
|
|
spell = strlower(GetItemSpell(name) or "");
|
|
else
|
|
spell = "";
|
|
end
|
|
end
|
|
end
|
|
return index, item, spell;
|
|
end
|
|
|
|
|
|
local CastRandomManager;
|
|
local CastRandomTable = {};
|
|
|
|
local function CastRandomManager_OnEvent(self, event, ...)
|
|
local unit, name, rank = ...;
|
|
|
|
if ( not name ) then
|
|
-- This was a server-side only spell affecting the player somehow, don't do anything with cast sequencing, just bail.
|
|
return;
|
|
end
|
|
|
|
if ( unit == "player" ) then
|
|
name, rank = strlower(name), strlower(rank);
|
|
local nameplus = name.."()";
|
|
local fullname = name.."("..rank..")";
|
|
for sequence, entry in pairs(CastRandomTable) do
|
|
if ( entry.pending and entry.value ) then
|
|
local entryName = strlower(entry.value);
|
|
if ( entryName == name or entryName == nameplus or entryName == fullname ) then
|
|
entry.pending = nil;
|
|
if ( event == "UNIT_SPELLCAST_SUCCEEDED" ) then
|
|
entry.value = nil;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function ExecuteCastRandom(actions)
|
|
if ( not CastRandomManager ) then
|
|
CastRandomManager = CreateFrame("Frame");
|
|
CastRandomManager:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
|
|
CastRandomManager:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
|
|
CastRandomManager:RegisterEvent("UNIT_SPELLCAST_FAILED");
|
|
CastRandomManager:RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET");
|
|
CastRandomManager:SetScript("OnEvent", CastRandomManager_OnEvent);
|
|
end
|
|
|
|
local entry = CastRandomTable[actions];
|
|
if ( not entry ) then
|
|
entry = {};
|
|
CreateCanonicalActions(entry, strsplit(",", actions));
|
|
CastRandomTable[actions] = entry;
|
|
end
|
|
if ( not entry.value ) then
|
|
entry.value = strtrim(GetRandomArgument(strsplit(",", actions)));
|
|
end
|
|
entry.pending = true;
|
|
return entry.value;
|
|
end
|
|
|
|
function GetRandomArgument(...)
|
|
return (select(random(select("#", ...)), ...));
|
|
end
|
|
|
|
-- Slash commands that are protected from tampering
|
|
local SecureCmdList = { };
|
|
|
|
function IsSecureCmd(command)
|
|
command = strupper(command);
|
|
-- first check the hash table
|
|
if ( hash_SecureCmdList[command] ) then
|
|
return true;
|
|
end
|
|
|
|
for index, value in pairs(SecureCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
if ( cmdString == command ) then
|
|
return true;
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
end
|
|
|
|
function SecureCmdItemParse(item)
|
|
if ( not item ) then
|
|
return nil, nil, nil;
|
|
end
|
|
local bag, slot = strmatch(item, "^(%d+)%s+(%d+)$");
|
|
if ( not bag ) then
|
|
slot = strmatch(item, "^(%d+)$");
|
|
end
|
|
if ( bag ) then
|
|
item = GetContainerItemLink(bag, slot);
|
|
elseif ( slot ) then
|
|
item = GetInventoryItemLink("player", slot);
|
|
end
|
|
return item, bag, slot;
|
|
end
|
|
|
|
function SecureCmdUseItem(name, bag, slot, target)
|
|
if ( bag ) then
|
|
UseContainerItem(bag, slot, target);
|
|
elseif ( slot ) then
|
|
UseInventoryItem(slot, target);
|
|
else
|
|
UseItemByName(name, target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["STARTATTACK"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target or target == "target" ) then
|
|
target = action;
|
|
end
|
|
StartAttack(target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["STOPATTACK"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
StopAttack();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CAST"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
local name, bag, slot = SecureCmdItemParse(action);
|
|
if ( slot or GetItemInfo(name) ) then
|
|
SecureCmdUseItem(name, bag, slot, target);
|
|
else
|
|
CastSpellByName(action, target);
|
|
end
|
|
end
|
|
end
|
|
SecureCmdList["USE"] = SecureCmdList["CAST"];
|
|
|
|
SecureCmdList["CASTRANDOM"] = function(msg)
|
|
local actions, target = SecureCmdOptionParse(msg);
|
|
if ( actions ) then
|
|
local action = ExecuteCastRandom(actions);
|
|
local name, bag, slot = SecureCmdItemParse(action);
|
|
if ( slot or GetItemInfo(name) ) then
|
|
SecureCmdUseItem(name, bag, slot, target);
|
|
else
|
|
CastSpellByName(action, target);
|
|
end
|
|
end
|
|
end
|
|
SecureCmdList["USERANDOM"] = SecureCmdList["CASTRANDOM"];
|
|
|
|
SecureCmdList["CASTSEQUENCE"] = function(msg)
|
|
local sequence, target = SecureCmdOptionParse(msg);
|
|
if ( sequence ) then
|
|
ExecuteCastSequence(sequence, target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["STOPCASTING"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
SpellStopCasting();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CANCELAURA"] = function(msg)
|
|
local spell = SecureCmdOptionParse(msg);
|
|
if ( spell ) then
|
|
local name, rank = strmatch(spell, "([^(]+)[(]([^)]+)[)]");
|
|
if ( not name ) then
|
|
name = spell;
|
|
end
|
|
CancelUnitBuff("player", name, rank);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CANCELFORM"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
CancelShapeshiftForm();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["EQUIP"] = function(msg)
|
|
local item = SecureCmdOptionParse(msg);
|
|
if ( item ) then
|
|
EquipItemByName((SecureCmdItemParse(item)));
|
|
end
|
|
end
|
|
|
|
SecureCmdList["EQUIP_TO_SLOT"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
local slot, item = strmatch(action, "^(%d+)%s+(.*)");
|
|
if ( item ) then
|
|
if ( PaperDoll_IsEquippedSlot(slot) ) then
|
|
EquipItemByName(SecureCmdItemParse(item), slot);
|
|
else
|
|
-- user specified a bad slot number (slot that you can't equip an item to)
|
|
ChatFrame_DisplayUsageError(format(ERROR_SLASH_EQUIP_TO_SLOT, EQUIPPED_FIRST, EQUIPPED_LAST));
|
|
end
|
|
elseif ( slot ) then
|
|
-- user specified a slot but not an item
|
|
ChatFrame_DisplayUsageError(format(ERROR_SLASH_EQUIP_TO_SLOT, EQUIPPED_FIRST, EQUIPPED_LAST));
|
|
end
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CHANGEACTIONBAR"] = function(msg)
|
|
local page = SecureCmdOptionParse(msg);
|
|
if ( page and page ~= "" ) then
|
|
page = tonumber(page);
|
|
if (page and page >= 1 and page <= NUM_ACTIONBAR_PAGES) then
|
|
ChangeActionBarPage(page);
|
|
else
|
|
ChatFrame_DisplayUsageError(format(ERROR_SLASH_CHANGEACTIONBAR, 1, NUM_ACTIONBAR_PAGES));
|
|
end
|
|
end
|
|
end
|
|
|
|
SecureCmdList["SWAPACTIONBAR"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
local a, b = strmatch(action, "(%d+)%s+(%d+)");
|
|
if ( a and b ) then
|
|
a = tonumber(a);
|
|
b = tonumber(b);
|
|
if ( ( a and a >= 1 and a <= NUM_ACTIONBAR_PAGES ) and ( b and b >= 1 and b <= NUM_ACTIONBAR_PAGES ) ) then
|
|
if ( GetActionBarPage() == a ) then
|
|
ChangeActionBarPage(b);
|
|
else
|
|
ChangeActionBarPage(a);
|
|
end
|
|
else
|
|
ChatFrame_DisplayUsageError(format(ERROR_SLASH_SWAPACTIONBAR, 1, NUM_ACTIONBAR_PAGES));
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target or target == "target" ) then
|
|
target = action;
|
|
end
|
|
TargetUnit(target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_EXACT"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target or target == "target" ) then
|
|
target = action;
|
|
end
|
|
TargetUnit(target, 1);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_ENEMY"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestEnemy(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_ENEMY_PLAYER"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestEnemyPlayer(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_FRIEND"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestFriend(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_FRIEND_PLAYER"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestFriendPlayer(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_PARTY"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestPartyMember(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_NEAREST_RAID"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetNearestRaidMember(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CLEARTARGET"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
ClearTarget();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_LAST_TARGET"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
TargetLastTarget();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_LAST_ENEMY"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetLastEnemy(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["TARGET_LAST_FRIEND"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
TargetLastFriend(action);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["ASSIST"] = function(msg)
|
|
if ( msg == "" ) then
|
|
AssistUnit();
|
|
else
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target ) then
|
|
target = action;
|
|
end
|
|
AssistUnit(target);
|
|
end
|
|
end
|
|
end
|
|
|
|
SecureCmdList["FOCUS"] = function(msg)
|
|
if ( msg == "" ) then
|
|
FocusUnit();
|
|
else
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target or target == "focus" ) then
|
|
target = action;
|
|
end
|
|
FocusUnit(target);
|
|
end
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CLEARFOCUS"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
ClearFocus();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CLEARMAINTANK"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
ClearPartyAssignment("MAINTANK");
|
|
end
|
|
end
|
|
|
|
SecureCmdList["MAINTANKON"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target ) then
|
|
target = action;
|
|
end
|
|
if ( target == "" ) then
|
|
target = "target";
|
|
end
|
|
SetPartyAssignment("MAINTANK", target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["MAINTANKOFF"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target ) then
|
|
target = action;
|
|
end
|
|
if ( target == "" ) then
|
|
target = "target";
|
|
end
|
|
ClearPartyAssignment("MAINTANK", target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CLEARMAINASSIST"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
ClearPartyAssignment("MAINASSIST");
|
|
end
|
|
end
|
|
|
|
SecureCmdList["MAINASSISTON"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target ) then
|
|
target = action;
|
|
end
|
|
if ( target == "" ) then
|
|
target = "target";
|
|
end
|
|
SetPartyAssignment("MAINASSIST", target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["MAINASSISTOFF"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target ) then
|
|
target = action;
|
|
end
|
|
if ( target == "" ) then
|
|
target = "target";
|
|
end
|
|
ClearPartyAssignment("MAINASSIST", target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["DUEL"] = function(msg)
|
|
StartDuel(msg)
|
|
end
|
|
|
|
SecureCmdList["DUEL_CANCEL"] = function(msg)
|
|
CancelDuel()
|
|
end
|
|
|
|
SecureCmdList["PET_ATTACK"] = function(msg)
|
|
local action, target = SecureCmdOptionParse(msg);
|
|
if ( action ) then
|
|
if ( not target or target == "pettarget" ) then
|
|
target = action;
|
|
end
|
|
PetAttack(target);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_FOLLOW"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
PetFollow();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_STAY"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
PetWait();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_PASSIVE"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
PetPassiveMode();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_DEFENSIVE"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
PetDefensiveMode();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_AGGRESSIVE"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
PetAggressiveMode();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_AUTOCASTON"] = function(msg)
|
|
local spell = SecureCmdOptionParse(msg);
|
|
if ( spell ) then
|
|
EnableSpellAutocast(spell);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_AUTOCASTOFF"] = function(msg)
|
|
local spell = SecureCmdOptionParse(msg);
|
|
if ( spell ) then
|
|
DisableSpellAutocast(spell);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["PET_AUTOCASTTOGGLE"] = function(msg)
|
|
local spell = SecureCmdOptionParse(msg);
|
|
if ( spell ) then
|
|
ToggleSpellAutocast(spell);
|
|
end
|
|
end
|
|
|
|
SecureCmdList["STOPMACRO"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
StopMacro();
|
|
end
|
|
end
|
|
|
|
SecureCmdList["CLICK"] = function(msg)
|
|
local action = SecureCmdOptionParse(msg);
|
|
if ( action and action ~= "" ) then
|
|
local name, mouseButton, down = strmatch(action, "([^%s]+)%s+([^%s]+)%s*(.*)");
|
|
if ( not name ) then
|
|
name = action;
|
|
end
|
|
local button = GetClickFrame(name);
|
|
if ( button and button:IsObjectType("Button") ) then
|
|
button:Click(mouseButton, down);
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Pre-populate the secure command hash table
|
|
for index, value in pairs(SecureCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
hash_SecureCmdList[cmdString] = value; -- add to hash
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
|
|
-- Slash commands
|
|
SlashCmdList = { };
|
|
|
|
SlashCmdList["CONSOLE"] = function(msg)
|
|
ConsoleExec(msg);
|
|
end
|
|
|
|
SlashCmdList["CHATLOG"] = function(msg)
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
if ( LoggingChat() ) then
|
|
LoggingChat(false);
|
|
DEFAULT_CHAT_FRAME:AddMessage(CHATLOGDISABLED, info.r, info.g, info.b, info.id);
|
|
else
|
|
LoggingChat(true);
|
|
DEFAULT_CHAT_FRAME:AddMessage(CHATLOGENABLED, info.r, info.g, info.b, info.id);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["COMBATLOG"] = function(msg)
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
if ( LoggingCombat() ) then
|
|
LoggingCombat(false);
|
|
DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGDISABLED, info.r, info.g, info.b, info.id);
|
|
else
|
|
LoggingCombat(true);
|
|
DEFAULT_CHAT_FRAME:AddMessage(COMBATLOGENABLED, info.r, info.g, info.b, info.id);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["INVITE"] = function(msg)
|
|
if(msg == "") then
|
|
msg = UnitName("target");
|
|
end
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
InviteUnit(msg);
|
|
end
|
|
|
|
SlashCmdList["UNINVITE"] = function(msg)
|
|
if(msg == "") then
|
|
msg = UnitName("target");
|
|
end
|
|
UninviteUnit(msg);
|
|
end
|
|
|
|
SlashCmdList["PROMOTE"] = function(msg)
|
|
PromoteToLeader(msg);
|
|
end
|
|
|
|
SlashCmdList["REPLY"] = function(msg, editBox)
|
|
local lastTell = ChatEdit_GetLastTellTarget();
|
|
if ( lastTell ~= "" ) then
|
|
SendChatMessage(msg, "WHISPER", editBox.language, lastTell);
|
|
else
|
|
-- error message
|
|
end
|
|
end
|
|
|
|
SlashCmdList["HELP"] = function(msg)
|
|
ChatFrame_DisplayHelpText(DEFAULT_CHAT_FRAME);
|
|
end
|
|
|
|
SlashCmdList["MACROHELP"] = function(msg)
|
|
ChatFrame_DisplayMacroHelpText(DEFAULT_CHAT_FRAME);
|
|
end
|
|
|
|
SlashCmdList["TIME"] = function(msg)
|
|
ChatFrame_DisplayGameTime(DEFAULT_CHAT_FRAME);
|
|
end
|
|
|
|
SlashCmdList["PLAYED"] = function(msg)
|
|
RequestTimePlayed();
|
|
end
|
|
|
|
SlashCmdList["FOLLOW"] = function(msg)
|
|
FollowUnit(msg);
|
|
end
|
|
|
|
SlashCmdList["TRADE"] = function(msg)
|
|
InitiateTrade("target");
|
|
end
|
|
|
|
SlashCmdList["INSPECT"] = function(msg)
|
|
InspectUnit("target");
|
|
end
|
|
|
|
SlashCmdList["LOGOUT"] = function(msg)
|
|
Logout();
|
|
end
|
|
|
|
SlashCmdList["QUIT"] = function(msg)
|
|
Quit();
|
|
end
|
|
|
|
SlashCmdList["JOIN"] = function(msg)
|
|
local name = gsub(msg, "%s*([^%s]+).*", "%1");
|
|
local password = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
|
|
if(strlen(name) <= 0) then
|
|
local joinhelp = CHAT_JOIN_HELP;
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
DEFAULT_CHAT_FRAME:AddMessage(joinhelp, info.r, info.g, info.b, info.id);
|
|
else
|
|
local zoneChannel, channelName = JoinPermanentChannel(name, password, DEFAULT_CHAT_FRAME:GetID(), 1);
|
|
if ( channelName ) then
|
|
name = channelName;
|
|
end
|
|
if ( not zoneChannel ) then
|
|
local info = ChatTypeInfo["CHANNEL"];
|
|
DEFAULT_CHAT_FRAME:AddMessage(CHAT_INVALID_NAME_NOTICE, info.r, info.g, info.b, info.id);
|
|
return;
|
|
end
|
|
|
|
local i = 1;
|
|
while ( DEFAULT_CHAT_FRAME.channelList[i] ) do
|
|
i = i + 1;
|
|
end
|
|
DEFAULT_CHAT_FRAME.channelList[i] = name;
|
|
DEFAULT_CHAT_FRAME.zoneChannelList[i] = zoneChannel;
|
|
end
|
|
end
|
|
|
|
SlashCmdList["LEAVE"] = function(msg)
|
|
local name = strmatch(msg, "%s*([^%s]+)");
|
|
if ( name ) then
|
|
local nameNum = tonumber(name);
|
|
if ( nameNum and nameNum > MAX_WOW_CHAT_CHANNELS ) then
|
|
BNLeaveConversation(nameNum - MAX_WOW_CHAT_CHANNELS);
|
|
else
|
|
LeaveChannelByName(name);
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
SlashCmdList["LIST_CHANNEL"] = function(msg)
|
|
local name = strmatch(msg, "%s*([^%s]+)");
|
|
if ( name ) then
|
|
local nameNum = tonumber(name);
|
|
if ( nameNum and nameNum > MAX_WOW_CHAT_CHANNELS ) then
|
|
BNListConversation(nameNum - MAX_WOW_CHAT_CHANNELS);
|
|
else
|
|
ListChannelByName(name);
|
|
end
|
|
else
|
|
ListChannels();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_HELP"] =
|
|
function(msg)
|
|
ChatFrame_DisplayChatHelp(DEFAULT_CHAT_FRAME)
|
|
end
|
|
|
|
SlashCmdList["CHAT_PASSWORD"] =
|
|
function(msg)
|
|
local name = gsub(msg, "%s*([^%s]+).*", "%1");
|
|
local password = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
|
|
SetChannelPassword(name, password);
|
|
end
|
|
|
|
SlashCmdList["CHAT_OWNER"] =
|
|
function(msg)
|
|
local channel = gsub(msg, "%s*([^%s]+).*", "%1");
|
|
local newOwner = gsub(msg, "%s*([^%s]+)%s*(.*)", "%2");
|
|
if ( not channel or not newOwner ) then
|
|
return;
|
|
end
|
|
local newOwnerLen = strlen(newOwner);
|
|
if ( newOwnerLen > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( strlen(channel) > 0 ) then
|
|
if ( newOwnerLen > 0 ) then
|
|
SetChannelOwner(channel, newOwner);
|
|
else
|
|
DisplayChannelOwner(channel);
|
|
end
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_MODERATOR"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
ChannelModerator(channel, player);
|
|
end
|
|
|
|
SlashCmdList["CHAT_UNMODERATOR"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelUnmoderator(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_MUTE"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelMute(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_UNMUTE"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelUnmute(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_CINVITE"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
|
|
if ( channel and player ) then
|
|
if ( tonumber(channel) and tonumber(channel) > MAX_WOW_CHAT_CHANNELS ) then
|
|
--We have a BNet conversation.
|
|
channel = tonumber(channel) - MAX_WOW_CHAT_CHANNELS;
|
|
if ( BNGetConversationInfo(channel) ) then
|
|
local presenceID = BNet_GetPresenceID(player);
|
|
if ( presenceID ) then
|
|
BNInviteToConversation(channel, presenceID);
|
|
end
|
|
end
|
|
else
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
ChannelInvite(channel, player);
|
|
end
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_KICK"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelKick(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_BAN"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelBan(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_UNBAN"] =
|
|
function(msg)
|
|
local channel, player = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( not channel or not player ) then
|
|
return;
|
|
end
|
|
if ( strlen(player) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
if ( channel and player ) then
|
|
ChannelUnban(channel, player);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CHAT_ANNOUNCE"] =
|
|
function(msg)
|
|
local channel = strmatch(msg, "%s*([^%s]+)");
|
|
if ( channel ) then
|
|
ChannelToggleAnnouncements(channel);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["TEAM_INVITE"] = function(msg)
|
|
if ( msg ~= "" ) then
|
|
local team, name = strmatch(msg, "^(%d+)[%w+%d+]*%s+(.*)");
|
|
if ( team and name ) then
|
|
if ( strlen(name) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
team = tonumber(team);
|
|
if ( team ) then
|
|
local teamsizeID = ArenaTeam_GetTeamSizeID(team);
|
|
if ( teamsizeID ) then
|
|
ArenaTeamInviteByName(teamsizeID, name);
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
ChatFrame_DisplayUsageError(ERROR_SLASH_TEAM_INVITE);
|
|
end
|
|
|
|
SlashCmdList["TEAM_QUIT"] = function(msg)
|
|
if ( msg ~= "" ) then
|
|
local team = strmatch(msg, "^(%d+)[%w+%d+]*");
|
|
if ( team ) then
|
|
team = tonumber(team);
|
|
if ( team ) then
|
|
local teamsizeID = ArenaTeam_GetTeamSizeID(team);
|
|
if ( teamsizeID ) then
|
|
ArenaTeamLeave(teamsizeID);
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
ChatFrame_DisplayUsageError(ERROR_SLASH_TEAM_QUIT);
|
|
end
|
|
|
|
SlashCmdList["TEAM_UNINVITE"] = function(msg)
|
|
if ( msg ~= "" ) then
|
|
local team, name = strmatch(msg, "^(%d+)[%w+%d+]*%s+(.*)");
|
|
if ( team and name ) then
|
|
if ( strlen(name) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
team = tonumber(team);
|
|
if ( team ) then
|
|
local teamsizeID = ArenaTeam_GetTeamSizeID(team);
|
|
if ( teamsizeID ) then
|
|
ArenaTeamUninviteByName(teamsizeID, name);
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
ChatFrame_DisplayUsageError(ERROR_SLASH_TEAM_UNINVITE);
|
|
end
|
|
|
|
SlashCmdList["TEAM_CAPTAIN"] = function(msg)
|
|
if ( msg ~= "" ) then
|
|
local team, name = strmatch(msg, "^(%d+)[%w+%d+]*%s+(.*)");
|
|
if ( team and name ) then
|
|
if ( strlen(name) > MAX_CHARACTER_NAME_BYTES ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
team = tonumber(team);
|
|
if ( team ) then
|
|
local teamsizeID = ArenaTeam_GetTeamSizeID(team);
|
|
if ( teamsizeID ) then
|
|
ArenaTeamSetLeaderByName(teamsizeID, name);
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
ChatFrame_DisplayUsageError(ERROR_SLASH_TEAM_CAPTAIN);
|
|
end
|
|
|
|
SlashCmdList["TEAM_DISBAND"] = function(msg)
|
|
if ( msg ~= "" ) then
|
|
local team = strmatch(msg, "^(%d+)[%w+%d+]*");
|
|
if ( team ) then
|
|
team = tonumber(team);
|
|
if ( team ) then
|
|
local teamsizeID = ArenaTeam_GetTeamSizeID(team);
|
|
if ( teamsizeID ) then
|
|
local teamName, teamSize = GetArenaTeam(teamsizeID);
|
|
for i = 1, teamSize * 2 do
|
|
name, rank = GetArenaTeamRosterInfo(teamsizeID, i);
|
|
if ( rank == 0 ) then
|
|
if ( name == UnitName("player") ) then
|
|
local dialog = StaticPopup_Show("CONFIRM_TEAM_DISBAND", teamName);
|
|
if ( dialog ) then
|
|
dialog.data = teamsizeID;
|
|
end
|
|
end
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
ChatFrame_DisplayUsageError(ERROR_SLASH_TEAM_DISBAND);
|
|
end
|
|
|
|
SlashCmdList["GUILD_INVITE"] = function(msg)
|
|
if(msg == "") then
|
|
msg = UnitName("target");
|
|
end
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
GuildInvite(msg);
|
|
end
|
|
|
|
SlashCmdList["GUILD_UNINVITE"] = function(msg)
|
|
if(msg == "") then
|
|
msg = UnitName("target");
|
|
end
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
GuildUninvite(msg);
|
|
end
|
|
|
|
SlashCmdList["GUILD_PROMOTE"] = function(msg)
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
GuildPromote(msg);
|
|
end
|
|
|
|
SlashCmdList["GUILD_DEMOTE"] = function(msg)
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
GuildDemote(msg);
|
|
end
|
|
|
|
SlashCmdList["GUILD_LEADER"] = function(msg)
|
|
if( msg and (strlen(msg) > MAX_CHARACTER_NAME_BYTES) ) then
|
|
ChatFrame_DisplayUsageError(ERR_NAME_TOO_LONG2);
|
|
return;
|
|
end
|
|
GuildSetLeader(msg);
|
|
end
|
|
|
|
SlashCmdList["GUILD_MOTD"] = function(msg)
|
|
GuildSetMOTD(msg)
|
|
end
|
|
|
|
SlashCmdList["GUILD_LEAVE"] = function(msg)
|
|
GuildLeave();
|
|
end
|
|
|
|
SlashCmdList["GUILD_DISBAND"] = function(msg)
|
|
if ( IsGuildLeader() ) then
|
|
StaticPopup_Show("CONFIRM_GUILD_DISBAND");
|
|
end
|
|
end
|
|
|
|
SlashCmdList["GUILD_INFO"] = function(msg)
|
|
GuildInfo();
|
|
end
|
|
|
|
SlashCmdList["GUILD_ROSTER"] = function(msg)
|
|
if ( IsInGuild() ) then
|
|
PanelTemplates_SetTab(FriendsFrame, 3);
|
|
FriendsFrame_ShowSubFrame("GuildFrame");
|
|
ShowUIPanel(FriendsFrame);
|
|
end
|
|
end
|
|
|
|
--SlashCmdList["GUILD_HELP"] = function(msg)
|
|
-- ChatFrame_DisplayGuildHelp(DEFAULT_CHAT_FRAME);
|
|
--end
|
|
|
|
SlashCmdList["CHAT_AFK"] = function(msg)
|
|
SendChatMessage(msg, "AFK");
|
|
end
|
|
|
|
SlashCmdList["CHAT_DND"] = function(msg)
|
|
SendChatMessage(msg, "DND");
|
|
end
|
|
|
|
SlashCmdList["WHO"] = function(msg)
|
|
if ( msg == "" ) then
|
|
msg = WhoFrame_GetDefaultWhoCommand();
|
|
ShowWhoPanel();
|
|
end
|
|
WhoFrameEditBox:SetText(msg);
|
|
SendWho(msg);
|
|
end
|
|
|
|
SlashCmdList["CHANNEL"] = function(msg, editBox)
|
|
SendChatMessage(msg, "CHANNEL", editBox.language, editBox:GetAttribute("channelTarget"));
|
|
end
|
|
|
|
SlashCmdList["FRIENDS"] = function(msg)
|
|
local player, note = strmatch(msg, "%s*([^%s]+)%s*(.*)");
|
|
if ( player ~= "" or UnitIsPlayer("target") ) then
|
|
AddOrRemoveFriend(player, note);
|
|
else
|
|
ToggleFriendsPanel();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["REMOVEFRIEND"] = function(msg)
|
|
RemoveFriend(msg);
|
|
end
|
|
|
|
SlashCmdList["IGNORE"] = function(msg)
|
|
if ( msg ~= "" or UnitIsPlayer("target") ) then
|
|
local presenceID = BNet_GetPresenceID(msg);
|
|
if ( presenceID ) then
|
|
if ( BNIsFriend(presenceID) ) then
|
|
SendSystemMessage(ERR_CANNOT_IGNORE_BN_FRIEND);
|
|
else
|
|
BNSetToonBlocked(presenceID, not BNIsToonBlocked(presenceID));
|
|
end
|
|
else
|
|
AddOrDelIgnore(msg);
|
|
end
|
|
else
|
|
ToggleIgnorePanel();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["UNIGNORE"] = function(msg)
|
|
if ( msg ~= "" or UnitIsPlayer("target") ) then
|
|
DelIgnore(msg);
|
|
else
|
|
ToggleIgnorePanel();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["SCRIPT"] = function(msg)
|
|
RunScript(msg);
|
|
end
|
|
|
|
SlashCmdList["LOOT_FFA"] = function(msg)
|
|
SetLootMethod("freeforall");
|
|
end
|
|
|
|
SlashCmdList["LOOT_ROUNDROBIN"] = function(msg)
|
|
SetLootMethod("roundrobin");
|
|
end
|
|
|
|
SlashCmdList["LOOT_MASTER"] = function(msg)
|
|
SetLootMethod("master", msg);
|
|
end
|
|
|
|
SlashCmdList["LOOT_GROUP"] = function(msg)
|
|
SetLootMethod("group");
|
|
end
|
|
|
|
SlashCmdList["LOOT_NEEDBEFOREGREED"] = function(msg)
|
|
SetLootMethod("needbeforegreed");
|
|
end
|
|
|
|
SlashCmdList["LOOT_SETTHRESHOLD"] = function(msg)
|
|
if ( not msg ) then
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
DEFAULT_CHAT_FRAME:AddMessage(format(ERROR_SLASH_LOOT_SETTHRESHOLD, MIN_LOOT_THRESHOLD, MAX_LOOT_THRESHOLD), info.r, info.g, info.b, info.id);
|
|
return;
|
|
end
|
|
|
|
local MIN_LOOT_THRESHOLD = 2; -- "good" item quality
|
|
local MAX_LOOT_THRESHOLD = 6; -- "artifact" item quality
|
|
|
|
local threshold = strmatch(msg, "(%d+)");
|
|
threshold = tonumber(threshold);
|
|
if ( threshold and threshold >= MIN_LOOT_THRESHOLD and threshold <= MAX_LOOT_THRESHOLD ) then
|
|
-- try to match a threshold number first
|
|
SetLootThreshold(threshold);
|
|
else
|
|
msg = strupper(msg);
|
|
if ( msg == strupper(ITEM_QUALITY2_DESC) ) then
|
|
SetLootThreshold(2);
|
|
elseif ( msg == strupper(ITEM_QUALITY3_DESC) ) then
|
|
SetLootThreshold(3);
|
|
elseif ( msg == strupper(ITEM_QUALITY4_DESC) ) then
|
|
SetLootThreshold(4);
|
|
elseif ( msg == strupper(ITEM_QUALITY5_DESC) ) then
|
|
SetLootThreshold(5);
|
|
elseif ( msg == strupper(ITEM_QUALITY6_DESC) ) then
|
|
SetLootThreshold(6);
|
|
else
|
|
-- no matches found
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
DEFAULT_CHAT_FRAME:AddMessage(format(ERROR_SLASH_LOOT_SETTHRESHOLD, MIN_LOOT_THRESHOLD, MAX_LOOT_THRESHOLD), info.r, info.g, info.b, info.id);
|
|
end
|
|
end
|
|
end
|
|
|
|
SlashCmdList["RANDOM"] = function(msg)
|
|
local num1 = gsub(msg, "(%s*)(%d+)(.*)", "%2", 1);
|
|
local rest = gsub(msg, "(%s*)(%d+)(.*)", "%3", 1);
|
|
local num2 = "";
|
|
local numSubs;
|
|
if ( strlen(rest) > 0 ) then
|
|
num2, numSubs = gsub(msg, "(%s*)(%d+)([-%s]+)(%d+)(.*)", "%4", 1);
|
|
if ( numSubs == 0 ) then
|
|
num2 = "";
|
|
end
|
|
end
|
|
if ( num1 == "" and num2 == "" ) then
|
|
RandomRoll("1", "100");
|
|
elseif ( num2 == "" ) then
|
|
RandomRoll("1", num1);
|
|
else
|
|
RandomRoll(num1, num2);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["MACRO"] = function(msg)
|
|
ShowMacroFrame();
|
|
end
|
|
|
|
SlashCmdList["PVP"] = function(msg)
|
|
TogglePVP();
|
|
end
|
|
|
|
SlashCmdList["RAID_INFO"] = function(msg)
|
|
RaidFrame.slashCommand = 1;
|
|
if ( ( GetNumSavedInstances() > 0 ) and not RaidInfoFrame:IsShown() ) then
|
|
ToggleFriendsFrame(5);
|
|
RaidInfoFrame:Show();
|
|
elseif ( not RaidFrame:IsShown() ) then
|
|
ToggleFriendsFrame(5);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["READYCHECK"] = function(msg)
|
|
if ( ((IsRaidLeader() or IsRaidOfficer()) and GetNumRaidMembers() > 0) or (IsPartyLeader() and GetNumPartyMembers() > 0) ) then
|
|
DoReadyCheck();
|
|
end
|
|
end
|
|
|
|
--[[All of this information is obtainable through the armory now.
|
|
SlashCmdList["SAVEGUILDROSTER"] = function(msg)
|
|
SaveGuildRoster();
|
|
end]]
|
|
|
|
SlashCmdList["DUNGEONS"] = function(msg)
|
|
ToggleLFDParentFrame();
|
|
end
|
|
|
|
SlashCmdList["RAIDBROWSER"] = function(msg)
|
|
ToggleLFRParentFrame();
|
|
end
|
|
|
|
SlashCmdList["BENCHMARK"] = function(msg)
|
|
SetTaxiBenchmarkMode(msg);
|
|
end
|
|
|
|
SlashCmdList["DISMOUNT"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
Dismount();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["LEAVEVEHICLE"] = function(msg)
|
|
if ( SecureCmdOptionParse(msg) ) then
|
|
VehicleExit();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["RESETCHAT"] = function(msg)
|
|
FCF_ResetAllWindows();
|
|
end
|
|
|
|
SlashCmdList["ENABLE_ADDONS"] = function(msg)
|
|
EnableAllAddOns();
|
|
ReloadUI();
|
|
end
|
|
|
|
SlashCmdList["DISABLE_ADDONS"] = function(msg)
|
|
DisableAllAddOns();
|
|
ReloadUI();
|
|
end
|
|
|
|
SlashCmdList["STOPWATCH"] = function(msg)
|
|
if ( not IsAddOnLoaded("Blizzard_TimeManager") ) then
|
|
UIParentLoadAddOn("Blizzard_TimeManager");
|
|
end
|
|
if ( StopwatchFrame ) then
|
|
local text = strmatch(msg, "%s*([^%s]+)%s*");
|
|
if ( text ) then
|
|
text = strlower(text);
|
|
|
|
-- in any of the following cases, the stopwatch will be shown
|
|
StopwatchFrame:Show();
|
|
|
|
-- try to match a command
|
|
local function MatchCommand(param, text)
|
|
local i, compare;
|
|
i = 1;
|
|
repeat
|
|
compare = _G[param..i];
|
|
if ( compare and compare == text ) then
|
|
return true;
|
|
end
|
|
i = i + 1;
|
|
until ( not compare );
|
|
return false;
|
|
end
|
|
if ( MatchCommand("SLASH_STOPWATCH_PARAM_PLAY", text) ) then
|
|
Stopwatch_Play();
|
|
return;
|
|
end
|
|
if ( MatchCommand("SLASH_STOPWATCH_PARAM_PAUSE", text) ) then
|
|
Stopwatch_Pause();
|
|
return;
|
|
end
|
|
if ( MatchCommand("SLASH_STOPWATCH_PARAM_STOP", text) ) then
|
|
Stopwatch_Clear();
|
|
return;
|
|
end
|
|
-- try to match a countdown
|
|
-- kinda ghetto, but hey, it's simple and it works =)
|
|
local hour, minute, second = strmatch(msg, "(%d+):(%d+):(%d+)");
|
|
if ( not hour ) then
|
|
minute, second = strmatch(msg, "(%d+):(%d+)");
|
|
if ( not minute ) then
|
|
second = strmatch(msg, "(%d+)");
|
|
end
|
|
end
|
|
Stopwatch_StartCountdown(tonumber(hour), tonumber(minute), tonumber(second));
|
|
else
|
|
Stopwatch_Toggle();
|
|
end
|
|
end
|
|
end
|
|
|
|
SlashCmdList["CALENDAR"] = function(msg)
|
|
if ( not IsAddOnLoaded("Blizzard_Calendar") ) then
|
|
UIParentLoadAddOn("Blizzard_Calendar");
|
|
end
|
|
if ( Calendar_Toggle ) then
|
|
Calendar_Toggle();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["ACHIEVEMENTUI"] = function(msg)
|
|
ToggleAchievementFrame();
|
|
end
|
|
|
|
SlashCmdList["EQUIP_SET"] = function(msg)
|
|
local set = SecureCmdOptionParse(msg);
|
|
if ( set and set ~= "" ) then
|
|
EquipmentManager_EquipSet(set);
|
|
end
|
|
end
|
|
|
|
SlashCmdList["SET_TITLE"] = function(msg)
|
|
local name = SecureCmdOptionParse(msg);
|
|
if ( name and name ~= "") then
|
|
if(not SetTitleByName(name)) then
|
|
UIErrorsFrame:AddMessage(TITLE_DOESNT_EXIST, 1.0, 0.1, 0.1, 1.0);
|
|
end
|
|
else
|
|
SetCurrentTitle(-1)
|
|
end
|
|
end
|
|
|
|
SlashCmdList["USE_TALENT_SPEC"] = function(msg)
|
|
local group = SecureCmdOptionParse(msg);
|
|
if ( group ) then
|
|
local groupNumber = tonumber(group);
|
|
if ( groupNumber ) then
|
|
SetActiveTalentGroup(groupNumber);
|
|
end
|
|
end
|
|
end
|
|
|
|
-- easier method to turn on/off errors for macros
|
|
SlashCmdList["UI_ERRORS_OFF"] = function(msg)
|
|
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE");
|
|
SetCVar("Sound_EnableSFX", "0");
|
|
end
|
|
|
|
SlashCmdList["UI_ERRORS_ON"] = function(msg)
|
|
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE");
|
|
SetCVar("Sound_EnableSFX", "1");
|
|
end
|
|
|
|
SlashCmdList["FRAMESTACK"] = function(msg)
|
|
UIParentLoadAddOn("Blizzard_DebugTools");
|
|
if(msg == tostring(true)) then
|
|
FrameStackTooltip_Toggle(true);
|
|
else
|
|
FrameStackTooltip_Toggle();
|
|
end
|
|
end
|
|
|
|
SlashCmdList["EVENTTRACE"] = function(msg)
|
|
UIParentLoadAddOn("Blizzard_DebugTools");
|
|
EventTraceFrame_HandleSlashCmd(msg);
|
|
end
|
|
|
|
SlashCmdList["DUMP"] = function(msg)
|
|
UIParentLoadAddOn("Blizzard_DebugTools");
|
|
DevTools_DumpCommand(msg);
|
|
end
|
|
|
|
SlashCmdList["RELOAD"] = function(msg)
|
|
ConsoleExec("reloadui");
|
|
end
|
|
|
|
for index, value in pairs(ChatTypeInfo) do
|
|
value.r = 1.0;
|
|
value.g = 1.0;
|
|
value.b = 1.0;
|
|
value.id = GetChatTypeIndex(index);
|
|
end
|
|
|
|
-- ChatFrame functions
|
|
function ChatFrame_OnLoad(self)
|
|
self.flashTimer = 0;
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD");
|
|
self:RegisterEvent("UPDATE_CHAT_COLOR");
|
|
self:RegisterEvent("UPDATE_CHAT_WINDOWS");
|
|
self:RegisterEvent("CHAT_MSG_CHANNEL");
|
|
self:RegisterEvent("ZONE_UNDER_ATTACK");
|
|
self:RegisterEvent("UPDATE_INSTANCE_INFO");
|
|
self:RegisterEvent("NEW_TITLE_EARNED");
|
|
self:RegisterEvent("OLD_TITLE_LOST");
|
|
self:RegisterEvent("UPDATE_CHAT_COLOR_NAME_BY_CLASS");
|
|
self:RegisterEvent("VARIABLES_LOADED");
|
|
self.tellTimer = GetTime();
|
|
self.channelList = {};
|
|
self.zoneChannelList = {};
|
|
self.messageTypeList = {};
|
|
|
|
self.defaultLanguage = GetDefaultLanguage(); --If PLAYER_ENTERING_WORLD hasn't been called yet, this is nil, but it'll be fixed whent he event is fired.
|
|
end
|
|
|
|
function ChatFrame_RegisterForMessages(self, ...)
|
|
local messageGroup;
|
|
local index = 1;
|
|
for i=1, select("#", ...) do
|
|
messageGroup = ChatTypeGroup[select(i, ...)];
|
|
if ( messageGroup ) then
|
|
self.messageTypeList[index] = select(i, ...);
|
|
for index, value in pairs(messageGroup) do
|
|
self:RegisterEvent(value);
|
|
end
|
|
index = index + 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RegisterForChannels(self, ...)
|
|
local index = 1;
|
|
for i=1, select("#", ...), 2 do
|
|
self.channelList[index], self.zoneChannelList[index] = select(i, ...);
|
|
index = index + 1;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_AddMessageGroup(chatFrame, group)
|
|
local info = ChatTypeGroup[group];
|
|
if ( info ) then
|
|
local i = 1;
|
|
while ( chatFrame.messageTypeList[i] ) do
|
|
i = i + 1;
|
|
end
|
|
chatFrame.messageTypeList[i] = group;
|
|
for index, value in pairs(info) do
|
|
chatFrame:RegisterEvent(value);
|
|
end
|
|
AddChatWindowMessages(chatFrame:GetID(), group);
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveMessageGroup(chatFrame, group)
|
|
local info = ChatTypeGroup[group];
|
|
if ( info ) then
|
|
for index, value in pairs(chatFrame.messageTypeList) do
|
|
if ( strupper(value) == strupper(group) ) then
|
|
chatFrame.messageTypeList[index] = nil;
|
|
end
|
|
end
|
|
for index, value in pairs(info) do
|
|
chatFrame:UnregisterEvent(value);
|
|
end
|
|
RemoveChatWindowMessages(chatFrame:GetID(), group);
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveAllMessageGroups(chatFrame)
|
|
for index, value in pairs(chatFrame.messageTypeList) do
|
|
for eventIndex, eventValue in pairs(ChatTypeGroup[value]) do
|
|
chatFrame:UnregisterEvent(eventValue);
|
|
end
|
|
RemoveChatWindowMessages(chatFrame:GetID(), value);
|
|
end
|
|
|
|
chatFrame.messageTypeList = {};
|
|
end
|
|
|
|
function ChatFrame_AddChannel(chatFrame, channel)
|
|
local zoneChannel = AddChatWindowChannel(chatFrame:GetID(), channel);
|
|
if ( zoneChannel ) then
|
|
local i = 1;
|
|
while ( chatFrame.channelList[i] ) do
|
|
i = i + 1;
|
|
end
|
|
chatFrame.channelList[i] = channel;
|
|
chatFrame.zoneChannelList[i] = zoneChannel;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveChannel(chatFrame, channel)
|
|
for index, value in pairs(chatFrame.channelList) do
|
|
if ( strupper(channel) == strupper(value) ) then
|
|
chatFrame.channelList[index] = nil;
|
|
chatFrame.zoneChannelList[index] = nil;
|
|
end
|
|
end
|
|
RemoveChatWindowChannel(chatFrame:GetID(), channel);
|
|
end
|
|
|
|
function ChatFrame_RemoveAllChannels(chatFrame)
|
|
for index, value in pairs(chatFrame.channelList) do
|
|
RemoveChatWindowChannel(chatFrame:GetID(), value);
|
|
end
|
|
chatFrame.channelList = {};
|
|
chatFrame.zoneChannelList = {};
|
|
end
|
|
|
|
function ChatFrame_AddPrivateMessageTarget(chatFrame, chatTarget)
|
|
ChatFrame_RemoveExcludePrivateMessageTarget(chatFrame, chatTarget);
|
|
if ( chatFrame.privateMessageList ) then
|
|
chatFrame.privateMessageList[strlower(chatTarget)] = true;
|
|
else
|
|
chatFrame.privateMessageList = { [strlower(chatTarget)] = true };
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemovePrivateMessageTarget(chatFrame, chatTarget)
|
|
if ( chatFrame.privateMessageList ) then
|
|
chatFrame.privateMessageList[strlower(chatTarget)] = nil;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ExcludePrivateMessageTarget(chatFrame, chatTarget)
|
|
ChatFrame_RemovePrivateMessageTarget(chatFrame, chatTarget);
|
|
if ( chatFrame.excludePrivateMessageList ) then
|
|
chatFrame.excludePrivateMessageList[strlower(chatTarget)] = true;
|
|
else
|
|
chatFrame.excludePrivateMessageList = { [strlower(chatTarget)] = true };
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveExcludePrivateMessageTarget(chatFrame, chatTarget)
|
|
if ( chatFrame.excludePrivateMessageList ) then
|
|
chatFrame.excludePrivateMessageList[strlower(chatTarget)] = nil;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ReceiveAllPrivateMessages(chatFrame)
|
|
chatFrame.privateMessageList = nil;
|
|
chatFrame.excludePrivateMessageList = nil;
|
|
end
|
|
|
|
function ChatFrame_AddBNConversationTarget(chatFrame, chatTarget)
|
|
ChatFrame_RemoveExcludeBNConversationTarget(chatFrame, chatTarget);
|
|
if ( chatFrame.bnConversationList ) then
|
|
chatFrame.bnConversationList[tonumber(chatTarget)] = true;
|
|
else
|
|
chatFrame.bnConversationList = { [tonumber(chatTarget)] = true };
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveBNConversationTarget(chatFrame, chatTarget)
|
|
if ( chatFrame.bnConversationList ) then
|
|
chatFrame.bnConversationList[tonumber(chatTarget)] = nil;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ExcludeBNConversationTarget(chatFrame, chatTarget)
|
|
ChatFrame_RemoveBNConversationTarget(chatFrame, chatTarget);
|
|
if ( chatFrame.excludeBNConversationList ) then
|
|
chatFrame.excludeBNConversationList[tonumber(chatTarget)] = true;
|
|
else
|
|
chatFrame.excludeBNConversationList = { [tonumber(chatTarget)] = true };
|
|
end
|
|
end
|
|
|
|
function ChatFrame_RemoveExcludeBNConversationTarget(chatFrame, chatTarget)
|
|
if ( chatFrame.excludeBNConversationList ) then
|
|
chatFrame.excludeBNConversationList[tonumber(chatTarget)] = nil;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ReceiveAllBNConversations(chatFrame)
|
|
chatFrame.bnConversationList = nil;
|
|
chatFrame.excludeBNConversationList = nil;
|
|
end
|
|
|
|
-- Set up a private editbox to handle macro execution
|
|
do
|
|
local function GetDefaultChatEditBox(field)
|
|
return DEFAULT_CHAT_FRAME.editBox;
|
|
end
|
|
|
|
local editbox = CreateFrame("Editbox", "MacroEditBox");
|
|
editbox:RegisterEvent("EXECUTE_CHAT_LINE");
|
|
editbox:SetScript("OnEvent",
|
|
function(self,event,line)
|
|
if ( event == "EXECUTE_CHAT_LINE" ) then
|
|
local defaulteditbox = securecall(GetDefaultChatEditBox);
|
|
self:SetAttribute("chatType", defaulteditbox:GetAttribute("chatType"));
|
|
self:SetAttribute("tellTarget", defaulteditbox:GetAttribute("tellTarget"));
|
|
self:SetAttribute("channelTarget", defaulteditbox:GetAttribute("channelTarget"));
|
|
self:SetText(line);
|
|
ChatEdit_SendText(self);
|
|
end
|
|
end
|
|
);
|
|
editbox:Hide();
|
|
end
|
|
|
|
function ChatFrame_OnEvent(self, event, ...)
|
|
if ( ChatFrame_ConfigEventHandler(self, event, ...) ) then
|
|
return;
|
|
end
|
|
if ( ChatFrame_SystemEventHandler(self, event, ...) ) then
|
|
return
|
|
end
|
|
if ( ChatFrame_MessageEventHandler(self, event, ...) ) then
|
|
return
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ConfigEventHandler(self, event, ...)
|
|
if ( event == "PLAYER_ENTERING_WORLD" ) then
|
|
self.defaultLanguage = GetDefaultLanguage();
|
|
return true;
|
|
elseif ( event == "UPDATE_CHAT_WINDOWS" ) then
|
|
local name, fontSize, r, g, b, a, shown, locked = FCF_GetChatWindowInfo(self:GetID());
|
|
if ( fontSize > 0 ) then
|
|
local fontFile, unused, fontFlags = self:GetFont();
|
|
self:SetFont(fontFile, fontSize, fontFlags);
|
|
end
|
|
if ( shown and not self.minimized ) then
|
|
self:Show();
|
|
end
|
|
-- Do more stuff!!!
|
|
ChatFrame_RegisterForMessages(self, GetChatWindowMessages(self:GetID()));
|
|
ChatFrame_RegisterForChannels(self, GetChatWindowChannels(self:GetID()));
|
|
return true;
|
|
end
|
|
|
|
local arg1, arg2, arg3, arg4 = ...;
|
|
if ( event == "UPDATE_CHAT_COLOR" ) then
|
|
local info = ChatTypeInfo[strupper(arg1)];
|
|
if ( info ) then
|
|
info.r = arg2;
|
|
info.g = arg3;
|
|
info.b = arg4;
|
|
self:UpdateColorByID(info.id, info.r, info.g, info.b);
|
|
|
|
if ( strupper(arg1) == "WHISPER" ) then
|
|
info = ChatTypeInfo["REPLY"];
|
|
if ( info ) then
|
|
info.r = arg2;
|
|
info.g = arg3;
|
|
info.b = arg4;
|
|
self:UpdateColorByID(info.id, info.r, info.g, info.b);
|
|
end
|
|
end
|
|
end
|
|
return true;
|
|
elseif ( event == "UPDATE_CHAT_COLOR_NAME_BY_CLASS" ) then
|
|
local info = ChatTypeInfo[strupper(arg1)];
|
|
if ( info ) then
|
|
info.colorNameByClass = arg2;
|
|
if ( strupper(arg1) == "WHISPER" ) then
|
|
info = ChatTypeInfo["REPLY"];
|
|
if ( info ) then
|
|
info.colorNameByClass = arg2;
|
|
end
|
|
end
|
|
end
|
|
return true;
|
|
elseif ( event == "VARIABLES_LOADED" ) then
|
|
if ( GetCVarBool("chatMouseScroll") ) then
|
|
self:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll);
|
|
self:EnableMouseWheel(true);
|
|
end
|
|
self:UnregisterEvent("VARIABLES_LOADED");
|
|
return true;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_SystemEventHandler(self, event, ...)
|
|
if ( event == "TIME_PLAYED_MSG" ) then
|
|
local arg1, arg2 = ...;
|
|
ChatFrame_DisplayTimePlayed(self, arg1, arg2);
|
|
return true;
|
|
elseif ( event == "PLAYER_LEVEL_UP" ) then
|
|
local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 = ...;
|
|
-- Level up
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
|
|
local string = format(LEVEL_UP, arg1);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
|
|
if ( arg3 > 0 ) then
|
|
string = format(LEVEL_UP_HEALTH_MANA, arg2, arg3);
|
|
else
|
|
string = format(LEVEL_UP_HEALTH, arg2);
|
|
end
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
|
|
if ( arg4 > 0 ) then
|
|
string = format(LEVEL_UP_CHAR_POINTS, arg4);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
|
|
if ( arg5 > 0 ) then
|
|
string = format(LEVEL_UP_STAT, SPELL_STAT1_NAME, arg5);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
if ( arg6 > 0 ) then
|
|
string = format(LEVEL_UP_STAT, SPELL_STAT2_NAME, arg6);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
if ( arg7 > 0 ) then
|
|
string = format(LEVEL_UP_STAT, SPELL_STAT3_NAME, arg7);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
if ( arg8 > 0 ) then
|
|
string = format(LEVEL_UP_STAT, SPELL_STAT4_NAME, arg8);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
if ( arg9 > 0 ) then
|
|
string = format(LEVEL_UP_STAT, SPELL_STAT5_NAME, arg9);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
return true;
|
|
elseif ( event == "CHARACTER_POINTS_CHANGED" ) then
|
|
local arg1, arg2 = ...;
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
if ( arg2 > 0 ) then
|
|
local cp1, cp2 = UnitCharacterPoints("player");
|
|
if ( cp2 ) then
|
|
local string = format(LEVEL_UP_SKILL_POINTS, cp2);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
end
|
|
return true;
|
|
elseif ( event == "GUILD_MOTD" ) then
|
|
local arg1 = ...;
|
|
if ( arg1 and (strlen(arg1) > 0) ) then
|
|
local info = ChatTypeInfo["GUILD"];
|
|
local string = format(GUILD_MOTD_TEMPLATE, arg1);
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
return true;
|
|
elseif ( event == "ZONE_UNDER_ATTACK" ) then
|
|
local arg1 = ...;
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
self:AddMessage(format(ZONE_UNDER_ATTACK, arg1), info.r, info.g, info.b, info.id);
|
|
return true;
|
|
elseif ( event == "UPDATE_INSTANCE_INFO" ) then
|
|
if ( RaidFrame.hasRaidInfo ) then
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
if ( RaidFrame.slashCommand and GetNumSavedInstances() == 0 and self == DEFAULT_CHAT_FRAME) then
|
|
self:AddMessage(NO_RAID_INSTANCES_SAVED, info.r, info.g, info.b, info.id);
|
|
RaidFrame.slashCommand = nil;
|
|
end
|
|
end
|
|
return true;
|
|
elseif ( event == "NEW_TITLE_EARNED" ) then
|
|
local arg1 = ...;
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
self:AddMessage(format(NEW_TITLE_EARNED, arg1), info.r, info.g, info.b, info.id);
|
|
return true;
|
|
elseif ( event == "OLD_TITLE_LOST" ) then
|
|
local arg1 = ...;
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
self:AddMessage(format(OLD_TITLE_LOST, arg1), info.r, info.g, info.b, info.id);
|
|
return true;
|
|
end
|
|
end
|
|
|
|
function GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
|
|
local chatType = strsub(event, 10);
|
|
if ( strsub(chatType, 1, 7) == "WHISPER" ) then
|
|
chatType = "WHISPER";
|
|
end
|
|
if ( strsub(chatType, 1, 7) == "CHANNEL" ) then
|
|
chatType = "CHANNEL"..arg8;
|
|
end
|
|
local info = ChatTypeInfo[chatType];
|
|
|
|
if ( info and info.colorNameByClass and arg12 ~= "" ) then
|
|
local localizedClass, englishClass, localizedRace, englishRace, sex = GetPlayerInfoByGUID(arg12)
|
|
|
|
if ( englishClass ) then
|
|
local classColorTable = RAID_CLASS_COLORS[englishClass];
|
|
if ( not classColorTable ) then
|
|
return arg2;
|
|
end
|
|
return string.format("\124cff%.2x%.2x%.2x", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255)..arg2.."\124r"
|
|
end
|
|
end
|
|
|
|
return arg2;
|
|
end
|
|
|
|
function ChatFrame_MessageEventHandler(self, event, ...)
|
|
if ( strsub(event, 1, 8) == "CHAT_MSG" ) then
|
|
local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 = ...;
|
|
local type = strsub(event, 10);
|
|
local info = ChatTypeInfo[type];
|
|
|
|
local filter = false;
|
|
if ( chatFilters[event] ) then
|
|
local newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12;
|
|
for _, filterFunc in next, chatFilters[event] do
|
|
filter, newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12 = filterFunc(self, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
|
if ( filter ) then
|
|
return true;
|
|
elseif ( newarg1 ) then
|
|
arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 = newarg1, newarg2, newarg3, newarg4, newarg5, newarg6, newarg7, newarg8, newarg9, newarg10, newarg11, newarg12;
|
|
end
|
|
end
|
|
end
|
|
|
|
local coloredName = GetColoredName(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
|
|
|
local channelLength = strlen(arg4);
|
|
local infoType = type;
|
|
if ( (strsub(type, 1, 7) == "CHANNEL") and (type ~= "CHANNEL_LIST") and ((arg1 ~= "INVITE") or (type ~= "CHANNEL_NOTICE_USER")) ) then
|
|
if ( arg1 == "WRONG_PASSWORD" ) then
|
|
local staticPopup = _G[StaticPopup_Visible("CHAT_CHANNEL_PASSWORD") or ""];
|
|
if ( staticPopup and strupper(staticPopup.data) == strupper(arg9) ) then
|
|
-- Don't display invalid password messages if we're going to prompt for a password (bug 102312)
|
|
return;
|
|
end
|
|
end
|
|
|
|
local found = 0;
|
|
for index, value in pairs(self.channelList) do
|
|
if ( channelLength > strlen(value) ) then
|
|
-- arg9 is the channel name without the number in front...
|
|
if ( ((arg7 > 0) and (self.zoneChannelList[index] == arg7)) or (strupper(value) == strupper(arg9)) ) then
|
|
found = 1;
|
|
infoType = "CHANNEL"..arg8;
|
|
info = ChatTypeInfo[infoType];
|
|
if ( (type == "CHANNEL_NOTICE") and (arg1 == "YOU_LEFT") ) then
|
|
self.channelList[index] = nil;
|
|
self.zoneChannelList[index] = nil;
|
|
end
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
if ( (found == 0) or not info ) then
|
|
return true;
|
|
end
|
|
end
|
|
|
|
local chatGroup = Chat_GetChatCategory(type);
|
|
local chatTarget;
|
|
if ( chatGroup == "CHANNEL" or chatGroup == "BN_CONVERSATION" ) then
|
|
chatTarget = tostring(arg8);
|
|
elseif ( chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" ) then
|
|
chatTarget = strupper(arg2);
|
|
end
|
|
|
|
if ( FCFManager_ShouldSuppressMessage(self, chatGroup, chatTarget) ) then
|
|
return true;
|
|
end
|
|
|
|
if ( chatGroup == "WHISPER" or chatGroup == "BN_WHISPER" ) then
|
|
if ( self.privateMessageList and not self.privateMessageList[strlower(arg2)] ) then
|
|
return true;
|
|
elseif ( self.excludePrivateMessageList and self.excludePrivateMessageList[strlower(arg2)] ) then
|
|
return true;
|
|
end
|
|
elseif ( chatGroup == "BN_CONVERSATION" ) then
|
|
if ( self.bnConversationList and not self.bnConversationList[arg8] ) then
|
|
return true;
|
|
elseif ( self.excludeBNConversationList and self.excludeBNConversationList[arg8] ) then
|
|
return true;
|
|
end
|
|
end
|
|
|
|
if ( type == "SYSTEM" or type == "SKILL" or type == "LOOT" or type == "MONEY" or
|
|
type == "OPENING" or type == "TRADESKILLS" or type == "PET_INFO" or type == "TARGETICONS") then
|
|
self:AddMessage(arg1, info.r, info.g, info.b, info.id);
|
|
elseif ( strsub(type,1,7) == "COMBAT_" ) then
|
|
self:AddMessage(arg1, info.r, info.g, info.b, info.id);
|
|
elseif ( strsub(type,1,6) == "SPELL_" ) then
|
|
self:AddMessage(arg1, info.r, info.g, info.b, info.id);
|
|
elseif ( strsub(type,1,10) == "BG_SYSTEM_" ) then
|
|
self:AddMessage(arg1, info.r, info.g, info.b, info.id);
|
|
elseif ( strsub(type,1,11) == "ACHIEVEMENT" ) then
|
|
self:AddMessage(format(arg1, "|Hplayer:"..arg2.."|h".."["..coloredName.."]".."|h"), info.r, info.g, info.b, info.id);
|
|
elseif ( strsub(type,1,18) == "GUILD_ACHIEVEMENT" ) then
|
|
self:AddMessage(format(arg1, "|Hplayer:"..arg2.."|h".."["..coloredName.."]".."|h"), info.r, info.g, info.b, info.id);
|
|
elseif ( type == "IGNORED" ) then
|
|
self:AddMessage(format(CHAT_IGNORED, arg2), info.r, info.g, info.b, info.id);
|
|
elseif ( type == "FILTERED" ) then
|
|
self:AddMessage(format(CHAT_FILTERED, arg2), info.r, info.g, info.b, info.id);
|
|
elseif ( type == "RESTRICTED" ) then
|
|
self:AddMessage(CHAT_RESTRICTED, info.r, info.g, info.b, info.id);
|
|
elseif ( type == "CHANNEL_LIST") then
|
|
if(channelLength > 0) then
|
|
self:AddMessage(format(_G["CHAT_"..type.."_GET"]..arg1, tonumber(arg8), arg4), info.r, info.g, info.b, info.id);
|
|
else
|
|
self:AddMessage(arg1, info.r, info.g, info.b, info.id);
|
|
end
|
|
elseif (type == "CHANNEL_NOTICE_USER") then
|
|
local globalstring = _G["CHAT_"..arg1.."_NOTICE_BN"];
|
|
if ( not globalstring ) then
|
|
globalstring = _G["CHAT_"..arg1.."_NOTICE"];
|
|
end
|
|
if(strlen(arg5) > 0) then
|
|
-- TWO users in this notice (E.G. x kicked y)
|
|
self:AddMessage(format(globalstring, arg8, arg4, arg2, arg5), info.r, info.g, info.b, info.id);
|
|
elseif ( arg1 == "INVITE" ) then
|
|
self:AddMessage(format(globalstring, arg4, arg2), info.r, info.g, info.b, info.id);
|
|
else
|
|
self:AddMessage(format(globalstring, arg8, arg4, arg2), info.r, info.g, info.b, info.id);
|
|
end
|
|
elseif (type == "CHANNEL_NOTICE") then
|
|
local globalstring = _G["CHAT_"..arg1.."_NOTICE_BN"];
|
|
if ( not globalstring ) then
|
|
globalstring = _G["CHAT_"..arg1.."_NOTICE"];
|
|
end
|
|
if ( arg10 > 0 ) then
|
|
arg4 = arg4.." "..arg10;
|
|
end
|
|
|
|
local accessID = ChatHistory_GetAccessID(Chat_GetChatCategory(type), arg8);
|
|
local typeID = ChatHistory_GetAccessID(infoType, arg8);
|
|
self:AddMessage(format(globalstring, arg8, arg4), info.r, info.g, info.b, info.id, false, accessID, typeID);
|
|
elseif ( type == "BN_CONVERSATION_NOTICE" ) then
|
|
local channelLink = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8);
|
|
local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), arg8, arg2);
|
|
local message = format(_G["CHAT_CONVERSATION_"..arg1.."_NOTICE"], channelLink, playerLink)
|
|
|
|
local accessID = ChatHistory_GetAccessID(Chat_GetChatCategory(type), arg8);
|
|
local typeID = ChatHistory_GetAccessID(infoType, arg8);
|
|
self:AddMessage(message, info.r, info.g, info.b, info.id, false, accessID, typeID);
|
|
elseif ( type == "BN_CONVERSATION_LIST" ) then
|
|
local channelLink = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8);
|
|
local message = format(CHAT_BN_CONVERSATION_LIST, channelLink, arg1);
|
|
self:AddMessage(message, info.r, info.g, info.b, info.id, false, accessID, typeID);
|
|
elseif ( type == "BN_INLINE_TOAST_ALERT" ) then
|
|
local globalstring = _G["BN_INLINE_TOAST_"..arg1];
|
|
local message;
|
|
if ( arg1 == "FRIEND_REQUEST" ) then
|
|
message = globalstring;
|
|
elseif ( arg1 == "FRIEND_PENDING" ) then
|
|
message = format(BN_INLINE_TOAST_FRIEND_PENDING, BNGetNumFriendInvites());
|
|
elseif ( arg1 == "FRIEND_REMOVED" ) then
|
|
message = format(globalstring, arg2);
|
|
else
|
|
local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2);
|
|
message = format(globalstring, playerLink);
|
|
end
|
|
self:AddMessage(message, info.r, info.g, info.b, info.id);
|
|
elseif ( type == "BN_INLINE_TOAST_BROADCAST" ) then
|
|
if ( arg1 ~= "" ) then
|
|
local playerLink = format("|HBNplayer:%s:%s:%s:%s:%s|h[%s]|h", arg2, arg13, arg11, Chat_GetChatCategory(type), 0, arg2);
|
|
self:AddMessage(format(BN_INLINE_TOAST_BROADCAST, playerLink, arg1), info.r, info.g, info.b, info.id);
|
|
end
|
|
elseif ( type == "BN_INLINE_TOAST_BROADCAST_INFORM" ) then
|
|
if ( arg1 ~= "" ) then
|
|
self:AddMessage(BN_INLINE_TOAST_BROADCAST_INFORM, info.r, info.g, info.b, info.id);
|
|
end
|
|
elseif ( type == "BN_INLINE_TOAST_CONVERSATION" ) then
|
|
self:AddMessage(format(BN_INLINE_TOAST_CONVERSATION, arg1), info.r, info.g, info.b, info.id);
|
|
else
|
|
local body;
|
|
|
|
local _, fontHeight = FCF_GetChatWindowInfo(self:GetID());
|
|
|
|
if ( fontHeight == 0 ) then
|
|
--fontHeight will be 0 if it's still at the default (14)
|
|
fontHeight = 14;
|
|
end
|
|
|
|
-- Add AFK/DND flags
|
|
local pflag;
|
|
if(strlen(arg6) > 0) then
|
|
if ( arg6 == "GM" ) then
|
|
--If it was a whisper, dispatch it to the GMChat addon.
|
|
if ( type == "WHISPER" ) then
|
|
return;
|
|
end
|
|
--Add Blizzard Icon, this was sent by a GM
|
|
pflag = "|TInterface\\ChatFrame\\UI-ChatIcon-Blizz.blp:0:2:0:-3|t ";
|
|
elseif ( arg6 == "DEV" ) then
|
|
--Add Blizzard Icon, this was sent by a Dev
|
|
pflag = "|TInterface\\ChatFrame\\UI-ChatIcon-Blizz.blp:0:2:0:-3|t ";
|
|
else
|
|
pflag = _G["CHAT_FLAG_"..arg6];
|
|
end
|
|
else
|
|
pflag = "";
|
|
end
|
|
if ( type == "WHISPER_INFORM" and GMChatFrame_IsGM and GMChatFrame_IsGM(arg2) ) then
|
|
return;
|
|
end
|
|
|
|
local showLink = 1;
|
|
if ( strsub(type, 1, 7) == "MONSTER" or strsub(type, 1, 9) == "RAID_BOSS") then
|
|
showLink = nil;
|
|
else
|
|
arg1 = gsub(arg1, "%%", "%%%%");
|
|
end
|
|
|
|
if ((type == "PARTY_LEADER") and (HasLFGRestrictions())) then
|
|
type = "PARTY_GUIDE";
|
|
end
|
|
|
|
-- Search for icon links and replace them with texture links.
|
|
local term;
|
|
for tag in string.gmatch(arg1, "%b{}") do
|
|
term = strlower(string.gsub(tag, "[{}]", ""));
|
|
if ( ICON_TAG_LIST[term] and ICON_LIST[ICON_TAG_LIST[term]] ) then
|
|
arg1 = string.gsub(arg1, tag, ICON_LIST[ICON_TAG_LIST[term]] .. "0|t");
|
|
end
|
|
end
|
|
|
|
local playerLink;
|
|
|
|
if ( type ~= "BN_WHISPER" and type ~= "BN_WHISPER_INFORM" and type ~= "BN_CONVERSATION" ) then
|
|
playerLink = "|Hplayer:"..arg2..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h";
|
|
else
|
|
playerLink = "|HBNplayer:"..arg2..":"..arg13..":"..arg11..":"..chatGroup..(chatTarget and ":"..chatTarget or "").."|h";
|
|
end
|
|
|
|
if ( (strlen(arg3) > 0) and (arg3 ~= "Universal") and (arg3 ~= self.defaultLanguage) ) then
|
|
local languageHeader = "["..arg3.."] ";
|
|
if ( showLink and (strlen(arg2) > 0) ) then
|
|
body = format(_G["CHAT_"..type.."_GET"]..languageHeader..arg1, pflag..playerLink.."["..coloredName.."]".."|h");
|
|
else
|
|
body = format(_G["CHAT_"..type.."_GET"]..languageHeader..arg1, pflag..arg2);
|
|
end
|
|
else
|
|
if ( not showLink or strlen(arg2) == 0 ) then
|
|
body = format(_G["CHAT_"..type.."_GET"]..arg1, pflag..arg2, arg2);
|
|
else
|
|
if ( type == "EMOTE" ) then
|
|
body = format(_G["CHAT_"..type.."_GET"]..arg1, pflag..playerLink..coloredName.."|h");
|
|
elseif ( type == "TEXT_EMOTE") then
|
|
body = string.gsub(arg1, arg2, pflag..playerLink..coloredName.."|h", 1);
|
|
else
|
|
body = format(_G["CHAT_"..type.."_GET"]..arg1, pflag..playerLink.."["..coloredName.."]".."|h");
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Add Channel
|
|
arg4 = gsub(arg4, "%s%-%s.*", "");
|
|
if( chatGroup == "BN_CONVERSATION" ) then
|
|
body = format(CHAT_BN_CONVERSATION_GET_LINK, arg8, MAX_WOW_CHAT_CHANNELS + arg8)..body;
|
|
elseif(channelLength > 0) then
|
|
body = "|Hchannel:channel:"..arg8.."|h["..arg4.."]|h "..body;
|
|
end
|
|
|
|
--Add Timestamps
|
|
if ( CHAT_TIMESTAMP_FORMAT ) then
|
|
body = BetterDate(CHAT_TIMESTAMP_FORMAT, time())..body;
|
|
end
|
|
|
|
local accessID = ChatHistory_GetAccessID(chatGroup, chatTarget);
|
|
local typeID = ChatHistory_GetAccessID(infoType, chatTarget);
|
|
self:AddMessage(body, info.r, info.g, info.b, info.id, false, accessID, typeID);
|
|
end
|
|
|
|
if ( type == "WHISPER" or type == "BN_WHISPER" ) then
|
|
--BN_WHISPER FIXME
|
|
ChatEdit_SetLastTellTarget(arg2);
|
|
if ( self.tellTimer and (GetTime() > self.tellTimer) ) then
|
|
PlaySound("TellMessage");
|
|
end
|
|
self.tellTimer = GetTime() + CHAT_TELL_ALERT_TIME;
|
|
--FCF_FlashTab(self);
|
|
end
|
|
|
|
if ( not self:IsShown() ) then
|
|
if ( (self == DEFAULT_CHAT_FRAME and info.flashTabOnGeneral) or (self ~= DEFAULT_CHAT_FRAME and info.flashTab) ) then
|
|
if ( not CHAT_OPTIONS.HIDE_FRAME_ALERTS or type == "WHISPER" or type == "BN_WHISPER" ) then --BN_WHISPER FIXME
|
|
FCF_StartAlertFlash(self);
|
|
end
|
|
end
|
|
end
|
|
|
|
return true;
|
|
end
|
|
end
|
|
|
|
function ChatFrame_AddMessageEventFilter (event, filter)
|
|
assert(event and filter);
|
|
|
|
if ( chatFilters[event] ) then
|
|
-- Only allow a filter to be added once
|
|
for index, filterFunc in next, chatFilters[event] do
|
|
if ( filterFunc == filter ) then
|
|
return;
|
|
end
|
|
end
|
|
else
|
|
chatFilters[event] = {};
|
|
end
|
|
|
|
tinsert(chatFilters[event], filter);
|
|
end
|
|
|
|
function ChatFrame_RemoveMessageEventFilter (event, filter)
|
|
assert(event and filter);
|
|
|
|
if ( chatFilters[event] ) then
|
|
for index, filterFunc in next, chatFilters[event] do
|
|
if ( filterFunc == filter ) then
|
|
tremove(chatFilters[event], index);
|
|
end
|
|
end
|
|
|
|
if ( #chatFilters[event] == 0 ) then
|
|
chatFilters[event] = nil;
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatFrame_GetMessageEventFilters (event)
|
|
assert(event);
|
|
|
|
return chatFilters[event];
|
|
end
|
|
|
|
function ChatFrame_OnUpdate(self, elapsedSec)
|
|
local flash = _G[self:GetName().."ButtonFrameBottomButtonFlash"];
|
|
|
|
if ( not flash ) then
|
|
return;
|
|
end
|
|
|
|
if ( self:AtBottom() ) then
|
|
if ( flash:IsShown() ) then
|
|
flash:Hide();
|
|
end
|
|
return;
|
|
end
|
|
|
|
local flashTimer = self.flashTimer + elapsedSec;
|
|
if ( flashTimer < CHAT_BUTTON_FLASH_TIME ) then
|
|
self.flashTimer = flashTimer;
|
|
return;
|
|
end
|
|
|
|
while ( flashTimer >= CHAT_BUTTON_FLASH_TIME ) do
|
|
flashTimer = flashTimer - CHAT_BUTTON_FLASH_TIME;
|
|
end
|
|
self.flashTimer = flashTimer;
|
|
|
|
if ( flash:IsShown() ) then
|
|
flash:Hide();
|
|
else
|
|
flash:Show();
|
|
end
|
|
end
|
|
|
|
function ChatFrame_OnHyperlinkShow(self, link, text, button)
|
|
SetItemRef(link, text, button, self);
|
|
end
|
|
|
|
function ChatFrame_OnMouseWheel(value)
|
|
if ( value > 0 ) then
|
|
SELECTED_DOCK_FRAME:ScrollUp();
|
|
elseif ( value < 0 ) then
|
|
SELECTED_DOCK_FRAME:ScrollDown();
|
|
end
|
|
end
|
|
|
|
function ChatFrame_OpenChat(text, chatFrame)
|
|
local editBox = ChatEdit_ChooseBoxForSend(chatFrame);
|
|
|
|
ChatEdit_ActivateChat(editBox);
|
|
editBox.setText = 1;
|
|
editBox.text = text;
|
|
|
|
if ( editBox:GetAttribute("chatType") == editBox:GetAttribute("stickyType") ) then
|
|
if ( (editBox:GetAttribute("stickyType") == "PARTY") and (GetNumPartyMembers() == 0) or
|
|
(editBox:GetAttribute("stickyType") == "RAID") and (GetNumRaidMembers() == 0) or
|
|
(editBox:GetAttribute("stickyType") == "BATTLEGROUND") and (GetNumRaidMembers() == 0) ) then
|
|
editBox:SetAttribute("chatType", "SAY");
|
|
end
|
|
end
|
|
|
|
ChatEdit_UpdateHeader(editBox);
|
|
return editBox;
|
|
end
|
|
|
|
function ChatFrame_ScrollToBottom()
|
|
SELECTED_DOCK_FRAME:ScrollToBottom();
|
|
end
|
|
|
|
function ChatFrame_ScrollUp()
|
|
SELECTED_DOCK_FRAME:ScrollUp();
|
|
end
|
|
|
|
function ChatFrame_ScrollDown()
|
|
SELECTED_DOCK_FRAME:ScrollDown();
|
|
end
|
|
|
|
--used for chatframe and combat log
|
|
function MessageFrameScrollButton_OnLoad(self)
|
|
self.clickDelay = MESSAGE_SCROLLBUTTON_INITIAL_DELAY;
|
|
self:RegisterForClicks("LeftButtonDown", "LeftButtonUp", "RightButtonUp", "RightButtonDown");
|
|
end
|
|
|
|
--Controls scrolling for chatframe and combat log
|
|
function MessageFrameScrollButton_OnUpdate(self, elapsed)
|
|
if (self:GetButtonState() == "PUSHED") then
|
|
self.clickDelay = self.clickDelay - elapsed;
|
|
if ( self.clickDelay < 0 ) then
|
|
local name = self:GetName();
|
|
if ( name == self:GetParent():GetName().."DownButton" ) then
|
|
self:GetParent():GetParent():ScrollDown();
|
|
elseif ( name == self:GetParent():GetName().."UpButton" ) then
|
|
self:GetParent():GetParent():ScrollUp();
|
|
end
|
|
self.clickDelay = MESSAGE_SCROLLBUTTON_SCROLL_DELAY;
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatFrame_OpenMenu()
|
|
ChatMenu:Show();
|
|
end
|
|
|
|
function ChatFrameMenu_UpdateAnchorPoint()
|
|
--Update the menu anchor point
|
|
if ( FCF_GetButtonSide(DEFAULT_CHAT_FRAME) == "right" ) then
|
|
ChatMenu:ClearAllPoints();
|
|
ChatMenu:SetPoint("BOTTOMRIGHT", ChatFrameMenuButton, "TOPLEFT");
|
|
else
|
|
ChatMenu:ClearAllPoints();
|
|
ChatMenu:SetPoint("BOTTOMLEFT", ChatFrameMenuButton, "TOPRIGHT");
|
|
end
|
|
end
|
|
|
|
function ChatFrame_SendTell(name, chatFrame)
|
|
local editBox = ChatEdit_ChooseBoxForSend(chatFrame);
|
|
|
|
--DEBUG FIXME - for now, we're not going to remove spaces from names. We need to make sure X-server still works.
|
|
-- Remove spaces from the server name for slash command parsing
|
|
--name = gsub(name, " ", "");
|
|
|
|
if ( editBox ~= ChatEdit_GetActiveWindow() ) then
|
|
ChatFrame_OpenChat(SLASH_WHISPER1.." "..name.." ", chatFrame);
|
|
else
|
|
editBox:SetText(SLASH_WHISPER1.." "..name.." ");
|
|
end
|
|
ChatEdit_ParseText(editBox, 0);
|
|
--[[
|
|
chatFrame.editBox:SetAttribute("chatType", "WHISPER");
|
|
chatFrame.editBox:SetAttribute("tellTarget", name);
|
|
ChatEdit_UpdateHeader(chatFrame.editBox);
|
|
if ( editBox ~= ChatEdit_GetActiveWindow() ) then
|
|
ChatFrame_OpenChat("", chatFrame);
|
|
end
|
|
]]
|
|
end
|
|
|
|
function ChatFrame_ReplyTell(chatFrame)
|
|
local editBox = ChatEdit_ChooseBoxForSend(chatFrame);
|
|
|
|
local lastTell = ChatEdit_GetLastTellTarget();
|
|
if ( lastTell ~= "" ) then
|
|
--BN_WHISPER FIXME
|
|
editBox:SetAttribute("chatType", "WHISPER");
|
|
editBox:SetAttribute("tellTarget", lastTell);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
if ( editBox ~= ChatEdit_GetActiveWindow() ) then
|
|
ChatFrame_OpenChat("", chatFrame);
|
|
end
|
|
else
|
|
-- Error message
|
|
end
|
|
end
|
|
|
|
function ChatFrame_ReplyTell2(chatFrame)
|
|
local editBox = ChatEdit_ChooseBoxForSend(chatFrame);
|
|
|
|
local lastTold = ChatEdit_GetLastToldTarget();
|
|
if ( lastTold ~= "" ) then
|
|
--BN_WHISPER FIXME
|
|
editBox:SetAttribute("chatType", "WHISPER");
|
|
editBox:SetAttribute("tellTarget", lastTold);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
if ( editBox ~= ChatEdit_GetActiveWindow() ) then
|
|
ChatFrame_OpenChat("", chatFrame);
|
|
end
|
|
else
|
|
-- Error message
|
|
end
|
|
end
|
|
|
|
function ChatFrame_DisplayStartupText(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local i = 1;
|
|
local text = _G["STARTUP_TEXT_LINE"..i];
|
|
while text do
|
|
frame:AddMessage(text, info.r, info.g, info.b, info.id);
|
|
i = i + 1;
|
|
text = _G["STARTUP_TEXT_LINE"..i];
|
|
end
|
|
|
|
end
|
|
|
|
function ChatFrame_DisplayHelpText(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local i = 1;
|
|
local text = _G["HELP_TEXT_LINE"..i];
|
|
while text do
|
|
frame:AddMessage(text, info.r, info.g, info.b, info.id);
|
|
i = i + 1;
|
|
text = _G["HELP_TEXT_LINE"..i];
|
|
end
|
|
|
|
end
|
|
|
|
function ChatFrame_DisplayMacroHelpText(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local i = 1;
|
|
local text = _G["MACRO_HELP_TEXT_LINE"..i];
|
|
while text do
|
|
frame:AddMessage(text, info.r, info.g, info.b, info.id);
|
|
i = i + 1;
|
|
text = _G["MACRO_HELP_TEXT_LINE"..i];
|
|
end
|
|
|
|
end
|
|
|
|
function ChatFrame_DisplayChatHelp(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local i = 1;
|
|
local text = _G["CHAT_HELP_TEXT_LINE"..i];
|
|
while text do
|
|
frame:AddMessage(text, info.r, info.g, info.b, info.id);
|
|
i = i + 1;
|
|
-- hack fix for removing a line without causing localization problems
|
|
if ( i == 15 ) then
|
|
i = i + 1;
|
|
end
|
|
text = _G["CHAT_HELP_TEXT_LINE"..i];
|
|
end
|
|
end
|
|
|
|
function ChatFrame_DisplayGuildHelp(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local i = 1;
|
|
local text = _G["GUILD_HELP_TEXT_LINE"..i];
|
|
while text do
|
|
frame:AddMessage(text, info.r, info.g, info.b, info.id);
|
|
i = i + 1;
|
|
text = _G["GUILD_HELP_TEXT_LINE"..i];
|
|
end
|
|
end
|
|
|
|
function ChatFrame_DisplayGameTime(frame)
|
|
if ( not frame ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
frame:AddMessage(GameTime_GetGameTime(true), info.r, info.g, info.b, info.id);
|
|
end
|
|
|
|
function ChatFrame_TimeBreakDown(time)
|
|
local days = floor(time / (60 * 60 * 24));
|
|
local hours = floor((time - (days * (60 * 60 * 24))) / (60 * 60));
|
|
local minutes = floor((time - (days * (60 * 60 * 24)) - (hours * (60 * 60))) / 60);
|
|
local seconds = mod(time, 60);
|
|
return days, hours, minutes, seconds;
|
|
end
|
|
|
|
function ChatFrame_DisplayTimePlayed(self, totalTime, levelTime)
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
local d;
|
|
local h;
|
|
local m;
|
|
local s;
|
|
d, h, m, s = ChatFrame_TimeBreakDown(totalTime);
|
|
local string = format(TIME_PLAYED_TOTAL, format(TIME_DAYHOURMINUTESECOND, d, h, m, s));
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
|
|
d, h, m, s = ChatFrame_TimeBreakDown(levelTime);
|
|
local string = format(TIME_PLAYED_LEVEL, format(TIME_DAYHOURMINUTESECOND, d, h, m, s));
|
|
self:AddMessage(string, info.r, info.g, info.b, info.id);
|
|
end
|
|
|
|
function ChatFrame_ChatPageUp()
|
|
SELECTED_CHAT_FRAME:PageUp();
|
|
end
|
|
|
|
function ChatFrame_ChatPageDown()
|
|
SELECTED_CHAT_FRAME:PageDown();
|
|
end
|
|
|
|
function ChatFrame_DisplayUsageError(messageTag)
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
DEFAULT_CHAT_FRAME:AddMessage(messageTag, info.r, info.g, info.b, info.id);
|
|
end
|
|
|
|
-- ChatEdit functions
|
|
|
|
local ChatEdit_LastTell = {};
|
|
for i = 1, NUM_REMEMBERED_TELLS, 1 do
|
|
ChatEdit_LastTell[i] = "";
|
|
end
|
|
local ChatEdit_LastTold = "";
|
|
|
|
function ChatEdit_OnLoad(self)
|
|
self:SetFrameLevel(self.chatFrame:GetFrameLevel()+1);
|
|
self:SetAttribute("chatType", "SAY");
|
|
self:SetAttribute("stickyType", "SAY");
|
|
self.chatLanguage = GetDefaultLanguage();
|
|
self:RegisterEvent("UPDATE_CHAT_COLOR");
|
|
|
|
self.addSpaceToAutoComplete = true;
|
|
|
|
if ( CHAT_OPTIONS.ONE_EDIT_AT_A_TIME == "many" ) then
|
|
self:Show();
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnEvent(self, event, ...)
|
|
if ( event == "UPDATE_CHAT_COLOR" ) then
|
|
local chatType = ...;
|
|
if ( chatType == self:GetAttribute("chatType") ) then
|
|
ChatEdit_UpdateHeader(self);
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnUpdate(self, elapsedSec)
|
|
if ( self.setText == 1) then
|
|
self:SetText(self.text);
|
|
self.setText = 0;
|
|
ChatEdit_ParseText(self, 0, true);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnShow(self)
|
|
ChatEdit_ResetChatType(self);
|
|
end
|
|
|
|
function ChatEdit_ResetChatType(self)
|
|
if ( self:GetAttribute("chatType") == "PARTY" and UnitName("party1") == "" ) then
|
|
self:SetAttribute("chatType", "SAY");
|
|
end
|
|
if ( self:GetAttribute("chatType") == "RAID" and (GetNumRaidMembers() == 0) ) then
|
|
self:SetAttribute("chatType", "SAY");
|
|
end
|
|
if ( (self:GetAttribute("chatType") == "GUILD" or self:GetAttribute("chatType") == "OFFICER") and not IsInGuild() ) then
|
|
self:SetAttribute("chatType", "SAY");
|
|
end
|
|
if ( self:GetAttribute("chatType") == "BATTLEGROUND" and (GetNumRaidMembers() == 0) ) then
|
|
self:SetAttribute("chatType", "SAY");
|
|
end
|
|
self.tabCompleteIndex = 1;
|
|
self.tabCompleteText = nil;
|
|
ChatEdit_UpdateHeader(self);
|
|
ChatEdit_OnInputLanguageChanged(self);
|
|
--[[if ( CHAT_OPTIONS.ONE_EDIT_AT_A_TIME == "old") then
|
|
self:SetFocus();
|
|
end]]
|
|
end
|
|
|
|
function ChatEdit_OnHide(self)
|
|
if ( ACTIVE_CHAT_EDIT_BOX == self ) then
|
|
ChatEdit_DeactivateChat(self);
|
|
end
|
|
|
|
if ( LAST_ACTIVE_CHAT_EDIT_BOX == self and self:IsShown() ) then --Our parent was hidden. Let's find a new default frame.
|
|
--We'll go with the active dock frame since people think of that as the primary chat.
|
|
ChatEdit_SetLastActiveWindow(FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK).editBox);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnEditFocusGained(self)
|
|
ChatEdit_ActivateChat(self);
|
|
end
|
|
|
|
function ChatEdit_OnEditFocusLost(self)
|
|
AutoCompleteEditBox_OnEditFocusLost(self);
|
|
ChatEdit_DeactivateChat(self);
|
|
end
|
|
|
|
function ChatEdit_ActivateChat(editBox)
|
|
if ( ACTIVE_CHAT_EDIT_BOX and ACTIVE_CHAT_EDIT_BOX ~= editBox ) then
|
|
ChatEdit_DeactivateChat(ACTIVE_CHAT_EDIT_BOX);
|
|
end
|
|
ACTIVE_CHAT_EDIT_BOX = editBox;
|
|
|
|
ChatEdit_SetLastActiveWindow(editBox);
|
|
|
|
--Stop any sort of fading
|
|
UIFrameFadeRemoveFrame(editBox);
|
|
|
|
editBox:Show();
|
|
editBox:SetFocus();
|
|
editBox:SetFrameStrata("DIALOG");
|
|
editBox:Raise();
|
|
|
|
editBox.header:Show();
|
|
editBox.focusLeft:Show();
|
|
editBox.focusRight:Show();
|
|
editBox.focusMid:Show();
|
|
editBox:SetAlpha(1.0);
|
|
|
|
ChatEdit_UpdateHeader(editBox);
|
|
|
|
if ( CHAT_SHOW_IME ) then
|
|
_G[editBox:GetName().."Language"]:Show();
|
|
end
|
|
end
|
|
|
|
local function ChatEdit_SetDeactivated(editBox)
|
|
editBox:SetFrameStrata("LOW");
|
|
if ( GetCVar("chatStyle") == "classic") then
|
|
editBox:Hide();
|
|
else
|
|
editBox:SetText("");
|
|
editBox.header:Hide();
|
|
editBox:SetAlpha(0.35);
|
|
editBox:ClearFocus();
|
|
|
|
editBox.focusLeft:Hide();
|
|
editBox.focusRight:Hide();
|
|
editBox.focusMid:Hide();
|
|
ChatEdit_ResetChatTypeToSticky(editBox);
|
|
ChatEdit_ResetChatType(editBox);
|
|
end
|
|
_G[editBox:GetName().."Language"]:Hide();
|
|
end
|
|
|
|
function ChatEdit_DeactivateChat(editBox)
|
|
if ( ACTIVE_CHAT_EDIT_BOX == editBox ) then
|
|
ACTIVE_CHAT_EDIT_BOX = nil;
|
|
end
|
|
|
|
ChatEdit_SetDeactivated(editBox);
|
|
end
|
|
|
|
function ChatEdit_ChooseBoxForSend(preferredChatFrame)
|
|
if ( GetCVar("chatStyle") == "classic" ) then
|
|
return DEFAULT_CHAT_FRAME.editBox;
|
|
elseif ( preferredChatFrame and preferredChatFrame:IsShown() ) then
|
|
return preferredChatFrame.editBox;
|
|
elseif ( ChatEdit_GetLastActiveWindow() and ChatEdit_GetLastActiveWindow():GetParent():IsShown() ) then
|
|
return ChatEdit_GetLastActiveWindow();
|
|
else
|
|
return FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK).editBox;
|
|
end
|
|
end
|
|
|
|
function ChatEdit_SetLastActiveWindow(editBox)
|
|
local previousValue = LAST_ACTIVE_CHAT_EDIT_BOX;
|
|
if ( LAST_ACTIVE_CHAT_EDIT_BOX and LAST_ACTIVE_CHAT_EDIT_BOX ~= editBox ) then
|
|
if ( GetCVar("chatStyle") == "im" ) then
|
|
LAST_ACTIVE_CHAT_EDIT_BOX:Hide();
|
|
end
|
|
end
|
|
|
|
LAST_ACTIVE_CHAT_EDIT_BOX = editBox;
|
|
if ( GetCVar("chatStyle") == "im" and ACTIVE_CHAT_EDIT_BOX ~= editBox ) then
|
|
editBox:Show();
|
|
ChatEdit_SetDeactivated(editBox);
|
|
end
|
|
|
|
if ( previousValue ) then
|
|
FCFClickAnywhereButton_UpdateState(previousValue.chatFrame.clickAnywhereButton);
|
|
end
|
|
FCFClickAnywhereButton_UpdateState(editBox.chatFrame.clickAnywhereButton);
|
|
end
|
|
|
|
function ChatEdit_GetActiveWindow()
|
|
return ACTIVE_CHAT_EDIT_BOX;
|
|
end
|
|
|
|
function ChatEdit_GetLastActiveWindow()
|
|
return LAST_ACTIVE_CHAT_EDIT_BOX;
|
|
end
|
|
|
|
function ChatEdit_FocusActiveWindow()
|
|
local active = ChatEdit_GetActiveWindow()
|
|
if ( active ) then
|
|
ChatEdit_ActivateChat(active);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_InsertLink(text)
|
|
if ( not text ) then
|
|
return false;
|
|
end
|
|
|
|
local activeWindow = ChatEdit_GetActiveWindow();
|
|
if ( activeWindow ) then
|
|
-- add a space for proper parsing
|
|
activeWindow:Insert(" "..text);
|
|
return true;
|
|
end
|
|
if ( BrowseName and BrowseName:IsVisible() ) then
|
|
local item;
|
|
if ( strfind(text, "item:", 1, true) ) then
|
|
item = GetItemInfo(text);
|
|
end
|
|
if ( item ) then
|
|
BrowseName:SetText(item);
|
|
return true;
|
|
end
|
|
end
|
|
if ( MacroFrameText and MacroFrameText:IsVisible() ) then
|
|
local item;
|
|
if ( strfind(text, "item:", 1, true) ) then
|
|
item = GetItemInfo(text);
|
|
end
|
|
local cursorPosition = MacroFrameText:GetCursorPosition();
|
|
if (cursorPosition == 0 or strsub(MacroFrameText:GetText(), cursorPosition, cursorPosition) == "\n" ) then
|
|
if ( item ) then
|
|
if ( GetItemSpell(text) ) then
|
|
MacroFrameText:Insert(SLASH_USE1.." "..item.."\n");
|
|
else
|
|
MacroFrameText:Insert(SLASH_EQUIP1.." "..item.."\n");
|
|
end
|
|
else
|
|
MacroFrameText:Insert(SLASH_CAST1.." "..text.."\n");
|
|
end
|
|
else
|
|
MacroFrameText:Insert(item or text);
|
|
end
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function ChatEdit_GetLastTellTarget()
|
|
for index, value in ipairs(ChatEdit_LastTell) do
|
|
if ( value ~= "" ) then
|
|
return value;
|
|
end
|
|
end
|
|
return "";
|
|
end
|
|
|
|
function ChatEdit_SetLastTellTarget(target)
|
|
local found = #ChatEdit_LastTell;
|
|
for index, value in ipairs(ChatEdit_LastTell) do
|
|
if ( strupper(target) == strupper(value) ) then
|
|
found = index;
|
|
break;
|
|
end
|
|
end
|
|
|
|
for i = found, 2, -1 do
|
|
ChatEdit_LastTell[i] = ChatEdit_LastTell[i-1];
|
|
end
|
|
ChatEdit_LastTell[1] = target;
|
|
end
|
|
|
|
function ChatEdit_GetNextTellTarget(target)
|
|
if ( not target or target == "" ) then
|
|
return ChatEdit_LastTell[1];
|
|
end
|
|
|
|
for i = 1, #ChatEdit_LastTell - 1, 1 do
|
|
if ( ChatEdit_LastTell[i] == "" ) then
|
|
break;
|
|
elseif ( strupper(target) == strupper(ChatEdit_LastTell[i]) ) then
|
|
if ( ChatEdit_LastTell[i+1] ~= "" ) then
|
|
return ChatEdit_LastTell[i+1];
|
|
else
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
|
|
return ChatEdit_LastTell[1];
|
|
end
|
|
|
|
function ChatEdit_GetLastToldTarget()
|
|
return ChatEdit_LastTold;
|
|
end
|
|
|
|
function ChatEdit_SetLastToldTarget(name)
|
|
ChatEdit_LastTold = name or "";
|
|
end
|
|
|
|
function ChatEdit_UpdateHeader(editBox)
|
|
local type = editBox:GetAttribute("chatType");
|
|
if ( not type ) then
|
|
return;
|
|
end
|
|
|
|
local info = ChatTypeInfo[type];
|
|
local header = _G[editBox:GetName().."Header"];
|
|
if ( not header ) then
|
|
return;
|
|
end
|
|
|
|
--BN_WHISPER FIXME
|
|
if ( type == "WHISPER" ) then
|
|
--If we have a BN presence ID for this name, it's a BN whisper.
|
|
if ( BNet_GetPresenceID(editBox:GetAttribute("tellTarget")) ) then
|
|
editBox:SetAttribute("chatType", "BN_WHISPER");
|
|
ChatEdit_UpdateHeader(editBox);
|
|
return;
|
|
end
|
|
|
|
header:SetFormattedText(CHAT_WHISPER_SEND, editBox:GetAttribute("tellTarget"));
|
|
elseif ( type == "BN_WHISPER" ) then
|
|
header:SetFormattedText(CHAT_BN_WHISPER_SEND, editBox:GetAttribute("tellTarget"));
|
|
elseif ( type == "EMOTE" ) then
|
|
header:SetFormattedText(CHAT_EMOTE_SEND, UnitName("player"));
|
|
elseif ( type == "CHANNEL" ) then
|
|
local channel, channelName, instanceID = GetChannelName(editBox:GetAttribute("channelTarget"));
|
|
if ( channelName ) then
|
|
if ( instanceID > 0 ) then
|
|
channelName = channelName.." "..instanceID;
|
|
end
|
|
info = ChatTypeInfo["CHANNEL"..channel];
|
|
editBox:SetAttribute("channelTarget", channel);
|
|
header:SetFormattedText(CHAT_CHANNEL_SEND, channel, channelName);
|
|
end
|
|
elseif ( type == "BN_CONVERSATION" ) then
|
|
local conversationID = editBox:GetAttribute("channelTarget");
|
|
header:SetFormattedText(CHAT_BN_CONVERSATION_SEND, conversationID + MAX_WOW_CHAT_CHANNELS);
|
|
else
|
|
header:SetText(_G["CHAT_"..type.."_SEND"]);
|
|
end
|
|
|
|
header:SetTextColor(info.r, info.g, info.b);
|
|
|
|
editBox:SetTextInsets(15 + header:GetWidth(), 13, 0, 0);
|
|
editBox:SetTextColor(info.r, info.g, info.b);
|
|
|
|
editBox.focusLeft:SetVertexColor(info.r, info.g, info.b);
|
|
editBox.focusRight:SetVertexColor(info.r, info.g, info.b);
|
|
editBox.focusMid:SetVertexColor(info.r, info.g, info.b);
|
|
end
|
|
|
|
function ChatEdit_AddHistory(editBox)
|
|
local text = "";
|
|
local type = editBox:GetAttribute("chatType");
|
|
local header = _G["SLASH_"..type.."1"];
|
|
if ( header ) then
|
|
text = header;
|
|
end
|
|
|
|
if ( type == "WHISPER" ) then
|
|
text = text.." "..editBox:GetAttribute("tellTarget");
|
|
elseif ( type == "CHANNEL" ) then
|
|
text = "/"..editBox:GetAttribute("channelTarget");
|
|
end
|
|
|
|
local editBoxText = editBox:GetText();
|
|
if ( strlen(editBoxText) > 0 ) then
|
|
text = text.." "..editBox:GetText();
|
|
end
|
|
|
|
if ( strlen(text) > 0 ) then
|
|
editBox:AddHistoryLine(text);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_SendText(editBox, addHistory)
|
|
ChatEdit_ParseText(editBox, 1);
|
|
|
|
local type = editBox:GetAttribute("chatType");
|
|
local text = editBox:GetText();
|
|
if ( strfind(text, "%s*[^%s]+") ) then
|
|
--BN_WHISPER FIXME
|
|
if ( type == "WHISPER") then
|
|
local target = editBox:GetAttribute("tellTarget");
|
|
ChatEdit_SetLastToldTarget(target);
|
|
SendChatMessage(text, type, editBox.language, target);
|
|
elseif ( type == "BN_WHISPER" ) then
|
|
local target = editBox:GetAttribute("tellTarget");
|
|
local presenceID = BNet_GetPresenceID(target);
|
|
if ( presenceID ) then
|
|
ChatEdit_SetLastToldTarget(target);
|
|
BNSendWhisper(presenceID, text);
|
|
else
|
|
local info = ChatTypeInfo["SYSTEM"]
|
|
editBox.chatFrame:AddMessage(format(BN_UNABLE_TO_RESOLVE_NAME, target), info.r, info.g, info.b);
|
|
end
|
|
elseif ( type == "BN_CONVERSATION" ) then
|
|
local target = tonumber(editBox:GetAttribute("channelTarget"));
|
|
BNSendConversationMessage(target, text);
|
|
elseif ( type == "CHANNEL") then
|
|
SendChatMessage(text, type, editBox.language, editBox:GetAttribute("channelTarget"));
|
|
else
|
|
SendChatMessage(text, type, editBox.language);
|
|
end
|
|
if ( addHistory ) then
|
|
ChatEdit_AddHistory(editBox);
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnEnterPressed(self)
|
|
if(AutoCompleteEditBox_OnEnterPressed(self)) then
|
|
return;
|
|
end
|
|
ChatEdit_SendText(self, 1);
|
|
|
|
local type = self:GetAttribute("chatType");
|
|
local chatFrame = self:GetParent();
|
|
if ( chatFrame.isTemporary ) then --Temporary window sticky types never change.
|
|
self:SetAttribute("stickyType", chatFrame.chatType);
|
|
--BN_WHISPER FIXME
|
|
if ( chatFrame.chatType == "WHISPER" or chatFrame.chatType == "BN_WHISPER" ) then
|
|
self:SetAttribute("tellTarget", chatFrame.chatTarget);
|
|
end
|
|
elseif ( ChatTypeInfo[type].sticky == 1 ) then
|
|
self:SetAttribute("stickyType", type);
|
|
end
|
|
|
|
ChatEdit_OnEscapePressed(self);
|
|
end
|
|
|
|
function ChatEdit_OnEscapePressed(editBox)
|
|
if ( not AutoCompleteEditBox_OnEscapePressed(editBox) ) then
|
|
ChatEdit_ResetChatTypeToSticky(editBox);
|
|
if ( GetCVar("chatStyle") ~= "im" or editBox == MacroEditBox ) then
|
|
editBox:SetText("");
|
|
editBox:Hide();
|
|
else
|
|
ChatEdit_DeactivateChat(editBox);
|
|
end
|
|
end
|
|
end
|
|
|
|
function ChatEdit_ResetChatTypeToSticky(editBox)
|
|
editBox:SetAttribute("chatType", editBox:GetAttribute("stickyType"));
|
|
end
|
|
|
|
function ChatEdit_OnSpacePressed(self)
|
|
ChatEdit_ParseText(self, 0);
|
|
end
|
|
|
|
function ChatEdit_CustomTabPressed(self)
|
|
end
|
|
|
|
function ChatEdit_SecureTabPressed(self)
|
|
local chatType = self:GetAttribute("chatType");
|
|
if ( chatType == "WHISPER" or chatType == "BN_WHISPER" ) then
|
|
local newTarget = ChatEdit_GetNextTellTarget(self:GetAttribute("tellTarget"));
|
|
if ( newTarget and newTarget ~= "" ) then
|
|
self:SetAttribute("chatType", "WHISPER"); --UpdateHeader will change it to BN_WHISPER if needed.
|
|
self:SetAttribute("tellTarget", newTarget);
|
|
ChatEdit_UpdateHeader(self);
|
|
end
|
|
return;
|
|
end
|
|
|
|
local text = self.tabCompleteText;
|
|
if ( not text ) then
|
|
text = self:GetText();
|
|
self.tabCompleteText = text;
|
|
end
|
|
|
|
if ( strsub(text, 1, 1) ~= "/" ) then
|
|
return;
|
|
end
|
|
|
|
-- Increment the current tabcomplete count
|
|
local tabCompleteIndex = self.tabCompleteIndex;
|
|
self.tabCompleteIndex = tabCompleteIndex + 1;
|
|
|
|
-- If the string is in the format "/cmd blah", command will be "/cmd"
|
|
local command = strmatch(text, "^(/[^%s]+)") or "";
|
|
|
|
for index, value in pairs(ChatTypeInfo) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
if ( strfind(cmdString, command, 1, 1) ) then
|
|
tabCompleteIndex = tabCompleteIndex - 1;
|
|
if ( tabCompleteIndex == 0 ) then
|
|
self.ignoreTextChange = 1;
|
|
self:SetText(cmdString);
|
|
return;
|
|
end
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
|
|
for index, value in pairs(SecureCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
if ( strfind(cmdString, command, 1, 1) ) then
|
|
tabCompleteIndex = tabCompleteIndex - 1;
|
|
if ( tabCompleteIndex == 0 ) then
|
|
self.ignoreTextChange = 1;
|
|
self:SetText(cmdString);
|
|
return;
|
|
end
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
for index, value in pairs(SlashCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
if ( strfind(cmdString, command, 1, 1) ) then
|
|
tabCompleteIndex = tabCompleteIndex - 1;
|
|
if ( tabCompleteIndex == 0 ) then
|
|
self.ignoreTextChange = 1;
|
|
self:SetText(cmdString);
|
|
return;
|
|
end
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
|
|
local i = 1;
|
|
local j = 1;
|
|
local cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
while ( cmdString ) do
|
|
if ( strfind(cmdString, command, 1, 1) ) then
|
|
tabCompleteIndex = tabCompleteIndex - 1;
|
|
if ( tabCompleteIndex == 0 ) then
|
|
self.ignoreTextChange = 1;
|
|
self:SetText(cmdString);
|
|
return;
|
|
end
|
|
end
|
|
j = j + 1;
|
|
cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
if ( not cmdString ) then
|
|
i = i + 1;
|
|
j = 1;
|
|
cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
end
|
|
end
|
|
|
|
-- No tab completion
|
|
self:SetText(self.tabCompleteText);
|
|
end
|
|
|
|
function ChatEdit_OnTabPressed(self)
|
|
if ( not AutoCompleteEditBox_OnTabPressed(self) ) then
|
|
if ( securecall("ChatEdit_CustomTabPressed") ) then
|
|
return;
|
|
end
|
|
ChatEdit_SecureTabPressed(self);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnTextChanged(self, userInput)
|
|
ChatEdit_ParseText(self, 0);
|
|
if ( not self.ignoreTextChange ) then
|
|
self.tabCompleteIndex = 1;
|
|
self.tabCompleteText = nil;
|
|
end
|
|
self.ignoreTextChange = nil;
|
|
local regex = "^((/[^%s]+)%s+)(.+)"
|
|
local full, command, target = strmatch(self:GetText(), regex);
|
|
if ( not target or (strsub(target, 1, 1) == "|") ) then
|
|
AutoComplete_HideIfAttachedTo(self);
|
|
return;
|
|
end
|
|
|
|
if ( userInput ) then
|
|
self.autoCompleteRegex = regex;
|
|
self.autoCompleteFormatRegex = "%2$s%1$s"
|
|
self.autoCompleteXOffset = 35;
|
|
AutoComplete_Update(self, target, self:GetUTF8CursorPosition() - strlenutf8(command) - 1);
|
|
end
|
|
end
|
|
|
|
function ChatEdit_OnTextSet(self)
|
|
ChatEdit_ParseText(self, 0);
|
|
end
|
|
|
|
function ChatEdit_LanguageShow()
|
|
CHAT_SHOW_IME = true;
|
|
end
|
|
|
|
function ChatEdit_OnInputLanguageChanged(self)
|
|
local button = _G[self:GetName().."Language"];
|
|
local variable = _G["INPUT_"..self:GetInputLanguage()];
|
|
button:SetText(variable);
|
|
end
|
|
|
|
local function processChatType(editBox, msg, index, send)
|
|
editBox.autoCompleteParams = AUTOCOMPLETE_LIST[index];
|
|
-- this is a special function for "ChatEdit_HandleChatType"
|
|
if ( ChatTypeInfo[index] ) then
|
|
if ( index == "WHISPER" ) then
|
|
local targetFound = ChatEdit_ExtractTellTarget(editBox, msg);
|
|
if ( send == 1 and not targetFound) then
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
end
|
|
elseif ( index == "REPLY" ) then
|
|
local lastTell = ChatEdit_GetLastTellTarget();
|
|
if ( lastTell ~= "" ) then
|
|
--BN_WHISPER FIXME
|
|
editBox:SetAttribute("chatType", "WHISPER");
|
|
editBox:SetAttribute("tellTarget", lastTell);
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
else
|
|
if ( send == 1 ) then
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
end
|
|
end
|
|
elseif (index == "CHANNEL") then
|
|
ChatEdit_ExtractChannel(editBox, msg);
|
|
elseif ( index == "BN_CONVERSATION" ) then
|
|
ChatEdit_ExtractBNConversation(editBox, msg);
|
|
else
|
|
editBox:SetAttribute("chatType", index);
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
end
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function ChatEdit_HandleChatType(editBox, msg, command, send)
|
|
local channel = strmatch(command, "/([0-9]+)");
|
|
|
|
if( channel ) then
|
|
local chanNum = tonumber(channel);
|
|
if ( chanNum > 0 and chanNum <= MAX_WOW_CHAT_CHANNELS ) then
|
|
local channelNum, channelName = GetChannelName(channel);
|
|
if ( channelNum > 0 ) then
|
|
editBox:SetAttribute("channelTarget", channelNum);
|
|
editBox:SetAttribute("chatType", "CHANNEL");
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
return true;
|
|
end
|
|
elseif ( chanNum > MAX_WOW_CHAT_CHANNELS ) then --This is a B.Net chat.
|
|
local conversationNum = chanNum - MAX_WOW_CHAT_CHANNELS;
|
|
if ( BNGetConversationInfo(conversationNum) ) then
|
|
editBox:SetAttribute("channelTarget", conversationNum);
|
|
editBox:SetAttribute("chatType", "BN_CONVERSATION");
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
return true;
|
|
end
|
|
end
|
|
else
|
|
-- first check the hash table
|
|
if ( hash_ChatTypeInfoList[command] ) then
|
|
return processChatType(editBox, msg, hash_ChatTypeInfoList[command], send);
|
|
end
|
|
for index, value in pairs(SecureCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
if ( cmdString == command ) then
|
|
hash_ChatTypeInfoList[command] = index;
|
|
return processChatType(editBox, msg, index, send);
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
for index, value in pairs(SlashCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
if ( cmdString == command ) then
|
|
hash_ChatTypeInfoList[command] = index;
|
|
return processChatType(editBox, msg, index, send);
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
for index, value in pairs(ChatTypeInfo) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
if ( cmdString == command ) then
|
|
hash_ChatTypeInfoList[command] = index; -- add to hash table
|
|
return processChatType(editBox, msg, index, send);
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
end
|
|
--This isn't one we found in our list, so we're not going to autocomplete.
|
|
editBox.autoCompleteParams = nil;
|
|
return false;
|
|
end
|
|
|
|
function ChatEdit_ParseText(editBox, send, parseIfNoSpaces)
|
|
|
|
local text = editBox:GetText();
|
|
if ( strlen(text) <= 0 ) then
|
|
return;
|
|
end
|
|
|
|
if ( strsub(text, 1, 1) ~= "/" ) then
|
|
return;
|
|
end
|
|
|
|
--Do not bother parsing if there is no space in the message and we aren't sending.
|
|
if ( send ~= 1 and not parseIfNoSpaces and not strfind(text, "%s") ) then
|
|
return;
|
|
end
|
|
|
|
-- If the string is in the format "/cmd blah", command will be "/cmd"
|
|
local command = strmatch(text, "^(/[^%s]+)") or "";
|
|
local msg = "";
|
|
|
|
|
|
if ( command ~= text ) then
|
|
msg = strsub(text, strlen(command) + 2);
|
|
end
|
|
|
|
command = strupper(command);
|
|
|
|
-- Check and see if we've got secure commands to run before we look for chat types or slash commands.
|
|
-- This hash table is prepopulated, unlike the other ones, since nobody can add secure commands. (See line 1205 or thereabouts)
|
|
-- We don't want this code to run unless send is 1, but we need ChatEdit_HandleChatType to run when send is 1 as well, which is why we
|
|
-- didn't just move ChatEdit_HandleChatType inside the send == 0 conditional, which could have also solved the problem with insecure
|
|
-- code having the ability to affect secure commands.
|
|
|
|
if ( send == 1 and hash_SecureCmdList[command] ) then
|
|
hash_SecureCmdList[command](strtrim(msg));
|
|
editBox:AddHistoryLine(text);
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
end
|
|
|
|
-- Handle chat types. No need for a securecall here, since we should be done with anything secure.
|
|
if ( ChatEdit_HandleChatType(editBox, msg, command, send) ) then
|
|
return;
|
|
end
|
|
|
|
if ( send == 0 ) then
|
|
return;
|
|
end
|
|
|
|
-- Check the hash tables for slash commands and emotes to see if we've run this before.
|
|
if ( hash_SlashCmdList[command] ) then
|
|
-- if the code in here changes - change the corresponding code below
|
|
hash_SlashCmdList[command](strtrim(msg), editBox);
|
|
editBox:AddHistoryLine(text);
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
elseif ( hash_EmoteTokenList[command] ) then
|
|
-- if the code in here changes - change the corresponding code below
|
|
DoEmote(hash_EmoteTokenList[command], msg);
|
|
editBox:AddHistoryLine(text);
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
end
|
|
|
|
-- If we didn't have the command in the hash tables, look for it the slow way...
|
|
for index, value in pairs(SlashCmdList) do
|
|
local i = 1;
|
|
local cmdString = _G["SLASH_"..index..i];
|
|
while ( cmdString ) do
|
|
cmdString = strupper(cmdString);
|
|
if ( cmdString == command ) then
|
|
-- if the code in here changes - change the corresponding code above
|
|
hash_SlashCmdList[command] = value; -- add to hash
|
|
value(strtrim(msg), editBox);
|
|
editBox:AddHistoryLine(text);
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
end
|
|
i = i + 1;
|
|
cmdString = _G["SLASH_"..index..i];
|
|
end
|
|
end
|
|
|
|
local i = 1;
|
|
local j = 1;
|
|
local cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
while ( i <= MAXEMOTEINDEX ) do
|
|
if ( cmdString and strupper(cmdString) == command ) then
|
|
local token = _G["EMOTE"..i.."_TOKEN"];
|
|
-- if the code in here changes - change the corresponding code above
|
|
if ( token ) then
|
|
hash_EmoteTokenList[command] = token; -- add to hash
|
|
DoEmote(token, msg);
|
|
end
|
|
editBox:AddHistoryLine(text);
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
end
|
|
j = j + 1;
|
|
cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
if ( not cmdString ) then
|
|
i = i + 1;
|
|
j = 1;
|
|
cmdString = _G["EMOTE"..i.."_CMD"..j];
|
|
end
|
|
end
|
|
|
|
-- Unrecognized chat command, show simple help text
|
|
if ( editBox.chatFrame ) then
|
|
local info = ChatTypeInfo["SYSTEM"];
|
|
editBox.chatFrame:AddMessage(HELP_TEXT_SIMPLE, info.r, info.g, info.b, info.id);
|
|
end
|
|
|
|
-- Reset the chat type and clear the edit box's contents
|
|
ChatEdit_OnEscapePressed(editBox);
|
|
return;
|
|
end
|
|
|
|
local tellTargetExtractionAutoComplete = AUTOCOMPLETE_LIST.ALL;
|
|
function ChatEdit_ExtractTellTarget(editBox, msg)
|
|
-- Grab the string after the slash command
|
|
local target = strmatch(msg, "%s*(.*)");
|
|
|
|
--If we haven't even finished one word, we aren't done.
|
|
if ( not target or not strfind(target, "%s") or (strsub(target, 1, 1) == "|") ) then
|
|
return false;
|
|
end
|
|
|
|
if ( GetAutoCompleteResults(target, tellTargetExtractionAutoComplete.include, tellTargetExtractionAutoComplete.exclude, 1, nil, true) ) then
|
|
--Even if there's a space, we still want to let the person keep typing -- they may be trying to type whatever is in AutoComplete.
|
|
return false;
|
|
end
|
|
|
|
--Keep pulling off everything after the last space until we either have something on the AutoComplete list or only a single word is left.
|
|
while ( strfind(target, "%s") ) do
|
|
--Pull off everything after the last space.
|
|
target = strmatch(target, "(.+)%s+[^%s]*");
|
|
if ( GetAutoCompleteResults(target, tellTargetExtractionAutoComplete.include, tellTargetExtractionAutoComplete.exclude, 1, nil, true) ) then
|
|
break;
|
|
end
|
|
end
|
|
|
|
msg = strsub(msg, strlen(target) + 2);
|
|
|
|
editBox:SetAttribute("tellTarget", target);
|
|
--BN_WHISPER FIXME
|
|
editBox:SetAttribute("chatType", "WHISPER");
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
return true;
|
|
end
|
|
|
|
function ChatEdit_ExtractChannel(editBox, msg)
|
|
local target = strmatch(msg, "%s*([^%s]+)");
|
|
if ( not target ) then
|
|
return;
|
|
end
|
|
|
|
local channelNum, channelName = GetChannelName(target);
|
|
if ( channelNum <= 0 ) then
|
|
return;
|
|
end
|
|
|
|
msg = strsub(msg, strlen(target) + 2);
|
|
|
|
editBox:SetAttribute("channelTarget", channelNum);
|
|
editBox:SetAttribute("chatType", "CHANNEL");
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
end
|
|
|
|
function ChatEdit_ExtractBNConversation(editBox, msg)
|
|
local target = tonumber(strmatch(msg, "%s*(%d+)"));
|
|
if ( not target ) then
|
|
return;
|
|
end
|
|
|
|
local conversationType = BNGetConversationInfo(target);
|
|
if ( not conversationType ) then
|
|
return;
|
|
end
|
|
|
|
msg = strsub(msg, strlen(tostring(target)) + 2);
|
|
|
|
editBox:SetAttribute("channelTarget", target);
|
|
editBox:SetAttribute("chatType", "BN_CONVERSATION");
|
|
editBox:SetText(msg);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
end
|
|
|
|
-- Chat menu functions
|
|
function ChatMenu_SetChatType(chatFrame, type)
|
|
local editBox = ChatFrame_OpenChat("");
|
|
editBox:SetAttribute("chatType", type);
|
|
ChatEdit_UpdateHeader(editBox);
|
|
end
|
|
|
|
function ChatMenu_Say(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "SAY");
|
|
end
|
|
|
|
function ChatMenu_Party(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "PARTY");
|
|
end
|
|
|
|
function ChatMenu_Raid(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "RAID");
|
|
end
|
|
|
|
function ChatMenu_Battleground(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "BATTLEGROUND");
|
|
end
|
|
|
|
function ChatMenu_Guild(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "GUILD");
|
|
end
|
|
|
|
function ChatMenu_Yell(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "YELL");
|
|
end
|
|
|
|
function ChatMenu_Whisper(self)
|
|
local editBox = ChatFrame_OpenChat(SLASH_WHISPER1.." ", chatFrame);
|
|
editBox:SetText(SLASH_WHISPER1.." "..editBox:GetText());
|
|
end
|
|
|
|
function ChatMenu_Emote(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "EMOTE");
|
|
end
|
|
|
|
function ChatMenu_Reply(self)
|
|
ChatFrame_ReplyTell();
|
|
end
|
|
|
|
function ChatMenu_VoiceMacro(self)
|
|
ChatMenu_SetChatType(self:GetParent().chatFrame, "YELL");
|
|
end
|
|
|
|
function ChatMenu_OnLoad(self)
|
|
self.chatFrame = DEFAULT_CHAT_FRAME;
|
|
|
|
UIMenu_Initialize(self);
|
|
UIMenu_AddButton(self, SAY_MESSAGE, SLASH_SAY1, ChatMenu_Say);
|
|
UIMenu_AddButton(self, PARTY_MESSAGE, SLASH_PARTY1, ChatMenu_Party);
|
|
UIMenu_AddButton(self, RAID_MESSAGE, SLASH_RAID1, ChatMenu_Raid);
|
|
UIMenu_AddButton(self, BATTLEGROUND_MESSAGE, SLASH_BATTLEGROUND1, ChatMenu_Battleground);
|
|
UIMenu_AddButton(self, GUILD_MESSAGE, SLASH_GUILD1, ChatMenu_Guild);
|
|
UIMenu_AddButton(self, YELL_MESSAGE, SLASH_YELL1, ChatMenu_Yell);
|
|
UIMenu_AddButton(self, WHISPER_MESSAGE, SLASH_WHISPER1, ChatMenu_Whisper);
|
|
UIMenu_AddButton(self, EMOTE_MESSAGE, SLASH_EMOTE1, ChatMenu_Emote, "EmoteMenu");
|
|
UIMenu_AddButton(self, REPLY_MESSAGE, SLASH_REPLY1, ChatMenu_Reply);
|
|
UIMenu_AddButton(self, LANGUAGE, nil, nil, "LanguageMenu");
|
|
UIMenu_AddButton(self, VOICEMACRO_LABEL, nil, nil, "VoiceMacroMenu");
|
|
UIMenu_AddButton(self, MACRO, SLASH_MACRO1, ShowMacroFrame);
|
|
UIMenu_AutoSize(self);
|
|
end
|
|
|
|
function ChatMenu_OnShow(self)
|
|
UIMenu_OnShow(self);
|
|
EmoteMenu:Hide();
|
|
LanguageMenu:Hide();
|
|
VoiceMacroMenu:Hide();
|
|
|
|
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
|
|
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
|
|
end
|
|
|
|
function EmoteMenu_Click(self)
|
|
DoEmote(EmoteList[self:GetID()]);
|
|
ChatMenu:Hide();
|
|
end
|
|
|
|
function TextEmoteSort(token1, token2)
|
|
local i = 1;
|
|
local string1, string2;
|
|
local token = _G["EMOTE"..i.."_TOKEN"];
|
|
while ( token ) do
|
|
if ( token == token1 ) then
|
|
string1 = _G["EMOTE"..i.."_CMD1"];
|
|
if ( string2 ) then
|
|
break;
|
|
end
|
|
end
|
|
if ( token == token2 ) then
|
|
string2 = _G["EMOTE"..i.."_CMD1"];
|
|
if ( string1 ) then
|
|
break;
|
|
end
|
|
end
|
|
i = i + 1;
|
|
token = _G["EMOTE"..i.."_TOKEN"];
|
|
end
|
|
return string1 < string2;
|
|
end
|
|
|
|
function OnMenuLoad(self,list,func)
|
|
sort(list, TextEmoteSort);
|
|
UIMenu_Initialize(self);
|
|
self.parentMenu = "ChatMenu";
|
|
for index, value in pairs(list) do
|
|
local i = 1;
|
|
local token = _G["EMOTE"..i.."_TOKEN"];
|
|
while ( token ) do
|
|
if ( token == value ) then
|
|
break;
|
|
end
|
|
i = i + 1;
|
|
token = _G["EMOTE"..i.."_TOKEN"];
|
|
end
|
|
local label = _G["EMOTE"..i.."_CMD1"];
|
|
if ( not label ) then
|
|
label = value;
|
|
end
|
|
UIMenu_AddButton(self, label, nil, func);
|
|
end
|
|
UIMenu_AutoSize(self);
|
|
end
|
|
|
|
function EmoteMenu_OnLoad(self)
|
|
OnMenuLoad(self, EmoteList, EmoteMenu_Click);
|
|
end
|
|
|
|
function LanguageMenu_OnLoad(self)
|
|
UIMenu_Initialize(self);
|
|
self.parentMenu = "ChatMenu";
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD");
|
|
self:RegisterEvent("LANGUAGE_LIST_CHANGED");
|
|
end
|
|
|
|
function VoiceMacroMenu_Click(self)
|
|
DoEmote(TextEmoteSpeechList[self:GetID()]);
|
|
ChatMenu:Hide();
|
|
end
|
|
|
|
function VoiceMacroMenu_OnLoad(self)
|
|
OnMenuLoad(self, TextEmoteSpeechList, VoiceMacroMenu_Click);
|
|
end
|
|
|
|
function LanguageMenu_OnEvent(self, event, ...)
|
|
if ( event == "PLAYER_ENTERING_WORLD" ) then
|
|
self:Hide();
|
|
UIMenu_Initialize(self);
|
|
LanguageMenu_LoadLanguages(self);
|
|
self:GetParent().chatFrame.editBox.language = GetDefaultLanguage();
|
|
return;
|
|
end
|
|
if ( event == "LANGUAGE_LIST_CHANGED" ) then
|
|
self:Hide();
|
|
UIMenu_Initialize(self);
|
|
LanguageMenu_LoadLanguages(self);
|
|
return;
|
|
end
|
|
end
|
|
|
|
function LanguageMenu_LoadLanguages(self)
|
|
local numLanguages = GetNumLanguages();
|
|
local i;
|
|
local editBoxLanguage = self:GetParent().chatFrame.editBox.language;
|
|
local languageKnown = false;
|
|
for i = 1, numLanguages, 1 do
|
|
local language = GetLanguageByIndex(i);
|
|
UIMenu_AddButton(self, language, nil, LanguageMenu_Click);
|
|
if ( language == editBoxLanguage ) then
|
|
languageKnown = true;
|
|
end
|
|
end
|
|
|
|
if ( languageKnown ~= true ) then
|
|
self:GetParent().chatFrame.editBox.language = GetLanguageByIndex(1);
|
|
end
|
|
|
|
UIMenu_AutoSize(self);
|
|
end
|
|
|
|
function LanguageMenu_Click(self)
|
|
self:GetParent():GetParent().chatFrame.editBox.language = GetLanguageByIndex(self:GetID());
|
|
ChatMenu:Hide();
|
|
end
|
|
|
|
function ChatFrame_ActivateCombatMessages(chatFrame)
|
|
ChatFrame_AddMessageGroup(chatFrame, "OPENING");
|
|
ChatFrame_AddMessageGroup(chatFrame, "TRADESKILLS");
|
|
ChatFrame_AddMessageGroup(chatFrame, "PET_INFO");
|
|
ChatFrame_AddMessageGroup(chatFrame, "COMBAT_MISC_INFO");
|
|
ChatFrame_AddMessageGroup(chatFrame, "COMBAT_XP_GAIN");
|
|
ChatFrame_AddMessageGroup(chatFrame, "COMBAT_HONOR_GAIN");
|
|
ChatFrame_AddMessageGroup(chatFrame, "COMBAT_FACTION_CHANGE");
|
|
end
|
|
|
|
function ChatChannelDropDown_Show(chatFrame, chatType, chatTarget, chatName)
|
|
HideDropDownMenu(1);
|
|
ChatChannelDropDown.initialize = ChatChannelDropDown_Initialize;
|
|
ChatChannelDropDown.displayMode = "MENU";
|
|
ChatChannelDropDown.chatType = chatType;
|
|
ChatChannelDropDown.chatTarget = chatTarget;
|
|
ChatChannelDropDown.chatName = chatName;
|
|
ChatChannelDropDown.chatFrame = chatFrame;
|
|
ToggleDropDownMenu(1, nil, ChatChannelDropDown, "cursor");
|
|
end
|
|
|
|
function ChatChannelDropDown_Initialize()
|
|
local frame = ChatChannelDropDown;
|
|
|
|
local info = UIDropDownMenu_CreateInfo();
|
|
|
|
info.text = frame.chatName;
|
|
info.notCheckable = true;
|
|
info.isTitle = true;
|
|
UIDropDownMenu_AddButton(info, 1);
|
|
|
|
info = UIDropDownMenu_CreateInfo();
|
|
|
|
if ( frame.chatType ~= "BN_CONVERSATION" or (FCFManager_GetNumDedicatedFrames(frame.chatType, frame.chatTarget) == 0)) then
|
|
if ( frame.chatType == "BN_CONVERSATION" ) then
|
|
info.text = MOVE_TO_CONVERSATION_WINDOW;
|
|
else
|
|
info.text = MOVE_TO_NEW_WINDOW;
|
|
end
|
|
info.notCheckable = 1;
|
|
info.func = ChatChannelDropDown_PopOutChat;
|
|
info.arg1 = frame.chatType;
|
|
info.arg2 = frame.chatTarget;
|
|
|
|
if ( frame.chatType ~= "BN_CONVERSATION" and FCF_GetNumActiveChatFrames() == NUM_CHAT_WINDOWS ) then
|
|
info.disabled = 1;
|
|
end
|
|
|
|
UIDropDownMenu_AddButton(info);
|
|
end
|
|
|
|
if ( frame.chatType == "BN_CONVERSATION" ) then
|
|
info = UIDropDownMenu_CreateInfo();
|
|
info.text = INVITE_FRIEND_TO_CONVERSATION;
|
|
info.notCheckable = 1;
|
|
info.func = ChatChannelDropDown_InviteToConversation;
|
|
info.arg1 = frame.chatType;
|
|
info.arg2 = frame.chatTarget;
|
|
UIDropDownMenu_AddButton(info);
|
|
|
|
info = UIDropDownMenu_CreateInfo();
|
|
info.text = LEAVE_CONVERSATION;
|
|
info.notCheckable = 1;
|
|
info.func = ChatChannelDropDown_LeaveConversation;
|
|
info.arg1 = frame.chatType;
|
|
info.arg2 = frame.chatTarget;
|
|
UIDropDownMenu_AddButton(info);
|
|
end
|
|
end
|
|
|
|
function ChatChannelDropDown_InviteToConversation(self, chatType, chatTarget)
|
|
if ( chatType == "BN_CONVERSATION" ) then
|
|
BNConversationInvite_SelectPlayers(chatTarget);
|
|
end
|
|
end
|
|
|
|
function ChatChannelDropDown_LeaveConversation(self, chatType, chatTarget)
|
|
BNLeaveConversation(chatTarget);
|
|
end
|
|
|
|
function ChatChannelDropDown_PopOutChat(self, chatType, chatTarget)
|
|
local sourceChatFrame = ChatChannelDropDown.chatFrame;
|
|
|
|
if ( chatType == "BN_CONVERSATION" ) then
|
|
FCF_OpenTemporaryWindow(chatType, chatTarget, sourceChatFrame, true);
|
|
else
|
|
local windowName;
|
|
if ( chatType == "CHANNEL" ) then
|
|
windowName = Chat_GetChannelShortcutName(chatTarget);
|
|
else
|
|
windowName = _G[chatType];
|
|
end
|
|
local frame = FCF_OpenNewWindow(windowName);
|
|
FCF_CopyChatSettings(frame, sourceChatFrame);
|
|
|
|
ChatFrame_RemoveAllMessageGroups(frame);
|
|
ChatFrame_RemoveAllChannels(frame);
|
|
ChatFrame_ReceiveAllPrivateMessages(frame);
|
|
ChatFrame_ReceiveAllBNConversations(frame);
|
|
|
|
ChatFrame_AddMessageGroup(frame, chatType);
|
|
|
|
if ( CHAT_CATEGORY_LIST[chatType] ) then
|
|
for _, chat in pairs(CHAT_CATEGORY_LIST[chatType]) do
|
|
ChatFrame_AddMessageGroup(frame, chat);
|
|
end
|
|
end
|
|
|
|
frame.editBox:SetAttribute("chatType", chatType);
|
|
frame.editBox:SetAttribute("stickyType", chatType);
|
|
|
|
if ( chatType == "CHANNEL" ) then
|
|
frame.editBox:SetAttribute("channelTarget", chatTarget);
|
|
ChatFrame_AddChannel(frame, Chat_GetChannelShortcutName(chatTarget));
|
|
end
|
|
|
|
--Remove the things popped out from the source chat frame.
|
|
if ( chatType == "CHANNEL" ) then
|
|
ChatFrame_RemoveChannel(sourceChatFrame, Chat_GetChannelShortcutName(chatTarget));
|
|
else
|
|
ChatFrame_RemoveMessageGroup(sourceChatFrame, chatType);
|
|
if ( CHAT_CATEGORY_LIST[chatType] ) then
|
|
for _, chat in pairs(CHAT_CATEGORY_LIST[chatType]) do
|
|
ChatFrame_RemoveMessageGroup(sourceChatFrame, chat);
|
|
end
|
|
end
|
|
end
|
|
|
|
--Copy over messages
|
|
local accessID = ChatHistory_GetAccessID(chatType, chatTarget);
|
|
for i = 1, sourceChatFrame:GetNumMessages(accessID) do
|
|
local text, accessID, lineID, extraData = sourceChatFrame:GetMessageInfo(i, accessID);
|
|
local cType, cTarget = ChatHistory_GetChatType(extraData);
|
|
|
|
local info = ChatTypeInfo[cType];
|
|
frame:AddMessage(text, info.r, info.g, info.b, lineID, false, accessID, extraData);
|
|
end
|
|
--Remove the messages from the old frame.
|
|
sourceChatFrame:RemoveMessagesByAccessID(accessID);
|
|
end
|
|
end
|
|
|
|
function Chat_GetChannelShortcutName(index)
|
|
local _, name = GetChannelName(index);
|
|
name = strtrim(name:match("([^%-]+)"));
|
|
return name;
|
|
end
|
|
|
|
function ChatChannelDropDown_PopInChat(self, chatType, chatTarget)
|
|
--PopOutChat_PopInChat(chatType, chatTarget);
|
|
end
|
|
|
|
function Chat_GetColoredChatName(chatType, chatTarget)
|
|
if ( chatType == "CHANNEL" ) then
|
|
local info = ChatTypeInfo["CHANNEL"..chatTarget];
|
|
local colorString = format("|cff%02x%02x%02x", info.r * 255, info.g * 255, info.b * 255);
|
|
local chanNum, channelName = GetChannelName(chatTarget);
|
|
return format("%s|Hchannel:channel:%d|h[%d. %s]|h", colorString, chanNum, chanNum, gsub(channelName, "%s%-%s.*", "")); --The gsub removes zone-specific markings (e.g. "General - Ironforge" to "General")
|
|
elseif ( chatType == "WHISPER" ) then
|
|
local info = ChatTypeInfo["WHISPER"];
|
|
local colorString = format("|cff%02x%02x%02x", info.r * 255, info.g * 255, info.b * 255);
|
|
return format("%s[%s] |Hplayer:%3$s|h[%3$s]|h|r", colorString, _G[chatType], chatTarget);
|
|
else
|
|
local info = ChatTypeInfo[chatType];
|
|
local colorString = format("|cff%02x%02x%02x", info.r * 255, info.g * 255, info.b * 255);
|
|
return format("%s|Hchannel:%s|h[%s]|h|r", colorString, chatType, _G[chatType]);
|
|
end
|
|
end |