My Balance Druid custom Rotation

18 posts Page 1 of 2
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


Hello Everyone,

since i am now at my third Iteration for this script, i decided to update the first message in this post to reflect the current version of my rotation. so here it is, 270 lines of pure awesome :)

Version 4 (2018-09-21): i incorporated Starlord rotation if talent was selected
  1. function(_, timeShift, currentSpell, gcd, talents)
  2.  
  3.   function(_, timeShift, currentSpell, gcd, talents)
  4.  
  5.     if _GadgetsanLibrary == nil or _GadgetsanLibrary.libVersion ~= "Moonkin4.0" then
  6.         _GadgetsanLibrary = {};
  7.         _GadgetsanLibrary.libVersion = "Moonkin4.0";
  8.  
  9.     --CACHEs setup
  10.         _GadgetsanLibrary.hitCountCache = {};
  11.         _GadgetsanLibrary.movingCache = nil;
  12.         _GadgetsanLibrary.hasAuraCache = {};
  13.         _GadgetsanLibrary.meAuraCountCache = {};
  14.  
  15.         --a function that should be called when a new rotation has started so it can do some wuick housekeeping
  16.         _GadgetsanLibrary.newRotation = function()            
  17.             _GadgetsanLibrary.hitCountCache = {};
  18.             _GadgetsanLibrary.movingCache = nil;
  19.             _GadgetsanLibrary.hasAuraCache = {};
  20.             _GadgetsanLibrary.meAuraCountCache = {};
  21.         end
  22.  
  23.  
  24.     --HELPER FUNCTIONS
  25.  
  26.         --for debugging purposes (i turn this off if i want to output some text)
  27.         _GadgetsanLibrary.DebugToggle = false;
  28.         _GadgetsanLibrary.debug = function(text)
  29.             if(_GadgetsanLibrary.DebugToggle) then print(text);end;
  30.         end
  31.  
  32.         --caching the value of TargetsInRange so i don't make unnecesary calls
  33.         _GadgetsanLibrary.hitCount = function(spellId)
  34.             if _GadgetsanLibrary.hitCountCache[spellId] == nil then
  35.                 _GadgetsanLibrary.hitCountCache[spellId] = MaxDps:TargetsInRange(spellId);
  36.             end
  37.             return _GadgetsanLibrary.hitCountCache[spellId];
  38.         end
  39.  
  40.         --caching the value of TargetAura so i don't make unnecesary calls
  41.         _GadgetsanLibrary.hasAura = function(spellId, shift)
  42.             if _GadgetsanLibrary.hasAuraCache[spellId] == nil then
  43.                 _GadgetsanLibrary.hasAuraCache[spellId] = MaxDps:TargetAura(spellId, shift);
  44.             end
  45.             return _GadgetsanLibrary.hasAuraCache[spellId];
  46.         end
  47.  
  48.         --caching the value of Aura so i don't make unnecesary calls
  49.         _GadgetsanLibrary.meAuraCount = function(spellId)
  50.             if _GadgetsanLibrary.meAuraCountCache[spellId] == nil then
  51.                 local trueOrFalse, count = MaxDps:Aura(spellId, timeShift);
  52.                 _GadgetsanLibrary.meAuraCountCache[spellId] = count;
  53.             end
  54.             return _GadgetsanLibrary.meAuraCountCache[spellId];
  55.         end
  56.  
  57.  
  58.         --function to test if character is moving (and caching the result)
  59.         _GadgetsanLibrary.isMoving = function()
  60.             if _GadgetsanLibrary.movingCache ~= nil then
  61.                 return _GadgetsanLibrary.movingCache
  62.             end
  63.             local currentSpeed, runSpeed, flightSpeed, swimSpeed = GetUnitSpeed("Player");
  64.             if currentSpeed == 0 then
  65.                 _GadgetsanLibrary.movingCache = false;
  66.             else
  67.                 _GadgetsanLibrary.movingCache = true;
  68.             end
  69.             return _GadgetsanLibrary.movingCache;
  70.         end
  71.        
  72.     --SKILLS
  73.         _GadgetsanLibrary.Moonfire = 8921;
  74.         _GadgetsanLibrary.Sunfire = 93402;
  75.         _GadgetsanLibrary.Starsurge = 78674;
  76.         _GadgetsanLibrary.LunarEmpowerment = 164547;
  77.         _GadgetsanLibrary.SolarEmpowerment = 164545;
  78.         _GadgetsanLibrary.LunarStrike = 194153;
  79.         _GadgetsanLibrary.SolarWrath = 190984;
  80.         _GadgetsanLibrary.NewMoon = 274281;
  81.         _GadgetsanLibrary.HalfMoon = 274282;
  82.         _GadgetsanLibrary.FullMoon = 274283;
  83.         _GadgetsanLibrary.CelestialAlignment = 194223;
  84.         _GadgetsanLibrary.IncarnationChosenofElune = 102560;
  85.         _GadgetsanLibrary.StellarFlare = 202347;
  86.         _GadgetsanLibrary.Starfall = 191034;
  87.         _GadgetsanLibrary.MasteryStarlight = 77492;
  88.         _GadgetsanLibrary.StellarEmpowerment = 197637;
  89.         _GadgetsanLibrary.Heroism = 32182;
  90.         _GadgetsanLibrary.Bloodlust = 2825;
  91.         _GadgetsanLibrary.Berserking = 26297;
  92.         _GadgetsanLibrary.ForceofNature = 205636;
  93.         _GadgetsanLibrary.WarriorofElune = 202425;
  94.         _GadgetsanLibrary.AstralCommunion = 202359;
  95.         _GadgetsanLibrary.BlessingoftheAncients = 202360;
  96.         _GadgetsanLibrary.BlessingofElune = 202737;
  97.         _GadgetsanLibrary.FuryofElune = 202770;
  98.         _GadgetsanLibrary.MoonkinMoonfire = 164812;
  99.         _GadgetsanLibrary.MoonkinSunfire = 164815;
  100.         _GadgetsanLibrary.StarLord = 202345;
  101.         _GadgetsanLibrary.StarLordAura = 279709;
  102.  
  103.  
  104.     end
  105.  
  106.     local GL = _GadgetsanLibrary;
  107.     GL.newRotation();
  108.  
  109. --Links
  110.     --http://maxdps.net/viewtopic.php?f=6&t=5&sid=134ea7dae4e3b8092032fb116836c364
  111.  
  112.  
  113. -------------------------------VARIABLES--------------------------------------------
  114.     local AP = UnitPower('player', Enum.PowerType.LunarPower);
  115.     --debug(string.format("AstralPower: %s", AP));
  116.     --Note: we can cast 30% before the end because of pandemic dotting
  117.     local solarE, solarCharges = MaxDps:Aura(GL.SolarEmpowerment, timeShift);
  118.     local lunarE, lunarCharges = MaxDps:Aura(GL.LunarEmpowerment, timeShift);
  119.    
  120.     local currentMoonCharges = 0;
  121.     if talents[GL.NewMoon] then
  122.         currentMoon = GL.NewMoon;
  123.         if MaxDps:FindSpell(GL.NewMoon) ~= nil then
  124.             currentMoon = GL.NewMoon;
  125.         end
  126.         if MaxDps:FindSpell(GL.HalfMoon) ~= nil then
  127.             currentMoon = GL.HalfMoon;
  128.         end
  129.         if MaxDps:FindSpell(GL.FullMoon) ~= nil then
  130.             currentMoon = GL.FullMoon;
  131.         end
  132.         --nextMoon is necessary in the case where we are currently casting
  133.         nextMoon = currentMoon;
  134.         local cd, charges, maxCharges = MaxDps:SpellCharges(currentMoon, timeShift);
  135.         currentMoonCharges = charges;
  136.     end
  137.  
  138.     --we look after the current casting to see in advance if we will have enough AP
  139.     if currentSpell == GL.SolarWrath then
  140.         AP = AP + 8;
  141.         solarCharges = solarCharges - 1;
  142.     elseif currentSpell == GL.LunarStrike then
  143.         AP = AP + 12;
  144.         lunarCharges = lunarCharges - 1;
  145.     elseif currentSpell == GL.NewMoon then
  146.         AP = AP + 10;
  147.         currentMoonCharges = currentMoonCharges-1;
  148.         nextMoon = GL.HalfMoon
  149.     elseif currentSpell == GL.HalfMoon then
  150.         AP = AP + 20;
  151.         currentMoonCharges = currentMoonCharges-1;
  152.         nextMoon = GL.FullMoon
  153.     elseif currentSpell == GL.FullMoon then
  154.         AP = AP + 40;
  155.         currentMoonCharges = currentMoonCharges-1;
  156.         nextMoon = GL.NewMoon
  157.     end
  158.     --i once ended up with negative solar charges...
  159.     if lunarCharges < 0 then lunarCharges = 0 end
  160.     if solarCharges < 0 then solarCharges = 0 end
  161.     --GL.debug(string.format("lunarCharges: %s solarCharges: %s ", lunarCharges, solarCharges));
  162.    
  163.  
  164. -------------------------------COOLDOWNS--------------------------------------------
  165.     if talents[GL.IncarnationChosenofElune] then
  166.         MaxDps:GlowCooldown(GL.IncarnationChosenofElune, MaxDps:SpellAvailable(GL.IncarnationChosenofElune, timeShift));
  167.     else
  168.         MaxDps:GlowCooldown(GL.CelestialAlignment, MaxDps:SpellAvailable(GL.CelestialAlignment, timeShift));
  169.     end
  170.  
  171.     if talents[GL.WarriorofElune] then
  172.         MaxDps:GlowCooldown(GL.WarriorofElune, MaxDps:SpellAvailable(GL.WarriorofElune, timeShift)
  173.             and not MaxDps:Aura(GL.WarriorofElune));
  174.     end
  175.    
  176. -------------------------------PRIORITY--------------------------------------------
  177. --6K DPS
  178. --DOTS so they are always applied
  179.     if not GL.hasAura(GL.MoonkinMoonfire, timeShift + 5) then      
  180.         GL.debug("Target does not have Moonfire!");
  181.         return GL.Moonfire;
  182.     end
  183.  
  184.     if not GL.hasAura(GL.MoonkinSunfire, timeShift + 4) then
  185.         GL.debug("Target does not have Sunfire");
  186.         return GL.Sunfire;
  187.     end    
  188.  
  189.     if talents[GL.StarLord] then
  190.         if(GL.meAuraCount(GL.StarLordAura) == 0) then
  191.             --gathering AP before starting to cast Starsurge    
  192.             if AP > 90 then
  193.                 return GL.Starsurge;
  194.             end
  195.         end
  196.  
  197.         if(GL.meAuraCount(GL.StarLordAura) > 0 and GL.meAuraCount(GL.StarLordAura) < 3) then
  198.             --gathering AP before starting to cast Starsurge      
  199.             if AP > 40 then
  200.                 return GL.Starsurge;
  201.             end
  202.         end
  203.     end
  204.  
  205. --if i'm moving, i want to instant cast only
  206.     if GL.isMoving() then
  207.         GL.debug("Currently Moving");
  208.         if AP >= 40 and GL.meAuraCount(GL.StarLordAura) == 0 then
  209.             return GL.Starsurge;
  210.         end
  211.  
  212.         --if i have warrior of elune, i wanna spend my StellarFlare instant casts        
  213.         if GL.meAuraCount(GL.WarriorofElune) > 0 then
  214.             return GL.LunarStrike
  215.         end
  216.  
  217.         -- is i'm still moving, i wanna cast Warrior of Elune
  218.         if talents[GL.WarriorofElune] and MaxDps:SpellAvailable(GL.WarriorofElune, timeShift) then
  219.             return GL.WarriorofElune
  220.         end
  221.  
  222.         --if nothing else, i can cast this while moving
  223.         return GL.Sunfire;
  224.     end
  225.  
  226. --Stellar Flare (i don't use it...)
  227.     if talents[GL.StellarFlare] and not GL.hasAura(GL.StellarFlare, timeShift + 5) and currentSpell ~= GL.StellarFlare then
  228.         return GL.StellarFlare;
  229.     end
  230.  
  231.    
  232. --New/Half/Full Moon, as suggested by HamOfMoose » 30 Aug 2018, 21:20. Requires New Moon Talent
  233.     if talents[GL.NewMoon] then        
  234.         GL.debug("New Moon Management");
  235.         local isAvailable, cd = MaxDps:SpellAvailable(currentMoon, timeShift)
  236.         --GL.debug(string.format("Found %s stakcs for moon thing", currentMoonCharges));
  237.         if currentMoonCharges > 1 and isAvailable then
  238.             --we look at the current moon (or the next if we are currently casting in order to decide if we cast it or not)
  239.             if(nextMoon == GL.NewMoon and AP < 90) or (nextMoon == GL.HalfMoon and AP < 80) or (nextMoon == GL.FullMoon and AP < 60) then
  240.                 return currentMoon;
  241.             end
  242.         end
  243.     end
  244.    
  245. --if i'm maxed on enhancement, i priorise this
  246.     if(lunarCharges > 2 or solarCharges > 2) then
  247.         GL.debug("Almost at max enhancement");
  248.         if lunarCharges > solarCharges then
  249.             return GL.LunarStrike
  250.         else
  251.             return GL.SolarWrath
  252.         end
  253.     end
  254.    
  255. --StarSurge or StarFall to spend AP (LunarStrike and Starfall have same range)
  256.     if(GL.hitCount(GL.LunarStrike) > 3) then
  257.         if AP > 90 then
  258.             GL.debug("enough AP to cast Starfall!");
  259.             return GL.Starfall;
  260.         end
  261.     else
  262.         if AP > 80 and not talents[GL.StarLord] then
  263.             GL.debug("enough AP to cast Starsurge!");
  264.             return GL.Starsurge;
  265.         end
  266.     end
  267.  
  268. --Empowerments so i use them
  269.     if(lunarCharges > 0 or solarCharges > 0) then
  270.         GL.debug("casting remaining enhancements");
  271.         if lunarCharges > solarCharges then
  272.             return GL.LunarStrike
  273.         else
  274.             return GL.SolarWrath
  275.         end
  276.     end
  277.  
  278. --SLunarStrike to Get AP if more than 1 in range
  279.     if(GL.hitCount(GL.LunarStrike) > 1) then        
  280.         GL.debug("casting Lunarstrike to raise AP");
  281.         return GL.LunarStrike;
  282.     else
  283.         GL.debug("casting Solar Wrath to raise AP");
  284.         return GL.SolarWrath;
  285.     end
  286.  
  287.     GL.debug("I've got nothing to do!");
  288.     return GL.LunarStrike;
  289. end
Last edited by Gadgetsan on 21 Sep 2018, 23:39, edited 2 times in total.
Kaminaris
Site Admin
Posts: 297
Joined: 25 Jun 2017, 03:45


Nice, anyways you dont really need to check if solar charges are minus once since neither 0 nor -1 is equal or greater 1.
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


ahah good point but it's more or less for debugging purpose.
HamOfMoose
Posts: 2
Joined: 31 Aug 2018, 01:16


I like it have been using it for a while but is there a way you could add in New moon if < 10 from max AP, Half moon if < 20 max ap, and full moon if < 40 to max AP.

Ive been running a few sims and that spell is pushing some DPS in the sim.
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


i can certainly make this modification however, for some reason this script no longer works, the Sunfire DOT has stopped working, i'm working of fixing this first
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


Here, i included the New/Half/Full Moon in the script
However, i'm curious about the efficiency of this talent, what do you use to test?
Code: Select all
function(_, timeShift, currentSpell, gcd, talents)
    local DEBUG = false;
--Links
    --http://maxdps.net/viewtopic.php?f=6&t=5&sid=134ea7dae4e3b8092032fb116836c364

--SKILLS
	local _Moonfire = 8921;
	local _Sunfire = 93402;
	local _Starsurge = 78674;
	local _LunarEmpowerment = 164547;
	local _SolarEmpowerment = 164545;
	local _LunarStrike = 194153;
	local _SolarWrath = 190984;
	local _NewMoon = 274281;
	local _HalfMoon = 274282;
	local _FullMoon = 274283;
	local _CelestialAlignment = 194223;
	local _IncarnationChosenofElune = 102560;
	local _StellarFlare = 202347;
	local _Starfall = 191034;
	local _MasteryStarlight = 77492;
	local _StellarEmpowerment = 197637;
	local _Heroism = 32182;
	local _Bloodlust = 2825;
	local _Berserking = 26297;
	local _ForceofNature = 205636;
	local _WarriorofElune = 202425;
	local _AstralCommunion = 202359;
	local _BlessingoftheAncients = 202360;
	local _BlessingofElune = 202737;
	local _FuryofElune = 202770;
	local _MoonkinMoonfire = 164812;
	local _MoonkinSunfire = 164815;
    local _WarriorofEluneAura = 202425;

    local debug = function(text)
        if(DEBUG) then print(text);end;
    end

-------------------------------VARIABLES--------------------------------------------
	local AP = UnitPower('player', Enum.PowerType.LunarPower);
    --debug(string.format("AstralPower: %s", AP));
    --Note: we can cast 30% before the end because of pandemic dotting
	local targetHasMoonfireDot = MaxDps:TargetAura(_MoonkinMoonfire, timeShift + 5);
	local targetHasSunfireDot = MaxDps:TargetAura(_MoonkinSunfire, timeShift + 4);
	local targetHasStellarFlareDot = MaxDps:TargetAura(_StellarFlare, timeShift + 5);

	local solarE, solarCharges = MaxDps:Aura(_SolarEmpowerment, timeShift);
	local lunarE, lunarCharges = MaxDps:Aura(_LunarEmpowerment, timeShift);
	
	if talents[_NewMoon] then
		currentMoon = _NewMoon;
		if MaxDps:FindSpell(_NewMoon) ~= nil then
			currentMoon = _NewMoon;
		end
		if MaxDps:FindSpell(_HalfMoon) ~= nil then
			currentMoon = _HalfMoon;
		end
		if MaxDps:FindSpell(_FullMoon) ~= nil then
			currentMoon = _FullMoon;
		end
		--nextMoon is necessary in the case where we are currently casting
		nextMoon = currentMoon;
		cd, currentMoonCharges, maxCharges = MaxDps:SpellCharges(currentMoon, timeShift);
	end

    --we look after the current casting to see in advance if we will have enough AP
	if currentSpell == _SolarWrath then
		AP = AP + 8;
		solarCharges = solarCharges - 1;
	elseif currentSpell == _LunarStrike then
		AP = AP + 12;
		lunarCharges = lunarCharges - 1;
	elseif currentSpell == _NewMoon then
		AP = AP + 10;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _HalfMoon
	elseif currentSpell == _HalfMoon then
		AP = AP + 20;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _FullMoon
	elseif currentSpell == _FullMoon then
		AP = AP + 40;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _NewMoon
    end
    --i once ended up with negative solar charges...
	if lunarCharges < 0 then lunarCharges = 0 end
    if solarCharges < 0 then solarCharges = 0 end
	--debug(string.format("lunarCharges: %s solarCharges: %s ", lunarCharges, solarCharges));
	

-------------------------------COOLDOWNS--------------------------------------------
	if talents[_IncarnationChosenofElune] then
		MaxDps:GlowCooldown(_IncarnationChosenofElune, MaxDps:SpellAvailable(_IncarnationChosenofElune, timeShift));
	else
		MaxDps:GlowCooldown(_CelestialAlignment, MaxDps:SpellAvailable(_CelestialAlignment, timeShift));
	end

	if talents[_WarriorofElune] then
		MaxDps:GlowCooldown(_WarriorofElune, MaxDps:SpellAvailable(_WarriorofElune, timeShift)
			and not MaxDps:Aura(_WarriorofEluneAura));
    end
    
-------------------------------PRIORITY--------------------------------------------

--DOTS so they are always applied
	if not targetHasMoonfireDot then		
		--debug("Target does not have Moonfire!");
		return _Moonfire;
	end

	if not targetHasSunfireDot then
		--debug("Target does not have Sunfire!");
		return _Sunfire;
    end    

--Stellar Flare (i don't use it...)
	if talents[_StellarFlare] and not targetHasStellarFlareDot and currentSpell ~= _StellarFlare then
		return _StellarFlare;
	end

	
--New/Half/Full Moon, as suggested by HamOfMoose » 30 Aug 2018, 21:20. Requires New Moon Talent
	if talents[_NewMoon] then
		local isAvailable, cd = MaxDps:SpellAvailable(currentMoon, timeShift)
		--debug(string.format("Found %s stakcs for moon thing", currentMoonCharges));
		if currentMoonCharges > 1 and isAvailable then
			--we look at the current moon (or the next if we are currently casting in order to decide if we cast it or not)
			if(nextMoon == _NewMoon and AP < 90) or (nextMoon == _HalfMoon and AP < 80) or (nextMoon == _FullMoon and AP < 60) then
				return currentMoon;
			end
		end
	end

--if i have a lot of AP, i want to be casting Star Surge or Starfall in priority
	if AP>80 then
		if(MaxDps:TargetsInRange(_LunarStrike) > 3) then
			return _Starfall;
		else
			return _Starsurge;
		end
	end


--Empowerments so i use spend them
	if(lunarCharges > 0 or solarCharges > 0) then
		if lunarCharges > solarCharges then
			return _LunarStrike
		else
			return _SolarWrath
		end
    end
    
--StarSurge or StarFall to spend AP (LunarStrike and Starfall have same range)
    if(MaxDps:TargetsInRange(_LunarStrike) > 3) then
        if AP > 50 then
            return _Starfall;
        end
    else
        if AP > 40 then
            return _Starsurge;
        end
    end

--SLunarStrike to Get AP if more than 1 in range
	if(MaxDps:TargetsInRange(_LunarStrike) > 1) then
		return _LunarStrike;
	else
		return _SolarWrath;
	end

	return _LunarStrike;
end

Kaminaris
Site Admin
Posts: 297
Joined: 25 Jun 2017, 03:45


You DONT WANT TO execute MaxDps:TargetsInRange more than once in entire rotation function. Trust me
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


Okay, may i know why? is it because it's particularly resource intensive?

in any case, here is the updated version (with the cached MaxDps:TargetsInRange result):
Code: Select all
function(_, timeShift, currentSpell, gcd, talents)
    local DEBUG = false;
--Links
    --http://maxdps.net/viewtopic.php?f=6&t=5&sid=134ea7dae4e3b8092032fb116836c364

--SKILLS
	local _Moonfire = 8921;
	local _Sunfire = 93402;
	local _Starsurge = 78674;
	local _LunarEmpowerment = 164547;
	local _SolarEmpowerment = 164545;
	local _LunarStrike = 194153;
	local _SolarWrath = 190984;
	local _NewMoon = 274281;
	local _HalfMoon = 274282;
	local _FullMoon = 274283;
	local _CelestialAlignment = 194223;
	local _IncarnationChosenofElune = 102560;
	local _StellarFlare = 202347;
	local _Starfall = 191034;
	local _MasteryStarlight = 77492;
	local _StellarEmpowerment = 197637;
	local _Heroism = 32182;
	local _Bloodlust = 2825;
	local _Berserking = 26297;
	local _ForceofNature = 205636;
	local _WarriorofElune = 202425;
	local _AstralCommunion = 202359;
	local _BlessingoftheAncients = 202360;
	local _BlessingofElune = 202737;
	local _FuryofElune = 202770;
	local _MoonkinMoonfire = 164812;
	local _MoonkinSunfire = 164815;
    local _WarriorofEluneAura = 202425;

    local debug = function(text)
        if(DEBUG) then print(text);end;
    end

-------------------------------VARIABLES--------------------------------------------
	local AP = UnitPower('player', Enum.PowerType.LunarPower);
    --debug(string.format("AstralPower: %s", AP));
    --Note: we can cast 30% before the end because of pandemic dotting
	local targetHasMoonfireDot = MaxDps:TargetAura(_MoonkinMoonfire, timeShift + 5);
	local targetHasSunfireDot = MaxDps:TargetAura(_MoonkinSunfire, timeShift + 4);
	local targetHasStellarFlareDot = MaxDps:TargetAura(_StellarFlare, timeShift + 5);

	local solarE, solarCharges = MaxDps:Aura(_SolarEmpowerment, timeShift);
	local lunarE, lunarCharges = MaxDps:Aura(_LunarEmpowerment, timeShift);
	
	if talents[_NewMoon] then
		currentMoon = _NewMoon;
		if MaxDps:FindSpell(_NewMoon) ~= nil then
			currentMoon = _NewMoon;
		end
		if MaxDps:FindSpell(_HalfMoon) ~= nil then
			currentMoon = _HalfMoon;
		end
		if MaxDps:FindSpell(_FullMoon) ~= nil then
			currentMoon = _FullMoon;
		end
		--nextMoon is necessary in the case where we are currently casting
		nextMoon = currentMoon;
		cd, currentMoonCharges, maxCharges = MaxDps:SpellCharges(currentMoon, timeShift);
	end

    --we look after the current casting to see in advance if we will have enough AP
	if currentSpell == _SolarWrath then
		AP = AP + 8;
		solarCharges = solarCharges - 1;
	elseif currentSpell == _LunarStrike then
		AP = AP + 12;
		lunarCharges = lunarCharges - 1;
	elseif currentSpell == _NewMoon then
		AP = AP + 10;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _HalfMoon
	elseif currentSpell == _HalfMoon then
		AP = AP + 20;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _FullMoon
	elseif currentSpell == _FullMoon then
		AP = AP + 40;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _NewMoon
    end
    --i once ended up with negative solar charges...
	if lunarCharges < 0 then lunarCharges = 0 end
    if solarCharges < 0 then solarCharges = 0 end
	--debug(string.format("lunarCharges: %s solarCharges: %s ", lunarCharges, solarCharges));

    local lunarStrikeTargetInRangeCount= MaxDps:TargetsInRange(_LunarStrike);
	

-------------------------------COOLDOWNS--------------------------------------------
	if talents[_IncarnationChosenofElune] then
		MaxDps:GlowCooldown(_IncarnationChosenofElune, MaxDps:SpellAvailable(_IncarnationChosenofElune, timeShift));
	else
		MaxDps:GlowCooldown(_CelestialAlignment, MaxDps:SpellAvailable(_CelestialAlignment, timeShift));
	end

	if talents[_WarriorofElune] then
		MaxDps:GlowCooldown(_WarriorofElune, MaxDps:SpellAvailable(_WarriorofElune, timeShift)
			and not MaxDps:Aura(_WarriorofEluneAura));
    end
    
-------------------------------PRIORITY--------------------------------------------

--DOTS so they are always applied
	if not targetHasMoonfireDot then		
		--debug("Target does not have Moonfire!");
		return _Moonfire;
	end

	if not targetHasSunfireDot then
		--debug("Target does not have Sunfire!");
		return _Sunfire;
    end    

--Stellar Flare (i don't use it...)
	if talents[_StellarFlare] and not targetHasStellarFlareDot and currentSpell ~= _StellarFlare then
		return _StellarFlare;
	end

	
--New/Half/Full Moon, as suggested by HamOfMoose » 30 Aug 2018, 21:20. Requires New Moon Talent
	if talents[_NewMoon] then
		local isAvailable, cd = MaxDps:SpellAvailable(currentMoon, timeShift)
		--debug(string.format("Found %s stakcs for moon thing", currentMoonCharges));
		if currentMoonCharges > 1 and isAvailable then
			--we look at the current moon (or the next if we are currently casting in order to decide if we cast it or not)
			if(nextMoon == _NewMoon and AP < 90) or (nextMoon == _HalfMoon and AP < 80) or (nextMoon == _FullMoon and AP < 60) then
				return currentMoon;
			end
		end
	end

--if i have a lot of AP, i want to be casting Star Surge or Starfall in priority
	if AP>80 then
		if(lunarStrikeTargetInRangeCount > 3) then
			return _Starfall;
		else
			return _Starsurge;
		end
	end


--Empowerments so i use spend them
	if(lunarCharges > 0 or solarCharges > 0) then
		if lunarCharges > solarCharges then
			return _LunarStrike
		else
			return _SolarWrath
		end
    end
    
--StarSurge or StarFall to spend AP (LunarStrike and Starfall have same range)
    if(lunarStrikeTargetInRangeCount > 3) then
        if AP > 50 then
            return _Starfall;
        end
    else
        if AP > 40 then
            return _Starsurge;
        end
    end

--SLunarStrike to Get AP if more than 1 in range
	if(lunarStrikeTargetInRangeCount > 1) then
		return _LunarStrike;
	else
		return _SolarWrath;
	end

	return _LunarStrike;
end
Kaminaris
Site Admin
Posts: 297
Joined: 25 Jun 2017, 03:45


Because its really slow. An another tip. You want to call it right before the first "IF" you are going to check it. Because in most cases code will never get there anyway and you are trying to call it at the begining.

This function needs to be as fast as possible unless you want to get FPS losses.
Gadgetsan
Posts: 12
Joined: 13 Aug 2018, 19:33


Better idea yet, caching the result (you should do this in the addon code!) here is the new version
Code: Select all
function(_, timeShift, currentSpell, gcd, talents)
    local DEBUG = false;
--Links
    --http://maxdps.net/viewtopic.php?f=6&t=5&sid=134ea7dae4e3b8092032fb116836c364

--SKILLS
	local _Moonfire = 8921;
	local _Sunfire = 93402;
	local _Starsurge = 78674;
	local _LunarEmpowerment = 164547;
	local _SolarEmpowerment = 164545;
	local _LunarStrike = 194153;
	local _SolarWrath = 190984;
	local _NewMoon = 274281;
	local _HalfMoon = 274282;
	local _FullMoon = 274283;
	local _CelestialAlignment = 194223;
	local _IncarnationChosenofElune = 102560;
	local _StellarFlare = 202347;
	local _Starfall = 191034;
	local _MasteryStarlight = 77492;
	local _StellarEmpowerment = 197637;
	local _Heroism = 32182;
	local _Bloodlust = 2825;
	local _Berserking = 26297;
	local _ForceofNature = 205636;
	local _WarriorofElune = 202425;
	local _AstralCommunion = 202359;
	local _BlessingoftheAncients = 202360;
	local _BlessingofElune = 202737;
	local _FuryofElune = 202770;
	local _MoonkinMoonfire = 164812;
	local _MoonkinSunfire = 164815;
    local _WarriorofEluneAura = 202425;

    local debug = function(text)
        if(DEBUG) then print(text);end;
	end

	--caching the value of TargetsInRange so i don't make unnecesary calls
	local targetsInRangeCacheList = {};
	local targetsInRangeCache = function(spellId)
		if targetsInRangeCacheList[spellId] == nil then
			targetsInRangeCacheList[spellId] = MaxDps:TargetsInRange(spellId);
		end
		return targetsInRangeCacheList[spellId];
	end

-------------------------------VARIABLES--------------------------------------------
	local AP = UnitPower('player', Enum.PowerType.LunarPower);
    --debug(string.format("AstralPower: %s", AP));
    --Note: we can cast 30% before the end because of pandemic dotting
	local targetHasMoonfireDot = MaxDps:TargetAura(_MoonkinMoonfire, timeShift + 5);
	local targetHasSunfireDot = MaxDps:TargetAura(_MoonkinSunfire, timeShift + 4);
	local targetHasStellarFlareDot = MaxDps:TargetAura(_StellarFlare, timeShift + 5);

	local solarE, solarCharges = MaxDps:Aura(_SolarEmpowerment, timeShift);
	local lunarE, lunarCharges = MaxDps:Aura(_LunarEmpowerment, timeShift);
	
	if talents[_NewMoon] then
		currentMoon = _NewMoon;
		if MaxDps:FindSpell(_NewMoon) ~= nil then
			currentMoon = _NewMoon;
		end
		if MaxDps:FindSpell(_HalfMoon) ~= nil then
			currentMoon = _HalfMoon;
		end
		if MaxDps:FindSpell(_FullMoon) ~= nil then
			currentMoon = _FullMoon;
		end
		--nextMoon is necessary in the case where we are currently casting
		nextMoon = currentMoon;
		cd, currentMoonCharges, maxCharges = MaxDps:SpellCharges(currentMoon, timeShift);
	end

    --we look after the current casting to see in advance if we will have enough AP
	if currentSpell == _SolarWrath then
		AP = AP + 8;
		solarCharges = solarCharges - 1;
	elseif currentSpell == _LunarStrike then
		AP = AP + 12;
		lunarCharges = lunarCharges - 1;
	elseif currentSpell == _NewMoon then
		AP = AP + 10;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _HalfMoon
	elseif currentSpell == _HalfMoon then
		AP = AP + 20;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _FullMoon
	elseif currentSpell == _FullMoon then
		AP = AP + 40;
		currentMoonCharges = currentMoonCharges-1;
		nextMoon = _NewMoon
    end
    --i once ended up with negative solar charges...
	if lunarCharges < 0 then lunarCharges = 0 end
    if solarCharges < 0 then solarCharges = 0 end
	--debug(string.format("lunarCharges: %s solarCharges: %s ", lunarCharges, solarCharges));
	

-------------------------------COOLDOWNS--------------------------------------------
	if talents[_IncarnationChosenofElune] then
		MaxDps:GlowCooldown(_IncarnationChosenofElune, MaxDps:SpellAvailable(_IncarnationChosenofElune, timeShift));
	else
		MaxDps:GlowCooldown(_CelestialAlignment, MaxDps:SpellAvailable(_CelestialAlignment, timeShift));
	end

	if talents[_WarriorofElune] then
		MaxDps:GlowCooldown(_WarriorofElune, MaxDps:SpellAvailable(_WarriorofElune, timeShift)
			and not MaxDps:Aura(_WarriorofEluneAura));
    end
    
-------------------------------PRIORITY--------------------------------------------

--DOTS so they are always applied
	if not targetHasMoonfireDot then		
		--debug("Target does not have Moonfire!");
		return _Moonfire;
	end

	if not targetHasSunfireDot then
		--debug("Target does not have Sunfire!");
		return _Sunfire;
    end    

--Stellar Flare (i don't use it...)
	if talents[_StellarFlare] and not targetHasStellarFlareDot and currentSpell ~= _StellarFlare then
		return _StellarFlare;
	end

	
--New/Half/Full Moon, as suggested by HamOfMoose » 30 Aug 2018, 21:20. Requires New Moon Talent
	if talents[_NewMoon] then
		local isAvailable, cd = MaxDps:SpellAvailable(currentMoon, timeShift)
		--debug(string.format("Found %s stakcs for moon thing", currentMoonCharges));
		if currentMoonCharges > 1 and isAvailable then
			--we look at the current moon (or the next if we are currently casting in order to decide if we cast it or not)
			if(nextMoon == _NewMoon and AP < 90) or (nextMoon == _HalfMoon and AP < 80) or (nextMoon == _FullMoon and AP < 60) then
				return currentMoon;
			end
		end
	end

--if i have a lot of AP, i want to be casting Star Surge or Starfall in priority
	if AP>80 then
		if(targetsInRangeCache(_LunarStrike) > 3) then
			return _Starfall;
		else
			return _Starsurge;
		end
	end


--Empowerments so i use spend them
	if(lunarCharges > 0 or solarCharges > 0) then
		if lunarCharges > solarCharges then
			return _LunarStrike
		else
			return _SolarWrath
		end
    end
    
--StarSurge or StarFall to spend AP (LunarStrike and Starfall have same range)
    if(targetsInRangeCache(_LunarStrike) > 3) then
        if AP > 50 then
            return _Starfall;
        end
    else
        if AP > 40 then
            return _Starsurge;
        end
    end

--SLunarStrike to Get AP if more than 1 in range
	if(targetsInRangeCache(_LunarStrike) > 1) then
		return _LunarStrike;
	else
		return _SolarWrath;
	end

	return _LunarStrike;
end
18 posts Page 1 of 2
drogie łóżka stolik kawowy stół dębowy rozkładany