All pastes #56811 Raw Edit

Mine

public lua v1 · immutable
#56811 ·published 2006-05-18 07:44 UTC
rendered paste body
--[[Titan [CritLine]CritLine Concept by SorditTitan Conversion until version 0.3.7 by UgghContinued Development from 0.3.7 by FALLIVERSION HISTORY:Titan [CritLine] v0.4.0b-fix some database issuesTitan [CritLine] v0.4.0a-fix an issue that sometimes the database creation was not completeTitan [CritLine] v0.4.0-add an option to use the Titan Button with SHIFT key-add a special mob filter (thanks to gogusrl) that filter out these mobs in existing records and future can turned on or off in the options dialog, if you do this, the old values were saved into the database-add a new saved value (missed attacks), for future useTitan [CritLine] v0.3.9b-fix the bug that the critical splash message not showed correctly-fix the issue the heals with the addon selfcast (or similar) not be counted Titan [CritLine] v0.3.9a-add the help text for the options-add some french translation, thanks to Feu-fix a bug with the button, that highest filtered attacks shown on the button-add a new message for criticals for the splash screenTitan [CritLine] v0.3.9-add an option to show all hits in the tooltip (only absolute hits, no misses)-add a post records to channel function-add to options panel when you click on the CL button should it be open the settings or post the data in the channel-change the level adjustment setting to a slider, the default trivial setting in pvp by blizz is 10 level difference-add a function for help text for each option, but I need translators for french (important)-resize dynamically the filter options windowTitan [CritLine] v0.3.8-add a filter option for the tooltip-fix a few minor bugsTitan [CritLine] v0.3.7d-fix a bug with french translation-made it compatible to game version 1.8.0Titan [CritLine] v0.3.7c-changed the combat log messages and add the new ones, for game version 1.7.0, add the new msgs to the code-add crit percentage to tooltip, add checkbox for this to options frame-override the original germann translation mistake for normal magic hits-override the french translation with brackets '()' thanks to FranaelTitan [CritLine] v0.3.7-Fixed an bug with DE and FR clients.Titan [CritLine] v0.3.6-Fixed an bug with DE client.Titan [CritLine] v0.3.5-Fixed an bug with DE clients crits not working.-Fixed a bug with french text on the settings menu.Titan [CritLine] v0.3.4-Fixed an error with the French clients recording one hit as a Crit and Normal hit.-Settings menu translated to French and German.-Changed default for Level Adjustment to be off.Titan [CritLine] v0.3.3-Attempts to repair saved data information.-Fixed an issue with French clients not recording hits.Titan [CritLine] v0.3.2-Fixed an issue with German clients not recording hits.-Added Right-Click menu to toggle Icon/Text.-Added better error handling and error recovery.Titan [CritLine] v0.3.1-Added command to rebuild data structure.-Change archive format to .zip.Titan [CritLine] v0.3-Added level range filter.-Added attack type to splash screen message (e.g. 'New Ambush Record!')-Cleaned up summary tooltip.-Added healing spells.Titan [CritLine] v0.2-Added settings menu-Added Detailed summary for high damage attacks (ToolTip)-Toggle for ScreenShot on new damage records.-Toggle for counting PvP damage only.-Toggle for sound-Toggle Splash ScreenTitan [CritLine] v0.1-Initial Release]]DEBUG = false; -- for internal testing only, left it to false !--[[ global addon variables ]]TITAN_CRITLINE_ID =  "CritLine";TITAN_CRITLINE_VERSION = " v0.4.0b";TITAN_CRITLINE_BUTTON_LABEL = "CL: ";TITAN_CRITLINE_BUTTON_ICON = "Interface\\AddOns\\TitanCritLine\\TitanCritLine";TITAN_CRITLINE_BUTTON_TEXT = "%s/%s";HEADER_TEXT_COLOR  = "|cffffffff";SUBHEADER_TEXT_COLOR  = "|cffCEA208";BODY_TEXT_COLOR  = "|cffffffff";HINT_TEXT_COLOR  = "|cff00ff00";TCL_REALM = "";TitanCritLine_PlayerRealmName = ""; -- only stored for compability reasonsTCL_MOBFILTER = {};DAMAGE_TYPE_NONHEAL = "0";DAMAGE_TYPE_HEAL =  "1";--[[ functions for the setup dialog ]]function tcl_DisplaySettings()	TitanCritLine_SettingsFrame_HeaderText:SetText(TITAN_CRITLINE_ID.." "..TITAN_CRITLINE_MENU_SETTINGS);	TitanCritLine_SettingsFrame_Option1Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_SPLASH_TEXT));	TitanCritLine_SettingsFrame_Option1.HelpText = TITAN_CRITLINE_OPTION_SPLASH_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] == "1" ) then		TitanCritLine_SettingsFrame_Option1:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option2Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_PLAYSOUNDS_TEXT));	TitanCritLine_SettingsFrame_Option2.HelpText = TITAN_CRITLINE_OPTION_PLAYSOUNDS_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] == "1" ) then		TitanCritLine_SettingsFrame_Option2:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option3Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_PVPONLY_TEXT));	TitanCritLine_SettingsFrame_Option3.HelpText = TITAN_CRITLINE_OPTION_PVPONLY_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] == "1" ) then		TitanCritLine_SettingsFrame_Option3:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option4Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_SCREENCAP_TEXT));	TitanCritLine_SettingsFrame_Option4.HelpText = TITAN_CRITLINE_OPTION_SCREENCAP_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] == "1" ) then		TitanCritLine_SettingsFrame_Option4:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option7Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_SHOW_CRIT_TEXT));	TitanCritLine_SettingsFrame_Option7.HelpText = TITAN_CRITLINE_OPTION_SHOW_CRIT_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] == "1" ) then		TitanCritLine_SettingsFrame_Option7:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option8Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_SHOWHITS_TEXT));	TitanCritLine_SettingsFrame_Option8.HelpText = TITAN_CRITLINE_OPTION_SHOWHITS_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] == "1" ) then		TitanCritLine_SettingsFrame_Option8:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option5Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_ONCLICK_TEXT));	TitanCritLine_SettingsFrame_Option5.HelpText = TITAN_CRITLINE_OPTION_ONCLICK_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == "1" ) then		TitanCritLine_SettingsFrame_Option5:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option9Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_SHIFT_ONCLICK_TEXT));	TitanCritLine_SettingsFrame_Option9.HelpText = TITAN_CRITLINE_OPTION_SHIFT_ONCLICK_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] == "1" ) then		TitanCritLine_SettingsFrame_Option9:SetChecked(true);	end	TitanCritLine_SettingsFrame_Option6Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_FILTER_HEALING_TEXT));	TitanCritLine_SettingsFrame_Option6.HelpText = TITAN_CRITLINE_OPTION_FILTER_HEALING_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == "1" ) then		TitanCritLine_SettingsFrame_Option6:SetChecked(true);	end	TitanCritLine_SettingsFrame_Slider1:SetValue(tonumber(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"]));	TitanCritLine_SettingsFrame_Slider1Text1:SetText(TITAN_CRITLINE_OPTION_LVLADJ_TEXT);	TitanCritLine_SettingsFrame_Slider1.HelpText = TITAN_CRITLINE_OPTION_LVLADJ_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"] == "0" ) then		TitanCritLine_SettingsFrame_Slider1Text2:SetText("Off");	else		TitanCritLine_SettingsFrame_Slider1Text2:SetText(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"]);	end	TitanCritLine_SettingsFrame_Option10Text:SetText(COLOR(SUBHEADER_TEXT_COLOR, TITAN_CRITLINE_OPTION_MOBFILTER_TEXT));	TitanCritLine_SettingsFrame_Option10.HelpText = TITAN_CRITLINE_OPTION_MOBFILTER_HELPTEXT;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] == "1" ) then		TitanCritLine_SettingsFrame_Option10:SetChecked(true);	end	TitanCritLine_SettingsFrame_Slider1:Show();	TitanCritLine_SettingsFrame:Show();endfunction tcl_SettingsOptionButton_OnClick(arg1)	if ( arg1 == 1 ) then		tcl_ToggleSplash();	elseif ( arg1 == 2 ) then		tcl_ToggleSound();	elseif ( arg1 == 3 ) then		tcl_TogglePvP();	elseif ( arg1 == 4 ) then		tcl_ToggleScreenShots();	elseif ( arg1 == 5 ) then		tcl_ToggleOnClick();	elseif ( arg1 == 6 ) then		tcl_ToggleHealing();	elseif ( arg1 == 7 ) then		tcl_ToggleShowCrit();	elseif ( arg1 == 8 ) then		tcl_ToggleShowHits();	elseif ( arg1 == 9 ) then		tcl_ToggleShiftOnClick();	elseif ( arg1 == 10 ) then		tcl_ToggleMobFilter();	end	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_SettingsOptionButton_OnEnter(button)	GameTooltip:SetOwner(button, "ANCHOR_NONE");	GameTooltip:SetPoint("TOPLEFT", button:GetName(), "BOTTOMLEFT", -10, -4);	GameTooltip:SetText(button.HelpText);	GameTooltip:Show();endfunction tcl_SettingsOptionButton_OnLeave()	GameTooltip:Hide();endfunction tcl_SettingsSlider_OnValueChanged()	local lvladj = TitanCritLine_SettingsFrame_Slider1:GetValue();	if ( lvladj == 0 ) then		TitanCritLine_SettingsFrame_Slider1Text2:SetText("Off");	else		TitanCritLine_SettingsFrame_Slider1Text2:SetText(tostring(lvladj));	end	TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"] = tostring(lvladj);	tcl_DEBUG(TITAN_CRITLINE_ID.." level adjustment set to "..tostring(lvladj));endfunction tcl_ToggleShowHits()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." show all hits is on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." show all hits is off");	endendfunction tcl_ToggleOnClick()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] = "1";		TitanCritLine_SettingsFrame_Option9:Enable();		tcl_DEBUG(TITAN_CRITLINE_ID.." post to chat on click is on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] = "0";		TitanCritLine_SettingsFrame_Option9:Disable();		tcl_DEBUG(TITAN_CRITLINE_ID.." post to chat on click is off");	endendfunction tcl_ToggleShiftOnClick()	if ( TitanCritLine_SettingsFrame_Option9:IsEnabled() ) then		if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] == "0" ) then			TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] = "1";			tcl_DEBUG(TITAN_CRITLINE_ID.." post to chat on SHIFT click is on");		else			TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] = "0";			tcl_DEBUG(TITAN_CRITLINE_ID.." post to chat on SHIFT click is off");		end	endendfunction tcl_ToggleScreenShots()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." screen shots on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." screen shots off");	endendfunction tcl_ToggleSound()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." sound on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." sound off");	endendfunction tcl_TogglePvP()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." pvponly on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." pvponly off");	endendfunction tcl_ToggleSplash()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." splash on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] = "0";		info.checked = 0;		tcl_DEBUG(TITAN_CRITLINE_ID.." splash off");	endendfunction tcl_ToggleHealing()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." filter healing on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." filter healing off");	endendfunction tcl_ToggleShowCrit()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." show crit percentage on");	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." show crit percentage off");	endendfunction tcl_ToggleMobFilter()	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] == "0" ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] = "1";		tcl_DEBUG(TITAN_CRITLINE_ID.." filter mobs on");		tcl_DeleteAllRecordsWithMobsInFilter();	else		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] = "0";		tcl_DEBUG(TITAN_CRITLINE_ID.." filter mobs off");		tcl_RestoreAllRecordsWithMobsInFilter();	endendfunction tcl_Reset()	TCL_SETTINGS[TCL_REALM]["DATA"] = {};	TitanPanelCritLineButtonText:SetText(TitanPanelCritLine_GetButtonText(0));endfunction tcl_ResetAll()	TCL_SETTINGS = {};	tcl_Initialize();	TitanPanelCritLineButtonText:SetText(TitanPanelCritLine_GetButtonText(0));endfunction tcl_SettingsClose()	if ( TitanCritLine_FilterFrame:IsVisible() ) then		tcl_FilterClose();	end	TitanCritLine_SettingsFrame:Hide();	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_Filter()	if ( TitanCritLine_FilterFrame:IsVisible() ) then		tcl_FilterClose();	else		local i = 1;		for k,v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"]) do			tcl_DEBUG("create button no."..tostring(i).." for "..k);			local button = getglobal("TitanCritLine_FilterFrame_Option"..tostring(i));			local text = getglobal("TitanCritLine_FilterFrame_Option"..tostring(i).."Text");			text:Show();			text:SetText(k);			button:Show();			if (TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "1") then				button:SetChecked(true);			end			i = i + 1;			if ( i > 20 ) then				do break end			end		end		local height = i * 24 + 20;		TitanCritLine_FilterFrame:SetHeight(height);		TitanCritLine_FilterFrame:SetPoint("LEFT", "TitanCritLine_SettingsFrame", "RIGHT", 5, 0);		TitanCritLine_FilterFrame:Show();	endendfunction tcl_FilterOptionButton_OnClick(id)	local button = getglobal("TitanCritLine_FilterFrame_Option"..tostring(id));	local attacktype = getglobal("TitanCritLine_FilterFrame_Option"..tostring(id).."Text"):GetText();	if ( button:GetChecked() ) then		tcl_DEBUG(attacktype.." filter is on");		TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Filter"] = "1";	else		tcl_DEBUG(attacktype.." filter is off");		TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Filter"] = "0";	end	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_FilterClose()	TitanCritLine_FilterFrame:Hide();	for i = 1, 20, 1 do		local button = getglobal("TitanCritLine_FilterFrame_Option"..tostring(i));		local text = getglobal("TitanCritLine_FilterFrame_Option"..tostring(i).."Text");		button:SetChecked(false);		button:Hide();		text:SetText(nil);		text:Hide();	end	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_ManualUpdate()	tcl_Update(TCL_SETTINGS["VERSION"]);end--[[ titan panel functions ]]function TitanPanelRightClickMenu_PrepareCritLineMenu()	local id = TITAN_CRITLINE_ID;	TitanPanelRightClickMenu_AddTitle(TitanPlugins[id].menuText..TITAN_CRITLINE_VERSION);	local info = {};	info.text = TITAN_CRITLINE_MENU_SETTINGS;	info.func = tcl_DisplaySettings;	UIDropDownMenu_AddButton(info);	TitanPanelRightClickMenu_AddSpacer();	local info2 = {};	info2.text = TITAN_CRITLINE_MENU_POSTGUILD;	info2.func = tcl_PostToGuild;	local info3 = {};	info3.text = TITAN_CRITLINE_MENU_POSTPARTY;	info3.func = tcl_PostToParty;	local info4 = {};	info4.text = TITAN_CRITLINE_MENU_POSTRAID;	info4.func = tcl_PostToRaid;	UIDropDownMenu_AddButton(info2);	UIDropDownMenu_AddButton(info3);	UIDropDownMenu_AddButton(info4);	TitanPanelRightClickMenu_AddSpacer();	TitanPanelRightClickMenu_AddToggleIcon(id);	TitanPanelRightClickMenu_AddToggleLabelText(id);	TitanPanelRightClickMenu_AddSpacer();	TitanPanelRightClickMenu_AddCommand(TITAN_PANEL_MENU_HIDE, id, TITAN_PANEL_MENU_FUNC_HIDE);endfunction TitanPanelCritLine_GetButtonText(id)	local buttonRichText = format(TITAN_CRITLINE_BUTTON_TEXT, COLOR(BODY_TEXT_COLOR, tcl_GetHighestDamage()), COLOR(BODY_TEXT_COLOR, tcl_GetHighestCrit()));	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == "0") then		buttonRichText = buttonRichText.." - "..format(TITAN_CRITLINE_BUTTON_TEXT, COLOR(BODY_TEXT_COLOR, tcl_GetHighestHeal()), COLOR(BODY_TEXT_COLOR, tcl_GetHighestHealCrit()));	end	tcl_DEBUG("TitanPanelCritLine_GetButtonText: "..TITAN_CRITLINE_BUTTON_LABEL..buttonRichText);	return TITAN_CRITLINE_BUTTON_LABEL, buttonRichText;end--[[ addon functions ]]function tcl_OnLoad()	this.registry = { 		id = TITAN_CRITLINE_ID,		menuText = TITAN_CRITLINE_ID, 		buttonTextFunction = "TitanPanelCritLine_GetButtonText", 		tooltipTitle = TITAN_CRITLINE_ID.." "..TITAN_CRITLINE_TOOLTIP_HEADER.." "..TITAN_CRITLINE_VERSION,		tooltipTextFunction = "tcl_GetSummaryRichText", 		icon = TITAN_CRITLINE_BUTTON_ICON,		iconWidth = 16,		savedVariables = {			ShowIcon = 1,			ShowLabelText = 1,		}	};	this:RegisterEvent("PLAYER_ENTERING_WORLD");	this:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS");	this:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE");	this:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF");	this:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES");	tcl_Msg(TITAN_CRITLINE_ID.." "..TITAN_CRITLINE_VERSION.." loaded.");endfunction tcl_OnUpdate(elapsed)	endfunction tcl_OnEvent()	tcl_DEBUG("Received Event: "..event);	if (event == "PLAYER_ENTERING_WORLD") then		if (TCL_SETTINGS == nil) then			TCL_SETTINGS = {};		end		if (TCL_SETTINGS["VERSION"] == nil) then			tcl_Update("UNKNOWN");		elseif (TCL_SETTINGS["VERSION"] ~= TITAN_CRITLINE_VERSION) then			tcl_Update(TCL_SETTINGS["VERSION"]);		else			tcl_Initialize();		end		tcl_CreateMobFilter();		TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);		TitanPanelButton_UpdateTooltip();	elseif (event == "CHAT_MSG_SPELL_SELF_BUFF") then		if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == "0") then			for attacktype, creaturename, damage in string.gfind(arg1, HEAL_SPELL_CRIT_MSG) do				tcl_RecordHit(attacktype, "CRIT", tonumber(damage), creaturename, DAMAGE_TYPE_HEAL);				return;			end			for attacktype, creaturename, damage in string.gfind(arg1, HEAL_SPELL_HIT_MSG) do				tcl_RecordHit(attacktype, "NORMAL", tonumber(damage), creaturename, DAMAGE_TYPE_HEAL);				return;			end		end	elseif (event == "CHAT_MSG_COMBAT_SELF_HITS") then		for creaturename, damage in string.gfind(arg1, COMBAT_CRIT_MSG)do			tcl_DEBUG("Crit Hit: "..creaturename.." for "..damage);			tcl_RecordHit(NORMAL_HIT_TEXT, "CRIT", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for creaturename, damage, damagetype in string.gfind(arg1, COMBAT_CRIT_SCHOOL_MSG)do			tcl_DEBUG("Crit School Hit: "..creaturename.." for "..damagetype.." "..damage);			tcl_RecordHit(NORMAL_HIT_TEXT, "CRIT", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for creaturename, damage in string.gfind(arg1, COMBAT_HIT_MSG) do			tcl_DEBUG("Regular Hit: "..creaturename.." for "..damage);			tcl_RecordHit(NORMAL_HIT_TEXT, "NORMAL", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for creaturename, damage, damagetype in string.gfind(arg1, COMBAT_HIT_SCHOOL_MSG) do			tcl_DEBUG("Regular School Hit: "..creaturename.." for "..damagetype.." "..damage);			tcl_RecordHit(NORMAL_HIT_TEXT, "NORMAL", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end	elseif (event == "CHAT_MSG_SPELL_SELF_DAMAGE") then		for attacktype, creaturename, damage in string.gfind(arg1, SPELL_CRIT_MSG) do			tcl_DEBUG(attacktype.." Crit: "..creaturename.." for "..damage);			tcl_RecordHit(attacktype, "CRIT", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for attacktype, creaturename, damage, damagetype in string.gfind(arg1, SPELL_CRIT_SCHOOL_MSG) do			tcl_DEBUG(attacktype.." School Crit: "..creaturename.." for "..damagetype.." "..damage);			tcl_RecordHit(attacktype, "CRIT", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for attacktype, creaturename, damage in string.gfind(arg1, SPELL_HIT_MSG) do			tcl_DEBUG(attacktype.." Hit: "..creaturename.." for "..damage);			tcl_RecordHit(attacktype, "NORMAL", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		for attacktype, creaturename, damage, damagetype in string.gfind(arg1, SPELL_HIT_SCHOOL_MSG) do			tcl_DEBUG(attacktype.." School Hit: "..creaturename.." for "..damagetype.." "..damage);			tcl_RecordHit(attacktype, "NORMAL", tonumber(damage), creaturename, DAMAGE_TYPE_NONHEAL);			return;		end		tcl_RecordMiss(arg1);	elseif ( event == "CHAT_MSG_COMBAT_SELF_MISSES") then		tcl_RecordMiss(arg1);	endendfunction tcl_OnClick(button)	if (button == "LeftButton") then		if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] == "1" ) then			if ( IsShiftKeyDown() ) then				if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == "0" ) then					tcl_DisplaySettings();				else					tcl_PostMessage();				end			else				return;			end		else			if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == "0" ) then				tcl_DisplaySettings();			else				tcl_PostMessage();			end		end	endendfunction tcl_Update(version)	tcl_Msg("Updating "..TITAN_CRITLINE_ID.." from version "..version.." to version "..TITAN_CRITLINE_VERSION.." ...");	-- set global variables	TCL_REALM = GetCVar("realmName");	tcl_Initialize();	TCL_SETTINGS["VERSION"] = TITAN_CRITLINE_VERSION;	-- check for old titan critline data	if (TitanCritLineSettings == nil) then		tcl_Msg("No old Titan Critline database found, creating new database for "..UnitName("player")..".");	else		TitanCritLine_PlayerRealmName = GetCVar("realmName").."."..UnitName("player");		if (TitanCritLineSettings[TitanCritLine_PlayerRealmName] == nil) then			tcl_Msg("Old Titan CritLine database found, but not for "..UnitName("player")..", creating new one.");		else			if ( table.getn(TCL_SETTINGS[TCL_REALM]["DATA"]) == nil or table.getn(TCL_SETTINGS[TCL_REALM]["DATA"]) == 0 ) then				tcl_Msg("Updating old Titan CritLine data ...");				for k,v in pairs(TitanCritLineSettings[TitanCritLine_PlayerRealmName]["SETTINGS"]) do					TCL_SETTINGS[TCL_REALM]["SETTINGS"][k] = v;				end				for k,v in pairs(TitanCritLineSettings[TitanCritLine_PlayerRealmName]["DATA"]) do					attacktype = k;					TCL_SETTINGS[TCL_REALM]["DATA"][attacktype] = {};					TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Filter"] = "0";					for k,v in pairs(TitanCritLineSettings[TitanCritLine_PlayerRealmName]["DATA"][attacktype]) do						hittype = k;						TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype] = {};						for k,v in pairs(TitanCritLineSettings[TitanCritLine_PlayerRealmName]["DATA"][attacktype][hittype]) do							TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype][k] = v;						end						if (TitanCritLineSettings[TitanCritLine_PlayerRealmName]["DATA"][attacktype][hittype]["Value"] == nil) then							TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype]["Value"] = 0;						end					end				end				TitanCritLineSettings[TitanCritLine_PlayerRealmName] = nil;			else				tcl_Msg("New data was found, no update needed ...");			end		end	end	--add changes to database	tcl_Msg("Updating main database ...");	for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"] == nil ) then			TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"] = 0;		end	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] = "0";	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] = "1";	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] = "0";	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] = "0";	end	-- update complete	tcl_Msg("Update complete, read the UPDATE.TXT file in the addon directory!");endfunction tcl_Initialize()	tcl_DEBUG("Initializing...");	TCL_REALM = GetCVar("realmName");	if (TCL_SETTINGS == nil) then		TCL_SETTINGS = {};	end	if (TCL_SETTINGS["VERSION"] == nil) then		TCL_SETTINGS["VERSION"] = TITAN_CRITLINE_VERSION;	end	if (TCL_SETTINGS[TCL_REALM] == nil) then		TCL_SETTINGS[TCL_REALM] = {};	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"] = {};	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] = "1";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"] = "0";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] = "1";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] = "0";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] = "1";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] = "0";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] = "1";	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] = "1";	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["ONCLICK"] = "1"	end	if (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] == nil) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHIFTONCLICK"] = "1";	end	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] == nil ) then		TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] = "1";	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then		TCL_SETTINGS[TCL_REALM]["DATA"] = {};	end	tcl_DEBUG("Initialization Complete.");endfunction tcl_CreateMobFilter()	tcl_DEBUG("Creating Mob Filter...");	table.insert(TCL_MOBFILTER, TITAN_CRITLINE_MOBFILTER_01);	table.insert(TCL_MOBFILTER, TITAN_CRITLINE_MOBFILTER_02);	table.insert(TCL_MOBFILTER, TITAN_CRITLINE_MOBFILTER_03);	tcl_DEBUG("Creation complete.");endfunction tcl_IsMobInFilter(mobname)	local returnvalue = false;	for k, v in pairs(TCL_MOBFILTER) do		if ( v == mobname ) then			tcl_DEBUG("Name of Mob ("..mobname..") is in Filter ...");			returnvalue = true;			do break end;		end	end	tcl_DEBUG("Name of Mob ("..mobname..") is NOT in Filter ...");	return returnvalue;endfunction tcl_DeleteAllRecordsWithMobsInFilter()	tcl_DEBUG("Search for filtered mobs and delte them ...");	for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"]) do		attacktype = k;		for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]) do			if ( k == "CRIT" or k == "NORMAL" ) then				local hittype = k;				if ( tcl_IsMobInFilter(TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype]["Target"]) ) then					tcl_DEBUG("Mob found, backup stats ...");					local filtered = "FILTER_"..hittype;					local backup = "OLD_"..hittype;					TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][filtered] = {};					TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][filtered] = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype];					if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][backup] == nil ) then						table.remove(TCL_SETTINGS[TCL_REALM]["DATA"][attacktype], hittype);					else						TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype] = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][backup];					end				end			end		end	end	tcl_DEBUG("All filtered mobs deleted if found.");	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_RestoreAllRecordsWithMobsInFilter()	tcl_DEBUG("Restore all records with filtered mobs ...");	for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"]) do		attacktype = k;		for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]) do			if ( k == "CRIT" or k == "NORMAL" ) then				local hittype = k;				if ( tcl_IsMobInFilter(TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype]["Target"]) ) then					tcl_DEBUG("Mob found, restoring stats ...");					local filtered = "FILTER_"..hittype;					local backup = "OLD_"..hittype;					if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][filtered] ~= nil ) then						if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][backup] == nil ) then							TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][backup] = {};							TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][backup] = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype];						end						TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][hittype] = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][filtered];					end				end			end		end	end	tcl_DEBUG("All records with filtered mobs are restored.");	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_RecordHit(AttackType, HitType, Damage, uname, IsHealing)	local targetlvl = UnitLevel("target");	local ulevel = false;	if (targetlvl == nil) then 		targetlvl = 0;	end	if (Damage == nil) then		tcl_DEBUG("No Damage! exiting...");		return;	end	if (uname == nil) then 		uname = "??"; 	end	if (not UnitExists("target")) then		if (IsHealing == DAMAGE_TYPE_HEAL) then			uname = UnitName("player");			ulevel = UnitLevel("player");		else			tcl_DEBUG("No Target! exiting...");			return;		end	end	if (IsHealing == nil) then		tcl_DEBUG("IsHealing==nil! exiting...");		return;	end	if ( (UnitIsPlayer("target") ~= 1) and (TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PVPONLY"] == "1") ) then		tcl_DEBUG("Target !=player and PvPOnly enabled, exiting...");		return;	end	local leveldiff = 0;	if (UnitLevel("player") < UnitLevel("target")) then		leveldiff = (UnitLevel("target") - UnitLevel("player"));	else		leveldiff = (UnitLevel("player") - UnitLevel("target"));	end	tcl_DEBUG("Level difference: "..leveldiff);	if ( (tonumber(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"]) ~= 0) and (tonumber(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["LVLADJ"]) < leveldiff) ) then		tcl_DEBUG("Target level too low and LvlAdj enabled, exiting...");		return;	end	if (TCL_SETTINGS == nil) then		return;	end	if (TCL_SETTINGS[TCL_REALM] == nil) then		tcl_DEBUG("TCL_SETTINGS[TCL_REALM] should not be nil at this point!");		tcl_Initialize();	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then		tcl_DEBUG("TCL_SETTINGS[TCL_REALM][DATA] should not be nil at this point!");		tcl_Initialize();	end	if (TCL_SETTINGS[TCL_REALM]["DATA"][AttackType] == nil) then		tcl_DEBUG("Creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..AttackType.."]...");		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType] = {};	end	if ( TCL_SETTINGS[TCL_REALM]["DATA"][AttackType]["Filter"] == nil ) then		tcl_DEBUG("Creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..AttackType.."][Filter]...");		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType]["Filter"] = "0";	end	if (TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType] == nil) then		tcl_DEBUG("Creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..AttackType.."]["..HitType.."]...");		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType] = {};	end	if ( TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Value"] == nil ) then		tcl_DEBUG("Creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..AttackType.."]["..HitType.."][Value]...");		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Value"] = 0;	end	local oldhitvalue = TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Value"];	TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Value"] = oldhitvalue + 1;	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_MOBS"] == "1" ) then		if ( tcl_IsMobInFilter(uname) ) then			return;		end	end	if ( TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Damage"] == nil or TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Damage"] < Damage ) then		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Damage"] = Damage;		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Target"] = uname;		if ( ulevel ) then			TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Level"] = ulevel;		else			TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Level"] = UnitLevel("target");		end		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["Date"] = date();		TCL_SETTINGS[TCL_REALM]["DATA"][AttackType][HitType]["IsHeal"] = IsHealing;		tcl_DisplayNewRecord(AttackType, Damage, HitType);	endendfunction tcl_RecordMiss(text)	if ( text == nil ) then		tcl_DEBUG("RecordMiss text value is nil, return.");		return;	end	if ( string.find(text, "(%d+)") ) then		tcl_DEBUG("RecordMiss found a number in text, return.");		return;	else		for k, v in pairs(TCL_SETTINGS[TCL_REALM]["DATA"]) do			attacktype = k;			if ( string.find(text, attacktype) ) then				tcl_DEBUG("RecordMiss found "..attacktype.." in text, add a miss and return.");				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"] == nil ) then					TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"] = 1;					do return end;				else					local oldvalue = TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"];					TCL_SETTINGS[TCL_REALM]["DATA"][k]["Misses"] = oldvalue + 1;					do return end;				end			end		end		tcl_DEBUG("RecordMiss found no attacktype in text.");		if ( TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT] == nil ) then			tcl_DEBUG("RecordMiss creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..NORMAL_HIT_TEXT.."].");			TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT] = {};		end		if ( TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT]["Misses"] == nil ) then			tcl_DEBUG("RecordMiss creating TCL_SETTINGS["..TCL_REALM.."][DATA]["..NORMAL_HIT_TEXT.."][Misses] = 1.");			TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT]["Misses"] = 1;			return;		else			tcl_DEBUG("RecordMiss add a miss to "..NORMAL_HIT_TEXT..".");			local oldvalue = TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT]["Misses"];			TCL_SETTINGS[TCL_REALM]["DATA"][NORMAL_HIT_TEXT]["Misses"] = oldvalue + 1;			return;		end	end	tcl_DEBUG("RecordMiss found nothing and return.");endfunction tcl_DisplayNewRecord(AttackType, DamageAmount, HitType)	local splash_msg = TITAN_CRITLINE_NEW_RECORD_MSG;	if ( HitType == "CRIT" ) then		splash_msg = TITAN_CRITLINE_NEW_CRIT_RECORD_MSG;	end	tcl_DEBUG(format(splash_msg, AttackType));	if(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SPLASH"] == "1") then		TitanCritLineSplashFrame:AddMessage(DamageAmount, 1, 1, 1, 1, 3);		TitanCritLineSplashFrame:AddMessage(format(splash_msg, AttackType), 1, 1, 0, 1, 3);	end	if(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["PLAYSOUND"] == "1") then 		PlaySound("LEVELUP", 1, 1, 0, 1, 3); 	end	if(TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SNAPSHOT"] == "1") then 		TakeScreenshot(); 	end	TitanPanelButton_UpdateButton(TITAN_CRITLINE_ID);endfunction tcl_GetHighestCrit()	local hidmg = 0;	local attack = "";	local enemy = "";	if (TCL_SETTINGS == nil) then 		return hidmg;	end	if (TCL_SETTINGS[TCL_REALM] == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then 		return hidmg; 	end	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "0" ) then			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["IsHeal"] == "0" ) then					if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Damage"] > hidmg ) then						hidmg = TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Damage"];						attack = k;						enemy = TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Target"].." ("..TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Level"]..")";					end				end			end		else			tcl_DEBUG(k.." Filter is on, did not recognized for highest CRIT.");		end	end	return hidmg, attack, enemy;endfunction tcl_GetHighestHealCrit()	local hidmg = 0;	local attack = "";	local enemy = "";	if (TCL_SETTINGS == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM] == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then 		return hidmg; 	end	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "0" ) then			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["IsHeal"] == "1" ) then					if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Damage"] > hidmg ) then						hidmg = TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Damage"];						attack = k;						enemy = TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Target"].." ("..TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Level"]..")";					end				end			end		else			tcl_DEBUG(k.." Filter is on, did not recognized for highest HEALCRIT");		end	end	return hidmg, attack, enemy;endfunction tcl_GetHighestDamage()	local hidmg = 0;	local attack = "";	local enemy = "";	if (TCL_SETTINGS == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM] == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then 		return hidmg; 	end	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "0" ) then			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["IsHeal"] == "0" ) then					if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Damage"] > hidmg ) then						hidmg = TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Damage"];						attack = k;						enemy = TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Target"].." ("..TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Level"]..")";					end				end			end		else			tcl_DEBUG(k.." Filter is on, did not recognized for highest HIT.")		end	end	return hidmg, attack, enemy;endfunction tcl_GetHighestHeal()	local hidmg = 0;	local attack = "";	local enemy = "";	if (TCL_SETTINGS == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM] == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then 		return hidmg; 	end	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "0" ) then			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["IsHeal"] == "1" ) then					if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Damage"] > hidmg ) then						hidmg = TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Damage"];						attack = k;						enemy = TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Target"].." ("..TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Level"]..")";					end				end			end		else			tcl_DEBUG(k.." Filter is on, did not recognized for highest HEAL.");		end	end	return hidmg, attack, enemy;endfunction tcl_GetHighestCritPercentage()	local critperc, crithits, normhits;	local hidmg = 0;	local attack = "";	if (TCL_SETTINGS == nil) then 		return hidmg;	end	if (TCL_SETTINGS[TCL_REALM] == nil) then 		return hidmg; 	end	if (TCL_SETTINGS[TCL_REALM]["DATA"] == nil) then 		return hidmg; 	end	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["Filter"] == "0" ) then			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["IsHeal"] == "0") then					crithits = TCL_SETTINGS[TCL_REALM]["DATA"][k]["CRIT"]["Value"];				end			end			if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"] ~= nil ) then				if ( TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["IsHeal"] == "0") then					normhits = TCL_SETTINGS[TCL_REALM]["DATA"][k]["NORMAL"]["Value"];				end			end			if ( crithits == 0 or crithits == nil or normhits == 0 or normhits == nil ) then				critperc = 0;			else				critperc = crithits / ( ( crithits + normhits ) / 100 );			end			tcl_DEBUG(k.." critical percentage: "..critperc);			if ( critperc > hidmg ) then				hidmg = critperc;				attack = k;			end		else			tcl_DEBUG(k.." Filter is on, did not recognized for highest CRIT percentage");		end	end	return format("%.2f", hidmg), attack;end--[[ tooltip functions ]]function tcl_DisplayDialog(message)	GameTooltip:SetText(message);	GameTooltip:Show();endfunction tcl_DisplaySummary()	tcl_DisplayDialog(tcl_GetSummaryRichText());endfunction tcl_DisplayAbout()	tcl_DisplayDialog(tcl_GetAboutRichText());endfunction tcl_GetSummaryRichText()	local hicrit = tcl_GetHighestCrit();	local hicritperc = tcl_GetHighestCritPercentage();	local hidmg = tcl_GetHighestDamage();	local hihealcrit = tcl_GetHighestHealCrit();	local hihealdmg = tcl_GetHighestHeal();	local rtfAttack="";	for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"]) do		attacktype = k;		if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Filter"] == "0" ) then			local crithits, normhits, critperc, normperc;			if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["CRIT"] == nil) then				crithits = 0;			else				if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["CRIT"]["Value"] == nil) then					crithits = 0;				else					crithits = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["CRIT"]["Value"];				end			end			if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["NORMAL"] == nil) then				normhits = 0;			else				if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["NORMAL"]["Value"] == nil) then					normhits = 0;				else					normhits = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["NORMAL"]["Value"];				end			end			local allhits = normhits + crithits;			if ( crithits == 0 ) then				critperc = 0;			else				critperc = format("%.2f", crithits / ( allhits / 100 ) );			end			if ( normhits == 0 ) then				normperc = 0;			else				normperc = format("%.2f", normhits / ( allhits / 100 ) );			end			local allmisses;			if ( TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Misses"] == nil) then				allmisses = 0;			else				allmisses = TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]["Misses"];			end			local allswings = allmisses + allhits;			local hitperc = format("%.2f", allhits / ( allswings / 100 ) );			if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWHITS"] == "1" ) then				rtfAttack = rtfAttack..COLOR(HEADER_TEXT_COLOR, attacktype).."\t "..COLOR(HEADER_TEXT_COLOR, allhits).." "..HIT_TEXT.." ("..COLOR(HEADER_TEXT_COLOR, hitperc.." %")..")\n";			else				rtfAttack = rtfAttack..COLOR(HEADER_TEXT_COLOR, attacktype).."\n";			end			for k,v in pairs (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype]) do				if (k == "NORMAL") then					rtfAttack = rtfAttack.."  "..COLOR(SUBHEADER_TEXT_COLOR, NORMAL_TEXT).." [";				elseif ( k == "CRIT" ) then					rtfAttack = rtfAttack.."  "..COLOR(SUBHEADER_TEXT_COLOR, CRIT_TEXT).." [";				end				if ( k == "CRIT") then					if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["IsHeal"] == "0") then						if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"] == hicrit) then							rtfAttack = rtfAttack..COLOR(HINT_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						else							rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						end					else						if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"] == hihealcrit) then							rtfAttack = rtfAttack..COLOR(HINT_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						else							rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						end					end					if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] == "1" ) then						if ( critperc == hicritperc ) then							rtfAttack = rtfAttack.." ["..COLOR(HINT_TEXT_COLOR, critperc.."%").."]\t";						else							rtfAttack = rtfAttack.." ["..COLOR(BODY_TEXT_COLOR, critperc.."%").."]\t";						end					else						rtfAttack = rtfAttack.."\t";					end				elseif ( k == "NORMAL" ) then					tcl_DEBUG(TCL_REALM..", "..attacktype..", "..k);					if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["IsHeal"] == "0") then						if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"] == hidmg) then							rtfAttack = rtfAttack..COLOR(HINT_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						else							rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						end					else						if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"] == hihealdmg) then							rtfAttack = rtfAttack..COLOR(HINT_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						else							rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Damage"]).."]";						end					end					if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["SHOWCRIT"] == "1" ) then						rtfAttack = rtfAttack.." ["..COLOR(BODY_TEXT_COLOR, normperc.."%").."]\t";					else						rtfAttack = rtfAttack.."\t";					end				end				if ( k == "NORMAL" ) then					if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Level"] == -1) then						rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Target"]).." ["..COLOR(BODY_TEXT_COLOR, "??").."]\n";					else						rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Target"]).." ["..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Level"]).."]\n";					end				elseif ( k == "CRIT" ) then					if (TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Level"] == -1) then						rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Target"]).." ["..COLOR(BODY_TEXT_COLOR, "??").."]\n";					else						rtfAttack = rtfAttack..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Target"]).." ["..COLOR(BODY_TEXT_COLOR, TCL_SETTINGS[TCL_REALM]["DATA"][attacktype][k]["Level"]).."]\n";					end				end			end		end	end	return rtfAttackendfunction tcl_GetAboutRichText()	return 		COLOR(HEADER_TEXT_COLOR, TITAN_CRITLINE_ID.." v"..TITAN_CRITLINE_VERSION).."\n"..		COLOR(SUBHEADER_TEXT_COLOR, "Developers: ").."\n"..		COLOR(BODY_TEXT_COLOR, "Sordit: ".."\t".."Concept and Stand-Alone version").."\n"..		COLOR(BODY_TEXT_COLOR, "Uggh: ".."\t".."Titan Panel version < 0.3.7").."\n\n"..		COLOR(BODY_TEXT_COLOR, "Falli: ".."\t".."Titan Panel version > 0.3.7");end--[[ chat functions ]]function tcl_PostMessage(message_array,channel)	if ( message_array == nil or type(message_array) ~= "table") then		message_array = tcl_GetRecordChatText();	end	if ( channel == nil ) then		channel = "GUILD";		if ( GetNumPartyMembers() > 0 ) then			channel = "PARTY";		end		if ( GetNumRaidMembers() > 0 ) then			channel = "RAID";		end	end	table.foreach(message_array, function(k,v) SendChatMessage(v, channel); end);endfunction tcl_PostToRaid()	if ( GetNumRaidMembers ~= 0 ) then		tcl_PostMessage(tcl_GetRecordChatText(),"RAID")	else		tcl_PostMessage(tcl_GetRecordChatText())	endendfunction tcl_PostToParty()	if ( GetNumPartyMembers ~= 0 ) then		tcl_PostMessage(tcl_GetRecordChatText(),"PARTY")	else		tcl_PostMessage(tcl_GetRecordChatText())	endendfunction tcl_PostToGuild()	local guildName, guildRankName, guildRankIndex = GetGuildInfo("player");	if ( guildName ) then		tcl_PostMessage(tcl_GetRecordChatText(),"GUILD")	else		local message_array = tcl_GetRecordChatText();		table.foreach(message_array, function(k,v) tcl_Msg(v); end);	endendfunction tcl_GetRecordChatText()	local hicrit, acrit, ecrit = tcl_GetHighestCrit();	local hidmg, anormal, enormal = tcl_GetHighestDamage();	local hihealcrit, hcrit, ehcrit = tcl_GetHighestHealCrit();	local hihealdmg, hnormal, ehnormal = tcl_GetHighestHeal();	local text = {};	table.insert(text, TITAN_CRITLINE_ID.." "..RECORDS_TEXT..":");	table.insert(text, CRIT_TEXT..": "..acrit.." ("..hicrit..")".." ["..ecrit.."]");	table.insert(text, NORMAL_TEXT..": "..anormal.." ("..hidmg..")".." ["..enormal.."]");	if ( TCL_SETTINGS[TCL_REALM]["SETTINGS"]["FILTER_HEALING"] == "0" ) then		if ( hihealcrit > 0 ) then			table.insert(text, CRIT_TEXT..": "..hcrit.." ("..hihealcrit..")".." ["..ehcrit.."]");		end		if ( hihealdmg > 0 ) then			table.insert(text, NORMAL_TEXT..": "..hnormal.." ("..hihealdmg..")".." ["..ehnormal.."]");		end	end	return text;end--[[ misc help functions ]]function COLOR(color, msg)	if ( msg == nil ) then		return;	end	return color..msg..FONT_COLOR_CODE_CLOSE;endfunction tcl_Msg(msg)	if ( msg == nil ) then		msg = "------------------------------";	end	if (DEFAULT_CHAT_FRAME) then		DEFAULT_CHAT_FRAME:AddMessage(msg);	endendfunction tcl_Rebuild()	tcl_Msg(TITAN_CRITLINE_ID.." "..TITAN_CRITLINE_VERSION.." rebuilding data.");	TCL_SETTINGS[TCL_REALM] = nil;	tcl_Initialize();	tcl_Msg(TITAN_CRITLINE_ID.." "..TITAN_CRITLINE_VERSION.." rebuilding data complete.");endfunction tcl_DEBUG(message)	if (DEBUG and DEFAULT_CHAT_FRAME) then		DEFAULT_CHAT_FRAME:AddMessage("DEBUG: "..message);	endend