I want to start contributing here sharing my own bard script, it currently works fine, just use AutoChain from Aionscript Cheating Interface!
Changelog:
- Added charged spells, with range check
- Added back return false;
- Added back Disharmony
- Clean Up a bit the code
- Add Wind Harmony buff check to increase dmg
To Do:
- Add option to turn off dot usage after 80% to save mana for grinding
Add in settings
Code: Select all
-- Songweaver
self.Songweaver = {
-- Indicates whether or not attacking is allowed. Songweaver version to allow following and such.
AllowAttack = true,
-- Indicates whether or not approaching a target is allowed. Auto approach must be enabled for this to work.
AllowApproach = true,
-- Indicates whether or not buffing force members is allowed. Disable this if you want to run as an assisting script.
AllowBuff = true,
-- Indicates whether or not sleeping multiple attackers is allowed.
AllowSleep = false,
-- Indicates whether or not healing is allowed. Disable this if you want to run as an assisting script.
AllowHealing = true,
-- Indicates whether or not mana healing is allowed. Disable this if you want to run as an assisting script.
AllowHealingMana = true
};
Code: Select all
--[[
--------------------------------------------------
Copyright (C) 2017 Locatelli
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
--------------------------------------------------
]]--
--- (Private Function) Checks the healing requirements for the provided entity.
--
-- @param Entity Contains the entity to perform healing on.
-- @param double Contains the
-- @return bool
function _CheckHeal( Entity )
-- Retrieve the range of the entity compared to my own character position.
local Range = Player:GetPosition():DistanceToPosition( Entity:GetPosition());
local EntityState = Entity:GetState();
-- Check if this routine is allowed to be ran under the current circumstances.
if Entity:IsDead() or ( not Settings.Songweaver.AllowApproach and Range > 23 ) then
return true;
end
-- Check if the entity requires healing and perform the correct healing routine.
if Entity:GetHealth() < 80 and ( Settings.Songweaver.AllowApproach or Range <= 23 ) then
-- Retrieve the local target for certain checks.
-- local Target = EntityList:GetEntity( Player:GetTargetID());
--Complete the Chain
if Entity:GetID() == Player:GetID() and Settings.Songweaver.AllowAttack then
if Entity:GetHealth() < 90 and Helper:CheckAvailable( "Melody of Joy" ) then
Helper:CheckExecute ( "Melody of Joy", Entity )
return false;
elseif Entity:GetHealth() < 90 and Helper:CheckAvailable( "Soft Echo" ) then
Helper:CheckExecute ( "Soft Echo", Entity )
return false;
elseif Entity:GetHealth() < 90 and Helper:CheckAvailable( "Mild Echo" ) then
Helper:CheckExecute ( "Mild Echo", Entity )
return false;
end
end
-- Change the healing routine if I'm healing myself when allowed to attack.
if Entity:GetID() == Player:GetID() and Settings.Songweaver.AllowAttack then --and Target ~= nil and not Target:IsDead() then
if Entity:GetHealth() < 50 and Helper:CheckAvailable( "Gentle Echo" ) then
Helper:CheckExecute( "Gentle Echo", Entity );
return false;
end
-- Check if we should heal the provided entity.
elseif Entity:GetHealth() < 40 and Helper:CheckAvailable( "Gentle Echo" ) then
Helper:CheckExecute( "Gentle Echo", Entity );
return false;
end
end
--Heal: Rejuvenation Melody
if Helper:CheckAvailable( "Rejuvenation Melody" ) and Entity:GetHealth() < 60 then
Helper:CheckExecute( "Rejuvenation Melody", Entity );
return false;
end
-- Return true to let the caller know this function completed.
return true;
end
---------------------------------------------------------------------------------------
---------------------!!!!!!!!! DO NOT TOUCH MANA HEALING!!!!!!!!!!!--------------------
---------------------------------------------------------------------------------------
--- Checks if the state of the provided entity.
--
-- @param Entity Contains the entity to check.
-- @return bool
function _CheckMana( Entity )
-- Retrieve the range of the entity compared to my own character position.
local Range = Player:GetPosition():DistanceToPosition( Entity:GetPosition());
local EntityState = Entity:GetState();
-- Check if this routine is allowed to be ran under the current circumstances.
if Entity:IsDead() or ( not Settings.Songweaver.AllowApproach and Range > 23 ) then
return true;
end
--Complete the Chain
if Player:GetMana() < 90 and Helper:CheckAvailable( "Variation of Peace" ) then
Helper:CheckExecute ( "Variation of Peace" )
return false;
end
-- Check if the entity requires healing and perform the correct mana healing routine.
if Entity:GetMana() < 50 and ( Settings.Songweaver.AllowApproach or Range <= 23 ) then
if Entity:GetMana() < 45 and Helper:CheckAvailable( "Echo of Clarity" ) then
Helper:CheckExecute( "Echo of Clarity", Entity )
return false;
end
end
if Player:GetMana() < 50 and Helper:CheckAvailable( "Melody of Reflection" ) then
Helper:CheckExecute( "Melody of Reflection" )
return false;
end
-- Return true to let the caller know this function completed.
return true;
end
--------------------------------------------------------------------------------------
function _CheckState( Entity )
-- Retrieve the range of the entity compared to my own character position.
local Range = Player:GetPosition():DistanceToPosition( Entity:GetPosition());
-- Check if this routine is allowed to be ran under the current circumstances.
if Entity:IsDead() or ( not Settings.Songweaver.AllowApproach and Range > 23 ) then
return true;
end
-- Retrieve the state for the current entity to inspect.
local EntityState = Entity:GetState();
-- Loop through the states only when we are available to dispel them. We still check for removed states!
if EntityState ~= nil and ( self.StateDispelTime == nil or self.StateDispelTime < Time()) then
-- Create the state array for the global entity storage and undispellable states if it does not exist.
if self.StateArray == nil or self.StateUndispellable == nil then
self.StateArray = {};
self.StateUndispellable = {};
end
-- Create the state array for the current entity if it does not exist.
if self.StateArray[Entity:GetID()] == nil then
self.StateArray[Entity:GetID()] = {};
end
-- Loop through the states to find which need to be removed.
for ID, Skill in DictionaryIterator( EntityState:GetList()) do
-- Check if the current skill is valid and has not been marked and undispellable.
if Skill ~= nil and Skill:IsDebuff() and ( self.StateUndispellable[Skill:GetID()] == nil or self.StateUndispellable[Skill:GetID()] < Time()) then
-- Check if this entity had the current skill effect on him and hasn't been removed by either Cure Mind or Dispel.
if self.StateArray[Entity:GetID()][Skill:GetID()] ~= nil and self.StateArray[Entity:GetID()][Skill:GetID()] == 2 then
self.StateUndispellable[Skill:GetID()] = Time() + 30000;
-- Remove the state from the entity.
else
-- Retrieve the magical state the current skill.
local RemoveMagical = Skill:IsMagical();
-- Check if we are required to change the magical state for the current skill.
if self.StateArray[Entity:GetID()][Skill:GetID()] ~= nil then
RemoveMagical = not RemoveMagical;
end
-- Check if the dispel or cure mind can be executed correctly. The function might need to set the target first!
if ( RemoveMagical and Helper:CheckExecute( "Melody of Purification", Entity )) or ( not RemoveMagical and Helper:CheckExecute( "Melody of Purification", Entity )) then
-- Change the state dispel timer to prevent dispel and cure mind from being used too quickly.
self.StateDispelTime = Time() + 500;
-- Track the current state of the dispel and cure mind to find undispellable states.
if self.StateArray[Entity:GetID()][Skill:GetID()] == nil then
self.StateArray[Entity:GetID()][Skill:GetID()] = 1;
return false;
else
self.StateArray[Entity:GetID()][Skill:GetID()] = 2;
return false;
end
end
end
end
end
-- Loop through the existing states to find which have been removed correctly.
for k,v in pairs( self.StateArray[Entity:GetID()] ) do
if v ~= nil and EntityState:GetState( k ) == nil then
self.StateArray[Entity:GetID()][k] = nil;
end
end
end
-- Return true to let the caller know this function completed.
return true;
end
-----Sleep second target
function CountMobs( EntityTarget, Distance )
local i = 0;
-- Iterate through all entities
for ID, Entity in DictionaryIterator( EntityList:GetList()) do
-- Check if the entiy is valid.
if Entity ~= nil then
-- Retrieve the entity state.
local EntityState = Entity:GetState();
-- Check if the entity state is valid.
if EntityState ~= nil then
-- Check if this is a living monster that is in range.
if Entity:IsMonster() and not Entity:IsDead() and Entity:IsHostile() and EntityTarget:GetPosition():DistanceToPosition( Entity:GetPosition()) <= Distance then
-- Check if this entity is sleeping
if EntityState:GetState( Helper:CheckName( "March of the Jester" )) ~= nil then
return 0;
-- Increment the number.
else
i = i + 1;
end
end
end
end
end
return i;
end
function SleepMultipleAttacker( EntityTarget, AttackRange )
-- Check if we have stored a target.
if self._SleepTarget ~= nil then
-- Check if the current target is the stored target.
if self._SleepTarget:GetID() == Player:GetTargetID() then
-- Check if Sleep Arrow is available.
if Helper:CheckAvailable( "March of the Jester" ) then
-- Shoot the Sleep Arrow.
Helper:CheckExecute( "March of the Jester" );
-- Indicate we cannot continue attacking.
return false;
else
-- Set the target.
Player:SetTarget( self._SleepTargetRestore );
-- Indicate we cannot continue attacking.
return false;
end
-- Check if the current target is the original target.
elseif not Helper:CheckAvailable( "March of the Jester" ) and self._SleepTargetRestore:GetID() == EntityTarget:GetID() then
-- Clear the sleep target.
self._SleepTarget = nil;
-- Indicate we cannot continue attacking.
return true;
else
-- Set the target.
Player:SetTarget( self._SleepTarget );
-- Indicate we cannot continue attacking.
return false;
end
end
-- Check if Sleep Arrow is available.
if Helper:CheckAvailable( "March of the Jester" ) then
-- Loop through the entities.
for ID, Entity in DictionaryIterator( EntityList:GetList()) do
-- Check if this entity is a monster, is not friendly and decided to attack me (and obviously is not my current target).
if not Entity:IsDead() and Entity:IsMonster() and not Entity:IsFriendly() and Entity:GetTargetID() == Player:GetID() and Entity:GetID() ~= EntityTarget:GetID() then
-- Check if the entity that is attacking us is within range.
if Entity:GetPosition():DistanceToPosition( Player:GetPosition()) <= AttackRange then
-- Store the sleep target.
self._SleepTarget = Entity;
-- Store the restore target.
self._SleepTargetRestore = EntityTarget;
-- Set the target.
Player:SetTarget( Entity );
-- Indicate we cannot continue attacking.
return false;
end
end
end
end
-- Indicate we can continue attacking.
return true;
end
--- Perform the attack routine on the selected target.
--
-- @param Entity Contains the entity we have targeted.
-- @param double Contains the distance to the target
-- @param bool Indicates whether or not the target is stunned.
-- @return bool
function Attack( Entity, Range, Stunned )
---enemy position check
local Position = Player:GetPosition();
--
local AttackRange = Player:GetAttackRange();
--
local EntityState = Entity:GetState();
local PlayerState = Player:GetState();
local CaptivateEffect = Entity:GetState():GetState( Helper:CheckName( "Captivate" ));
-- Check if we are allowed to sleep attackers.
if Settings.Songweaver.AllowSleep and not self:SleepMultipleAttacker( Entity, AttackRange ) then
return false;
end
-----------------------------------------
-------------------Shock-----------------
-----------------------------------------
-- Use Remove Shock
if Helper:CheckAvailable( "Remove Shock" ) then
Helper:CheckExecute( "Remove Shock" );
return false;
end
-- Finish the Chain
if Helper:CheckAvailable( "Melody of Appreciation" ) and Player:GetHealth() < 50 then
Helper:CheckExecute( "Melody of Appreciation" );
return false;
elseif Helper:CheckAvailable( "Shock Blast" ) then
Helper:CheckExecute( "Shock Blast" );
return false;
end
-----------------------------------------
--------------Wind Harmony---------------
-----------------------------------------
-- Wind Hrmony Buff Check here for best farming speed!
if Helper:CheckAvailable( "Wind Harmony" ) and Helper:CheckAvailable ( "Chilling Harmony" ) then
Helper:CheckExecute( "Chilling Harmony" )
return false;
end
-----------------------------------------
-------------Chain Completer-------------
-----------------------------------------
-- Charged Skills
if Helper:CheckAvailable( "Tsunami Requiem" ) then
Helper:CheckExecute( "Tsunami Requiem" );
return false;
end
-- Chilling Harmony
if Helper:CheckAvailable ( "Wind Harmony" ) then
Helper:CheckExecute( "Wind Harmony" )
return false;
elseif Helper:CheckAvailable( "Earth Harmony" ) then
Helper:CheckExecute( "Earth Harmony" );
return false;
elseif Helper:CheckAvailable( "Flame Harmony" ) then
Helper:CheckExecute( "Flame Harmony" );
return false;
end
-- Soul Harmony
if Helper:CheckAvailable( "Harmony of Destruction" ) then
Helper:CheckExecute( "Harmony of Destruction" );
return false;
elseif Helper:CheckAvailable( "Harmony of Death" ) then
Helper:CheckExecute( "Harmony of Death" );
return false;
end
-- Attack Resonation
if Helper:CheckAvailable( "Acute Grating Sound" ) then
Helper:CheckExecute( "Acute Grating Sound" );
return false;
end
-----------------------------------------
-----------------Bufovani----------------
-----------------------------------------
-- Emergency!: Snowflower Melody
if Helper:CheckAvailable( "Snowflower Melody" ) and Player:GetHealth() < 40 then
Helper:CheckExecute( "Snowflower Melody" );
return false;
end
-- Shield Melody
if Helper:CheckAvailable( "Shield Melody" ) and PlayerState:GetState( "Shield Melody" ) == nil then
Helper:CheckExecute( "Shield Melody" );
return false;
end
-- Buff: Melody of Cheer
if Helper:CheckAvailable( "Melody of Cheer" ) and Entity:GetHealth() < 90 then
Helper:CheckExecute( "Melody of Cheer" );
return false;
end
-----------------------------------------
--------------Primary Skills-------------
-----------------------------------------
-- Harmony of Silence
if Helper:CheckAvailable( "Harmony of Silence" ) and Entity:GetSkillID() ~= 0 and SkillList[Entity:GetSkillID()]:IsMagical() and Entity:GetSkillTime() >= 500 then
Helper:CheckExecute( "Harmony of Silence" );
return false;
end
-- Fantastic Variation
if Entity:GetHealth() >= 90 and Helper:CheckAvailable( "Fantastic Variatio" ) and Position:DistanceToPosition( Entity:GetPosition()) >= 12 then
Helper:CheckExecute( "Fantastic Variation" );
return false;
end
-- Illusion Variation
if Entity:GetHealth() >= 90 and Helper:CheckAvailable( "Illusion Variation" ) and Position:DistanceToPosition( Entity:GetPosition()) >= 12 then
Helper:CheckExecute( "Illusion Variation" );
return false;
end
-- Battle Variation
if Entity:GetHealth() >= 0 and Helper:CheckAvailable( "Battle Variation" ) and Helper:CheckAvailable( "Tsunami Requiem" ) and Position:DistanceToPosition( Entity:GetPosition()) >= 12 then
Helper:CheckExecute( "Battle Variation");
return false;
end
-- Ascended Soul Variation
if Entity:GetHealth() >= 90 and Helper:CheckAvailable( "Ascended Soul Variation" ) and Position:DistanceToPosition( Entity:GetPosition()) >= 12 then
Helper:CheckExecute( "Ascended Soul Variation" );
return false;
end
-- Sea Variation
if Entity:GetHealth() >= 90 and Helper:CheckAvailable( "Sea Variation" ) and Position:DistanceToPosition( Entity:GetPosition()) >= 12 then
Helper:CheckExecute( "Sea Variation" );
return false;
end
-- 2000DP Skill Symphony of Wrath , Symphony of Destruction
if Helper:CheckAvailable( "Symphony of Destruction" ) and Player:GetDP() >=2000 then
Helper:CheckExecute( "Symphony of Destruction");
return false;
end
-- DOT Attack : Attack Resonation
if Entity:GetHealth() >= 80 and Helper:CheckAvailable( "Attack Resonation" ) and Entity ~= nil then
Helper:CheckExecute( "Attack Resonation" );
return false;
end
-- Chain : Chilling Harmony
if Helper:CheckAvailable( "Chilling Harmony" ) then
Helper:CheckExecute( "Chilling Harmony" );
return false;
end
-- Attack : Loud Bang
if Helper:CheckAvailable( "Loud Bang" ) then
Helper:CheckExecute( "Loud Bang" );
return false;
end
-- 2000 DP Skill Symphony of Wrath
if Helper:CheckAvailable( "Symphony of Wrath" ) and Player:GetDP() >=2000 then
Helper:CheckExecute( "Symphony of Wrath");
return false;
end
-- Attack : Disharmony
if Entity:GetHealth() >= 25 and Helper:CheckAvailable( "Disharmony" ) then
Helper:CheckExecute( "Disharmony" );
end
-- DOT Attack : Mosky Requiem
if Entity:GetHealth() >= 80 and Helper:CheckAvailable( "Mosky Requiem" ) then
Helper:CheckExecute( "Mosky Requiem" );
return false;
end
-- Attack : Gust Requiem
if Helper:CheckAvailable( "Gust Requiem" ) then
Helper:CheckExecute( "Gust Requiem" );
return false;
end
--Attack : March of the Bees
if Helper:CheckAvailable( "March of the Bees" ) then
Helper:CheckExecute( "March of the Bees" );
return false;
end
--Chain attack: Harmony of Death
if Helper:CheckAvailable( "Soul Harmony" ) then
Helper:CheckExecute( "Soul Harmony" );
return false;
end
-- Attack : Sound of the Breeze
if Helper:CheckAvailable( "Sound of the Breeze" ) then
Helper:CheckExecute( "Sound of the Breeze" );
return false;
end
-- Initial Attack : Automatic Attack
if self.AttackStarted ~= Entity:GetID() then
self.AttackStarted = Entity:GetID();
Helper:CheckExecute( "Attack/Chat" );
return false;
end
end
--- Perform healing checks both in and our of combat.
--
-- @param bool Indicates whether or not the function is running before force checks.
-- @return bool
function Heal( BeforeForce )
if BeforeForce and Settings.Songweaver.AllowBuff and ( self.StateBuffTime == nil or self.StateBuffTime < Time()) then
local EntityState = Player:GetState();
if EntityState ~= nil then
if EntityState:GetState( "Melody of Life" ) == nil and Helper:CheckAvailable( "Melody of Life" ) then
Helper:CheckExecute( "Melody of Life", Entity )
end
end
end
-- Check if we are allowed to execute our healing routines, after checking the force we can check our own HP.
if not BeforeForce and Settings.Songweaver.AllowHealing then
-- Check the required direct healing for my own character.
if not self:_CheckHeal( Player ) then
return false;
end
end
-- Check if we are allowed to execute our healing routines, after checking the force we can check our own HP.
if not BeforeForce and Settings.Songweaver.AllowHealingMana then
-- Check the required direct healing for my own character.
if not self:_CheckMana( Player ) then
return false;
end
end
-- Nothing was executed, continue with other functions.
return true;
end
--- Perform the safety checks before moving to the next target.
--
-- @return bool
function Pause()
--self:_CheckHeal ( Player )
--self:_CheckMana ( Player )
-- Nothing was executed, continue with other functions.
return true;
end