Quantcast
local L = Elementarist.Locals;

Elementarist:RegisterModule("enhancement");

Elementarist.enhancement = {
	["Configuration"] = {
		["ShowHealingStream"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -60,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_ENABLE_HS_TOTEM
		}
	};
	Initialize = function(self)
		Elementarist:LoadSpells({
			["Stormstrike"] = GetSpellInfo(17364),
			["Windstrike"] = 115357,		-- not in spellbook, ID must be used!
			["Lava Lash"] = GetSpellInfo(60103),
			["Flask of Spring Blossoms"] = GetSpellInfo(76084),
			["AscendanceEnhancementBuff"] = GetSpellInfo(114051),
			["Ancestral Swiftness"] = GetSpellInfo(16188),
			["Feral Spirit"] = GetSpellInfo(51533),
			["Lightning Shield"] = GetSpellInfo(192106),

			["Flametongue"] = GetSpellInfo(193796),
			["Boulderfist"] = GetSpellInfo(201897),
			["Frostbrand"] = GetSpellInfo(196834),
			["Crash Lightning"] = GetSpellInfo(187874),

			["Greater Draenic Agility Flask"] = GetSpellInfo(156064),
			["Draenic Agility Flask"] = GetSpellInfo(156073),
			["Flask of Spring Blossoms"] = GetSpellInfo(114769),
			["Flask of the Winds"] = GetSpellInfo(79471)
		});

		Elementarist.role = "DPS";
		Elementarist.trackAura = false;
		Elementarist.trackFilter = nil;
		Elementarist.trackDuration = 30;
		Elementarist.trackSpread = false;
		Elementarist.debuffCount = 0;
		Elementarist.exspell1=nil;
	end;
	NextSpell = function(self,timeshift,exspell1,exspell2)
		local guid = UnitGUID("target")
		local currentTime = GetTime()
		local s,d,e
		local name, fsExpiration, unitCaster
		local lastSpell
		local haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration
		local EBTalent, EETalent, EFTalent, MWcount, EFcount
		local LLCharges, maxLLCharges, cdLLStart, cdLLLength
		local SSCharges, maxSSCharges, cdSSStart, cdSSLength
		local ascendance, ascendanceExp
		local flameshockavail = false
		local spellInCast, sICstartTime, sICendTime
		local _

		ascendance, _, _, _, _, _, ascendanceExp = Elementarist:hasBuff("player", Elementarist.SpellList["AscendanceEnhancementBuff"])
		if (ascendance == nil) then
			ascendanceExp = 0
		end

		if (exspell1) then
			if (exspell2) then
				lastSpell = exspell2
			else
				lastSpell = exspell1
			end
		else
			lastSpell = Elementarist.lastSpell
		end

		Elementarist.lastBaseGCD = 1.5 - (1.5 * Elementarist.spellHaste * .01)

		-- if target is dead, return ""
		if (UnitHealth("target")<=0) then
			return ""
		end

		if (not timeshift) then
			timeshift = 0
		end

		local LvBct = 2 - (2 * Elementarist.spellHaste * .01)

		local bdfCharges, _, cdStart, cdLength  = GetSpellCharges(Elementarist.SpellList["Boulderfist"]);
		bdfCharges = bdfCharges - Elementarist:Count(Elementarist.SpellList["Boulderfist"], spellInCast,exspell1,exspell2);
		if (((cdStart + cdLength)- GetTime()) - timeshift <= 0) then
			bdfCharges = bdfCharges + 1
		end

		-- check current spell
		spellInCast, _, _, _, sICstartTime, sICendTime = UnitCastingInfo("player")
		if (spellInCast) then
			if ( (sICendTime - sICstartTime) / 1000 ) < Elementarist.lastBaseGCD then
				sICendTime = sICstartTime + (Elementarist.lastBaseGCD * 1000)
			end
			timeshift = timeshift + (sICendTime / 1000) - currentTime
		else
			-- no spell in cast, check global cd via Ghost Wolf
			if (Elementarist.SpellList["Ghost Wolf"]) then
				local ftcd = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ghost Wolf"])
				if (ftcd) then
					timeshift = timeshift + Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ghost Wolf"])
				else
					timeshift = timeshift + Elementarist.lastBaseGCD
				end
			else
				timeshift = timeshift + Elementarist.lastBaseGCD
			end
		end

		-- Maintain Boulderfist and Landslide
		if (not Elementarist:hasBuff("player", Elementarist.SpellList["Boulderfist"])) and (bdfCharges>=1) then
			if Elementarist:ZeroCount(Elementarist.SpellList["Boulderfist"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Boulderfist"]) then
				return Elementarist.SpellList["Boulderfist"]
			end
		end

		-- Maintain Hailstorm (if talented)
		if (Elementarist.talents[4] == 3) then
			if (not Elementarist:hasBuff("player", Elementarist.SpellList["Frostbrand"])) then
				if Elementarist:ZeroCount(Elementarist.SpellList["Frostbrand"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Frostbrand"]) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Frostbrand"])
					if d-timeshift <= 0.5 then
						return Elementarist.SpellList["Frostbrand"]
					end
				end
			end
		end

		-- Boulderfist if Maelstorm < 130 and 2 charges of Boulderfist
		if (UnitPower("player",11)<130) then
			-- get lava burst charges and adjust Charges based on timeshift
			if (Elementarist:SpellAvailable(Elementarist.SpellList["Boulderfist"])) and (bdfCharges>=2) then
				return Elementarist.SpellList["Boulderfist"]
			end
		end

		-- Maintain Flametongue
		if (not Elementarist:hasBuff("player", Elementarist.SpellList["Flametongue"])) then
			if Elementarist:ZeroCount(Elementarist.SpellList["Flametongue"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Flametongue"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Flametongue"])
				if d-timeshift <= 0.5 then
					return Elementarist.SpellList["Flametongue"]
				end
			end
		end

		-- Stormstrike
		if Elementarist:ZeroCount(Elementarist.SpellList["Stormstrike"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Stormstrike"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Stormstrike"])
			if d-timeshift <= 0.5 then
				return Elementarist.SpellList["Stormstrike"]
			end
		end

		-- Crash Lightning if Crashing Storm talent
		if (Elementarist.talents[6] == 1) then
			if Elementarist:ZeroCount(Elementarist.SpellList["Crash Lightning"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Crash Lightning"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Crash Lightning"])
				if d-timeshift <= 0.5 then
					return Elementarist.SpellList["Crash Lightning"]
				end
			end
		end

		-- Lava Lash if Maelstorm > 110
		if Elementarist:ZeroCount(Elementarist.SpellList["Lava Lash"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Lava Lash"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Lava Lash"])
			if (d-timeshift <= 0.5) and (UnitPower("Player",11)>=110) then
				return Elementarist.SpellList["Lava Lash"]
			end
		end

		-- Boulderfist
		if Elementarist:ZeroCount(Elementarist.SpellList["Boulderfist"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Boulderfist"]) then
			return Elementarist.SpellList["Boulderfist"]
		end

		-- Flametongue
		if Elementarist:ZeroCount(Elementarist.SpellList["Flametongue"],spellInCast,exspell1,exspell2) and Elementarist:SpellAvailable(Elementarist.SpellList["Flametongue"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Flametongue"])
			if d-timeshift <= 0.5 then
				return Elementarist.SpellList["Flametongue"]
			end
		end

		-- Lightning Bolt
		return Elementarist.SpellList["Lightning Bolt"]
	end;
	MiscSpell = function(self)
		-- Miscelaneous spell order:
		-- Lightning Shield
		-- Searing Totem
		-- Berserking troll racial (if available)
		-- Blood Fury orc racial

		local d, e
		local name, expirationTime, _, name2, expirationTime2, name3, expirationTime3

		------  Augment Rune
		if (
			(
				((Elementarist.faction == "Horde") and (GetItemCount(Elementarist.CustomIDs["Empowered Augment Rune Horde"]) ~= 0)) or
				((Elementarist.faction == "Alliance") and (GetItemCount(Elementarist.CustomIDs["Empowered Augment Rune Alliance"]) ~= 0))
			) and ( not  Elementarist:hasBuff("player", Elementarist.SpellList["Hyper Augmentation"]))
		) then
        	if (
        		((Elementarist.faction == "Horde") and (Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Empowered Augment Rune Horde"]) < 2)) or
        		((Elementarist.faction == "Alliance") and (Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Empowered Augment Rune Alliance"]) < 2))
        	) then
				return nil,GetItemIcon(Elementarist.CustomIDs["Empowered Augment Rune Horde"])
			end
       	end

		-- Alchemy Flask of Enhancement
		if	(
			((GetItemCount(Elementarist.CustomIDs["Whispers of Insanity Item"]) ~= 0) and (Elementarist.playerLevel >= 90)  ) or
			((GetItemCount(Elementarist.CustomIDs["Crystal of Insanity Item"]) ~= 0)and (Elementarist.playerLevel >= 85)  ) or
			((GetItemCount(Elementarist.CustomIDs["Alchemist's Flask Item"]) ~= 0)  and (Elementarist.playerLevel <= 91)  )
		) then
			name = Elementarist:hasBuff("player", Elementarist.SpellList["Greater Draenic Agility Flask"]);
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Draenic Agility Flask"]);
			end
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Flask of Spring Blossoms"]);
			end
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Flask of the Winds"]);
			end
			if (name == nil) then
				name,  _, _, _, _, _, expirationTime = Elementarist:hasBuff("player", Elementarist.SpellList["Whispers of Insanity"], false, Elementarist.CustomIDs["Whispers of Insanity Spell"]);
				name2, _, _, _, _, _, expirationTime2 = Elementarist:hasBuff("player", Elementarist.SpellList["Crystal of Insanity"], false, Elementarist.CustomIDs["Crystal of Insanity Spell"]);
				name3, _, _, _, _, _, expirationTime3 = Elementarist:hasBuff("player", Elementarist.SpellList["Alchemist's Flask"], false, Elementarist.CustomIDs["Alchemist's Flask Spell"]);

				if ((name == nil) and (name2 == nil) and (name3 == nil)) or (((name ~= nil) and (expirationTime<2)) or ((name2 ~= nil) and (expirationTime2<2)) or ((name3 ~= nil) and (expirationTime3<2))) then
					if (GetItemCount(Elementarist.CustomIDs["Whispers of Insanity Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Whispers of Insanity Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Whispers of Insanity Item"])
						end
					elseif (GetItemCount(Elementarist.CustomIDs["Crystal of Insanity Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Crystal of Insanity Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Crystal of Insanity Item"])
						end
					elseif (GetItemCount(Elementarist.CustomIDs["Alchemist's Flask Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Alchemist's Flask Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Alchemist's Flask Item"])
						end
					end
				end
			end
		end

		-- Lightning Shield
		if Elementarist:SpellAvailable(Elementarist.SpellList["Lightning Shield"]) then
			name, _, _, _, _, _, expirationTime = Elementarist:hasBuff("player", Elementarist.SpellList["Lightning Shield"]);
			if (name == nil) or (expirationTime < 1) then
				return Elementarist.SpellList["Lightning Shield"]
			end
		end

		-- Fire Elemental Totem
		if Elementarist:SpellAvailable(Elementarist.SpellList["Fire Elemental Totem"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Fire Elemental Totem"])
			if d <= 0.5 then
				return Elementarist.SpellList["Fire Elemental Totem"]
			end
		end

		-- Storm Elemental Totem
		if (Elementarist.tier7Talent == 21199) then
			if Elementarist:SpellAvailable(Elementarist.SpellList["Storm Elemental Totem"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Storm Elemental Totem"])
				if d <= 0.5 then
					return Elementarist.SpellList["Storm Elemental Totem"]
				end
			end
		end

		-- Feral Spirit
		if Elementarist:SpellAvailable(Elementarist.SpellList["Feral Spirit"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Feral Spirit"])
			if d <= 0.5 then
				return Elementarist.SpellList["Feral Spirit"]
			end
		end

		-- Elemental Mastery
		if Elementarist:SpellAvailable(Elementarist.SpellList["Elemental Mastery"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Elemental Mastery"])
			if d <= 0.5 then
				return Elementarist.SpellList["Elemental Mastery"]
			end
		end

		-- Ascendance
		if Elementarist:SpellAvailable(Elementarist.SpellList["Ascendance"]) then
			name = Elementarist:hasBuff("player",Elementarist.SpellList["AscendanceElementalBuff"])
			if (name == nil) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ascendance"])
				if d <= 0.5 then
					return Elementarist.SpellList["Ascendance"]
				end
			end
		end

		-- Berserking
		if Elementarist:SpellAvailable(Elementarist.SpellList["Berserking"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Berserking"])
			if d <= 0.5 then
				return Elementarist.SpellList["Berserking"]
			end
		end

		-- Blood Fury
		if Elementarist:SpellAvailable(Elementarist.SpellList["Blood Fury"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Blood Fury"])
			if d <= 0.5 then
				return Elementarist.SpellList["Blood Fury"]
			end
		end

		return ""
	end;
	IntSpell = function(self)
		-- interruptions, purge, and AoE on target
		local d

		Elementarist.trackSpread = (Elementarist.lastSpell == Elementarist.SpellList["Flame Shock"])

		-- AOE at least 3 enemies
 		if (Elementarist.person["foeCount"]>=3) then
			if (Elementarist.lastSpell ~= Elementarist.SpellList["Crash Lightning"]) and Elementarist:SpellAvailable(Elementarist.SpellList["Crash Lightning"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Crash Lightning"])
				if d-timeshift <= 0.5 then
					return Elementarist.SpellList["Crash Lightning"]
				end
			end
		end

        -- Wind Shear
		if Elementarist:SpellAvailable(Elementarist.SpellList["Wind Shear"]) then
			if IsSpellInRange(Elementarist.SpellList["Wind Shear"], "target") == 1 then
				local _, status, threatpct, _, _ = UnitDetailedThreatSituation("player", "target")
				if ((UnitCastingInfo("target")) or (UnitChannelInfo("target"))) or ((status) and (threatpct>80) and (Elementarist.person["friendCount"]>1) and (Elementarist.inParty>0)) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Wind Shear"])
					if (d) and (d<0.5) and (IsSpellInRange(Elementarist.SpellList["Wind Shear"], "target") ) then
						return Elementarist.SpellList["Wind Shear"]
					end
				end

				if (UnitChannelInfo("target")) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Wind Shear"])
					if (d<0.5) and (interruptable) and (IsSpellInRange(Elementarist.SpellList["Wind Shear"], "target") ) then
						return Elementarist.SpellList["Wind Shear"]
					end
				end
			end
		end

		---------- check if purgeable buff is on target (not sure if this is ok)
		if Elementarist:SpellAvailable(Elementarist.SpellList["Purge"]) then
			if IsSpellInRange(Elementarist.SpellList["Purge"], "target") == 1 then
				if (Elementarist:hasBuff("target", ".", 1)) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Purge"])
					if (d) and (d<0.5) then
						return Elementarist.SpellList["Purge"]
					end
				end
			end
		end

		return ""
	end;
	ShieldName = function(self)
		return "Lightning Shield";
	end;
};