Guest User

Untitled

a guest
Jan 14th, 2019
311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.16 KB | None | 0 0
  1. -------------------------------------------------------------------------------------------------------------------
  2. -- Setup functions for this job.  Generally should not be modified.
  3. -------------------------------------------------------------------------------------------------------------------
  4.  
  5. -- Also, you'll need the Shortcuts addon to handle the auto-targetting of the custom pact commands.
  6.  
  7. --[[
  8.     Custom commands:
  9.    
  10.     gs c petweather
  11.         Automatically casts the storm appropriate for the current avatar, if possible.
  12.    
  13.     gs c siphon
  14.         Automatically run the process to: dismiss the current avatar; cast appropriate
  15.         weather; summon the appropriate spirit; Elemental Siphon; release the spirit;
  16.         and re-summon the avatar.
  17.        
  18.         Will not cast weather you do not have access to.
  19.         Will not re-summon the avatar if one was not out in the first place.
  20.         Will not release the spirit if it was out before the command was issued.
  21.        
  22.     gs c pact [PactType]
  23.         Attempts to use the indicated pact type for the current avatar.
  24.         PactType can be one of:
  25.             cure
  26.             curaga
  27.             buffOffense
  28.             buffDefense
  29.             buffSpecial
  30.             debuff1
  31.             debuff2
  32.             sleep
  33.             nuke2
  34.             nuke4
  35.             bp70
  36.             bp75 (merits and lvl 75-80 pacts)
  37.             astralflow
  38.  
  39. --]]
  40.  
  41. -- Initialization function for this job file.
  42. function get_sets()
  43.     Campestres = {}
  44.     Campestres.FC = { name="Campestres's Cape", augments={'Pet: M.Acc.+20 Pet: M.Dmg.+20','Eva.+20 /Mag. Eva.+20','Pet: Magic Damage+10','"Fast Cast"+10',}}
  45.     Campestres.TP = { name="Campestres's Cape", augments={'Pet: Acc.+20 Pet: R.Acc.+20 Pet: Atk.+20 Pet: R.Atk.+20','Eva.+20 /Mag. Eva.+20','Pet: Accuracy+10 Pet: Rng. Acc.+10','Pet: Haste+10',}}
  46.  
  47.     MerlinicHands = {}
  48.     MerlinicHands.Phys = { name="Merlinic Dastanas", augments={'Pet: Attack+13 Pet: Rng.Atk.+13','Blood Pact Dmg.+9','Pet: INT+7','Pet: Mag. Acc.+5','Pet: "Mag.Atk.Bns."+6',}}
  49.     MerlinicHands.Mag = { name="Merlinic Dastanas", augments={'Pet: "Mag.Atk.Bns."+25','Blood Pact Dmg.+2','Pet: Mag. Acc.+7',}}   
  50.  
  51.     mote_include_version = 2
  52.  
  53.     -- Load and initialize the include file.
  54.     include('Mote-Include.lua')
  55. end
  56.  
  57. -- Setup vars that are user-independent.  state.Buff vars initialized here will automatically be tracked.
  58. function job_setup()
  59.     state.Buff["Avatar's Favor"] = buffactive["Avatar's Favor"] or false
  60.     state.Buff["Astral Conduit"] = buffactive["Astral Conduit"] or false
  61.    
  62.     spirits = S{"LightSpirit", "DarkSpirit", "FireSpirit", "EarthSpirit", "WaterSpirit", "AirSpirit", "IceSpirit", "ThunderSpirit"}
  63.     avatars = S{"Carbuncle", "Fenrir", "Diabolos", "Ifrit", "Titan", "Leviathan", "Garuda", "Shiva", "Ramuh", "Odin", "Alexander", "Cait Sith"}
  64.  
  65.     magicalRagePacts = S{
  66.         'Inferno','Earthen Fury','Tidal Wave','Aerial Blast','Diamond Dust','Judgment Bolt','Searing Light','Howling Moon','Ruinous Omen',
  67.         'Fire II','Stone II','Water II','Aero II','Blizzard II','Thunder II',
  68.         'Fire IV','Stone IV','Water IV','Aero IV','Blizzard IV','Thunder IV',
  69.         'Thunderspark','Meteorite','Nether Blast',
  70.         'Holy Mist','Lunar Bay','Night Terror','Level ? Holy'}
  71.  
  72.     hybridPacts = S{
  73.         'Burning Strike','Flaming Crush',
  74.     }  
  75.        
  76.     enticersRagePacts = S{
  77.         'Impact','Heavenly Strike','Wind Blade','Geocrush','Thunderstorm','Meteor Strike','Grand Fall'
  78.     }
  79.     enticersWardPacts = S{
  80.         'Healing Ruby II','Whispering Wind','Healing Ruby','Spring Water'
  81.     }      
  82.  
  83.     pacts = {}
  84.     pacts.cure = {['Carbuncle']='Healing Ruby'}
  85.     pacts.curaga = {['Carbuncle']='Healing Ruby II', ['Garuda']='Whispering Wind', ['Leviathan']='Spring Water'}
  86.     pacts.buffoffense = {['Carbuncle']='Glittering Ruby', ['Ifrit']='Crimson Howl', ['Garuda']='Hastega', ['Ramuh']='Rolling Thunder',
  87.         ['Fenrir']='Ecliptic Growl'}
  88.     pacts.buffdefense = {['Carbuncle']='Shining Ruby', ['Shiva']='Frost Armor', ['Garuda']='Aerial Armor', ['Titan']='Earthen Ward',
  89.         ['Ramuh']='Lightning Armor', ['Fenrir']='Ecliptic Howl', ['Diabolos']='Noctoshield', ['Cait Sith']='Reraise II'}
  90.     pacts.buffspecial = {['Ifrit']='Inferno Howl', ['Garuda']='Fleet Wind', ['Titan']='Earthen Armor', ['Diabolos']='Dream Shroud',
  91.         ['Carbuncle']='Soothing Ruby', ['Fenrir']='Heavenward Howl', ['Cait Sith']='Raise II'}
  92.     pacts.debuff1 = {['Shiva']='Diamond Storm', ['Ramuh']='Shock Squall', ['Leviathan']='Tidal Roar', ['Fenrir']='Lunar Cry',
  93.         ['Diabolos']='Pavor Nocturnus', ['Cait Sith']='Eerie Eye'}
  94.     pacts.debuff2 = {['Shiva']='Sleepga', ['Leviathan']='Slowga', ['Fenrir']='Lunar Roar', ['Diabolos']='Somnolence'}
  95.     pacts.sleep = {['Shiva']='Sleepga', ['Diabolos']='Nightmare', ['Cait Sith']='Mewing Lullaby'}
  96.     pacts.nuke2 = {['Ifrit']='Fire II', ['Shiva']='Blizzard II', ['Garuda']='Aero II', ['Titan']='Stone II',
  97.         ['Ramuh']='Thunder II', ['Leviathan']='Water II'}
  98.     pacts.nuke4 = {['Ifrit']='Fire IV', ['Shiva']='Blizzard IV', ['Garuda']='Aero IV', ['Titan']='Stone IV',
  99.         ['Ramuh']='Thunder IV', ['Leviathan']='Water IV', ['Fenrir']='Impact'}
  100.     pacts.bp70 = {['Ifrit']='Flaming Crush', ['Shiva']='Rush', ['Garuda']='Predator Claws', ['Titan']='Mountain Buster',
  101.         ['Ramuh']='Chaotic Strike', ['Leviathan']='Spinning Dive', ['Carbuncle']='Meteorite', ['Fenrir']='Eclipse Bite',
  102.         ['Diabolos']='Nether Blast',['Cait Sith']='Regal Scratch'}
  103.     pacts.bp75 = {['Ifrit']='Meteor Strike', ['Shiva']='Heavenly Strike', ['Garuda']='Wind Blade', ['Titan']='Geocrush',
  104.         ['Ramuh']='Thunderstorm', ['Leviathan']='Grand Fall', ['Carbuncle']='Holy Mist', ['Fenrir']='Lunar Bay',
  105.         ['Diabolos']='Night Terror', ['Cait Sith']='Level ? Holy'}
  106.     pacts.astralflow = {['Ifrit']='Inferno', ['Shiva']='Diamond Dust', ['Garuda']='Aerial Blast', ['Titan']='Earthen Fury',
  107.         ['Ramuh']='Judgment Bolt', ['Leviathan']='Tidal Wave', ['Carbuncle']='Searing Light', ['Fenrir']='Howling Moon',
  108.         ['Diabolos']='Ruinous Omen', ['Cait Sith']="Altana's Favor"}
  109.  
  110.     -- Wards table for creating custom timers  
  111.     wards = {}
  112.     -- Base duration for ward pacts.
  113.     wards.durations = {
  114.         ['Crimson Howl'] = 60, ['Earthen Armor'] = 60, ['Inferno Howl'] = 60, ['Heavenward Howl'] = 60,
  115.         ['Rolling Thunder'] = 120, ['Fleet Wind'] = 120,
  116.         ['Shining Ruby'] = 180, ['Frost Armor'] = 180, ['Lightning Armor'] = 180, ['Ecliptic Growl'] = 180,
  117.         ['Glittering Ruby'] = 180, ['Hastega'] = 180, ['Noctoshield'] = 180, ['Ecliptic Howl'] = 180,
  118.         ['Dream Shroud'] = 180,
  119.         ['Reraise II'] = 3600
  120.     }
  121.     -- Icons to use when creating the custom timer.
  122.     wards.icons = {
  123.         ['Earthen Armor']   = 'spells/00299.png', -- 00299 for Titan
  124.         ['Shining Ruby']    = 'spells/00043.png', -- 00043 for Protect
  125.         ['Dream Shroud']    = 'spells/00304.png', -- 00304 for Diabolos
  126.         ['Noctoshield']     = 'spells/00106.png', -- 00106 for Phalanx
  127.         ['Inferno Howl']    = 'spells/00298.png', -- 00298 for Ifrit
  128.         ['Hastega']         = 'spells/00358.png', -- 00358 for Hastega
  129.         ['Rolling Thunder'] = 'spells/00104.png', -- 00358 for Enthunder
  130.         ['Frost Armor']     = 'spells/00250.png', -- 00250 for Ice Spikes
  131.         ['Lightning Armor'] = 'spells/00251.png', -- 00251 for Shock Spikes
  132.         ['Reraise II']      = 'spells/00135.png', -- 00135 for Reraise
  133.         ['Fleet Wind']      = 'abilities/00074.png', --
  134.     }
  135.     -- Flags for code to get around the issue of slow skill updates.
  136.     wards.flag = false
  137.     wards.spell = ''
  138.    
  139. end
  140.  
  141. -------------------------------------------------------------------------------------------------------------------
  142. -- User setup functions for this job.  Recommend that these be overridden in a sidecar file.
  143. -------------------------------------------------------------------------------------------------------------------
  144.  
  145. -- Setup vars that are user-dependent.  Can override this function in a sidecar file.
  146. function user_setup()
  147.     --F9 Toggles between Avatar Idle and TPing sets while engaged
  148.     state.OffenseMode:options('Pet Priority', 'Normal')
  149.     --Ctrl F12 Toggles Idle modes
  150.     --NOTE: having an avatar takes priority over normal "PDT" set
  151.     state.IdleMode:options('Normal', 'Avatar PDT', 'PDT')
  152.  
  153.     gear.perp_staff = {name="Nirvana"}
  154.    
  155.     select_default_macro_book()
  156.     send_command('wait 2; input /lockstyleset 7')  
  157.     add_to_chat (55, 'You are on '..('SMN '):color(204)..''..('btw. '):color(55)..''..('Macros set!'):color(121))
  158. end
  159.  
  160.  
  161. -- Define sets and vars used by this job file.
  162. function init_gear_sets()
  163.     --------------------------------------
  164.     -- Precast Sets
  165.     --------------------------------------
  166.    
  167.     -- Precast sets to enhance JAs
  168.     sets.precast.JA['Astral Flow'] = {head="Glyphic Horn +1"}
  169.    
  170.     sets.precast.JA['Elemental Siphon'] = {
  171.         main={ name="Kirin's Pole", augments={'DMG:+24','Summoning magic skill +12',}},
  172.         sub="Vox Grip",
  173.         ammo="Esper Stone +1",
  174.         head="Convoker's Horn +2",
  175.         body="Beck. Doublet +1",
  176.         hands="Lamassu Mitts +1",
  177.         legs="Beck. Spats +1",
  178.         feet="Beck. Pigaches +1",
  179.         neck="Caller's Pendant",
  180.         right_ear="Smn. Earring",
  181.         back="Conveyance Cape",
  182.         waist="Summoning Belt",
  183.         left_ring="Fervor Ring",
  184.         right_ring="Evoker's Ring",
  185.     }
  186.  
  187.     sets.precast.JA['Mana Cede'] = {hands="Beck. Bracers +1"}
  188.  
  189.     -- Pact delay reduction gear
  190.     -- BP Delay per tier: max -15
  191.     -- BP Delay Max: -(?)30 or is it 30 delay plus JP bonus?
  192.     -- Stack skill otherwise for Favor tiers
  193.     sets.precast.BloodPactWard = set_combine(sets.precast.JA['Elemental Siphon'], {
  194.         -- -7 II
  195.         ammo="Sancus Sachet +1",
  196.         head="Beckoner's Horn +1",
  197.         -- -2 II
  198.         body="Glyphic Doublet +1",
  199.         -- -6
  200.         hands="Glyphic Bracers +1",
  201.         -- -6
  202.         legs="Glyphic Spats +1",
  203.         -- Path D Apogee feet could go here for +15 skill
  204.         -- -3
  205.         back="Samanisi Cape",
  206.     })
  207.  
  208.     sets.precast.BloodPactRage = set_combine(sets.precast.BloodPactWard,{})
  209.  
  210.     -- Fast cast sets for spells
  211.    
  212.     sets.precast.FC = {
  213.         ammo="Impatiens",
  214.         neck="Voltsurge Torque",
  215.         ear1 = "Etiolation Earring",
  216.         right_ear="Loquac. Earring",
  217.         body="Vrikodara Jupon",
  218.         ring1="Kishar Ring",
  219.         ring2="Lebeche Ring",
  220.         back=Campestres.FC,
  221.         waist="Witful Belt",
  222.     }
  223.  
  224.     sets.precast.FC['Enhancing Magic'] = set_combine(sets.precast.FC, {
  225.         head="Umuthi Hat",
  226.         waist="Siegel Sash"
  227.     })
  228.  
  229.     sets.midcast.Refresh = set_combine(sets.midcast['Enhancing Magic'], {    
  230.         feet="Inspirited Boots",
  231.     })     
  232.        
  233.     -- Weaponskill sets
  234.     -- Default set for any weaponskill that isn't any more specifically defined
  235.     sets.precast.WS = {
  236.         neck="Fotia Gorget",
  237.         waist="Fotia Belt"
  238.     }
  239.  
  240.     -- Specific weaponskill sets.  Uses the base set if an appropriate WSMod version isn't found.
  241.     sets.precast.WS['Myrkr'] = {}
  242.  
  243.    
  244.     -- Should focus M.ACC to stick Def down
  245.     sets.precast.WS['Garland of Bliss'] = set_combine(sets.precast.WS, {
  246.         main="Nirvana",
  247.         head="Vanya Hood",
  248.         body="Con. Doublet +2",
  249.         hands="Glyphic Bracers +1",
  250.         legs="Gyve Trousers",
  251.         feet="Convo. Pigaches +2",
  252.         neck="Fotia Gorget",
  253.         waist="Fotia Belt",
  254.         left_ear="Hecate's Earring",
  255.         right_ear="Friomisi Earring",
  256.         left_ring="Karieyh Ring",
  257.         right_ring="Strendu Ring", 
  258.     })
  259.  
  260.     -- sets.precast.BloodPactRage = {
  261.         -- left_ring={"Varar Ring", bag="wardrobe3"},
  262.         -- right_ring={"Varar Ring", bag="wardrobe4"},
  263.     -- }
  264.    
  265.     --------------------------------------
  266.     -- Midcast sets
  267.     --------------------------------------
  268.  
  269.     sets.midcast.FastRecast = {}
  270.  
  271.     sets.midcast.Cure = {
  272.         head="Vanya Hood",
  273.         body="Vrikodara Jupon",
  274.         legs="Gyve Trousers",
  275.         feet="Medium's Sabots",
  276.         back="Solemnity Cape",
  277.         neck="Colossus's Torque",
  278.         left_ear="Gifted Earring",
  279.         right_ear="Roundel Earring",
  280.         ring2="Lebeche Ring",
  281.     }
  282.  
  283.     sets.midcast.Stoneskin = {
  284.         neck="Stone Gorget",
  285.         ear1="Earthcry Earring",
  286.         waist="Siegel Sash"
  287.     }
  288.  
  289.     sets.midcast['Elemental Magic'] = {}
  290.  
  291.     sets.midcast['Dark Magic'] = {}
  292.  
  293.     -- Avatar pact sets.  All pacts are Ability type.
  294.  
  295.     -- Triggers on Enhancing/Healing BPS
  296.     sets.midcast.Pet.BloodPactWard = {
  297.         main="Nirvana",
  298.         sub="Vox Grip",
  299.         ammo="Sancus Sachet +1",
  300.         head="Convoker's Horn +2",
  301.         body="Beck. Doublet +1",
  302.         hands="Lamassu Mitts +1",
  303.         legs="Beck. Spats +1",
  304.         feet="Apogee Pumps",
  305.         neck="Caller's Pendant",
  306.         waist="Summoning Belt",
  307.         left_ear="Etiolation Earring",
  308.         right_ear="Smn. Earring",
  309.         left_ring="Fervor Ring",
  310.         right_ring="Evoker's Ring",
  311.         back="Conveyance Cape",
  312.     }
  313.  
  314.     sets.midcast.Pet.DebuffBloodPactWard = {
  315.         main="Nirvana",
  316.         sub="Vox Grip",
  317.         ammo="Sancus Sachet +1",
  318.         head="Convoker's Horn +2",
  319.         body="Con. Doublet +2",
  320.         hands="Lamassu Mitts +1",
  321.         legs="Helios Spats",
  322.         feet="Convo. Pigaches +2",
  323.         neck="Caller's Pendant",
  324.         waist="Incarnation Sash",
  325.         left_ear="Enmerkar Earring",
  326.         right_ear="Smn. Earring",
  327.         left_ring="Tali'ah Ring",
  328.         right_ring="Evoker's Ring",
  329.         back="Conveyance Cape",
  330.     }
  331.        
  332.     sets.midcast.Pet.DebuffBloodPactWard.Acc = sets.midcast.Pet.DebuffBloodPactWard
  333.    
  334.     sets.midcast.Pet.TPBloodPactWard = set_combine(sets.midcast.Pet.DebuffBloodPactWard, {
  335.         legs="Enticer's Pants"
  336.     }) 
  337.    
  338.     sets.midcast.Pet.PhysicalBloodPactRage = {
  339.         main="Nirvana",
  340.         sub="Elan Strap",
  341.         ammo="Sancus Sachet +1",
  342.         head="Convoker's Horn +2",
  343.         body="Con. Doublet +2",
  344.         hands=MerlinicHands.Phys,
  345.         legs="Enticer's Pants",
  346.         feet="Convo. Pigaches +2",
  347.         neck="Shulmanu Collar",
  348.         waist="Incarnation Sash",
  349.         left_ear="Gelos Earring",
  350.         right_ear="Esper Earring",
  351.         back=Campestres.TP,
  352.         left_ring="Varar Ring",
  353.         right_ring="Varar Ring",       
  354.         -- left_ring={"Varar Ring",bag="wardrobe3",priority=2},
  355.         -- right_ring={"Varar Ring",bag="wardrobe4",priority=1},
  356.     }
  357.  
  358.     sets.midcast.Pet.PhysicalBloodPactRage.Acc = sets.midcast.Pet.PhysicalBloodPactRage
  359.  
  360.     --"Hybrid" BP TP bonus and Crit Hit Rate help to spike damage
  361.     sets.midcast.Pet.HybridBloodPactRage = set_combine(sets.midcast.Pet.PhysicalBloodPactRage, {
  362.         legs="Enticer's Pants"
  363.     })
  364.    
  365.     sets.midcast.Pet.MagicalBloodPactRage = {
  366.         main="Nirvana",
  367.         sub="Elan Strap",
  368.         ammo="Sancus Sachet +1",
  369.         head="Glyphic Horn +1",
  370.         body="Con. Doublet +2",
  371.         hands=MerlinicHands.Mag,
  372.         legs="Apogee Slacks",
  373.         feet="Apogee Pumps",
  374.         neck="Adad Amulet",
  375.         waist="Incarnation Sash",
  376.         left_ear="Gelos Earring",
  377.         right_ear="Esper Earring",
  378.         back=Campestres.FC,
  379.         left_ring="Varar Ring",
  380.         right_ring="Varar Ring",
  381.         -- left_ring={"Varar Ring",bag="wardrobe3",priority=2},
  382.         -- right_ring={"Varar Ring",bag="wardrobe4",priority=1},
  383.     }
  384.  
  385.     sets.midcast.Pet.MagicalBloodPactRage.Acc = sets.midcast.Pet.MagicalBloodPactRage
  386.  
  387.     sets.midcast.Pet.TPMagicalBloodPactRage = set_combine(sets.midcast.Pet.MagicalBloodPactRage, {
  388.         legs="Enticer's Pants"
  389.     }) 
  390.    
  391.     -- Spirits cast magic spells, which can be identified in standard ways.
  392.    
  393.     sets.midcast.Pet.WhiteMagic = {legs="Glyphic Spats +1"}
  394.    
  395.     sets.midcast.Pet['Elemental Magic'] = set_combine(sets.midcast.Pet.BloodPactRage, {})
  396.  
  397.     sets.midcast.Pet['Elemental Magic'].Resistant = {}
  398.    
  399.     --------------------------------------
  400.     -- Idle/resting/defense/etc sets
  401.     --------------------------------------
  402.    
  403.     -- Resting sets
  404.     sets.resting = {
  405.         main=gear.Staff.HMP,
  406.         head="Beckoner's Horn +1",
  407.         body="Shomonjijoe +1",
  408.         hands="Serpentes Cuffs",
  409.         legs="Nares Trews",
  410.         feet="Serpentes Sabots",
  411.         neck="Eidolon Pendant +1",
  412.         waist="Austerity Belt",
  413.         left_ear="Magnetic Earring",
  414.         right_ear="Moonshade Earring",
  415.     }
  416.    
  417.     -- Idle sets
  418.     sets.idle = {
  419.         main="Nirvana",
  420.         sub="Oneiros Grip",
  421.         ammo="Sancus Sachet +1",
  422.         head="Beckoner's Horn +1",
  423.         body="Shomonjijoe +1",
  424.         hands="Asteria Mitts +1",
  425.         legs="Assiduity Pants +1",
  426.         feet="Herald's Gaiters",
  427.         neck="Sanctity Necklace",
  428.         waist="Incarnation Sash",
  429.         ear1="Etiolation Earring",
  430.         ear2="Moonshade Earring",
  431.         ring1="Defending Ring",
  432.         ring2="Evoker's Ring",
  433.         back=Campestres.TP,
  434.     }
  435.  
  436.     sets.idle.PDT = {
  437.         main="Nirvana",
  438.         sub="Oneiros Strap",
  439.         ammo="Staunch Tathlum",
  440.         head="Convoker's Horn +2",
  441.         neck="Twilight Torque",
  442.         ear1="Etiolation Earring",
  443.         body="Udug Jacket",
  444.         hands="Beck. Bracers +1",
  445.         ring1="Defending Ring",
  446.         ring2="Gelatinous Ring +1",
  447.         back="Solemnity Cape",
  448.         legs="Assiduity Pants +1",
  449.         feet="Battlecast Gaiters",
  450.     }  
  451.    
  452.     sets.idle.Avatar = {
  453.         main="Nirvana",
  454.         sub="Oneiros Grip",
  455.         ammo="Sancus Sachet +1",
  456.         head="Convoker's Horn +2",
  457.         body="Shomonjijoe +1",
  458.         hands="Asteria Mitts +1",
  459.         legs="Assid. Pants +1",
  460.         feet="Convo. Pigaches +2",
  461.         neck="Caller's Pendant",
  462.         waist="Incarnation Sash",
  463.         left_ear="Enmerkar Earring",
  464.         right_ear="Moonshade Earring",
  465.         right_ring="Evoker's Ring",
  466.         back=Campestres.TP,
  467.     }
  468.  
  469.    
  470.     sets.idle.PDT.Avatar = set_combine(sets.idle.Avatar, {
  471.         ear2="Evans Earring",
  472.         body="Udug Jacket",
  473.         waist="Lucidity Sash"
  474.     })
  475.  
  476.     sets.idle.Spirit = {
  477.         main="Nirvana",
  478.         sub="Vox Grip",
  479.         ammo="Sancus Sachet +1",
  480.         head="Convoker's Horn +2",
  481.         body="Beck. Doublet +1",
  482.         hands="Lamassu Mitts +1",
  483.         legs="Assid. Pants +1",
  484.         feet="Apogee Pumps",
  485.         neck="Caller's Pendant",
  486.         waist="Incarnation Sash",
  487.         left_ear="Smn. Earring",
  488.         right_ear="Moonshade Earring",
  489.         left_ring="Fervor Ring",
  490.         right_ring="Evoker's Ring",
  491.         back="Conveyance Cape",
  492.     }
  493.  
  494.     sets.idle.Town = {}
  495.  
  496.     -- Favor uses Caller's Horn instead of Convoker's Horn for refresh
  497.     sets.idle.Avatar.Favor = {
  498.         head="Beckoner's Horn +1",
  499.         ear1="Smn. Earring",
  500.     }
  501.        
  502.     sets.idle.Avatar.Melee = {
  503.         ear1="Enmerkar Earring",
  504.         body="Glyphic Doublet +1",
  505.         hands="Glyphic Bracers +1",
  506.         ring1="Varar Ring",
  507.         waist="Incarnation Sash",
  508.         legs="Enticer's Pants",
  509.         feet="Tali'ah Crackows +2",
  510.     }
  511.        
  512.     -- Caller's Bracer's halve the perp cost after other costs are accounted for.
  513.     -- Using -10 (Gridavor, ring, Conv.feet), standard avatars would then cost 5, halved to 2.
  514.     -- We can then use Hagondes Coat and end up with the same net MP cost, but significantly better defense.
  515.     -- Weather is the same, but we can also use the latent on the pendant to negate the last point lost.
  516.  
  517.     -- perp costs (favor cost):
  518.     -- spirits: 7
  519.     -- carby/cait sith: 11(13) (5/6 with mitts)
  520.     -- fenrir: 13(15)
  521.     -- others: 15(18)
  522.     -- avatar's favor: +20% cost.
  523.    
  524.     -- Max useful -perp gear is 1 less than the perp cost (can't be reduced below 1)
  525.     -- Aim for -14 perp, and refresh in other slots.   
  526.     sets.perp = {}
  527.  
  528.     sets.perp.Day = set_combine(sets.idle.Avatar, {hands="Beck. Bracers +1"})
  529.    
  530.     sets.perp.Weather = set_combine(sets.idle.Avatar, {
  531.         neck="Caller's Pendant",
  532.         hands="Beck. Bracers +1"
  533.     })
  534.        
  535.     -- Carby: Mitts+Conv.feet = 1/tick perp.  Everything else should be +refresh
  536.     sets.perp.Carbuncle = set_combine(sets.idle.Avatar, {hands="Asteria Mitts +1"})
  537.  
  538.     sets.perp['Cait Sith'] = set_combine(sets.perp.Carbuncle, {hands="Lamassu Mitts +1"})
  539.        
  540.     -- Diabolos's Rope doesn't gain us anything at this time
  541.     --sets.perp.Diabolos = {waist="Diabolos's Rope"}
  542.  
  543.     sets.perp.Alexander = sets.midcast.Pet.BloodPactWard
  544.  
  545.     sets.perp.staff_and_grip = {main=gear.perp_staff,sub="Oneiros Grip"}
  546.    
  547.     -- Defense sets
  548.    
  549.     sets.defense = {}
  550.    
  551.     sets.defense.PDT = {
  552.         main="Nirvana",
  553.         sub="Oneiros Strap",
  554.         ammo="Staunch Tathlum",
  555.         head="Convoker's Horn +2",
  556.         neck="Twilight Torque",
  557.         ear1="Etiolation Earring",
  558.         body="Udug Jacket",
  559.         hands="Beck. Bracers +1",
  560.         ring1="Defending Ring",
  561.         ring2="Gelatinous Ring +1",
  562.         back="Solemnity Cape",
  563.         legs="Assiduity Pants +1",
  564.         feet="Battlecast Gaiters",
  565.     }
  566.  
  567.     sets.defense.MDT = set_combine(sets.defense.PDT, {})
  568.  
  569.     sets.Kiting = {feet="Herald's Gaiters"}
  570.    
  571.     sets.latent_refresh = {
  572.         grip = "Oneiros Grip",
  573.         waist="Fucho-no-obi"
  574.     }
  575.    
  576.  
  577.     --------------------------------------
  578.     -- Engaged sets
  579.     --------------------------------------
  580.    
  581.     -- Normal melee group
  582.     sets.engaged['Normal'] = set_combine(sets.idle.Avatar, {
  583.         neck="Shulmanu Collar",
  584.         ear1="Brutal Earring",
  585.         ring1="Petrov Ring",
  586.         ring2="Rajas Ring",
  587.         waist="Windbuffet Belt +1",
  588.         feet="Tali'ah Crackows +2"
  589.     })
  590.    
  591.     sets.engaged['Pet Priority'] = set_combine(sets.idle.Avatar, {})
  592. end
  593.  
  594. -------------------------------------------------------------------------------------------------------------------
  595. -- Job-specific hooks for standard casting events.
  596. -------------------------------------------------------------------------------------------------------------------
  597.  
  598. -- Set eventArgs.handled to true if we don't want any automatic gear equipping to be done.
  599. -- Set eventArgs.useMidcastGear to true if we want midcast gear equipped on precast.
  600. function job_precast(spell, action, spellMap, eventArgs)
  601.     if state.Buff['Astral Conduit'] and pet_midaction() then
  602.         eventArgs.handled = true
  603.     end
  604. end
  605.  
  606. function job_midcast(spell, action, spellMap, eventArgs)
  607.     if state.Buff['Astral Conduit'] and pet_midaction() then
  608.         eventArgs.handled = true
  609.     end
  610. end
  611.  
  612. -- Runs when pet completes an action.
  613. function job_pet_aftercast(spell, action, spellMap, eventArgs)
  614.     if not spell.interrupted and spell.type == 'BloodPactWard' and spellMap ~= 'DebuffBloodPactWard' then
  615.         wards.flag = true
  616.         wards.spell = spell.english
  617.         send_command('wait 4; gs c reset_ward_flag')
  618.     end
  619. end
  620.  
  621. -------------------------------------------------------------------------------------------------------------------
  622. -- Job-specific hooks for non-casting events.
  623. -------------------------------------------------------------------------------------------------------------------
  624.  
  625. -- Called when a player gains or loses a buff.
  626. -- buff == buff gained or lost
  627. -- gain == true if the buff was gained, false if it was lost.
  628. function job_buff_change(buff, gain)
  629.     if state.Buff[buff] ~= nil then
  630.         handle_equipping_gear(player.status)
  631.     elseif storms:contains(buff) then
  632.         handle_equipping_gear(player.status)
  633.     end
  634. end
  635.  
  636.  
  637. -- Called when the player's pet's status changes.
  638. -- This is also called after pet_change after a pet is released.  Check for pet validity.
  639. function job_pet_status_change(newStatus, oldStatus, eventArgs)
  640.     if pet.isvalid and not midaction() and not pet_midaction() and (newStatus == 'Engaged' or oldStatus == 'Engaged') then
  641.         handle_equipping_gear(player.status, newStatus)
  642.     end
  643. end
  644.  
  645.  
  646. -- Called when a player gains or loses a pet.
  647. -- pet == pet structure
  648. -- gain == true if the pet was gained, false if it was lost.
  649. function job_pet_change(petparam, gain)
  650.     classes.CustomIdleGroups:clear()
  651.     if gain then
  652.         if avatars:contains(pet.name) then
  653.             classes.CustomIdleGroups:append('Avatar')
  654.         elseif spirits:contains(pet.name) then
  655.             classes.CustomIdleGroups:append('Spirit')
  656.         end
  657.     else
  658.         select_default_macro_book('reset')
  659.     end
  660. end
  661.  
  662. --Way to track Pet TP from source:
  663. --https://www.ffxiah.com/forum/topic/47688/summoner-gearswap-yep-another-one-p/2/
  664. pet_tp = 0
  665. --Fix missing Pet.TP field by getting the packets from the fields lib
  666. packets = require('packets')
  667. function update_pet_tp(id,data)
  668.     if id == 0x068 then
  669.         pet_tp = 0
  670.         local update = packets.parse('incoming', data)
  671.         pet_tp = update["Pet TP"]
  672.         windower.send_command('lua c gearswap c pet_tp '..pet_tp)
  673.     end
  674. end
  675. id = windower.raw_register_event('incoming chunk', update_pet_tp)
  676.  
  677. --Locks Main/sub/range/ammo to keep Aftermath or building TP towards Aftermath
  678. function job_precast(spell, action, spellMap, eventArgs)
  679.     if spell.type == 'BloodPact' then
  680.             enable('main', 'sub', 'range', 'ammo')
  681.         elseif buffactive["Aftermath: Lv.1"] or buffactive["Aftermath: Lv.2"] or buffactive["Aftermath: Lv.3"] or player.tp > 1000 then
  682.             disable('main', 'sub', 'range', 'ammo')
  683.         elseif not buffactive["Aftermath: Lv.1"] or buffactive["Aftermath: Lv.2"]or buffactive["Aftermath: Lv.3"]  and player.tp < 1000 then
  684.             enable('main', 'sub', 'range', 'ammo')
  685.     else
  686.         enable('main', 'sub', 'range', 'ammo')
  687.     end
  688. end
  689.  
  690. -------------------------------------------------------------------------------------------------------------------
  691. -- User code that supplements standard library decisions.
  692. -------------------------------------------------------------------------------------------------------------------
  693.  
  694. -- Custom spell mapping.
  695. function job_get_spell_map(spell)
  696.     if spell.type == 'BloodPactRage' then
  697.         if enticersRagePacts:contains(spell.english) and spell.english ~= 'Impact' and pet_tp > 1400 then
  698.             equip({left_ring=empty})
  699.             equip({right_ring=empty})
  700.             return 'MagicalBloodPactRage'
  701.         elseif enticersRagePacts:contains(spell.english) then
  702.             equip({left_ring=empty})
  703.             equip({right_ring=empty})
  704.             return 'TPMagicalBloodPactRage'
  705.         elseif hybridPacts:contains(spell.english) then
  706.             equip({left_ring=empty})
  707.             equip({right_ring=empty})
  708.             return 'HybridBloodPactRage'
  709.         elseif magicalRagePacts:contains(spell.english) then
  710.             equip({left_ring=empty})
  711.             equip({right_ring=empty})
  712.             return 'MagicalBloodPactRage'
  713.         else
  714.             equip({left_ring=empty})
  715.             equip({right_ring=empty})
  716.             return 'PhysicalBloodPactRage'
  717.         end
  718.         elseif spell.type == 'BloodPactWard' and spell.target.type == 'MONSTER' then
  719.             return 'DebuffBloodPactWard'
  720.         elseif spell.type=='BloodPactWard' and enticersWardPacts:contains(spell.english) then
  721.             return 'TPBloodPactWard'
  722.     end
  723. end
  724.  
  725.  
  726. -- Modify the default idle set after it was constructed.
  727. function customize_idle_set(idleSet)
  728.     if pet.isvalid then
  729.         if pet.element == world.day_element then
  730.             idleSet = set_combine(idleSet, sets.perp.Day)
  731.         end
  732.         if pet.element == world.weather_element then
  733.             idleSet = set_combine(idleSet, sets.perp.Weather)
  734.         end
  735.         if sets.perp[pet.name] then
  736.             idleSet = set_combine(idleSet, sets.perp[pet.name])
  737.         end
  738.         gear.perp_staff.name = elements.perpetuance_staff_of[pet.element]
  739.         if gear.perp_staff.name and (player.inventory[gear.perp_staff.name] or player.wardrobe[gear.perp_staff.name]) then
  740.             idleSet = set_combine(idleSet, sets.perp.staff_and_grip)
  741.         end
  742.         if state.Buff["Avatar's Favor"] and avatars:contains(pet.name) then
  743.             idleSet = set_combine(idleSet, sets.idle.Avatar.Favor)
  744.         end
  745.         if pet.status == 'Engaged' then
  746.             idleSet = set_combine(idleSet, sets.idle.Avatar.Melee)
  747.         end
  748.     end
  749.    
  750.     if player.mpp < 51 then
  751.         idleSet = set_combine(idleSet, sets.latent_refresh)
  752.     end
  753.    
  754.     return idleSet
  755. end
  756.  
  757. -- Called by the 'update' self-command, for common needs.
  758. -- Set eventArgs.handled to true if we don't want automatic equipping of gear.
  759. function job_update(cmdParams, eventArgs)
  760.     classes.CustomIdleGroups:clear()
  761.     if pet.isvalid then
  762.         if avatars:contains(pet.name) then
  763.             classes.CustomIdleGroups:append('Avatar')
  764.         elseif spirits:contains(pet.name) then
  765.             classes.CustomIdleGroups:append('Spirit')
  766.         end
  767.     end
  768. end
  769.  
  770. -- Set eventArgs.handled to true if we don't want the automatic display to be run.
  771. function display_current_job_state(eventArgs)
  772.  
  773. end
  774.  
  775.  
  776. -------------------------------------------------------------------------------------------------------------------
  777. -- User self-commands.
  778. -------------------------------------------------------------------------------------------------------------------
  779.  
  780. -- Called for custom player commands.
  781. function job_self_command(cmdParams, eventArgs)
  782.     if cmdParams[1]:lower() == 'petweather' then
  783.         handle_petweather()
  784.         eventArgs.handled = true
  785.     elseif cmdParams[1]:lower() == 'siphon' then
  786.         handle_siphoning()
  787.         eventArgs.handled = true
  788.     elseif cmdParams[1]:lower() == 'pact' then
  789.         handle_pacts(cmdParams)
  790.         eventArgs.handled = true
  791.     elseif cmdParams[1] == 'reset_ward_flag' then
  792.         wards.flag = false
  793.         wards.spell = ''
  794.         eventArgs.handled = true
  795.     end
  796. end
  797.  
  798.  
  799. -------------------------------------------------------------------------------------------------------------------
  800. -- Utility functions specific to this job.
  801. -------------------------------------------------------------------------------------------------------------------
  802.  
  803. -- Cast the appopriate storm for the currently summoned avatar, if possible.
  804. function handle_petweather()
  805.     if player.sub_job ~= 'SCH' then
  806.         add_to_chat(122, "You can not cast storm spells")
  807.         return
  808.     end
  809.        
  810.     if not pet.isvalid then
  811.         add_to_chat(122, "You do not have an active avatar.")
  812.         return
  813.     end
  814.    
  815.     local element = pet.element
  816.     if element == 'Thunder' then
  817.         element = 'Lightning'
  818.     end
  819.    
  820.     if S{'Light','Dark','Lightning'}:contains(element) then
  821.         add_to_chat(122, 'You do not have access to '..elements.storm_of[element]..'.')
  822.         return
  823.     end
  824.    
  825.     local storm = elements.storm_of[element]
  826.    
  827.     if storm then
  828.         send_command('@input /ma "'..elements.storm_of[element]..'" <me>')
  829.     else
  830.         add_to_chat(123, 'Error: Unknown element ('..tostring(element)..')')
  831.     end
  832. end
  833.  
  834.  
  835. -- Custom uber-handling of Elemental Siphon
  836. function handle_siphoning()
  837.     if areas.Cities:contains(world.area) then
  838.         add_to_chat(122, 'Cannot use Elemental Siphon in a city area.')
  839.         return
  840.     end
  841.  
  842.     local siphonElement
  843.     local stormElementToUse
  844.     local releasedAvatar
  845.     local dontRelease
  846.    
  847.     -- If we already have a spirit out, just use that.
  848.     if pet.isvalid and spirits:contains(pet.name) then
  849.         siphonElement = pet.element
  850.         dontRelease = true
  851.         -- If current weather doesn't match the spirit, but the spirit matches the day, try to cast the storm.
  852.         if player.sub_job == 'SCH' and pet.element == world.day_element and pet.element ~= world.weather_element then
  853.             if not S{'Light','Dark','Lightning'}:contains(pet.element) then
  854.                 stormElementToUse = pet.element
  855.             end
  856.         end
  857.     -- If we're subbing /sch, there are some conditions where we want to make sure specific weather is up.
  858.     -- If current (single) weather is opposed by the current day, we want to change the weather to match
  859.     -- the current day, if possible.
  860.     elseif player.sub_job == 'SCH' and world.weather_element ~= 'None' then
  861.         -- We can override single-intensity weather; leave double weather alone, since even if
  862.         -- it's partially countered by the day, it's not worth changing.
  863.         if get_weather_intensity() == 1 then
  864.             -- If current weather is weak to the current day, it cancels the benefits for
  865.             -- siphon.  Change it to the day's weather if possible (+0 to +20%), or any non-weak
  866.             -- weather if not.
  867.             -- If the current weather matches the current avatar's element (being used to reduce
  868.             -- perpetuation), don't change it; just accept the penalty on Siphon.
  869.             if world.weather_element == elements.weak_to[world.day_element] and
  870.                 (not pet.isvalid or world.weather_element ~= pet.element) then
  871.                 -- We can't cast lightning/dark/light weather, so use a neutral element
  872.                 if S{'Light','Dark','Lightning'}:contains(world.day_element) then
  873.                     stormElementToUse = 'Wind'
  874.                 else
  875.                     stormElementToUse = world.day_element
  876.                 end
  877.             end
  878.         end
  879.     end
  880.    
  881.     -- If we decided to use a storm, set that as the spirit element to cast.
  882.     if stormElementToUse then
  883.         siphonElement = stormElementToUse
  884.     elseif world.weather_element ~= 'None' and (get_weather_intensity() == 2 or world.weather_element ~= elements.weak_to[world.day_element]) then
  885.         siphonElement = world.weather_element
  886.     else
  887.         siphonElement = world.day_element
  888.     end
  889.    
  890.     local command = ''
  891.     local releaseWait = 0
  892.    
  893.     if pet.isvalid and avatars:contains(pet.name) then
  894.         command = command..'input /pet "Release" <me>;wait 1.1;'
  895.         releasedAvatar = pet.name
  896.         releaseWait = 10
  897.     end
  898.    
  899.     if stormElementToUse then
  900.         command = command..'input /ma "'..elements.storm_of[stormElementToUse]..'" <me>;wait 4;'
  901.         releaseWait = releaseWait - 4
  902.     end
  903.    
  904.     if not (pet.isvalid and spirits:contains(pet.name)) then
  905.         command = command..'input /ma "'..elements.spirit_of[siphonElement]..'" <me>;wait 4;'
  906.         releaseWait = releaseWait - 4
  907.     end
  908.    
  909.     command = command..'input /ja "Elemental Siphon" <me>;'
  910.     releaseWait = releaseWait - 1
  911.     releaseWait = releaseWait + 0.1
  912.    
  913.     if not dontRelease then
  914.         if releaseWait > 0 then
  915.             command = command..'wait '..tostring(releaseWait)..';'
  916.         else
  917.             command = command..'wait 1.1;'
  918.         end
  919.        
  920.         command = command..'input /pet "Release" <me>;'
  921.     end
  922.    
  923.     if releasedAvatar then
  924.         command = command..'wait 1.1;input /ma "'..releasedAvatar..'" <me>'
  925.     end
  926.    
  927.     send_command(command)
  928. end
  929.  
  930.  
  931. -- Handles executing blood pacts in a generic, avatar-agnostic way.
  932. -- cmdParams is the split of the self-command.
  933. -- gs c [pact] [pacttype]
  934. function handle_pacts(cmdParams)
  935.     if areas.Cities:contains(world.area) then
  936.         add_to_chat(122, 'You cannot use pacts in town.')
  937.         return
  938.     end
  939.  
  940.     if not pet.isvalid then
  941.         add_to_chat(122,'No avatar currently available. Returning to default macro set.')
  942.         select_default_macro_book('reset')
  943.         return
  944.     end
  945.  
  946.     if spirits:contains(pet.name) then
  947.         add_to_chat(122,'Cannot use pacts with spirits.')
  948.         return
  949.     end
  950.  
  951.     if not cmdParams[2] then
  952.         add_to_chat(123,'No pact type given.')
  953.         return
  954.     end
  955.    
  956.     local pact = cmdParams[2]:lower()
  957.    
  958.     if not pacts[pact] then
  959.         add_to_chat(123,'Unknown pact type: '..tostring(pact))
  960.         return
  961.     end
  962.    
  963.     if pacts[pact][pet.name] then
  964.         if pact == 'astralflow' and not buffactive['astral flow'] then
  965.             add_to_chat(122,'Cannot use Astral Flow pacts at this time.')
  966.             return
  967.         end
  968.        
  969.         -- Leave out target; let Shortcuts auto-determine it.
  970.         send_command('@input /pet "'..pacts[pact][pet.name]..'"')
  971.     else
  972.         add_to_chat(122,pet.name..' does not have a pact of type ['..pact..'].')
  973.     end
  974. end
  975.  
  976.  
  977. -- Event handler for updates to player skill, since we can't rely on skill being
  978. -- correct at pet_aftercast for the creation of custom timers.
  979. windower.raw_register_event('incoming chunk',
  980.     function (id)
  981.         if id == 0x62 then
  982.             if wards.flag then
  983.                 create_pact_timer(wards.spell)
  984.                 wards.flag = false
  985.                 wards.spell = ''
  986.             end
  987.         end
  988.     end)
  989.  
  990. -- Function to create custom timers using the Timers addon.  Calculates ward duration
  991. -- based on player skill and base pact duration (defined in job_setup).
  992. function create_pact_timer(spell_name)
  993.     -- Create custom timers for ward pacts.
  994.     if wards.durations[spell_name] then
  995.         local ward_duration = wards.durations[spell_name]
  996.         if ward_duration < 181 then
  997.             local skill = player.skills.summoning_magic
  998.             if skill > 300 then
  999.                 skill = skill - 300
  1000.                 if skill > 200 then skill = 200 end
  1001.                 ward_duration = ward_duration + skill
  1002.             end
  1003.         end
  1004.        
  1005.         local timer_cmd = 'timers c "'..spell_name..'" '..tostring(ward_duration)..' down'
  1006.        
  1007.         if wards.icons[spell_name] then
  1008.             timer_cmd = timer_cmd..' '..wards.icons[spell_name]
  1009.         end
  1010.  
  1011.         send_command(timer_cmd)
  1012.     end
  1013. end
  1014.  
  1015.  
  1016. -- Select default macro book on initial load or subjob change.
  1017. function select_default_macro_book(reset)
  1018.     if reset == 'reset' then
  1019.         -- lost pet, or tried to use pact when pet is gone
  1020.     end
  1021.    
  1022.     -- Default macro set/book
  1023.     set_macro_page(1, 8)
  1024. end
Add Comment
Please, Sign In to add comment