--初始设置
RaidAlerter_SET = {
OnOff = true,						--启用警报
RAIDMODE_MAX_GROUP = 5,				--团队模式
Party_Alerter = true,				--5人小队
OnlySelfCHAN = false,				--仅本机
OnlySelfSCR = false,				--仅本屏
SoundAlert = true,					--音效
TextMShow_OnOff = true,				--状态条
AF_Scale = 1,						--缩放比例
MAXRAM = 416,						--内存清理
BossHealthPecentOnOff = true,		--Boss血量
BossHealthPecent = 10,				--通报上限
BossKill = true,					--最后一击
TANK_DangerHealth = true,			--TANK血量
TANK_DangerHealthPecent = 30,		--危急上限
TANK_Death = true,					--TANK阵亡
TANK_ShieldWall = true,				--盾墙
TANK_LastStand = true,				--破釜沉舟
TANK_ShieldReflection = true,		--法术反射
ScrMsg = true,						--屏幕讯息
THREATCheck = true,					--仇恨提示
ToTCheck = true,					--目标提示
OT_OnOff = true,					--OT通告
OTM_OnOff = false,					--OT密语
OTMShow_OnOff = false,				--显示发送
Hunter_Mark = false,				--猎人标记
Hunter_Misdirection = true,			--猎人误导
Hunter_Shot = true,					--猎人宁神
TANK_Taunt = true,					--抵抗嘲讽
RES_DispelMagic = true,				--抵抗驱散
RES_Polymorph = true,				--抵抗变形
RES_MagicBreak = true,				--抵抗反制
RES_BuffStolen = true,				--抵抗法偷
Check_Poly = true,					--被控制
PolyDispel = true,					--解除控制
Break_Poly = true,					--打破控制
Dispel_Magic = true,				--魔法驱散
BuffStolen = true,					--法术偷取
Break_Magic = true,					--魔法打断
Check_Gem = true,					--灵魂绑定
Paladin_Intervention = true,		--神圣干涉
Check_Death_AtCombatEnd = true,		--阵亡通报
Nef_PriestDown = false,				--堕落(NEF)
Nef_TANKPoly = false,				--变形(NEF)
TAQ_Twin_AOEAdd = false,			--Add(双子)
ShowSysInfo = false,				--显示占用
cameraMax = false,					--增大镜头
RaidSpell = true,					--团队物品
Check_Cooking = true,				--进食充分
Check_Cooking_Whisper = false,		--未进食密语
Check_Inner_Fire = true,			--心灵之火
Check_Inner_Fire_Whisper = false,	--心灵之火密语
};

RaidAlerter = {};
RAL = {};
RaidAlerter_UINameEN = "RaidAlerter";
RaidAlerter_Version = GetAddOnMetadata("RaidAlerter", "Version");
RaidAlerter_MainLabel = RaidAlerter_UINameEN.." |cFFDDDDDDv"..RaidAlerter_Version.."|r";

BINDING_HEADER_RaidAlerter_BINDING_TopTitle = RaidAlerter_UINameEN..RaidAlerter_UIName;
BINDING_NAME_RaidAlerter_BINDING_Title1 = RAL_TEXT_BINDING_1;
BINDING_NAME_RaidAlerter_BINDING_Title2 = RAL_TEXT_BINDING_2;
BINDING_NAME_RaidAlerter_BINDING_Title3 = RAL_TEXT_BINDING_3;

RaidAlerter_SYNC_SELECT_TMPPRA = 0;
RaidAlerter_SYNC_SELECT_TOME = 1;
RaidAlerter_SYNC_SELECT_SETTOME = 0;
RaidAlerter_SYNC_SELECT_NAME = "|cFFFF0000"..RAL_TEXT_SYNC_SELECT_NONE.."|r";
RaidAlerter_SYNC_SELECT_NAME_MSG = 0;
RaidAlerter_SYNC_CHECKVER = 0;
RaidAlerter_SYNC_CHECKVERCOUNT = 0;
RaidAlerter_SYNC_VerPOINT = 20;
RaidAlerter_SYNC_MyStatus = "FFF";
RaidAlerter_SYNC_MyStatus_Last = "TTT";

RAL_BlzTanks = {};
RAL_Tanks = {};

RAL_UIMSG_TIMELIMIT = 0.5;	--Debug
RAL_DEBUG = false;

RaidAlerter_Alerter_System	= {
	["lasticon"]	= "0",
	["maxcn"]	= 0,
	["stcn"]	= 0,
	["stcntmp"]	= 0,
	["ctmp"]	= 0,
	["counttmp"]	= 0,
	["BossHealthPecentTMP"]	= 100,
	};

RaidAlerter_SOUND_DATA = {
	[1]	= "Sound\\Doodad\\BellTollNightElf.wav",
	[2]	= "Sound\\interface\\AuctionWindowOpen.wav",
	[3]	= "Sound\\Doodad\\BellTollAlliance.wav",
	[4]	= "Sound\\Spells\\SeepingGaseous_Fel_Nova.wav",
	[5]	= "Sound\\Spells\\PVPFlagTaken.wav",
};

RaidAlerter_Alerter_dangerHealth = {};
RaidAlerter_Alerter_BeControled = {};
RaidAlerter_Alerter_ErrorCure = {};
for i = -4, 40 do
	local unit = "";
	if i < 0 then
		unit = "party"..abs(i);
	elseif i == 0 then
		unit = "player";
	else
		unit = "raid"..i;
	end
	RaidAlerter_Alerter_dangerHealth[unit] = 0;
	RaidAlerter_Alerter_BeControled[unit] = 0;
	RaidAlerter_Alerter_ErrorCure[unit] = 0;
end

local TankingPlayer="";
local RaidAlerter_Raid_DeadMsg = false;
local RaidAlerter_RaidAllInCombat = false;
local RaidAlerter_RaidCombatEnd_CheckRAM = false;
local ManaPercent=0;
local CureManaPercent=0;
local DeadRaidmembers=0;
local OffLineRaidmembers=0;
local RaidNum = 0;
local RaidNumALL = 0;
local Attack_Frame_UPDATE_FREQ = 2;
local RaidAlerter_MT_Dead = {};
local GemName={};
local RaidAlerter_Check_CPU_DATA=0;
local RaidAlerter_Check_RAM_DATA=0;
local TempUnit1, TempUnit2, TempUnit3;
local Timer_NOW, Timer_START;
local subgroup = 9999;
local RaidAlerter_ChkMyHP = false;
local RaidAlerter_MyDangerHP = 30;
local RaidAlerter_BattleTime_This = 0;
local RaidAlerter_BattleTime_Last = 0;
local RaidAlerter_BattleTime_Record = false;
local AlertChan = "RAID";
local AlertWChan = "RAID_WARNING";
local SameIDPolyBreakCount = 0;
local LastPolyBreakID;
local ICONTEXT_unit;
local ICONTEXT_icon;
local ICONTEXT_icontext = "";
local TeamLevel = UnitLevel("player");
local RaidHPMAXAVG = UnitHealthMax("player");
local PartyHPMAXAVG = UnitHealthMax("player");
local BossHPMin = 999999999;
local DangerUnitHPMin = 666666666;
local MyLastThreatState = 0;
local FouTarISME = false;
local TarTarISME = false;
local ImTANK = false;
local RosterChanged = true;
local RAL_LootMethod 	= {
	["freeforall"]	= RAL_TEXT_LOOT_FREE_FOR_ALL,
	["roundrobin"]	= RAL_TEXT_LOOT_ROUND_ROBIN,
	["master"]	= RAL_TEXT_LOOT_MASTER_LOOTER,
	["group"]	= RAL_TEXT_LOOT_GROUP_LOOT,
	["needbeforegreed"]	= RAL_TEXT_LOOT_NEED_BEFORE_GREED,
	};
local RAL_LootMethod_SYS 	= {
	["freeforall"]	= LOOT_FREE_FOR_ALL,
	["roundrobin"]	= LOOT_ROUND_ROBIN,
	["master"]	= LOOT_MASTER_LOOTER,
	["group"]	= LOOT_GROUP_LOOT,
	["needbeforegreed"]	= LOOT_NEED_BEFORE_GREED,
	};
local RAL_NextUpdateTime = 0;
local RAL_UIMSG_PREFIX;
local RAL_UIMSG_MSG;
local RAL_UIMSG_CHAN;
local RAL_UIMSG_SENDED = true;
local GameVER = select(4,GetBuildInfo());
local SysDif = 1;
local EQDif = 1;
local DifText = "";
local instanceType, difficulty, maxPlayers, playerDifficulty, isDynamicInstance;
local COOKFOODDUR = 0;

--3.2-4.0过渡
local UnitMana = UnitMana;
local UnitManaMax = UnitManaMax;
if GameVER >= 40000 then
	UnitMana = UnitPower;
	UnitManaMax = UnitPowerMax;
end

--事件注册
local RaidAlerter_EVENT_LIST = {
	"PLAYER_ENTERING_WORLD",
	"ADDON_LOADED",
	"CHAT_MSG_ADDON",
	"CHAT_MSG_WHISPER_INFORM",
	"CHAT_MSG_WHISPER",
	"COMBAT_LOG_EVENT_UNFILTERED",
	"UNIT_THREAT_SITUATION_UPDATE",
	"PLAYER_REGEN_ENABLED",
	"RAID_ROSTER_UPDATE",
	"PARTY_MEMBERS_CHANGED",
	"UPDATE_INSTANCE_INFO",
	"PLAYER_DIFFICULTY_CHANGED",
	"ZONE_CHANGED_NEW_AREA",
	};

--Oldhand原版本的CHAT_MSG设定
--[[
local RaidAlerter_EVENT_LIST = {
	"CHAT_MSG_WHISPER_INFORM",
	"CHAT_MSG_SPELL_SELF_DAMAGE",
	"CHAT_MSG_SPELL_FAILED_LOCALPLAYER",
	"CHAT_MSG_SPELL_PARTY_DAMAGE",
	"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
	"CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
	"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
	"CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
	};
]]


--Terry@bf
function BF_RaidAlerter_LoadPosition(self)
	self:ClearAllPoints();
	self:SetPoint(unpack(RaidAlerter_SET_AttackFramePosition))
end


function BF_RaidAlerter_SavePosition(self)
	local _point,rel,relp,xo,yo=self:GetPoint()
	RaidAlerter_SET_AttackFramePosition={_point,"UIParent",relp,xo,yo}
end


function RaidAlerter_OnEnter(self,action)
	GameTooltip:SetOwner(RaidAlerter_Attack_Frame, "ANCHOR_NONE");
	GameTooltip:SetText(RaidAlerter_UINameEN..RaidAlerter_UIName);
	GameTooltip:SetPoint("TOPLEFT", RaidAlerter_Attack_Frame, "BOTTOMLEFT", 0, 4);
	if GetNumRaidMembers()>0 then
		GameTooltip:AddLine(RAL_TEXT_TIP_35..": "..RaidAlerter_GetCurrentDifficulty(3));
		GameTooltip:AddLine(RaidAlerter_LootMethodTEXT(1));
		if RaidAlerter_BattleTime_Record then
			local m, s = RaidAlerter_SecondsToTime(RaidAlerter_GetTimer("BattleTime_Record"));
			if m == 0 then
				GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_1.." "..string.format(RAL_TEXT_TIP_4,"|cFFFFFFFF"..s.."|r"));
			else
				GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_1.." "..string.format(RAL_TEXT_TIP_5,"|cFFFFFFFF"..m.."|r","|cFFFFFFFF"..s.."|r"));
			end
		else
			if RaidAlerter_BattleTime_This == 0 then
				GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_2.." |cFFFFFFFF"..RAL_TEXT_NUL);
			else
				local m, s = RaidAlerter_SecondsToTime(RaidAlerter_BattleTime_This);
				if m == 0 then
					GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_2.." "..string.format(RAL_TEXT_TIP_4,"|cFFFFFFFF"..s.."|r"));
				else
					GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_2.." "..string.format(RAL_TEXT_TIP_5,"|cFFFFFFFF"..m.."|r","|cFFFFFFFF"..s.."|r"));
				end
			end
		end
		if RaidAlerter_BattleTime_Last == 0 then
			GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_3.." |cFFCCCCCC"..RAL_TEXT_NUL);
		else
			local m, s = RaidAlerter_SecondsToTime(RaidAlerter_BattleTime_Last);
			if m == 0 then
				GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_3.." "..string.format(RAL_TEXT_TIP_4,"|cFFCCCCCC"..s.."|r"));
			else
				GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_3.." "..string.format(RAL_TEXT_TIP_5,"|cFFCCCCCC"..m.."|r","|cFFCCCCCC"..s.."|r"));
			end
		end
		GameTooltip:AddLine(RaidAlerter_CheckPlayer("tip"));
		GameTooltip:AddLine(RaidAlerter_CheckPvP("tip"));
		GameTooltip:AddLine(RaidAlerter_CheckFlask("","tip"));
		GameTooltip:AddLine(RaidAlerter_CheckFlask("all","tip"));
		if not RaidAlerter_RaidAllInCombat then
			RaidAlerter_Check_SoulGemOn();
		end
		if #GemName==0 then
			GameTooltip:AddLine("|cFF99CCFF"..string.format(RAL_TEXT_TIP_6,"|cFFFF0000"..#GemName.."|cFF99CCFF").."|r");
		elseif #GemName<3 then
			GameTooltip:AddLine("|cFF99CCFF"..string.format(RAL_TEXT_TIP_6,"|cFFFFFFFF"..#GemName.."|cFF99CCFF")..": "..RaidAlerter_GetGemOnNames(1));
		else
			GameTooltip:AddLine("|cFF99CCFF"..string.format(RAL_TEXT_TIP_6,"|cFFFFFFFF"..#GemName.."|cFF99CCFF").."|r");
		end
		GameTooltip:AddLine(" ");
	elseif GetNumPartyMembers()>0 then
		GameTooltip:AddLine(RAL_TEXT_TIP_35..": "..RaidAlerter_GetCurrentDifficulty(3));
		GameTooltip:AddLine(RaidAlerter_LootMethodTEXT(1));
		GameTooltip:AddLine(RaidAlerter_CheckPlayer("tip"));
		GameTooltip:AddLine(" ");
	end

	GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_7.."|r");
	if IsControlKeyDown() then
		GameTooltip:AddLine(RAL_TEXT_TIP_8..": |cFFFFFFFF"..RAL_TEXT_TIP_14);
		GameTooltip:AddLine(RAL_TEXT_TIP_9..": |cFFFFFFFF"..RAL_TEXT_TIP_15);
		GameTooltip:AddLine(RAL_TEXT_TIP_10..": |cFFFFFFFF"..RAL_TEXT_TIP_16);
		GameTooltip:AddLine(RAL_TEXT_TIP_11.."+"..RAL_TEXT_TIP_8..": |cFFFFFFFF"..RAL_TEXT_TIP_17);
		GameTooltip:AddLine(RAL_TEXT_TIP_11.."+"..RAL_TEXT_TIP_9..": |cFFFFFFFF"..RAL_TEXT_TIP_18);
		GameTooltip:AddLine(RAL_TEXT_TIP_12.."+"..RAL_TEXT_TIP_8..": |cFFFFFFFF"..RAL_TEXT_TIP_19);
		GameTooltip:AddLine(RAL_TEXT_TIP_12.."+"..RAL_TEXT_TIP_9..": |cFFFFFFFF"..RAL_TEXT_TIP_20);
		GameTooltip:AddLine(RAL_TEXT_TIP_13.."+"..RAL_TEXT_TIP_8..": |cFFFFFFFF"..RAL_TEXT_TIP_21);
		GameTooltip:AddLine(RAL_TEXT_TIP_13.."+"..RAL_TEXT_TIP_9..": |cFFFFFFFF"..RAL_TEXT_TIP_22);
		GameTooltip:AddLine(RAL_TEXT_TIP_11.."+"..RAL_TEXT_TIP_12.."+"..RAL_TEXT_TIP_8..": |cFFFFFFFF"..RAL_TEXT_TIP_23);
	else
		GameTooltip:AddLine("|cFFFFFFFF"..RAL_TEXT_TIP_24);
	end
--显示系统资源占用。调试用
	if RaidAlerter_SET.ShowSysInfo then
		GameTooltip:AddLine(" ");
		GameTooltip:AddLine("|cFF00FF00"..RAL_TEXT_TIP_25.."|r");
		GameTooltip:AddLine(RaidAlerter_Check_RAM_CPU("tip"));
	end

--	GameTooltipTextLeft1:SetTextColor(1, 1, 1);
	GameTooltip:Show();
end

function RaidAlerter_OnLoad(self)
	for K,valueB in pairs(RaidAlerter_EVENT_LIST) do
		self:RegisterEvent(valueB);
	end
	SLASH_RaidAlerter1 = "/raidalerter";
	SLASH_RaidAlerter2 = "/ral";
	SlashCmdList["RaidAlerter"] = function(msg)
		RaidAlerter_SlashCommand(msg);
	end
	RaidAlerter_SET_AttackFramePosition= RaidAlerter_SET_AttackFramePosition or {"TOP","UIParent","TOP",20,-12}

end

function RaidAlerter_SlashCommand(msg)
	msg = string.lower(msg);
	if ( not msg or msg == "") then
		RaidAlerter_Option_MainFrame_Show(self);
		return;
	elseif ( msg == "help" or msg == "?") then
		RaidAlerter.AddMsg("|cFF8000FF"..RaidAlerter_UINameEN.."|cFFFFFFFF"..RaidAlerter_UIName.." - |cFF5588FF"..RAL_TEXT_CMD_1..":", 1);
		RaidAlerter.AddMsg("/raidalerter "..RAL_TEXT_CMD_2.." /ral  |cFF5588FF"..RAL_TEXT_CMD_3, 1);
		RaidAlerter.AddMsg("/ral help "..RAL_TEXT_CMD_2.." /ral ?  |cFF5588FF"..RAL_TEXT_CMD_4, 1);
		RaidAlerter.AddMsg("/ral on|off  |cFF5588FF"..RAL_TEXT_CMD_5, 1);
--		RaidAlerter.AddMsg("/ral pa  |cFF5588FF"..RAL_TEXT_CMD_6, 1);
--		RaidAlerter.AddMsg("/ral ot  |cFF5588FF"..RAL_TEXT_CMD_7, 1);
--		RaidAlerter.AddMsg("/ral otm  |cFF5588FF"..RAL_TEXT_CMD_8, 1);
--		RaidAlerter.AddMsg("/ral otmshow  |cFF5588FF"..RAL_TEXT_CMD_9, 1);
--		RaidAlerter.AddMsg("/ral mark  |cFF5588FF"..RAL_TEXT_CMD_10, 1);
--		RaidAlerter.AddMsg("/ral show  |cFF5588FF"..RAL_TEXT_CMD_11, 1);
--		RaidAlerter.AddMsg("/ral resetshow  |cFF5588FF"..RAL_TEXT_CMD_12, 1);
--		RaidAlerter.AddMsg("/ral cp  |cFF5588FF"..RAL_TEXT_CMD_13, 1);
--		RaidAlerter.AddMsg("/ral pvp  |cFF5588FF"..RAL_TEXT_CMD_14, 1);
--		RaidAlerter.AddMsg("/ral gem  |cFF5588FF"..RAL_TEXT_CMD_15, 1);
		RaidAlerter.AddMsg("/ral hjjc "..RAL_TEXT_CMD_2.." /ral cb |cFF5588FF"..RAL_TEXT_CMD_16, 1);
		RaidAlerter.AddMsg("/ral tc "..RAL_TEXT_CMD_17.." |cFF5588FF"..RAL_TEXT_CMD_18, 1);
		RaidAlerter.AddMsg("/ral myhp  |cFF5588FF"..RAL_TEXT_CMD_19, 1);
		RaidAlerter.AddMsg("/ral showsysinfo  |cFF5588FF"..RAL_TEXT_CMD_20, 1);
		RaidAlerter.AddMsg("/ral cpustart  |cFF5588FF"..RAL_TEXT_CMD_21.." |cFFFF0000"..RAL_TEXT_CMD_22, 1);
		RaidAlerter.AddMsg("/ral cpustop  |cFF5588FF"..RAL_TEXT_CMD_23.." |cFFFF0000"..RAL_TEXT_CMD_22, 1);
--		RaidAlerter.AddMsg("/ral ramreset  |cFF5588FF"..RAL_TEXT_CMD_24, 1);
--		RaidAlerter.AddMsg("/ral reset  |cFF5588FF"..RAL_TEXT_CMD_25, 1);
		RaidAlerter.AddMsg("/ral status  |cFF5588FF"..RAL_TEXT_CMD_26, 1);
		return;
	end

	local cmd, param = msg:match("^([%w%-]+)%s*(.*)$");
	if ( cmd == "on" ) then
		RaidAlerter_SET_FUNC_OnOff(1);
	elseif ( cmd == "off" ) then
		RaidAlerter_SET_FUNC_OnOff(0);
	elseif ( cmd == "pa" ) then
		RaidAlerter_SET_FUNC_Party_Alerter("OnOff");
	elseif ( cmd == "ot" ) then
		RaidAlerter_SET_FUNC_OT_OnOff("OnOff");
	elseif ( cmd == "otm" ) then
		RaidAlerter_SET_FUNC_OTM_OnOff("OnOff");
	elseif ( cmd == "otmshow" ) then
		RaidAlerter_SET_FUNC_OTMShow_OnOff("OnOff");
	elseif ( cmd == "mark" ) then
		RaidAlerter_SET_FUNC_Hunter_Mark("OnOff");
	elseif ( cmd == "show" ) then
		RaidAlerter_SET_FUNC_TextMShow_OnOff("OnOff");
	elseif ( cmd == "resetshow" ) then
		RaidAlerter_SET_FUNC_TextMShow_Reset();
	elseif ( cmd == "cp" ) then
		RaidAlerter_CheckPlayer();
	elseif ( cmd == "pvp" ) then
		RaidAlerter_CheckPvP();
	elseif ( cmd == "gem" ) then
		RaidAlerter_CheckGem();
	elseif ( cmd == "hjjc" or cmd == "cb" or cmd == "checkbuff" or cmd == "checkflask" ) then
		RaidAlerter_CheckFlask(param);
	elseif ( cmd == "showsysinfo" ) then
		RaidAlerter_SET_FUNC_ShowSysInfo("OnOff");
	elseif ( cmd == "cpustart" ) then
		RaidAlerter_SET_FUNC_GTT_cpustart();
	elseif ( cmd == "cpustop" ) then
		RaidAlerter_SET_FUNC_GTT_cpustop();
	elseif ( cmd == "ramreset" ) then
		RaidAlerter_SET_FUNC_ResetRAM("reset");
	elseif ( cmd == "reset" ) then
		RaidAlerter_SET_FUNC_ResetToDefaut();
	elseif ( cmd == "status" ) then
		RaidAlerter_ListStatus();
		RaidAlerter_Check_CTRAORA_LA_TANKS();
	elseif ( cmd == "settome" ) then
		RaidAlerter_SET_FUNC_SYNC_SELECT_SETTOME();
	elseif ( cmd == "checkver" ) then
		if GetNumPartyMembers()>0 or UnitInRaid("player") then
			RaidAlerter_SYNC_CHECKVER = 1;
			RaidAlerter_SYNC_CHECKVERCOUNT = 0;
			RaidAlerter_StartTimer("SYNCCHECKVER");
			RaidAlerter.AddMsg(RAL_TEXT_SYNC_START_CHECK);
			RaidAlerter_SetAddonMessage("RAL_CHECKVER","startcheck");
		else
			RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTTEAM);
		end
	elseif ( cmd == "myhp" ) then
		RaidAlerter_SET_FUNC_CHK_MY_HP(param);
	elseif ( cmd == "tc" ) then
		RaidAlerter_Target_Check(param);
	else
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_CMD_27);
	end
end

function RaidAlerter_Option_MainFrame_Show(self)
	if (RaidAlerter_MainFrame:IsVisible()) then
		RaidAlerter_MainFrame:Hide();
		if GetNumPartyMembers()>0 or UnitInRaid("player") then
			RaidAlerter_SetAddonMessage("RAL_SELECT","startcheck");
			RaidAlerter_SYNC_SELECT_NAME_MSG = 1;
			RaidAlerter_StartTimer("SELECTNAMEMSG");
		end
	else
		RaidAlerter_MainFrame:Show();
		RaidAlerter_Option_MainFrame_Update();
		RaidAlerter_Check_CTRAORA_LA_TANKS();
	end
end

function RaidAlerter_Option_MainFrame_Update()
--更新选项菜单
	if (RaidAlerter_MainFrame:IsVisible()) then
		if RaidAlerter_SET.OnOff then RaidAlerterCheckLabel03_1:SetChecked(1) else RaidAlerterCheckLabel03_1:SetChecked(0) end
		if RaidAlerter_SET.Party_Alerter then RaidAlerterCheckLabel03_2:SetChecked(1) else RaidAlerterCheckLabel03_2:SetChecked(0) end
		if RaidAlerter_SET.OnlySelfCHAN then RaidAlerterCheckLabel03_3:SetChecked(1) else RaidAlerterCheckLabel03_3:SetChecked(0) end
		if RaidAlerter_SET.OnlySelfSCR then RaidAlerterCheckLabel03_4:SetChecked(1) else RaidAlerterCheckLabel03_4:SetChecked(0) end
		if RaidAlerter_SET.SoundAlert then RaidAlerterCheckLabel03_5:SetChecked(1) else RaidAlerterCheckLabel03_5:SetChecked(0) end
		if RaidAlerter_SET.ScrMsg then RaidAlerterCheckLabel03_6:SetChecked(1) else RaidAlerterCheckLabel03_6:SetChecked(0) end
		if RaidAlerter_SET.THREATCheck then RaidAlerterCheckLabel03_7:SetChecked(1) else RaidAlerterCheckLabel03_7:SetChecked(0) end
		if RaidAlerter_SET.ToTCheck then RaidAlerterCheckLabel03_8:SetChecked(1) else RaidAlerterCheckLabel03_8:SetChecked(0) end
		if RaidAlerter_SET.MAXRAM then RaidAlerterCheckLabel04_1:SetValue(RaidAlerter_SET.MAXRAM); end
		if RaidAlerter_SET.TextMShow_OnOff then RaidAlerterCheckLabel05_1:SetChecked(1) else RaidAlerterCheckLabel05_1:SetChecked(0) end
		if RaidAlerter_SET.AF_Scale then RaidAlerterCheckLabel05_2:SetValue(RaidAlerter_SET.AF_Scale); end
		if RaidAlerter_SET.BossHealthPecentOnOff then RaidAlerterCheckLabel06_1:SetChecked(1) else RaidAlerterCheckLabel06_1:SetChecked(0) end
		if RaidAlerter_SET.BossHealthPecent then RaidAlerterCheckLabel06_2:SetValue(RaidAlerter_SET.BossHealthPecent); end
		if RaidAlerter_SET.BossKill then RaidAlerterCheckLabel06_3:SetChecked(1) else RaidAlerterCheckLabel06_3:SetChecked(0) end
		if RaidAlerter_SET.TANK_DangerHealth then RaidAlerterCheckLabel07_1:SetChecked(1) else RaidAlerterCheckLabel07_1:SetChecked(0) end
		if RaidAlerter_SET.TANK_DangerHealthPecent then RaidAlerterCheckLabel07_2:SetValue(RaidAlerter_SET.TANK_DangerHealthPecent); end
		if RaidAlerter_SET.TANK_Death then RaidAlerterCheckLabel07_3:SetChecked(1) else RaidAlerterCheckLabel07_3:SetChecked(0) end
		if RaidAlerter_SET.TANK_ShieldWall then RaidAlerterCheckLabel08_1:SetChecked(1) else RaidAlerterCheckLabel08_1:SetChecked(0) end
		if RaidAlerter_SET.TANK_LastStand then RaidAlerterCheckLabel09_1:SetChecked(1) else RaidAlerterCheckLabel09_1:SetChecked(0) end
		if RaidAlerter_SET.TANK_ShieldReflection then RaidAlerterCheckLabel10_1:SetChecked(1) else RaidAlerterCheckLabel10_1:SetChecked(0) end
		if RaidAlerter_SET.OT_OnOff then RaidAlerterCheckLabel11_1:SetChecked(1) else RaidAlerterCheckLabel11_1:SetChecked(0) end
		if RaidAlerter_SET.OTM_OnOff then RaidAlerterCheckLabel12_1:SetChecked(1);RaidAlerterCheckLabel13_1:Enable(); else RaidAlerterCheckLabel12_1:SetChecked(0);RaidAlerterCheckLabel13_1:Disable(); end
		if RaidAlerter_SET.OTMShow_OnOff then RaidAlerterCheckLabel13_1:SetChecked(1) else RaidAlerterCheckLabel13_1:SetChecked(0) end
		if RaidAlerter_SET.Hunter_Mark then RaidAlerterCheckLabel15_2:SetChecked(1) else RaidAlerterCheckLabel15_2:SetChecked(0) end
		if RaidAlerter_SET.Hunter_Misdirection then RaidAlerterCheckLabel08_2:SetChecked(1) else RaidAlerterCheckLabel08_2:SetChecked(0) end
		if RaidAlerter_SET.Hunter_Shot then RaidAlerterCheckLabel09_2:SetChecked(1) else RaidAlerterCheckLabel09_2:SetChecked(0) end
		if RaidAlerter_SET.TANK_Taunt then RaidAlerterCheckLabel10_2:SetChecked(1) else RaidAlerterCheckLabel10_2:SetChecked(0) end
		if RaidAlerter_SET.RES_DispelMagic then RaidAlerterCheckLabel11_2:SetChecked(1) else RaidAlerterCheckLabel11_2:SetChecked(0) end
		if RaidAlerter_SET.RES_Polymorph then RaidAlerterCheckLabel12_2:SetChecked(1) else RaidAlerterCheckLabel12_2:SetChecked(0) end
		if RaidAlerter_SET.RES_MagicBreak then RaidAlerterCheckLabel13_2:SetChecked(1) else RaidAlerterCheckLabel13_2:SetChecked(0) end
		if RaidAlerter_SET.RES_BuffStolen then RaidAlerterCheckLabel14_2:SetChecked(1) else RaidAlerterCheckLabel14_2:SetChecked(0) end
		if RaidAlerter_SET.Check_Poly then RaidAlerterCheckLabel08_3:SetChecked(1) else RaidAlerterCheckLabel08_3:SetChecked(0) end
		if RaidAlerter_SET.PolyDispel then RaidAlerterCheckLabel09_3:SetChecked(1) else RaidAlerterCheckLabel09_3:SetChecked(0) end
		if RaidAlerter_SET.Break_Poly then RaidAlerterCheckLabel10_3:SetChecked(1) else RaidAlerterCheckLabel10_3:SetChecked(0) end
		if RaidAlerter_SET.Dispel_Magic then RaidAlerterCheckLabel11_3:SetChecked(1) else RaidAlerterCheckLabel11_3:SetChecked(0) end
		if RaidAlerter_SET.BuffStolen then RaidAlerterCheckLabel12_3:SetChecked(1) else RaidAlerterCheckLabel12_3:SetChecked(0) end
		if RaidAlerter_SET.Break_Magic then RaidAlerterCheckLabel13_3:SetChecked(1) else RaidAlerterCheckLabel13_3:SetChecked(0) end
		if RaidAlerter_SET.Check_Gem then RaidAlerterCheckLabel14_4:SetChecked(1) else RaidAlerterCheckLabel14_4:SetChecked(0) end
		if RaidAlerter_SET.Paladin_Intervention then RaidAlerterCheckLabel08_4:SetChecked(1) else RaidAlerterCheckLabel08_4:SetChecked(0) end
		if RaidAlerter_SET.Check_Death_AtCombatEnd then RaidAlerterCheckLabel09_4:SetChecked(1) else RaidAlerterCheckLabel09_4:SetChecked(0) end
		if RaidAlerter_SET.Nef_PriestDown then RaidAlerterCheckLabel10_4:SetChecked(1) else RaidAlerterCheckLabel10_4:SetChecked(0) end
		if RaidAlerter_SET.Nef_TANKPoly then RaidAlerterCheckLabel11_4:SetChecked(1) else RaidAlerterCheckLabel11_4:SetChecked(0) end
		if RaidAlerter_SET.TAQ_Twin_AOEAdd then RaidAlerterCheckLabel12_4:SetChecked(1) else RaidAlerterCheckLabel12_4:SetChecked(0) end
		if RaidAlerter_SET.RaidSpell then RaidAlerterCheckLabel13_4:SetChecked(1) else RaidAlerterCheckLabel13_4:SetChecked(0) end
		if RaidAlerter_SET.Check_Cooking then RaidAlerterCheckLabel14_1:SetChecked(1); RaidAlerterCheckLabel15_1:Enable(); else RaidAlerterCheckLabel14_1:SetChecked(0); RaidAlerterCheckLabel15_1:Disable(); end
		if RaidAlerter_SET.Check_Cooking_Whisper then RaidAlerterCheckLabel15_1:SetChecked(1) else RaidAlerterCheckLabel15_1:SetChecked(0) end
		if RaidAlerter_SET.Check_Inner_Fire then RaidAlerterCheckLabel14_3:SetChecked(1); RaidAlerterCheckLabel15_3:Enable(); else RaidAlerterCheckLabel14_3:SetChecked(0); RaidAlerterCheckLabel15_3:Disable(); end
		if RaidAlerter_SET.Check_Inner_Fire_Whisper then RaidAlerterCheckLabel15_3:SetChecked(1) else RaidAlerterCheckLabel15_3:SetChecked(0) end
		if RaidAlerter_SET.cameraMax then RaidAlerterCheckLabel16_1:SetChecked(1) else RaidAlerterCheckLabel16_1:SetChecked(0) end
	end
end

--事件注册注销并更新事件表RaidAlerter_EVENT_LIST
--[[
function RaidAlerter_EVENT_LIST_Update(evname,act)
	if act == "add" then
		RaidAlerter_Attack_Frame:RegisterEvent(evname);
		table.insert(RaidAlerter_EVENT_LIST,evname);
		return;
	end
	if act =="remove" then
		RaidAlerter_Attack_Frame:UnregisterEvent(evname);
		for k, v in pairs(RaidAlerter_EVENT_LIST) do
			if v == evname then
				table.remove(RaidAlerter_EVENT_LIST,k);
				return;
			end
		end
	end
end
]]

function RaidAlerter_GetTFVarText(VariableID, SIMPLE)
	if VariableID then
		if SIMPLE then
			return RAL_TEXT_ON_SIMPLE;
		else
			return "|cFF20FF20"..RAL_TEXT_ON.."|r";
		end
	else
		if SIMPLE then
			return RAL_TEXT_OFF_SIMPLE;
		else
			return "|cFFFF2020"..RAL_TEXT_OFF.."|r";
		end
	end
end

--设置函数
function RaidAlerter_SET_FUNC_OnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.OnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OnOff = not RaidAlerter_SET.OnOff;
	else
		RaidAlerter_SET.OnOff = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_1..RaidAlerter_GetTFVarText(RaidAlerter_SET.OnOff));
	RaidAlerter_Option_MainFrame_Update();
	RaidAlerter_SetAddonMessage("RAL_SELECT","startcheck");
end

function RaidAlerter_SET_FUNC_Party_Alerter(checked)
	if checked == 1 then
		RaidAlerter_SET.Party_Alerter = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Party_Alerter = not RaidAlerter_SET.Party_Alerter;
	else
		RaidAlerter_SET.Party_Alerter = false;
	end
	RaidAlerter.AddMsg("|cFFAAAAFF"..RAL_TEXT_FUNC_2..RaidAlerter_GetTFVarText(RaidAlerter_SET.Party_Alerter));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_OnlySelfCHAN(checked)
	if checked == 1 then
		RaidAlerter_SET.OnlySelfCHAN = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OnlySelfCHAN = not RaidAlerter_SET.OnlySelfCHAN;
	else
		RaidAlerter_SET.OnlySelfCHAN = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_3..RaidAlerter_GetTFVarText(RaidAlerter_SET.OnlySelfCHAN));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_OnlySelfSCR(checked)
	if checked == 1 then
		RaidAlerter_SET.OnlySelfSCR = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OnlySelfSCR = not RaidAlerter_SET.OnlySelfSCR;
	else
		RaidAlerter_SET.OnlySelfSCR = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_4..RaidAlerter_GetTFVarText(RaidAlerter_SET.OnlySelfSCR));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_SoundAlert(checked)
	if checked == 1 then
		RaidAlerter_SET.SoundAlert = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.SoundAlert = not RaidAlerter_SET.SoundAlert;
	else
		RaidAlerter_SET.SoundAlert = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_129..RaidAlerter_GetTFVarText(RaidAlerter_SET.SoundAlert));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_BossKill(checked)
	if checked == 1 then
		RaidAlerter_SET.BossKill = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.BossKill = not RaidAlerter_SET.BossKill;
	else
		RaidAlerter_SET.BossKill = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_5..RaidAlerter_GetTFVarText(RaidAlerter_SET.BossKill));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_DangerHealth(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_DangerHealth = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_DangerHealth = not RaidAlerter_SET.TANK_DangerHealth;
	else
		RaidAlerter_SET.TANK_DangerHealth = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_6..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_DangerHealth));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_DangerHealthPecent(arg)
	if arg =="defaut" then
		RaidAlerter_SET.TANK_DangerHealthPecent = 30;
	else
		RaidAlerter_SET.TANK_DangerHealthPecent = arg;
	end
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_7,"|cFFFF5555"..RaidAlerter_SET.TANK_DangerHealthPecent));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_Death(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_Death = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_Death = not RaidAlerter_SET.TANK_Death;
	else
		RaidAlerter_SET.TANK_Death = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_8..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_Death));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_ShieldWall(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_ShieldWall = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_ShieldWall = not RaidAlerter_SET.TANK_ShieldWall;
	else
		RaidAlerter_SET.TANK_ShieldWall = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_58..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_ShieldWall));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_LastStand(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_LastStand = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_LastStand = not RaidAlerter_SET.TANK_LastStand;
	else
		RaidAlerter_SET.TANK_LastStand = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_60..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_LastStand));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_ShieldReflection(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_ShieldReflection = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_ShieldReflection = not RaidAlerter_SET.TANK_ShieldReflection;
	else
		RaidAlerter_SET.TANK_ShieldReflection = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_11..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_ShieldReflection));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TANK_Taunt(checked)
	if checked == 1 then
		RaidAlerter_SET.TANK_Taunt = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TANK_Taunt = not RaidAlerter_SET.TANK_Taunt;
	else
		RaidAlerter_SET.TANK_Taunt = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_12..RaidAlerter_GetTFVarText(RaidAlerter_SET.TANK_Taunt));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_RES_DispelMagic(checked)
	if checked == 1 then
		RaidAlerter_SET.RES_DispelMagic = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.RES_DispelMagic = not RaidAlerter_SET.RES_DispelMagic;
	else
		RaidAlerter_SET.RES_DispelMagic = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_13..RaidAlerter_GetTFVarText(RaidAlerter_SET.RES_DispelMagic));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_RES_Polymorph(checked)
	if checked == 1 then
		RaidAlerter_SET.RES_Polymorph = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.RES_Polymorph = not RaidAlerter_SET.RES_Polymorph;
	else
		RaidAlerter_SET.RES_Polymorph = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_14..RaidAlerter_GetTFVarText(RaidAlerter_SET.RES_Polymorph));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_RES_MagicBreak(checked)
	if checked == 1 then
		RaidAlerter_SET.RES_MagicBreak = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.RES_MagicBreak = not RaidAlerter_SET.RES_MagicBreak;
	else
		RaidAlerter_SET.RES_MagicBreak = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_15..RaidAlerter_GetTFVarText(RaidAlerter_SET.RES_MagicBreak));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_RES_BuffStolen(checked)
	if checked == 1 then
		RaidAlerter_SET.RES_BuffStolen = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.RES_BuffStolen = not RaidAlerter_SET.RES_BuffStolen;
	else
		RaidAlerter_SET.RES_BuffStolen = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_16..RaidAlerter_GetTFVarText(RaidAlerter_SET.RES_BuffStolen));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Hunter_Shot(checked)
	if checked == 1 then
		RaidAlerter_SET.Hunter_Shot = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Hunter_Shot = not RaidAlerter_SET.Hunter_Shot;
	else
		RaidAlerter_SET.Hunter_Shot = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_17..RaidAlerter_GetTFVarText(RaidAlerter_SET.Hunter_Shot));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Hunter_Mark(checked)
	if checked == 1 then
		RaidAlerter_SET.Hunter_Mark = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Hunter_Mark = not RaidAlerter_SET.Hunter_Mark;
	else
		RaidAlerter_SET.Hunter_Mark = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_18..RaidAlerter_GetTFVarText(RaidAlerter_SET.Hunter_Mark));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Hunter_Misdirection(checked)
	if checked == 1 then
		RaidAlerter_SET.Hunter_Misdirection = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Hunter_Misdirection = not RaidAlerter_SET.Hunter_Misdirection;
	else
		RaidAlerter_SET.Hunter_Misdirection = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_19..RaidAlerter_GetTFVarText(RaidAlerter_SET.Hunter_Misdirection));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Poly(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Poly = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Poly = not RaidAlerter_SET.Check_Poly;
	else
		RaidAlerter_SET.Check_Poly = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_20..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Poly));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_PolyDispel(checked)
	if checked == 1 then
		RaidAlerter_SET.PolyDispel = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.PolyDispel = not RaidAlerter_SET.PolyDispel;
	else
		RaidAlerter_SET.PolyDispel = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_21..RaidAlerter_GetTFVarText(RaidAlerter_SET.PolyDispel));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Break_Poly(checked)
	if checked == 1 then
		RaidAlerter_SET.Break_Poly = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Break_Poly = not RaidAlerter_SET.Break_Poly;
	else
		RaidAlerter_SET.Break_Poly = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_22..RaidAlerter_GetTFVarText(RaidAlerter_SET.Break_Poly));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Gem(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Gem = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Gem = not RaidAlerter_SET.Check_Gem;
	else
		RaidAlerter_SET.Check_Gem = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_23..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Gem));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Death_AtCombatEnd(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Death_AtCombatEnd = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Death_AtCombatEnd = not RaidAlerter_SET.Check_Death_AtCombatEnd;
	else
		RaidAlerter_SET.Check_Death_AtCombatEnd = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_24..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Death_AtCombatEnd));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TAQ_Twin_AOEAdd(checked)
	if checked == 1 then
		RaidAlerter_SET.TAQ_Twin_AOEAdd = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TAQ_Twin_AOEAdd = not RaidAlerter_SET.TAQ_Twin_AOEAdd;
	else
		RaidAlerter_SET.TAQ_Twin_AOEAdd = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_25..RaidAlerter_GetTFVarText(RaidAlerter_SET.TAQ_Twin_AOEAdd));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_RaidSpell(checked)
	if checked == 1 then
		RaidAlerter_SET.RaidSpell = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.RaidSpell = not RaidAlerter_SET.RaidSpell;
	else
		RaidAlerter_SET.RaidSpell = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_141..RaidAlerter_GetTFVarText(RaidAlerter_SET.RaidSpell));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Cooking(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Cooking = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Cooking = not RaidAlerter_SET.Check_Cooking;
	else
		RaidAlerter_SET.Check_Cooking = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_145..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Cooking));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Cooking_Whisper(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Cooking_Whisper = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Cooking_Whisper = not RaidAlerter_SET.Check_Cooking_Whisper;
	else
		RaidAlerter_SET.Check_Cooking_Whisper = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_148..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Cooking_Whisper));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Inner_Fire(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Inner_Fire = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Inner_Fire = not RaidAlerter_SET.Check_Inner_Fire;
	else
		RaidAlerter_SET.Check_Inner_Fire = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_151..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Inner_Fire));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Check_Inner_Fire_Whisper(checked)
	if checked == 1 then
		RaidAlerter_SET.Check_Inner_Fire_Whisper = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Check_Inner_Fire_Whisper = not RaidAlerter_SET.Check_Inner_Fire_Whisper;
	else
		RaidAlerter_SET.Check_Inner_Fire_Whisper = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_154..RaidAlerter_GetTFVarText(RaidAlerter_SET.Check_Inner_Fire_Whisper));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_BossHealthPecentOnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.BossHealthPecentOnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.BossHealthPecentOnOff = not RaidAlerter_SET.BossHealthPecentOnOff;
	else
		RaidAlerter_SET.BossHealthPecentOnOff = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_26..RaidAlerter_GetTFVarText(RaidAlerter_SET.BossHealthPecentOnOff)..", "..string.format(RAL_TEXT_FUNC_27,"|cFFFF5555"..RaidAlerter_SET.BossHealthPecent));
	RaidAlerter_Option_MainFrame_Update();
end


function RaidAlerter_SET_FUNC_BossHealthPecent(arg)
	if arg =="defaut" then
		RaidAlerter_SET.BossHealthPecent = 10;
	else
		RaidAlerter_SET.BossHealthPecent = arg;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_26..": "..string.format(RAL_TEXT_FUNC_27,"|cFFFF5555"..RaidAlerter_SET.BossHealthPecent));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_TextMShow_OnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.TextMShow_OnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.TextMShow_OnOff = not RaidAlerter_SET.TextMShow_OnOff;
	else
		RaidAlerter_SET.TextMShow_OnOff = false;
	end
	if RaidAlerter_SET.TextMShow_OnOff then
		RaidAlerter_Attack_Frame:Show();
		RaidAlerter_SET_FUNC_AF_Scale();
	else
		RaidAlerter_Attack_Frame:Hide();
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_28..RaidAlerter_GetTFVarText(RaidAlerter_SET.TextMShow_OnOff));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_ScrMsg(checked)
	if checked == 1 then
		RaidAlerter_SET.ScrMsg = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.ScrMsg = not RaidAlerter_SET.ScrMsg;
	else
		RaidAlerter_SET.ScrMsg = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_134..RaidAlerter_GetTFVarText(RaidAlerter_SET.ScrMsg));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_THREATCheck(checked)
	if checked == 1 then
		RaidAlerter_SET.THREATCheck = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.THREATCheck = not RaidAlerter_SET.THREATCheck;
	else
		RaidAlerter_SET.THREATCheck = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_126..RaidAlerter_GetTFVarText(RaidAlerter_SET.THREATCheck));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_ToTCheck(checked)
	if checked == 1 then
		RaidAlerter_SET.ToTCheck = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.ToTCheck = not RaidAlerter_SET.ToTCheck;
	else
		RaidAlerter_SET.ToTCheck = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_136..RaidAlerter_GetTFVarText(RaidAlerter_SET.ToTCheck));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_OT_OnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.OT_OnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OT_OnOff = not RaidAlerter_SET.OT_OnOff;
	else
		RaidAlerter_SET.OT_OnOff = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_29..RaidAlerter_GetTFVarText(RaidAlerter_SET.OT_OnOff));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_OTM_OnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.OTM_OnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OTM_OnOff = not RaidAlerter_SET.OTM_OnOff;
	else
		RaidAlerter_SET.OTM_OnOff = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_30..RaidAlerter_GetTFVarText(RaidAlerter_SET.OTM_OnOff));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_OTMShow_OnOff(checked)
	if checked == 1 then
		RaidAlerter_SET.OTMShow_OnOff = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.OTMShow_OnOff = not RaidAlerter_SET.OTMShow_OnOff;
	else
		RaidAlerter_SET.OTMShow_OnOff = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_31..RaidAlerter_GetTFVarText(RaidAlerter_SET.OTMShow_OnOff));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Nef_PriestDown(checked)
	if checked == 1 then
		RaidAlerter_SET.Nef_PriestDown = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Nef_PriestDown = not RaidAlerter_SET.Nef_PriestDown;
	else
		RaidAlerter_SET.Nef_PriestDown = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_32..RaidAlerter_GetTFVarText(RaidAlerter_SET.Nef_PriestDown));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Nef_TANKPoly(checked)
	if checked == 1 then
		RaidAlerter_SET.Nef_TANKPoly = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Nef_TANKPoly = not RaidAlerter_SET.Nef_TANKPoly;
	else
		RaidAlerter_SET.Nef_TANKPoly = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_33..RaidAlerter_GetTFVarText(RaidAlerter_SET.Nef_TANKPoly));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Dispel_Magic(checked)
	if checked == 1 then
		RaidAlerter_SET.Dispel_Magic = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Dispel_Magic = not RaidAlerter_SET.Dispel_Magic;
	else
		RaidAlerter_SET.Dispel_Magic = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_34..RaidAlerter_GetTFVarText(RaidAlerter_SET.Dispel_Magic));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_BuffStolen(checked)
	if checked == 1 then
		RaidAlerter_SET.BuffStolen = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.BuffStolen = not RaidAlerter_SET.BuffStolen;
	else
		RaidAlerter_SET.BuffStolen = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_35..RaidAlerter_GetTFVarText(RaidAlerter_SET.BuffStolen));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Break_Magic(checked)
	if checked == 1 then
		RaidAlerter_SET.Break_Magic = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Break_Magic = not RaidAlerter_SET.Break_Magic;
	else
		RaidAlerter_SET.Break_Magic = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_36..RaidAlerter_GetTFVarText(RaidAlerter_SET.Break_Magic));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_Paladin_Intervention(checked)
	if checked == 1 then
		RaidAlerter_SET.Paladin_Intervention = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.Paladin_Intervention = not RaidAlerter_SET.Paladin_Intervention;
	else
		RaidAlerter_SET.Paladin_Intervention = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_37..RaidAlerter_GetTFVarText(RaidAlerter_SET.Paladin_Intervention));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_SYNC_SELECT_SETTOME(checked)
	if RaidAlerter_SYNC_SELECT_SETTOME == 0 then
		RaidAlerter_SYNC_SELECT_SETTOME = 1;
		RaidAlerter.AddMsg(RAL_TEXT_FUNC_38..":|cFFFF2020 "..RAL_TEXT_FUNC_39);
	elseif RaidAlerter_SYNC_SELECT_SETTOME ==1 then
		RaidAlerter_SYNC_SELECT_SETTOME = 2;
		RaidAlerter.AddMsg(RAL_TEXT_FUNC_38..":|cFFFF7711 "..RAL_TEXT_FUNC_40);
	else
		RaidAlerter_SYNC_SELECT_SETTOME = 0;
		RaidAlerter.AddMsg(RAL_TEXT_FUNC_38..":|cFF20FF20 "..RAL_TEXT_FUNC_41);
	end
	RaidAlerter_SetAddonMessage("RAL_SELECT","startcheck");
end

function RaidAlerter_SET_FUNC_CHK_MY_HP(param)
	if param == 1 then
		RaidAlerter_ChkMyHP = true;
	elseif param == 0 then
		RaidAlerter_ChkMyHP = false;
	elseif (not param) or (param=="") or (param=="onoff") then
		RaidAlerter_ChkMyHP = not RaidAlerter_ChkMyHP;
	else
		RaidAlerter_ChkMyHP = true;
		RaidAlerter_MyDangerHP = tonumber(param) or RaidAlerter_MyDangerHP;
		if RaidAlerter_MyDangerHP<1 then RaidAlerter_MyDangerHP=1; end
		if RaidAlerter_MyDangerHP>99 then RaidAlerter_MyDangerHP=99; end
	end
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_42,RaidAlerter_GetTFVarText(RaidAlerter_ChkMyHP),"|cFFFF5555"..RaidAlerter_MyDangerHP));
end

function RaidAlerter_SET_FUNC_AF_Scale()
	if not RaidAlerter_SET.AF_Scale then RaidAlerter_SET.AF_Scale=1 end;
	RaidAlerter_Attack_Frame:SetScale(tonumber(RaidAlerter_SET.AF_Scale));
end

function RaidAlerter_SET_FUNC_TextMShow_Reset()
	RaidAlerter_Attack_Frame:ClearAllPoints();
	RaidAlerter_Attack_Frame:SetPoint("TOP","UIParent","TOP",20,-12);
	RaidAlerter_Attack_Frame:Show();
	RaidAlerter_SET.AF_Scale = 1
	RaidAlerterCheckLabel05_2:SetValue(RaidAlerter_SET.AF_Scale);
	RaidAlerter_SET_FUNC_AF_Scale();
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_43,"|cFF20FF20"..string.format("%.2f", RaidAlerter_SET.AF_Scale)));
end

function RaidAlerter_SET_FUNC_ShowSysInfo(checked)
	if checked == 1 then
		RaidAlerter_SET.ShowSysInfo = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.ShowSysInfo = not RaidAlerter_SET.ShowSysInfo;
	else
		RRaidAlerter_SET.ShowSysInfo = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_44..RaidAlerter_GetTFVarText(RaidAlerter_SET.ShowSysInfo));
	RaidAlerter_Option_MainFrame_Update();
end

function RaidAlerter_SET_FUNC_cameraMax(checked)
	if checked == 1 then
		RaidAlerter_SET.cameraMax = true;
	elseif checked =="OnOff" then
		RaidAlerter_SET.cameraMax = not RaidAlerter_SET.cameraMax;
	else
		RaidAlerter_SET.cameraMax = false;
	end
	RaidAlerter.AddMsg(RAL_TEXT_XML_131..RaidAlerter_GetTFVarText(RaidAlerter_SET.cameraMax));
	if RaidAlerter_SET.cameraMax then
		RaidAlerter_SetCameraMaxToMax();
	else
		RaidAlerter_SetCameraMaxToDefaut();
		RaidAlerter.AddMsg("|cFF20FF20"..RAL_TEXT_FUNC_48);
		RaidAlerter.AddMsg("|cFFFF0000"..RAL_TEXT_XML_133);
	end
	RaidAlerter_Option_MainFrame_Update();
end

StaticPopupDialogs["RaidAlerter_RELOADUI"] = {
	text = "|cFFFFDD00"..RaidAlerter_UINameEN..RaidAlerter_UIName.."|r\n\n"..RAL_TEXT_CPUMSG_1,
	button1 = RAL_TEXT_CPUMSG_2,
	button2 = RAL_TEXT_CPUMSG_3,
	OnAccept = function()
		ReloadUI();
	end,
	timeout = 0,
	exclusive = 1,
	hideOnEscape = 1,
};

function RaidAlerter_SET_FUNC_GTT_cpustart()
	if (GetCVar("scriptProfile") == "1") then
		RaidAlerter.AddMsg(RAL_TEXT_FUNC_45.."|cFF20FF20"..RAL_TEXT_ON);
	else
		SetCVar("scriptProfile", "1");
		StaticPopup_Show("RaidAlerter_RELOADUI");
	end
end

function RaidAlerter_SET_FUNC_GTT_cpustop()
	if (GetCVar("scriptProfile") == "0") then
		RaidAlerter.AddMsg(RAL_TEXT_FUNC_45.."|cFFFF2020"..RAL_TEXT_OFF);
	else
		SetCVar("scriptProfile", "0");
		StaticPopup_Show("RaidAlerter_RELOADUI");
	end
end

function RaidAlerter_SET_FUNC_ResetRAM(arg)
	if arg=="reset" then
		collectgarbage("collect");
--		terry@bf 去掉内存清理提示信息
	--	RaidAlerter.AddMsg(RAL_TEXT_FUNC_46);
	else
--		UpdateAddOnMemoryUsage();
		RaidAlerter_Check_RAM_CPU();
		if GetAddOnMemoryUsage("RaidAlerter")>arg then
			collectgarbage("collect");
--		terry@bf 去掉内存清理提示信息
	--	RaidAlerter.AddMsg(RAL_TEXT_FUNC_46);
		end
	end
end

function RaidAlerter_SET_FUNC_MsgTest()
	local PN = UnitName("player");
	local AlertMsg = {
		[1]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_1,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3,PN),
			["Scr"]=string.format(RAL_TEXT_ALERT_1,RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3),RAL.ToPink(RAL_TEXT_YOU)),
			},
		[2]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_30,PN,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3,RAL_TEXT_BUFF_5),
			["Scr"]=string.format(RAL_TEXT_ALERT_30,RAL.ToPink(RAL_TEXT_YOU),RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3),RAL.ToCyan(RAL_TEXT_BUFF_5)),
			},
		[3]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_31,PN,RAL_TEXT_SPELL_17,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3),
			["Scr"]=string.format(RAL_TEXT_ALERT_31,RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(RAL_TEXT_SPELL_17),RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3)),
			},
		[4]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_32,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3,PN,RAL_TEXT_SPELL_17),
			["Scr"]=string.format(RAL_TEXT_ALERT_32,RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3),RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(RAL_TEXT_SPELL_17)),
			},
		[5]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_32,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3,PN,RAL_TEXT_SPELL_17),
			["Scr"]=string.format(RAL_TEXT_ALERT_32,RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3),RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(RAL_TEXT_SPELL_17)),
			},
		[6]	= {
			["Raid"]=string.format(RAL_TEXT_ALERT_34,PN,RaidAlerter_RAIDICON[8]..RAL_TEXT_UINTNAME_3,RAL_TEXT_SPELL_9),
			["Scr"]=string.format(RAL_TEXT_ALERT_34,RAL.ToPink(RAL_TEXT_YOU),RaidAlerter_RAIDICON[8]..RAL.ToRed(RAL_TEXT_UINTNAME_3),RAL.ToCyan(RAL_TEXT_SPELL_9)),
			},
	};
	local ToTMsg = {
		[1]	= string.format(RAL_TEXT_THREAT_INFO_05,RAL_TEXT_YOU),
		[2]	= string.format(RAL_TEXT_THREAT_INFO_03,RAL_TEXT_YOU),
	};
	local ThreatMsg = {
		[1]	= RAL_TEXT_THREAT_INFO_04,
		[2]	= RAL_TEXT_THREAT_INFO_01,
		[3]	= RAL_TEXT_THREAT_INFO_02,
	};
	RaidAlerter.AddMsg("|cFF00FF00"..RAL_TEXT_XML_139.."...");
	RaidAlerter.AddErrorMsg("|cFFFF7711<|r|cFFFFFF99"..RaidAlerter_UINameEN.."|r|cFFFF7711>|r".."|cFF00FF00"..RAL_TEXT_XML_139.."...");
	local i = 1;
	i = random(1, 6);
	RaidAlerter.AddMsg(AlertMsg[i]["Raid"]);
	RaidAlerter.AddSCRMsg(AlertMsg[i]["Scr"]);
	if RaidAlerter_SET.ToTCheck then
		i = random(1, 2);
		if i == 1 then
			RAL_TOT_Info:AddMessage(ToTMsg[i], 0.8, 0.8, 0.8);
		elseif i == 2 then
			RAL_TOT_Info:AddMessage(ToTMsg[i], 1, 0.9, 0);
		end
		RAL.SOUND(1);
	end
	if RaidAlerter_SET.THREATCheck then
		i = random(1, 3);
		if i == 1 then
			RAL_THREAT_Info:AddMessage(ThreatMsg[i], 1, 0.1, 1);
		elseif i == 2 then
			RAL_THREAT_Info:AddMessage(ThreatMsg[i], 1, 0.1, 0.1);
		elseif i == 3 then
			RAL_THREAT_Info:AddMessage(ThreatMsg[i], 0.1, 1, 0.1);
		end
		RAL.SOUND(1);
	end
end

function RaidAlerter_SET_FUNC_ResetToDefaut(arg)
	UIDropDownMenu_SetSelectedID(RaidAlerter_RAIDMODEList,4);
	RaidAlerter_RAIDMODE_MAX_GROUP_SETUP(5);
	RaidAlerter_SET.MAXRAM = 416;
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_47,"|cFF44FF44"..RaidAlerter_SET.MAXRAM));
	RaidAlerter_SET.TANK_DangerHealthPecent = 30;
	RaidAlerter_SET.BossHealthPecent = 10;
	RaidAlerter_SET_FUNC_OnOff(1);
	RaidAlerter_SET_FUNC_Party_Alerter(1);
	RaidAlerter_SET_FUNC_OnlySelfCHAN(0);
	RaidAlerter_SET_FUNC_OnlySelfSCR(0);
	RaidAlerter_SET_FUNC_SoundAlert(1);
	RaidAlerter_SET_FUNC_TextMShow_OnOff(1);
	RaidAlerter_SET_FUNC_BossHealthPecentOnOff(1);
	RaidAlerter_SET_FUNC_BossHealthPecent(10);
	RaidAlerter_SET_FUNC_BossKill(1);
	RaidAlerter_SET_FUNC_TANK_DangerHealth(1);
	RaidAlerter_SET_FUNC_TANK_DangerHealthPecent(30);
	RaidAlerter_SET_FUNC_TANK_Death(1);
	RaidAlerter_SET_FUNC_TANK_ShieldWall(1);
	RaidAlerter_SET_FUNC_TANK_LastStand(1);
	RaidAlerter_SET_FUNC_TANK_ShieldReflection(1);
	RaidAlerter_SET_FUNC_ScrMsg(1);
	RaidAlerter_SET_FUNC_THREATCheck(1);
	RaidAlerter_SET_FUNC_ToTCheck(1);
	RaidAlerter_SET_FUNC_OT_OnOff(1);
	RaidAlerter_SET_FUNC_OTM_OnOff(0);
	RaidAlerter_SET_FUNC_OTMShow_OnOff(0);
	RaidAlerter_SET_FUNC_Hunter_Mark(0);
	RaidAlerter_SET_FUNC_Hunter_Misdirection(1);
	RaidAlerter_SET_FUNC_Hunter_Shot(1);
	RaidAlerter_SET_FUNC_TANK_Taunt(1);
	RaidAlerter_SET_FUNC_RES_DispelMagic(1);
	RaidAlerter_SET_FUNC_RES_Polymorph(1);
	RaidAlerter_SET_FUNC_RES_MagicBreak(1);
	RaidAlerter_SET_FUNC_RES_BuffStolen(1);
	RaidAlerter_SET_FUNC_Check_Poly(1);
	RaidAlerter_SET_FUNC_PolyDispel(1);
	RaidAlerter_SET_FUNC_Break_Poly(1);
	RaidAlerter_SET_FUNC_Dispel_Magic(1);
	RaidAlerter_SET_FUNC_BuffStolen(1);
	RaidAlerter_SET_FUNC_Break_Magic(1);
	RaidAlerter_SET_FUNC_Check_Gem(1);
	RaidAlerter_SET_FUNC_Paladin_Intervention(1);
	RaidAlerter_SET_FUNC_Check_Death_AtCombatEnd(1);
	RaidAlerter_SET_FUNC_Nef_PriestDown(0);
	RaidAlerter_SET_FUNC_Nef_TANKPoly(0);
	RaidAlerter_SET_FUNC_TAQ_Twin_AOEAdd(0);
	RaidAlerter_SET_FUNC_RaidSpell(1);
	RaidAlerter_SET_FUNC_Check_Cooking(1);
	RaidAlerter_SET_FUNC_Check_Cooking_Whisper(0);
	RaidAlerter_SET_FUNC_Check_Inner_Fire(1);
	RaidAlerter_SET_FUNC_Check_Inner_Fire_Whisper(0);
	RaidAlerter_SET_FUNC_CHK_MY_HP(0);
--	RaidAlerter_Attack_Frame:Show();
	RaidAlerter_Check_CTRAORA_LA_TANKS();
	RaidAlerter.AddMsg("|cFF20FF20"..RAL_TEXT_FUNC_48);
end

function RaidAlerter_MainFrame_SetAllChecked()
	RaidAlerter_SET_FUNC_OnOff(1);
	RaidAlerter_SET_FUNC_Party_Alerter(1);
	RaidAlerter_SET_FUNC_SoundAlert(1);
	RaidAlerter_SET_FUNC_TextMShow_OnOff(1);
	RaidAlerter_SET_FUNC_BossHealthPecentOnOff(1);
	RaidAlerter_SET_FUNC_BossKill(1);
	RaidAlerter_SET_FUNC_TANK_DangerHealth(1);
	RaidAlerter_SET_FUNC_TANK_Death(1);
	RaidAlerter_SET_FUNC_TANK_ShieldWall(1);
	RaidAlerter_SET_FUNC_TANK_LastStand(1);
	RaidAlerter_SET_FUNC_TANK_ShieldReflection(1);
	RaidAlerter_SET_FUNC_ScrMsg(1);
	RaidAlerter_SET_FUNC_THREATCheck(1);
	RaidAlerter_SET_FUNC_ToTCheck(1);
	RaidAlerter_SET_FUNC_OT_OnOff(1);
	RaidAlerter_SET_FUNC_OTM_OnOff(1);
	RaidAlerter_SET_FUNC_OTMShow_OnOff(1);
	RaidAlerter_SET_FUNC_Hunter_Mark(1);
	RaidAlerter_SET_FUNC_Hunter_Misdirection(1);
	RaidAlerter_SET_FUNC_Hunter_Shot(1);
	RaidAlerter_SET_FUNC_TANK_Taunt(1);
	RaidAlerter_SET_FUNC_RES_DispelMagic(1);
	RaidAlerter_SET_FUNC_RES_Polymorph(1);
	RaidAlerter_SET_FUNC_RES_MagicBreak(1);
	RaidAlerter_SET_FUNC_RES_BuffStolen(1);
	RaidAlerter_SET_FUNC_Check_Poly(1);
	RaidAlerter_SET_FUNC_PolyDispel(1);
	RaidAlerter_SET_FUNC_Break_Poly(1);
	RaidAlerter_SET_FUNC_Dispel_Magic(1);
	RaidAlerter_SET_FUNC_BuffStolen(1);
	RaidAlerter_SET_FUNC_Break_Magic(1);
	RaidAlerter_SET_FUNC_Check_Gem(1);
	RaidAlerter_SET_FUNC_Paladin_Intervention(1);
	RaidAlerter_SET_FUNC_Check_Death_AtCombatEnd(1);
	RaidAlerter_SET_FUNC_Nef_PriestDown(1);
	RaidAlerter_SET_FUNC_Nef_TANKPoly(1);
	RaidAlerter_SET_FUNC_TAQ_Twin_AOEAdd(1);
	RaidAlerter_SET_FUNC_RaidSpell(1);
	RaidAlerter_SET_FUNC_Check_Cooking(1);
	RaidAlerter_SET_FUNC_Check_Cooking_Whisper(1);
	RaidAlerter_SET_FUNC_Check_Inner_Fire(1);
	RaidAlerter_SET_FUNC_Check_Inner_Fire_Whisper(1);
--	RaidAlerter_SET_FUNC_CHK_MY_HP(1);
end

function RaidAlerter_MainFrame_SetAllClean()
--	RaidAlerter_SET_FUNC_OnOff(0);
--	RaidAlerter_SET_FUNC_Party_Alerter(0);
	RaidAlerter_SET_FUNC_OnlySelfCHAN(0);
	RaidAlerter_SET_FUNC_OnlySelfSCR(0);
	RaidAlerter_SET_FUNC_SoundAlert(0);
	RaidAlerter_SET_FUNC_BossHealthPecentOnOff(0);
	RaidAlerter_SET_FUNC_BossKill(0);
	RaidAlerter_SET_FUNC_TANK_DangerHealth(0);
	RaidAlerter_SET_FUNC_TANK_Death(0);
	RaidAlerter_SET_FUNC_TANK_ShieldWall(0);
	RaidAlerter_SET_FUNC_TANK_LastStand(0);
	RaidAlerter_SET_FUNC_TANK_ShieldReflection(0);
	RaidAlerter_SET_FUNC_ScrMsg(0);
	RaidAlerter_SET_FUNC_THREATCheck(0);
	RaidAlerter_SET_FUNC_ToTCheck(0);
	RaidAlerter_SET_FUNC_OT_OnOff(0);
	RaidAlerter_SET_FUNC_OTM_OnOff(0);
	RaidAlerter_SET_FUNC_OTMShow_OnOff(0);
	RaidAlerter_SET_FUNC_Hunter_Mark(0);
	RaidAlerter_SET_FUNC_Hunter_Misdirection(0);
	RaidAlerter_SET_FUNC_Hunter_Shot(0);
	RaidAlerter_SET_FUNC_TANK_Taunt(0);
	RaidAlerter_SET_FUNC_RES_DispelMagic(0);
	RaidAlerter_SET_FUNC_RES_Polymorph(0);
	RaidAlerter_SET_FUNC_RES_MagicBreak(0);
	RaidAlerter_SET_FUNC_RES_BuffStolen(0);
	RaidAlerter_SET_FUNC_Check_Poly(0);
	RaidAlerter_SET_FUNC_PolyDispel(0);
	RaidAlerter_SET_FUNC_Break_Poly(0);
	RaidAlerter_SET_FUNC_Dispel_Magic(0);
	RaidAlerter_SET_FUNC_BuffStolen(0);
	RaidAlerter_SET_FUNC_Break_Magic();
	RaidAlerter_SET_FUNC_Check_Gem(0);
	RaidAlerter_SET_FUNC_Paladin_Intervention(0);
	RaidAlerter_SET_FUNC_Check_Death_AtCombatEnd(0);
	RaidAlerter_SET_FUNC_Nef_PriestDown(0);
	RaidAlerter_SET_FUNC_Nef_TANKPoly(0);
	RaidAlerter_SET_FUNC_TAQ_Twin_AOEAdd(0);
	RaidAlerter_SET_FUNC_RaidSpell(0);
	RaidAlerter_SET_FUNC_Check_Cooking(0);
	RaidAlerter_SET_FUNC_Check_Cooking_Whisper(0);
	RaidAlerter_SET_FUNC_Check_Inner_Fire(0);
	RaidAlerter_SET_FUNC_Check_Inner_Fire_Whisper(0);
--	RaidAlerter_SET_FUNC_CHK_MY_HP(0);
end

function RaidAlerter_ListStatus()
	RaidAlerter.AddMsg("|cFF5588FF"..RaidAlerter_UINameEN..RaidAlerter_UIName.." - "..RAL_TEXT_FUNC_49..":");
	RaidAlerter_Check_RAM_CPU();
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_50..": "..RaidAlerter_Version);
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_51..": ".."|cFFFFFFFF"..format("%.1f",RaidAlerter_Check_RAM_DATA).."|r".."K");
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_52,"|cFF20FF20"..(RaidAlerter_SET.RAIDMODE_MAX_GROUP*5).."|r"));
	RaidAlerter.AddMsg(RAL_TEXT_FUNC_1..RaidAlerter_GetTFVarText(RaidAlerter_SET.OnOff));
end

--增加最大镜头距离
function RaidAlerter_SetCameraMaxToMax()
	if RaidAlerter_SET.cameraMax then
		SetCVar("cameraDistanceMax", 50);			--当前3.05版本极限=25，但不排除BLZ将来增大的可能，所以预留点空间
		SetCVar("cameraDistanceMaxFactor", 4);		--当前3.05版本极限=2
	end
end

function RaidAlerter_SetCameraMaxToDefaut()
	SetCVar("cameraDistanceMax", 15);
	SetCVar("cameraDistanceMaxFactor", 1);
end

function RaidAlerter_RAIDMODEList_OnClick(self,id)
	RaidAlerter_RAIDMODE_MAX_GROUP_SETUP((self:GetID()) + 1);
	UIDropDownMenu_SetSelectedID(RaidAlerter_RAIDMODEList, self:GetID());
end

function RaidAlerter_RAIDMODEList_Init(id)
	local info = {};
	local i = 1;
	while i <= 7 do
		info.text = RaidAlerter_RAIDMODE[i];
		info.func = RaidAlerter_RAIDMODEList_OnClick;
		info.value = i;
		info.checked = nil;
		UIDropDownMenu_AddButton(info);
		i = i + 1;
	end
end

function RaidAlerter_RAIDMODE_MAX_GROUP_SETUP(num)
	RaidAlerter_SET.RAIDMODE_MAX_GROUP = num;
	RaidAlerter.AddMsg(string.format(RAL_TEXT_FUNC_53,"|cFF20FF20"..(RaidAlerter_SET.RAIDMODE_MAX_GROUP*5).."|r"));
end

--变量检查，确保更新兼容
function RaidAlerter_Check_Variables()
	if (not RaidAlerter_SET) then RaidAlerter_SET = {}; end
	if RaidAlerter_SET.OnOff == nil then RaidAlerter_SET.OnOff = true; end
	if RaidAlerter_SET.RAIDMODE_MAX_GROUP == nil then RaidAlerter_SET.RAIDMODE_MAX_GROUP = 5; end
	if RaidAlerter_SET.Party_Alerter == nil then RaidAlerter_SET.Party_Alerter = true; end
	if RaidAlerter_SET.OnlySelfCHAN == nil then RaidAlerter_SET.OnlySelfCHAN = false; end
	if RaidAlerter_SET.OnlySelfSCR == nil then RaidAlerter_SET.OnlySelfSCR = false; end
	if RaidAlerter_SET.SoundAlert == nil then RaidAlerter_SET.SoundAlert = true; end
	if RaidAlerter_SET.TextMShow_OnOff == nil then RaidAlerter_SET.TextMShow_OnOff = true; end
	if RaidAlerter_SET.AF_Scale == nil then RaidAlerter_SET.AF_Scale = 1; end
	if RaidAlerter_SET.MAXRAM == nil then RaidAlerter_SET.MAXRAM = 416; end
	if RaidAlerter_SET.BossHealthPecentOnOff == nil then RaidAlerter_SET.BossHealthPecentOnOff = true; end
	if RaidAlerter_SET.BossHealthPecent == nil then RaidAlerter_SET.BossHealthPecent = 10; end
	if RaidAlerter_SET.BossKill == nil then RaidAlerter_SET.BossKill = true; end
	if RaidAlerter_SET.TANK_DangerHealth == nil then RaidAlerter_SET.TANK_DangerHealth = true; end
	if RaidAlerter_SET.TANK_DangerHealthPecent == nil then RaidAlerter_SET.TANK_DangerHealthPecent = 30; end
	if RaidAlerter_SET.TANK_Death == nil then RaidAlerter_SET.TANK_Death = true; end
	if RaidAlerter_SET.TANK_ShieldWall == nil then RaidAlerter_SET.TANK_ShieldWall = true; end
	if RaidAlerter_SET.TANK_LastStand == nil then RaidAlerter_SET.TANK_LastStand = true; end
	if RaidAlerter_SET.TANK_ShieldReflection == nil then RaidAlerter_SET.TANK_ShieldReflection = true; end
	if RaidAlerter_SET.ScrMsg == nil then RaidAlerter_SET.ScrMsg = true; end
	if RaidAlerter_SET.THREATCheck == nil then RaidAlerter_SET.THREATCheck = true; end
	if RaidAlerter_SET.ToTCheck == nil then RaidAlerter_SET.ToTCheck = true; end
	if RaidAlerter_SET.OT_OnOff == nil then RaidAlerter_SET.OT_OnOff = true; end
	if RaidAlerter_SET.OTM_OnOff == nil then RaidAlerter_SET.OTM_OnOff = false; end
	if RaidAlerter_SET.OTMShow_OnOff == nil then RaidAlerter_SET.OTMShow_OnOff = false; end
	if RaidAlerter_SET.Hunter_Mark == nil then RaidAlerter_SET.Hunter_Mark = false; end
	if RaidAlerter_SET.Hunter_Misdirection == nil then RaidAlerter_SET.Hunter_Misdirection = true; end
	if RaidAlerter_SET.Hunter_Shot == nil then RaidAlerter_SET.Hunter_Shot = true; end
	if RaidAlerter_SET.TANK_Taunt == nil then RaidAlerter_SET.TANK_Taunt = true; end
	if RaidAlerter_SET.RES_DispelMagic == nil then RaidAlerter_SET.RES_DispelMagic = true; end
	if RaidAlerter_SET.RES_Polymorph == nil then RaidAlerter_SET.RES_Polymorph = true; end
	if RaidAlerter_SET.RES_MagicBreak == nil then RaidAlerter_SET.RES_MagicBreak = true; end
	if RaidAlerter_SET.RES_BuffStolen == nil then RaidAlerter_SET.RES_BuffStolen = true; end
	if RaidAlerter_SET.Check_Poly == nil then RaidAlerter_SET.Check_Poly = true; end
	if RaidAlerter_SET.PolyDispel == nil then RaidAlerter_SET.PolyDispel = true; end
	if RaidAlerter_SET.Break_Poly == nil then RaidAlerter_SET.Break_Poly = true; end
	if RaidAlerter_SET.Dispel_Magic == nil then RaidAlerter_SET.Dispel_Magic = true; end
	if RaidAlerter_SET.BuffStolen == nil then RaidAlerter_SET.BuffStolen = true; end
	if RaidAlerter_SET.Break_Magic == nil then RaidAlerter_SET.Break_Magic = true; end
	if RaidAlerter_SET.Check_Gem == nil then RaidAlerter_SET.Check_Gem = true; end
	if RaidAlerter_SET.Paladin_Intervention == nil then RaidAlerter_SET.Paladin_Intervention = true; end
	if RaidAlerter_SET.Check_Death_AtCombatEnd == nil then RaidAlerter_SET.Check_Death_AtCombatEnd = true; end
	if RaidAlerter_SET.Nef_PriestDown == nil then RaidAlerter_SET.Nef_PriestDown = false; end
	if RaidAlerter_SET.Nef_TANKPoly == nil then RaidAlerter_SET.Nef_TANKPoly = false; end
	if RaidAlerter_SET.TAQ_Twin_AOEAdd == nil then RaidAlerter_SET.TAQ_Twin_AOEAdd = false; end
	if RaidAlerter_SET.RaidSpell == nil then RaidAlerter_SET.RaidSpell = true; end
	if RaidAlerter_SET.Check_Cooking == nil then RaidAlerter_SET.Check_Cooking = true; end
	if RaidAlerter_SET.Check_Cooking_Whisper == nil then RaidAlerter_SET.Check_Cooking_Whisper = false; end
	if RaidAlerter_SET.Check_Inner_Fire == nil then RaidAlerter_SET.Check_Inner_Fire = true; end
	if RaidAlerter_SET.Check_Inner_Fire_Whisper == nil then RaidAlerter_SET.Check_Inner_Fire_Whisper = false; end
	if RaidAlerter_SET.ShowSysInfo == nil then RaidAlerter_SET.ShowSysInfo = false; end
	if RaidAlerter_SET.cameraMax == nil then RaidAlerter_SET.cameraMax = false; end
end

function RaidAlerter_Check_RAM_CPU(check)
	local smsg_tip = "";

	UpdateAddOnMemoryUsage();
	UpdateAddOnCPUUsage();

	local MEM_Cur = GetAddOnMemoryUsage("RaidAlerter");
	local CPU_Cur = GetAddOnCPUUsage("RaidAlerter");
	local GetTimer = RaidAlerter_GetTimer("RaidAlerter_Check_RAM_CPU");

	smsg_tip = smsg_tip..RAL_TEXT_TIP_26..": ".."|cFFFFFFFF"..format("%.1f",MEM_Cur).."|r".."K (".."|cFFFFFFFF"..format("%.2f",((MEM_Cur - RaidAlerter_Check_RAM_DATA)/GetTimer)).."|r".."K/"..RAL_TEXT_TIP_28..")";
	if(GetCVar("scriptProfile")=="1") then
		smsg_tip = smsg_tip.."\nCPU: ".."|cFFFFFFFF"..format("%.2f",((CPU_Cur - RaidAlerter_Check_CPU_DATA)/GetTimer)).."|r".."/"..RAL_TEXT_TIP_28;
	else
		smsg_tip = smsg_tip.."\nCPU: ".."|cFFFFFFFF".."N/A|r";
	end

	RaidAlerter_Check_RAM_DATA = MEM_Cur;
	RaidAlerter_Check_CPU_DATA = CPU_Cur;
	RaidAlerter_StartTimer("RaidAlerter_Check_RAM_CPU");
	RaidAlerter_StartTimer("RaidAlerter_GameTooltip");
	if check=="tip" then return smsg_tip end
end

--到位检查
function RaidAlerter_CheckPlayer(check)
	if UnitInRaid("player") then
		local RAL_UnVisiblePlayer = "";
		local RAL_DeadPlayer = "";
		local RAL_OfflinePlayer = "";
		local RAL_UnVisiblePlayerCount = 0;
		local RAL_DeadPlayerCount = 0;
		local RAL_OfflinePlayerCount = 0;
		local smsg = "["..RAL_TEXT_CHECK_1.."]";
		local smsg_tip = "|cFF00FF00"..RAL_TEXT_CHECK_1.."|r ";
		for i = 1,GetNumRaidMembers() do
			_, _, subgroup = GetRaidRosterInfo(i);
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				local unit = "raid"..i;
				if UnitIsConnected(unit) then
					if not UnitIsDeadOrGhost(unit) then
						if not UnitIsVisible(unit) then
							RAL_UnVisiblePlayerCount = RAL_UnVisiblePlayerCount + 1;
							if RAL_UnVisiblePlayerCount>0 and RAL_UnVisiblePlayerCount<20 then
								RAL_UnVisiblePlayer = RAL_UnVisiblePlayer..UnitName(unit)..".";
							end
							if RAL_UnVisiblePlayerCount == 20 then
								RAL_UnVisiblePlayer = RAL_UnVisiblePlayer.." "..RAL_TEXT_ETC;
							end
						end
					else
						RAL_DeadPlayerCount = RAL_DeadPlayerCount + 1;
						if RAL_DeadPlayerCount>0 and RAL_DeadPlayerCount<10 then
							RAL_DeadPlayer = RAL_DeadPlayer..UnitName(unit)..".";
						end
						if RAL_DeadPlayerCount == 10 then
							RAL_DeadPlayer = RAL_DeadPlayer.." "..RAL_TEXT_ETC;
						end
					end
				else
					RAL_OfflinePlayerCount = RAL_OfflinePlayerCount + 1;
					if RAL_OfflinePlayerCount>0 and RAL_OfflinePlayerCount<10 then
						RAL_OfflinePlayer = RAL_OfflinePlayer..UnitName(unit)..".";
					end
					if RAL_OfflinePlayerCount == 10 then
						RAL_OfflinePlayer = RAL_OfflinePlayer.." "..RAL_TEXT_ETC;
					end
				end
			end
		end
		if RAL_UnVisiblePlayerCount==0 and RAL_DeadPlayerCount==0 and RAL_OfflinePlayerCount==0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_2,RaidNum);
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_2,"|cFF5588FF"..RaidNum.."|r");
		else
			smsg = smsg..string.format(RAL_TEXT_CHECK_3,(RaidNum-RAL_OfflinePlayerCount-RAL_DeadPlayerCount-RAL_UnVisiblePlayerCount))..".";
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_3,"|cFFFFFFFF"..(RaidNum-RAL_OfflinePlayerCount-RAL_DeadPlayerCount-RAL_UnVisiblePlayerCount).."|r")..".";
			if RAL_OfflinePlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_4,RAL_OfflinePlayerCount)..":"..RAL_OfflinePlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_4,"|cFFEEEE20"..RAL_OfflinePlayerCount.."|r")..".";
			end
			if RAL_DeadPlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_5,RAL_DeadPlayerCount)..":"..RAL_DeadPlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_5,"|cFFFF2020"..RAL_DeadPlayerCount.."|r")..".";
			end
			if RAL_UnVisiblePlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_6,RAL_UnVisiblePlayerCount)..":"..RAL_UnVisiblePlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_6,"|cFFEEEE20"..RAL_UnVisiblePlayerCount.."|r")..".";
			end
		end
		if check=="tip" then
			return smsg_tip;
		else
			RAL.SendMSG(smsg,"RAID",1);
		end
	elseif GetNumPartyMembers() > 0 then
		local RAL_UnVisiblePlayer = "";
		local RAL_DeadPlayer = "";
		local RAL_OfflinePlayer = "";
		local RAL_UnVisiblePlayerCount = 0;
		local RAL_DeadPlayerCount = 0;
		local RAL_OfflinePlayerCount = 0;
		local smsg = "["..RAL_TEXT_CHECK_1.."]";
		local smsg_tip = "|cFF00FF00"..RAL_TEXT_CHECK_1.."|r ";
		local i;
		local unit = "";
		local PartyNum = GetNumPartyMembers() + 1;
		for i = 0, GetNumPartyMembers() do
			if i == 0 then
				unit = "player";
			else
				unit = "party"..i;
			end
			if UnitIsConnected(unit) then
				if not UnitIsDeadOrGhost(unit) then
					if not UnitIsVisible(unit) then
						RAL_UnVisiblePlayerCount = RAL_UnVisiblePlayerCount + 1;
						if RAL_UnVisiblePlayerCount>0 and RAL_UnVisiblePlayerCount<20 then
							RAL_UnVisiblePlayer = RAL_UnVisiblePlayer..UnitName(unit)..".";
						end
						if RAL_UnVisiblePlayerCount == 20 then
							RAL_UnVisiblePlayer = RAL_UnVisiblePlayer.." "..RAL_TEXT_ETC;
						end
					end
				else
					RAL_DeadPlayerCount = RAL_DeadPlayerCount + 1;
					if RAL_DeadPlayerCount>0 and RAL_DeadPlayerCount<10 then
						RAL_DeadPlayer = RAL_DeadPlayer..UnitName(unit)..".";
					end
					if RAL_DeadPlayerCount == 10 then
						RAL_DeadPlayer = RAL_DeadPlayer.." "..RAL_TEXT_ETC;
					end
				end
			else
				RAL_OfflinePlayerCount = RAL_OfflinePlayerCount + 1;
				if RAL_OfflinePlayerCount>0 and RAL_OfflinePlayerCount<10 then
					RAL_OfflinePlayer = RAL_OfflinePlayer..UnitName(unit)..".";
				end
				if RAL_OfflinePlayerCount == 10 then
					RAL_OfflinePlayer = RAL_OfflinePlayer.." "..RAL_TEXT_ETC;
				end
			end
		end
		if RAL_UnVisiblePlayerCount==0 and RAL_DeadPlayerCount==0 and RAL_OfflinePlayerCount==0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_2,PartyNum);
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_2,"|cFF5588FF"..PartyNum.."|r");
		else
			smsg = smsg..string.format(RAL_TEXT_CHECK_3,(PartyNum-RAL_OfflinePlayerCount-RAL_DeadPlayerCount-RAL_UnVisiblePlayerCount))..".";
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_3,"|cFFFFFFFF"..(PartyNum-RAL_OfflinePlayerCount-RAL_DeadPlayerCount-RAL_UnVisiblePlayerCount).."|r")..".";
			if RAL_OfflinePlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_4,RAL_OfflinePlayerCount)..":"..RAL_OfflinePlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_4,"|cFFEEEE20"..RAL_OfflinePlayerCount.."|r")..".";
			end
			if RAL_DeadPlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_5,RAL_DeadPlayerCount)..":"..RAL_DeadPlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_5,"|cFFFF2020"..RAL_DeadPlayerCount.."|r")..".";
			end
			if RAL_UnVisiblePlayerCount>0 then
				smsg = smsg..string.format(RAL_TEXT_CHECK_6,RAL_UnVisiblePlayerCount)..":"..RAL_UnVisiblePlayer;
				smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_6,"|cFFEEEE20"..RAL_UnVisiblePlayerCount.."|r")..".";
			end
		end
		if check=="tip" then
			return smsg_tip;
		else
			RAL.SendMSG(smsg,"PARTY",1);
		end
	else
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTTEAM);
		return;
	end
end

--PvP检查
function RaidAlerter_CheckPvP(check)
	if (not UnitInRaid("player")) then
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTRAID);
		return;
	end
	local RAL_PvPPlayer = "";
	local RAL_PvPPlayerCount = 0;
	local smsg = "["..RAL_TEXT_CHECK_7.."]";
	local smsg_tip = "|cFF00FF00"..RAL_TEXT_CHECK_7.."|r ";
	for i = 1,GetNumRaidMembers() do
		_, _, subgroup = GetRaidRosterInfo(i);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			local unit = "raid"..i;
			if UnitIsPVP(unit) and UnitIsConnected(unit) then
				RAL_PvPPlayerCount = RAL_PvPPlayerCount + 1;
			end
		end
	end

	if RAL_PvPPlayerCount<RaidNum/2 then
		RAL_PvPPlayerCount = 0;
		for i = 1,GetNumRaidMembers() do
			_, _, subgroup = GetRaidRosterInfo(i);
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				local unit = "raid"..i;
				if UnitIsPVP(unit) and UnitIsConnected(unit) then
					RAL_PvPPlayerCount = RAL_PvPPlayerCount + 1;
					if RAL_PvPPlayerCount>0 then
						RAL_PvPPlayer = RAL_PvPPlayer..UnitName(unit)..".";
					end
				end
			end
		end
		if RAL_PvPPlayerCount>0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_8,RAL_PvPPlayerCount)..":"..RAL_PvPPlayer;
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_8,"|cFFEEEE20"..RAL_PvPPlayerCount.."|r")..".";
			if check=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		else
			smsg = smsg..RAL_TEXT_CHECK_9;
			smsg_tip = smsg_tip.."|cFF5588FF"..RAL_TEXT_CHECK_9.."|r";
			if check=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		end
	else
		RAL_PvPPlayerCount = 0;
		for i = 1,GetNumRaidMembers() do
			_, _, subgroup = GetRaidRosterInfo(i);
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				local unit = "raid"..i;
				if (not UnitIsPVP(unit)) and (UnitIsConnected(unit)) then
					RAL_PvPPlayerCount = RAL_PvPPlayerCount + 1;
					if RAL_PvPPlayerCount>0 then
						RAL_PvPPlayer = RAL_PvPPlayer..UnitName(unit)..".";
					end
				end
			end
		end
		if RAL_PvPPlayerCount>0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_10,RAL_PvPPlayerCount)..":"..RAL_PvPPlayer;
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_10,"|cFFEEEE20"..RAL_PvPPlayerCount.."|r")..".";
			if check=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		else
			smsg = smsg..RAL_TEXT_CHECK_11;
			smsg_tip = smsg_tip.."|cFF5588FF"..RAL_TEXT_CHECK_11.."|r";
			if check=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		end
	end
end

function RaidAlerter_CheckFlask(FlaskName, Show)
	if (not UnitInRaid("player")) then
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTRAID);
		return;
	end

	local FlaskText = "";
	local SuperFlask = true;
	local FlaskDATA = {};
	if FlaskName then
		FlaskName = tostring(FlaskName);
		if (FlaskName ~= "") then
			SuperFlask = false;
		end
	end

	if SuperFlask then
		FlaskText = RAL_TEXT_CHECK_12;
		FlaskDATA = RaidAlerter_SuperFlask_TEXT;
	else
		if (FlaskName=="all" or FlaskName=="yj" or FlaskName=="force") then
			FlaskText = RAL_TEXT_CHECK_13;
			FlaskDATA = RaidAlerter_ForceFlask_TEXT;
		else
			FlaskText = FlaskName;
			RaidAlerter_Table_Update(FlaskDATA, FlaskName, "ADD");
		end
	end

	local RAL_FlaskPlayer = "";
	local RAL_FlaskPlayerCount = 0;
	local smsg = "["..FlaskText..RAL_TEXT_CHECK_14.."]";
	local smsg_tip = "|cFF00FF00"..FlaskText..RAL_TEXT_CHECK_14.."|r ";
	for i = 1,GetNumRaidMembers() do
		_, _, subgroup = GetRaidRosterInfo(i);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			local unit = "raid"..i;
			local j = 1;
			local has = 0;
			while ((UnitBuff(unit, j)) and (has == 0)) and UnitIsConnected(unit) do
				for k, v in pairs(FlaskDATA) do
					if string.find(UnitBuff(unit, j), v) then
						has = 1;
						RAL_FlaskPlayerCount = RAL_FlaskPlayerCount + 1;
						break;
					end
				end
				j = j + 1;
			end
		end
	end

	if RAL_FlaskPlayerCount<RaidNum/2 then
		RAL_FlaskPlayerCount = 0;
		for i = 1,GetNumRaidMembers() do
			_, _, subgroup = GetRaidRosterInfo(i);
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				local unit = "raid"..i;
				local j = 1;
				local has = 0;
				while ((UnitBuff(unit, j)) and (has == 0)) and UnitIsConnected(unit) do
					for k, v in pairs(FlaskDATA) do
						if string.find(UnitBuff(unit, j), v) then
							has = 1;
							RAL_FlaskPlayerCount = RAL_FlaskPlayerCount + 1;
							RAL_FlaskPlayer = RAL_FlaskPlayer..UnitName(unit)..".";
							break;
						end
					end
					j = j + 1;
				end
			end
		end
		if RAL_FlaskPlayerCount>0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_15,RAL_FlaskPlayerCount,FlaskText)..": "..RAL_FlaskPlayer;
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_15,"|cFFFFFF99"..RAL_FlaskPlayerCount.."|r",FlaskText)..".";
			if Show=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		else
			smsg = smsg..string.format(RAL_TEXT_CHECK_16,FlaskText);
			smsg_tip = smsg_tip.."|cFFFF5555"..string.format(RAL_TEXT_CHECK_16,FlaskText).."|r";
			if Show=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		end
	else
		RAL_FlaskPlayerCount = 0;
		for i = 1,GetNumRaidMembers() do
			_, _, subgroup = GetRaidRosterInfo(i);
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				local unit = "raid"..i;
				local j = 1;
				local has = 0;
				while ((UnitBuff(unit, j)) and (has == 0)) and UnitIsConnected(unit) do
					for k, v in pairs(FlaskDATA) do
						if string.find(UnitBuff(unit, j), v) then
							has = 1;
							break;
						end
					end
					j = j + 1;
					if (not(UnitBuff(unit, j)) and (has == 0)) then
						RAL_FlaskPlayerCount = RAL_FlaskPlayerCount + 1;
						RAL_FlaskPlayer = RAL_FlaskPlayer..UnitName(unit)..".";
					end
				end
			end
		end
		if RAL_FlaskPlayerCount>0 then
			smsg = smsg..string.format(RAL_TEXT_CHECK_17,RAL_FlaskPlayerCount,FlaskText)..": "..RAL_FlaskPlayer;
			smsg_tip = smsg_tip..string.format(RAL_TEXT_CHECK_17,"|cFFFF5555"..RAL_FlaskPlayerCount.."|r",FlaskText)..".";
			if Show=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		else
			smsg = smsg..string.format(RAL_TEXT_CHECK_18,FlaskText);
			smsg_tip = smsg_tip.."|cFF5588FF"..string.format(RAL_TEXT_CHECK_18,FlaskText).."|r";
			if Show=="tip" then
				return smsg_tip;
			else
				RAL.SendMSG(smsg,"RAID",1);
			end
		end
	end
end

--Buff检查
function RaidAlerter_CheckRaidBuff()
	if (not UnitInRaid("player")) then
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTRAID);
		return;
	end

	local CLASS_INDEX = {
		[1]		= RAL_TEXT_DRUID,
		[2]		= RAL_TEXT_HUNTER,
		[3]		= RAL_TEXT_MAGE,
		[4]		= RAL_TEXT_PRIEST,
		[5]		= RAL_TEXT_ROGUE,
		[6]		= RAL_TEXT_WARLOCK,
		[7]		= RAL_TEXT_WARRIOR,
		[8]		= RAL_TEXT_SHAMAN,
		[9]		= RAL_TEXT_PALADIN,
		[10]	= RAL_TEXT_DEATHKNIGHT,
		};

	local CLASS_COUNT = {
		[1]		= 0,
		[2]		= 0,
		[3]		= 0,
		[4]		= 0,
		[5]		= 0,
		[6]		= 0,
		[7]		= 0,
		[8]		= 0,
		[9]		= 0,
		[10]	= 0,
		};

	local GROUP_COUNT = {
		[1]		= 0,
		[2]		= 0,
		[3]		= 0,
		[4]		= 0,
		[5]		= 0,
		[6]		= 0,
		[7]		= 0,
		[8]		= 0,
		};

	local Group_NoBuff_Name = {
		--耐,智,野性、精神按小队号记录
		[RAL_TEXT_BUFF_4] = {
			[1]	= {["name"]="",["count"]=0,},
			[2]	= {["name"]="",["count"]=0,},
			[3]	= {["name"]="",["count"]=0,},
			[4]	= {["name"]="",["count"]=0,},
			[5]	= {["name"]="",["count"]=0,},
			[6]	= {["name"]="",["count"]=0,},
			[7]	= {["name"]="",["count"]=0,},
			[8]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_6] = {
			[1]	= {["name"]="",["count"]=0,},
			[2]	= {["name"]="",["count"]=0,},
			[3]	= {["name"]="",["count"]=0,},
			[4]	= {["name"]="",["count"]=0,},
			[5]	= {["name"]="",["count"]=0,},
			[6]	= {["name"]="",["count"]=0,},
			[7]	= {["name"]="",["count"]=0,},
			[8]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_8] = {
			[1]	= {["name"]="",["count"]=0,},
			[2]	= {["name"]="",["count"]=0,},
			[3]	= {["name"]="",["count"]=0,},
			[4]	= {["name"]="",["count"]=0,},
			[5]	= {["name"]="",["count"]=0,},
			[6]	= {["name"]="",["count"]=0,},
			[7]	= {["name"]="",["count"]=0,},
			[8]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_22] = {
			[1]	= {["name"]="",["count"]=0,},
			[2]	= {["name"]="",["count"]=0,},
			[3]	= {["name"]="",["count"]=0,},
			[4]	= {["name"]="",["count"]=0,},
			[5]	= {["name"]="",["count"]=0,},
			[6]	= {["name"]="",["count"]=0,},
			[7]	= {["name"]="",["count"]=0,},
			[8]	= {["name"]="",["count"]=0,},
			},
		--QS祝福按职业记录
		[RAL_TEXT_BUFF_12] = {
			[RAL_TEXT_DRUID]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_HUNTER]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_MAGE]			= {["name"]="",["count"]=0,},
			[RAL_TEXT_PRIEST]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_ROGUE]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARLOCK]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARRIOR]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_SHAMAN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_PALADIN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_DEATHKNIGHT]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_14] = {
			[RAL_TEXT_DRUID]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_HUNTER]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_MAGE]			= {["name"]="",["count"]=0,},
			[RAL_TEXT_PRIEST]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_ROGUE]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARLOCK]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARRIOR]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_SHAMAN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_PALADIN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_DEATHKNIGHT]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_16] = {
			[RAL_TEXT_DRUID]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_HUNTER]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_MAGE]			= {["name"]="",["count"]=0,},
			[RAL_TEXT_PRIEST]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_ROGUE]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARLOCK]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARRIOR]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_SHAMAN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_PALADIN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_DEATHKNIGHT]	= {["name"]="",["count"]=0,},
			},
		[RAL_TEXT_BUFF_18] = {
			[RAL_TEXT_DRUID]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_HUNTER]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_MAGE]			= {["name"]="",["count"]=0,},
			[RAL_TEXT_PRIEST]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_ROGUE]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARLOCK]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_WARRIOR]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_SHAMAN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_PALADIN]		= {["name"]="",["count"]=0,},
			[RAL_TEXT_DEATHKNIGHT]	= {["name"]="",["count"]=0,},
			},
		};
	local LostFQBuff_NAME = "";			--记录未开正义之怒的防骑名字
	local LostPRIESTBuff_NAME = "";		--记录未开心灵之火的牧师名字
	local LostCOOKINGBuff_NAME = "";	--记录无进食充分的玩家名字

	local HasPRIEST = false;
	local HasMAGE = false;
	local HasDRUID = false;
	local HasPALADIN_12 = false;
	local HasPALADIN_14 = false;
	local HasPALADIN_16 = false;
	local HasPALADIN_18 = false;
	local NoBuffCount = 0;
	local HasCookingCount = 0;
	local OnlineRaidMembers = 0;
	local OfflineRaidMembers = 0;

	for i = 1,GetNumRaidMembers() do
		local _, _, subgroup, _, class, _, _, online = GetRaidRosterInfo(i);
		if online then
			if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				if class == RAL_TEXT_DRUID then CLASS_COUNT[1] = CLASS_COUNT[1] + 1; HasDRUID = true; end
				if class == RAL_TEXT_HUNTER then CLASS_COUNT[2] = CLASS_COUNT[2] + 1; end
				if class == RAL_TEXT_MAGE then CLASS_COUNT[3] = CLASS_COUNT[3] + 1; HasMAGE = true; end
				if class == RAL_TEXT_PRIEST then CLASS_COUNT[4] = CLASS_COUNT[4] + 1; HasPRIEST = true; end
				if class == RAL_TEXT_ROGUE then CLASS_COUNT[5] = CLASS_COUNT[5] + 1; end
				if class == RAL_TEXT_WARLOCK then CLASS_COUNT[6] = CLASS_COUNT[6] + 1; end
				if class == RAL_TEXT_WARRIOR then CLASS_COUNT[7] = CLASS_COUNT[7] + 1; end
				if class == RAL_TEXT_SHAMAN then CLASS_COUNT[8] = CLASS_COUNT[8] + 1; end
				if class == RAL_TEXT_PALADIN then CLASS_COUNT[9] = CLASS_COUNT[9] + 1; end
				if class == RAL_TEXT_DEATHKNIGHT then CLASS_COUNT[10] = CLASS_COUNT[10] + 1; end
				GROUP_COUNT[subgroup] = GROUP_COUNT[subgroup] + 1;
			end
		end
	end

	if CLASS_COUNT[9] >= 1 then HasPALADIN_12 = true; end							--1QS检查王者
	if CLASS_COUNT[9] >= 2 then HasPALADIN_16 = true; HasPALADIN_18 = true; end		--2QS增加智慧、力量祝福检查
	if CLASS_COUNT[9] >= 3 then HasPALADIN_14 = true; end							--3QS增加庇护祝福检查

	for i = 1,GetNumRaidMembers() do
		local name, _, subgroup, _, class = GetRaidRosterInfo(i);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			local unit = "raid"..i;
			local j = 1;
			local HasPRIEST_BUFF_1 = false;		--耐
			local HasPRIEST_BUFF_2 = false;		--精神
			local IsPRIEST = false;
			local HasPRIEST_BUFF = false;		--心灵之火
			local HasMAGE_BUFF = false;
			local HasDRUID_BUFF = false;
			local HasPALADIN_BUFF_12 = false;
			local HasPALADIN_BUFF_14 = false;
			local HasPALADIN_BUFF_16 = false;
			local HasPALADIN_BUFF_18 = false;
			local IsFQ = false;
			local HasFQBuff = false;
			local HasCookingBuff = false;		--进食充分
			if not UnitIsConnected(unit) then
				HasPRIEST_BUFF_1 = true;
				HasPRIEST_BUFF_2 = true;
				IsPRIEST = true;
				HasPRIEST_BUFF = true;
				HasMAGE_BUFF = true;
				HasDRUID_BUFF = true;
				HasPALADIN_BUFF_12 = true;
				HasPALADIN_BUFF_14 = true;
				HasPALADIN_BUFF_16 = true;
				HasPALADIN_BUFF_18 = true;
				IsFQ = true;
				HasFQBuff = true;
				HasCookingBuff = true;
				OfflineRaidMembers = OfflineRaidMembers + 1;
			else
				OnlineRaidMembers = OnlineRaidMembers + 1;
			end
			while UnitBuff(unit, j) do
				local BuffTEXT = UnitBuff(unit, j);
				if string.find(BuffTEXT, RAL_TEXT_BUFF_4) or string.find(BuffTEXT, RAL_TEXT_BUFF_5) then
					HasPRIEST_BUFF_1 = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_22) or string.find(BuffTEXT, RAL_TEXT_BUFF_23) then
					HasPRIEST_BUFF_2 = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_6) or string.find(BuffTEXT, RAL_TEXT_BUFF_7) or string.find(BuffTEXT, RAL_TEXT_BUFF_7_SPEC_1) or string.find(BuffTEXT, RAL_TEXT_BUFF_7_SPEC_2) then
					HasMAGE_BUFF = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_8) or string.find(BuffTEXT, RAL_TEXT_BUFF_9) then
					HasDRUID_BUFF = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_12) or string.find(BuffTEXT, RAL_TEXT_BUFF_13)
				or string.find(BuffTEXT, RAL_TEXT_BUFF_13_SPEC_1) then
					HasPALADIN_BUFF_12 = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_14) or string.find(BuffTEXT, RAL_TEXT_BUFF_15) then
					HasPALADIN_BUFF_14 = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_16) or string.find(BuffTEXT, RAL_TEXT_BUFF_17) or string.find(BuffTEXT, RAL_TEXT_BUFF_17_SPEC_1) then
					HasPALADIN_BUFF_16 = true;
				end
				if string.find(BuffTEXT, RAL_TEXT_BUFF_18) or string.find(BuffTEXT, RAL_TEXT_BUFF_19) or string.find(BuffTEXT, RAL_TEXT_BUFF_19_SPEC_1) then
					HasPALADIN_BUFF_18 = true;
				end
				if UnitPowerType(unit) ~= 0 then		--忽略无蓝条职业的精神
					HasPRIEST_BUFF_2 = true;
				end
				if class == RAL_TEXT_DRUID then
					--忽略野德的智力和智慧（猎豹和熊状态/HP>MP则判定为野德）
					if (string.find(BuffTEXT, RAL_TEXT_BUFF_3) or string.find(BuffTEXT, RAL_TEXT_BUFF_20))
					 or ((UnitHealthMax(unit) > (UnitManaMax(unit)*1.4))) then
						HasMAGE_BUFF = true;
						HasPALADIN_BUFF_16 = true;
					end
					--忽略鸟德和奶德的力量
					if (string.find(BuffTEXT, RAL_TEXT_BUFF_26) or string.find(BuffTEXT, RAL_TEXT_BUFF_27))
					 or ((UnitManaMax(unit) > (UnitHealthMax(unit)*0.7))) then
						HasPALADIN_BUFF_18 = true;
					end
				end
				if class == RAL_TEXT_SHAMAN then
					--忽略增强萨满的智慧（HP>>MP）
					if UnitHealthMax(unit) > (UnitManaMax(unit)*1.4) then
						HasPALADIN_BUFF_16 = true;
					end
					--忽略元素和恢复萨满的力量（HP>>MP）
					if UnitManaMax(unit) > (UnitHealthMax(unit)*0.7) then
						HasPALADIN_BUFF_18 = true;
					end
				end
				if (class == RAL_TEXT_ROGUE) or (class == RAL_TEXT_WARRIOR) or (class == RAL_TEXT_DEATHKNIGHT) then
					HasMAGE_BUFF = true;		--忽略潜行者、战士和死亡骑士的智力
				end
				if class == RAL_TEXT_PALADIN then
					if RaidAlerter_TestIsMtList(unit) then
						--检查FQ坦的正义之怒
						IsFQ = true;
						if string.find(BuffTEXT, RAL_TEXT_BUFF_21) then
							HasFQBuff = true;
						end
					else
						--忽略神圣骑士的的力量（MP>>HP）
						if UnitManaMax(unit) > (UnitHealthMax(unit)*0.7) then
							HasPALADIN_BUFF_18 = true;
						end
					end

				end
				if class == RAL_TEXT_PRIEST then
					--检查牧师的心灵之火
					IsPRIEST = true;
					if string.find(BuffTEXT, RAL_TEXT_BUFF_25) then
						HasPRIEST_BUFF = true;
					end
				end
				--检查进食充分
				if string.find(BuffTEXT, RAL_TEXT_BUFF_24) then
					HasCookingBuff = true;
				end
--				if (HasPRIEST_BUFF_1 and HasPRIEST_BUFF_2 and HasMAGE_BUFF and HasDRUID_BUFF and HasPALADIN_BUFF_12 and HasPALADIN_BUFF_14
--				and HasPALADIN_BUFF_16 and HasPALADIN_BUFF_18 and ((IsFQ and HasFQBuff) or (not IsFQ))) then j = 99; end
				j = j + 1;
			end
			if (not HasPRIEST_BUFF_1) and HasPRIEST then
				Group_NoBuff_Name[RAL_TEXT_BUFF_4][subgroup]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_4][subgroup]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_4][subgroup]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_4][subgroup]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			if (not HasPRIEST_BUFF_2) and HasPRIEST then
				Group_NoBuff_Name[RAL_TEXT_BUFF_22][subgroup]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_22][subgroup]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_22][subgroup]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_22][subgroup]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			if (not HasMAGE_BUFF) and HasMAGE then
				Group_NoBuff_Name[RAL_TEXT_BUFF_6][subgroup]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_6][subgroup]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_6][subgroup]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_6][subgroup]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			if (not HasDRUID_BUFF) and HasDRUID then
				Group_NoBuff_Name[RAL_TEXT_BUFF_8][subgroup]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_8][subgroup]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_8][subgroup]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_8][subgroup]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			if (not HasPALADIN_BUFF_12) and HasPALADIN_12 then
				Group_NoBuff_Name[RAL_TEXT_BUFF_12][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_12][class]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_12][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_12][class]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			if (not HasPALADIN_BUFF_14) and HasPALADIN_14 then
				--检查庇护祝福
				Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["name"]..name..".";
				Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["count"] + 1;
				NoBuffCount = NoBuffCount + 1;
			end
			--[[
			--注意: 这段检测拯救祝福的代码已废除!!
			if (not HasPALADIN_BUFF_14) and HasPALADIN_14 then
				if (class == RAL_TEXT_HUNTER) or (class == RAL_TEXT_MAGE) or (class == RAL_TEXT_ROGUE) or (class == RAL_TEXT_WARLOCK) then
				--(3.0起停用)只检查4个纯dps职业的拯救：猎人、法师、潜行者、术士
					Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["name"]..name..".";
					Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_14][class]["count"] + 1;
					NoBuffCount = NoBuffCount + 1;
				end
			end
			]]--
			--3.2-4.0过渡
			if GameVER >= 40000 then
				if (not HasPALADIN_BUFF_18) and HasPALADIN_18 then
					--4.0.3检查所有职业的力量祝福（智慧祝福已合并到力量祝福）
					Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["name"]..name..".";
					Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["count"] + 1;
					NoBuffCount = NoBuffCount + 1;
				end
			else
				if (not HasPALADIN_BUFF_16) and HasPALADIN_16 then
					if (class == RAL_TEXT_DRUID) or (class == RAL_TEXT_MAGE) or (class == RAL_TEXT_PRIEST)
					 or (class == RAL_TEXT_WARLOCK) or (class == RAL_TEXT_SHAMAN) or (class == RAL_TEXT_PALADIN) then
					--只检查6个法系职业的智慧祝福：德鲁伊、法师、牧师、术士、萨满祭司、圣骑士
						Group_NoBuff_Name[RAL_TEXT_BUFF_16][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_16][class]["name"]..name..".";
						Group_NoBuff_Name[RAL_TEXT_BUFF_16][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_16][class]["count"] + 1;
						NoBuffCount = NoBuffCount + 1;
					end
				end
				if (not HasPALADIN_BUFF_18) and HasPALADIN_18 then
					if (class == RAL_TEXT_ROGUE) or (class == RAL_TEXT_WARRIOR) or (class == RAL_TEXT_DEATHKNIGHT) or (class == RAL_TEXT_HUNTER)
					 or (class == RAL_TEXT_PALADIN) or (class == RAL_TEXT_SHAMAN) or (class == RAL_TEXT_DRUID) then
					--只检查7个AP职业的力量祝福：潜行者、战士、死亡骑士、猎人、德鲁伊、萨满祭司、圣骑士
						Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["name"] = Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["name"]..name..".";
						Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["count"] = Group_NoBuff_Name[RAL_TEXT_BUFF_18][class]["count"] + 1;
						NoBuffCount = NoBuffCount + 1;
					end
				end
			end
			if IsFQ and (not HasFQBuff) then
				LostFQBuff_NAME = LostFQBuff_NAME..name..".";
				NoBuffCount = NoBuffCount + 1;
				RaidAlerter_Whisper(name, RAL_TEXT_ALERT_42);
			end
			if IsPRIEST and (not HasPRIEST_BUFF) then
				LostPRIESTBuff_NAME = LostPRIESTBuff_NAME..name..".";
				if RaidAlerter_SET.Check_Inner_Fire_Whisper then
					NoBuffCount = NoBuffCount + 1;
					RaidAlerter_Whisper(name, RAL_TEXT_ALERT_45);
				end
			end
			if not HasCookingBuff then
				LostCOOKINGBuff_NAME = LostCOOKINGBuff_NAME..name..".";
				if RaidAlerter_SET.Check_Cooking then
					NoBuffCount = NoBuffCount + 1;
					if RaidAlerter_SET.Check_Cooking_Whisper and (RaidAlerter_GetTimer("COOKFOOD_CREAT") < (COOKFOODDUR-15)) then
						RaidAlerter_Whisper(name, RAL_TEXT_ALERT_47);
					end
				end
			else
				if UnitIsConnected(unit) then
					HasCookingCount = HasCookingCount + 1;
				end
			end
		end
	end
	if NoBuffCount == 0 then
		RAL.SendMSG(RAL_TEXT_CHECK_19,"RAID",1);
	else
		RAL.SendMSG(string.format(RAL_TEXT_CHECK_20,NoBuffCount),"RAID",1);
		local msg = "";
		if HasPRIEST then
			msg = "";
			for i = 1, RaidAlerter_SET.RAIDMODE_MAX_GROUP do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_4][i]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_4][i]["count"] >= GROUP_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_4][i]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format(RAL_TEXT_CHECK_22,i,Group_NoBuff_Name[RAL_TEXT_BUFF_4][i]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_CHECK_23..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
			msg = "";
			for i = 1, RaidAlerter_SET.RAIDMODE_MAX_GROUP do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_22][i]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_22][i]["count"] >= GROUP_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_22][i]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format(RAL_TEXT_CHECK_22,i,Group_NoBuff_Name[RAL_TEXT_BUFF_22][i]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_22..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasMAGE then
			msg = "";
			for i = 1, RaidAlerter_SET.RAIDMODE_MAX_GROUP do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_6][i]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_6][i]["count"] >= GROUP_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_6][i]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format(RAL_TEXT_CHECK_22,i,Group_NoBuff_Name[RAL_TEXT_BUFF_6][i]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_7..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasDRUID then
			msg = "";
			for i = 1, RaidAlerter_SET.RAIDMODE_MAX_GROUP do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_8][i]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_8][i]["count"] >= GROUP_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_8][i]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format(RAL_TEXT_CHECK_22,i,Group_NoBuff_Name[RAL_TEXT_BUFF_8][i]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_9..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasPALADIN_12 then
			msg = "";
			for i = 1, 10 do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_12][CLASS_INDEX[i]]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_12][CLASS_INDEX[i]]["count"] >= CLASS_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_12][CLASS_INDEX[i]]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format("%s(%s)",CLASS_INDEX[i],Group_NoBuff_Name[RAL_TEXT_BUFF_12][CLASS_INDEX[i]]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_12..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasPALADIN_14 then
			msg = "";
			for i = 1, 10 do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_14][CLASS_INDEX[i]]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_14][CLASS_INDEX[i]]["count"] >= CLASS_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_14][CLASS_INDEX[i]]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format("%s(%s)",CLASS_INDEX[i],Group_NoBuff_Name[RAL_TEXT_BUFF_14][CLASS_INDEX[i]]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_14..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasPALADIN_16 then
			msg = "";
			for i = 1, 10 do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_16][CLASS_INDEX[i]]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_16][CLASS_INDEX[i]]["count"] >= CLASS_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_16][CLASS_INDEX[i]]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format("%s(%s)",CLASS_INDEX[i],Group_NoBuff_Name[RAL_TEXT_BUFF_16][CLASS_INDEX[i]]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_16..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if HasPALADIN_18 then
			msg = "";
			for i = 1, 10 do
				if Group_NoBuff_Name[RAL_TEXT_BUFF_18][CLASS_INDEX[i]]["name"] ~= "" then
					if Group_NoBuff_Name[RAL_TEXT_BUFF_18][CLASS_INDEX[i]]["count"] >= CLASS_COUNT[i] then
						Group_NoBuff_Name[RAL_TEXT_BUFF_18][CLASS_INDEX[i]]["name"] = RAL_TEXT_CHECK_21;
					end
					msg = msg..string.format("%s(%s)",CLASS_INDEX[i],Group_NoBuff_Name[RAL_TEXT_BUFF_18][CLASS_INDEX[i]]["name"]).." ";
				end
			end
			if msg ~= "" then
				msg = RAL_TEXT_BUFF_18..": "..msg;
				RAL.SendMSG(msg,"RAID",1);
			end
		end
		if LostFQBuff_NAME ~= "" then
			RAL.SendMSG(RAL_TEXT_ALERT_43..": "..LostFQBuff_NAME,"RAID",1);
		end
		if RaidAlerter_SET.Check_Inner_Fire and (LostPRIESTBuff_NAME ~= "") then
			RAL.SendMSG(RAL_TEXT_ALERT_46..": "..LostPRIESTBuff_NAME,"RAID",1);
		end
		if RaidAlerter_SET.Check_Cooking then
			local bShowCookingDetail = false;
			msg = "";
			--若放置的团队烹饪食物还未消失，则检查进食充分buff
			if RaidAlerter_GetTimer("COOKFOOD_CREAT") < (COOKFOODDUR-15) then
				--若已有进食充分的玩家超过1/3才显示详细的未进食名单, 否则只显示概况
				if HasCookingCount >= (OnlineRaidMembers / 3) then
					if HasCookingCount >= OnlineRaidMembers then
						bShowCookingDetail = true;
						RAL.SendMSG(RAL_TEXT_BUFF_24..": "..RAL_TEXT_CHECK_35,"RAID",1);
					else
						if LostCOOKINGBuff_NAME ~= "" then
							bShowCookingDetail = true;
							msg = string.format("%s"..RAL_TEXT_CHECK_37, RAL_TEXT_ALERT_48, (OnlineRaidMembers-HasCookingCount));
							RAL.SendMSG(msg..": "..LostCOOKINGBuff_NAME,"RAID",1);
						end
					end
				end
			end
			if not bShowCookingDetail then
				--若已有进食充分的玩家超过半数才显示详细的未进食名单, 否则只显示概况
				if HasCookingCount >= (OnlineRaidMembers / 2) then
					if HasCookingCount >= OnlineRaidMembers then
						RAL.SendMSG(RAL_TEXT_BUFF_24..": "..RAL_TEXT_CHECK_35,"RAID",1);
					else
						if LostCOOKINGBuff_NAME ~= "" then
							msg = string.format("%s"..RAL_TEXT_CHECK_37, RAL_TEXT_ALERT_48, (OnlineRaidMembers-HasCookingCount));
							RAL.SendMSG(msg..": "..LostCOOKINGBuff_NAME,"RAID",1);
						end
					end
				else
					if HasCookingCount <= 0 then
						msg = RAL_TEXT_CHECK_21;
					elseif HasCookingCount >= OnlineRaidMembers then
						--msg = string.format(RAL_TEXT_CHECK_18, RAL_TEXT_BUFF_24);
						msg = RAL_TEXT_CHECK_35;
					elseif (OnlineRaidMembers-HasCookingCount) > 0 then
						msg = string.format(RAL_TEXT_CHECK_36, HasCookingCount, (OnlineRaidMembers-HasCookingCount));
					else
						msg = string.format(RAL_TEXT_CHECK_15, HasCookingCount, RAL_TEXT_BUFF_24)..", ";
					end
					RAL.SendMSG(RAL_TEXT_BUFF_24..": "..msg,"RAID",1);
				end
			end
		end
	end
end

--通报玩家目标锁定状况（默认检查MT）
function RaidAlerter_Target_Check(check)
	if (not UnitInRaid("player")) then
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTRAID);
		return;
	end
	if ((not check) or check=="") then
		check = "MT";
	end
	local ICON_COUNT = {
			[1]	= 0,
			[2]	= 0,
			[3]	= 0,
			[4]	= 0,
			[5]	= 0,
			[6]	= 0,
			[7]	= 0,
			[8]	= 0,
						};
	local NAME_COUNT = {
			[1]	= "",
			[2]	= "",
			[3]	= "",
			[4]	= "",
			[5]	= "",
			[6]	= "",
			[7]	= "",
			[8]	= "",
						};
	local SAME_NUM = 0;
	local NONE_NUM = 0;
	local msgend = RAL_TEXT_CHECK_29;
	local msg2 = "";
	local msg3 = "";
	local MSG_NAME = "";
	local MSG_ICON = "";
	local MSG_TARNAME = "";
	if string.upper(check) == "MT" then
		if not RaidAlerter_TestMtHasSet() then
			RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_CHECK_24);
			return;
		end
		RAL.SendMSG(string.format(RAL_TEXT_CHECK_28,check),"RAID",1);

		local i;
		for i = 1, 5 do
			if (RAL_Tanks[i]) then
				MSG_NAME = "("..i.."T)"..RAL_Tanks[i];
				local unit = RaidAlerter_NameToUnit(RAL_Tanks[i]);
				if (unit) then
					if UnitName(unit.."target") then
						MSG_TARNAME = UnitName(unit.."target");
						local icon = GetRaidTargetIndex(unit.."target");
						if icon then
							MSG_ICON = RaidAlerter_RAIDICON[icon];
							ICON_COUNT[icon] = ICON_COUNT[icon] + 1;
							NAME_COUNT[icon] = NAME_COUNT[icon]..UnitName(unit)..".";
						else
							MSG_ICON = "";
						end
						if not UnitIsEnemy("player", unit.."target") then
							NONE_NUM = NONE_NUM + 1;
							msg3 = msg3..UnitName(unit)..".";
						end
					else
						MSG_TARNAME = RAL_TEXT_CHECK_31;
						MSG_ICON = "";
						NONE_NUM = NONE_NUM + 1;
						msg3 = msg3..UnitName(unit)..".";
					end
					RAL.SendMSG(string.format(RAL_TEXT_CHECK_30,MSG_NAME,MSG_ICON,MSG_TARNAME),"RAID",1);
				end
			end
		end
	else
		if (string.upper(check)=="XD" or string.upper(check)=="DLY") then check=RAL_TEXT_DRUID; end
		if (string.upper(check)=="LR") then check=RAL_TEXT_HUNTER; end
		if (string.upper(check)=="FS") then check=RAL_TEXT_MAGE; end
		if (string.upper(check)=="MS") then check=RAL_TEXT_PRIEST; end
		if (string.upper(check)=="DZ" or string.upper(check)=="QXZ") then check=RAL_TEXT_ROGUE; end
		if (string.upper(check)=="SS") then check=RAL_TEXT_WARLOCK; end
		if (string.upper(check)=="ZS") then check=RAL_TEXT_WARRIOR; end
		if (string.upper(check)=="SM" or string.upper(check)=="SMJS") then check=RAL_TEXT_SHAMAN; end
		if (string.upper(check)=="QS" or string.upper(check)=="SQS") then check=RAL_TEXT_PALADIN; end
		if (check==RAL_TEXT_DRUID) or (check==RAL_TEXT_HUNTER) or (check==RAL_TEXT_MAGE) or
		(check==RAL_TEXT_PRIEST) or (check==RAL_TEXT_ROGUE) or (check==RAL_TEXT_WARLOCK) or
		(check==RAL_TEXT_WARRIOR) or (check==RAL_TEXT_SHAMAN) or (check==RAL_TEXT_PALADIN) then
			RAL.SendMSG(string.format(RAL_TEXT_CHECK_28,check),"RAID",1);
			for i = 1,GetNumRaidMembers() do
				local _, _, subgroup, _, class = GetRaidRosterInfo(i);
				if (class == check) and (subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP) then
					local unit = "raid"..i;
					MSG_NAME = UnitName(unit);
					if UnitName(unit.."target") then
						MSG_TARNAME = UnitName(unit.."target");
						local icon = GetRaidTargetIndex(unit.."target");
						if icon then
							MSG_ICON = RaidAlerter_RAIDICON[icon];
							ICON_COUNT[icon] = ICON_COUNT[icon] + 1;
							NAME_COUNT[icon] = NAME_COUNT[icon]..UnitName(unit)..".";
						else
							MSG_ICON = "";
						end
						if not UnitIsEnemy("player", unit.."target") then
							NONE_NUM = NONE_NUM + 1;
							msg3 = msg3..UnitName(unit)..".";
						end
					else
						MSG_TARNAME = RAL_TEXT_CHECK_31;
						MSG_ICON = "";
						NONE_NUM = NONE_NUM + 1;
						msg3 = msg3..UnitName(unit)..".";
					end
					RAL.SendMSG(string.format(RAL_TEXT_CHECK_30,MSG_NAME,MSG_ICON,MSG_TARNAME),"RAID",1);
				end
			end
		else
			RaidAlerter.AddMsg(string.format(RAL_TEXT_CHECK_32,"|cFFFF5555"..check.."|r"));
			return;
		end
	end

	if NONE_NUM > 0 then
		msgend = msgend..string.format(RAL_TEXT_CHECK_33,NONE_NUM)..msg3;
	end
	for i = 1, 8 do
		if ICON_COUNT[i] > 1 then
			SAME_NUM = SAME_NUM + ICON_COUNT[i];
			msg2 = msg2.."("..RaidAlerter_RAIDICON[i]..":"..NAME_COUNT[i]..") ";
		end
	end
	if msg2 ~= "" then
		msgend = msgend..string.format(RAL_TEXT_CHECK_34,SAME_NUM)..msg2;
	end
	RAL.SendMSG(msgend,"RAID",1);
end

--通报灵魂石绑定状态
function RaidAlerter_CheckGem(check)
	if (not UnitInRaid("player")) then
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_OUTRAID);
		return;
	end
	RAL.SendMSG(string.format(RAL_TEXT_TIP_6,#GemName)..": "..RaidAlerter_GetGemOnNames(),"RAID",1);
end

function RaidAlerter_Check_CTRAORA_LA_TANKS()
	if (not UnitInRaid("player")) then
		return;
	end
	if RaidAlerter_TestMtHasSet() then
		RaidAlerter.AddMsg(string.format(RAL_TEXT_CHECK_26,"|cFF20FF20"..RaidAlerter_TestMtHasSet().."|r"));
		for k, v in pairs(RAL_Tanks) do
			RaidAlerter.AddMsg(RAL.ToRed(k.."T")..RAL.ToGreen(RAL_TEXT_ARROW_R)..RaidAlerter_ToClassColorNameText(v));
		end
	else
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_CHECK_24);
	end
	if (IsRaidLeader() or IsRaidOfficer()) then
		RaidAlerter.AddMsg("|cFF20FF20"..RAL_TEXT_CHECK_27);
	else
		RaidAlerter.AddMsg("|cFFFF5555"..RAL_TEXT_CHECK_25);
	end
end

function RaidAlerter_OnEvent(self, event, ...)
	if (event=="ADDON_LOADED") then
		local addon = ...
		if addon ~="RaidAlerter" then return end
		if RaidAlerter_SET.TextMShow_OnOff then
			RaidAlerter_Attack_Frame:Show();
			RaidAlerter_SET_FUNC_AF_Scale();
		else
			RaidAlerter_Attack_Frame:Hide()
		end
		RaidAlerter_Check_Variables();
		RaidAlerter_ChatFrame_Filter(self);
		BF_RaidAlerter_LoadPosition(RaidAlerter_Attack_Frame);
		self:UnregisterEvent("ADDON_LOADED")
	elseif (event=="PLAYER_ENTERING_WORLD") then
		RaidAlerter_SET_AttackFramePosition= RaidAlerter_SET_AttackFramePosition or {"TOP","UIParent","TOP",20,-12}
		BF_RaidAlerter_LoadPosition(RaidAlerter_Attack_Frame);
--		if UnitInRaid("player") or UnitInParty("player") then
--			RaidAlerter.AddMsg(RAL_TEXT_MINDMSG.."|cFF5588FF/ral help|r");
--		end
		RaidAlerter_SetCameraMaxToMax();
		RaidAlerter_Option_MainFrame_Update();
	elseif (event=="CHAT_MSG_ADDON") then
		local ARG_1, ARG_2, ARG_3, ARG_4 = ...;
		if string.sub(ARG_1, 1, 4) == "RAL_" then
--			if RAL_DEBUG then RaidAlerter.AddMsg(ARG_1.."↑"..ARG_2.."↑"..ARG_3.."↑"..ARG_4);end		--debug
			if ARG_3=="PARTY" or ARG_3=="RAID" or ARG_3=="BATTLEGROUND" then
				RaidAlerter_SYNC(ARG_1,ARG_2,ARG_3,ARG_4);
			end
		end
	elseif event == "UNIT_THREAT_SITUATION_UPDATE" then
		local ARG_1 = ...;
		RaidAlerter_THREAT_UPDATE(ARG_1);
	elseif event == "PLAYER_REGEN_ENABLED" then
		MyLastThreatState = 0;
		TarTarISME = false;
	elseif event == "RAID_ROSTER_UPDATE" or event == "PARTY_MEMBERS_CHANGED" then
		RosterChanged = true;
	elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" or event == "ZONE_CHANGED_NEW_AREA" then
		RaidAlerter_GetCurrentDifficulty();
		local CUR_MAX_GROUP = floor((maxPlayers+4)/5);
		if (instanceType == "pvp" and maxPlayers == 0) then CUR_MAX_GROUP = 8;end
		--GetWintergraspWaitTime 4.06后失效
		if GameVER < 40600 then
			if (GetWintergraspWaitTime() == nil) and (GetZoneText() == RAL_TEXT_ZONE_5) then CUR_MAX_GROUP = 8;end
		end
		if CUR_MAX_GROUP > 1 then
			if CUR_MAX_GROUP ~= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				UIDropDownMenu_SetSelectedID(RaidAlerter_RAIDMODEList, (CUR_MAX_GROUP-1));
				RaidAlerter_RAIDMODE_MAX_GROUP_SETUP(CUR_MAX_GROUP);
			end
		end
	end
end

function RaidAlerter_CombatLogEvent(self, timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, spellId, spellName, spellSchool, auraType, amount, ...)
	if RaidAlerter_SET.OnOff then
		RaidAlerter_Raid_PARTY_Combat_Alerter(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, spellId, spellName, spellSchool, auraType, amount);
	end
end

function RaidAlerter_ChatFrame_Filter(self)
	ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", function(self, event, msg)
		if not RaidAlerter_SET.OTMShow_OnOff then
			if msg:match("<RaidAlerter> ") then
				return true;
			end
		end
	end)
	ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", function(self, event, msg)
		if not RaidAlerter_SET.OTMShow_OnOff then
			if msg:match("<BWS>") and UnitAffectingCombat("player")==1 then
				return true;
			end
		end
	end)
end

function RaidAlerter_SYNC(ARG_1,ARG_2,ARG_3,ARG_4)
	if ARG_1=="RAL_SELECT" then
		local RAL_SYNC_PAR = "";

		local SETONCOUNT = 0;
		--传递设置参数，优先取用开启警报项目较全者为报警方（基于默认设定项目）
		if RaidAlerter_SET.BossHealthPecentOnOff then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.BossKill then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.TANK_DangerHealth then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.TANK_Death then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.TANK_ShieldWall then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.TANK_LastStand then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.TANK_ShieldReflection then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Hunter_Misdirection then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Hunter_Shot then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.TANK_Taunt then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.RES_DispelMagic then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.RES_Polymorph then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.RES_MagicBreak then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.RES_BuffStolen then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Check_Poly then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.PolyDispel then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Break_Poly then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.Dispel_Magic then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.BuffStolen then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Break_Magic then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Check_Gem then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Paladin_Intervention then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.Check_Death_AtCombatEnd then SETONCOUNT = SETONCOUNT + 0.5;end
		if RaidAlerter_SET.OT_OnOff then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.RaidSpell then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.Check_Cooking then SETONCOUNT = SETONCOUNT + 1;end
		if RaidAlerter_SET.Check_Inner_Fire then SETONCOUNT = SETONCOUNT + 1;end

		--不适宜做警报方的检测修正
		if not(oRA or oRA3 or CT_RA_MainTanks) then SETONCOUNT = SETONCOUNT - 2;end		--无团队助手

		SETONCOUNT = floor(SETONCOUNT);
		if SETONCOUNT<1 then SETONCOUNT = 1;end
		if SETONCOUNT>16 then SETONCOUNT = 16;end

		if RaidAlerter_SYNC_SELECT_SETTOME == 0 then
			SETONCOUNT = SETONCOUNT + RaidAlerter_SYNC_VerPOINT;
		end
		if RaidAlerter_SYNC_SELECT_SETTOME == 2 then
			SETONCOUNT = 1;
		end
		if RaidAlerter_SYNC_SELECT_SETTOME == 1 then
			SETONCOUNT = 99;
		end
		if (UnitInRaid("player")) then
			if RaidAlerter_NameToGroup(UnitName("player")) > RaidAlerter_SET.RAIDMODE_MAX_GROUP then	--自己属于替补
				SETONCOUNT = 1;
			end
		end
		if UnitIsGhost("player") then	--灵魂中
			SETONCOUNT = 1;
		end

		RAL_SYNC_PAR = SETONCOUNT..RAL_SYNC_PAR;

		--附加传递性能参数，大者为优。若开启警报项目数量一致则取游戏性能较好的玩家为报警方
		local _,_,RAL_SYNC_latency = GetNetStats();
		RAL_SYNC_PAR = RAL_SYNC_PAR..format("%012d",((10000/(RAL_SYNC_latency+10))+((GetFramerate()/10) + (random(100)/100)))*1000000);

		RaidAlerter_SetAddonMessage("RAL_SELECTREPLY", RAL_SYNC_PAR);
		return;
	end
	if ARG_1=="RAL_SELECTREPLY" then
		if RaidAlerter_GetTimer("SYNCSELECT")<3 then		--有效响应时间：3秒内
			if tonumber(ARG_2) >= RaidAlerter_SYNC_SELECT_TMPPRA then
				if ARG_4 == UnitName("player") then
					RaidAlerter_SYNC_SELECT_TOME = 1;
				else
					RaidAlerter_SYNC_SELECT_TOME = 0;
				end
				RaidAlerter_SYNC_SELECT_TMPPRA = tonumber(ARG_2);
				RaidAlerter_SYNC_SELECT_NAME = ARG_4;
			end
		end
		return;
	end
	if ARG_1=="RAL_CHECKVER" then
		local _,_,RAL_SYNC_latency = GetNetStats();
		RaidAlerter_SetAddonMessage("RAL_CHECKVERREPLY", RaidAlerter_Version.."("..RaidAlerter_GetTFVarText(RaidAlerter_SET.OnOff,1)..")  "..RAL_SYNC_latency.."ms, "..format("%.1f",GetFramerate()).."FPS");
		return;
	end
	if ARG_1=="RAL_CHECKVERREPLY" then
		if RaidAlerter_SYNC_CHECKVER==1 then
			RaidAlerter.AddMsg(ARG_4..": "..RAL_TEXT_FUNC_50..ARG_2, 1);
			RaidAlerter_SYNC_CHECKVERCOUNT = RaidAlerter_SYNC_CHECKVERCOUNT + 1;
		end
		return;
	end
end

--OnUpdate事件
function RaidAlerter_Frame_OnUpdate(self)
--	if RaidAlerter_GetTimer("RaidAlerter_Update")>0.25 then	--每秒检测大约4次
	if GetTime() > RAL_NextUpdateTime then
		RaidAlerter_SendAddonMessage();
		--每9秒检查一次自己的组队和LA状态是否变更，若有变化（如加入团队或被提升）则发起选择报警方请求
		if (RaidAlerter_GetTimer("RaidAlerter_SYNC_MyStatus_Check")>9) and (RosterChanged) then
			local PR="";
			local PP="";
			local PA="";
			if UnitInRaid("player") then PR="T" else PR="F" end
			if (not UnitInRaid("player")) and (GetNumPartyMembers()>0) then PP="T" else PP="F" end
			if (IsRaidLeader() or IsRaidOfficer()) then PA="T" else PA="F" end
			RaidAlerter_SYNC_MyStatus = PR..PP..PA;
			if RaidAlerter_SYNC_MyStatus_Last ~= RaidAlerter_SYNC_MyStatus then
				RaidAlerter_SYNC_SELECT_TOME = 1;
				RaidAlerter_SetAddonMessage("RAL_SELECT","startcheck");
				RaidAlerter_SYNC_MyStatus_Last = RaidAlerter_SYNC_MyStatus;
				RaidAlerter_StartTimer("RaidAlerter_SYNC_MyStatus_Check");
			end
			ImTANK = RaidAlerter_TestIsMtList("player");		--检查自己是否TANK
			RosterChanged = false;
		end

		if RaidAlerter_SYNC_CHECKVER == 1 then
			if RaidAlerter_GetTimer("SYNCCHECKVER")>3 then		--版本检查：等待3秒
				RaidAlerter.AddMsg(string.format(RAL_TEXT_SYNC_END_CHECK,"|cFF20FF20"..RaidAlerter_SYNC_CHECKVERCOUNT.."|r"));
				RaidAlerter_SYNC_CHECKVER = 0;
				RaidAlerter_SYNC_CHECKVERCOUNT = 0;
			end
		end

		if RaidAlerter_SYNC_SELECT_NAME_MSG == 1 then
			if RaidAlerter_GetTimer("SELECTNAMEMSG")>3 then		--显示报警发送方选择：等待3秒
				RaidAlerter.AddMsg(RAL_TEXT_SYNC_SELECT_FINISH..RaidAlerter_ToClassColorNameText(RaidAlerter_SYNC_SELECT_NAME));
				RaidAlerter_SYNC_SELECT_NAME_MSG = 0;
			end
		end

		RaidAlerter_TOT_CHECK();

		if UnitInRaid("player") then					--In RAID
			RaidAlerter_Attack_Frame_OnUpdate();		--更新状态条参数
			RaidAlerter_Check_MyHP();

			if RaidAlerter_GetTimer("RaidAlerter_Boss_Record")>5 then		--RAID中每5秒更新一次worldboss表
				RaidAlerter_Boss_Record();
				RaidAlerter_StartTimer("RaidAlerter_Boss_Record");
			end

			if not RaidAlerter_SET.OnOff then
				RaidAlerter_StartTimer("RaidAlerter_Update");
				return;
			end

			RaidAlerter_TestAllRaidAffectingCombat();		--更新RaidAlerter_RaidAllInCombat参数

			if RaidAlerter_RaidAllInCombat then
				RaidAlerter_Raid_DeadMsg = true;
				RaidAlerter_RaidCombatEnd_CheckRAM = true;
				if not RaidAlerter_BattleTime_Record then
					RaidAlerter_BattleTime_Record = true;
					RaidAlerter_StartTimer("BattleTime_Record");
				end
				RaidAlerter_Check_BossHealthPecent(RaidAlerter_GetIsTargetBossUnit());
				RaidAlerter_Check_T_health();
				RaidAlerter_Check_P_BeControled();
			else
				if (RaidAlerter_Alerter_System["lasticon"] ~= "0") then
					SetRaidTargetIcon(RaidAlerter_NameToUnit(RaidAlerter_Alerter_System["lasticon"]), 0);
					RaidAlerter_Alerter_System["lasticon"] = "0";
					if (IsRaidLeader() or IsRaidOfficer()) then
						RaidAlerter.AddMsg(RAL_TEXT_ICON_CLEAR);
					end
				end
				--自动回收垃圾内存机制：RAID中若RaidAlerter内存占用超过设定界限（默认416K）则在战斗结束时予以回收
				if RaidAlerter_RaidCombatEnd_CheckRAM then
					RaidAlerter_SET_FUNC_ResetRAM(RaidAlerter_SET.MAXRAM);
					RaidAlerter_RaidCombatEnd_CheckRAM = false;
				end

				if RaidAlerter_Raid_DeadMsg then
					if (DeadRaidmembers > 0) and RaidAlerter_SET.OnOff then
						if RaidAlerter_SET.Check_Death_AtCombatEnd then
							if (RaidAlerter_Alerter_System["stcn"]>0) then
								if UnitName("raid"..RaidAlerter_Alerter_System["stcn"])~=nil then
									RaidAlerter.AddMsg(string.format(RAL_TEXT_ALERT_11,RaidAlerter_ToClassColorNameText(UnitName("raid"..RaidAlerter_Alerter_System["stcn"]))));
								end
							end

							if ((not UnitIsGhost("player")) and (GetRealZoneText()~=RAL_TEXT_ZONE_4)) then
								local CENDSCMSG="**";
								if (DeadRaidmembers >= ((RaidNum - OffLineRaidmembers)*0.5)) then
									CENDSCMSG=CENDSCMSG..string.format(RAL_TEXT_ALERT_12,DeadRaidmembers);
									CENDSCMSG=CENDSCMSG..", "..string.format(RAL_TEXT_ALERT_13,#GemName)..":"..RaidAlerter_GetGemOnNames();
								else
									CENDSCMSG=CENDSCMSG..string.format(RAL_TEXT_ALERT_12,DeadRaidmembers);
									if ManaPercent<60 then
										CENDSCMSG=CENDSCMSG..", "..string.format(RAL_TEXT_ALERT_14,ManaPercent);
									end
									if CureManaPercent<60 then
										CENDSCMSG=CENDSCMSG..", "..string.format(RAL_TEXT_ALERT_15,CureManaPercent);
									end
								end
								CENDSCMSG=CENDSCMSG.."**";
								RAL.SendMSG(CENDSCMSG,"RAID");
							end
						end
						RaidAlerter_Raid_DeadMsg = false;
					end
				else
					RaidAlerter_Check_SoulGemOn();
				end

				if RaidAlerter_BattleTime_Record then
					local timetmp = RaidAlerter_GetTimer("BattleTime_Record");
					if timetmp > 30 then						--只记录持续30秒以上的战斗时间（排除一些特例）
						RaidAlerter_BattleTime_Last = RaidAlerter_BattleTime_This;
						RaidAlerter_BattleTime_This = timetmp;
					end
					RaidAlerter_BattleTime_Record = false;

					if (not UnitIsGhost("player")) then
						local m, s = RaidAlerter_SecondsToTime(timetmp);
						if m == 0 then
							if RaidAlerter_Alerter_System.BossHealthPecentTMP < 99 then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_9,s),"RAID");
							else
								RaidAlerter.AddMsg("|cFF00FF00"..string.format(RAL_TEXT_ALERT_9,"|cFFFFFFFF"..s.."|cFF00FF00"));
							end
						else
							if RaidAlerter_Alerter_System.BossHealthPecentTMP < 99 then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_10,m,s),"RAID");
							else
								RaidAlerter.AddMsg("|cFF00FF00"..string.format(RAL_TEXT_ALERT_10,"|cFFFFFFFF"..m.."|cFF00FF00","|cFFFFFFFF"..s.."|cFF00FF00"));
							end
						end
					end
					RaidAlerter_Alerter_System["stcn"] = 0;
					RaidAlerter_Alerter_System["maxcn"] = 0;
					TankingPlayer = "";
				end
				RaidAlerter_Alerter_System.BossHealthPecentTMP = 100;
			end
			--OT监测（团队）
			if DeadRaidmembers < ((RaidNum - OffLineRaidmembers)*0.5) then		--死亡人数过多视为AG，停报OT
				RaidAlerter_MemberThreatCheck(RaidAlerter_GetDangerUnit());
			end
		else
			--非RAID状态下，在非战斗状态时每200秒检测一次内存占用。若内存占用超过设定界限（默认416K）则启动清理
			if UnitAffectingCombat("player")~=1 and RaidAlerter_GetTimer("RaidAlerter_SOLO_Party_CheckRAM")>200 then
				RaidAlerter_SET_FUNC_ResetRAM(RaidAlerter_SET.MAXRAM);
				RaidAlerter_StartTimer("RaidAlerter_SOLO_Party_CheckRAM");
			end
			if GetNumPartyMembers()>0 then		--In Party
				if RaidAlerter_SET.OnOff then
					if RaidAlerter_SYNC_SELECT_TOME == 1 then
						RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_2, "|cFF20FF20"..RAL_TEXT_FRAME_ON.."|r", RAL.ToOrange(GetNumPartyMembers()+1), RaidAlerter_GetCurrentDifficulty(2), RaidAlerter_LootMethodTEXT(2)));
					else
						RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_2, "|cFFFFDD00"..RAL_TEXT_FRAME_ON.."|r", RAL.ToOrange(GetNumPartyMembers()+1), RaidAlerter_GetCurrentDifficulty(2), RaidAlerter_LootMethodTEXT(2)));
					end
				else
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_2, "|cFFFF2020"..RAL_TEXT_FRAME_OFF.."|r", RAL.ToOrange(GetNumPartyMembers()+1), RaidAlerter_GetCurrentDifficulty(2), RaidAlerter_LootMethodTEXT(2)));
				end
				if RaidAlerter_GetTimer("RaidAlerter_Boss_Record")>5 then		--5人小队中每5秒更新一次boss表
					RaidAlerter_Boss_Record_Party();
					RaidAlerter_StartTimer("RaidAlerter_Boss_Record");
				end
				if not (RaidAlerter_SET.OnOff and RaidAlerter_SET.Party_Alerter) then
					RaidAlerter_StartTimer("RaidAlerter_Update");
					return;
				end
				if (UnitAffectingCombat("player")==1 or UnitIsDead("player")) then
					RaidAlerter_Check_Party_health();
					RaidAlerter_Check_BossHealthPecent_Party(RaidAlerter_GetIsTargetBossUnit_Party());
					RaidAlerter_Check_P_BeControled_Party();
				end
				--OT监测（5人小队）
				RaidAlerter_MemberThreatCheck(RaidAlerter_GetDangerUnit());
			else		--SOLO
				if RaidAlerter_SET.OnOff then
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_1,"|cFF20FF20"..RAL_TEXT_FRAME_ON.."|r"));
				else
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_1,"|cFFFF2020"..RAL_TEXT_FRAME_OFF.."|r"));
				end
			end
		end
		RAL_NextUpdateTime = GetTime() + 0.15;			--每秒检测大约6次
--		RaidAlerter_StartTimer("RaidAlerter_Update");
	end
end

--名称按玩家职业着色，非玩家着色为红色
function RaidAlerter_ToClassColorNameText(name)
	local SELECT_UNIT = RaidAlerter_NameToUnit(name);
	if not SELECT_UNIT then return "|cFFFF0000"..name.."|r";end
	local ClassColor = RAID_CLASS_COLORS[select(2,UnitClass(SELECT_UNIT))] or NORMAL_FONT_COLOR;
	return format("|cFF%s%s|r",format("%02X%02X%02X",ClassColor.r*255,ClassColor.g*255,ClassColor.b*255),name);
end

--数值着色
function RaidAlerter_ToSafeColorText(num,safe,mid,danger)
	local r, g, b;
	if safe > danger then					--规则1：大值安全
		if num >= safe then
			r = 0.0; g = 1.0; b = 0.0;		--安全，绿色
		elseif num <= danger then
			r = 1.0; g = 0.0; b = 0.0;		--危险，红色
		else
			if num >= mid then				--中值，黄色
				r = 1-((num-mid)/(safe-mid)); g = 1.0; b = 0.0;
			else
				r = 1.0; g = 1-((mid-num)/(mid-danger)); b = 0.0;
			end
		end
	else									--规则2：小值安全
		if num <= safe then
			r = 0.0; g = 1.0; b = 0.0;
		elseif num >= danger then
			r = 1.0; g = 0.0; b = 0.0;
		else
			if num <= mid then
				r = 1-((mid-num)/(mid-safe)); g = 1.0; b = 0.0;
			else
				r = 1.0; g = 1-((num-mid)/(danger-mid)); b = 0.0;
			end
		end
	end
	return format("|cFF%s%d|r",format("%02X%02X%02X",r*255,g*255,b*255),num);
end

--更新状态条（团队时）
function RaidAlerter_Attack_Frame_OnUpdate()
	if Attack_Frame_UPDATE_FREQ >= 2 then				--更新频率0.25x2=0.5秒
		RaidAlerter_Get_RaidState();					--更新团队参数
		RaidAlerter_UpdateTanks();						--更新主坦克表
		local RAL_AllMP = RaidAlerter_ToSafeColorText(ManaPercent,95,50,20);
		local RAL_HealMP = RaidAlerter_ToSafeColorText(CureManaPercent,95,50,20);
		local RAL_DeadN = RaidAlerter_ToSafeColorText(DeadRaidmembers,0,RaidNum/4,RaidNum/2);
		local AFrame_TEXT = "";
		if IsInInstance() or RaidAlerter_RaidAllInCombat then
			if RaidAlerter_SET.OnOff then
				if RaidAlerter_SYNC_SELECT_TOME == 1 then
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_3, "|cFF20FF20"..RAL_TEXT_FRAME_ON.."|r",RAL_AllMP, RAL_HealMP, RAL_DeadN));
				else
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_3, "|cFFFFDD00"..RAL_TEXT_FRAME_ON.."|r",RAL_AllMP, RAL_HealMP, RAL_DeadN));
				end
			else
				RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_3, "|cFFFF2020"..RAL_TEXT_FRAME_OFF.."|r",RAL_AllMP, RAL_HealMP, RAL_DeadN));
			end
		else
			if RaidAlerter_SET.OnOff then
				if RaidAlerter_SYNC_SELECT_TOME == 1 then
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_4, "|cFF20FF20"..RAL_TEXT_FRAME_ON.."|r",RAL.ToOrange(GetNumRaidMembers()), RaidAlerter_GetCurrentDifficulty(1), RaidAlerter_LootMethodTEXT(2)));
				else
					RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_4, "|cFFFFDD00"..RAL_TEXT_FRAME_ON.."|r",RAL.ToOrange(GetNumRaidMembers()), RaidAlerter_GetCurrentDifficulty(1), RaidAlerter_LootMethodTEXT(2)));
				end
			else
				RaidAlerter_Attack_Frame_Text:SetText(string.format(RAL_TEXT_FRAME_4, "|cFFFF2020"..RAL_TEXT_FRAME_OFF.."|r",RAL.ToOrange(GetNumRaidMembers()), RaidAlerter_GetCurrentDifficulty(1), RaidAlerter_LootMethodTEXT(2)));
			end
		end
--[[
		if (CureManaPercent > 0) and (ManaPercent > 0) and ((ManaPercent < 30) or (CureManaPercent < 20) or (DeadRaidmembers > RaidNum/2)) then
			RaidAlerter_Attack_Frame_Text:SetTextColor(1.0,0.1,0.1);
		else
			RaidAlerter_Attack_Frame_Text:SetTextColor(1.0,1.0,1.0);
		end
]]
		Attack_Frame_UPDATE_FREQ = 0;
	end
	Attack_Frame_UPDATE_FREQ = Attack_Frame_UPDATE_FREQ + 1;
end

--团队状态条快捷键操作
function RaidAlerter_RaidState(self, button)
	if button=="LeftButton" then
		if (IsControlKeyDown() and IsAltKeyDown()) then
			RaidAlerter_SET_FUNC_CHK_MY_HP();
			return;
		end
		if IsShiftKeyDown() then
			RaidAlerter_CheckRaidBuff();
		elseif IsAltKeyDown() then
			RaidAlerter_Target_Check("MT");
		elseif IsControlKeyDown() then
			RaidAlerter_CheckPlayer();
		else
			RaidAlerter_SET_FUNC_OnOff("OnOff");
		end
	elseif button=="RightButton" then
		if IsShiftKeyDown() then
			RaidAlerter_SET_FUNC_ResetRAM("reset");
		elseif IsAltKeyDown() then
			RaidAlerter_CheckFlask("all");
		elseif IsControlKeyDown() then
			RaidAlerter_CheckFlask();
		else
			RaidAlerter_Option_MainFrame_Show(self);
		end
	end
end

--报警监视
function RaidAlerter_Raid_PARTY_Combat_Alerter(timestamp, eventtype, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, spellId, spellName, spellSchool, auraType, amount)
	if UnitInRaid("player") then
		AlertChan = "RAID";
		AlertWChan = "RAID_WARNING";
	elseif GetNumPartyMembers()>0 then
		if not RaidAlerter_SET.Party_Alerter then return; end
		AlertChan = "PARTY";
		AlertWChan = "PARTY_RW";
	else
		return;
	end

	if eventtype == "SPELL_AURA_APPLIED" then
		if RaidAlerter_SET.TANK_ShieldWall then
			if spellName == RAL_TEXT_SPELL_1 or spellName == RAL_TEXT_SPELL_30 or spellName == RAL_TEXT_SPELL_33
			or spellName == RAL_TEXT_SPELL_34 then
				TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_16,dstName,spellName), AlertWChan);
				end
				return;
			end
		end
		if RaidAlerter_SET.TANK_LastStand then
			if spellName == RAL_TEXT_SPELL_2 or spellName == RAL_TEXT_SPELL_31 or spellName == RAL_TEXT_SPELL_36 then
				TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_16,dstName,spellName), AlertWChan);
				end
				return;
			end
		end
		if spellName == RAL_TEXT_SPELL_3 then
			TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
			if TempUnit1 then
				if RaidAlerter_SET.Check_Gem then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_18,dstName), AlertChan);
				end
				if RaidAlerter_RaidAllInCombat then
					RaidAlerter_Table_Update(GemName, dstName, "ADD");
				else
					RaidAlerter_Check_SoulGemOn();
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_CREATE" then
		if not RaidAlerter_RaidAllInCombat then			--只在非团队战斗状态检测
			if RaidAlerter_SET.RaidSpell then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					for i, v in pairs(RAL_TEXT_RAIDSPELL_1) do
						if v["MATCH"] == 0 then
							if string.find(spellName, v["TEXT"]) then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_39,srcName,spellName), AlertWChan, 0, 10, "RAIDSPELL"..srcGUID);	--刷屏限制：10秒
								RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_39,srcName,spellName));
								if v["TYPE"] == "COOKFOOD" then
									RaidAlerter_StartTimer("COOKFOOD_CREAT");
									COOKFOODDUR = v["DUR"];
								end
								return;
							end
						elseif v["MATCH"] == 1 then
							if spellName == v["TEXT"] then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_39,srcName,spellName), AlertWChan, 0, 10, "RAIDSPELL"..srcGUID);	--刷屏限制：10秒
								RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_39,srcName,spellName));
								if v["TYPE"] == "COOKFOOD" then
									RaidAlerter_StartTimer("COOKFOOD_CREAT");
									COOKFOODDUR = v["DUR"];
								end
								return;
							end
						end
					end
				end
			end
		end
		return;
	end

	if eventtype == "SPELL_CAST_SUCCESS" then
		if not RaidAlerter_RaidAllInCombat then			--只在非团队战斗状态检测
			if RaidAlerter_SET.RaidSpell then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					for i, v in pairs(RAL_TEXT_RAIDSPELL_2) do
						if v["MATCH"] == 0 then
							if string.find(spellName, v["TEXT"]) then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_39,srcName,spellName), AlertWChan, 0, 10, "RAIDSPELL"..srcGUID);	--刷屏限制：10秒
								RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_39,srcName,spellName));
								return;
							end
						elseif v["MATCH"] == 1 then
							if spellName == v["TEXT"] then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_39,srcName,spellName), AlertWChan, 0, 10, "RAIDSPELL"..srcGUID);	--刷屏限制：10秒
								RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_39,srcName,spellName));
								return;
							end
						end
					end
				end
			end
		end
		if spellName == RAL_TEXT_SPELL_37 then		--专注魔法：只在本机显示提示，玩家属于无关人员则不于显示
			if not(IsRaidLeader() or IsRaidOfficer() or (UnitPowerType("player")==0 and (UnitClass("player")~=RAL_TEXT_HUNTER))) then
				return;
			end
			TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
			if TempUnit1 then
				if srcName == UnitName("player") then
					RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_44,spellName,RAL.ToPink(RAL_TEXT_YOU),RaidAlerter_ToClassColorNameText(dstName)), nil, true);
				elseif dstName == UnitName("player") then
					RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_44,spellName,RaidAlerter_ToClassColorNameText(srcName),RAL.ToPink(RAL_TEXT_YOU)), nil, true);
				else
					RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_44,spellName,RaidAlerter_ToClassColorNameText(srcName),RaidAlerter_ToClassColorNameText(dstName)), nil, true);
				end
			end
			return;
		end
		if spellName == RAL_TEXT_SPELL_4 or spellName == RAL_TEXT_SPELL_4_SPEC_1 then
			if RaidAlerter_SET.Hunter_Misdirection then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					if srcName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_44,spellName,RAL.ToPink(RAL_TEXT_YOU),RaidAlerter_ToClassColorNameText(dstName)));
					elseif dstName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_44,spellName,RaidAlerter_ToClassColorNameText(srcName),RAL.ToPink(RAL_TEXT_YOU)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_44,spellName,srcName,dstName), AlertChan);
				end
			end
			return;
		end
		if spellName == RAL_TEXT_SPELL_5 then
			if RaidAlerter_SET.Hunter_Shot then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_20,srcName,RaidAlerter_GUIDTOICONTEXT(dstGUID)..dstName), AlertChan);
				end
			end
			return;
		end
		if spellName == RAL_TEXT_SPELL_6 then
			if RaidAlerter_SET.Hunter_Mark then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_21,srcName,RaidAlerter_GUIDTOICONTEXT(dstGUID)..dstName), AlertChan);
				end
			end
			return;
		end
		if spellName == RAL_TEXT_SPELL_7 then
			if RaidAlerter_SET.Paladin_Intervention then
				TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_22,srcName,dstName), AlertWChan);
				end
			end
			return;
		end
		if spellName == RAL_TEXT_SPELL_8 then
			if (RaidAlerter_SET.Nef_TANKPoly and GetRealZoneText() == RAL_TEXT_ZONE_1) then
				TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
				if TempUnit1 then
						local playerClass = UnitClass(TempUnit1);
						if(playerClass==RAL_TEXT_WARRIOR or playerClass==RAL_TEXT_ROGUE) then
						RAL.SendMSG(string.format(RAL_TEXT_ALERT_23,srcName,dstName), AlertWChan);
					end
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_AURA_BROKEN_SPELL" or eventtype == "SPELL_AURA_BROKEN" then
		if (spellName == RAL_TEXT_SPELL_9 or spellName == RAL_TEXT_SPELL_10 or spellName == RAL_TEXT_SPELL_11 or spellName == RAL_TEXT_SPELL_12) then
			if RaidAlerter_SET.Break_Poly then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				TempUnit2 = RaidAlerter_GUIDToUnit(dstGUID);
				amount = amount or RAL_TEXT_SPELL_29;
				if not TempUnit2 then
					local DeText = "";
					local PolymorphTactic = false;
					if (spellName == RAL_TEXT_SPELL_9) then DeText = RAL_TEXT_ALERT_24; end
					if (spellName == RAL_TEXT_SPELL_10) then DeText = RAL_TEXT_ALERT_25; end
					if (spellName == RAL_TEXT_SPELL_11) then DeText = RAL_TEXT_ALERT_26; end
					if (spellName == RAL_TEXT_SPELL_12) then DeText = RAL_TEXT_ALERT_27; end
					if TempUnit1 then
						if spellName == RAL_TEXT_SPELL_9 then
							if LastPolyBreakID == dstGUID then
								SameIDPolyBreakCount = SameIDPolyBreakCount + 1;
							else
								SameIDPolyBreakCount = 0;
								LastPolyBreakID = dstGUID;
							end
							if SameIDPolyBreakCount >= 3 then		--队员重复3次以上打同一只羊，若其血量已低于95%，则认为是刷羊战术，不报警
								TempUnit3 = RaidAlerter_GetTarIsGUIDUnit(dstGUID);
								if TempUnit3 then
									local P_unit = TempUnit3.."target";
									local P_health, P_healthmax = UnitHealth(P_unit), UnitHealthMax(P_unit);
									local P_healthPercent = floor(P_health/P_healthmax*100+0.5);
									if P_healthPercent < 95 then
										PolymorphTactic = true;
									end
								end
							end
						end
						if not PolymorphTactic then
							RAL.SendMSG(string.format(RAL_TEXT_ALERT_28,DeText,srcName,RaidAlerter_GetPetMaster(srcGUID),RaidAlerter_GUIDTOICONTEXT(dstGUID)..dstName,amount), AlertChan);
							RAL.SOUND(2);
						end
					elseif srcName then
						if (UnitAffectingCombat("player")==1 or UnitIsDead("player")) then
							RAL.SendMSG(string.format(RAL_TEXT_ALERT_28,DeText,srcName,RaidAlerter_GetPetMaster(srcGUID),RaidAlerter_GUIDTOICONTEXT(dstGUID)..dstName,amount), AlertChan);
							RAL.SOUND(2);
						end
					end
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_DISPEL" or eventtype == "SPELL_AURA_DISPELLED" then
		if (spellName == RAL_TEXT_SPELL_13 or spellName == RAL_TEXT_SPELL_14 or spellName == RAL_TEXT_SPELL_15) then
			if RaidAlerter_SET.Dispel_Magic then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				TempUnit2 = RaidAlerter_GUIDToUnit(dstGUID);
				if (TempUnit1 and (not TempUnit2)) then
					local icon = RaidAlerter_GUIDTOICONTEXT(dstGUID);
					if srcName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_29,RAL.ToPink(RAL_TEXT_YOU),icon..RAL.ToRed(dstName),RAL.ToCyan(amount)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_29,srcName,icon..dstName,amount), AlertChan, 0, 0.5, "DM"..srcGUID);		--防止未来版本战斗记录可能改变导致的群驱刷屏
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_STOLEN" or eventtype == "SPELL_AURA_STOLEN" then
		if spellName == RAL_TEXT_SPELL_16 then
			if RaidAlerter_SET.BuffStolen then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				TempUnit2 = RaidAlerter_GUIDToUnit(dstGUID);
				if (TempUnit1 and (not TempUnit2)) then
					local icon = RaidAlerter_GUIDTOICONTEXT(dstGUID);
					if srcName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_30,RAL.ToPink(RAL_TEXT_YOU),icon..RAL.ToRed(dstName),RAL.ToCyan(amount)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_30,srcName,icon..dstName,amount), AlertChan);
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_MISSED" then
		if (spellName == RAL_TEXT_SPELL_17 or spellName == RAL_TEXT_SPELL_18 or spellName == RAL_TEXT_SPELL_19 or spellName == RAL_TEXT_SPELL_32
		or spellName == RAL_TEXT_SPELL_9 or spellName == RAL_TEXT_SPELL_20 or spellName == RAL_TEXT_SPELL_16 or spellName == RAL_TEXT_SPELL_13
		or spellName == RAL_TEXT_SPELL_14 or spellName == RAL_TEXT_SPELL_21 or spellName == RAL_TEXT_SPELL_5) then
			if ((not RaidAlerter_SET.TANK_Taunt) and (spellName == RAL_TEXT_SPELL_17 or spellName == RAL_TEXT_SPELL_18
			or spellName == RAL_TEXT_SPELL_19 or spellName == RAL_TEXT_SPELL_32)) then return; end
			if ((not RaidAlerter_SET.RES_DispelMagic) and (spellName == RAL_TEXT_SPELL_13 or spellName == RAL_TEXT_SPELL_14 or spellName == RAL_TEXT_SPELL_5)) then return; end
			if ((not RaidAlerter_SET.RES_Polymorph) and (spellName == RAL_TEXT_SPELL_9 or spellName == RAL_TEXT_SPELL_20)) then return; end
			if ((not RaidAlerter_SET.RES_MagicBreak) and (spellName == RAL_TEXT_SPELL_21)) then return; end
			if ((not RaidAlerter_SET.RES_BuffStolen) and (spellName == RAL_TEXT_SPELL_16)) then return; end
			TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
			if TempUnit1 then
				if auraType == "MISS" or auraType == "RESIST" then
					local icon = RaidAlerter_GUIDTOICONTEXT(dstGUID);
					if srcName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_31,RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(spellName),icon..RaidAlerter_ToClassColorNameText(dstName)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_31,srcName,spellName,icon..dstName), AlertChan);
				elseif auraType == "IMMUNE" then
					local icon = RaidAlerter_GUIDTOICONTEXT(dstGUID);
					if srcName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_32,icon..RaidAlerter_ToClassColorNameText(dstName),RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(spellName)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_32,icon..dstName,srcName,spellName), AlertChan);
				end
			end
			return;
		end
		if RaidAlerter_SET.TANK_ShieldReflection then
			if auraType == "REFLECT" then
				TempUnit1 = RaidAlerter_GUIDToUnit(dstGUID);
				if TempUnit1 then
					local icon = RaidAlerter_GUIDTOICONTEXT(srcGUID);
					if dstName == UnitName("player") then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_33,RAL.ToPink(RAL_TEXT_YOU),RAL.ToCyan(spellName),icon..RaidAlerter_ToClassColorNameText(srcName)));
					end
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_33,dstName,spellName,icon..srcName), AlertChan);
					return;
				end
			end
		end
		return;
	end

	if eventtype == "SPELL_INTERRUPT" then
		if RaidAlerter_SET.Break_Magic then
			TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
			if TempUnit1 then
				local icon = RaidAlerter_GUIDTOICONTEXT(dstGUID);
				if srcName == UnitName("player") then
					RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_34,RAL.ToPink(RAL_TEXT_YOU),icon..RaidAlerter_ToClassColorNameText(dstName),RAL.ToCyan(amount)));
				end
				RAL.SendMSG(string.format(RAL_TEXT_ALERT_34,srcName,icon..dstName,amount), AlertChan, 0, 0.5, "BM"..srcGUID);		--防DZ刀扇刷屏
				return;
			end
		end
		return;
	end

	if eventtype == "PARTY_KILL" then
		if RaidAlerter_SET.BossKill then
			TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
			TempUnit2 = RaidAlerter_GUIDToUnit(dstGUID);
			if (TempUnit1 and (not TempUnit2)) then
				for k, v in pairs(RaidAlerter_Bosses) do
					if dstName == v then
						RAL.SendMSG(string.format(RAL_TEXT_ALERT_35,RaidAlerter_GUIDTOICONTEXT(dstGUID)..dstName,srcName), AlertChan);
						return;
					end
				end
			end
		end
		return;
	end

	if eventtype == "SPELL_SUMMON" then
		if RaidAlerter_SET.TANK_ShieldWall then
			if spellName == RAL_TEXT_SPELL_35 then
				TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
				if TempUnit1 then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_39,srcName,spellName), AlertWChan);
				end
				return;
			end
		end
		return;
	end

--	if (eventtype == "SWING_DAMAGE"or eventtype == "RANGE_DAMAGE" or eventtype == "SPELL_DAMAGE") then
	if eventtype == "SPELL_DAMAGE" then
		if RaidAlerter_SET.TAQ_Twin_AOEAdd then
			if GetRealZoneText() == RAL_TEXT_ZONE_2 then
				if (spellName == RAL_TEXT_SPELL_22 or spellName == RAL_TEXT_SPELL_23 or spellName == RAL_TEXT_SPELL_24
				or spellName == RAL_TEXT_SPELL_25 or spellName == RAL_TEXT_SPELL_26 or spellName == RAL_TEXT_SPELL_27) then
					if (dstName == RAL_TEXT_UINTNAME_1 or dstName == RAL_TEXT_UINTNAME_2) then
						RAL.SendMSG(string.format(RAL_TEXT_ALERT_36,srcName,spellName,dstName), AlertChan);
						RAL.SOUND(3);
					end
				end
			end
			return;
		end
		return;
	end

	if eventtype == "SPELL_PERIODIC_DAMAGE" then
		if RaidAlerter_SET.Nef_PriestDown then
			if GetRealZoneText() == RAL_TEXT_ZONE_1 then
				if spellName == RAL_TEXT_SPELL_28 then
					TempUnit1 = RaidAlerter_GUIDToUnit(srcGUID);
					TempUnit2 = RaidAlerter_GUIDToUnit(dstGUID);
					if (TempUnit1 and TempUnit2)then
						RaidAlerter_Alerter_ErrorCure[TempUnit1] = RaidAlerter_Alerter_ErrorCure[TempUnit1] + 1;
						RaidAlerter_Alerter_ErrorCure[TempUnit2] = RaidAlerter_Alerter_ErrorCure[TempUnit2] + auraType;
						if ( RaidAlerter_Alerter_ErrorCure[TempUnit1] > 5) then
							RaidAlerter_Alerter_ErrorCure[TempUnit1] = 0;
						elseif ( RaidAlerter_Alerter_ErrorCure[TempUnit1] == 1)then
							RAL.SendMSG(string.format(RAL_TEXT_ALERT_37,srcName,dstName,RaidAlerter_Alerter_ErrorCure[TempUnit2]), AlertChan);
						end
					end
				end
				return;
			end
		end
		return;
	end
end

--TANK血量监视
function RaidAlerter_Check_T_health()
	local i;
	for i = 1, 5 do
		if (RAL_Tanks[i]) then
			local unit = RaidAlerter_NameToUnit(RAL_Tanks[i]);
			if (unit) then
				if (UnitIsConnected(unit)) then
					if RaidAlerter_SET.TANK_Death then
						if (UnitIsDeadOrGhost(unit)) then
							if RaidAlerter_MT_Dead[unit] == nil then
								RaidAlerter_MT_Dead[unit] = 0;
							end
							if ( RaidAlerter_MT_Dead[unit] == 0) then
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_5,i.."T",RAL_Tanks[i]),"RAID_WARNING");
								RaidAlerter_MT_Dead[unit] = 1;
							end
--									return;
						else
							RaidAlerter_MT_Dead[unit] = 0;
						end
					end

					local health, healthmax, mana, manamax = UnitHealth(unit), UnitHealthMax(unit), UnitMana(unit), UnitManaMax(unit);
					local healthPercent = floor(health/healthmax*100+0.5)

					if RaidAlerter_SET.TANK_DangerHealth then
						if (healthPercent <= RaidAlerter_SET.TANK_DangerHealthPecent) and (not UnitIsDeadOrGhost(unit)) then
							RaidAlerter_Alerter_dangerHealth[unit] = RaidAlerter_Alerter_dangerHealth[unit] + 1;
							if ( RaidAlerter_Alerter_dangerHealth[unit] > 40) then
								RaidAlerter_Alerter_dangerHealth[unit] = 0;
							elseif ( RaidAlerter_Alerter_dangerHealth[unit] == 1)then
								if RaidAlerter_GetTimer("RH"..RAL_Tanks[i])>3 then		--同一人3秒内只报一次
									RAL.SendMSG(string.format(RAL_TEXT_ALERT_4,i.."T",RAL_Tanks[i],healthPercent),"RAID_WARNING");
									RAL.SOUND(3);
									RaidAlerter_StartTimer("RH"..RAL_Tanks[i]);
								end
							end
--							return;
						else
							RaidAlerter_Alerter_dangerHealth[unit] = 0;
						end
					end

					if healthPercent > RaidAlerter_SET.TANK_DangerHealthPecent then
						RaidAlerter_Alerter_dangerHealth[unit] = 0;
					end
				end
			end
		end
	end
	return true;
end

--小队血量监视（非团队）
function RaidAlerter_Check_Party_health()
	local i;
	local unit = "";
	for i = 0, GetNumPartyMembers() do
		if i == 0 then
			unit = "player";
		else
			unit = "party"..i;
		end
		if UnitIsConnected(unit) then
			if (UnitIsDeadOrGhost(unit)) then
				if RaidAlerter_MT_Dead[unit] == nil then
					RaidAlerter_MT_Dead[unit] = 0;
				end
				if ( RaidAlerter_MT_Dead[unit] == 0) then
					if unit == "player" then
						if RaidAlerter_SET.TANK_Death then
							RAL.SendMSG(RAL_TEXT_ALERT_6,"PARTY",1);
						end
					end
					RaidAlerter_MT_Dead[unit] = 1;
				end
				return;
			else
				RaidAlerter_MT_Dead[unit] = 0;
			end

			local health, healthmax, mana, manamax = UnitHealth(unit), UnitHealthMax(unit), UnitMana(unit), UnitManaMax(unit);
			local healthPercent = floor(health/healthmax*100+0.5);
			local playerClass = UnitClass(unit);

			if (healthPercent <= RaidAlerter_SET.TANK_DangerHealthPecent) and (not UnitIsDeadOrGhost(unit)) then
				RaidAlerter_Alerter_dangerHealth[unit] = RaidAlerter_Alerter_dangerHealth[unit] + 1;
				if ( RaidAlerter_Alerter_dangerHealth[unit] > 40) then
					RaidAlerter_Alerter_dangerHealth[unit] = 0;
				elseif ( RaidAlerter_Alerter_dangerHealth[unit] == 1)then
					if RaidAlerter_GetTimer("PH"..UnitName(unit))>3 then		--同一人3秒内只报一次
						if RaidAlerter_SET.TANK_DangerHealth then
							RAL.SendMSG(string.format(RAL_TEXT_ALERT_4,playerClass,UnitName(unit),healthPercent),"PARTY_RW");
							RAL.SOUND(3);
						end
						RaidAlerter_StartTimer("PH"..UnitName(unit));
					end
				end
				return;
			else
				RaidAlerter_Alerter_dangerHealth[unit] = 0;
			end

			if healthPercent > RaidAlerter_SET.TANK_DangerHealthPecent then
				RaidAlerter_Alerter_dangerHealth[unit] = 0;
			end
		end
	end
	return true;
end

--Boss血量报警（团队）
function RaidAlerter_Check_BossHealthPecent(unit)
	if RaidAlerter_SET.BossHealthPecentOnOff then
		if unit then
			local health, healthmax = UnitHealth(unit.."target"), UnitHealthMax(unit.."target");
			local healthPercent = floor(health/healthmax*100+0.5);
			if (healthPercent - RaidAlerter_Alerter_System.BossHealthPecentTMP >=2) then
				RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
			end
			if (healthPercent > 0) then
				if (RaidAlerter_Alerter_System.BossHealthPecentTMP - healthPercent >= 1) then
					if (healthPercent <= RaidAlerter_SET.BossHealthPecent) then
						RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").."**", "RAID", 0, 1.5, "BossHPP");
						RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
						return;
					else
						if (floor((RaidAlerter_Alerter_System.BossHealthPecentTMP-1)/10)-floor((healthPercent-1)/10)>=1) then
							if RaidAlerter_BattleTime_Record then
								local m, s = RaidAlerter_SecondsToTime(RaidAlerter_GetTimer("BattleTime_Record"));
								if m == 0 then
									RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").." ("..string.format(RAL_TEXT_TIP_4,s)..")**", "RAID");
								else
									RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").." ("..string.format(RAL_TEXT_TIP_5,m,s)..")**", "RAID");
								end
							else
								RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").."**", "RAID", 0, 1.5, "BossHPP");
							end
							RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
							return;
						end
					end
				end
			end
		end
	end
end

--Boss血量报警（5人小队）
function RaidAlerter_Check_BossHealthPecent_Party(unit)
	if RaidAlerter_SET.BossHealthPecentOnOff then
		if unit then
			local health, healthmax = UnitHealth(unit.."target"), UnitHealthMax(unit.."target");
			local healthPercent = floor(health/healthmax*100+0.5);
			if (healthPercent - RaidAlerter_Alerter_System.BossHealthPecentTMP >=2) then
				RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
			end
			if (healthPercent > 0) then
				if (RaidAlerter_Alerter_System.BossHealthPecentTMP - healthPercent >= 1) then
--					if (healthPercent <= RaidAlerter_SET.BossHealthPecent) then
					if (healthPercent <= 5) then		--逐一通报界限固定为5%，不受选项控制
						RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").."**", "PARTY", 0, 1.5, "BossHPP");
						RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
						return;
					else
						if (floor((RaidAlerter_Alerter_System.BossHealthPecentTMP-1)/10)-floor((healthPercent-1)/10)>=2) then		--间隔通报血量报警间隔20%（RAID是10%）
							RAL.SendMSG("**["..healthPercent.."%]"..UnitName(unit.."target").."**", "PARTY", 0, 1.5, "BossHPP");
							RaidAlerter_Alerter_System.BossHealthPecentTMP = healthPercent;
							return;
						end
					end
				end
			end
		end
	end
end

--仇恨提示：自己的仇恨信息
function RaidAlerter_THREAT_UPDATE(unit)
	if RaidAlerter_SET.THREATCheck then
		if (GetNumPartyMembers()>0 or GetNumRaidMembers()>0) then
			if unit == "player" then
				local state = UnitThreatSituation(unit);
				if (state == nil) then state = 0;end
				local MYTARstate = 0;
				local MYTARthreatValue = 0;
				if UnitExists("target") then
					_,MYTARstate,_,_,MYTARthreatValue = UnitDetailedThreatSituation("player", "target");
					if MYTARstate == nil then MYTARstate = 0;end
					if MYTARthreatValue == nil then MYTARthreatValue = 0;end
				end
				if (state >= 2) and (MyLastThreatState < 2) then		--OT
					RAL_THREAT_Info:AddMessage(RAL_TEXT_THREAT_INFO_01, 1, 0.1, 0.1);
--					if (MYTARstate >= 2) and (MYTARthreatValue > 50000) then
						if not ImTANK then
							RAL.SOUND(1);
						end
--					end
					MyLastThreatState = 2;
				elseif (state == 1) and (MyLastThreatState < 1) then		--高仇恨：快OT了（>100%）
					RAL_THREAT_Info:AddMessage(RAL_TEXT_THREAT_INFO_04, 1, 0.1, 1);
					MyLastThreatState = 1;
					if (MYTARstate == 1) and (MYTARthreatValue > 50000) then
						if not ImTANK then
							RAL.SOUND(4);
						end
					end
				else		--仇恨安全
					if MyLastThreatState > 0 then
						RAL_THREAT_Info:AddMessage(RAL_TEXT_THREAT_INFO_02, 0.1, 1, 0.1);
						if ImTANK then
							RAL.SOUND(1);
						end
						MyLastThreatState = 0;
					end
				end
			end
		end
	end
end

--TOT监测
function RaidAlerter_TOT_CHECK()
	if RaidAlerter_SET.ToTCheck then
		if (GetNumPartyMembers()>0 or GetNumRaidMembers()>0) then
			if UnitExists("focus") and UnitExists("focustarget") then
				if (UnitIsUnit("focustarget", "player") and UnitCanAttack("player", "focus")) then
					if not FouTarISME then
						RAL_TOT_Info:AddMessage(string.format(RAL_TEXT_THREAT_INFO_05,RAL_TEXT_YOU), 0.8, 0.8, 0.8);
						if not ImTANK then
							RAL.SOUND(1);
						end
						FouTarISME = true;
					end
				else
					FouTarISME = false;
				end
			else
				FouTarISME = false;
			end
			if UnitExists("target") and UnitExists("targettarget") then
				if (UnitIsUnit("targettarget", "player") and UnitCanAttack("player", "target")) then
					if not TarTarISME then
						RAL_TOT_Info:AddMessage(string.format(RAL_TEXT_THREAT_INFO_03,RAL_TEXT_YOU), 1, 0.9, 0);
						if not ImTANK then
							RAL.SOUND(1);
						end
						TarTarISME = true;
					end
				else
					TarTarISME = false;
				end
			else
				TarTarISME = false;
			end
		end
	end
end

--OT和仇恨监测
function RaidAlerter_MemberThreatCheck(unit)
	if not unit then return;end
	if RaidAlerter_SET.OT_OnOff or RaidAlerter_SET.OTM_OnOff then
		if UnitExists(unit.."target") then
			local state = UnitThreatSituation(unit.."target", unit);
			if (state == nil) then state = 0;end
			if state >= 2 then
				if TankingPlayer ~= UnitName(unit.."target") then
					if not RaidAlerter_TestIsMtList(unit.."target") then
						RaidAlerter_OTAlert(UnitName(unit), UnitName(unit.."target"), RaidAlerter_GetUnitICONTEXT(unit));
					end
					TankingPlayer = UnitName(unit.."target");
				end
			end
		end
		if RaidAlerter_GetTimer("BossDangerThreatCheck") > 5 then
			if RaidAlerter_IsBossUnit(unit) then
				local state, threatValue;
				local DangerNames = "";
				local BossICON = RaidAlerter_GetUnitICONTEXT(unit);
				local Bossname = UnitName(unit);
				if UnitInRaid("player") then
					for i=1, GetNumRaidMembers() do
						_,state,_,_,threatValue = UnitDetailedThreatSituation("raid"..i, unit);
						if (state ~= nil) and (threatValue ~= nil) then
							if (state == 1) and (threatValue > 400000) then
								if not RaidAlerter_TestIsMtList("raid"..i) then
									DangerNames = DangerNames..UnitName("raid"..i)..".";
									if RaidAlerter_SET.OTM_OnOff then
										RaidAlerter_Whisper(UnitName("raid"..i), string.format(RAL_TEXT_ALERT_40, BossICON..Bossname));
									end
								end
							end
						end
					end
				elseif GetNumPartyMembers() > 0 then
					for i=0, GetNumPartyMembers() do
						local punit = "";
						if i == 0 then
							punit = "player";
						else
							punit = "party"..i;
						end
						_,state,_,_,threatValue = UnitDetailedThreatSituation(punit, unit);
						if (state ~= nil) and (threatValue ~= nil) then
							if (state == 1) and (threatValue > 200000) then
								if not RaidAlerter_TestIsMtList(punit) then
									DangerNames = DangerNames..UnitName(punit)..".";
									if RaidAlerter_SET.OTM_OnOff then
										RaidAlerter_Whisper(UnitName(punit), string.format(RAL_TEXT_ALERT_40, BossICON..Bossname));
									end
								end
							end
						end
					end
				end
				if DangerNames ~= "" and RaidAlerter_SET.OT_OnOff then
					RAL.SendMSG(string.format(RAL_TEXT_ALERT_41, DangerNames, BossICON..Bossname), "RAID");
				end
			end
			RaidAlerter_StartTimer("BossDangerThreatCheck");
		end
	end
end

--OT警报
function RaidAlerter_OTAlert(Bossname, OTname, BossICON)
	if RaidAlerter_SET.OT_OnOff then
		RAL.SendMSG(string.format(RAL_TEXT_ALERT_1, BossICON..Bossname, OTname), "RAID");		--"RAID"在PARTY时会自动置换
		if (UnitName("player") == OTname) then
			RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_1, BossICON..RAL.ToRed(Bossname), RAL.ToPink(RAL_TEXT_YOU)));
			RAL.SOUND(3);
		else
			RAL.SOUND(1);
		end
	end
	if RaidAlerter_SET.OTM_OnOff then
		if RaidAlerter_NameToUnit(OTname) then
			RaidAlerter_Whisper(OTname, string.format(RAL_TEXT_ALERT_3, BossICON..Bossname));
		end
	end
end

--玩家自身血量危急自动喊话（需在团队状态并属于正常队员）
function RaidAlerter_Check_MyHP()
	if RaidAlerter_ChkMyHP then
		if UnitAffectingCombat("player")==1 then
			local healthPercent = floor(UnitHealth("player")/UnitHealthMax("player")*100+0.5);
			if (healthPercent < RaidAlerter_MyDangerHP) and (not UnitIsDeadOrGhost("player")) then
				local MyGroup = RaidAlerter_NameToGroup(UnitName("player"));
				if MyGroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
					if RaidAlerter_GetTimer("MyHPDanger")>6 then
						RaidAlerter.AddSCRMsg(string.format(RAL_TEXT_ALERT_4, "", RAL.ToPink(RAL_TEXT_YOU), RAL.ToRed(healthPercent)));
						SendChatMessage(string.format(RAL_TEXT_ALERT_38,healthPercent,MyGroup,UnitClass("player")),"YELL");
						RaidAlerter_StartTimer("MyHPDanger");
					end
				end
			end
		end
	end
end

--[[
function RaidAlerter_BU(s) local P,B,i="player",true,1 while UnitBuff(P,i) do if string.find(UnitBuff(P,i),s) then B=false end i=i+1 end return B end
function RaidAlerter_TargetBU(s) local P,B,i="target",true,1 while UnitBuff(P,i) do if string.find(UnitBuff(P,i),s) then B=false end i=i+1 end return B end
]]
function RaidAlerter_TargetDeBU(s,t) local B,i=true,1 while UnitDebuff(t,i) do if string.find(UnitDebuff(t,i),s) then B=false end i=i+1 end return B end

--统计有效成员数量（限定人数模式）
--[[
function RaidAlerter_GetNumRaidMembers(check)
	local n=0;
	for i=1, GetNumRaidMembers() do
		_, _, subgroup = GetRaidRosterInfo(i);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			n = n + 1;
		end
	end
	return n;
end
]]

--更新主坦克表
function RaidAlerter_UpdateTanks()
	RAL_Tanks = {};
	if (oRA3) then
		if oRA3.GetSortedTanks then
			RAL_Tanks = oRA3.GetSortedTanks();
			local i = 1;
			while RAL_Tanks[i] do
				local found = false;
				for k, v in pairs(RAL_BlzTanks) do
					if v == RAL_Tanks[i] then
						found = true;
						break;
					end
				end
				if not found then
					table.remove(RAL_Tanks,i);
					i = i - 1;
				end
				i = i + 1;
			end
		end
	elseif (oRA) then		--oRA2
		if oRA.maintanktable then
			for i=1, 5 do
				if (oRA.maintanktable[i]) then
					RaidAlerter_Table_Update(RAL_Tanks, oRA.maintanktable[i], "ADD");
				end
			end
		end
	elseif (CT_RA_MainTanks) then
		for i=1, 5 do
			if (CT_RA_MainTanks[i]) then
				RaidAlerter_Table_Update(RAL_Tanks, CT_RA_MainTanks[i], "ADD");
			end
		end
	end
	if #RAL_Tanks == 0 then
		RAL_Tanks = RAL_BlzTanks;
	end
end

--TANK判定
function RaidAlerter_TestIsMtList(inameunit)
	if oRA or CT_RA_MainTanks then		--oRA2和CTA下的RAL_Tanks未作判定，可能会属于替补
		if (UnitInRaid("player")) then
			if RaidAlerter_NameToGroup(UnitName(inameunit)) > RaidAlerter_SET.RAIDMODE_MAX_GROUP then
				return false;
			end
		end
	end
	if RaidAlerter_TestMtHasSet() then
		local i;
		for i = 1, 5 do
			if RAL_Tanks[i] then
				if RaidAlerter_NameToUnit(RAL_Tanks[i]) then
					if RAL_Tanks[i] == UnitName(inameunit) then
						return true;
					end
				end
			end
		end
		return false;
	else
		local playerClass = UnitClass(inameunit);
		if (playerClass==RAL_TEXT_WARRIOR) or (playerClass==RAL_TEXT_DEATHKNIGHT) then
			if UnitInRaid("player") then
				if UnitHealthMax(inameunit) > (RaidHPMAXAVG*1.4) then
					return true;			--高血量判定为TANK（考虑未设定TANK的情况）
				end
				return false;				--RAID中应避免DPS板甲职业OT的情况
			else
				return true;				--PARTY中DPS板甲职业也可视为TANK
			end
		elseif (playerClass==RAL_TEXT_DRUID) then		--熊德
			if UnitInRaid("player") then
				if UnitHealthMax(inameunit) > (RaidHPMAXAVG*1.4) then
					return true;			--高血量判定为TANK（考虑未设定TANK的情况）
				end
				return false;
			else
				local i = 1;
				while (UnitBuff(inameunit, i)) do
					if (string.find(UnitBuff(inameunit, i), RAL_TEXT_BUFF_3)) then
						return true;
					end
					i = i + 1;
				end
				return false;
			end
		elseif (playerClass==RAL_TEXT_PALADIN) then		--防骑
			if UnitInRaid("player") then
				if UnitHealthMax(inameunit) > (RaidHPMAXAVG*1.4) then
					return true;			--高血量判定为TANK（考虑未设定TANK的情况）
				end
				return false;
			else
				local i = 1;
				while (UnitBuff(inameunit, i)) do
					if (string.find(UnitBuff(inameunit, i), RAL_TEXT_BUFF_21)) then
						return true;		--考虑PARTY中开了正义之怒的QS客串TANK
					end
					i = i + 1;
				end
				return false;
			end
		end
	end
	return false;
end

--TANK检测
function RaidAlerter_TestMtHasSet()
	if #RAL_Tanks >= 1 then
		return #RAL_Tanks;
	else
		return false;
	end
end

--MT战斗状态判定
--[[
function RaidAlerter_TestRaidAffectingCombat()
	if (RAL_Tanks[1]) then
		local unit = RaidAlerter_NameToUnit(RAL_Tanks[1]);
		if(UnitAffectingCombat(unit)==1) then
			return true;
		end
	end
	return false;
end
]]

--原版团队战斗判定
--[[
function RaidAlerter_TestAllRaidAffectingCombat()
	local MeZone;
	for id=1, GetNumRaidMembers() do
		local name, rank, subgroup, level, class, fileName, zone, online = GetRaidRosterInfo(id);
		if UnitName("player") == name then
			MeZone=zone;
		end
	end
	for id=1, GetNumRaidMembers() do
		local name, rank, subgroup, level, class, fileName, zone, online = GetRaidRosterInfo(id);
		if(UnitAffectingCombat("raid"..id)==1) and (MeZone==zone) then
			return true;
		end
	end
	return false;
end
]]

--团队全局战斗判定
function RaidAlerter_TestAllRaidAffectingCombat()
	local MeZone = GetRealZoneText();
	RaidAlerter_Alerter_System["ctmp"] = 0;
	for id=1, GetNumRaidMembers() do
		local name, rank, subgroup, level, class, fileName, zone, online = GetRaidRosterInfo(id);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			if(UnitAffectingCombat("raid"..id)==1) and (MeZone==zone) then
				RaidAlerter_Alerter_System["ctmp"] = RaidAlerter_Alerter_System["ctmp"] + 1;
				RaidAlerter_Alerter_System["stcntmp"] = id;
			end
		end
	end
	RaidAlerter_Alerter_System["counttmp"] = RaidAlerter_Alerter_System["counttmp"] + 1;
	if RaidAlerter_Alerter_System["counttmp"] >4 then
		RaidAlerter_Alerter_System["counttmp"]=0;
	end
	if (RaidAlerter_Alerter_System["counttmp"] ==4) and (RaidAlerter_Alerter_System["maxcn"]==1) then
--		if not RaidAlerter_Check_BloodRageUp(RaidAlerter_Alerter_System["stcntmp"]) then	--WOW2.2后血性狂暴已不再触发战斗状态，此判定废止
			RaidAlerter_Alerter_System["stcn"] = RaidAlerter_Alerter_System["stcntmp"];
			RaidAlerter_Alerter_System["stcntmp"] = 0;
--		end
	end
	if ( RaidAlerter_Alerter_System["maxcn"] < RaidAlerter_Alerter_System["ctmp"] ) then
		RaidAlerter_Alerter_System["maxcn"] = RaidAlerter_Alerter_System["ctmp"];
	end
--	ManaPercent,CureManaPercent,DeadRaidmembers,OffLineRaidmembers = RaidAlerter_Get_RaidState();
	if (RaidAlerter_Alerter_System["maxcn"] > ((RaidNum - DeadRaidmembers - OffLineRaidmembers)/4) and RaidAlerter_Alerter_System["ctmp"] > 0) then
		RaidAlerter_RaidAllInCombat = true;
		return true;
	else
		if (RaidAlerter_Alerter_System["ctmp"]==0) and ( (RaidAlerter_Alerter_System["maxcn"]>0) and (RaidAlerter_Alerter_System["maxcn"] <= ((RaidNum - DeadRaidmembers - OffLineRaidmembers)/4))) then
		RaidAlerter_Alerter_System["stcn"] = 0;
		RaidAlerter_Alerter_System["maxcn"] = 0;
		end
		RaidAlerter_RaidAllInCombat = false;
		return false;
	end
	RaidAlerter_RaidAllInCombat = false;
	return false;
end

--判定自己是否和团队在同一场景
--[[
function RaidAlerter_TestMe_InRaidZone()
	local MeZone = GetRealZoneText();
	local OnlineCount = 0;
	local MeZoneCount = 0;
	for i=1, GetNumRaidMembers() do
		local _, _, _, _, _, _, zone, online = GetRaidRosterInfo(i);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			if online then
				OnlineCount = OnlineCount + 1;
				if (MeZone==zone) then
					MeZoneCount = MeZoneCount + 1;
				end
			end
		end
	end
	if (MeZoneCount > (OnlineCount/2)) then
		return true;
	else
		return false;
	end
end
]]

--查找目标锁定Boss的ID
function RaidAlerter_GetIsTargetBossUnit()
	for k, v in pairs(RaidAlerter_Bosses) do
		if UnitName("playertarget") == v then
			return "player";
		else
			for i=1, GetNumRaidMembers() do
				if UnitName("raid"..i.."target") == v then
					return "raid"..i;
				end
			end
		end
	end
	return false;
end

--查找目标为指定GUID的unit
function RaidAlerter_GetTarIsGUIDUnit(GUID)
	if ((not GUID) or GUID == "NuL" or GUID == "") then
		return false;
	elseif (GUID == UnitGUID("playertarget")) then
		return "player";
	elseif (GUID == UnitGUID("party1target")) then
		return "party1";
	elseif (GUID == UnitGUID("party2target")) then
		return "party2";
	elseif (GUID == UnitGUID("party3target")) then
		return "party3";
	elseif (GUID == UnitGUID("party4target")) then
		return "party4";
	else
		RaidNumALL = GetNumRaidMembers();
		if (RaidNumALL > 0) then
			-- we are in a raid
			for i=1, RaidNumALL do
				if (GUID == UnitGUID("raid"..i.."target")) then
					return "raid"..i;
				end
			end
		end
	end
	return false;
end

--获取PET的主人名称，直接用于"打破控制"报警
function RaidAlerter_GetPetMaster(GUID)
	if ((not GUID) or GUID == "NuL" or GUID == "") then
		return "";
	elseif (GUID == UnitGUID("pet")) then
		return "("..UnitName("player")..")";
	elseif (GUID == UnitGUID("partypet1")) then
		return "("..UnitName("party1")..")";
	elseif (GUID == UnitGUID("partypet2")) then
		return "("..UnitName("party2")..")";
	elseif (GUID == UnitGUID("partypet3")) then
		return "("..UnitName("party3")..")";
	elseif (GUID == UnitGUID("partypet4")) then
		return "("..UnitName("party4")..")";
	else
		RaidNumALL = GetNumRaidMembers();
		if (RaidNumALL > 0) then
			-- we are in a raid
			for i=1, RaidNumALL do
				if (GUID == UnitGUID("raidpet"..i)) then
					return "("..UnitName("raid"..i)..")";
				end
			end
		end
	end
	return "";
end

--获取Unit的标记符号
function RaidAlerter_GetUnitICONTEXT(unit)
	ICONTEXT_icontext = "";
	if unit then
		ICONTEXT_icon = GetRaidTargetIndex(unit);
		if ICONTEXT_icon then
			ICONTEXT_icontext = RaidAlerter_RAIDICON[ICONTEXT_icon];
		end
	end
	return ICONTEXT_icontext;
end

--获取怪物GUID的标记符号
function RaidAlerter_GUIDTOICONTEXT(GUID)
	ICONTEXT_unit = RaidAlerter_GetTarIsGUIDUnit(GUID);
	if ICONTEXT_unit then
		return RaidAlerter_GetUnitICONTEXT(ICONTEXT_unit.."target");
	else
		return "";
	end
end

--查找目标锁定Boss的ID（5人小队）
function RaidAlerter_GetIsTargetBossUnit_Party()
	for k, v in pairs(RaidAlerter_Bosses) do
		if UnitName("playertarget") == v then
			return "player";
		end
	end
	for i=1, GetNumPartyMembers() do
		for k, v in pairs(RaidAlerter_Bosses) do
			if UnitName("party"..i.."target") == v then
				return "party"..i;
			end
		end
	end
	return false;
end

--获取当次RAID的boss名单
function RaidAlerter_Boss_Record()
	local n = 0;
--	if not RaidAlerter_RaidAllInCombat then		--考虑极远带怪时未看到boss就全副本进战斗的状况，取消此限定
		for i=1, GetNumRaidMembers() do
			if RaidAlerter_IsBossUnit("raid"..i.."target") then
				RaidAlerter_Bosses_TableUpdate(UnitName("raid"..i.."target"));
				n=n+1;
				if n>3 then		--4次中断以提高运行效率
					return;
				end
			end
		end
--	end
end

--获取当次PARTY的boss名单
function RaidAlerter_Boss_Record_Party()
	local n = 0;
	if RaidAlerter_IsBossUnit("playertarget") then
		if not RaidAlerter_Bosses_TableUpdate_EXC(UnitName("playertarget")) then		--Boss表排除某些特定小怪
			RaidAlerter_Bosses_TableUpdate(UnitName("playertarget"));
			n=n+1;
		end
	end
	for i=1, GetNumPartyMembers() do
		if RaidAlerter_IsBossUnit("party"..i.."target") then
			if not RaidAlerter_Bosses_TableUpdate_EXC(UnitName("party"..i.."target")) then		--Boss表排除某些特定小怪
				RaidAlerter_Bosses_TableUpdate(UnitName("party"..i.."target"));
				n=n+1;
			end
			if n>1 then		--2次中断以提高运行效率
				return;
			end
		end
	end
end

function RaidAlerter_LootMethodTEXT(TipTextMode)	--1全 2简
	if TipTextMode == 1 then
		return RaidAlerter_GetColoredText(_G["ITEM_QUALITY_COLORS"][GetLootThreshold()], RAL_LootMethod_SYS[GetLootMethod()]);
	else
		return RaidAlerter_GetColoredText(_G["ITEM_QUALITY_COLORS"][GetLootThreshold()], RAL_LootMethod[GetLootMethod()]);
	end
end

function RaidAlerter_GetColoredText(color, text)
	if (color and text) then
		return format("|cFF%s%s|r",format("%02X%02X%02X",color.r*255,color.g*255,color.b*255),text);
	else
		return "";
	end
end

function RaidAlerter_GetCurrentDifficulty(TipTextMode)		--副本难度返回值：1=普通  2=英雄
	SysDif = 1;	--小队：1=普通 2=英雄		团队：1=10人  2=25人  3=10人(英雄)  4=25人(英雄)
	EQDif = 1;	--副本难度：1=普通  2=英雄
	DifText = "";
	_, instanceType, difficulty, _, maxPlayers, playerDifficulty, isDynamicInstance = GetInstanceInfo();
	if instanceType == "raid" then				--在副本时直接读取副本参数
		SysDif = difficulty;
		if difficulty > 2 then EQDif = 2;end
	elseif instanceType == "party" then			--在副本时直接读取副本参数
		SysDif = difficulty;
		EQDif = SysDif;
	else										--不在副本时读取团队设定值
		if UnitInRaid("player") then
			SysDif = GetRaidDifficulty();
			if SysDif > 2 then EQDif = 2;end
		elseif GetNumPartyMembers() > 0 then
			SysDif = GetDungeonDifficulty();
			EQDif = SysDif;
		end
	end

	if isDynamicInstance then			--可动态调整难度的副本
		if playerDifficulty == 1 then
			EQDif = 2;
		end
	end

	if TipTextMode then
		--字串处理
		if instanceType == "party" or instanceType == "raid" then			--在副本时
			if EQDif == 1 then
				DifText = string.format(RAL_TEXT_TIP_36, RAL.ToWhite(maxPlayers), RAL.ToGreen(RAL_TEXT_TIP_33));
			else
				DifText = string.format(RAL_TEXT_TIP_36, RAL.ToWhite(maxPlayers), RAL.ToRed(RAL_TEXT_TIP_34));
			end
		else		--不在副本
			if UnitInRaid("player") then
				if SysDif == 1 then DifText = RAL.ToWhite(RAL_TEXT_TIP_31)..RAL.ToGreen(RAL_TEXT_TIP_33) end;
				if SysDif == 2 then DifText = RAL.ToWhite(RAL_TEXT_TIP_32)..RAL.ToGreen(RAL_TEXT_TIP_33) end;
				if SysDif == 3 then DifText = RAL.ToWhite(RAL_TEXT_TIP_31)..RAL.ToRed(RAL_TEXT_TIP_34) end;
				if SysDif == 4 then DifText = RAL.ToWhite(RAL_TEXT_TIP_32)..RAL.ToRed(RAL_TEXT_TIP_34) end;
			elseif GetNumPartyMembers() > 0 then
				DifText = RAL.ToWhite(RAL_TEXT_TIP_30);
				if SysDif == 1 then
					DifText = DifText..RAL.ToGreen(RAL_TEXT_TIP_33);
				else
					DifText = DifText..RAL.ToRed(RAL_TEXT_TIP_34);
				end
			end
		end
		if TipTextMode == 1 then			--1完整彩色文本如：25人英雄
			return DifText;
		elseif TipTextMode == 2 then		--2仅难度如：英雄
			if EQDif == 1 then
				return RAL.ToGreen(RAL_TEXT_TIP_33);
			elseif EQDif == 2 then
				return RAL.ToRed(RAL_TEXT_TIP_34);
			else
				return "";
			end
		elseif TipTextMode == 3 then		--3(用于tip显示)完整彩色文本并显示动态如：25人英雄(动态)
			if isDynamicInstance then
				return DifText.."("..RAL.ToYellow(RAL_TEXT_TIP_37)..")";
			else
				return DifText;
			end
		end
	else
		return EQDif;
	end
end

function RaidAlerter_IsBossUnit(unit)
	if UnitExists(unit) then
		if (UnitClassification(unit) == "worldboss") then
			return true;
		end
		BossHPMin = 999999999;
		if UnitInRaid("player") then
			if (RaidNum - OffLineRaidmembers) > 14 then
				BossHPMin = RaidHPMAXAVG*200;		--25RAID
			else
				BossHPMin = RaidHPMAXAVG*80;		--10RAID
			end
		elseif GetNumPartyMembers() > 0 then
			TeamLevel = UnitLevel("player");
			PartyHPMAXAVG = UnitHealthMax("player");
			for i=1, GetNumPartyMembers() do
				TeamLevel = TeamLevel + UnitLevel("party"..i);
				PartyHPMAXAVG = PartyHPMAXAVG + UnitHealthMax("party"..i);
			end
			TeamLevel = TeamLevel/(GetNumPartyMembers()+1);
			PartyHPMAXAVG = PartyHPMAXAVG/(GetNumPartyMembers()+1);
			BossHPMin = PartyHPMAXAVG*15;			--PARTY
		end
		if EQDif >= 2 then
			BossHPMin = BossHPMin*1.35;
		end
--		if TeamLevel > 80 then
--			BossHPMin = BossHPMin*(1+((TeamLevel-80)/5));		--Lv80-85动态调整
--		end
		if (UnitHealth(unit) > BossHPMin) then
			return true;
		end
		return false;
	end
	return false;
end

function RaidAlerter_IsDangerUnit(unit)
	if UnitExists(unit) then
		if (not UnitIsDead(unit)) and UnitCanAttack("player", unit) then
			if (UnitClassification(unit) == "worldboss") then
				return true;
			end
			DangerUnitHPMin = 666666666;
			if UnitInRaid("player") then
				if (RaidNum - OffLineRaidmembers) > 14 then
					DangerUnitHPMin = RaidHPMAXAVG*20;		--25RAID
				else
					DangerUnitHPMin = RaidHPMAXAVG*8;		--10RAID
				end
			elseif GetNumPartyMembers() > 0 then
				DangerUnitHPMin = PartyHPMAXAVG*3;			--PARTY
			end
			if EQDif >= 2 then
				DangerUnitHPMin = DangerUnitHPMin*1.35;
			end
--			if TeamLevel > 80 then
--				DangerUnitHPMin = DangerUnitHPMin*(1+((TeamLevel-80)/5));		--Lv80-85动态调整
--			end
			if (UnitLevel(unit)-TeamLevel) >= 3 then
				DangerUnitHPMin = DangerUnitHPMin*0.75;
			elseif (UnitLevel(unit)-TeamLevel) >= 2 then
				DangerUnitHPMin = DangerUnitHPMin*0.85;
			end
			if (UnitClassification(unit) == "normal") then
				DangerUnitHPMin = DangerUnitHPMin*3;
			end
			if (UnitHealthMax(unit) > DangerUnitHPMin) then
				return true;
			end
			return false;
		end
	end
	return false;
end

--查找危险怪物的ID
function RaidAlerter_GetDangerUnit()
	if RaidAlerter_IsDangerUnit("playertarget") then
		return "playertarget";
	elseif UnitInRaid("player") then
		for i=1, GetNumRaidMembers() do
			if RaidAlerter_IsDangerUnit("raid"..i.."target") then
				return "raid"..i.."target";
			end
		end
	elseif GetNumPartyMembers() > 0 then
		for i=1, GetNumPartyMembers() do
			if RaidAlerter_IsDangerUnit("party"..i.."target") then
				return "party"..i.."target";
			end
		end
	end
	return false;
end

--无重复数据的表单数据更新
function RaidAlerter_Table_Update(TableName, Data, ACT)
	ACT = string.upper(ACT);
	if ACT == "ADD" then
		local samed = 0;
		for k, v in pairs(TableName) do
			if v == Data then
				samed = 1;
				return;
			end
		end
		if samed == 0 then
			table.insert(TableName,Data);
		end
	elseif ACT == "DEL" then
		for k, v in pairs(TableName) do
			if v == Data then
				table.remove(TableName,k);
				return;
			end
		end
	else
		return false;
	end
end

--更新Boss表
function RaidAlerter_Bosses_TableUpdate(bname)
	local bnsamed = 0;
	for k, v in pairs(RaidAlerter_Bosses) do
		if v == bname then
			bnsamed = 1;
			return;
		end
	end
	if bnsamed == 0 then
		table.insert(RaidAlerter_Bosses,bname);
	end
end

--Boss表排除特例
function RaidAlerter_Bosses_TableUpdate_EXC(bname)
	for k, v in pairs(RaidAlerter_Bosses_EXC) do
		if v == bname then
			return true;
		end
	end
	return false;
end

--灵魂石检测
function RaidAlerter_Check_SoulGemOn()
	GemName = {};
	for id=1, GetNumRaidMembers() do
		_, _, subgroup = GetRaidRosterInfo(id);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			local i = 1;
			while (UnitBuff("raid"..id, i)) do
				if (string.find(UnitBuff("raid"..id, i), RAL_TEXT_BUFF_1)) then
					RaidAlerter_Table_Update(GemName, UnitName("raid"..id), "ADD");
				end
			i = i + 1;
			end
		end
	end
end

--获取已保存灵魂石的玩家列表字串
function RaidAlerter_GetGemOnNames(SetClassColor)
	if #GemName == 0 then return "";end
	local GemMSG = "";
	for id=1, #GemName do
		if SetClassColor == 1 then
			GemMSG = GemMSG..RaidAlerter_ToClassColorNameText(GemName[id])..".";
		else
			GemMSG = GemMSG..GemName[id]..".";
		end
	end
	return GemMSG;
end

--变形检测
function RaidAlerter_Check_P_BeControled_ButIsPolyUp(unit)
	local i = 1;
	while (UnitDebuff(unit, i)) do
		if (string.find(UnitDebuff(unit, i), RAL_TEXT_BUFF_10) or string.find(UnitDebuff(unit, i), RAL_TEXT_BUFF_11)) then
			return true;
		end
		i = i + 1;
	end
	return false;
end

--判断是否自己被控制（团队）
function RaidAlerter_TestEnemyIsMe()
	local Enemy_control_Count = 0;
	for id=1, GetNumRaidMembers() do
		if (UnitIsFriend("player", "raid"..id) and UnitIsEnemy("player", "raid"..id)) then
			Enemy_control_Count = Enemy_control_Count + 1;
		end
	end
	if (Enemy_control_Count > RaidNum/2 ) then
		return true;
	else
		return false;
	end
end

--判断是否自己被控制（5人小队）
function RaidAlerter_TestEnemyIsMe_Party()
	local Enemy_control_Count = 0;
	for id=1, GetNumPartyMembers() do
		if (UnitIsFriend("player", "party"..id) and UnitIsEnemy("player", "party"..id)) then
			Enemy_control_Count = Enemy_control_Count + 1;
		end
	end
	if (Enemy_control_Count > GetNumPartyMembers()/2 ) then
		return true;
	else
		return false;
	end
end

--控制警报（团队）
function RaidAlerter_Check_P_BeControled()
	local BC_count = 0;
	local DEP_count = 0;
	for id=1, GetNumRaidMembers() do
		if (BC_count >= 3) or (DEP_count >= 3) then return; end			--一次最多只报3人，防刷屏
--		local unit = RaidAlerter_NameToUnit(UnitName("raid"..id));
		local unit = "raid"..id;
		if (unit) then
			if (UnitIsFriend("player", "raid"..id) and UnitIsEnemy("player", "raid"..id)) then
				if RaidAlerter_Check_P_BeControled_ButIsPolyUp("raid"..id) then
					RaidAlerter_Alerter_BeControled[unit] = 0;
				else
					RaidAlerter_Alerter_BeControled[unit] = RaidAlerter_Alerter_BeControled[unit] + 1;
				end
				if ( RaidAlerter_Alerter_BeControled[unit] > 40) then
					RaidAlerter_Alerter_BeControled[unit] = 0;
				elseif ( RaidAlerter_Alerter_BeControled[unit] == 1)then
					if RaidAlerter_SET.Check_Poly then
						if RaidAlerter_TestEnemyIsMe() then
							if RaidAlerter_GetTimer("BC"..UnitName("player"))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_7,UnitName("player")),"RAID_WARNING");
								RaidAlerter_StartTimer("BC"..UnitName("player"));
								SetRaidTargetIcon("player", 8);
								RaidAlerter_Alerter_System["lasticon"] = UnitName("player");
								if BC_count == 0 then
									RAL.SOUND(5);
								end
								BC_count = BC_count + 1;
							end
						else
							if RaidAlerter_GetTimer("BC"..UnitName("raid"..id))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_7,UnitName("raid"..id)),"RAID_WARNING");
								RaidAlerter_StartTimer("BC"..UnitName("raid"..id));
								SetRaidTargetIcon("raid"..id, 8);
								RaidAlerter_Alerter_System["lasticon"] = UnitName("raid"..id);
								if BC_count == 0 then
									RAL.SOUND(5);
								end
								BC_count = BC_count + 1;
							end
						end
					end
				end
--				return;
			else
				if ( RaidAlerter_Check_P_BeControled_ButIsPolyUp("raid"..id) and RaidAlerter_TestIsMtList(unit) and UnitIsFriend("player", "raid"..id) ) then
					RaidAlerter_Alerter_BeControled[unit] = RaidAlerter_Alerter_BeControled[unit] + 1000;
					if ( RaidAlerter_Alerter_BeControled[unit] > 40000) then
						RaidAlerter_Alerter_BeControled[unit] = 0;
					elseif ( RaidAlerter_Alerter_BeControled[unit] == 1000)then
						if RaidAlerter_SET.PolyDispel then
							if RaidAlerter_GetTimer("DEP"..UnitName("raid"..id))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_8,UnitName("raid"..id)),"RAID");
								SetRaidTargetIcon("raid"..id, 8);
								RaidAlerter_Alerter_System["lasticon"] = UnitName("raid"..id);
								RaidAlerter_StartTimer("DEP"..UnitName("raid"..id));
								DEP_count = DEP_count + 1;
							end
						end
					end
				else
					RaidAlerter_Alerter_BeControled[unit] = 0;
				end
			end
		end
	end
	return true;
end

--控制警报（5人小队）
function RaidAlerter_Check_P_BeControled_Party()
	local unit = "";
	local BC_count = 0;
	local DEP_count = 0;
	for id=0, GetNumPartyMembers() do
		if (BC_count >= 3) or (DEP_count >= 3) then return; end			--一次最多只报3人，防刷屏
		if id==0 then unit="player" else unit="party"..id end
		if (unit) then
			if (UnitIsFriend("player", unit) and UnitIsEnemy("player", unit)) then
				if RaidAlerter_Check_P_BeControled_ButIsPolyUp(unit) then
					RaidAlerter_Alerter_BeControled[unit] = 0;
				else
					RaidAlerter_Alerter_BeControled[unit] = RaidAlerter_Alerter_BeControled[unit] + 1;
				end
				if ( RaidAlerter_Alerter_BeControled[unit] > 40) then
					RaidAlerter_Alerter_BeControled[unit] = 0;
				elseif ( RaidAlerter_Alerter_BeControled[unit] == 1)then
					if RaidAlerter_SET.Check_Poly then
						if RaidAlerter_TestEnemyIsMe_Party() then
							if RaidAlerter_GetTimer("BC"..UnitName("player"))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_7,UnitName("player")),"PARTY_RW");
								RaidAlerter_StartTimer("BC"..UnitName("player"));
								if BC_count == 0 then
									RAL.SOUND(5);
								end
								BC_count = BC_count + 1;
							end
						else
							if RaidAlerter_GetTimer("BC"..UnitName(unit))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_7,UnitName(unit)),"PARTY_RW");
								RaidAlerter_StartTimer("BC"..UnitName(unit));
								if BC_count == 0 then
									RAL.SOUND(5);
								end
								BC_count = BC_count + 1;
							end
						end
					end
				end
--				return;
			else
				if ( RaidAlerter_Check_P_BeControled_ButIsPolyUp(unit) and RaidAlerter_TestIsMtList(unit) and UnitIsFriend("player", unit) ) then
					RaidAlerter_Alerter_BeControled[unit] = RaidAlerter_Alerter_BeControled[unit] + 1000;
					if ( RaidAlerter_Alerter_BeControled[unit] > 40000) then
						RaidAlerter_Alerter_BeControled[unit] = 0;
					elseif ( RaidAlerter_Alerter_BeControled[unit] == 1000)then
						if RaidAlerter_SET.PolyDispel then
							if RaidAlerter_GetTimer("DEP"..UnitName(unit))>5 then		--同一人5秒内只报一次
								RAL.SendMSG(string.format(RAL_TEXT_ALERT_8,UnitName(unit)),"PARTY");
--								SetRaidTargetIcon(unit, 8);
--								RaidAlerter_Alerter_System["lasticon"] = UnitName(unit);
								RaidAlerter_StartTimer("DEP"..UnitName(unit));
								DEP_count = DEP_count + 1;
							end
						end
					end
				else
					RaidAlerter_Alerter_BeControled[unit] = 0;
				end
			end
		end
	end
	return true;
end

--查找锁定标记者ID
--[[
function RaidAlerter_Find_Hunter_SniperShot()
	if UnitExists("playertarget") then
		if(not UnitIsFriend("player","playertarget")) then
--				if (not RaidAlerter_TargetDeBU("Ability_Hunter_SniperShot","playertarget")) then
				if (not RaidAlerter_TargetDeBU(RAL_TEXT_BUFF_2,"playertarget")) then
					return "player";
				end
		end
	end
	if (UnitInRaid("player")) then
		for id=1, GetNumRaidMembers() do
			local unit = "raid"..id;
			if (UnitIsConnected(unit)) then
				if (not UnitIsDeadOrGhost(unit)) then
					if UnitExists("raid"..id.."target") then
							if(not UnitIsFriend("player","raid"..id.."target")) then
--								if (not RaidAlerter_TargetDeBU("Ability_Hunter_SniperShot",unit.."target")) then
								if (not RaidAlerter_TargetDeBU(RAL_TEXT_BUFF_2,unit.."target")) then
									return unit;
								end
							end
					end
				end
			end
		end
	end
	return "";
end
]]

--玩家名称转换为ID
function RaidAlerter_NameToUnit(Name)
	if (not Name) then
		return false;
	end
	Name = Name:match("(.+)%-(.+)") or Name;
	if (Name == UnitName("player")) then
		return "player";
	elseif (Name == UnitName("party1")) then
		return "party1";
	elseif (Name == UnitName("party2")) then
		return "party2";
	elseif (Name == UnitName("party3")) then
		return "party3";
	elseif (Name == UnitName("party4")) then
		return "party4";
	else
		RaidNumALL = GetNumRaidMembers();
		if (RaidNumALL > 0) then
			-- we are in a raid
			for i=1, RaidNumALL do
				if Name == GetRaidRosterInfo(i) then
					return "raid"..i;
				end
			end
		end
	end
	return false;
end

--玩家GUID转换为ID
function RaidAlerter_GUIDToUnit(GUID)
	if (not GUID) then
		return false;
	elseif (GUID == UnitGUID("player")) then
		return "player";
	elseif (GUID == UnitGUID("party1")) then
		return "party1";
	elseif (GUID == UnitGUID("party2")) then
		return "party2";
	elseif (GUID == UnitGUID("party3")) then
		return "party3";
	elseif (GUID == UnitGUID("party4")) then
		return "party4";
	else
		RaidNumALL = GetNumRaidMembers();
		if (RaidNumALL > 0) then
			-- we are in a raid
			for i=1, RaidNumALL do
				if GUID == UnitGUID("raid"..i) then
					return "raid"..i;
				end
			end
		end
	end
	return false;
end

--PET名称转换为ID
--[[
function RaidAlerter_PetNameToUnit(Name)
	if (Name or Name ~="") then
		for k, v in pairs(RaidAlerter_Bosses) do
			if v == Name then
				return false;
			end
		end
	end
	if (not Name) then
		return false;
	elseif (Name == UnitName("pet")) then
		return "pet";
	elseif (Name == UnitName("partypet1")) then
		return "partypet1";
	elseif (Name == UnitName("partypet2")) then
		return "partypet2";
	elseif (Name == UnitName("partypet3")) then
		return "partypet3";
	elseif (Name == UnitName("partypet4")) then
		return "partypet4";
	else
		local numRaidMembers = GetNumRaidMembers();
		if (numRaidMembers > 0) then
			-- we are in a raid
			for i=1, numRaidMembers do
				RaidPetName = UnitName("raidpet"..i);
				if ( Name == RaidPetName) then
					return "raidpet"..i;
				end
			end
		end
	end
	return false;
end
]]

--查找玩家的小队号（团队）
function RaidAlerter_NameToGroup(CheckName)
	for i=1, GetNumRaidMembers() do
		local name, _, subgroup = GetRaidRosterInfo(i);
		if ( name == CheckName) then
			return subgroup;
		end
	end
	return 9999;
end

--团队参数更新：DPS和治疗法力、死亡、离线、有效人数，平均等级
function RaidAlerter_Get_RaidState()
	DeadRaidmembers = 0;
	OffLineRaidmembers = 0;
	RaidNum = 0;
	local totalmana = 0;
	local totalmanamax = 0;
	local totalcuremana = 0;
	local totalcuremanamax = 0;
	local playerClass;
	local level;
	local totallevel = 0;
	local totalhpmax = 0;
	local role = "";
	RAL_BlzTanks = {};

	for id=1, GetNumRaidMembers() do
		_, _, subgroup, level, playerClass, _, _, _, _, role = GetRaidRosterInfo(id);
		if subgroup <= RaidAlerter_SET.RAIDMODE_MAX_GROUP then
			local unit = "raid"..id;
			if role == "MAINTANK" then
--				table.insert(RAL_BlzTanks, UnitName(unit));
				RaidAlerter_Table_Update(RAL_BlzTanks, UnitName(unit), "ADD");
			end
			if (UnitIsConnected(unit)) then
				if (UnitIsDeadOrGhost(unit)) then
					DeadRaidmembers = DeadRaidmembers + 1;
				else
					if (UnitPowerType(unit) == 0) then
						if (playerClass==RAL_TEXT_PRIEST) or (playerClass==RAL_TEXT_SHAMAN) or
						(playerClass==RAL_TEXT_DRUID) or (playerClass==RAL_TEXT_PALADIN)then
							totalcuremana = totalcuremana + UnitMana(unit);
							totalcuremanamax = totalcuremanamax + UnitManaMax(unit);
						else
							totalmana = totalmana + UnitMana(unit);
							totalmanamax = totalmanamax + UnitManaMax(unit);
						end
					end
				end
				totalhpmax = totalhpmax + UnitHealthMax(unit);
			else
				OffLineRaidmembers = OffLineRaidmembers + 1;
			end
			totallevel = totallevel + level;
			RaidNum = RaidNum + 1;
		end
	end
	if totalcuremana ~= 0 then
		CureManaPercent = floor(totalcuremana/totalcuremanamax*100+0.5);
	else
		CureManaPercent = 0;
	end
	if totalmana ~=0 then
		ManaPercent = floor(totalmana/totalmanamax*100+0.5);
	else
		ManaPercent = 0;
	end
	TeamLevel = totallevel/RaidNum;
	if RaidNum > OffLineRaidmembers then
		RaidHPMAXAVG = totalhpmax/(RaidNum-OffLineRaidmembers);
	end
--	return ManaPercent,CureManaPercent,DeadRaidmembers,OffLineRaidmembers,RaidNum,TeamLevel;
end

function RaidAlerter_Whisper(playerName, Message)
	if (RaidAlerter_SYNC_SELECT_TOME==1) and (IsRaidLeader() or IsRaidOfficer()) then
		--如果是仅本机或仅本屏的话, 则不发送密语
		if (RaidAlerter_SET.OnlySelfCHAN or RaidAlerter_SET.OnlySelfSCR) then return end
		return SendChatMessage("<RaidAlerter> "..Message, "WHISPER", nil, playerName);
	end
end

local RaidAlerterTimerDatas = {
		{
		["Name"] = "RaidAlerter_Update",
		["Time"] = 0,
		},
};

function RaidAlerter_StartTimer(id)
	for k, v in pairs(RaidAlerterTimerDatas) do
		if(id == v["Name"]) then
			v["Time"] = GetTime();
			return;
		end
	end
	table.insert(RaidAlerterTimerDatas,
		{
		["Name"] = id,
		["Time"] = GetTime(),
		});
end

function RaidAlerter_GetTimer(id)
	for k, v in pairs(RaidAlerterTimerDatas) do
		if(id == v["Name"]) then
			Timer_NOW = GetTime();
			Timer_START = v["Time"];
			return (Timer_NOW - Timer_START), Timer_START, Timer_NOW;
		end
	end
	return 9999;
end

--[[
function RaidAlerter_EndTimer(id)
	for k, v in pairs(RaidAlerterTimerDatas) do
		if(id == v["Name"]) then
			table.remove(RaidAlerterTimerDatas,k);
			return;
		end
	end
end
]]

function RaidAlerter_SecondsToTime(seconds, returntype)
	local m, s;
	if not tonumber(seconds) then
		return 0, 0;
	else
		seconds = tonumber(seconds);
		seconds = floor(seconds);
	end
	m = floor(seconds/60);
	s = seconds - (m*60);
	if s == 60 then
		s = 0;
		m = m + 1;
	end
	return m, s;
end

function RaidAlerter_Inspect(self, check)
	local unit = "player";
 	if UnitExists("mouseover") then unit="mouseover";end
 	if UnitExists("target") then
		if (not UnitIsPlayer("target")) and (UnitExists("mouseover") and UnitIsPlayer("mouseover"))then
			unit="mouseover";
		else
			unit="target";
		end
	end
	if InspectFrame then
		if InspectFrame:IsVisible() and unit=="player" then
			HideUIPanel(InspectFrame);
			return;
		end
	end
	if SuperInspectFrame then
		if(SuperInspectFrame:IsVisible()) and unit=="player" then
			HideUIPanel(SuperInspectFrame);
			return;
		end
	end
	InspectUnit(unit);
end

function RaidAlerter.AddMsg(msg, NoPrefix)
	if DEFAULT_CHAT_FRAME then
		if not NoPrefix then
			DEFAULT_CHAT_FRAME:AddMessage("|cFFFF7711<|r|cFFFFFF99"..RaidAlerter_UINameEN.."|r|cFFFF7711>|r"..tostring(msg).."|r", 1, 1, 0.8);
		elseif NoPrefix == 1 then
			DEFAULT_CHAT_FRAME:AddMessage(tostring(msg), 1, 1, 0.8);
		end
	end
end

function RaidAlerter.AddErrorMsg(msg)
	if UIErrorsFrame then
		UIErrorsFrame:AddMessage(tostring(msg), 1, 1, 0.8);
	end
end

function RaidAlerter.AddSCRMsg(msg, iconsize, WithChatFrameMSG)
	if RaidAlerter_SET.ScrMsg then
		if not iconsize then iconsize = 0;end
		for index,value in pairs(RaidAlerter_RAIDICON) do
			msg = string.gsub(msg,value,"|T".."Interface\\TargetingFrame\\UI-RaidTargetingIcon_"..index..":"..iconsize.."|t");
		end
		msg = string.gsub(msg,RAL_TEXT_ARROW_L,RAL.ToOrange(RAL_TEXT_ARROW_L));
		msg = string.gsub(msg,RAL_TEXT_ARROW_R,RAL.ToOrange(RAL_TEXT_ARROW_R));
		msg = string.gsub(msg,"%*%*",RAL.ToGreen("**"));
		RAL_SCRInfo:AddMessage(tostring(msg), 1.0, 1.0, 0.7);
		if WithChatFrameMSG then
			RaidAlerter.AddMsg(msg);
		end
	end
end

function RaidAlerter_SetAddonMessage(ARG_1,msg)
	if not ARG_1 then return; end
	if not msg then return; end
	if (ARG_1=="RAL_SELECTREPLY") and ((not RaidAlerter_SET.OnOff) or RaidAlerter_SET.OnlySelfCHAN or RaidAlerter_SET.OnlySelfSCR) then
		return;
	end

	if ARG_1=="RAL_SELECT" or ARG_1=="RAL_SELECTREPLY" then
		if RaidAlerter_GetTimer("SYNCSELECT")>4 then		--4秒前的传递参数视为过期，重置
			RaidAlerter_SYNC_SELECT_TMPPRA = 0;
			RaidAlerter_SYNC_SELECT_NAME = "|cFFFF0000"..RAL_TEXT_SYNC_SELECT_NONE.."|r";
			RaidAlerter_StartTimer("SYNCSELECT");
		end
	end

	local SendAddonMSG = false;
	local SendAddonMSGCHAN = "";

	if ARG_1=="RAL_CHECKVER" or ARG_1=="RAL_CHECKVERREPLY" then SendAddonMSG = true;end

	if (UnitInRaid("player")) then
		if ARG_1=="RAL_SELECT" or ARG_1=="RAL_CHECKVER" or ARG_1=="RAL_CHECKVERREPLY" then
			SendAddonMSG = true;
			SendAddonMSGCHAN = "RAID";
		end
		if (IsRaidLeader() or IsRaidOfficer()) then
			SendAddonMSG = true;
			SendAddonMSGCHAN = "RAID";
		end
	elseif GetNumPartyMembers()>0 then
		if (ARG_1=="RAL_SELECTREPLY") and (not RaidAlerter_SET.Party_Alerter) then
			return;
		end
		SendAddonMSG = true;
		SendAddonMSGCHAN = "PARTY";
	end

	if SendAddonMSG and SendAddonMSGCHAN~="" then
--		SendAddonMessage(ARG_1,msg,SendAddonMSGCHAN);
		RAL_UIMSG_PREFIX = ARG_1;
		RAL_UIMSG_MSG = msg;
		RAL_UIMSG_CHAN = SendAddonMSGCHAN;
		RAL_UIMSG_SENDED = false;
	end
end

function RaidAlerter_SendAddonMessage()
	if not RAL_UIMSG_SENDED then
		if RaidAlerter_GetTimer("RAL_UIMSG_TIME") >= RAL_UIMSG_TIMELIMIT then		--4.0后SendAddonMessage()使用频率限制?
			SendAddonMessage(RAL_UIMSG_PREFIX,RAL_UIMSG_MSG,RAL_UIMSG_CHAN);
			RAL_UIMSG_SENDED = true;
			RaidAlerter_StartTimer("RAL_UIMSG_TIME");
		end
	end
end

function RAL.SendMSG(msg, chan, ForceSend, CheckTime, MsgID)
	if not msg then return; end
	if not chan then chan="MYCHAN"; end

	if CheckTime and MsgID then
		if RaidAlerter_GetTimer("MSG"..MsgID) < CheckTime then
			return;
		else
			RaidAlerter_StartTimer("MSG"..MsgID);
		end
	end

	chan = string.upper(chan);
	if chan == "S" then chan = "SAY" end
	if chan == "Y" then chan = "YELL" end
	if chan == "RA" then chan = "RAID" end
	if chan == "RW" then chan = "RAID_WARNING" end

	if RaidAlerter_SET.OnlySelfCHAN then chan = "MYCHAN" end
	if RaidAlerter_SET.OnlySelfSCR then chan = "MYSCR" end
	if (RaidAlerter_SET.OnlySelfCHAN and RaidAlerter_SET.OnlySelfSCR) then chan = "MYCHANandSCR" end

	if not(chan=="MYCHAN" or chan=="MYSCR" or chan=="MYCHANandSCR" or chan=="SAY" or chan=="YELL" or chan=="PARTY" or chan=="PARTY_RW" or chan=="RAID" or chan=="RAID_WARNING") then
		return;
	end
	if not UnitInRaid("player") then
		if (chan=="RAID") then chan = "PARTY";end
		if (chan=="RAID_WARNING") then chan = "PARTY_RW";end
	end

	if chan =="PARTY" then
		if (RaidAlerter_SYNC_SELECT_TOME==1) or (ForceSend == 1) then
			SendChatMessage(msg,chan);
--		else
--			RaidAlerter.AddMsg(msg);
		end
		RaidAlerter.AddSCRMsg(msg);
		return;
	end
	if chan =="PARTY_RW" then
		if RaidAlerter_SYNC_SELECT_TOME==1 then
			--3.2-4.0过渡
			if GameVER >= 30300 then
				SendChatMessage(msg,"PARTY");
				RaidAlerter.AddSCRMsg(msg);
			else
				SendChatMessage(msg,"RAID_WARNING");
			end
		else
--			RaidAlerter.AddMsg(msg);
			if GameVER >= 30300 then
				RaidAlerter.AddSCRMsg(msg);
			end
		end
		return;
	end
	if (chan=="RAID" or chan=="RAID_WARNING") then
		if ((IsRaidLeader() or IsRaidOfficer()) and (RaidAlerter_SYNC_SELECT_TOME==1)) or (chan=="RAID" and ForceSend == 1) then
			SendChatMessage(msg,chan);
			return;
		elseif RaidAlerter_SYNC_SELECT_NAME == "|cFFFF0000"..RAL_TEXT_SYNC_SELECT_NONE.."|r" then
			if chan=="RAID_WARNING" then
				RaidAlerter.AddSCRMsg(msg);
			end
			RaidAlerter.AddMsg(msg);
			return;
		end
	end
	if chan =="MYCHAN" then
		RaidAlerter.AddMsg(msg);
		return;
	end
	if chan =="MYSCR" then
		RaidAlerter.AddSCRMsg(msg);
		return;
	end
	if chan =="MYCHANandSCR" then
		RaidAlerter.AddMsg(msg);
		RaidAlerter.AddSCRMsg(msg);
		return;
	end
	if (chan=="SAY" or chan=="YELL") then
		SendChatMessage(msg,chan);
		return;
	end
end

function RAL.SOUND(i)
	if RaidAlerter_SET.SoundAlert then
		PlaySoundFile(RaidAlerter_SOUND_DATA[i]);
	end
end

function RAL.ToWhite(text)
	if (not text) or (text==nil) then return "";end
	return "|cFFFFFFFF"..tostring(text).."|r";
end
function RAL.ToRed(text)
	if (not text) or (text==nil) then return "";end
	return "|cFFFF0000"..tostring(text).."|r";
end
function RAL.ToGreen(text)
	if (not text) or (text==nil) then return "";end
	return "|cFF00FF00"..tostring(text).."|r";
end
function RAL.ToBlue(text)
	if (not text) or (text==nil) then return "";end
	return "|cFF0000FF"..tostring(text).."|r";
end
function RAL.ToYellow(text)
	if (not text) or (text==nil) then return "";end
	return "|cFFFFFF00"..tostring(text).."|r";
end
function RAL.ToCyan(text)
	if (not text) or (text==nil) then return "";end
	return "|cFF00FFFF"..tostring(text).."|r";
end
function RAL.ToPink(text)
	if (not text) or (text==nil) then return "";end
	return "|cFFFF00FF"..tostring(text).."|r";
end
function RAL.ToOrange(text)
	if (not text) or (text==nil) then return "";end
	return "|cFFFF9900"..tostring(text).."|r";
end

--[[
function RAL.ChatIconToSCRText(icontext, size)
	if (not icontext) or (icontext==nil) then return "";end
	for index,value in pairs(RaidAlerter_RAIDICON) do
		if icontext == value then
			return "|T".."Interface\\TargetingFrame\\UI-RaidTargetingIcon_"..index..":"..size.."|t"
		end
	end
	return icontext;
end
]]

--下面提供可用于宏的增强讯息函数
function RAL.MSG(msg,Repeattime,mychan,latencytime,PREF)
	if not msg then
		--游戏里键入/run RAL.MSG()可查看到帮助
		RaidAlerter.AddMsg(RAL_TEXT_MARCO_1.."|cFF5588FF"..RAL_TEXT_MARCO_3);
		RaidAlerter.AddMsg(RAL_TEXT_MARCO_2.."|cFF5588FF"..RAL_TEXT_MARCO_4);
		return;
	end
	if not Repeattime then Repeattime=1 end
	Repeattime = floor(Repeattime);
	if not mychan then mychan="SAY" end
	if not latencytime then latencytime=3 end

	mychan = string.upper(mychan);
	if not(mychan=="SAY" or mychan=="YELL" or mychan=="PARTY" or mychan=="RAID" or mychan=="RAID_WARNING") then
		if mychan == "S" then
			mychan = "SAY";
		elseif mychan == "Y" then
			mychan = "YELL";
		elseif mychan == "P" then
			mychan = "PARTY";
		elseif mychan == "RA" then
			mychan = "RAID";
		elseif mychan == "RW" then
			mychan = "RAID_WARNING";
		else
			mychan = "SAY";
		end
	end

	if not PREF then
		PREF = "MyMSG";
		if UnitName("target") then
			PREF = PREF..UnitName("target");
		else
			PREF = PREF..UnitName("player");
		end
	end
	if RaidAlerter_GetTimer(PREF)>latencytime then
		for i=1,Repeattime do
			SendChatMessage(msg,mychan);
		end
		RaidAlerter_StartTimer(PREF);
	end
end

function RAL.W(msg,Repeattime,name,latencytime,PREF)
	if not msg then
		--游戏里键入/run RAL.W()可查看到帮助
		RaidAlerter.AddMsg(RAL_TEXT_MARCO_1.."|cFF5588FF"..RAL_TEXT_MARCO_5);
		RaidAlerter.AddMsg(RAL_TEXT_MARCO_2.."|cFF5588FF"..RAL_TEXT_MARCO_6);
		return;
	end
	if not Repeattime then Repeattime=1 end
	Repeattime = floor(Repeattime);
	if not name then
		if UnitName("target") then
			name=UnitName("target");
		else
			name=UnitName("player");
		end
	end
	if not latencytime then latencytime=3 end
	if not PREF then
		PREF = "MyW";
		if UnitName("target") then
			PREF = PREF..UnitName("target");
		else
			PREF = PREF..UnitName("player");
		end
	end
	if RaidAlerter_GetTimer(PREF)>latencytime then
		for i=1,Repeattime do
			SendChatMessage(msg, "WHISPER", nil, name);
		end
		RaidAlerter_StartTimer(PREF);
	end
end

function RAL.GI(unit)
	if not unit then
		if UnitName("target") then
			unit="target";
		else
			return "";
		end
	end
	if GetRaidTargetIndex(unit) then
		return RaidAlerter_RAIDICON[GetRaidTargetIndex(unit)];
	else
		return "";
	end
end

function RAL.GG(unit)
	if not unit then
		if UnitName("target") then
			unit="target";
		else
			return "";
		end
	end
	for i=1, GetNumRaidMembers() do
		local name, _, subgroup = GetRaidRosterInfo(i);
		if (name == UnitName(unit)) then
			return subgroup;
		end
	end
	return "";
end
