Advertisement
Lygre

Cali's Mote-Include

Aug 3rd, 2016
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 39.88 KB | None | 0 0
  1. -------------------------------------------------------------------------------------------------------------------
  2. -- Common variables and functions to be included in job scripts, for general default handling.
  3. --
  4. -- Include this file in the get_sets() function with the command:
  5. -- include('Mote-Include.lua')
  6. --
  7. -- It will then automatically run its own init_include() function.
  8. --
  9. -- IMPORTANT: This include requires supporting include files:
  10. -- Mote-Utility
  11. -- Mote-Mappings
  12. -- Mote-SelfCommands
  13. -- Mote-Globals
  14. --
  15. -- Place the include() directive at the start of a job's get_sets() function.
  16. --
  17. -- Included variables and functions are considered to be at the same scope level as
  18. -- the job script itself, and can be used as such.
  19. -------------------------------------------------------------------------------------------------------------------
  20.  
  21. -------------------------------------------------------------------------------------------------------------------
  22. -- Initialization function that defines variables to be used.
  23. -- These are accessible at the including job lua script's scope.
  24. --
  25. -- Auto-initialize after defining this function.
  26. -------------------------------------------------------------------------------------------------------------------
  27.  
  28. current_mote_include_version = 2
  29.  
  30. function init_include()
  31.  
  32.    
  33.     -- Used to define various types of data mappings.  These may be used in the initialization, so load it up front.
  34.     include('Mote-Mappings')
  35.    
  36.     -- Modes is the include for a mode-tracking variable class.  Used for state vars, below.
  37.     include('Modes')
  38.  
  39.     -- Var for tracking state values
  40.     state = {}
  41.  
  42.     -- General melee offense/defense modes, allowing for hybrid set builds, as well as idle/resting/weaponskill.
  43.     -- This just defines the vars and sets the descriptions.  List modes with no values automatically
  44.     -- get assigned a 'Normal' default value.
  45.  
  46.     state.useMidcastGear    = M(false, 'Equip midcast gear on precast')
  47.  
  48.     state.OffenseMode         = M{['description'] = 'Offense Mode'}
  49.     state.HybridMode          = M{['description'] = 'Hybrid Mode'}
  50.     state.RangedMode          = M{['description'] = 'Ranged Mode'}
  51.     state.WeaponskillMode     = M{['description'] = 'Weaponskill Mode'}
  52.     state.CastingMode         = M{['description'] = 'Casting Mode'}
  53.     state.IdleMode            = M{['description'] = 'Idle Mode'}
  54.     state.RestingMode         = M{['description'] = 'Resting Mode'}
  55.     state.MagicBurst         = M{['description'] = 'Magic Burst Mode'}
  56.     state.DualWield         = M{['description'] = 'Dual Weild Mode'}
  57.  
  58.     state.DefenseMode         = M{['description'] = 'Defense Mode', 'None', 'Physical', 'Magical'}
  59.     state.PhysicalDefenseMode = M{['description'] = 'Physical Defense Mode', 'PDT'}
  60.     state.MagicalDefenseMode  = M{['description'] = 'Magical Defense Mode', 'MDT'}
  61.  
  62.    
  63.     state.Kiting              = M(false, 'Kiting')
  64.     state.SelectNPCTargets    = M(false, 'Select NPC Targets')
  65.     state.PCTargetMode        = M{['description'] = 'PC Target Mode', 'default', 'stpt', 'stal', 'stpc'}
  66.  
  67.     state.EquipStop           = M{['description'] = 'Stop Equipping Gear', 'off', 'precast', 'midcast', 'pet_midcast'}
  68.  
  69.     state.CombatWeapon        = M{['description']='Combat Weapon', ['string']=''}
  70.     state.CombatForm          = M{['description']='Combat Form', ['string']=''}
  71.    
  72.  
  73.     -- Non-mode vars that are used for state tracking.
  74.     state.MaxWeaponskillDistance = 0
  75.     state.Buff = {}
  76.  
  77.     -- Classes describe a 'type' of action.  They are similar to state, but
  78.     -- may have any free-form value, or describe an entire table of mapped values.
  79.     classes = {}
  80.     -- Basic spell mappings are based on common spell series.
  81.     -- EG: 'Cure' for Cure, Cure II, Cure III, Cure IV, Cure V, or Cure VI.
  82.     classes.SpellMaps = spell_maps
  83.     -- List of spells and spell maps that don't benefit from greater skill (though
  84.     -- they may benefit from spell-specific augments, such as improved regen or refresh).
  85.     -- Spells that fall under this category will be skipped when searching for
  86.     -- spell.skill sets.
  87.     classes.NoSkillSpells = no_skill_spells_list
  88.     classes.SkipSkillCheck = false
  89.     -- Custom, job-defined class, like the generic spell mappings.
  90.     -- Takes precedence over default spell maps.
  91.     -- Is reset at the end of each spell casting cycle (ie: at the end of aftercast).
  92.     classes.JAMode = nil
  93.     classes.CustomClass = nil
  94.     -- Custom groups used for defining melee and idle sets.  Persists long-term.
  95.     classes.CustomMeleeGroups = L{}
  96.     classes.CustomRangedGroups = L{}
  97.     classes.CustomIdleGroups = L{}
  98.     classes.CustomDefenseGroups = L{}
  99.  
  100.     -- Class variables for time-based flags
  101.     classes.Daytime = false
  102.     classes.DuskToDawn = false
  103.  
  104.  
  105.     -- Var for tracking misc info
  106.     info = {}
  107.     options = {}
  108.  
  109.     -- Special control flags.
  110.     mote_vars = {}
  111.     mote_vars.set_breadcrumbs = L{}
  112.     mote_vars.res_buffs = S{}
  113.     for index,struct in pairs(gearswap.res.buffs) do
  114.         mote_vars.res_buffs:add(struct.en)
  115.     end
  116.  
  117.     -- Sub-tables within the sets table that we expect to exist, and are annoying to have to
  118.     -- define within each individual job file.  We can define them here to make sure we don't
  119.     -- have to check for existence.  The job file should be including this before defining
  120.     -- any sets, so any changes it makes will override these anyway.
  121.     sets.precast = {}
  122.     sets.precast.FC = {}
  123.     sets.precast.JA = {}
  124.     sets.precast.WS = {}
  125.     sets.precast.RA = {}
  126.     sets.midcast = {}
  127.     sets.midcast.RA = {}
  128.     sets.midcast.Pet = {}
  129.     sets.idle = {}
  130.     sets.resting = {}
  131.     sets.engaged = {}
  132.     sets.defense = {}
  133.     sets.buff = {}
  134.  
  135.     gear = {}
  136.     gear.default = {}
  137.  
  138.     gear.ElementalGorget = {name=""}
  139.     gear.ElementalBelt = {name=""}
  140.     gear.ElementalObi = {name=""}
  141.     gear.ElementalCape = {name=""}
  142.     gear.ElementalRing = {name=""}
  143.     gear.FastcastStaff = {name=""}
  144.     gear.RecastStaff = {name=""}
  145.  
  146.  
  147.     -- Load externally-defined information (info that we don't want to change every time this file is updated).
  148.  
  149.     -- Used to define misc utility functions that may be useful for this include or any job files.
  150.     include('Mote-Utility')
  151.  
  152.     -- Used for all self-command handling.
  153.     include('Mote-SelfCommands')
  154.  
  155.     -- Include general user globals, such as custom binds or gear tables.
  156.     -- Load Mote-Globals first, followed by User-Globals, followed by <character>-Globals.
  157.     -- Any functions re-defined in the later includes will overwrite the earlier versions.
  158.     include('Mote-Globals')
  159.     optional_include({'user-globals.lua'})
  160.     optional_include({player.name..'-globals.lua'})
  161.  
  162.     -- *-globals.lua may define additional sets to be added to the local ones.
  163.     if define_global_sets then
  164.         define_global_sets()
  165.     end
  166.  
  167.     -- Global default binds (either from Mote-Globals or user-globals)
  168.     (binds_on_load or global_on_load)()
  169.  
  170.     -- Load a sidecar file for the job (if it exists) that may re-define init_gear_sets and file_unload.
  171.     load_sidecar(player.main_job)
  172.  
  173.     -- General var initialization and setup.
  174.     if job_setup then
  175.         job_setup()
  176.     end
  177.  
  178.     -- User-specific var initialization and setup.
  179.     if user_setup then
  180.         user_setup()
  181.     end
  182.  
  183.     -- Load up all the gear sets.
  184.     init_gear_sets()
  185. end
  186.  
  187. if not mote_include_version or mote_include_version < current_mote_include_version then
  188.     add_to_chat(123,'Warning: Your job file is out of date.  Please update to the latest repository baseline.')
  189.     add_to_chat(123,'For details, visit https://github.com/Kinematics/GearSwap-Jobs/wiki/Upgrading')
  190.     rev = mote_include_version or 1
  191.     include_path('rev' .. tostring(rev))
  192.     include('Mote-Include')
  193.     return
  194. end
  195.  
  196. -- Auto-initialize the include
  197. init_include()
  198.  
  199.  
  200. -- Called when this job file is unloaded (eg: job change)
  201. -- Conditional definition so that it doesn't overwrite explicit user
  202. -- versions of this function.
  203. if not file_unload then
  204.     file_unload = function()
  205.         if user_unload then
  206.             user_unload()
  207.         elseif job_file_unload then
  208.             job_file_unload()
  209.         end
  210.         _G[(binds_on_unload and 'binds_on_unload') or 'global_on_unload']()
  211.     end
  212. end
  213.  
  214.  
  215.  
  216.  
  217. -------------------------------------------------------------------------------------------------------------------
  218. -- Generalized functions for handling precast/midcast/aftercast for player-initiated actions.
  219. -- This depends on proper set naming.
  220. -- Global hooks can be written as user_xxx() to override functions at a global level.
  221. -- Each job can override any of these general functions using job_xxx() hooks.
  222. -------------------------------------------------------------------------------------------------------------------
  223.  
  224. ------------------------------------------------------------------------
  225. -- Generic function to map a set processing order to all action events.
  226. ------------------------------------------------------------------------
  227.  
  228.  
  229. -- Process actions in a specific order of events:
  230. -- Filter  - filter_xxx() functions determine whether to run any of the code for this action.
  231. -- Global  - user_xxx() functions get called first.  Define in Mote-Globals or User-Globals.
  232. -- Local   - job_xxx() functions get called next. Define in JOB.lua file.
  233. -- Default - default_xxx() functions get called next. Defined in this file.
  234. -- Cleanup - cleanup_xxx() functions always get called before exiting.
  235. --
  236. -- Parameters:
  237. -- spell - standard spell table passed in by GearSwap
  238. -- action - string defining the function mapping to use (precast, midcast, etc)
  239. function handle_actions(spell, action)
  240.     -- Init an eventArgs that allows cancelling.
  241.     local eventArgs = {handled = false, cancel = false}
  242.    
  243.     mote_vars.set_breadcrumbs:clear()
  244.  
  245.     -- Get the spell mapping, since we'll be passing it to various functions and checks.
  246.     local spellMap = get_spell_map(spell)
  247.  
  248.     -- General filter checks to see whether this function should be run.
  249.     -- If eventArgs.cancel is set, cancels this function, not the spell.
  250.     if _G['filter_'..action] then
  251.         _G['filter_'..action](spell, spellMap, eventArgs)
  252.     end
  253.  
  254.     -- If filter didn't cancel it, process user and default actions.
  255.     if not eventArgs.cancel then
  256.         -- Global user handling of this action
  257.         if _G['user_'..action] then
  258.             _G['user_'..action](spell, action, spellMap, eventArgs)
  259.            
  260.             if eventArgs.cancel then
  261.                 cancel_spell()
  262.             end
  263.         end
  264.        
  265.         -- Job-specific handling of this action
  266.         if not eventArgs.cancel and not eventArgs.handled and _G['job_'..action] then
  267.             _G['job_'..action](spell, action, spellMap, eventArgs)
  268.            
  269.             if eventArgs.cancel then
  270.                 cancel_spell()
  271.             end
  272.         end
  273.    
  274.         -- Default handling of this action
  275.         if not eventArgs.cancel and not eventArgs.handled and _G['default_'..action] then
  276.             _G['default_'..action](spell, spellMap)
  277.             display_breadcrumbs(spell, spellMap, action)
  278.         end
  279.        
  280.         -- Global post-handling of this action
  281.         if not eventArgs.cancel and _G['user_post_'..action] then
  282.             _G['user_post_'..action](spell, action, spellMap, eventArgs)
  283.         end
  284.  
  285.         -- Job-specific post-handling of this action
  286.         if not eventArgs.cancel and _G['job_post_'..action] then
  287.             _G['job_post_'..action](spell, action, spellMap, eventArgs)
  288.         end
  289.     end
  290.  
  291.     -- Cleanup once this action is done
  292.     if _G['cleanup_'..action] then
  293.         _G['cleanup_'..action](spell, spellMap, eventArgs)
  294.     end
  295. end
  296.  
  297.  
  298. --------------------------------------
  299. -- Action hooks called by GearSwap.
  300. --------------------------------------
  301.  
  302. function pretarget(spell)
  303.     handle_actions(spell, 'pretarget')
  304. end
  305.  
  306. function precast(spell)
  307.     if state.Buff[spell.english] ~= nil then
  308.         state.Buff[spell.english] = true
  309.     end
  310.     handle_actions(spell, 'precast')
  311. end
  312.  
  313. function midcast(spell)
  314.     handle_actions(spell, 'midcast')
  315. end
  316.  
  317. function aftercast(spell)
  318.     if state.Buff[spell.english] ~= nil then
  319.         state.Buff[spell.english] = not spell.interrupted or buffactive[spell.english] or false
  320.     end
  321.     handle_actions(spell, 'aftercast')
  322. end
  323.  
  324. function pet_midcast(spell)
  325.     handle_actions(spell, 'pet_midcast')
  326. end
  327.  
  328. function pet_aftercast(spell)
  329.     handle_actions(spell, 'pet_aftercast')
  330. end
  331.  
  332. --------------------------------------
  333. -- Default code for each action.
  334. --------------------------------------
  335.  
  336. function default_pretarget(spell, spellMap)
  337.     auto_change_target(spell, spellMap)
  338. end
  339.  
  340.  
  341. function default_precast(spell, spellMap)
  342.  
  343.     if spell.action_type == 'Magic' then
  344.  
  345.         if not state.useMidcastGear.value then
  346.  
  347.             equip(get_precast_set(spell, spellMap))
  348.  
  349.             return
  350.  
  351.         else
  352.  
  353.             equip(get_midcast_set(spell, spellMap))
  354.        
  355.             return
  356.  
  357.         end
  358.  
  359.     end
  360.  
  361.     equip(get_precast_set(spell, spellMap))
  362.  
  363. end
  364.  
  365. function default_midcast(spell, spellMap)
  366.     equip(get_midcast_set(spell, spellMap))
  367. end
  368.  
  369. function default_aftercast(spell, spellMap)
  370.     if not pet_midaction() then
  371.         handle_equipping_gear(player.status)
  372.     end
  373. end
  374. --- This is Error Line ??!!! ------
  375.  
  376.  
  377. function default_pet_midcast(spell, spellMap)
  378.     equip(get_pet_midcast_set(spell, spellMap))
  379. end
  380.  
  381. function default_pet_aftercast(spell, spellMap)
  382.     handle_equipping_gear(player.status)
  383. end
  384.  
  385. --------------------------------------
  386. -- Filters for each action.
  387. -- Set eventArgs.cancel to true to stop further processing.
  388. -- May show notification messages, but should not do any processing here.
  389. --------------------------------------
  390.  
  391. function filter_midcast(spell, spellMap, eventArgs)
  392.     if state.EquipStop.value == 'precast' then
  393.         eventArgs.cancel = true
  394.     end
  395. end
  396.  
  397. function filter_aftercast(spell, spellMap, eventArgs)
  398.     if state.EquipStop.value == 'precast' or state.EquipStop.value == 'midcast' or state.EquipStop.value == 'pet_midcast' then
  399.         eventArgs.cancel = true
  400.     elseif spell.name == 'Unknown Interrupt' then
  401.         eventArgs.cancel = true
  402.     end
  403. end
  404.  
  405. function filter_pet_midcast(spell, spellMap, eventArgs)
  406.     -- If we have show_set active for precast or midcast, don't try to equip pet midcast gear.
  407.     if state.EquipStop.value == 'precast' or state.EquipStop.value == 'midcast' then
  408.         add_to_chat(104, 'Show Sets: Pet midcast not equipped.')
  409.         eventArgs.cancel = true
  410.     end
  411. end
  412.  
  413. function filter_pet_aftercast(spell, spellMap, eventArgs)
  414.     -- If show_set is flagged for precast or midcast, don't try to equip aftercast gear.
  415.     if state.EquipStop.value == 'precast' or state.EquipStop.value == 'midcast' or state.EquipStop.value == 'pet_midcast' then
  416.         eventArgs.cancel = true
  417.     end
  418. end
  419.  
  420. --------------------------------------
  421. -- Cleanup code for each action.
  422. --------------------------------------
  423.  
  424. function cleanup_precast(spell, spellMap, eventArgs)
  425.     -- If show_set is flagged for precast, notify that we won't try to equip later gear.
  426.     if state.EquipStop.value == 'precast' then
  427.         add_to_chat(104, 'Show Sets: Stopping at precast.')
  428.     end
  429. end
  430.  
  431. function cleanup_midcast(spell, spellMap, eventArgs)
  432.     -- If show_set is flagged for midcast, notify that we won't try to equip later gear.
  433.     if state.EquipStop.value == 'midcast' then
  434.         add_to_chat(104, 'Show Sets: Stopping at midcast.')
  435.     end
  436. end
  437.  
  438. function cleanup_aftercast(spell, spellMap, eventArgs)
  439.     -- Reset custom classes after all possible precast/midcast/aftercast/job-specific usage of the value.
  440.     -- If we're in the middle of a pet action, pet_aftercast will handle clearing it.
  441.     if not pet_midaction() then
  442.         reset_transitory_classes()
  443.     end
  444. end
  445.  
  446. function cleanup_pet_midcast(spell, spellMap, eventArgs)
  447.     -- If show_set is flagged for pet midcast, notify that we won't try to equip later gear.
  448.     if state.EquipStop.value == 'pet_midcast' then
  449.         add_to_chat(104, 'Show Sets: Stopping at pet midcast.')
  450.     end
  451. end
  452.  
  453. function cleanup_pet_aftercast(spell, spellMap, eventArgs)
  454.     -- Reset custom classes after all possible precast/midcast/aftercast/job-specific usage of the value.
  455.     reset_transitory_classes()
  456. end
  457.  
  458.  
  459. -- Clears the values from classes that only exist til the action is complete.
  460. function reset_transitory_classes()
  461.     classes.CustomClass = nil
  462.     classes.JAMode = nil
  463. end
  464.  
  465.  
  466.  
  467. -------------------------------------------------------------------------------------------------------------------
  468. -- High-level functions for selecting and equipping gear sets.
  469. -------------------------------------------------------------------------------------------------------------------
  470.  
  471. -- Central point to call to equip gear based on status.
  472. -- Status - Player status that we're using to define what gear to equip.
  473. function handle_equipping_gear(playerStatus, petStatus)
  474.     -- init a new eventArgs
  475.     local eventArgs = {handled = false}
  476.  
  477.     -- Allow jobs to override this code
  478.     if job_handle_equipping_gear then
  479.         job_handle_equipping_gear(playerStatus, eventArgs)
  480.     end
  481.  
  482.     -- Equip default gear if job didn't handle it.
  483.     if not eventArgs.handled then
  484.         equip_gear_by_status(playerStatus, petStatus)
  485.     end
  486. end
  487.  
  488.  
  489. -- Function to wrap logic for equipping gear on aftercast, status change, or user update.
  490. -- @param status : The current or new player status that determines what sort of gear to equip.
  491. function equip_gear_by_status(playerStatus, petStatus)
  492.     if _global.debug_mode then add_to_chat(123,'Debug: Equip gear for status ['..tostring(status)..'], HP='..tostring(player.hp)) end
  493.  
  494.     playerStatus = playerStatus or player.status or 'Idle'
  495.    
  496.     -- If status not defined, treat as idle.
  497.     -- Be sure to check for positive HP to make sure they're not dead.
  498.     if (playerStatus == 'Idle' or playerStatus == '') and player.hp > 0 then
  499.         equip(get_idle_set(petStatus))
  500.     elseif playerStatus == 'Engaged' then
  501.         equip(get_melee_set(petStatus))
  502.     elseif playerStatus == 'Resting' then
  503.         equip(get_resting_set(petStatus))
  504.     end
  505. end
  506.  
  507.  
  508. -------------------------------------------------------------------------------------------------------------------
  509. -- Functions for constructing default gear sets based on status.
  510. -------------------------------------------------------------------------------------------------------------------
  511.  
  512. -- Returns the appropriate idle set based on current state values and location.
  513. -- Set construction order (all of which are optional):
  514. --   sets.idle[idleScope][state.IdleMode][Pet[Engaged]][CustomIdleGroups]
  515. --
  516. -- Params:
  517. -- petStatus - Optional explicit definition of pet status.
  518. function get_idle_set(petStatus)
  519.     local idleSet = sets.idle
  520.    
  521.     if not idleSet then
  522.         return {}
  523.     end
  524.    
  525.     mote_vars.set_breadcrumbs:append('sets')
  526.     mote_vars.set_breadcrumbs:append('idle')
  527.    
  528.     local idleScope
  529.  
  530.     if buffactive.weakness then
  531.         idleScope = 'Weak'
  532.     elseif areas.Cities:contains(world.area) then
  533.         idleScope = 'Town'
  534.     else
  535.         idleScope = 'Field'
  536.     end
  537.  
  538.     if idleSet[idleScope] then
  539.         idleSet = idleSet[idleScope]
  540.         mote_vars.set_breadcrumbs:append(idleScope)
  541.     end
  542.  
  543.     if idleSet[state.IdleMode.current] then
  544.         idleSet = idleSet[state.IdleMode.current]
  545.         mote_vars.set_breadcrumbs:append(state.IdleMode.current)
  546.     end
  547.  
  548.     if (pet.isvalid or state.Buff.Pet) and idleSet.Pet then
  549.         idleSet = idleSet.Pet
  550.         petStatus = petStatus or pet.status
  551.         mote_vars.set_breadcrumbs:append('Pet')
  552.  
  553.         if petStatus == 'Engaged' and idleSet.Engaged then
  554.             idleSet = idleSet.Engaged
  555.             mote_vars.set_breadcrumbs:append('Engaged')
  556.         end
  557.     end
  558.  
  559.     for _,group in ipairs(classes.CustomIdleGroups) do
  560.         if idleSet[group] then
  561.             idleSet = idleSet[group]
  562.             mote_vars.set_breadcrumbs:append(group)
  563.         end
  564.     end
  565.  
  566.     idleSet = apply_defense(idleSet)
  567.     idleSet = apply_kiting(idleSet)
  568.  
  569.     if user_customize_idle_set then
  570.         idleSet = user_customize_idle_set(idleSet)
  571.     end
  572.  
  573.     if customize_idle_set then
  574.         idleSet = customize_idle_set(idleSet)
  575.     end
  576.  
  577.     return idleSet
  578. end
  579.  
  580.  
  581. -- Returns the appropriate melee set based on current state values.
  582. -- Set construction order (all sets after sets.engaged are optional):
  583. --   sets.engaged[state.CombatForm][state.CombatWeapon][state.OffenseMode][state.DefenseMode][classes.CustomMeleeGroups (any number)]
  584. function get_melee_set()
  585.     local meleeSet = sets.engaged
  586.    
  587.     if not meleeSet then
  588.         return {}
  589.     end
  590.    
  591.     mote_vars.set_breadcrumbs:append('sets')
  592.     mote_vars.set_breadcrumbs:append('engaged')
  593.  
  594.     if state.CombatForm.has_value and meleeSet[state.CombatForm.value] then
  595.         meleeSet = meleeSet[state.CombatForm.value]
  596.         mote_vars.set_breadcrumbs:append(state.CombatForm.value)
  597.     end
  598.  
  599.     if state.CombatWeapon.has_value and meleeSet[state.CombatWeapon.value] then
  600.         meleeSet = meleeSet[state.CombatWeapon.value]
  601.         mote_vars.set_breadcrumbs:append(state.CombatWeapon.value)
  602.     end
  603.  
  604.     if meleeSet[state.OffenseMode.current] then
  605.         meleeSet = meleeSet[state.OffenseMode.current]
  606.         mote_vars.set_breadcrumbs:append(state.OffenseMode.current)
  607.     end
  608.  
  609.     if meleeSet[state.HybridMode.current] then
  610.         meleeSet = meleeSet[state.HybridMode.current]
  611.         mote_vars.set_breadcrumbs:append(state.HybridMode.current)
  612.     end
  613.  
  614.     for _,group in ipairs(classes.CustomMeleeGroups) do
  615.         if meleeSet[group] then
  616.             meleeSet = meleeSet[group]
  617.             mote_vars.set_breadcrumbs:append(group)
  618.         end
  619.     end
  620.  
  621.     meleeSet = apply_defense(meleeSet)
  622.     meleeSet = apply_kiting(meleeSet)
  623.  
  624.     if customize_melee_set then
  625.         meleeSet = customize_melee_set(meleeSet)
  626.     end
  627.  
  628.     if user_customize_melee_set then
  629.         meleeSet = user_customize_melee_set(meleeSet)
  630.     end
  631.  
  632.     return meleeSet
  633. end
  634.  
  635.  
  636. -- Returns the appropriate resting set based on current state values.
  637. -- Set construction order:
  638. --   sets.resting[state.RestingMode]
  639. function get_resting_set()
  640.     local restingSet = sets.resting
  641.  
  642.     if not restingSet then
  643.         return {}
  644.     end
  645.  
  646.     mote_vars.set_breadcrumbs:append('sets')
  647.     mote_vars.set_breadcrumbs:append('resting')
  648.  
  649.     if restingSet[state.RestingMode.current] then
  650.         restingSet = restingSet[state.RestingMode.current]
  651.         mote_vars.set_breadcrumbs:append(state.RestingMode.current)
  652.     end
  653.  
  654.     return restingSet
  655. end
  656.  
  657.  
  658. -------------------------------------------------------------------------------------------------------------------
  659. -- Functions for constructing default gear sets based on action.
  660. -------------------------------------------------------------------------------------------------------------------
  661.  
  662. -- Get the default precast gear set.
  663. function get_precast_set(spell, spellMap)
  664.     -- If there are no precast sets defined, bail out.
  665.     if not sets.precast then
  666.         return {}
  667.     end
  668.  
  669.     local equipSet = sets.precast
  670.  
  671.     mote_vars.set_breadcrumbs:append('sets')
  672.     mote_vars.set_breadcrumbs:append('precast')
  673.    
  674.     -- Determine base sub-table from type of action being performed.
  675.    
  676.     local cat
  677.    
  678.     if spell.action_type == 'Magic' then
  679.         cat = 'FC'
  680.     elseif spell.action_type == 'Ranged Attack' then
  681.         cat = (sets.precast.RangedAttack and 'RangedAttack') or 'RA'
  682.     elseif spell.action_type == 'Ability' then
  683.         if spell.type == 'WeaponSkill' then
  684.             cat = 'WS'
  685.         elseif spell.type == 'JobAbility' then
  686.             cat = 'JA'
  687.         else
  688.             -- Allow fallback to .JA table if spell.type isn't found, for all non-weaponskill abilities.
  689.             cat = (sets.precast[spell.type] and spell.type) or 'JA'
  690.         end
  691.     elseif spell.action_type == 'Item' then
  692.         cat = 'Item'
  693.     end
  694.    
  695.     -- If no proper sub-category is defined in the job file, bail out.
  696.     if cat then
  697.         if equipSet[cat] then
  698.             equipSet = equipSet[cat]
  699.             mote_vars.set_breadcrumbs:append(cat)
  700.         else
  701.             mote_vars.set_breadcrumbs:clear()
  702.             return {}
  703.         end
  704.     end
  705.  
  706.     classes.SkipSkillCheck = false
  707.     -- Handle automatic selection of set based on spell class/name/map/skill/type.
  708.     equipSet = select_specific_set(equipSet, spell, spellMap)
  709.  
  710.    
  711.     -- Once we have a named base set, do checks for specialized modes (casting mode, weaponskill mode, etc).
  712.    
  713.     if spell.action_type == 'Magic' then
  714.         if equipSet[state.CastingMode.current] then
  715.             equipSet = equipSet[state.CastingMode.current]
  716.             mote_vars.set_breadcrumbs:append(state.CastingMode.current)
  717.         end
  718.     elseif spell.type == 'WeaponSkill' then
  719.         equipSet = get_weaponskill_set(equipSet, spell, spellMap)
  720.     elseif spell.action_type == 'Ability' then
  721.         if classes.JAMode and equipSet[classes.JAMode] then
  722.             equipSet = equipSet[classes.JAMode]
  723.             mote_vars.set_breadcrumbs:append(classes.JAMode)
  724.         end
  725.     elseif spell.action_type == 'Ranged Attack' then
  726.         equipSet = get_ranged_set(equipSet, spell, spellMap)
  727.     end
  728.  
  729.     -- Update defintions for element-specific gear that may be used.
  730.     set_elemental_gear(spell)
  731.    
  732.     -- Return whatever we've constructed.
  733.     return equipSet
  734. end
  735.  
  736.  
  737.  
  738. -- Get the default midcast gear set.
  739. -- This builds on sets.midcast.
  740. function get_midcast_set(spell, spellMap)
  741.     -- If there are no midcast sets defined, bail out.
  742.     if not sets.midcast then
  743.         return {}
  744.     end
  745.    
  746.     local equipSet = sets.midcast
  747.  
  748.     mote_vars.set_breadcrumbs:append('sets')
  749.     mote_vars.set_breadcrumbs:append('midcast')
  750.    
  751.     -- Determine base sub-table from type of action being performed.
  752.     -- Only ranged attacks and items get specific sub-categories here.
  753.    
  754.     local cat
  755.  
  756.     if spell.action_type == 'Ranged Attack' then
  757.         cat = (sets.precast.RangedAttack and 'RangedAttack') or 'RA'
  758.     elseif spell.action_type == 'Item' then
  759.         cat = 'Item'
  760.     end
  761.    
  762.     -- If no proper sub-category is defined in the job file, bail out.
  763.     if cat then
  764.         if equipSet[cat] then
  765.             equipSet = equipSet[cat]
  766.             mote_vars.set_breadcrumbs:append(cat)
  767.         else
  768.             mote_vars.set_breadcrumbs:clear()
  769.             return {}
  770.         end
  771.     end
  772.    
  773.     classes.SkipSkillCheck = classes.NoSkillSpells:contains(spell.english)
  774.     -- Handle automatic selection of set based on spell class/name/map/skill/type.
  775.     equipSet = select_specific_set(equipSet, spell, spellMap)
  776.    
  777.     -- After the default checks, do checks for specialized modes (casting mode, etc).
  778.    
  779.     if spell.action_type == 'Magic' then
  780.         if equipSet[state.CastingMode.current] then
  781.             equipSet = equipSet[state.CastingMode.current]
  782.             mote_vars.set_breadcrumbs:append(state.CastingMode.current)
  783.         end
  784.     elseif spell.action_type == 'Ranged Attack' then
  785.         equipSet = get_ranged_set(equipSet, spell, spellMap)
  786.     end
  787.    
  788.     -- Return whatever we've constructed.
  789.     return equipSet
  790. end
  791.  
  792.  
  793. -- Get the default pet midcast gear set.
  794. -- This is built in sets.midcast.Pet.
  795. function get_pet_midcast_set(spell, spellMap)
  796.     -- If there are no midcast sets defined, bail out.
  797.     if not sets.midcast or not sets.midcast.Pet then
  798.         return {}
  799.     end
  800.  
  801.     local equipSet = sets.midcast.Pet
  802.  
  803.     mote_vars.set_breadcrumbs:append('sets')
  804.     mote_vars.set_breadcrumbs:append('midcast')
  805.     mote_vars.set_breadcrumbs:append('Pet')
  806.  
  807.     if sets.midcast and sets.midcast.Pet then
  808.         classes.SkipSkillCheck = false
  809.         equipSet = select_specific_set(equipSet, spell, spellMap)
  810.  
  811.         -- We can only generally be certain about whether the pet's action is
  812.         -- Magic (ie: it cast a spell of its own volition) or Ability (it performed
  813.         -- an action at the request of the player).  Allow CastinMode and
  814.         -- OffenseMode to refine whatever set was selected above.
  815.         if spell.action_type == 'Magic' then
  816.             if equipSet[state.CastingMode.current] then
  817.                 equipSet = equipSet[state.CastingMode.current]
  818.                 mote_vars.set_breadcrumbs:append(state.CastingMode.current)
  819.             end
  820.         elseif spell.action_type == 'Ability' then
  821.             if equipSet[state.OffenseMode.current] then
  822.                 equipSet = equipSet[state.OffenseMode.current]
  823.                 mote_vars.set_breadcrumbs:append(state.OffenseMode.current)
  824.             end
  825.         end
  826.     end
  827.  
  828.     return equipSet
  829. end
  830.  
  831.  
  832. -- Function to handle the logic of selecting the proper weaponskill set.
  833. function get_weaponskill_set(equipSet, spell, spellMap)
  834.     -- Custom handling for weaponskills
  835.     local ws_mode = state.WeaponskillMode.current
  836.    
  837.     if ws_mode == 'Normal' then
  838.         -- If a particular weaponskill mode isn't specified, see if we have a weaponskill mode
  839.         -- corresponding to the current offense mode.  If so, use that.
  840.         if spell.skill == 'Archery' or spell.skill == 'Marksmanship' then
  841.             if state.RangedMode.current ~= 'Normal' and state.WeaponskillMode:contains(state.RangedMode.current) then
  842.                 ws_mode = state.RangedMode.current
  843.             end
  844.         else
  845.             if state.OffenseMode.current ~= 'Normal' and state.WeaponskillMode:contains(state.OffenseMode.current) then
  846.                 ws_mode = state.OffenseMode.current
  847.             end
  848.         end
  849.     end
  850.  
  851.     local custom_wsmode
  852.  
  853.     -- Allow the job file to specify a preferred weaponskill mode
  854.     if get_custom_wsmode then
  855.         custom_wsmode = get_custom_wsmode(spell, spellMap, ws_mode)
  856.     end
  857.  
  858.     -- If the job file returned a weaponskill mode, use that.
  859.     if custom_wsmode then
  860.         ws_mode = custom_wsmode
  861.     end
  862.  
  863.     if equipSet[ws_mode] then
  864.         equipSet = equipSet[ws_mode]
  865.         mote_vars.set_breadcrumbs:append(ws_mode)
  866.     end
  867.    
  868.     return equipSet
  869. end
  870.  
  871.  
  872. -- Function to handle the logic of selecting the proper ranged set.
  873. function get_ranged_set(equipSet, spell, spellMap)
  874.     -- Attach Combat Form and Combat Weapon to set checks
  875.     if state.CombatForm.has_value and equipSet[state.CombatForm.value] then
  876.         equipSet = equipSet[state.CombatForm.value]
  877.         mote_vars.set_breadcrumbs:append(state.CombatForm.value)
  878.     end
  879.  
  880.     if state.CombatWeapon.has_value and equipSet[state.CombatWeapon.value] then
  881.         equipSet = equipSet[state.CombatWeapon.value]
  882.         mote_vars.set_breadcrumbs:append(state.CombatWeapon.value)
  883.     end
  884.  
  885.     -- Check for specific mode for ranged attacks (eg: Acc, Att, etc)
  886.     if equipSet[state.RangedMode.current] then
  887.         equipSet = equipSet[state.RangedMode.current]
  888.         mote_vars.set_breadcrumbs:append(state.RangedMode.current)
  889.     end
  890.  
  891.     -- Tack on any additionally specified custom groups, if the sets are defined.
  892.     for _,group in ipairs(classes.CustomRangedGroups) do
  893.         if equipSet[group] then
  894.             equipSet = equipSet[group]
  895.             mote_vars.set_breadcrumbs:append(group)
  896.         end
  897.     end
  898.  
  899.     return equipSet
  900. end
  901.  
  902.  
  903. -------------------------------------------------------------------------------------------------------------------
  904. -- Functions for optional supplemental gear overriding the default sets defined above.
  905. -------------------------------------------------------------------------------------------------------------------
  906.  
  907. -- Function to apply any active defense set on top of the supplied set
  908. -- @param baseSet : The set that any currently active defense set will be applied on top of. (gear set table)
  909. function apply_defense(baseSet)
  910.     if state.DefenseMode.current ~= 'None' then
  911.         local defenseSet = sets.defense
  912.  
  913.         defenseSet = sets.defense[state[state.DefenseMode.current .. 'DefenseMode'].current] or defenseSet
  914.  
  915.         for _,group in ipairs(classes.CustomDefenseGroups) do
  916.             defenseSet = defenseSet[group] or defenseSet
  917.         end
  918.  
  919.         if customize_defense_set then
  920.             defenseSet = customize_defense_set(defenseSet)
  921.         end
  922.  
  923.         baseSet = set_combine(baseSet, defenseSet)
  924.     end
  925.  
  926.     return baseSet
  927. end
  928.  
  929.  
  930. -- Function to add kiting gear on top of the base set if kiting state is true.
  931. -- @param baseSet : The gear set that the kiting gear will be applied on top of.
  932. function apply_kiting(baseSet)
  933.     if state.Kiting.value then
  934.         if sets.Kiting then
  935.             baseSet = set_combine(baseSet, sets.Kiting)
  936.         end
  937.     end
  938.  
  939.     return baseSet
  940. end
  941.  
  942.  
  943. -------------------------------------------------------------------------------------------------------------------
  944. -- Utility functions for constructing default gear sets.
  945. -------------------------------------------------------------------------------------------------------------------
  946.  
  947. -- Get a spell mapping for the spell.
  948. function get_spell_map(spell)
  949.     local defaultSpellMap = classes.SpellMaps[spell.english]
  950.     local jobSpellMap
  951.    
  952.     if job_get_spell_map then
  953.         jobSpellMap = job_get_spell_map(spell, defaultSpellMap)
  954.     end
  955.  
  956.     return jobSpellMap or defaultSpellMap
  957. end
  958.  
  959.  
  960. -- Select the equipment set to equip from a given starting table, based on standard
  961. -- selection order: custom class, spell name, spell map, spell skill, and spell type.
  962. -- Spell skill and spell type may further refine their selections based on
  963. -- custom class, spell name and spell map.
  964. function select_specific_set(equipSet, spell, spellMap)
  965.     -- Take the determined base equipment set and try to get the simple naming extensions that
  966.     -- may apply to it (class, spell name, spell map).
  967.     local namedSet = get_named_set(equipSet, spell, spellMap)
  968.    
  969.     -- If no simple naming sub-tables were found, and we simply got back the original equip set,
  970.     -- check for spell.skill and spell.type, then check the simple naming extensions again.
  971.     if namedSet == equipSet then
  972.         if spell.skill and equipSet[spell.skill] and not classes.SkipSkillCheck then
  973.             namedSet = equipSet[spell.skill]
  974.             mote_vars.set_breadcrumbs:append(spell.skill)
  975.         elseif spell.type and equipSet[spell.type] then
  976.             namedSet = equipSet[spell.type]
  977.             mote_vars.set_breadcrumbs:append(spell.type)
  978.         else
  979.             return equipSet
  980.         end
  981.        
  982.         namedSet = get_named_set(namedSet, spell, spellMap)
  983.     end
  984.  
  985.     return namedSet or equipSet
  986. end
  987.  
  988.  
  989. -- Simple utility function to handle a portion of the equipment set determination.
  990. -- It attempts to select a sub-table of the provided equipment set based on the
  991. -- standard search order of custom class, spell name, and spell map.
  992. -- If no such set is found, it returns the original base set (equipSet) provided.
  993. function get_named_set(equipSet, spell, spellMap)
  994.     if equipSet then
  995.         if classes.CustomClass and equipSet[classes.CustomClass] then
  996.             mote_vars.set_breadcrumbs:append(classes.CustomClass)
  997.             return equipSet[classes.CustomClass]
  998.         elseif equipSet[spell.english] then
  999.             mote_vars.set_breadcrumbs:append(spell.english)
  1000.             return equipSet[spell.english]
  1001.         elseif spellMap and equipSet[spellMap] then
  1002.             mote_vars.set_breadcrumbs:append(spellMap)
  1003.             return equipSet[spellMap]
  1004.         else
  1005.             return equipSet
  1006.         end
  1007.     end
  1008. end
  1009.  
  1010.  
  1011. -------------------------------------------------------------------------------------------------------------------
  1012. -- Hooks for other events.
  1013. -------------------------------------------------------------------------------------------------------------------
  1014.  
  1015. -- Called when the player's subjob changes.
  1016. function sub_job_change(newSubjob, oldSubjob)
  1017.     if user_setup then
  1018.         user_setup()
  1019.     end
  1020.    
  1021.     if job_sub_job_change then
  1022.         job_sub_job_change(newSubjob, oldSubjob)
  1023.     end
  1024.    
  1025.     send_command('gs c update')
  1026. end
  1027.  
  1028.  
  1029. -- Called when the player's status changes.
  1030. function status_change(newStatus, oldStatus)
  1031.     -- init a new eventArgs
  1032.     local eventArgs = {handled = false}
  1033.     mote_vars.set_breadcrumbs:clear()
  1034.  
  1035.     -- Allow a global function to be called on status change.
  1036.     if user_status_change then
  1037.         user_status_change(newStatus, oldStatus, eventArgs)
  1038.     end
  1039.  
  1040.     -- Then call individual jobs to handle status change events.
  1041.     if not eventArgs.handled then
  1042.         if job_status_change then
  1043.             job_status_change(newStatus, oldStatus, eventArgs)
  1044.         end
  1045.     end
  1046.  
  1047.     -- Handle equipping default gear if the job didn't mark this as handled.
  1048.     if not eventArgs.handled then
  1049.         handle_equipping_gear(newStatus)
  1050.         display_breadcrumbs()
  1051.     end
  1052. end
  1053.  
  1054.  
  1055. -- Called when a player gains or loses a buff.
  1056. -- buff == buff gained or lost
  1057. -- gain == true if the buff was gained, false if it was lost.
  1058. function buff_change(buff, gain)
  1059.     -- Init a new eventArgs
  1060.     local eventArgs = {handled = false}
  1061.  
  1062.     if state.Buff[buff] ~= nil then
  1063.         state.Buff[buff] = gain
  1064.     end
  1065.  
  1066.     -- Allow a global function to be called on buff change.
  1067.     if user_buff_change then
  1068.         user_buff_change(buff, gain, eventArgs)
  1069.     end
  1070.  
  1071.     -- Allow jobs to handle buff change events.
  1072.     if not eventArgs.handled then
  1073.         if job_buff_change then
  1074.             job_buff_change(buff, gain, eventArgs)
  1075.         end
  1076.     end
  1077. end
  1078.  
  1079.  
  1080. -- Called when a player gains or loses a pet.
  1081. -- pet == pet gained or lost
  1082. -- gain == true if the pet was gained, false if it was lost.
  1083. function pet_change(pet, gain)
  1084.     -- Init a new eventArgs
  1085.     local eventArgs = {handled = false}
  1086.  
  1087.     -- Allow jobs to handle pet change events.
  1088.     if job_pet_change then
  1089.         job_pet_change(pet, gain, eventArgs)
  1090.     end
  1091.  
  1092.     -- Equip default gear if not handled by the job.
  1093.     if not eventArgs.handled then
  1094.         handle_equipping_gear(player.status)
  1095.     end
  1096. end
  1097.  
  1098.  
  1099. -- Called when the player's pet's status changes.
  1100. -- Note that this is also called after pet_change when the pet is released.
  1101. -- As such, don't automatically handle gear equips.  Only do so if directed
  1102. -- to do so by the job.
  1103. function pet_status_change(newStatus, oldStatus)
  1104.     -- Init a new eventArgs
  1105.     local eventArgs = {handled = false}
  1106.  
  1107.     -- Allow jobs to override this code
  1108.     if job_pet_status_change then
  1109.         job_pet_status_change(newStatus, oldStatus, eventArgs)
  1110.     end
  1111. end
  1112.  
  1113.  
  1114. -------------------------------------------------------------------------------------------------------------------
  1115. -- Debugging functions.
  1116. -------------------------------------------------------------------------------------------------------------------
  1117.  
  1118. -- This is a debugging function that will print the accumulated set selection
  1119. -- breadcrumbs for the default selected set for any given action stage.
  1120. function display_breadcrumbs(spell, spellMap, action)
  1121.     if not _settings.debug_mode then
  1122.         return
  1123.     end
  1124.    
  1125.     local msg = 'Default '
  1126.    
  1127.     if action and spell then
  1128.         msg = msg .. action .. ' set selection for ' .. spell.name
  1129.     end
  1130.    
  1131.     if spellMap then
  1132.         msg = msg .. ' (' .. spellMap .. ')'
  1133.     end
  1134.     msg = msg .. ' : '
  1135.    
  1136.     local cons
  1137.    
  1138.     for _,name in ipairs(mote_vars.set_breadcrumbs) do
  1139.         if not cons then
  1140.             cons = name
  1141.         else
  1142.             if name:contains(' ') or name:contains("'") then
  1143.                 cons = cons .. '["' .. name .. '"]'
  1144.             else
  1145.                 cons = cons .. '.' .. name
  1146.             end
  1147.         end
  1148.     end
  1149.  
  1150.     if cons then
  1151.         if action and cons == ('sets.' .. action) then
  1152.             msg = msg .. "None"
  1153.         else
  1154.             msg = msg .. tostring(cons)
  1155.         end
  1156.         add_to_chat(123, msg)
  1157.     end
  1158. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement