|
Gearswap Support Thread
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:27:33
function job_precast(spell, action, spellMap, eventArgs)
if spell.action_type == 'Ranged Attack' then
if buffactive[581] then
equip(sets.Flurry2)
elseif buffactive[265] then
equip(sets.Flurry)
else
equip(sets.precast.RA)
end
end
end
Not working, equips sets.precast.RA even if i have flurry on, what mote files i need? i only use mote-include. Sorry for taking so long to respond, have been busy lately. I'll need to see the rest of your file in order to address why it's not working properly. Please use http://www.pastebin.com and link it here or PM it to me and I'll try to fix it for you.
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:31:39
Out of curiosity, how would one make it so you automatically equip Councilor's Garb using Mote's files? I tried to do this myself by editing the Mote-Mappings and Mote-Include files then finally my own gearswap but it wasn't successful.
Wish I could get the hang of this! In your function user_setup(), put this line: Code areas.AdoulinCity = S{'Eastern Adoulin','Western Adoulin','Mog Garden','Celennia Memorial Library'} Then, in your function customize_idle_set(idleSet), this: Code if areas.AdoulinCity:contains(world.area) then
idleSet = set_combine(idleSet, {body="Councilor's Garb"})
end If you don't have that function in your file, use this: Code function customize_idle_set(idleSet)
if areas.AdoulinCity:contains(world.area) then
idleSet = set_combine(idleSet, {body="Councilor's Garb"})
end
return idleSet
end
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:37:58
Hello again. I'm reposting this in a better format and hopefully I can be more explicit in what I'm looking for to fix this code. I'm using Kinematic's SMN lua as a base, which does not contain any segment of code dealing with Curing during lightsday or weather. I'd like to add this into my lua, and I can't seem to get the coding correct. What I'm trying to do is have the Hachirin-no-Obi equipped midcast when cures are cast during lightsday and/or weather.
I've put my full lua code below. The relevant portion where I have the weather/day conditions defined is:
Code
-- Custom spell mapping.
function job_get_spell_map(spell, default_spell_map)
if default_spell_map == 'Cure' or default_spell_map == 'Curaga' then
if world.weather_element == 'Light' or world.day_element == 'Light' then
return 'CureWithLightWeather'
end
elseif spell.type == 'BloodPactRage' then
if magicalRagePacts:contains(spell.english) then
return 'MagicalBloodPactRage'
else
return 'PhysicalBloodPactRage'
end
elseif spell.type == 'BloodPactWard' and spell.target.type == 'MONSTER' then
return 'DebuffBloodPactWard'
end
end
The result when I run my lua file is that I end up casting Cures with my precast belt (verified by having the showswaps on) during lightsday or light weather.
If someone could help figure this out I'd be very appreciative.
Full lua code: Code -------------------------------------------------------------------------------------------------------------------
-- Setup functions for this job. Generally should not be modified.
-------------------------------------------------------------------------------------------------------------------
-- Also, you'll need the Shortcuts addon to handle the auto-targetting of the custom pact commands.
--[[
Custom commands:
gs c petweather
Automatically casts the storm appropriate for the current avatar, if possible.
gs c siphon
Automatically run the process to: dismiss the current avatar; cast appropriate
weather; summon the appropriate spirit; Elemental Siphon; release the spirit;
and re-summon the avatar.
Will not cast weather you do not have access to.
Will not re-summon the avatar if one was not out in the first place.
Will not release the spirit if it was out before the command was issued.
gs c pact [PactType]
Attempts to use the indicated pact type for the current avatar.
PactType can be one of:
cure
curaga
buffOffense
buffDefense
buffSpecial
debuff1
debuff2
sleep
nuke2
nuke4
bp70
bp75 (merits and lvl 75-80 pacts)
astralflow
--]]
-- Initialization function for this job file.
function get_sets()
mote_include_version = 2
-- Load and initialize the include file.
include('Mote-Include.lua')
end
-- Setup vars that are user-independent. state.Buff vars initialized here will automatically be tracked.
function job_setup()
state.Buff["Avatar's Favor"] = buffactive["Avatar's Favor"] or false
state.Buff["Astral Conduit"] = buffactive["Astral Conduit"] or false
spirits = S{"LightSpirit", "DarkSpirit", "FireSpirit", "EarthSpirit", "WaterSpirit", "AirSpirit", "IceSpirit", "ThunderSpirit"}
avatars = S{"Carbuncle", "Fenrir", "Diabolos", "Ifrit", "Titan", "Leviathan", "Garuda", "Shiva", "Ramuh", "Odin", "Alexander", "Cait Sith"}
magicalRagePacts = S{
'Inferno','Earthen Fury','Tidal Wave','Aerial Blast','Diamond Dust','Judgment Bolt','Searing Light','Howling Moon','Ruinous Omen',
'Fire II','Stone II','Water II','Aero II','Blizzard II','Thunder II',
'Fire IV','Stone IV','Water IV','Aero IV','Blizzard IV','Thunder IV',
'Thunderspark','Burning Strike','Meteorite','Nether Blast','Flaming Crush',
'Meteor Strike','Heavenly Strike','Wind Blade','Geocrush','Grand Fall','Thunderstorm',
'Holy Mist','Lunar Bay','Night Terror','Level ? Holy'}
pacts = {}
pacts.cure = {['Carbuncle']='Healing Ruby'}
pacts.curaga = {['Carbuncle']='Healing Ruby II', ['Garuda']='Whispering Wind', ['Leviathan']='Spring Water'}
pacts.buffoffense = {['Carbuncle']='Glittering Ruby', ['Ifrit']='Crimson Howl', ['Garuda']='Hastega', ['Garuda']='Hastega II', ['Ramuh']='Rolling Thunder',
['Fenrir']='Ecliptic Growl'}
pacts.buffdefense = {['Carbuncle']='Shining Ruby', ['Shiva']='Frost Armor', ['Garuda']='Aerial Armor', ['Titan']='Earthen Ward',
['Ramuh']='Lightning Armor', ['Fenrir']='Ecliptic Howl', ['Diabolos']='Noctoshield', ['Cait Sith']='Reraise II'}
pacts.buffspecial = {['Ifrit']='Inferno Howl', ['Garuda']='Fleet Wind', ['Titan']='Earthen Armor', ['Diabolos']='Dream Shroud',
['Carbuncle']='Soothing Ruby', ['Fenrir']='Heavenward Howl', ['Cait Sith']='Raise II'}
pacts.debuff1 = {['Shiva']='Diamond Storm', ['Ramuh']='Shock Squall', ['Leviathan']='Tidal Roar', ['Fenrir']='Lunar Cry',
['Diabolos']='Pavor Nocturnus', ['Cait Sith']='Eerie Eye'}
pacts.debuff2 = {['Shiva']='Sleepga', ['Leviathan']='Slowga', ['Fenrir']='Lunar Roar', ['Diabolos']='Somnolence'}
pacts.sleep = {['Shiva']='Sleepga', ['Diabolos']='Nightmare', ['Cait Sith']='Mewing Lullaby'}
pacts.nuke2 = {['Ifrit']='Fire II', ['Shiva']='Blizzard II', ['Garuda']='Aero II', ['Titan']='Stone II',
['Ramuh']='Thunder II', ['Leviathan']='Water II'}
pacts.nuke4 = {['Ifrit']='Fire IV', ['Shiva']='Blizzard IV', ['Garuda']='Aero IV', ['Titan']='Stone IV',
['Ramuh']='Thunder IV', ['Leviathan']='Water IV'}
pacts.bp70 = {['Ifrit']='Flaming Crush', ['Shiva']='Rush', ['Garuda']='Predator Claws', ['Titan']='Mountain Buster',
['Ramuh']='Chaotic Strike', ['Leviathan']='Spinning Dive', ['Carbuncle']='Meteorite', ['Fenrir']='Eclipse Bite',
['Diabolos']='Nether Blast',['Cait Sith']='Regal Scratch'}
pacts.bp75 = {['Ifrit']='Meteor Strike', ['Shiva']='Heavenly Strike', ['Garuda']='Wind Blade', ['Titan']='Geocrush',
['Ramuh']='Thunderstorm', ['Leviathan']='Grand Fall', ['Carbuncle']='Holy Mist', ['Fenrir']='Lunar Bay',
['Diabolos']='Night Terror', ['Cait Sith']='Level ? Holy'}
pacts.astralflow = {['Ifrit']='Inferno', ['Shiva']='Diamond Dust', ['Garuda']='Aerial Blast', ['Titan']='Earthen Fury',
['Ramuh']='Judgment Bolt', ['Leviathan']='Tidal Wave', ['Carbuncle']='Searing Light', ['Fenrir']='Howling Moon',
['Diabolos']='Ruinous Omen', ['Cait Sith']="Altana's Favor"}
-- Wards table for creating custom timers
wards = {}
-- Base duration for ward pacts.
wards.durations = {
['Crimson Howl'] = 60, ['Earthen Armor'] = 60, ['Inferno Howl'] = 60, ['Heavenward Howl'] = 60,
['Rolling Thunder'] = 120, ['Fleet Wind'] = 120,
['Shining Ruby'] = 180, ['Frost Armor'] = 180, ['Lightning Armor'] = 180, ['Ecliptic Growl'] = 180,
['Glittering Ruby'] = 180, ['Hastega'] = 180, ['Noctoshield'] = 180, ['Ecliptic Howl'] = 180,
['Dream Shroud'] = 180,
['Reraise II'] = 3600
}
-- Icons to use when creating the custom timer.
wards.icons = {
['Earthen Armor'] = 'spells/00299.png', -- 00299 for Titan
['Shining Ruby'] = 'spells/00043.png', -- 00043 for Protect
['Dream Shroud'] = 'spells/00304.png', -- 00304 for Diabolos
['Noctoshield'] = 'spells/00106.png', -- 00106 for Phalanx
['Inferno Howl'] = 'spells/00298.png', -- 00298 for Ifrit
['Hastega'] = 'spells/00358.png', -- 00358 for Hastega
['Rolling Thunder'] = 'spells/00104.png', -- 00358 for Enthunder
['Frost Armor'] = 'spells/00250.png', -- 00250 for Ice Spikes
['Lightning Armor'] = 'spells/00251.png', -- 00251 for Shock Spikes
['Reraise II'] = 'spells/00135.png', -- 00135 for Reraise
['Fleet Wind'] = 'abilities/00074.png', --
}
-- Flags for code to get around the issue of slow skill updates.
wards.flag = false
wards.spell = ''
end
-------------------------------------------------------------------------------------------------------------------
-- User setup functions for this job. Recommend that these be overridden in a sidecar file.
-------------------------------------------------------------------------------------------------------------------
-- Setup vars that are user-dependent. Can override this function in a sidecar file.
function user_setup()
state.OffenseMode:options('None', 'Normal', 'Acc')
state.CastingMode:options('Normal', 'Resistant')
state.IdleMode:options('Normal', 'PDT')
gear.perp_staff = {name=""}
select_default_macro_book()
end
-- Define sets and vars used by this job file.
function init_gear_sets()
--------------------------------------
-- Precast Sets
--------------------------------------
-- Precast sets to enhance JAs
sets.precast.JA['Astral Flow'] = {head="Glyphic Horn"}
sets.precast.JA['Elemental Siphon'] = {main="Soulscourge",
head="Caller's Horn +2",sub="Vox Grip",neck="Caller's Pendant",
body="Anhur Robe",hands="Summoner's Bracers +2",ring2="Evoker's Ring",ring1="Fervor Ring",
legs="Caller's Spats +2",waist="Cimmerian Sash",feet="Caller's Pigaches +2"}
sets.precast.JA['Mana Cede'] = {hands="Caller's Bracers +2"}
-- Pact delay reduction gear
sets.precast.BloodPactWard = {head="Summoner's Horn", ammo="Eminent Sachet", ear1="Caller's Earring", body="Yinyang Robe",hands="Summoner's Bracers +2",
back="Tiresias' Cape", legs="Summoner's Spats", feet="Summoner's Pigaches"}
sets.precast.BloodPactRage = sets.precast.BloodPactWard
-- Fast cast sets for spells
sets.precast.FC = {
head="Nares Cap",ear1="Loquacious Earring",ammo="Impatiens",
body="Anhur Robe",hands="Rubeus Gloves",
back="Swith Cape",waist="Witful Belt",legs="Rubeus Spats",feet="Rostrum Pumps"}
sets.precast.FC['Enhancing Magic'] = set_combine(sets.precast.FC, {waist="Siegel Sash"})
sets.precast.FC['Healing Magic'] = set_combine(sets.precast.FC, {body="Heka's Kalasiris"})
-- Weaponskill sets
-- Default set for any weaponskill that isn't any more specifically defined
sets.precast.WS = {
head="Nahtirah Hat",neck="Asperity Necklace",ear1="Bladeborn Earring",ear2="Steelflash Earring",
body="Vanir Cotehardie",hands="Yaoyotl Gloves",ring1="Rajas Ring",ring2="K'ayres Ring",
back="Pahtli Cape",waist="Cascade Belt",legs="Hagondes Pants",feet="Hagondes Sabots"}
-- Specific weaponskill sets. Uses the base set if an appropriate WSMod version isn't found.
sets.precast.WS['Myrkr'] = {
head="Nahtirah Hat",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Convoker's Doublet",hands="Caller's Bracers +2",ring1="Evoker's Ring",ring2="Sangoma Ring",
back="Pahtli Cape",waist="Fucho-no-Obi",legs="Nares Trews",feet="Chelona Boots +1"}
--------------------------------------
-- Midcast sets
--------------------------------------
sets.midcast.FastRecast = {
head="Nahtirah Hat",ear2="Loquacious Earring",
body="Vanir Cotehardie",hands="Bokwus Gloves",ring1="Prolix Ring",
back="Swith Cape +1",waist="Witful Belt",legs="Hagondes Pants",feet="Hagondes Sabots"}
sets.midcast.Cure = {main="Arka IV",sub="Bugard Strap +1",
head="Nares Cap",neck="Phalaina Locket",ear1="Magnetic Earring",
body="Heka's Kalasiris",hands="Serpentes Cuffs",ring1="Tamas Ring",
back="Swith Cape +1",waist="Penitent's Rope",legs="Nares Trews",feet="Serpentes Sabots"}
sets.midcast.CureWithLightWeather = {waist="Hachirin-no-Obi"}
sets.midcast.Stoneskin = {main="Kirin's Pole",sub="Bugard Strap+1", neck="Colossus's Torque", body="Anhur Robe",waist="Penitent's Rope",ring1="Tamas Ring",
back="Merciful Cape",legs="Nares Trews",feet="Rubeus Boots"}
sets.midcast.Barfira = sets.midcast.Stoneskin
sets.midcast.Baraera = sets.midcast.Stoneskin
sets.midcast.Barblizzara = sets.midcast.Stoneskin
sets.midcast.Barwatera = sets.midcast.Stoneskin
sets.midcast.Barthundra = sets.midcast.Stoneskin
sets.midcast.Barstonra = sets.midcast.Stoneskin
sets.midcast.Barvira = sets.midcast.Stoneskin
sets.midcast.Barsleepra = sets.midcast.Stoneskin
sets.midcast.Barparalyzra = sets.midcast.Stoneskin
sets.midcast.Barpoisonra = sets.midcast.Stoneskin
sets.midcast.Barblindra = sets.midcast.Stoneskin
sets.midcast.Barsilencera = sets.midcast.Stoneskin
sets.midcast.Barpetra = sets.midcast.Stoneskin
sets.midcast.Barfire = sets.midcast.Stoneskin
sets.midcast.Baraero = sets.midcast.Stoneskin
sets.midcast.Barblizzard = sets.midcast.Stoneskin
sets.midcast.Barwater = sets.midcast.Stoneskin
sets.midcast.Barthunder = sets.midcast.Stoneskin
sets.midcast.Barstone = sets.midcast.Stoneskin
sets.midcast.Barvirus = sets.midcast.Stoneskin
sets.midcast.Barsleep = sets.midcast.Stoneskin
sets.midcast.Barparalyze = sets.midcast.Stoneskin
sets.midcast.Barpoison = sets.midcast.Stoneskin
sets.midcast.Barblind = sets.midcast.Stoneskin
sets.midcast.Barsilence = sets.midcast.Stoneskin
sets.midcast.Barpetrify = sets.midcast.Stoneskin
sets.midcast['Elemental Magic'] = {main="Lehbrailg +2",sub="Wizzan Grip",
head="Hagondes Hat",neck="Stoicheion Medal",ear1="Friomisi Earring",ear2="Hecate's Earring",
body="Hagondes Coat",hands="Yaoyotl Gloves",ring1="Icesoul Ring",ring2="Acumen Ring",
back="Toro Cape",waist=gear.ElementalBelt,legs="Hagondes Pants",feet="Hagondes Sabots"}
sets.midcast['Dark Magic'] = {main="Lehbrailg +2",sub="Wizzan Grip",
head="Nahtirah Hat",neck="Aesir Torque",ear1="Lifestorm Earring",ear2="Psystorm Earring",
body="Vanir Cotehardie",hands="Yaoyotl Gloves",ring1="Excelsis Ring",ring2="Sangoma Ring",
waist="Fuchi-no-Obi",legs="Bokwus Slops",feet="Bokwus Boots"}
-- Avatar pact sets. All pacts are Ability type.
sets.midcast.Pet.BloodPactWard = {main="Soulscourge",sub="Vox Grip",head="Caller's Horn +2",neck="Caller's Pendant", ammo="Eminent Sachet",
body="Anhur Robe",hands="Summoner's Bracers +2",ring2="Evoker's Ring",ring1="Fervor Ring",
legs="Caller's Spats +2",waist="Cimmerian Sash",feet="Rubeus Boots"}
sets.midcast.Pet.DebuffBloodPactWard = {main="Soulscourge",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",
body="Caller's Doublet +2",hands="Summoner's Bracers +2",ring2="Evoker's Ring",ring1="Fervor Ring",
waist="Cimmerian Sash",legs="Caller's Spats +2",feet="Caller's Pigaches +2"}
sets.midcast.Pet.DebuffBloodPactWard.Acc = sets.midcast.Pet.DebuffBloodPactWard
sets.midcast.Pet.PhysicalBloodPactRage = {main="Soulscourge",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",
body="Caller's Doublet +2",hands="Summoner's Bracers +2",ring1="Evoker's Ring",ring2="Fervor Ring",
waist="Cimmerian Sash",legs="Caller's Spats +2",feet="Summoner's Pigaches"}
sets.midcast.Pet.PhysicalBloodPactRage.Acc = sets.midcast.Pet.PhysicalBloodPactRage
sets.midcast.Pet.MagicalBloodPactRage = {main="Balsam Staff",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",
body="Caller's Doublet +2",hands="Glyphic Bracers",ring1="Evoker's Ring",ring2="Fervor Ring",
back="Tiresias' Cape",waist="Cimmerian Sash",legs="Caller's Spats +2",feet="Caller's Pigaches +2"}
sets.midcast.Pet.MagicalBloodPactRage.Acc = sets.midcast.Pet.MagicalBloodPactRage
-- Spirits cast magic spells, which can be identified in standard ways.
sets.midcast.Pet.WhiteMagic = {legs="Summoner's Spats"}
sets.midcast.Pet['Elemental Magic'] = set_combine(sets.midcast.Pet.BloodPactRage, {legs="Summoner's Spats"})
sets.midcast.Pet['Elemental Magic'].Resistant = {}
--------------------------------------
-- Idle/resting/defense/etc sets
--------------------------------------
-- Resting sets
sets.resting = sets.idle
-- Idle sets
sets.idle = {main="Owleyes",sub="Genbu's Shield",
head="Caller's Horn +2",ear2="Moonshade Earring",ear1="Loquacious Earring",
body="Orvail Robe",hands="Serpentes Cuffs",ring1="Dark Ring",ring2="Evoker's Ring",
back="Merciful Cape",waist="Tarutaru Sash",legs="Tatsumaki Sitagoromo",feet="Serpentes Sabots"}
sets.idle.PDT = {main=gear.Staff.PDT,sub="Vox Grip",ammo="Eminent Sachet",
head="Convoker's Horn",neck="Twilight Torque",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Hagondes Coat",hands="Yaoyotl Gloves",ring1="Defending Ring",ring2="Sangoma Ring",
back="Umbra Cape",waist="Fucho-no-Obi",legs="Hagondes Pants",feet="Herald's Gaiters"}
-- perp costs:
-- spirits: 7
-- carby: 11 (5 with mitts)
-- fenrir: 13
-- others: 15
-- avatar's favor: -4/tick
-- Max useful -perp gear is 1 less than the perp cost (can't be reduced below 1)
-- Aim for -14 perp, and refresh in other slots.
-- -perp gear:
-- Gridarvor: -5
-- Glyphic Horn: -4
-- Caller's Doublet +2/Glyphic Doublet: -4
-- Evoker's Ring: -1
-- Convoker's Pigaches: -4
-- total: -18
-- Can make due without either the head or the body, and use +refresh items in those slots.
sets.idle.Avatar = {main="Chatoyant Staff",sub="Vox Grip",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",ear1="Caller's Earring",ear2="Moonshade Earring",
body="Caller's Doublet +2",hands="Serpentes Cuffs",ring2="Evoker's Ring",ring1="Dark Ring",
back="Merciful Cape",waist="Moepapa Stone",legs="Nares Trews",feet="Caller's Pigaches +2"}
sets.idle.PDT.Avatar = {main="Gridarvor",sub="Vox Grip",ammo="Eminent Sachet",
head="Convoker's Horn",neck="Caller's Pendant",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Hagondes Coat",hands="Regimen Mittens",ring1="Evoker's Ring",ring2="Defending Ring",
back="Conveyance Cape",waist="Fucho-no-Obi",legs="Hagondes Pants",feet="Convoker's Pigaches"}
sets.idle.Spirit = {main="Chatoyant Staff",sub="Vox Grip",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",ear1="Caller's Earring",ear2="Moonshade Earring",
body="Caller's Doublet +2",hands="Serpentes Cuffs",ring2="Evoker's Ring",ring1="Dark Ring",
back="Merciful Cape",waist="Moepapa Stone",legs="Summoner's Spats",feet="Caller's Pigaches +2"}
sets.idle.Town = {main="Owleyes",sub="Genbu's Shield",ammo="Eminent Sachet",
head="Caller's Horn +2",ear2="Moonshade Earring",ear1="Loquacious Earring",
body="Orvail Robe",hands="Serpentes Cuffs",ring1="Dark Ring",ring2="Evoker's Ring",
back="Merciful Cape",waist="Tarutaru Sash",legs="Tatsumaki Sitagoromo",feet="Serpentes Sabots"}
-- Favor uses Caller's Horn instead of Convoker's Horn for refresh
sets.idle.Avatar.Favor = {head="Caller's Horn +2",sub="Vox Grip",neck="Caller's Pendant",
body="Anhur Robe",hands="Summoner's Bracers +2",ring2="Evoker's Ring",ring1="Fervor Ring",
legs="Caller's Spats +2",waist="Cimmerian Sash",feet="Caller's Pigaches +2"}
sets.idle.Avatar.Melee = {hands="Regimen Mittens",back="Samanisi Cape",waist="Kuku Stone",legs="Convoker's Spats"}
sets.perp = {}
-- Caller's Bracer's halve the perp cost after other costs are accounted for.
-- Using -10 (Gridavor, ring, Conv.feet), standard avatars would then cost 5, halved to 2.
-- We can then use Hagondes Coat and end up with the same net MP cost, but significantly better defense.
-- Weather is the same, but we can also use the latent on the pendant to negate the last point lost.
sets.perp.Day = {hands="Caller's Bracers +2"}
sets.perp.Weather = {neck="Caller's Pendant",hands="Caller's Bracers +2"}
-- Carby: Mitts+Conv.feet = 1/tick perp. Everything else should be +refresh
sets.perp.Carbuncle = {main="Chatoyant Staff",sub="Vox Grip",
head="Caller's Horn +2",body="Orvail Robe",hands="Carbuncle Mitts",legs="Nares Trews",feet="Caller's Pigaches +2"}
-- Garuda Perp:
sets.perp.Garuda = {main="Vayuvata III",sub="Vox Grip",ammo="Eminent Sachet",
head="Caller's Horn +2",neck="Caller's Pendant",ear1="Caller's Earring",ear2="Moonshade Earring",
body="Caller's Doublet +2",hands="Serpentes Cuffs",ring2="Evoker's Ring",ring1="Dark Ring",
back="Merciful Cape",waist="Moepapa Stone",legs="Nares Trews",feet="Caller's Pigaches +2"}
-- Diabolos's Rope doesn't gain us anything at this time
--sets.perp.Diabolos = {waist="Diabolos's Rope"}
sets.perp.Alexander = sets.midcast.Pet.BloodPactWard
sets.perp.staff_and_grip = {main=gear.perp_staff,sub="Vox Grip"}
-- Defense sets
sets.defense.PDT = {main=gear.Staff.PDT,
head="Hagondes Hat",neck="Wiglen Gorget",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Hagondes Coat",hands="Yaoyotl Gloves",ring1="Defending Ring",ring2=gear.DarkRing.physical,
back="Umbra Cape",waist="Fucho-no-Obi",legs="Hagondes Pants",feet="Hagondes Sabots"}
sets.defense.MDT = {
head="Hagondes Hat",neck="Twilight Torque",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Vanir Cotehardie",hands="Yaoyotl Gloves",ring1="Defending Ring",ring2="Shadow Ring",
back="Umbra Cape",waist="Fucho-no-Obi",legs="Bokwus Slops",feet="Hagondes Sabots"}
sets.Kiting = {legs="Tatsumaki Sitagoromo"}
sets.latent_refresh = {waist="Fucho-no-obi"}
--------------------------------------
-- Engaged sets
--------------------------------------
-- Normal melee group
sets.engaged = {ammo="Eminent Sachet",
head="Zelus Tiara",neck="Asperity Necklace",ear1="Bladeborn Earring",ear2="Steelflash Earring",
body="Vanir Cotehardie",hands="Bokwus Gloves",ring1="Rajas Ring",ring2="K'ayres Ring",
back="Umbra Cape",waist="Goading Belt",legs="Hagondes Pants",feet="Hagondes Sabots"}
end
-------------------------------------------------------------------------------------------------------------------
-- Job-specific hooks for standard casting events.
-------------------------------------------------------------------------------------------------------------------
-- Set eventArgs.handled to true if we don't want any automatic gear equipping to be done.
-- Set eventArgs.useMidcastGear to true if we want midcast gear equipped on precast.
function job_precast(spell, action, spellMap, eventArgs)
if state.Buff['Astral Conduit'] and pet_midaction() then
eventArgs.handled = true
end
end
function job_midcast(spell, action, spellMap, eventArgs)
if state.Buff['Astral Conduit'] and pet_midaction() then
eventArgs.handled = true
end
end
-- Runs when pet completes an action.
function job_pet_aftercast(spell, action, spellMap, eventArgs)
if not spell.interrupted and spell.type == 'BloodPactWard' and spellMap ~= 'DebuffBloodPactWard' then
wards.flag = true
wards.spell = spell.english
send_command('wait 4; gs c reset_ward_flag')
end
end
-------------------------------------------------------------------------------------------------------------------
-- Job-specific hooks for non-casting events.
-------------------------------------------------------------------------------------------------------------------
-- Called when a player gains or loses a buff.
-- buff == buff gained or lost
-- gain == true if the buff was gained, false if it was lost.
function job_buff_change(buff, gain)
if state.Buff[buff] ~= nil then
handle_equipping_gear(player.status)
elseif storms:contains(buff) then
handle_equipping_gear(player.status)
end
end
-- Called when the player's pet's status changes.
-- This is also called after pet_change after a pet is released. Check for pet validity.
function job_pet_status_change(newStatus, oldStatus, eventArgs)
if pet.isvalid and not midaction() and not pet_midaction() and (newStatus == 'Engaged' or oldStatus == 'Engaged') then
handle_equipping_gear(player.status, newStatus)
end
end
-- Called when a player gains or loses a pet.
-- pet == pet structure
-- gain == true if the pet was gained, false if it was lost.
function job_pet_change(petparam, gain)
classes.CustomIdleGroups:clear()
if gain then
if avatars:contains(pet.name) then
classes.CustomIdleGroups:append('Avatar')
elseif spirits:contains(pet.name) then
classes.CustomIdleGroups:append('Spirit')
end
else
select_default_macro_book('reset')
end
end
-------------------------------------------------------------------------------------------------------------------
-- User code that supplements standard library decisions.
-------------------------------------------------------------------------------------------------------------------
-- Custom spell mapping.
function job_get_spell_map(spell, default_spell_map)
if default_spell_map == 'Cure' or default_spell_map == 'Curaga' then
if world.weather_element == 'Light' or world.day_element == 'Light' then
return 'CureWithLightWeather'
end
elseif spell.type == 'BloodPactRage' then
if magicalRagePacts:contains(spell.english) then
return 'MagicalBloodPactRage'
else
return 'PhysicalBloodPactRage'
end
elseif spell.type == 'BloodPactWard' and spell.target.type == 'MONSTER' then
return 'DebuffBloodPactWard'
end
end
-- Modify the default idle set after it was constructed.
function customize_idle_set(idleSet)
if pet.isvalid then
if pet.element == world.day_element then
idleSet = set_combine(idleSet, sets.perp.Day)
end
if pet.element == world.weather_element then
idleSet = set_combine(idleSet, sets.perp.Weather)
end
if sets.perp[pet.name] then
idleSet = set_combine(idleSet, sets.perp[pet.name])
end
gear.perp_staff.name = elements.perpetuance_staff_of[pet.element]
if gear.perp_staff.name and (player.inventory[gear.perp_staff.name] or player.wardrobe[gear.perp_staff.name]) then
idleSet = set_combine(idleSet, sets.perp.staff_and_grip)
end
if state.Buff["Avatar's Favor"] and avatars:contains(pet.name) then
idleSet = set_combine(idleSet, sets.idle.Avatar.Favor)
end
if pet.status == 'Engaged' then
idleSet = set_combine(idleSet, sets.idle.Avatar.Melee)
end
end
if player.mpp < 51 then
idleSet = set_combine(idleSet, sets.latent_refresh)
end
return idleSet
end
-- Called by the 'update' self-command, for common needs.
-- Set eventArgs.handled to true if we don't want automatic equipping of gear.
function job_update(cmdParams, eventArgs)
classes.CustomIdleGroups:clear()
if pet.isvalid then
if avatars:contains(pet.name) then
classes.CustomIdleGroups:append('Avatar')
elseif spirits:contains(pet.name) then
classes.CustomIdleGroups:append('Spirit')
end
end
end
-- Set eventArgs.handled to true if we don't want the automatic display to be run.
function display_current_job_state(eventArgs)
end
-------------------------------------------------------------------------------------------------------------------
-- User self-commands.
-------------------------------------------------------------------------------------------------------------------
-- Called for custom player commands.
function job_self_command(cmdParams, eventArgs)
if cmdParams[1]:lower() == 'petweather' then
handle_petweather()
eventArgs.handled = true
elseif cmdParams[1]:lower() == 'siphon' then
handle_siphoning()
eventArgs.handled = true
elseif cmdParams[1]:lower() == 'pact' then
handle_pacts(cmdParams)
eventArgs.handled = true
elseif cmdParams[1] == 'reset_ward_flag' then
wards.flag = false
wards.spell = ''
eventArgs.handled = true
end
end
-------------------------------------------------------------------------------------------------------------------
-- Utility functions specific to this job.
-------------------------------------------------------------------------------------------------------------------
-- Cast the appopriate storm for the currently summoned avatar, if possible.
function handle_petweather()
if player.sub_job ~= 'SCH' then
add_to_chat(122, "You can not cast storm spells")
return
end
if not pet.isvalid then
add_to_chat(122, "You do not have an active avatar.")
return
end
local element = pet.element
if element == 'Thunder' then
element = 'Lightning'
end
if S{'Light','Dark','Lightning'}:contains(element) then
add_to_chat(122, 'You do not have access to '..elements.storm_of[element]..'.')
return
end
local storm = elements.storm_of[element]
if storm then
send_command('@input /ma "'..elements.storm_of[element]..'" <me>')
else
add_to_chat(123, 'Error: Unknown element ('..tostring(element)..')')
end
end
-- Custom uber-handling of Elemental Siphon
function handle_siphoning()
if areas.Cities:contains(world.area) then
add_to_chat(122, 'Cannot use Elemental Siphon in a city area.')
return
end
local siphonElement
local stormElementToUse
local releasedAvatar
local dontRelease
-- If we already have a spirit out, just use that.
if pet.isvalid and spirits:contains(pet.name) then
siphonElement = pet.element
dontRelease = true
-- If current weather doesn't match the spirit, but the spirit matches the day, try to cast the storm.
if player.sub_job == 'SCH' and pet.element == world.day_element and pet.element ~= world.weather_element then
if not S{'Light','Dark','Lightning'}:contains(pet.element) then
stormElementToUse = pet.element
end
end
-- If we're subbing /sch, there are some conditions where we want to make sure specific weather is up.
-- If current (single) weather is opposed by the current day, we want to change the weather to match
-- the current day, if possible.
elseif player.sub_job == 'SCH' and world.weather_element ~= 'None' then
-- We can override single-intensity weather; leave double weather alone, since even if
-- it's partially countered by the day, it's not worth changing.
if get_weather_intensity() == 1 then
-- If current weather is weak to the current day, it cancels the benefits for
-- siphon. Change it to the day's weather if possible (+0 to +20%), or any non-weak
-- weather if not.
-- If the current weather matches the current avatar's element (being used to reduce
-- perpetuation), don't change it; just accept the penalty on Siphon.
if world.weather_element == elements.weak_to[world.day_element] and
(not pet.isvalid or world.weather_element ~= pet.element) then
-- We can't cast lightning/dark/light weather, so use a neutral element
if S{'Light','Dark','Lightning'}:contains(world.day_element) then
stormElementToUse = 'Wind'
else
stormElementToUse = world.day_element
end
end
end
end
-- If we decided to use a storm, set that as the spirit element to cast.
if stormElementToUse then
siphonElement = stormElementToUse
elseif world.weather_element ~= 'None' and (get_weather_intensity() == 2 or world.weather_element ~= elements.weak_to[world.day_element]) then
siphonElement = world.weather_element
else
siphonElement = world.day_element
end
local command = ''
local releaseWait = 0
if pet.isvalid and avatars:contains(pet.name) then
command = command..'input /pet "Release" <me>;wait 1.1;'
releasedAvatar = pet.name
releaseWait = 10
end
if stormElementToUse then
command = command..'input /ma "'..elements.storm_of[stormElementToUse]..'" <me>;wait 4;'
releaseWait = releaseWait - 4
end
if not (pet.isvalid and spirits:contains(pet.name)) then
command = command..'input /ma "'..elements.spirit_of[siphonElement]..'" <me>;wait 4;'
releaseWait = releaseWait - 4
end
command = command..'input /ja "Elemental Siphon" <me>;'
releaseWait = releaseWait - 1
releaseWait = releaseWait + 0.1
if not dontRelease then
if releaseWait > 0 then
command = command..'wait '..tostring(releaseWait)..';'
else
command = command..'wait 1.1;'
end
command = command..'input /pet "Release" <me>;'
end
if releasedAvatar then
command = command..'wait 1.1;input /ma "'..releasedAvatar..'" <me>'
end
send_command(command)
end
-- Handles executing blood pacts in a generic, avatar-agnostic way.
-- cmdParams is the split of the self-command.
-- gs c [pact] [pacttype]
function handle_pacts(cmdParams)
if areas.Cities:contains(world.area) then
add_to_chat(122, 'You cannot use pacts in town.')
return
end
if not pet.isvalid then
add_to_chat(122,'No avatar currently available. Returning to default macro set.')
select_default_macro_book('reset')
return
end
if spirits:contains(pet.name) then
add_to_chat(122,'Cannot use pacts with spirits.')
return
end
if not cmdParams[2] then
add_to_chat(123,'No pact type given.')
return
end
local pact = cmdParams[2]:lower()
if not pacts[pact] then
add_to_chat(123,'Unknown pact type: '..tostring(pact))
return
end
if pacts[pact][pet.name] then
if pact == 'astralflow' and not buffactive['astral flow'] then
add_to_chat(122,'Cannot use Astral Flow pacts at this time.')
return
end
-- Leave out target; let Shortcuts auto-determine it.
send_command('@input /pet "'..pacts[pact][pet.name]..'"')
else
add_to_chat(122,pet.name..' does not have a pact of type ['..pact..'].')
end
end
-- Event handler for updates to player skill, since we can't rely on skill being
-- correct at pet_aftercast for the creation of custom timers.
windower.raw_register_event('incoming chunk',
function (id)
if id == 0x62 then
if wards.flag then
create_pact_timer(wards.spell)
wards.flag = false
wards.spell = ''
end
end
end)
-- Function to create custom timers using the Timers addon. Calculates ward duration
-- based on player skill and base pact duration (defined in job_setup).
function create_pact_timer(spell_name)
-- Create custom timers for ward pacts.
if wards.durations[spell_name] then
local ward_duration = wards.durations[spell_name]
if ward_duration < 181 then
local skill = player.skills.summoning_magic
if skill > 300 then
skill = skill - 300
if skill > 200 then skill = 200 end
ward_duration = ward_duration + skill
end
end
local timer_cmd = 'timers c "'..spell_name..'" '..tostring(ward_duration)..' down'
if wards.icons[spell_name] then
timer_cmd = timer_cmd..' '..wards.icons[spell_name]
end
send_command(timer_cmd)
end
end
-- Select default macro book on initial load or subjob change.
function select_default_macro_book(reset)
if reset == 'reset' then
-- lost pet, or tried to use pact when pet is gone
end
-- Default macro set/book
set_macro_page(4, 16)
end
In your function user_setup(), put this line: Code gear.default.obi_waist = "" and put whatever belt you would normally cast cures without weather/day inside the quotes. Then, in your cure set, rename the waist slot to: and it will automatically trigger with day/weather. If day/weather don't match, it will use your gear.default.obi_waist as listed above.
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:40:19
I have a morally grey question about gearswap. You know how when you get charmed you can't use menus or anything? During that time can gearswap still change your equipment? I don't think so. I've never done any charm testing, as it's difficult to fully test it since there's no way to charm a fellow player. Relying on a mob to charm you through a TP move and testing that way can get tedious, at best. If I get a chance, I'll write something into my personal luas to trigger on a charm and see if the packets still send.
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:45:00
Hi I have this weird error; tried everything including fresh install of gearswap, unloading all other addons and plugins:
Every time I zone, get a drop or buy/sell something from inventory I get following error on my screen (same error repeated 20 times)
Gearswap: Lua runtime error gearswap/gearswap.lua379: attempt to index field '?' (a nil value)
I looked up line 379 in gearswap.lua (but didn't touch anything /scared), wich says:
if not items[bag][slot] then items[bag][slot] = make_empty_item_table(slot) end
Could someone please help me out, this error is making me crazy and unloading gearswap because of that error spam I get bombarded with everytime I zone or my inv changes.
Gearswap seems to be working fine for the rest, if this can't be fixed, I would be happy with a mute method for that error line as well! I no longer get this error, though I did for a short time right after an update (May would sound about right, as posted in the reply comment). This is my gearswap.lua file: Code --Copyright (c) 2013, Byrthnoth
--All rights reserved.
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are met:
-- * Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- * Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
-- * Neither the name of <addon name> nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
--DISCLAIMED. IN NO EVENT SHALL <your name> BE LIABLE FOR ANY
--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
_addon.name = 'GearSwap'
_addon.version = '0.904'
_addon.author = 'Byrth'
_addon.commands = {'gs','gearswap'}
if windower.file_exists(windower.addon_path..'data/bootstrap.lua') then
debugging = {windower_debug = true,command_registry = false,general=false,logging=false}
else
debugging = {}
end
__raw = {lower = string.lower, upper = string.upper, debug=windower.debug,text={create=windower.text.create,
delete=windower.text.delete,registry = {}},prim={create=windower.prim.create,delete=windower.prim.delete,registry={}}}
language = 'english'
file = require 'files'
require 'strings'
require 'tables'
require 'logger'
-- Restore the normal error function (logger changes it)
error = _raw.error
require 'lists'
require 'sets'
windower.text.create = function (str)
if __raw.text.registry[str] then
msg.addon_msg(123,'Text object cannot be created because it already exists.')
else
__raw.text.registry[str] = true
__raw.text.create(str)
end
end
windower.text.delete = function (str)
if __raw.text.registry[str] then
local deleted = false
if windower.text.saved_texts then
for i,v in pairs(windower.text.saved_texts) do
if v._name == str then
__raw.text.registry[str] = nil
windower.text.saved_texts[i]:destroy()
deleted = true
break
end
end
end
if not deleted then
__raw.text.registry[str] = nil
__raw.text.delete(str)
end
else
__raw.text.delete(str)
end
end
windower.prim.create = function (str)
if __raw.prim.registry[str] then
msg.addon_msg(123,'Primitive cannot be created because it already exists.')
else
__raw.prim.registry[str] = true
__raw.prim.create(str)
end
end
windower.prim.delete = function (str)
if __raw.prim.registry[str] then
__raw.prim.registry[str] = nil
__raw.prim.delete(str)
else
__raw.prim.delete(str)
end
end
texts = require 'texts'
require 'pack'
bit = require 'bit'
socket = require 'socket'
mime = require 'mime'
res = require 'resources'
extdata = require 'extdata'
require 'helper_functions'
require 'actions'
-- Resources Checks
if res.items and res.bags and res.slots and res.statuses and res.jobs and res.elements and res.skills and res.buffs and res.spells and res.job_abilities and res.weapon_skills and res.monster_abilities and res.action_messages and res.skills and res.monstrosity and res.weather and res.moon_phases and res.races then
else
error('Missing resources!')
end
require 'statics'
require 'equip_processing'
require 'targets'
require 'user_functions'
require 'refresh'
require 'export'
require 'validate'
require 'flow'
require 'triggers'
windower.register_event('load',function()
windower.debug('load')
refresh_globals()
if world.logged_in then
refresh_user_env()
if debugging.general then windower.send_command('@unload spellcast;') end
end
end)
windower.register_event('unload',function ()
windower.debug('unload')
user_pcall('file_unload')
if logging then logfile:close() end
end)
windower.register_event('addon command',function (...)
windower.debug('addon command')
logit('\n\n'..tostring(os.clock)..table.concat({...},' '))
local splitup = {...}
if not splitup[1] then return end -- handles //gs
for i,v in pairs(splitup) do splitup[i] = windower.from_shift_jis(windower.convert_auto_trans(v)) end
local cmd = table.remove(splitup,1):lower()
if cmd == 'c' then
if gearswap_disabled then return end
if splitup[1] then
refresh_globals()
equip_sets('self_command',nil,_raw.table.concat(splitup,' '))
else
msg.addon_msg(123,'No self command passed.')
end
elseif cmd == 'equip' then
if gearswap_disabled then return end
local key_list = parse_set_to_keys(splitup)
local set = get_set_from_keys(key_list)
if set then
refresh_globals()
equip_sets('equip_command',nil,set)
else
msg.addon_msg(123,'Equip command cannot be completed. That set does not exist.')
end
elseif cmd == 'export' then
export_set(splitup)
elseif cmd == 'validate' then
if user_env and user_env.sets then
refresh_globals()
validate(splitup)
else
msg.addon_msg(123,'There is nothing to validate because there is no file loaded.')
end
elseif cmd == 'l' or cmd == 'load' then
if splitup[1] then
local f_name = table.concat(splitup,' ')
if pathsearch({f_name}) then
refresh_globals()
command_registry = Command_Registry.new()
load_user_files(false,f_name)
else
msg.addon_msg(123,'File not found.')
end
else
msg.addon_msg(123,'No file name was provided.')
end
elseif cmd == 'enable' then
disenable(splitup,command_enable,'enable',false)
elseif cmd == 'disable' then
disenable(splitup,disable,'disable',true)
elseif cmd == 'reload' or cmd == 'r' then
refresh_user_env()
elseif strip(cmd) == 'debugmode' then
_settings.debug_mode = not _settings.debug_mode
print('GearSwap: Debug Mode set to '..tostring(_settings.debug_mode)..'.')
elseif strip(cmd) == 'demomode' then
_settings.demo_mode = not _settings.demo_mode
print('GearSwap: Demo Mode set to '..tostring(_settings.demo_mode)..'.')
elseif strip(cmd) == 'showswaps' then
_settings.show_swaps = not _settings.show_swaps
print('GearSwap: Show Swaps set to '..tostring(_settings.show_swaps)..'.')
elseif _settings.debug_mode and strip(cmd) == 'eval' then
assert(loadstring(table.concat(splitup,' ')))()
else
local handled = false
if not gearswap_disabled then
for i,v in ipairs(unhandled_command_events) do
handled = equip_sets(v,nil,cmd,unpack(splitup))
if handled then break end
end
end
if not handled then
print('GearSwap: Command not found')
end
end
end)
function disenable(tab,funct,functname,pol)
local slot_name = ''
local ltab = L{}
for i,v in pairs(tab) do
ltab:append(v:gsub('[^%a_%d]',''):lower())
end
if ltab:contains('all') then
funct('main','sub','range','ammo','head','neck','lear','rear','body','hands','lring','rring','back','waist','legs','feet')
print('GearSwap: All slots '..functname..'d.')
elseif ltab.n > 0 then
local found = L{}
local not_found = L{}
for slot_name in ltab:it() do
if slot_map[slot_name] then
funct(slot_name)
found:append(slot_name)
else
not_found:append(slot_name)
end
end
if found.n > 0 then
print('GearSwap: '..found:tostring()..' slot'..(found.n>1 and 's' or '')..' '..functname..'d.')
end
if not_found.n > 0 then
print('GearSwap: Unable to find slot'..(not_found.n>1 and 's' or '')..' '..not_found:tostring()..'.')
end
elseif gearswap_disabled ~= pol and not tab[2] then
print('GearSwap: User file '..functname..'d')
gearswap_disabled = pol
end
end
windower.register_event('incoming chunk',function(id,data,modified,injected,blocked)
windower.debug('incoming chunk '..id)
if next_packet_events and next_packet_events.sequence_id ~= data:unpack('H',3) then
if not next_packet_events.globals_update or next_packet_events.globals_update ~= data:unpack('H',3) then
refresh_globals()
next_packet_events.globals_update = data:unpack('H',3)
end
if next_packet_events.pet_status_change then
if pet.isvalid then
equip_sets('pet_status_change',nil,next_packet_events.pet_status_change.newstatus,next_packet_events.pet_status_change.oldstatus)
end
next_packet_events.pet_status_change = nil
end
if next_packet_events.pet_change then
if next_packet_events.pet_change.pet then -- Losing a pet
equip_sets('pet_change',nil,next_packet_events.pet_change.pet,false)
next_packet_events.pet_change = nil
elseif pet.isvalid then -- Gaining a pet
equip_sets('pet_change',nil,pet,true)
next_packet_events.pet_change = nil
end
end
if not next_packet_events.pet_status_change and not next_packet_events.pet_change then
next_packet_events = nil
end
end
if injected then
elseif id == 0x00A then
windower.debug('zone change')
command_registry = Command_Registry.new()
table.clear(not_sent_out_equip)
player.id = data:unpack('I',0x05)
player.index = data:unpack('H',0x09)
if player.main_job_id and player.main_job_id ~= data:byte(0xB5) and player.name and player.name == data:unpack('z',0x85) then
windower.debug('job change on zone')
load_user_files(data:byte(0xB5))
else
player.name = data:unpack('z',0x85)
end
player.main_job_id = data:byte(0xB5)
player.sub_job_id = data:byte(0xB8)
player.vitals.max_hp = data:unpack('I',0xE9)
player.vitals.max_mp = data:unpack('I',0xED)
player.max_hp = data:unpack('I',0xE9)
player.max_mp = data:unpack('I',0xED)
update_job_names()
world.zone_id = data:unpack('H',0x31)
_ExtraData.world.conquest = false
for i,v in pairs(region_to_zone_map) do
if v:contains(world.zone_id) then
_ExtraData.world.conquest = {
region_id = i,
region_name = res.regions[i][language],
}
break
end
end
weather_update(data:byte(0x69))
world.logged_in = true
_ExtraData.world.in_mog_house = data:byte(0x81) == 1
refresh_ffxi_info()
elseif id == 0x00B then
-- Blank temporary items when zoning.
items.temporary = make_inventory_table()
elseif id == 0x0E and pet.index and pet.index == data:unpack('H',9) and math.floor((data:byte(11)%8)/4)== 1 then
local oldstatus = pet.status
local status_id = data:byte(32)
-- Filter all statuses aside from Idle/Engaged/Dead/Engaged dead.
if status_id < 4 or status_id == 33 or status_id == 47 then
local newstatus = copy_entry(res.statuses[status_id])
if newstatus and newstatus[language] then
newstatus = newstatus[language]
if oldstatus ~= newstatus then
if not next_packet_events then next_packet_events = {sequence_id = data:byte(4)*256+data:byte(3)} end
next_packet_events.pet_status_change = {newstatus=newstatus,oldstatus=oldstatus}
end
end
end
elseif id == 0x01B then
for job_id = 1,23 do
player.jobs[to_windower_api(res.jobs[job_id].english)] = data:byte(job_id + 72)
end
local enc = data:unpack('H',0x61)
local tab = {}
for slot_id,slot_name in pairs(default_slot_map) do
local tf = (((enc%(2^(slot_id+1))) / 2^slot_id) >= 1)
if encumbrance_table[slot_id] and not tf and not_sent_out_equip[slot_name] and not disable_table[i] then
tab[slot_name] = not_sent_out_equip[slot_name]
not_sent_out_equip[slot_name] = nil
end
if encumbrance_table[slot_id] and not tf then
msg.debugging("Your "..slot_name.." slot is now unlocked.")
end
encumbrance_table[slot_id] = tf
end
if table.length(tab) > 0 then
refresh_globals()
equip_sets('equip_command',nil,tab)
end
elseif id == 0x01E then
local bag = to_windower_compact(res.bags[data:byte(0x09)].english)
local slot = data:byte(0x0A)
local count = data:unpack('I',5)
if not items[bag][slot] then items[bag][slot] = make_empty_item_table(slot) end
items[bag][slot].count = count
if count == 0 then
items[bag][slot].id = 0
items[bag][slot].bazaar = 0
items[bag][slot].status = 0
end
elseif id == 0x01F then
local bag = to_windower_compact(res.bags[data:byte(0x0B)].english)
local slot = data:byte(0x0C)
if not items[bag][slot] then items[bag][slot] = make_empty_item_table(slot) end
items[bag][slot].id = data:unpack('H',9)
items[bag][slot].count = data:unpack('I',5)
items[bag][slot].status = data:byte(0x0D)
elseif id == 0x020 then
local bag = to_windower_compact(res.bags[data:byte(0x0F)].english)
local slot = data:byte(0x10)
if not items[bag][slot] then items[bag][slot] = make_empty_item_table(slot) end
items[bag][slot].id = data:unpack('H',0x0D)
items[bag][slot].count = data:unpack('I',5)
items[bag][slot].bazaar = data:unpack('I',9)
items[bag][slot].status = data:byte(0x11)
items[bag][slot].extdata = data:sub(0x12,0x29)
-- Did not mess with linkshell stuff
elseif id == 0x28 then
inc_action(windower.packets.parse_action(data))
elseif id == 0x29 then
if gearswap_disabled then return end
local arr = {}
arr.actor_id = data:unpack('I',0x05)
arr.target_id = data:unpack('I',0x09)
arr.param_1 = data:unpack('I',0x0D)
arr.param_2 = data:unpack('I',0x11)%64 -- First 6 bits
arr.param_3 = math.floor(data:unpack('I',0x11)/64) -- Rest
arr.actor_index = data:unpack('H',0x15)
arr.target_index = data:unpack('H',0x17)
arr.message_id = data:unpack('H',0x19)%32768
inc_action_message(arr)
elseif id == 0x037 then
player.status_id = data:byte(0x31)
local bitmask = data:sub(0x4D,0x54)
for i = 1,32 do
local bitmask_position = 2*((i-1)%4)
player.buffs[i] = data:byte(4+i) + 256*math.floor(bitmask:byte(1+math.floor((i-1)/4))%(2^(bitmask_position+2))/(2^bitmask_position))
end
local indi_byte = data:byte(0x59)
if indi_byte%128/64 >= 1 then
local temp_indi = _ExtraData.player.indi
_ExtraData.player.indi = {
element = res.elements[indi_byte%8][language],
element_id = indi_byte%8,
size = math.floor((indi_byte%64)/16) + 1, -- Size range of 1~4
}
if (indi_byte%16)/8 >= 1 then
_ExtraData.player.indi.target = 'Enemy'
else
_ExtraData.player.indi.target = 'Ally'
end
if not temp_indi then
-- There was not an indi spell up
refresh_globals()
equip_sets('indi_change',nil,_ExtraData.player.indi,true)
elseif temp_indi.element_id ~= _ExtraData.player.indi.element_id or temp_indi.target ~= _ExtraData.player.indi.target or temp_indi.size ~= _ExtraData.player.indi.size then
-- There was already an indi spell up, so check if it changed
refresh_globals()
equip_sets('indi_change',nil,temp_indi,false)
equip_sets('indi_change',nil,_ExtraData.player.indi,true)
end
elseif _ExtraData.player.indi then
-- An indi effect has been lost.
local temp_indi = _ExtraData.player.indi
_ExtraData.player.indi = nil
refresh_globals()
equip_sets('indi_change',nil,temp_indi,false)
end
local subj_ind = data:unpack('H', 0x35) / 8
if subj_ind == 0 and pet.isvalid then
if not next_packet_events then next_packet_events = {sequence_id = data:unpack('H',3)} end
refresh_globals()
pet.isvalid = false
next_packet_events.pet_change = {pet = table.reassign({},pet)}
elseif subj_ind ~= 0 and not pet.isvalid then
if not next_packet_events then next_packet_events = {sequence_id = data:unpack('H',3)} end
next_packet_events.pet_change = {subj_ind = subj_ind}
end
elseif id == 0x044 then
-- No idea what this is doing
elseif id == 0x050 then
local inv = items[to_windower_compact(res.bags[data:byte(7)].english)]
if data:byte(5) ~= 0 then
items.equipment[toslotname(data:byte(6))] = {slot=data:byte(5),bag_id = data:byte(7)}
if not inv[data:byte(5)] then inv[data:byte(5)] = make_empty_item_table(data:byte(5)) end
items[to_windower_compact(res.bags[data:byte(7)].english)][data:byte(5)].status = 5 -- Set the status to "equipped"
else
items.equipment[toslotname(data:byte(6))] = {slot=empty,bag_id=0}
if not inv[data:byte(5)] then inv[data:byte(5)] = make_empty_item_table(data:byte(5)) end
items[to_windower_compact(res.bags[data:byte(7)].english)][data:byte(5)].status = 0 -- Set the status to "unequipped"
end
elseif id == 0x05E then -- Conquest ID
if _ExtraData.world.conquest then
local offset = _ExtraData.world.conquest.region_id*4 + 11
if offset == 99 then
offset = 95
elseif offset == 107 then
offset = 99
end
local strength_map = {[0]='Minimal',[1]='Minor',[2]='Major',[3]='Dominant'}
local nation_map = {[0]={english='Neutral',japanese='Neutral'},[1]=res.regions[0],[2]=res.regions[1],
[3]=res.regions[2],[4]={english='Beastman',japanese='Beastman'},[0xFF]=res.regions[3]}
_ExtraData.world.conquest.strengths = {
sandoria=strength_map[data:byte(offset+2)%4],
bastok=strength_map[math.floor(data:byte(offset+2)%16/4)],
windurst=strength_map[math.floor(data:byte(offset+2)%64/16)],
beastmen=strength_map[math.floor(data:byte(offset+2)/64)],}
_ExtraData.world.conquest.nation = nation_map[data:byte(offset+3)][language]
_ExtraData.world.conquest.sandoria = data:byte(0x87)
_ExtraData.world.conquest.bastok = data:byte(0x88)
_ExtraData.world.conquest.windurst = data:byte(0x89)
_ExtraData.world.conquest.beastmen = 100-data:byte(0x87)-data:byte(0x88)-data:byte(0x89)
end
elseif id == 0x061 then
player.vitals.max_hp = data:unpack('I',5)
player.vitals.max_mp = data:unpack('I',9)
player.max_hp = data:unpack('I',5)
player.max_mp = data:unpack('I',9)
player.main_job_id = data:byte(13)
player.main_job_level = data:byte(14)
_ExtraData.player.nation_id = data:byte(0x51)
_ExtraData.player.nation = res.regions[_ExtraData.player.nation_id][language] or 'None'
if player.sub_job_id ~= data:byte(15) then
-- Subjob change event
local temp_sub = player.sub_job
player.sub_job_id = data:byte(15)
player.sub_job_level = data:byte(16)
update_job_names()
refresh_globals()
equip_sets('sub_job_change',nil,player.sub_job,temp_sub)
end
update_job_names()
elseif id == 0x062 then
for i = 1,0x71,2 do
local skill = data:unpack('H',i + 0x82)%32768
local current_skill = res.skills[math.floor(i/2)+1]
if current_skill then
player.skills[to_windower_api(current_skill.english)] = skill
end
end
elseif id == 0x076 then
partybuffs = {}
for i = 0,4 do
if data:unpack('I',i*48+5) == 0 then
break
else
local index = data:unpack('H',i*48+5+4)
partybuffs[index] = {
id = data:unpack('I',i*48+5+0),
index = data:unpack('H',i*48+5+4),
buffs = {}
}
for n=1,32 do
partybuffs[index].buffs[n] = data:byte(i*48+5+16+n-1) + 256*( math.floor( data:byte(i*48+5+8+ math.floor((n-1)/4)) / 4^((n-1)%4) )%4)
end
end
end
elseif id == 0x0DF and data:unpack('I',5) == player.id then
player.vitals.hp = data:unpack('I',9)
player.vitals.mp = data:unpack('I',13)
player.vitals.tp = data:unpack('I',0x11)
player.vitals.hpp = data:byte(0x17)
player.vitals.mpp = data:byte(0x18)
player.hp = data:unpack('I',9)
player.mp = data:unpack('I',13)
player.tp = data:unpack('I',0x11)
player.hpp = data:byte(0x17)
player.mpp = data:byte(0x18)
elseif id == 0x0E2 and data:unpack('I',5)==player.id then
player.vitals.hp = data:unpack('I',9)
player.vitals.mp = data:unpack('I',0xB)
player.vitals.tp = data:unpack('I',0x11)
player.vitals.hpp = data:byte(0x1E)
player.vitals.mpp = data:byte(0x1F)
player.hp = data:unpack('I',9)
player.mp = data:unpack('I',0xB)
player.tp = data:unpack('I',0x11)
player.hpp = data:byte(0x1E)
player.mpp = data:byte(0x1F)
elseif id == 0x117 then
for i=0x49,0x85,4 do
local arr = data:sub(i,i+3)
local inv = items[to_windower_compact(res.bags[arr:byte(3)].english)]
if arr:byte(1) ~= 0 then
items.equipment[toslotname(arr:byte(2))] = {slot=arr:byte(1),bag_id = arr:byte(3)}
if not inv[arr:byte(1)] then inv[arr:byte(1)] = make_empty_item_table(arr:byte(1)) end
items[to_windower_compact(res.bags[arr:byte(3)].english)][arr:byte(1)].status = 5 -- Set the status to "equipped"
else
items.equipment[toslotname(arr:byte(2))] = {slot=empty,bag_id=0}
if not inv[arr:byte(1)] then inv[arr:byte(1)] = make_empty_item_table(arr:byte(1)) end
items[to_windower_compact(res.bags[arr:byte(3)].english)][arr:byte(1)].status = 0 -- Set the status to "unequipped"
end
end
end
end)
windower.register_event('status change',function(new,old)
windower.debug('status change '..new)
if gearswap_disabled or T{2,3,4}:contains(old) or T{2,3,4}:contains(new) then return end
refresh_globals()
equip_sets('status_change',nil,res.statuses[new].english,res.statuses[old].english)
end)
windower.register_event('gain buff',function(buff_id)
if not res.buffs[buff_id] then
error('GearSwap: No known status for buff id #'..tostring(buff_id))
end
local buff_name = res.buffs[buff_id][language]
windower.debug('gain buff '..buff_name..' ('..tostring(buff_id)..')')
if gearswap_disabled then return end
-- Need to figure out what I'm going to do with this:
if T{'terror','sleep','stun','petrification','charm','weakness'}:contains(buff_name:lower()) then
for ts,v in pairs(command_registry) do
if v.midaction then
command_registry:delete_entry(ts)
end
end
end
refresh_globals()
equip_sets('buff_change',nil,buff_name,true,copy_entry(res.buffs[buff_id]))
end)
windower.register_event('lose buff',function(buff_id)
if not res.buffs[buff_id] then
error('GearSwap: No known status for buff id #'..tostring(buff_id))
end
local buff_name = res.buffs[buff_id][language]
windower.debug('lose buff '..buff_name..' ('..tostring(buff_id)..')')
if gearswap_disabled then return end
refresh_globals()
equip_sets('buff_change',nil,buff_name,false,copy_entry(res.buffs[buff_id]))
end)
windower.register_event('login',function(name)
windower.debug('login '..name)
initialize_globals()
windower.send_command('@wait 2;lua i gearswap refresh_user_env;')
end)
Explorer shows it last being modified on 8/18/2015, but I don't recall making any changes myself. Hope it helps!
Server: Asura
Game: FFXI
Posts: 363
By Asura.Vafruvant 2015-09-12 02:45:38
If I missed anything, post again or PM me and I'll try to help.
Server: Asura
Game: FFXI
Posts: 95
By Asura.Omnijuggernaut 2015-09-15 11:11:11
Just wanna give a shout out and a huge thank you to Vafruvant for all the work and help he does on this thread for everyone with questions.
By Aeyela 2015-09-15 11:16:10
Gearswap will not change equipment during Charm, no. Whilst I was fairly confident this would be the case I went and tested it anyway in Beacuedine and no, it cannot, no matter how hard you try. You just get myriad "Unable to equip..." lines, just like if you'd sent /equip feet "Something" commands natively.
Server: Phoenix
Game: FFXI
Posts: 118
By Phoenix.Tigertail 2015-09-15 14:06:13
idss there anyway to have my mule send me a tell using gearswap if if its follow distance gets farther then a certin amount this would be great for when i mmulti box and dont notice if one of my alts gets stuck I don't think there is. I'll check, but I don't recall seeing anything like it.
Woo that would be great, my taru is always getting stuck... :D Another nice thing would be to automatically take off movement speed if you set the alt to follow, if she doesn't have equal movement speed. Yes. Lazy.
Cerberus.Conagh
Server: Cerberus
Game: FFXI
Posts: 3189
By Cerberus.Conagh 2015-09-15 14:29:10
Phoenix.Tigertail said: »idss there anyway to have my mule send me a tell using gearswap if if its follow distance gets farther then a certin amount this would be great for when i mmulti box and dont notice if one of my alts gets stuck I don't think there is. I'll check, but I don't recall seeing anything like it.
Woo that would be great, my taru is always getting stuck... :D Another nice thing would be to automatically take off movement speed if you set the alt to follow, if she doesn't have equal movement speed. Yes. Lazy.
The distance method works fine, it's pretty easy to code into creating a trigger event which gets parsed whenever distance changes, and have it send a tell.
The 2nd one however is not so dosable, if you put your companion on follow there's no method locally on a machine using Lua to create a trigger for the event, what you can do however is just create a toggle to turn it on/off if party.member.player.name = mules name (although that would require some messing around with to work, it is technically doable). There's a tab on the windower site for lua about party members and person specific events, have a look! I made something using it to auto correct single target cures into Aga spells if the average of 3 players HP dropped below 75% ~.
Not the actual coding you need, but hope it's doable, if no one else has coded it for you, i'll dig it out from my old gearswaps when I get home from work in about 11 hours ._.
Edit:
I should mention that to party member name isn't an event and is a rule, so you would need to add some trigger either using a stat that changes every now and again to *** it, create a check for this data either changing sets (which could cause some stability issue) or create a custom Timer using lua.timer plugin (standard install includes this) and have it look while in a certain set but that adds a great deal more system usage from lua, lua however uses a rather small amount compared to C++ (spellcast) so it's doable on a better machine, but personally I wouldn't use it.
By zaxtiss 2015-09-15 14:32:08
I thought it might be possible to do using target distance something like if auto follow == on then if target distance greater then 16 send command input /tell main "hey your missing some thing!!! ME!!!!" That would be great I go to work soon anyway so ill check out after. Sucks having to use a cell for this. >_<
Bismarck.Speedyjim
Server: Bismarck
Game: FFXI
Posts: 516
By Bismarck.Speedyjim 2015-09-16 00:11:24
Having an issue where Hailstorm I+II will not equip my enhancing gear. Instead, my nuking gear is equipping. Rest of the storm-spells will properly set my enhancing gear.
Also, when the current storm spell is still active but about to wear off, using the same storm-spell (or Perpetuance+storm-spell) will NOT equip my Arbatel Bracers +1; same nuking gear is again equipped.
Root file: https://drive.google.com/open?id=0ByGS22kY0-SpZ0N0VkcxMlpvZzg
Gear sidecar: https://drive.google.com/open?id=0ByGS22kY0-SpN0Rrc3RaU1hvNE0
Asura.Arnan
Server: Asura
Game: FFXI
Posts: 132
By Asura.Arnan 2015-09-16 18:20:31
Does this cover all ways to cap magic haste on BLU now we have mighty guard? (excluding haste samba)
if (buffactive.March and (buffactive.Embrava or buffactive.Haste or buffactive['Mighty Guard']) or (buffactive.Haste == 2) or (buffactive['Mighty Guard']) and (buffactive.Embrava or buffactive.Haste)) and equipSet["HighHaste"] then
equipSet = equipSet["HighHaste"]
end
thanks
Shiva.Hiep
Server: Shiva
Game: FFXI
Posts: 669
By Shiva.Hiep 2015-09-17 06:15:17
For some reason, my Kaykaus Bliaut +1 isn't swapping in for my cure sets. Anyone know why? Pretty sure I spelled it right.
sets.midcast.Cure.ConserveMP = {main="Akademos",sub="Willpower Grip",ammo="Hasty Pinion +1",
head=gear.CuringHat,neck="Phalaina Locket",left_ear="Enchanter Earring +1",right_ear="Mendi. Earring",
body="Kaykaus Bliault +1",hands=gear.CMPHands,left_ring="Haoma's Ring",right_ring="Lebeche Ring",
back="Oretan. Cape +1",waist="Gishdubar Sash",legs=gear.CMPLegs,feet=gear.CMPFeet}
By Aeyela 2015-09-17 06:30:56
body="Kaykaus Bliault +1"
Remove the L.
Ramuh.Austar
Server: Ramuh
Game: FFXI
Posts: 10481
By Ramuh.Austar 2015-09-18 21:01:13
I'm trying to make a map with a handful of spells specifically for enmity. maps.Enmity = {} doesn't seem to work, and neither does magic_maps.Enmity = {}
Any ideas how I can do this?
Bismarck.Inference
Server: Bismarck
Game: FFXI
Posts: 417
By Bismarck.Inference 2015-09-18 23:20:42
If you're not looking to break down the spells into any further detail like varying 'tiers' or something a simple table should suffice :
Code
EnmitySpells = {"Flash","Stun",etc}
if EnmitySpells:contains(spell.english) then
do something fancy
end
Server: Siren
Game: FFXI
Posts: 228
By Siren.Noxzema 2015-09-19 23:53:03
How do I check set priorities? Before the update if I had my Avatar's Favor set on, and had my pet attacking it would create a hybrid set. But since the update, my pet melee set is taking priority over my Favor set, and I've checked 2 different luas. My sets work fine other than that.
Edit: Also happens with my pet PDT set.
Server: Asura
Game: FFXI
Posts: 230
By Asura.Sabishii 2015-09-20 15:54:34
Having a problem with one of BLU's since the update. I'm using a mote based BLU lua, and it's not swapping gear for precast-midcast for mighty guard. I noticed the spell is taking too long to cast, then enabled show swaps, it's not switching gear, and I added 'Mighty Guard' to blue_magic_maps.Buff and to the unbridled_spells lists. I don't have cesspool, tearing gust, nor cruel joke yet, so I can't test those yet, but it's just not swapping gear for mighty guard. Friend of mine is having the same issue with gear not changing for mighty guard and he made the same changes I did.
By Aeyela 2015-09-20 16:28:39
How do I check set priorities? Before the update if I had my Avatar's Favor set on, and had my pet attacking it would create a hybrid set. But since the update, my pet melee set is taking priority over my Favor set, and I've checked 2 different luas. My sets work fine other than that.
Edit: Also happens with my pet PDT set.
It sounds like you don't need to check priorities as you've already established that your melee set is taking priority when it shouldn't. Post your Lua and we'll edit it as a simple reorder of code will likely correct it.
Having a problem with one of BLU's since the update. I'm using a mote based BLU lua, and it's not swapping gear for precast-midcast for mighty guard. I noticed the spell is taking too long to cast, then enabled show swaps, it's not switching gear, and I added 'Mighty Guard' to blue_magic_maps.Buff and to the unbridled_spells lists. I don't have cesspool, tearing gust, nor cruel joke yet, so I can't test those yet, but it's just not swapping gear for mighty guard. Friend of mine is having the same issue with gear not changing for mighty guard and he made the same changes I did.
I don't know for sure what the problem is here, especially if you've added it to your map, but there's a dirty fix we can use for now if you just want it functioning. Add the following to your precast and midcast functions:
Code if spell.name == 'Mighty Guard' then
equip(sets.precast)
end
Where sets.precast is the relevant set you want to equip for this spell. It's not pretty but it should do for now.
Server: Asura
Game: FFXI
Posts: 230
By Asura.Sabishii 2015-09-20 16:54:34
I'm hunting around within Gearswap, and in gearswap/statics.lua, line 214-217, Cesspool, Mighty Guard, Tearing Gust, and Cruel Joke weren't added to unbridled_learning_set. That might do it.
Server: Asura
Game: FFXI
Posts: 230
By Asura.Sabishii 2015-09-20 17:23:23
Sorry to double post, but I added them and the issue wasn't fixed =/ it's something else then.
By Aeyela 2015-09-21 03:35:47
I can only assume that Gearswap itself needs updating for these new spells, especially if that fix I posted didn't work.
Quetzalcoatl.Langly
Server: Quetzalcoatl
Game: FFXI
Posts: 684
By Quetzalcoatl.Langly 2015-09-21 09:29:23
Complaint about mighty guard not registering in gearswap etc etc
edit: seems like there's a fix on dev that was posted on BG. I lost the link... uhh it's there though.
Shiva.Hiep
Server: Shiva
Game: FFXI
Posts: 669
By Shiva.Hiep 2015-09-21 13:33:27
I've having an issue when I cast 2 GEO spells back to back. The first spell swaps my Dunna in midcast, but my 2nd spell swaps in Sapience Orb for midcast. Not sure why Sapience is swapping in, but I need Dunna to hit 900 Geomancy Tier. Here are my sets:
sets.precast.FC = {
main="Lehbrailg +2",
sub="Willpower Grip",
head="Vanya Hood",
neck="Orunmila's Torque",
ear1="Enchanter Earring +1",
ear2="Loquacious Earring",
body="Anhur Robe",
hands=gear.FCHands,
ring1="Weather. Ring",
ring2="Prolix Ring",
back="Lifestream Cape",
waist="Witful Belt",
legs="Geomancy Pants +1",
range="Dunna",
feet="Regal Pumps +1"}
sets.midcast.Geomancy = {range="Dunna",
main="Idris",
sub="Genmei Shield",
head="Azimuth Hood +1",
neck="Reti Pendant",
ear1="Gifted Earring",
ear2="Calamitous Earring",
body="Bagua Tunic +1",
hands="Geomancy Mitaines +1",
ring1="Defending Ring",
ring2="Dark Ring",
back="Lifestream cape",
waist="Austerity belt +1",
legs="Vanya Slops",
feet="Medium's Sabots"}
sets.midcast.Geomancy.Indi = set_combine(sets.midcast.Geomancy,{legs="Bagua Pants +1",feet="Azimuth Gaiters +1"})
I wouldn't want to //gs disable anything because I use a lot of different ammos for nuking/enf etc.
Bismarck.Inference
Server: Bismarck
Game: FFXI
Posts: 417
By Bismarck.Inference 2015-09-21 14:15:19
Need your midcast rule more than anything, sets don't tell us much especially since none have Sapience Orb in them. Best to pastebin the whole thing really.
By Aeyela 2015-09-21 15:11:41
Try adding this to midcast:
Code if midaction() then
return
end
By nanohamaho 2015-09-21 16:16:30
I'm trying to understand the "states" thing in the mote files. In the mote dnc lua for example it gives options for offense and hybrid modes, and while I've found the keybinds to switch said modes, I don't understand when they would take effect.
So far I've gotten that offense modes can handle the "engaged" state, but I guess my question is how would switching through the hybrid modes for like a pdt/eva set work? would whatever I pushed take priority over normal engaged or would it just go back every time I weaponskill or cast?
My apologies if these questions are stupid or don't make sense.
Server: Siren
Game: FFXI
Posts: 228
By Siren.Noxzema 2015-09-21 18:34:43
How do I check set priorities? Before the update if I had my Avatar's Favor set on, and had my pet attacking it would create a hybrid set. But since the update, my pet melee set is taking priority over my Favor set, and I've checked 2 different luas. My sets work fine other than that.
Edit: Also happens with my pet PDT set.
It sounds like you don't need to check priorities as you've already established that your melee set is taking priority when it shouldn't. Post your Lua and we'll edit it as a simple reorder of code will likely correct it.
Code require 'organizer-lib'
-------------------------------------------------------------------------------------------------------------------
-- Setup functions for this job. Generally should not be modified.
-------------------------------------------------------------------------------------------------------------------
-- Also, you'll need the Shortcuts addon to handle the auto-targetting of the custom pact commands.
--[[
Custom commands:
gs c petweather
Automatically casts the storm appropriate for the current avatar, if possible.
gs c siphon
Automatically run the process to: dismiss the current avatar; cast appropriate
weather; summon the appropriate spirit; Elemental Siphon; release the spirit;
and re-summon the avatar.
Will not cast weather you do not have access to.
Will not re-summon the avatar if one was not out in the first place.
Will not release the spirit if it was out before the command was issued.
gs c pact [PactType]
Attempts to use the indicated pact type for the current avatar.
PactType can be one of:
cure
curaga
buffOffense
buffDefense
buffSpecial
debuff1
debuff2
sleep
nuke2
nuke4
bp70
bp75 (merits and lvl 75-80 pacts)
astralflow
--]]
-- Initialization function for this job file.
function get_sets()
mote_include_version = 2
-- Load and initialize the include file.
include('Mote-Include.lua')
end
-- Setup vars that are user-independent. state.Buff vars initialized here will automatically be tracked.
function job_setup()
state.Buff["Avatar's Favor"] = buffactive["Avatar's Favor"] or false
state.Buff["Astral Conduit"] = buffactive["Astral Conduit"] or false
spirits = S{"LightSpirit", "DarkSpirit", "FireSpirit", "EarthSpirit", "WaterSpirit", "AirSpirit", "IceSpirit", "ThunderSpirit"}
avatars = S{"Carbuncle", "Fenrir", "Diabolos", "Ifrit", "Titan", "Leviathan", "Garuda", "Shiva", "Ramuh", "Odin", "Alexander", "Cait Sith"}
magicalRagePacts = S{
'Inferno','Earthen Fury','Tidal Wave','Aerial Blast','Diamond Dust','Judgment Bolt','Searing Light','Howling Moon','Ruinous Omen',
'Fire II','Stone II','Water II','Aero II','Blizzard II','Thunder II',
'Fire IV','Stone IV','Water IV','Aero IV','Blizzard IV','Thunder IV',
'Thunderspark','Burning Strike','Meteorite','Nether Blast','Flaming Crush',
'Conflag Strike',
'Meteor Strike','Heavenly Strike','Wind Blade','Geocrush','Grand Fall','Thunderstorm',
'Holy Mist','Lunar Bay','Night Terror','Level ? Holy','Impact'}
pacts = {}
pacts.cure = {['Carbuncle']='Healing Ruby'}
pacts.curaga = {['Carbuncle']='Healing Ruby II', ['Garuda']='Whispering Wind', ['Leviathan']='Spring Water'}
pacts.buffoffense = {['Carbuncle']='Glittering Ruby', ['Ifrit']='Crimson Howl', ['Garuda']='Hastega', ['Ramuh']='Rolling Thunder',
['Fenrir']='Ecliptic Growl'}
pacts.buffdefense = {['Carbuncle']='Shining Ruby', ['Shiva']='Frost Armor', ['Garuda']='Aerial Armor', ['Titan']='Earthen Ward',
['Ramuh']='Lightning Armor', ['Fenrir']='Ecliptic Howl', ['Diabolos']='Noctoshield', ['Cait Sith']='Reraise II'}
pacts.buffspecial = {['Ifrit']='Inferno Howl', ['Garuda']='Fleet Wind', ['Titan']='Earthen Armor', ['Diabolos']='Dream Shroud',
['Carbuncle']='Soothing Ruby', ['Fenrir']='Heavenward Howl', ['Cait Sith']='Raise II'}
pacts.buffspecial2 = {['Shiva']='Crystal Blessing', ['Leviathan']='Soothing Current', ['Garuda']='Hastega II', ['Carbuncle']='Pacifying Ruby'}
pacts.debuff1 = {['Shiva']='Diamond Storm', ['Ramuh']='Shock Squall', ['Leviathan']='Tidal Roar', ['Fenrir']='Lunar Cry',
['Diabolos']='Pavor Nocturnus', ['Cait Sith']='Eerie Eye'}
pacts.debuff2 = {['Shiva']='Sleepga', ['Leviathan']='Slowga', ['Fenrir']='Lunar Roar', ['Diabolos']='Somnolence'}
pacts.sleep = {['Shiva']='Sleepga', ['Diabolos']='Nightmare', ['Cait Sith']='Mewing Lullaby'}
pacts.nuke2 = {['Ifrit']='Fire II', ['Shiva']='Blizzard II', ['Garuda']='Aero II', ['Titan']='Stone II',
['Ramuh']='Thunder II', ['Leviathan']='Water II'}
pacts.nuke4 = {['Ifrit']='Fire IV', ['Shiva']='Blizzard IV', ['Garuda']='Aero IV', ['Titan']='Stone IV',
['Ramuh']='Thunder IV', ['Leviathan']='Water IV'}
pacts.bp70 = {['Ifrit']='Flaming Crush', ['Shiva']='Rush', ['Garuda']='Predator Claws', ['Titan']='Mountain Buster',
['Ramuh']='Chaotic Strike', ['Leviathan']='Spinning Dive', ['Carbuncle']='Meteorite', ['Fenrir']='Eclipse Bite',
['Diabolos']='Nether Blast',['Cait Sith']='Regal Scratch'}
pacts.bp75 = {['Ifrit']='Meteor Strike', ['Shiva']='Heavenly Strike', ['Garuda']='Wind Blade', ['Titan']='Geocrush',
['Ramuh']='Thunderstorm', ['Leviathan']='Grand Fall', ['Carbuncle']='Holy Mist', ['Fenrir']='Lunar Bay',
['Diabolos']='Night Terror', ['Cait Sith']='Level ? Holy'}
pacts.bp99 = {['Ifrit']='Conflag Srike', ['Titan']='Crag Throw', ['Ramuh']='Volt Strike', ['Diabolos']='Blindside', ['Cait Sith']='Regal Gash'}
pacts.astralflow = {['Ifrit']='Inferno', ['Shiva']='Diamond Dust', ['Garuda']='Aerial Blast', ['Titan']='Earthen Fury',
['Ramuh']='Judgment Bolt', ['Leviathan']='Tidal Wave', ['Carbuncle']='Searing Light', ['Fenrir']='Howling Moon',
['Diabolos']='Ruinous Omen', ['Cait Sith']="Altana's Favor"}
-- Wards table for creating custom timers
wards = {}
-- Base duration for ward pacts.
wards.durations = {
['Crimson Howl'] = 60, ['Earthen Armor'] = 60, ['Inferno Howl'] = 60, ['Heavenward Howl'] = 60,
['Rolling Thunder'] = 120, ['Fleet Wind'] = 120,
['Shining Ruby'] = 180, ['Frost Armor'] = 180, ['Lightning Armor'] = 180, ['Ecliptic Growl'] = 180,
['Glittering Ruby'] = 180, ['Hastega'] = 180, ['Noctoshield'] = 180, ['Ecliptic Howl'] = 180,
['Dream Shroud'] = 180, ['Hastega II'] = 180, ['Crystal Blessing'] = 180, ['Soothing Current'] = 180,
['Reraise II'] = 3600
}
-- Icons to use when creating the custom timer.
wards.icons = {
['Earthen Armor'] = 'spells/00299.png', -- 00299 for Titan
['Shining Ruby'] = 'spells/00043.png', -- 00043 for Protect
['Dream Shroud'] = 'spells/00304.png', -- 00304 for Diabolos
['Noctoshield'] = 'spells/00106.png', -- 00106 for Phalanx
['Inferno Howl'] = 'spells/00298.png', -- 00298 for Ifrit
['Hastega'] = 'spells/00358.png', -- 00358 for Hastega
['Rolling Thunder'] = 'spells/00104.png', -- 00358 for Enthunder
['Frost Armor'] = 'spells/00250.png', -- 00250 for Ice Spikes
['Lightning Armor'] = 'spells/00251.png', -- 00251 for Shock Spikes
['Reraise II'] = 'spells/00135.png', -- 00135 for Reraise
['Fleet Wind'] = 'abilities/00074.png', --
['Hastega II'] = 'abilities/01114.png', --
['Soothing Current']= 'abilities/01098.png', --
['Crystal Blessing']= 'abilities/01130.png', --
}
-- Flags for code to get around the issue of slow skill updates.
wards.flag = false
wards.spell = ''
end
-------------------------------------------------------------------------------------------------------------------
-- User setup functions for this job. Recommend that these be overridden in a sidecar file.
-------------------------------------------------------------------------------------------------------------------
-- Setup vars that are user-dependent. Can override this function in a sidecar file.
function user_setup()
state.OffenseMode:options('None', 'Normal', 'Acc')
state.CastingMode:options('Normal', 'Resistant')
state.IdleMode:options('Normal', 'PDT')
gear.perp_staff = {name=""}
-- 'Out of Range' distance; WS will auto-cancel
target_distance = 6
select_default_macro_book()
end
-- Define sets and vars used by this job file.
function init_gear_sets()
--------------------------------------
-- Precast Sets
--------------------------------------
-- Precast sets to enhance JAs
sets.precast.JA['Astral Flow'] = {head="Glyphic Horn +1"}
sets.precast.JA['Elemental Siphon'] = {main="Espiritus",sub="Vox Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Summoning Earring",ear2="Andoaa earring",
body="Anhur Robe",hands="Lamassu Mitts +1",ring1="Globidonta Ring",ring2="Evoker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +3','Pet: Enmity+15','Blood Pact Dmg.+2','Blood Pact ab. del. II -3',}},waist="Lucidity Sash",legs="Telchine Braconi",feet="Beck. Pigaches"}
sets.precast.JA['Mana Cede'] = {hands="Caller's Bracers +2"}
-- Pact delay reduction gear
sets.precast.BloodPactWard = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Caller's Earring",
body="Glyphic doublet +1",hands="Glyphic Bracers +1",ring1="Thurandaut Ring",ring2="Evoker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +3','Pet: Enmity+15','Blood Pact Dmg.+2','Blood Pact ab. del. II -3',}},waist="Moepapa Stone",legs="Glyphic spats",feet="Glyphic pigaches +1"}
sets.precast.BloodPactWard["Astral Conduit"] = {} -- intentionally left null
sets.precast.BloodPactRage = sets.precast.BloodPactWard
sets.precast.BloodPactRage["Astral Conduit"] = {} -- intentionally left null
-- Fast cast sets for spells
sets.precast.FC = {
head="Nahtirah Hat",ear1="Domesticator's Earring",ear2="Loquacious Earring",
body="Anhur Robe",hands="Telchine Gloves",ring1="Veneficium Ring",ring2="Prolix Ring",
back="Swith Cape",waist="Witful Belt",legs="Lengo Pants",feet="Regal Pumps"}
sets.precast.FC['Enhancing Magic'] = set_combine(sets.precast.FC, {waist="Siegel Sash"})
sets.precast.FC['Healing Magic'] = set_combine(sets.precast.FC, {main="Serenity",ammo="Impatiens",back="Pahtli Cape",legs="Nabu's Shalwar"})
-- Weaponskill sets
-- Default set for any weaponskill that isn't any more specifically defined
sets.precast.WS = {
head="Nahtirah Hat",neck="Asperity Necklace",ear1="Bladeborn Earring",ear2="Steelflash Earring",
body="Vanir Cotehardie",hands="Yaoyotl Gloves",ring1="Rajas Ring",ring2="K'ayres Ring",
back="Pahtli Cape",waist="Cascade Belt"}
-- Specific weaponskill sets. Uses the base set if an appropriate WSMod version isn't found.
sets.precast.WS['Myrkr'] = {
head="Nahtirah Hat",ear1="Gifted Earring",ear1="Moonshade earring",ear2="Loquacious Earring",
body="Convoker's Doublet",hands="Caller's Bracers +2",ring1="Evoker's Ring",ring2="Sangoma Ring",
back="Pahtli Cape",waist="Fucho-no-Obi",legs="Nares Trews",feet="Chelona Boots +1"}
sets.precast.WS['Garland of Bliss'] = {ammo="Seraphicaller",
head="Hagondes hat",neck="Eddy Necklace",ear1="Friomisi Earring",ear2="Novio Earring",
body="Witching Robe",hands={ name="Helios Gloves", augments={'"Mag.Atk.Bns."+17','Magic crit. hit rate +1',}}, ring1="Acumen Ring",ring2="Strendu Ring",
back="Argochampsa Mantle",waist="Eschan stone",legs="Hagondes pants",feet="Umbani Boots"}
sets.precast.WS['Shattersoul'] = {
head="Nahtirah hat",neck="Asperity Necklace",ear1="Moonshade Earring",ear2="Brutal Earring",
body="Vanir cotehardie",hands="Glyphic Bracers +1",ring1="Spiral Ring",ring2="Acumen Ring",
back="Blithe Mantle",waist="Windbuffet belt +1",legs="Telchine braconi", feet="Umbani boots"}
organizer_items = {
echos="Echo Drops", cap="Trizek Ring", xp="Echad Ring", cp="Capacity Ring"}
--------------------------------------
-- Midcast sets
--------------------------------------
sets.midcast.FastRecast = {
head="Nahtirah Hat",ear2="Loquacious Earring",
body="Vanir Cotehardie",hands="Telchine Gloves",ring1="Prolix Ring",
back="Swith Cape",waist="Witful Belt"}
sets.midcast.Cure = {main="Serenity",
head="Nahtirah Hat",ear2="Loquacious Earring",
body="Vrikodara Jupon",hands="Telchine Gloves",ring1="Prolix Ring",ring2="Veneficium Ring",
waist="Witful Belt",legs="Gyve Trousers"}
sets.midcast.Stoneskin = {waist="Siegel Sash"}
sets.midcast.Cursna = {neck="Malison Medallion", ring1="Ephedra Ring",ring2="Ephedra Ring"}
sets.midcast['Elemental Magic'] = {main="Marin Staff +1",sub="Wizzan Grip",
head="Hagondes Hat",neck="Eddy Necklace",ear1="Friomisi Earring",ear2="Novio Earring",
body="Vanir Cotehardie",hands="Otomi Gloves",ring1="Strendu Ring",ring2="Acumen Ring",
back="Argochampsa Mantle",waist=gear.ElementalBelt,legs="Hagondes Pants +1",feet="Umbani boots"}
-- Avatar pact sets. All pacts are Ability type.
sets.midcast.Pet.BloodPactWard = {main="Espiritus",sub="Vox Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Summoning Earring", ear2="Andoaa earring",
body="Anhur Robe",hands="Lamassu Mitts +1",ring1="Globidonta Ring",ring2="Evoker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},waist="Lucidity Sash",legs="Beckoner's spats +1",feet="Apogee pumps"}
sets.midcast.Pet.DebuffBloodPactWard = {main="Espiritus",sub="Vox Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Summoning Earring",ear2="Andoaa earring",
body="Anhur Robe",hands="Lamassu Mitts +1",ring1="Globidonta Ring",ring2="Evoker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},waist="Lucidity Sash",legs="Helios Spats",feet="Beck. Pigaches +1"}
sets.midcast.Pet.DebuffBloodPactWard.Acc = sets.midcast.Pet.DebuffBloodPactWard
sets.midcast.Pet.PhysicalBloodPactRage = {main="Nirvana",sub="Vox Grip",ammo="Seraphicaller",
head={ name="Helios Band", augments={'Pet: "Mag.Atk.Bns."+28','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
neck="Empath Necklace",ear1="Gelos Earring",ear2="Esper earring",
body="Glyphic Doublet +1",hands={ name="Helios Gloves", augments={'Pet: "Mag.Atk.Bns."+29','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
ring1="Thurandaut Ring",ring2="Speaker's Ring",back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},
waist="Mujin obi",
legs={ name="Helios Spats", augments={'Pet: "Mag.Atk.Bns."+28','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
feet={ name="Helios Boots", augments={'Pet: "Mag.Atk.Bns."+30','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}}}
sets.midcast.Pet.PhysicalBloodPactRage.Acc = sets.midcast.Pet.PhysicalBloodPactRage
sets.midcast.Pet.MagicalBloodPactRage = {main="Espiritus",sub="Vox Grip",ammo="Seraphicaller",
head={ name="Helios Band", augments={'Pet: "Mag.Atk.Bns."+28','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
neck="Eidolon Pendant +1",ear1="Gelos earring",ear2="Esper earring",
body={ name="Helios Jacket", augments={'Pet: "Mag.Atk.Bns."+29','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
hands={ name="Helios Gloves", augments={'Pet: "Mag.Atk.Bns."+29','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
ring1="Thurandaut Ring",ring2="Speaker's Ring",back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},
waist="Caller's Sash",
legs="Enticer's Pants",
feet={ name="Helios Boots", augments={'Pet: "Mag.Atk.Bns."+30','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}}}
sets.midcast.Pet.MagicalBloodPactRage.Acc = sets.midcast.Pet.MagicalBloodPactRage
sets.midcast.Pet['Flaming Crush'] = {main="Nirvana",sub="Vox Grip",ammo="Seraphicaller",
head={ name="Helios Band", augments={'Pet: "Mag.Atk.Bns."+28','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
neck="Eidolon Pendant +1",ear1="Gelos Earring",ear2="Esper earring",
body={ name="Helios Jacket", augments={'Pet: "Mag.Atk.Bns."+29','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
hands={ name="Helios Gloves", augments={'Pet: "Mag.Atk.Bns."+29','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
ring1="Thurandaut Ring",ring2="Speaker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},
waist="Caller's Sash",legs={ name="Helios Spats", augments={'Pet: "Mag.Atk.Bns."+28','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}},
feet={ name="Helios Boots", augments={'Pet: "Mag.Atk.Bns."+30','Pet: Crit.hit rate +4','Blood Pact Dmg.+7',}}}
-- Spirits cast magic spells, which can be identified in standard ways.
sets.midcast.Pet.WhiteMagic = {legs="Glyphic Spats"}
sets.midcast.Pet['Elemental Magic'] = set_combine(sets.midcast.Pet.BloodPactRage, {legs="Glyphic Spats"})
sets.midcast.Pet['Elemental Magic'].Resistant = {}
--------------------------------------
-- Idle/resting/defense/etc sets
--------------------------------------
-- Resting sets
sets.resting = {main="Nirvana",sub="Oneiros grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes Coat +1",hands="Asteria Mitts +1",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa stone",legs="Assiduity Pants +1",feet="Serpentes sabots"}
-- Idle sets
sets.idle = {main="Nirvana",sub="Oneiros grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes Coat +1",hands="Asteria Mitts +1",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa stone",legs="Assiduity Pants +1",feet="Serpentes sabots"}
sets.idle.PDT = {main="Nirvana",sub="Oneiros grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes Coat +1",hands="Asteria Mitts +1",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa stone",legs="Assiduity Pants +1",feet="Serpentes sabots"}
-- perp costs:
-- spirits: 7
-- carby: 11 (5 with mitts)
-- fenrir: 13
-- others: 15
-- avatar's favor: -4/tick
-- Max useful -perp gear is 1 less than the perp cost (can't be reduced below 1)
-- Aim for -14 perp, and refresh in other slots.
-- -perp gear:
-- Gridarvor: -5
-- Glyphic Horn: -4
-- Caller's Doublet +2/Glyphic Doublet: -4
-- Evoker's Ring: -1
-- Convoker's Pigaches: -4
-- total: -18
-- Can make due without either the head or the body, and use +refresh items in those slots.
sets.idle.Avatar = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes coat +1",hands="Asteria Mitts +1",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa Stone",legs="Assiduity pants +1",feet={ name="Helios Boots", augments={'Pet: Attack+26 Pet: Rng.Atk.+26','Pet: "Dbl. Atk."+7','Pet: Haste+6'}}}
sets.idle.Avatar.Melee = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Empath Necklace",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes coat +1",hands={ name="Helios Gloves", augments={'Pet: Attack+30 Pet: Rng.Atk.+30','Pet: "Dbl. Atk."+7','Pet: Haste+6',}},ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa Stone",legs="Assiduity pants +1",feet={ name="Helios Boots", augments={'Pet: Attack+26 Pet: Rng.Atk.+26','Pet: "Dbl. Atk."+7','Pet: Haste+6'}}}
sets.idle.PDT.Avatar = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Selenian cap",neck="Empath Necklace",ear1="Handler's Earring +1",ear2="Handler's Earring",
body="Hagondes coat +1",hands="Artsieq cuffs",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Isa Belt",legs="Assiduity pants +1",feet={ name="Telchine Pigaches", augments={'Pet: "Regen"+2','Pet: Damage taken -3%',}}}
sets.idle.Spirit = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Caller's Pendant",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes coat +1",hands="Regimen mittens",ring1="Globidonta Ring",ring2="Evoker's Ring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},waist="Moepapa Stone",legs="Glyphic spats",feet="Convoker's pigaches +1"}
sets.idle.Town = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Empath Necklace",ear1="Domesticator's Earring",ear2="Rimeice Earring",
body="Hagondes coat +1",hands="Asteria Mitts +1",ring1="Thurandaut Ring",ring2="Speaker's Ring",
back="Penetrating Cape",waist="Moepapa Stone",legs="Assiduity pants +1",feet="Herald's Gaiters"}
-- Favor uses Caller's Horn instead of Convoker's Horn for refresh
sets.idle.Avatar.Favor = {head="Beckoner's Horn +1",neck="Caller's Pendant",hands="Lamassu Mitts +1",ear2="Andoaa Earring",
back={ name="Conveyance Cape", augments={'Summoning magic skill +5','Blood Pact Dmg.+5','Blood Pact ab. del. II -1',}},
feet="Apogee Pumps"}
sets.perp = {}
-- Caller's Bracer's halve the perp cost after other costs are accounted for.
-- Using -10 (Gridavor, ring, Conv.feet), standard avatars would then cost 5, halved to 2.
-- We can then use Hagondes Coat and end up with the same net MP cost, but significantly better defense.
-- Weather is the same, but we can also use the latent on the pendant to negate the last point lost.
sets.perp.Day = {body="Hagondes Coat +1"}
sets.perp.Weather = {neck="Caller's Pendant",body="Hagondes Coat +1"}
-- Carby: Mitts+Conv.feet = 1/tick perp. Everything else should be +refresh
sets.perp.Alexander = sets.midcast.Pet.BloodPactWard
sets.perp.staff_and_grip = {main=gear.perp_staff,sub="Achaq Grip"}
-- Defense sets
sets.defense.PDT = {main=gear.Staff.PDT,
head="Hagondes Hat",neck="Wiglen Gorget",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Hagondes Coat +1",hands="Yaoyotl Gloves",ring1="Defending Ring",ring2="Patricius Ring",
back="Umbra Cape",waist="Fucho-no-Obi"}
sets.defense.MDT = {
head="Hagondes Hat",neck="Twilight Torque",ear1="Gifted Earring",ear2="Loquacious Earring",
body="Vanir Cotehardie",hands="Yaoyotl Gloves",ring1="Defending Ring",ring2="Shadow Ring",
back="Umbra Cape",waist="Fucho-no-Obi",legs="Bokwus Slops"}
sets.Kiting = {back="Mecistopins Mantle", feet="Herald's Gaiters"}
-- sets.latent_refresh = {waist="Fucho-no-obi"}
sets.reive = {neck="Adoulin's Refuge +1"}
--------------------------------------
-- Engaged sets
--------------------------------------
-- Normal melee group
sets.engaged = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Convoker's Horn +1",neck="Asperity Necklace",ear1="Steelflash Earring",ear2="Bladeborn Earring",
body="Hagondes coat +1",hands="Regimen mittens",ring1="Thurandaut Ring",ring2="Evoker's Ring",
back="Blithe Mantle",waist="Moepapa Stone",legs="Assiduity pants +1",feet="Convoker's pigaches +1"}
sets.engaged.Acc = {main="Nirvana",sub="Oneiros Grip",ammo="Seraphicaller",
head="Theia's Hairpin +1",neck="Empath Necklace",ear1="Steelflash Earring",ear2="Heartseeker Earring",
body="Hagondes coat +1",hands="Regimen mittens",ring1="Thurandaut Ring",ring2="Patricius Ring",
back="Kayapa Cape",waist="Kuku Stone",legs="Assiduity pants +1",feet="Convoker's pigaches +1"}
end
-------------------------------------------------------------------------------------------------------------------
-- Job-specific hooks for standard casting events.
-------------------------------------------------------------------------------------------------------------------
-- Set eventArgs.handled to true if we don't want any automatic gear equipping to be done.
-- Set eventArgs.useMidcastGear to true if we want midcast gear equipped on precast.
function job_precast(spell, action, spellMap, eventArgs)
if state.Buff['Astral Conduit'] or state.Buff['Apogee'] and pet_midaction() then
eventArgs.useMidcastGear = true
end
end
function job_precast(spell, action, spellMap, eventArgs)
if state.Buff["Astral Conduit"] then
sets.precast.BloodPactWard = sets.precast.BloodPactWard["Astral Conduit"]
sets.precast.BloodPactRage = sets.precast.BloodPactRage["Astral Conduit"]
end
end
function job_precast(spell, action, spellMap, eventArgs)
if spell.english == "Paralyna" and buffactive.Paralyzed then
-- no gear swaps if we're paralyzed, to avoid blinking while trying to remove it.
eventArgs.handled = true
end
end
function job_precast(spell, action, spellMap, eventArgs)
cancel_conflicting_buffs(spell, action, spellMap, eventArgs)
if spell.type == "WeaponSkill" and spell.name ~= 'Myrkr' and spell.target.distance > target_distance then
cancel_spell()
add_to_chat(123, spell.name..' Canceled: [Out of Range]')
return
end
end
function job_midcast(spell, action, spellMap, eventArgs)
if state.Buff['Astral Conduit'] and pet_midaction() then
eventArgs.handled = true
end
end
function job_pet_midcast(spell, action, spellMap, eventArgs)
if spirits:contains(pet.name) then
classes.CustomClass = 'Spirit'
elseif spell.type == 'BloodPactRage' then
if magicalRagePacts:contains(spell.english) then
spellMap = 'MagicalBloodPactRage'
else
spellMap = 'PhysicalBloodPactRage'
end
end
end
-- Runs when pet completes an action.
function job_pet_aftercast(spell, action, spellMap, eventArgs)
if not spell.interrupted and spell.type == 'BloodPactWard' and spellMap ~= 'DebuffBloodPactWard' then
wards.flag = true
wards.spell = spell.english
send_command('wait 4; gs c reset_ward_flag')
end
end
function aftercast(spell,action)
if spell.type ~= 'BloodPactRage' and spell.type ~= 'BloodPactWard' and spell.type ~= 'SummonerPact' then
if pet.isvalid then
equip(sets.idle.avatar[petmode])
else
equip(sets.idle)
end
end
end
-------------------------------------------------------------------------------------------------------------------
-- Job-specific hooks for non-casting events.
-------------------------------------------------------------------------------------------------------------------
-- Called when a player gains or loses a buff.
-- buff == buff gained or lost
-- gain == true if the buff was gained, false if it was lost.
function job_buff_change(buff, gain)
if state.Buff[buff] ~= nil then
handle_equipping_gear(player.status)
elseif storms:contains(buff) then
handle_equipping_gear(player.status)
end
end
-- Handle notifications of general user state change.
function job_state_change(stateField, newValue, oldValue)
if stateField == 'Offense Mode' then
if newValue == 'Normal' then
disable('main','sub','range')
elseif newValue == 'Acc' then
disable('main','sub','range')
else
enable('main','sub','range')
end
end
end
-- Called when the player's pet's status changes.
-- This is also called after pet_change after a pet is released. Check for pet validity.
function job_pet_status_change(newStatus, oldStatus, eventArgs)
if pet.isvalid and not midaction() and not pet_midaction() and (newStatus == 'Engaged' or oldStatus == 'Engaged') then
handle_equipping_gear(player.status, newStatus)
end
end
-- Called when a player gains or loses a pet.
-- pet == pet structure
-- gain == true if the pet was gained, false if it was lost.
function job_pet_change(petparam, gain)
classes.CustomIdleGroups:clear()
if gain then
if avatars:contains(pet.name) then
classes.CustomIdleGroups:append('Avatar')
elseif spirits:contains(pet.name) then
classes.CustomIdleGroups:append('Spirit')
end
else
select_default_macro_book('reset')
end
end
-------------------------------------------------------------------------------------------------------------------
-- User code that supplements standard library decisions.
-------------------------------------------------------------------------------------------------------------------
-- Custom spell mapping.
function job_get_spell_map(spell)
if spell.type == 'BloodPactRage' then
if magicalRagePacts:contains(spell.english) then
return 'MagicalBloodPactRage'
else
return 'PhysicalBloodPactRage'
end
elseif spell.type == 'BloodPactWard' and spell.target.type == 'MONSTER' then
return 'DebuffBloodPactWard'
end
end
-- Modify the default idle set after it was constructed.
function customize_idle_set(idleSet)
if pet.isvalid then
if pet.element == world.day_element then
idleSet = set_combine(idleSet, sets.perp.Day)
end
if pet.element == world.weather_element then
idleSet = set_combine(idleSet, sets.perp.Weather)
end
if sets.perp[pet.name] then
idleSet = set_combine(idleSet, sets.perp[pet.name])
end
gear.perp_staff.name = elements.perpetuance_staff_of[pet.element]
if gear.perp_staff.name and (player.inventory[gear.perp_staff.name] or player.wardrobe[gear.perp_staff.name]) then
idleSet = set_combine(idleSet, sets.perp.staff_and_grip)
end
if state.Buff["Avatar's Favor"] and avatars:contains(pet.name) then
idleSet = set_combine(idleSet, sets.idle.Avatar.Favor)
end
if pet.status == 'Engaged' then
idleSet = set_combine(idleSet, sets.idle.Avatar.Melee)
end
if pet.tp == 300 then
idleSet = set_combine(idleSet, {Neck="Empath Necklace"})
end
if buffactive ['Commitment'] and areas.Adoulin:contains(world.area) and not areas.Cities:contains(world.area) then
idleSet = set_combine(idleSet, {back="Mecistopins Mantle"})
end
end
if player.equipment.back == 'Mecisto. Mantle' then
disable('back')
else
enable('back')
end
if player.mpp < 51 then
idleSet = set_combine(idleSet, sets.latent_refresh)
end
return idleSet
end
-- Called by the 'update' self-command, for common needs.
-- Set eventArgs.handled to true if we don't want automatic equipping of gear.
function job_update(cmdParams, eventArgs)
classes.CustomIdleGroups:clear()
if pet.isvalid then
if avatars:contains(pet.name) then
classes.CustomIdleGroups:append('Avatar')
elseif spirits:contains(pet.name) then
classes.CustomIdleGroups:append('Spirit')
end
end
end
-- Set eventArgs.handled to true if we don't want the automatic display to be run.
function display_current_job_state(eventArgs)
end
-------------------------------------------------------------------------------------------------------------------
-- User self-commands.
-------------------------------------------------------------------------------------------------------------------
-- Called for custom player commands.
function job_self_command(cmdParams, eventArgs)
if cmdParams[1]:lower() == 'petweather' then
handle_petweather()
eventArgs.handled = true
elseif cmdParams[1]:lower() == 'siphon' then
handle_siphoning()
eventArgs.handled = true
elseif cmdParams[1]:lower() == 'pact' then
handle_pacts(cmdParams)
eventArgs.handled = true
elseif cmdParams[1] == 'reset_ward_flag' then
wards.flag = false
wards.spell = ''
eventArgs.handled = true
end
end
-------------------------------------------------------------------------------------------------------------------
-- Utility functions specific to this job.
-------------------------------------------------------------------------------------------------------------------
-- Global intercept on midcast.
function user_post_midcast(spell, action, spellMap, eventArgs)
if buffactive['Reive Mark'] and (spell.skill == 'Elemental Magic' or spellMap == 'Cure' or spellMap == 'Curaga') then
equip(sets.reive)
end
end
function user_customize_idle_set(idleSet)
if buffactive['Reive Mark'] then
idleSet = set_combine(idleSet, sets.reive)
end
return idleSet
end
-- Cast the appopriate storm for the currently summoned avatar, if possible.
function handle_petweather()
if player.sub_job ~= 'SCH' then
add_to_chat(122, "You can not cast storm spells")
return
end
if not pet.isvalid then
add_to_chat(122, "You do not have an active avatar.")
return
end
local element = pet.element
if element == 'Thunder' then
element = 'Lightning'
end
if S{'Light','Dark','Lightning'}:contains(element) then
add_to_chat(122, 'You do not have access to '..elements.storm_of[element]..'.')
return
end
local storm = elements.storm_of[element]
if storm then
send_command('@input /ma "'..elements.storm_of[element]..'" <me>')
else
add_to_chat(123, 'Error: Unknown element ('..tostring(element)..')')
end
end
-- Custom uber-handling of Elemental Siphon
function handle_siphoning()
if areas.Cities:contains(world.area) then
add_to_chat(122, 'Cannot use Elemental Siphon in a city area.')
return
end
local siphonElement
local stormElementToUse
local releasedAvatar
local dontRelease
-- If we already have a spirit out, just use that.
if pet.isvalid and spirits:contains(pet.name) then
siphonElement = pet.element
dontRelease = true
-- If current weather doesn't match the spirit, but the spirit matches the day, try to cast the storm.
if player.sub_job == 'SCH' and pet.element == world.day_element and pet.element ~= world.weather_element then
if not S{'Light','Dark','Lightning'}:contains(pet.element) then
stormElementToUse = pet.element
end
end
-- If we're subbing /sch, there are some conditions where we want to make sure specific weather is up.
-- If current (single) weather is opposed by the current day, we want to change the weather to match
-- the current day, if possible.
elseif player.sub_job == 'SCH' and world.weather_element ~= 'None' then
-- We can override single-intensity weather; leave double weather alone, since even if
-- it's partially countered by the day, it's not worth changing.
if get_weather_intensity() == 1 then
-- If current weather is weak to the current day, it cancels the benefits for
-- siphon. Change it to the day's weather if possible (+0 to +20%), or any non-weak
-- weather if not.
-- If the current weather matches the current avatar's element (being used to reduce
-- perpetuation), don't change it; just accept the penalty on Siphon.
if world.weather_element == elements.weak_to[world.day_element] and
(not pet.isvalid or world.weather_element ~= pet.element) then
-- We can't cast lightning/dark/light weather, so use a neutral element
if S{'Light','Dark','Lightning'}:contains(world.day_element) then
stormElementToUse = 'Wind'
else
stormElementToUse = world.day_element
end
end
end
end
-- If we decided to use a storm, set that as the spirit element to cast.
if stormElementToUse then
siphonElement = stormElementToUse
elseif world.weather_element ~= 'None' and (get_weather_intensity() == 2 or world.weather_element ~= elements.weak_to[world.day_element]) then
siphonElement = world.weather_element
else
siphonElement = world.day_element
end
local command = ''
local releaseWait = 0
if pet.isvalid and avatars:contains(pet.name) then
command = command..'input /pet "Release" <me>;wait 1.1;'
releasedAvatar = pet.name
releaseWait = 10
end
if stormElementToUse then
command = command..'input /ma "'..elements.storm_of[stormElementToUse]..'" <me>;wait 4;'
releaseWait = releaseWait - 4
end
if not (pet.isvalid and spirits:contains(pet.name)) then
command = command..'input /ma "'..elements.spirit_of[siphonElement]..'" <me>;wait 4;'
releaseWait = releaseWait - 4
end
command = command..'input /ja "Elemental Siphon" <me>;'
releaseWait = releaseWait - 1
releaseWait = releaseWait + 0.1
if not dontRelease then
if releaseWait > 0 then
command = command..'wait '..tostring(releaseWait)..';'
else
command = command..'wait 1.1;'
end
command = command..'input /pet "Release" <me>;'
end
if releasedAvatar then
command = command..'wait 1.1;input /ma "'..releasedAvatar..'" <me>'
end
send_command(command)
end
-- Handles executing blood pacts in a generic, avatar-agnostic way.
-- cmdParams is the split of the self-command.
-- gs c [pact] [pacttype]
function handle_pacts(cmdParams)
if areas.Cities:contains(world.area) then
add_to_chat(122, 'You cannot use pacts in town.')
return
end
if not pet.isvalid then
add_to_chat(122,'No avatar currently available. Returning to default macro set.')
select_default_macro_book('reset')
return
end
if spirits:contains(pet.name) then
add_to_chat(122,'Cannot use pacts with spirits.')
return
end
if not cmdParams[2] then
add_to_chat(123,'No pact type given.')
return
end
local pact = cmdParams[2]:lower()
if not pacts[pact] then
add_to_chat(123,'Unknown pact type: '..tostring(pact))
return
end
if pacts[pact][pet.name] then
if pact == 'astralflow' and not buffactive['astral flow'] then
add_to_chat(122,'Cannot use Astral Flow pacts at this time.')
return
end
-- Leave out target; let Shortcuts auto-determine it.
send_command('@input /pet "'..pacts[pact][pet.name]..'"')
else
add_to_chat(122,pet.name..' does not have a pact of type ['..pact..'].')
end
end
-- Event handler for updates to player skill, since we can't rely on skill being
-- correct at pet_aftercast for the creation of custom timers.
windower.raw_register_event('incoming chunk',
function (id)
if id == 0x62 then
if wards.flag then
create_pact_timer(wards.spell)
wards.flag = false
wards.spell = ''
end
end
end)
-- Function to create custom timers using the Timers addon. Calculates ward duration
-- based on player skill and base pact duration (defined in job_setup).
function create_pact_timer(spell_name)
-- Create custom timers for ward pacts.
if wards.durations[spell_name] then
local ward_duration = wards.durations[spell_name]
if ward_duration < 181 then
local skill = player.skills.summoning_magic
if skill > 300 then
skill = skill - 300
if skill > 200 then skill = 200 end
ward_duration = ward_duration + skill
end
end
local timer_cmd = 'timers c "'..spell_name..'" '..tostring(ward_duration)..' down'
if wards.icons[spell_name] then
timer_cmd = timer_cmd..' '..wards.icons[spell_name]
end
send_command(timer_cmd)
end
end
-- Select default macro book on initial load or subjob change.
function select_default_macro_book(reset)
if reset == 'reset' then
-- lost pet, or tried to use pact when pet is gone
end
-- Default macro set/book
set_macro_page(2, 4)
end
Just looking for someone to explain this addon a bit for me. It looks like it is an alternative to Spellcast.
Is it going to be replacing Spellcast? In which ways is it better or worse. I don't know any programming but I've slowly learned more and more about spellcast and the 'language' used in gearswap is confusing to me.
It says it uses packets so it potentially could be more detectable? but does that also eliminate any lag that spellcast may encounter?
I plan on redoing my PUP xml to include pet casting sets thanks to the new addon petschool. I'm just not sure if it's worth it to just wait until gearswap gets more popular or to go ahead and do it in spellcast.
If anyone could give me more info I'd greatly appreciate it.
|
|