Kushitap

BRD

Jul 6th, 2014
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.62 KB | None | 0 0
  1. -------------------------------------------------------------------------------------------------------------------
  2. -- Setup functions for this job.  Generally should not be modified.
  3. -------------------------------------------------------------------------------------------------------------------
  4.  
  5. --[[
  6.     Custom commands:
  7.    
  8.     ExtraSongsMode may take one of three values: None, Dummy, FullLength
  9.    
  10.     You can set these via the standard 'set' and 'cycle' self-commands.  EG:
  11.     gs c cycle ExtraSongsMode
  12.     gs c set ExtraSongsMode Dummy
  13.    
  14.     The Dummy state will equip the bonus song instrument and ensure non-duration gear is equipped.
  15.     The FullLength state will simply equip the bonus song instrument on top of standard gear.
  16.    
  17.    
  18.     Simple macro to cast a dummy Daurdabla song:
  19.     /console gs c set ExtraSongsMode Dummy
  20.     /ma "Shining Fantasia" <me>
  21.    
  22.     To use a Terpander rather than Daurdabla, set the info.ExtraSongInstrument variable to
  23.     'Terpander', and info.ExtraSongs to 1.
  24. --]]
  25.  
  26. -- Initialization function for this job file.
  27. function get_sets()
  28.     mote_include_version = 2
  29.    
  30.     -- Load and initialize the include file.
  31.     include('Mote-Include.lua')
  32. end
  33.  
  34.  
  35. -- Setup vars that are user-independent.  state.Buff vars initialized here will automatically be tracked.
  36. function job_setup()
  37.     state.ExtraSongsMode = M{['description']='Extra Songs', 'None', 'Dummy', 'FullLength'}
  38.  
  39.     state.Buff['Pianissimo'] = buffactive['pianissimo'] or false
  40.  
  41.     -- For tracking current recast timers via the Timers plugin.
  42.     custom_timers = {}
  43. end
  44.  
  45. -------------------------------------------------------------------------------------------------------------------
  46. -- User setup functions for this job.  Recommend that these be overridden in a sidecar file.
  47. -------------------------------------------------------------------------------------------------------------------
  48.  
  49. -- Setup vars that are user-dependent.  Can override this function in a sidecar file.
  50. function user_setup()
  51.     state.OffenseMode:options('None', 'Normal')
  52.     state.CastingMode:options('Normal', 'Resistant')
  53.     state.IdleMode:options('Normal', 'PDT')
  54.  
  55.     brd_daggers = S{'Izhiikoh', 'Vanir Knife', 'Atoyac', 'Aphotic Kukri', 'Sabebus'}
  56.     pick_tp_weapon()
  57.    
  58.     -- Adjust this if using the Terpander (new +song instrument)
  59.     info.ExtraSongInstrument = 'Terpander'
  60.     -- How many extra songs we can keep from Daurdabla/Terpander
  61.     info.ExtraSongs = 1
  62.    
  63.     -- Set this to false if you don't want to use custom timers.
  64.     state.UseCustomTimers = M(true, 'Use Custom Timers')
  65.    
  66.     -- Additional local binds
  67.     send_command('bind ^` gs c cycle ExtraSongsMode')
  68.     send_command('bind !` input /ma "Chocobo Mazurka" <me>')
  69.     send_command('bind !q input /ma "Cure IV" <t>;input /ma "Utsusemi: Ichi" <me>')
  70.     send_command('bind !w input /ma "Cure III" <t>;input /ma "Utsusemi: Ni" <me>')
  71.     send_command('bind !e input /ma "Cure II" <t>')
  72.     send_command('bind !a input /ma "Regen II" <stpc>, input /ma "Regen" <stpc>')
  73.     send_command('bind !s input /ma "Refresh" <stpc>')
  74.     send_command('bind !d input /ma "Haste" <stpc>')
  75.     send_command('bind !z input /ma "Blink" <me>')
  76.     send_command('bind !x input /ma "Stoneskin" <me>')
  77.     send_command('bind !c input /ma "Phalanx" <stpc>')
  78.     send_command('bind ^q input /ja "Pianissimo" <me>')
  79.     send_command('bind ^w input /ja "Tenuto" <me>')
  80.  
  81.     select_default_macro_book(1, 2)
  82. end
  83.  
  84.  
  85. -- Called when this job file is unloaded (eg: job change)
  86. function user_unload()
  87.     send_command('unbind ^`')
  88.     send_command('unbind !`')
  89. end
  90.  
  91.  
  92. -- Define sets and vars used by this job file.
  93. function init_gear_sets()
  94.     include('BRD_gear.lua')
  95. end
  96.  
  97. -------------------------------------------------------------------------------------------------------------------
  98. -- Job-specific hooks for standard casting events.
  99. -------------------------------------------------------------------------------------------------------------------
  100.  
  101. -- Set eventArgs.handled to true if we don't want any automatic gear equipping to be done.
  102. -- Set eventArgs.useMidcastGear to true if we want midcast gear equipped on precast.
  103. function job_precast(spell, action, spellMap, eventArgs)
  104.     if spell.type == 'BardSong' then
  105.         -- Auto-Pianissimo
  106.         if ((spell.target.type == 'PLAYER' and not spell.target.charmed) or (spell.target.type == 'NPC' and spell.target.in_party)) and
  107.             not state.Buff['Pianissimo'] then
  108.            
  109.             local spell_recasts = windower.ffxi.get_spell_recasts()
  110.             if spell_recasts[spell.recast_id] < 2 then
  111.                 send_command('@input /ja "Pianissimo" <me>; wait 1.5; input /ma "'..spell.name..'" '..spell.target.name)
  112.                 eventArgs.cancel = true
  113.                 return
  114.             end
  115.         end
  116.     end
  117.     if spell.english == 'Utsusemi: Ichi' and (buffactive['Copy Image'] or buffactive['Copy Image (2)']) then
  118.         send_command('@wait 3.3; cancel 66; cancel 444')
  119.     end
  120. end
  121.  
  122. -- Set eventArgs.handled to true if we don't want any automatic gear equipping to be done.
  123. function job_midcast(spell, action, spellMap, eventArgs)
  124.     if spell.action_type == 'Magic' then
  125.         if spell.type == 'BardSong' then
  126.             -- layer general gear on first, then let default handler add song-specific gear.
  127.             local generalClass = get_song_class(spell)
  128.             if generalClass and sets.midcast[generalClass] then
  129.                 equip(sets.midcast[generalClass])
  130.             end
  131.         end
  132.     end
  133. end
  134.  
  135. function job_post_midcast(spell, action, spellMap, eventArgs)
  136.     if spell.type == 'BardSong' then
  137.         if state.ExtraSongsMode.value == 'FullLength' then
  138.             equip(sets.midcast.Daurdabla)
  139.         end
  140.  
  141.         state.ExtraSongsMode:reset()
  142.     end
  143. end
  144.  
  145. -- Set eventArgs.handled to true if we don't want automatic gear equipping to be done.
  146. function job_aftercast(spell, action, spellMap, eventArgs)
  147.     if spell.type == 'BardSong' and not spell.interrupted then
  148.         if spell.target and spell.target.type == 'SELF' then
  149.             adjust_timers(spell, spellMap)
  150.         end
  151.     end
  152. end
  153.  
  154. -------------------------------------------------------------------------------------------------------------------
  155. -- Job-specific hooks for non-casting events.
  156. -------------------------------------------------------------------------------------------------------------------
  157.  
  158. -- Handle notifications of general user state change.
  159. function job_state_change(stateField, newValue, oldValue)
  160.     if stateField == 'Offense Mode' then
  161.         if newValue == 'Normal' then
  162.             disable('main','sub','ammo')
  163.         else
  164.             enable('main','sub','ammo')
  165.         end
  166.     end
  167. end
  168.  
  169. -------------------------------------------------------------------------------------------------------------------
  170. -- User code that supplements standard library decisions.
  171. -------------------------------------------------------------------------------------------------------------------
  172.  
  173. -- Called by the 'update' self-command.
  174. function job_update(cmdParams, eventArgs)
  175.     pick_tp_weapon()
  176. end
  177.  
  178.  
  179. -- Modify the default idle set after it was constructed.
  180. function customize_idle_set(idleSet)
  181.     if player.mpp < 51 then
  182.         idleSet = set_combine(idleSet, sets.latent_refresh)
  183.     end
  184.    
  185.     return idleSet
  186. end
  187.  
  188.  
  189. -- Function to display the current relevant user state when doing an update.
  190. function display_current_job_state(eventArgs)
  191.     display_current_caster_state()
  192.     eventArgs.handled = true
  193. end
  194.  
  195. -------------------------------------------------------------------------------------------------------------------
  196. -- Utility functions specific to this job.
  197. -------------------------------------------------------------------------------------------------------------------
  198.  
  199. -- Determine the custom class to use for the given song.
  200. function get_song_class(spell)
  201.     -- Can't use spell.targets:contains() because this is being pulled from resources
  202.     if set.contains(spell.targets, 'Enemy') then
  203.         if state.CastingMode.value == 'Resistant' then
  204.             return 'ResistantSongDebuff'
  205.         else
  206.             return 'SongDebuff'
  207.         end
  208.     elseif state.ExtraSongsMode.value == 'Dummy' then
  209.         return 'DaurdablaDummy'
  210.     else
  211.         return 'SongEffect'
  212.     end
  213. end
  214.  
  215.  
  216. -- Function to create custom buff-remaining timers with the Timers plugin,
  217. -- keeping only the actual valid songs rather than spamming the default
  218. -- buff remaining timers.
  219. function adjust_timers(spell, spellMap)
  220.     if state.UseCustomTimers.value == false then
  221.         return
  222.     end
  223.    
  224.     local current_time = os.time()
  225.    
  226.     -- custom_timers contains a table of song names, with the os time when they
  227.     -- will expire.
  228.    
  229.     -- Eliminate songs that have already expired from our local list.
  230.     local temp_timer_list = {}
  231.     for song_name,expires in pairs(custom_timers) do
  232.         if expires < current_time then
  233.             temp_timer_list[song_name] = true
  234.         end
  235.     end
  236.     for song_name,expires in pairs(temp_timer_list) do
  237.         custom_timers[song_name] = nil
  238.     end
  239.    
  240.     local dur = calculate_duration(spell.name, spellMap)
  241.     if custom_timers[spell.name] then
  242.         -- Songs always overwrite themselves now, unless the new song has
  243.         -- less duration than the old one (ie: old one was NT version, new
  244.         -- one has less duration than what's remaining).
  245.        
  246.         -- If new song will outlast the one in our list, replace it.
  247.         if custom_timers[spell.name] < (current_time + dur) then
  248.             send_command('timers delete "'..spell.name..'"')
  249.             custom_timers[spell.name] = current_time + dur
  250.             send_command('timers create "'..spell.name..'" '..dur..' down')
  251.         end
  252.     else
  253.         -- Figure out how many songs we can maintain.
  254.         local maxsongs = 2
  255.         if player.equipment.range == info.ExtraSongInstrument then
  256.             maxsongs = maxsongs + info.ExtraSongs
  257.         end
  258.         if buffactive['Clarion Call'] then
  259.             maxsongs = maxsongs + 1
  260.         end
  261.         -- If we have more songs active than is currently apparent, we can still overwrite
  262.         -- them while they're active, even if not using appropriate gear bonuses (ie: Daur).
  263.         if maxsongs < table.length(custom_timers) then
  264.             maxsongs = table.length(custom_timers)
  265.         end
  266.        
  267.         -- Create or update new song timers.
  268.         if table.length(custom_timers) < maxsongs then
  269.             custom_timers[spell.name] = current_time + dur
  270.             send_command('timers create "'..spell.name..'" '..dur..' down')
  271.         else
  272.             local rep,repsong
  273.             for song_name,expires in pairs(custom_timers) do
  274.                 if current_time + dur > expires then
  275.                     if not rep or rep > expires then
  276.                         rep = expires
  277.                         repsong = song_name
  278.                     end
  279.                 end
  280.             end
  281.             if repsong then
  282.                 custom_timers[repsong] = nil
  283.                 send_command('timers delete "'..repsong..'"')
  284.                 custom_timers[spell.name] = current_time + dur
  285.                 send_command('timers create "'..spell.name..'" '..dur..' down')
  286.             end
  287.         end
  288.     end
  289. end
  290.  
  291. -- Function to calculate the duration of a song based on the equipment used to cast it.
  292. -- Called from adjust_timers(), which is only called on aftercast().
  293. function calculate_duration(spellName, spellMap)
  294.     local mult = 1
  295.     if player.equipment.range == 'Daurdabla' then mult = mult + 0.3 end -- change to 0.25 with 90 Daur
  296.     if player.equipment.range == "Gjallarhorn" then mult = mult + 0.4 end -- change to 0.3 with 95 Gjall
  297.    
  298.     if player.equipment.main == "Carnwenhan" then mult = mult + 0.1 end -- 0.1 for 75, 0.4 for 95, 0.5 for 99/119
  299.     if player.equipment.main == "Legato Dagger" then mult = mult + 0.05 end
  300.     if player.equipment.sub == "Legato Dagger" then mult = mult + 0.05 end
  301.     if player.equipment.neck == "Aoidos' Matinee" then mult = mult + 0.1 end
  302.     if player.equipment.body == "Aoidos' Hngrln. +2" then mult = mult + 0.1 end
  303.     if player.equipment.legs == "Mdk. Shalwar +1" then mult = mult + 0.1 end
  304.     if player.equipment.feet == "Brioso Slippers" then mult = mult + 0.1 end
  305.     if player.equipment.feet == "Brioso Slippers +1" then mult = mult + 0.11 end
  306.    
  307.     if spellMap == 'Paeon' and player.equipment.head == "Brioso Roundlet" then mult = mult + 0.1 end
  308.     if spellMap == 'Paeon' and player.equipment.head == "Brioso Roundlet +1" then mult = mult + 0.1 end
  309.     if spellMap == 'Madrigal' and player.equipment.head == "Aoidos' Calot +2" then mult = mult + 0.1 end
  310.     if spellMap == 'Minuet' and player.equipment.body == "Aoidos' Hngrln. +2" then mult = mult + 0.1 end
  311.     if spellMap == 'March' and player.equipment.hands == 'Ad. Mnchtte. +2' then mult = mult + 0.1 end
  312.     if spellMap == 'Ballad' and player.equipment.legs == "Aoidos' Rhing. +2" then mult = mult + 0.1 end
  313.     if spellName == "Sentinel's Scherzo" and player.equipment.feet == "Aoidos' Cothrn. +2" then mult = mult + 0.1 end
  314.    
  315.     if buffactive.Troubadour then
  316.         mult = mult*2
  317.     end
  318.     if spellName == "Sentinel's Scherzo" then
  319.         if buffactive['Soul Voice'] then
  320.             mult = mult*2
  321.         elseif buffactive['Marcato'] then
  322.             mult = mult*1.5
  323.         end
  324.     end
  325.    
  326.     local totalDuration = math.floor(mult*120)
  327.  
  328.     return totalDuration
  329. end
  330.  
  331.  
  332. -- Examine equipment to determine what our current TP weapon is.
  333. function pick_tp_weapon()
  334.     if brd_daggers:contains(player.equipment.main) then
  335.         state.CombatWeapon:set('Dagger')
  336.        
  337.         if S{'NIN','DNC'}:contains(player.sub_job) and brd_daggers:contains(player.equipment.sub) then
  338.             state.CombatForm:set('DW')
  339.         else
  340.             state.CombatForm:reset()
  341.         end
  342.     else
  343.         state.CombatWeapon:reset()
  344.         state.CombatForm:reset()
  345.     end
  346. end
  347.  
  348. -- Function to reset timers.
  349. function reset_timers()
  350.     for i,v in pairs(custom_timers) do
  351.         send_command('timers delete "'..i..'"')
  352.     end
  353.     custom_timers = {}
  354. end
  355.  
  356.  
  357. -- Select default macro book on initial load or subjob change.
  358. function select_default_macro_book()
  359.     set_macro_page(1, 2)
  360. end
  361.  
  362.  
  363. windower.raw_register_event('zone change',reset_timers)
  364. windower.raw_register_event('logout',reset_timers)
  365.  
  366. function customize_melee_set(meleeSet)
  367.     if state.DefenseMode.value ~= "None" and buffactive['Reive Mark'] then
  368.         meleeSet = set_combine(meleeSet, {neck="Adoulin's Refuge +1"})
  369.     end
  370.    
  371.     return meleeSet
  372. end
Add Comment
Please, Sign In to add comment