local GetBuildInfo, select, ipairs, pairs, tonumber, GetSpellInfo, IsUsableSpell, GetTime, UnitAffectingCombat, IsMounted, UnitInVehicle, UnitIsDeadOrGhost, UnitChannelInfo, UnitCastingInfo = GetBuildInfo, select, ipairs, pairs, tonumber, GetSpellInfo, IsUsableSpell, GetTime, UnitAffectingCombat, IsMounted, UnitInVehicle, UnitIsDeadOrGhost, UnitChannelInfo, UnitCastingInfo
local wotlk = select(4, GetBuildInfo()) == 30300

if wotlk then
--ni.vars.debug = true
local spells = {
	HolyShock = GetSpellInfo(48825),
	DivineShield = GetSpellInfo(642),
	HandofProtection = GetSpellInfo(10278),
	FlashofLight = GetSpellInfo(48785),
	LayonHands = GetSpellInfo(48788),
	DivineProtection = GetSpellInfo(498),
	DivineFavor = GetSpellInfo(20216),
	AvengingWrath = GetSpellInfo(31884),
	DivineSacrifice = GetSpellInfo(64205),
	HandofSacrifice = GetSpellInfo(6940),
	Consecration = GetSpellInfo(48819),
	HammerofWrath = GetSpellInfo(48806),
	HammerofJustice = GetSpellInfo(10308),
	AuraMastery = GetSpellInfo(31821),
	DivineIllumination = GetSpellInfo(31842),
	DivinePlea = GetSpellInfo(54428),
	HandofFreedom = GetSpellInfo(1044),
	Cleanse = GetSpellInfo(4987),
	HolyWrath = GetSpellInfo(48817),
	TurnEvil = GetSpellInfo(10326),
	SacredShield = GetSpellInfo(53601),
	BeaconofLight = GetSpellInfo(53563),
	BlessingofKings = GetSpellInfo(20217),
	SealofWisdom = GetSpellInfo(20166),
	RighteousFury = GetSpellInfo(25780),
	JudgementofWisdom = GetSpellInfo(53408),
	-- Racials
	EveryManForHimself = GetSpellInfo(59752),
	GiftofNaaru = GetSpellInfo(59542),
	ArcaneTorrent = GetSpellInfo(28730),
	-- Others Spells
	HealAllyPet = GetSpellInfo(48785),
	Forbearance = GetSpellInfo(25771),
	ConcentrationAura = GetSpellInfo(19746),
	InfusionofLight = GetSpellInfo(54149),
	GreaterBlessingofKings = GetSpellInfo(25898),
	-- Items
	FelHealthstone = 36894,
	FelHealthstoneL = 36892,
	BaubleofTrueBlood = 50726,
	BaubleofTrueBloodL = 50354,
}

local HoFDebuff = {
	-- Mage
	18118, -- "Aftermath"
	42945, -- "Blast Wave"
	51585, -- "Blade Twisting"
	42931, -- "Cone of Cold"
	42842, -- "Frostbolt"
	58799, -- "Frostbrand Attack"
	47610, -- "Frostfire Bolt"
	42917, -- "Frost Nova"

	-- Hunter
	5116,  -- "Concussive Shot"
	14311, -- "Freezing Trap"
	13809, -- "Frost Trap"
	53548, -- "Pin"
	61290, -- "Shadowflame"
	53227, -- "Typhoon"
	4167,  -- "Web"
	2974,  -- "Wing Clip"

	-- Rogue
	3775,  -- "Crippling Poison"
	3776,  -- "Crippling Poison II"

	-- Death Knight
	45524, -- "Chains of Ice"

	-- Shaman
	53313, -- "Nature's Grasp"
	49236, -- "Frost Shock"

	-- Warlock
	61291, -- "Shadowflame"

	-- Warrior
	1715,  -- "Hamstring"
	12323, -- "Piercing Howl"

	-- Death Knight
	53114, -- "Hungering Cold"

	-- Shaman
	64695, -- "Earthbind Root"
	63685, -- "Enhance Nova"
	12494, -- "Frost Bite"
	33395, -- "Pet Nova"

	-- Warlock
	3409,  -- "Crippling Poison"

	-- Multiple Class
	68766, -- "Desecration"
	7321,  -- "Chilled"
	31589, -- "Slow"
}

local CCDebuff = {
	-- Mage
	44572, -- Deep Freeze
	118,   -- Polymorph
	12826, -- Polymorph Sheep
	28271, -- Polymorph Turtle
	61721, -- Polymorph Rabbit
	61305, -- Polymorph Black Cat
	28272, -- Polymorph Pig
	42950, -- Dragon's Breath

	-- Warlock
	6215,  -- Fear
	18658, -- Hibernate
	6358,  -- Seduction (Succubus)
	30283, -- Shadowfury
	47860, -- Death Coil

	-- Druid
	33786, -- Cyclone

	-- Death Knight
	51209, -- Hungering Cold

	-- Hunter
	60210, -- Freezing Arrow
	14309, -- Freezing Trap

	-- Paladin
	20066, -- Repentance
	10308, -- Hammer of Justice

	-- Rogue
	2094,  -- Blind
	51724, -- Sap

	-- Priest
	10890, -- Psychic Scream
	605,   -- Mind Control

	-- Warrior
	17928, -- Howl of Terror

	-- Warlock
	18647, -- Banish
	51514, -- Hex
}

local queue = {
	"Initial",
	"Every Man for Himself",
	"Divine Shield",
	"Pause",
	"Hand of Protection",
	"Lay on Hands",
	"Divine Protection",
	"Divine Favor",
	"Fel Healthstone",
	"Bauble of True Blood",
	"Avenging Wrath",
	"Divine Sacrifice",
	"Hand of Sacrifice",
	"Consecration",
	"Hammer of Wrath",
	"Hammer of Justice",
	"Arcane Torrent",
	"Aura Mastery",
	"Divine Illumination",
	"Divine Plea",
	"Hand of Freedom",
	"Gift of Naaru",
	"Holy Shock",
	"Flash of Light",
	"Heal Ally Pet",
	"Judgement of Wisdom",
	"Cleanse",
	"Holy Wrath",
	"Turn Evil",
	"Sacred Shield",
	"Beacon of Light",
	"Blessing of Kings",
	"Seal of Wisdom",
	"Righteous Fury"
}

local items = {
	settingsfile = "HPal.json",
	{ type = "title", text = "|cffFFFF00Holy Paladin|r PVP Profile" },
	{ type = "title", text = "HPal for NI by darhanger. github.com/nelbin4" },
	{ type = "separator" },
	{ type = "page", number = 1, text = "|cffFFFF00Healing Spells" },
	{ type = "separator" },
	{ type = "entry", text = ni.spell.icon(48788).." Lay on Hands", enabled = true, key = "LayonHands", value = 25, min = 1, max = 100, step = 1, width = 40, tooltip = "Stops current cast to use Lay on Hands when health is low" },
	{ type = "entry", text = ni.spell.icon(20216).." Divine Favor", enabled = true, key = "DivineFavor", value = 40, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Divine Favor in combination with Holy Shock" },
	{ type = "entry", text = ni.player.itemicon(36894).." Fel Healthstone", enabled = true, key = "FelHealthstone", value = 25, min = 1, max = 100, step = 1, width = 40, tooltip = "Stops current cast to use Fel Healthstone when health is low" },
	{ type = "entry", text = ni.player.itemicon(50354).." Bauble of True Blood", enabled = true, key = "BaubleofTrueBlood", value = 30, min = 1, max = 100, step = 1, width = 40, tooltip = "Uses Bauble of True Blood when equipped and health is low" },
	{ type = "entry", text = ni.spell.icon(48825).." Holy Shock", enabled = true, key = "HolyShock", value = 85, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Holy Shock when usable" },
	{ type = "entry", text = ni.spell.icon(48785).." Flash of Light", enabled = true, key = "FlashofLight", value = 85, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Flash of Light even while moving if Infusion of Light is active" },
	{ type = "entry", text = ni.spell.icon(59542).." Gift of Naaru", enabled = true, key = "GiftofNaaru", value = 90, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Gift of Naaru when target health is below threshold. Racial Ability: Draenei" },
	{ type = "entry", text = ni.spell.icon(35295).." Heal Ally's Pet", enabled = true, key = "HealAllyPet", value = 70, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Flash of Light on an ally's pet or minion if its health is below the threshold" },

	{ type = "page", number = 2, text = "|cffFFFF00Defensive Spells" },
	{ type = "separator" },
	{ type = "entry", text = ni.spell.icon(642).." Divine Shield", enabled = true, key = "DivineShield", value = 35, min = 1, max = 100, step = 1, width = 40, tooltip = "Stops current cast to use Divine Shield when health is low" },
	{ type = "entry", text = ni.spell.icon(10278).." Hand of Protection", enabled = true, key = "HandofProtection", value = 35, min = 1, max = 100, step = 1, width = 40, tooltip = "Stops current cast to use Hand of Protection when health is low" },
	{ type = "entry", text = ni.spell.icon(498).." Divine Protection", enabled = true, key = "DivineProtection", value = 35, min = 1, max = 100, step = 1, width = 40, tooltip = "Stops current cast to use Divine Protection when health is low" },
	{ type = "entry", text = ni.spell.icon(64205).." Divine Sacrifice", enabled = true, key = "DivineSacrifice", value = 70, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Divine Sacrifice when in a group" },
	{ type = "entry", text = ni.spell.icon(6940).." Hand of Sacrifice", enabled = true, key = "HandofSacrifice", value = 60, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Hand of Sacrifice when in a group" },
	{ type = "entry", text = ni.spell.icon(31821).." Aura Mastery", enabled = true, key = "AuraMastery", value = 60, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Aura Mastery when Concentration Aura is active" },
	{ type = "entry", text = ni.spell.icon(1044).." Hand of Freedom", enabled = true, key = "HandofFreedom", value = 60, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Hand of Freedom when ally's health is below threshold" },
	{ type = "entry", text = ni.spell.icon(31842).." Divine Illumination", enabled = true, key = "DivineIllumination", value = 70, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Divine Illumination when mana is below threshold" },
	{ type = "entry", text = ni.spell.icon(59752).." Every Man For Himself", enabled = true, key = "EveryManForHimself", value = 50, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Every Man for Himself when CC is more than 5 seconds and ally's health is below threshold. Racial Ability: Human" },

	{ type = "page", number = 3, text = "|cffFFFF00Utility Spells" },
	{ type = "separator" },
	{ type = "entry", text = ni.spell.icon(48819).." Consecration", enabled = true, key = "Consecration", tooltip = "Casts Consecration when a stealthed enemy is nearby" },
	{ type = "entry", text = ni.spell.icon(48806).." Hammer of Wrath", enabled = true, key = "HammerofWrath", value = 20, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Hammer of Wrath on low health enemies" },
	{ type = "entry", text = ni.spell.icon(10308).." Hammer of Justice", enabled = true, key = "HammerofJustice", value = 35, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Hammer of Justice on nearby enemy that has health lower than threshold" },
	{ type = "entry", text = ni.spell.icon(28730).." Arcane Torrent", enabled = true, key = "ArcaneTorrent", tooltip = "Casts Arcane Torrent on nearby enemy that is casting or channeling a spell. Racial Ability: Blood Elf" },
	{ type = "entry", text = ni.spell.icon(53408).." Judgement of Wisdom", enabled = true, key = "JudgementofWisdom", value = 90, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Judgement of Wisdom to nearby enemy when we have mana lower than threshold" },
	{ type = "entry", text = ni.spell.icon(4987).." Cleanse", enabled = true, key = "Cleanse", value = 40, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Cleanse until mana is above threshold" },
	{ type = "entry", text = ni.spell.icon(48817).." Holy Wrath", enabled = true, key = "HolyWrath", tooltip = "Casts Holy Wrath on nearby undead or demons" },
	{ type = "entry", text = ni.spell.icon(10326).." Turn Evil", enabled = true, key = "TurnEvil", tooltip = "Casts Turn Evil on Ebon Gargoyle, Succubus, Felhunter, Ghoul" },

	{ type = "page", number = 4, text = "|cffFFFF00Buff Spells" },
	{ type = "separator" },
	{ type = "entry", text = ni.spell.icon(31884).." Avenging Wrath", enabled = true, key = "AvengingWrath", value = 40, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Avenging Wrath if Divine Shield is not available" },
	{ type = "entry", text = ni.spell.icon(54428).." Divine Plea", enabled = true, key = "DivinePlea", value = 20, min = 1, max = 100, step = 1, width = 40, tooltip = "Casts Divine Plea when mana is below threshold" },
	{ type = "entry", text = ni.spell.icon(53601).." Sacred Shield", enabled = true, key = "SacredShield", tooltip = "Casts Sacred Shield on self" },
	{ type = "entry", text = ni.spell.icon(53563).." Beacon of Light", enabled = true, key = "BeaconofLight", tooltip = "Casts Beacon of Light on the focus target if it's an ally, otherwise casts on self" },
	{ type = "entry", text = ni.spell.icon(20217).." Blessing of Kings", enabled = true, key = "BlessingofKings", tooltip = "Casts Blessing of Kings, but won't overwrite if Greater Blessing of Kings is active" },
	{ type = "entry", text = ni.spell.icon(20166).." Seal of Wisdom", enabled = true, key = "SealofWisdom", tooltip = "Casts Seal of Wisdom on self. Only when we are at Preparation Stage" },
	{ type = "entry", text = ni.spell.icon(25780).." Righteous Fury", enabled = true, key = "RighteousFury", tooltip = "Casts Righteous Fury on self. Only when we are at Preparation Stage" },
}

local function setting(name)
	local EN, SP, TR
	for _, v in ipairs(items) do
        if v.key == name then
			EN = v.enabled
            SP = spells[name]
			TR = v.value
            break
        end
    end
    return EN, SP, TR
end

-- Function Helper
local AntiAFKTime = 0
local function FunctionHelper()
	inCombat = UnitAffectingCombat("player")
	hasForb = UnitDebuff("player", spells.Forbearance)
	isCast = UnitCastingInfo("player") or UnitChannelInfo("player")
	inGroup = (GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0)
end

-- Usable Spells
local function USS(spellid)
    if not spellid or spellid == 0 then return false end
    return ni.spell.available(spellid) and IsUsableSpell(spellid)
end

-- Usable Items
local function USI(itemid)
    if not itemid or itemid == 0 then return false end
    return ni.player.itemcd(itemid) == 0 and IsUsableItem(itemid)
end

-- Food and Drink
local function snackTime()
	return ni.unit.buffs("player", "43180||45548||43183||45544||25990||57073||Food||Drink||Refreshment||First Aid")
end

local abilities = {
	["Initial"] = function()
		FunctionHelper()
		if GetTime() - AntiAFKTime > 80 then
			ni.utils.resetlasthardwareaction();
			AntiAFKTime = GetTime();
		end

		if not inCombat	then
			if snackTime() then
			return true
			end
		end

		if IsMounted()
			or UnitInVehicle("player")
			or UnitIsDeadOrGhost("player")
			or ni.player.islooting()
		then
			return true
		end
	end,

	["Every Man for Himself"] = function()
		local EN, SP, TR = setting("EveryManForHimself")
		if not EN or not USS(SP) then return false end

		local ally = ni.members.inrangebelow("player", 40, TR)[1]
		if not ally then return false end

		for i = 1, #CCDebuff do
			local CCD = CCDebuff[i]
			if ni.unit.debuffremaining("player", CCD) > 4 then
				ni.spell.cast(SP)
				return true
			end
		end
		return false
	end,

	["Divine Shield"] = function()
		local EN, SP, TR = setting("DivineShield")
		if not EN or not inCombat or hasForb or not USS(SP) then return false end

		if ni.unit.hp("player") < TR then
			if isCast then ni.spell.stopcasting() end
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Pause"] = function()
		if ni.player.isstunned()
			or ni.player.issilenced()
		then
			return true
		end
	end,

	["Hand of Protection"] = function()
		local EN, SP, TR = setting("HandofProtection")
		if not EN or not inCombat or not USS(SP) then return false end

		local ally = ni.members.inrangebelow("player", 30, TR)[1]
		if ally and ally:valid(SP, false, true) and not ni.unit.debuff(ally.guid, spells.Forbearance) then
			if isCast then ni.spell.stopcasting() end
			ni.spell.cast(SP, ally.guid)
			return true
		end
		return false
	end,

	["Lay on Hands"] = function()
		local EN, SP, TR = setting("DivineProtection")
		if not EN or not inCombat or not USS(SP) then return false end

		if select(2, IsInInstance()) == "arena" then return false end
		local ally = ni.members.inrangebelow("player", 40, TR)[1]
		if ally and ally:valid(SP, false, true) and not ni.unit.debuff(ally.guid, spells.Forbearance) then
			if isCast then ni.spell.stopcasting() end
			ni.spell.cast(SP, ally.guid)
			return true
		end
		return false
	end,

	["Divine Protection"] = function()
		local EN, SP, TR = setting("DivineProtection")
		if not EN or not inCombat or hasForb or not USS(SP) then return false end

		if ni.unit.hp("player") < TR then
			if isCast then ni.spell.stopcasting() end
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Divine Favor"] = function()
		local EN, SP, TR = setting("DivineFavor")
		if not EN or not inCombat or not USS(SP) or not USS(spells.HolyShock) then return false end

		local ally = ni.members.inrangebelow("player", 40, TR)[1]
		if ally and ally:valid(spells.HolyShock, false, true) then
			ni.spell.cast(SP, "player")
			ni.spell.cast(spells.HolyShock, ally.guid)
			return true
		end
		return false
	end,

	["Fel Healthstone"] = function()
		local EN, SP, TR = setting("FelHealthstone")
		if not EN or not inCombat then return false	end

		if ni.unit.hp("player") < TR then
			if ni.player.hasitem(SP) and USI(SP) then
				ni.player.useitem(SP)
				return true
			elseif ni.player.hasitem(spells.FelHealthstoneL) and USI(spells.FelHealthstoneL) then
				ni.player.useitem(spells.FelHealthstoneL)
				return true
			end
		end
		return false
	end,

	["Bauble of True Blood"] = function()
		local EN, SP, TR = setting("BaubleofTrueBlood")
		if not EN or not inCombat then return false end

		local BBA = ni.player.hasitemequipped(SP) and USI(SP)
		local BBB = ni.player.hasitemequipped(spells.BaubleofTrueBloodL) and USI(spells.BaubleofTrueBloodL)
		if BBA or BBB then
			local ally = ni.members.inrangebelow("player", 40, TR)[1]
			if ally and ally:los() then
				local BBC = BBA and SP or spells.BaubleofTrueBloodL
				ni.player.useitem(BBC, ally.guid)
				return true
			end
		end
		return false
	end,

	["Avenging Wrath"] = function()
		local EN, SP, TR = setting("AvengingWrath")
		if not EN or not inCombat or not USS(SP) then return false end

		if not ni.unit.buffs("player", "642||489||10278")
			and not ni.spell.available(spells.DivineShield) then
			local ally = ni.members.inrangebelow("player", 40, TR)[1]
			if ally then
				ni.spell.cast(SP, "player")
				return true
			end
		end
		return false
	end,

	["Divine Sacrifice"] = function()
		local EN, SP, TR = setting("DivineSacrifice")
		if not EN or not inCombat or not USS(SP) then return false end

		if inGroup then
			if ni.members.inrangebelow("player", 30, TR)[1] then
				ni.spell.cast(SP, "player")
				return true
			end
		end
		return false
	end,

	["Hand of Sacrifice"] = function()
		local EN, SP, TR = setting("HandofSacrifice")
		if not EN or not inCombat or not USS(SP) then return false end

		if inGroup and not ni.unit.buffs("player", "642||1044||64205") then
			local ally = ni.members.inrangebelow("player", 30, TR)[1]
			if ally and ally:valid(SP, false, true) and ally.guid ~= UnitGUID("player") then
				ni.spell.cast(SP, ally.guid)
				return true
			end
		end
		return false
	end,

	["Consecration"] = function()
		local EN, SP = setting("Consecration")
		if not EN or not USS(SP) then return false end

		local stealthAbilities = {1784, 5215, 66, 58984, 1856}
		local enemies = ni.unit.enemiesinrange("player", 10)
		for i = 1, #enemies do
			local enemy = enemies[i]
			for j = 1, #stealthAbilities do
				if ni.unit.buff(enemy.guid, stealthAbilities[j]) then
					ni.spell.cast(SP)
					return true
				end
			end
		end
		return false
	end,

	["Hammer of Wrath"] = function()
		local EN, SP, TR = setting("HammerofWrath")
		if not EN or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 30)
		for i = 1, #enemies do
			local wTarget = enemies[i].guid
			if ni.unit.hp(wTarget) < TR
				and ni.spell.valid(wTarget, SP, false, true)
				and not ni.unit.isimmune(wTarget)
				and ni.unit.isplayer(wTarget) then
				ni.player.lookat(wTarget)
				ni.spell.cast(SP, wTarget)
				return true
			end
		end
		return false
	end,

	["Hammer of Justice"] = function()
		local EN, SP, TR = setting("HammerofJustice")
		if not EN or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 10)
		for i = 1, #enemies do
			local jTarget = enemies[i].guid
			if ni.spell.valid(jTarget, SP, false, true)
				and ni.unit.hp(jTarget) < TR
				and not ni.unit.isimmune(jTarget)
				and ni.unit.isplayer(jTarget) then
				ni.spell.cast(SP, jTarget)
				return true
			end
		end
		return false
	end,


	["Arcane Torrent"] = function()
		local EN, SP = setting("ArcaneTorrent")
		if not EN or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 8)
		for i = 1, #enemies do
			local aTarget = enemies[i].guid
			if ni.spell.valid(aTarget, SP, false, true)
				and ni.unit.iscasting(aTarget) or ni.unit.ischanneling(aTarget)
				and ni.unit.isplayer(aTarget) then
				ni.spell.cast(SP)
				return true
			end
		end
		return false
	end,

	["Aura Mastery"] = function()
		local EN, SP, TR = setting("AuraMastery")
		if not EN or not inCombat or not USS(SP) then return false end

		if ni.unit.aura("player", spells.ConcentrationAura)
			and not ni.unit.buffs("player", "10278||642") then
			local ally = ni.members.inrangebelow("player", 40, TR)[1]
			if ally then
				ni.spell.cast(SP, "player")
				return true
			end
		end
		return false
	end,

	["Divine Illumination"] = function()
		local EN, SP, TR = setting("DivineIllumination")
		if not EN or not inCombat or not USS(SP) then return false end

		if ni.unit.power("player") < TR then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Divine Plea"] = function()
		local EN, SP, TR = setting("DivinePlea")
		if not EN or not inCombat or not USS(SP) then return false end

		if ni.unit.power("player") < TR then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Hand of Freedom"] = function()
		local EN, SP, TR = setting("HandofFreedom")
		if not EN or not inCombat or not USS(SP) then return false end

		for _, debuff in ipairs(HoFDebuff) do
			local member = ni.members.inrangewithdebuff("player", 30, debuff)
			if member and #member > 0 then
				for _, ally in ipairs(member) do
					if ni.unit.hp(ally.guid) < TR then
						ni.spell.delaycast(SP, ally.guid, 0.1)
						return true
					end
				end
			end
		end
		return false
	end,

	["Gift of Naaru"] = function()
		local EN, SP, TR = setting("GiftofNaaru")
		if not EN or not USS(SP) then return false end

		local ally = ni.members.inrangebelow("player", 40, TR)[1]
		if ally and ally:valid(SP, false, true) then
			ni.spell.cast(SP, ally.guid)
			return true
		end
		return false
	end,

	["Holy Shock"] = function()
		local EN, SP, TR = setting("HolyShock")
		if not EN or not USS(SP) then return false end

		local ally = ni.members.inrangebelow("player", 40, TR)[1]
		if ally and ally:valid(SP, false, true) then
			ni.spell.cast(SP, ally.guid)
			return true
		end
		return false
	end,

	["Flash of Light"] = function()
		local EN, SP, TR = setting("FlashofLight")
		if not EN or not USS(SP) then return false end

		if not ni.player.movingfor(0.1) or ni.unit.buff("player", spells.InfusionofLight) then
			local ally = ni.members.inrangebelow("player", 40, TR)[1]
			if ally and ally:valid(SP, false, true) then
				ni.spell.cast(SP, ally.guid)
				return true
			end
		end
		return false
	end,

	["Heal Ally Pet"] = function()
		local EN, SP, TR = setting("HealAllyPet")
		if not EN or not USS(SP) then return false	end

		for i = 1, #ni.members do
			local ally = ni.members[i].unit
			local pet = UnitGUID(ally.."pet")
			local minion = UnitGUID(ally.."minion")
			if pet or minion then
				local tarpet = pet or minion
				if ni.unit.hp(tarpet) < TR and ni.spell.valid(tarpet, SP, false, true, true)
					and (not ni.player.movingfor(0.1) or ni.unit.buff("player", spells.InfusionofLight)) then
					ni.spell.cast(SP, tarpet)
					return true
				end
			end
		end
		return false
	end,

	["Judgement of Wisdom"] = function()
		local EN, SP, TR = setting("JudgementofWisdom")
		if not EN or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 40)
		for i = 1, #enemies do
			local wTarget = enemies[i].guid
			if ni.spell.valid(wTarget, SP, false, true)
				and ni.unit.power("player") < TR
				and not ni.unit.isimmune(wTarget)
				and ni.unit.isplayer(wTarget) then
				ni.spell.cast(SP, wTarget)
				return true
			end
		end
		return false
	end,

	["Cleanse"] = function()
		local EN, SP, TR = setting("Cleanse")
		if not EN or not inCombat or not USS(SP) then return false end

		if ni.unit.power("player") > TR then
			local members = ni.members.sort()
			for i = 1, #members do
				local member = members[i]
				if ni.healing.candispel(member.guid)
					and not member:debuffs("51162||55078||49194||55095")
					and member:valid(SP, false, true) then
					ni.spell.cast(SP, member.guid)
					return true
				end
			end
		end
		return false
	end,

	["Holy Wrath"] = function()
		local EN, SP = setting("HolyWrath")
		if not EN or not inCombat or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 10)
		local CCD = CCDebuff

		for i = 1, #enemies do
			local enemy = enemies[i]
			local targetType = ni.unit.creaturetype(enemy.guid)

			if (targetType == 3 or targetType == 6)
				and ni.unit.los("player", enemy.guid)
				and not ni.unit.debuff(enemy.guid, spells.TurnEvil) then
				for j = 1, #CCD do
					local CC = CCD[j]
					if ni.unit.debuff(enemy.guid, CC) then
						ni.spell.cast(SP)
						return true
					end
				end
			end
		end
		return false
	end,

	["Turn Evil"] = function()
		local EN, SP = setting("TurnEvil")
		if not EN or not inCombat or not USS(SP) then return false end

		local enemies = ni.unit.enemiesinrange("player", 20)
		local CCD = CCDebuff

		for i = 1, #enemies do
			local enemy = enemies[i]
			local targetType = ni.unit.creaturetype(enemy.guid)

			if (targetType == 3 or targetType == 6)
				and ni.unit.los("player", enemy.guid)
				and not ni.unit.debuff(enemy.guid, spells.HolyWrath) then
				for j = 1, #CCD do
					local CC = CCD[j]
					if ni.unit.debuff(enemy.guid, CC) then
						ni.spell.cast(SP)
						return true
					end
				end
			end
		end
		return false
	end,

	["Sacred Shield"] = function()
		local EN, SP = setting("SacredShield")
		if not EN or not USS(SP) then return false end

		if not ni.unit.buff("player", SP) then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Beacon of Light"] = function()
		local EN, SP = setting("BeaconofLight")
		if not EN or not USS(SP) then return false end

		if ni.unit.exists("focus")
			and not ni.unit.buff("focus", SP)
			and ni.spell.valid("focus", SP, false, true, true)
			and (UnitInRaid("focus") or UnitInParty("focus")) then
			ni.spell.cast(SP, "focus")
			return true
		elseif not ni.unit.buff("player", SP) then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Blessing of Kings"] = function()
		local EN, SP = setting("BlessingofKings")
		if not EN or not USS(SP) then return false end

		local hasGreaterBlessing = ni.unit.buff("player", spells.GreaterBlessingofKings)
		local hasBlessing = ni.unit.buff("player", SP)
		if not hasBlessing and not hasGreaterBlessing then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Seal of Wisdom"] = function()
		local EN, SP = setting("SealofWisdom")
		if not EN or not USS(SP) then return false end

		if not ni.unit.buff("player", SP)
			and ni.unit.ispreparation("player") then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,

	["Righteous Fury"] = function()
		local EN, SP = setting("RighteousFury")
		if not EN or not USS(SP) then return false end

		if not ni.unit.buff("player", SP)
			and ni.unit.ispreparation("player") then
			ni.spell.cast(SP, "player")
			return true
		end
		return false
	end,
}

local function OnLoad()
	ni.GUI.AddFrame("HPal", items)
end

local function OnUnLoad()
	ni.GUI.DestroyFrame("HPal")
end

ni.bootstrap.profile("HPal", queue, abilities, OnLoad, OnUnLoad)

else ni.bootstrap.profile("HPal", {"Error"}, {["Error"] = function() ni.vars.profiles.enabled = false; if not wotlk then ni.frames.floatingtext:message("Profile for 3.3.5a") end end}) end 

Lua online compiler

Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.4. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.

Taking inputs (stdin)

OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.

name = io.read("*a")
print ("Hello ", name)

About Lua

Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.

Syntax help

Variables

  • By default all the variables declared are global variables
  • If the variables are explicitly mentioned as local then they are local variables.
  • Lua is a dynamically typed language and hence only the values will have types not the variables.

Examples

-- global variables
a = 10

-- local variables

local x = 30
Value TypeDescription
numberRepresents numbers
stringRepresents text
nilDifferentiates values whether it has data or not
booleanValue can be either true or false
functionRepresents a sub-routine
userdataRepresents arbitary C data
threadRepresents independent threads of execution.
tableCan hold any value except nil

Loops

1. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition)
do
--code
end

2. Repeat-Until:

Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.

repeat
   --code
until( condition )

3. For:

For loop is used to iterate a set of statements based on a condition.

for init,max/min value, increment
do
   --code
end

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.

optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end