TheNomadMan
New member
- Joined
- Feb 8, 2014
- RedCents
- 451¢
Recently, the development of KissAssist has moved away from using the asynchronous plugin MQ2Cast in favor of the in-line macro MQ2Cast_Spell_Routines. Doing so assures that all cast functions are handled in a liner fashion and prevents "sync issues" that had previously been compensated for (to varing degrees of success) through the use of hardcoded delays. However, this also represents a complete loss of all advantageous asynchronous behavior while casting and creates artificial lag in KissAssist itself.
Allowing for, taking advantage of, and staying in sync with asynchronous plugins requires the use of While loops. MQ2 does not support actual while functions. However, while loops can be simulated through the use of no-delay loops to a bookmark. For example:
- This will effectively monitor the MA's HP while a DPS spell is casting. Thusly allowing us to interrupt the DPS spell if the MA's HP hits an ini defined threshold while the spell is still casting. In this example the macro would then move to Sub CheckHealth to ensure heals are sorted out before another DPS is attempted. Below the HP monitoring loop is a casting status monitor. This will hold all "If cast result equals" lines until after there is an actual cast result or the lack there of. Thusly keeping the KA macro and MQ2Cast plugin in sync. This is not possible with Spell Routines as it runs in-line, rather than parallel to, KissAssist and therefore will not reach the monitoring loop until after spell casting is complete.
Because there will be conditions that escape us on occasion, reliability can be ensured with catch-all while looping at the beginning of any cast related subroutine. For example:
Simulated while loops can also be used to replace many other delays and improve general responsiveness.
This segment, used to check for globalcool down, can use this loop behavior to trim off a little time
as opposed to the current
While this segment can be removed all togather to trim off a big chunk of time:
Because the aforementioned simulated while loops already sort out the necessary delay down to as fine a grain as can be done, removing the above line safely brings about a very significant improvement in the over all time-cost of mob mezzing.
And; because simulated-while looping gives us such a sure and fast response to events, code such as fast Nuke-Healing becomes viable as well as true chaining of heals, runes as heals, stuns, nukes, etc. This, because there is no guessing as to the delay nessiacary to compensate for lag, slow machines, or unforeseen events. The delay to allow for proper targeting and spell selection becomes dynamic and always as precisely what we need as possible. And; less code is run through due to "skips" than otherwise possiable without accounting for every single condition in EQ.
To conclude this post: simulated-while loops can improve KA's progression speed thru in-line code, reduce the occurrence of skipped events, and can extend KA's functionality by taking advantage of, rather than being hindered by, asynchronous plugins.
Below is a functional example of how using asynchronous plugins and simulated-while loops can improve your KissAssist experience. I'd suggest allowing it to make a fresh ini; if you'd like to try out the nuke healing, dps cast interrupting, chain healing with DPS enabled, and ooc rezzing features. Be aware there are other changes in this example, too (no AE's or Mez's if extended target window is clear, check health after successful heals, and other such tweeks).
Allowing for, taking advantage of, and staying in sync with asynchronous plugins requires the use of While loops. MQ2 does not support actual while functions. However, while loops can be simulated through the use of no-delay loops to a bookmark. For example:
- This will effectively monitor the MA's HP while a DPS spell is casting. Thusly allowing us to interrupt the DPS spell if the MA's HP hits an ini defined threshold while the spell is still casting. In this example the macro would then move to Sub CheckHealth to ensure heals are sorted out before another DPS is attempted. Below the HP monitoring loop is a casting status monitor. This will hold all "If cast result equals" lines until after there is an actual cast result or the lack there of. Thusly keeping the KA macro and MQ2Cast plugin in sync. This is not possible with Spell Routines as it runs in-line, rather than parallel to, KissAssist and therefore will not reach the monitoring loop until after spell casting is complete.
Rich (BB code):
/if (${Cast.Ready[${castWhat}]} && !${IAmABard}) {
/casting "${castWhat}"
| Monitor MA HP While Casting. Abort if InterruptHP is hit.
:MonitorHPWhileCasting
/if (${sentFrom.Equal[DPS]} && ${Spawn[${MainAssist} ${MainAssistType}].PctHPs}<=${InterruptHP}) {
/docommand /stopcast
/echo ${sentFrom} spell ${castWhat} ABORTED to CAST A HEAL!
/call CheckHealth
}
/if (${sentFrom.Equal[DPS]} && ${${Cast.Status}.Equal[C]}) /goto :MonitorHPWhileCasting
| Wait while casting
:Stillcasting
/if (${${Cast.Status}.Equal[C]}) /goto :Stillcasting
/varset CastResult ${Cast.Return}
/if (${Debug}) /echo DEBUG CastWhat cast Spell result: ${Cast.Return}
/doevents
/call CheckCasting 50
}
Because there will be conditions that escape us on occasion, reliability can be ensured with catch-all while looping at the beginning of any cast related subroutine. For example:
Rich (BB code):
/for i 1 to ${SingleHeal.Size}
| If heal is null or off |0 or spell/aa/item not ready skip it
/if (${DebugHeal} || ${DebugAll}) /echo DEBUGHEALS SingleHeal Spell ${i}: ${SingleHeal[${i}]} ${SingleHeal[${i}].Arg[1,|]} ${SingleHeal[${i}].Arg[2,|]} ${SingleHeal[${i}].Arg[3,|]}
/if (${DebugHeal} || ${DebugAll}) /echo DEBUGHEALS SingleHeal SpellSkip: !${SingleHeal[${i}].Length} || ${SingleHeal[${i}].Arg[2,|].Equal[0]}}
/if (!${SingleHeal[${i}].Length} || ${SingleHeal[${i}].Arg[2,|].Equal[0]}) /goto :SNextHeal
:tooofast
/if (!${IAmABard} && !${Cast.Ready[${SingleHeal[${i}]}]} && !${Me.SpellReady[${Me.Gem[1].Name}]} && !${Me.SpellReady[${Me.Gem[3].Name}]} && !${Me.SpellReady[${Me.Gem[5].Name}]} && !${Me.SpellReady[${Me.Gem[7].Name}]}) /goto :tooofast
/if (!${IAmABard} && !${Cast.Ready[${SingleHeal[${i}]}]} && (${Me.SpellReady[${Me.Gem[1].Name}]} || ${Me.SpellReady[${Me.Gem[3].Name}]} || ${Me.SpellReady[${Me.Gem[5].Name}]} || ${Me.SpellReady[${Me.Gem[7].Name}]})) /goto :SNextHeal
Simulated while loops can also be used to replace many other delays and improve general responsiveness.
This segment, used to check for globalcool down, can use this loop behavior to trim off a little time
Rich (BB code):
:Waitforcooldown
/if (!${IAmABard} && !${Cast.Ready[${castWhat}]} && !${Me.SpellReady[${Me.Gem[1].Name}]} && !${Me.SpellReady[${Me.Gem[3].Name}]} && !${Me.SpellReady[${Me.Gem[5].Name}]} && !${Me.SpellReady[${Me.Gem[7].Name}]}) /goto :Waitforcooldown
as opposed to the current
Rich (BB code):
:Waitforcooldown
/if (!${IAmABard} && !${Me.SpellReady[${castWhat}]} && !${Me.SpellReady[${Me.Gem[1].Name}]} && !${Me.SpellReady[${Me.Gem[3].Name}]} && !${Me.SpellReady[${Me.Gem[5].Name}]} && !${Me.SpellReady[${Me.Gem[7].Name}]}) {
/delay 2
/goto :Waitforcooldown
}
While this segment can be removed all togather to trim off a big chunk of time:
Rich (BB code):
/delay 3s ${Me.SpellReady[${MezSpell}]}
Because the aforementioned simulated while loops already sort out the necessary delay down to as fine a grain as can be done, removing the above line safely brings about a very significant improvement in the over all time-cost of mob mezzing.
Rich (BB code):
A targeting example would be like this:
| -------------------------------------------------------------------------------------
| SUB: CombatTargetCheck
| -------------------------------------------------------------------------------------
Sub CombatTargetCheck
:fixtarget
/squelch /target id ${MyTargetID}
/if (${Target.ID}!=${MyTargetID} && ${Spawn[${MyTargetID}].ID}) /goto :fixtarget
/return
| -------------------------------------------------------------------------------------
OR
| -------------------------------------------------------------------------------------
| SUB: CombatTargetCheck
| -------------------------------------------------------------------------------------
Sub CombatTargetCheck
:fixtarget
/if (${Target.ID}!=${MyTargetID} && ${Spawn[${MyTargetID}].ID}) {
/squelch /target id ${MyTargetID}
/goto :fixtarget
}
/return
| -------------------------------------------------------------------------------------
rather than
| -------------------------------------------------------------------------------------
| SUB: CombatTargetCheck
| -------------------------------------------------------------------------------------
Sub CombatTargetCheck
/if (${Target.ID}!=${MyTargetID} && ${Spawn[${MyTargetID}].ID}) {
/squelch /target id ${MyTargetID}
/delay 10 ${Target.ID}==${MyTargetID}
}
/return
| -------------------------------------------------------------------------------------
And; because simulated-while looping gives us such a sure and fast response to events, code such as fast Nuke-Healing becomes viable as well as true chaining of heals, runes as heals, stuns, nukes, etc. This, because there is no guessing as to the delay nessiacary to compensate for lag, slow machines, or unforeseen events. The delay to allow for proper targeting and spell selection becomes dynamic and always as precisely what we need as possible. And; less code is run through due to "skips" than otherwise possiable without accounting for every single condition in EQ.
Rich (BB code):
| Check For Nuke Heals
/if (${SHealTag.Find[Mob]}) {
/if (!${AggroTargetID}) /goto :SNextHeal
/doevents Switch
/if (!${MyTargetID}) /call Assist
/if (${MyTargetID} && ${Spawn[${MainAssist} ${MainAssistType}].PctHPs}<=${SHealPct} && ${Spawn[${MyTargetID}].ID} && ${Spawn[${MyTargetID}].Distance}<=${SHealRange}) {
/call CastWhat "${SHealSpell}" ${Spawn[${MyTargetID}].ID} Heal
/if (${Macro.Return.Equal[CAST_SUCCESS]}) {
/call BroadCast ${IRCOn} ${EQBCOn} o "${SHealSpell} for ${SHealThem} >> Heal Nuke << aginst ${Spawn[${MyTargetID}].ID} "
/call CheckHealth
/return
}
} else {
/goto :SNextHeal
}
To conclude this post: simulated-while loops can improve KA's progression speed thru in-line code, reduce the occurrence of skipped events, and can extend KA's functionality by taking advantage of, rather than being hindered by, asynchronous plugins.
Below is a functional example of how using asynchronous plugins and simulated-while loops can improve your KissAssist experience. I'd suggest allowing it to make a fresh ini; if you'd like to try out the nuke healing, dps cast interrupting, chain healing with DPS enabled, and ooc rezzing features. Be aware there are other changes in this example, too (no AE's or Mez's if extended target window is clear, check health after successful heals, and other such tweeks).
Attachments
Last edited:

