It's a magical night of Christmas Spirit beginning to fill the land where I live in. Good will and happiness surrounding me, I'm here with a present in a form of part of my own Ultima Online Spirit - A part of my main script I run while playing
To my great regret, I'm afraid to publish the whole script as I do not think it'd be appropriate to share publicly and the staff might not take it lightly as it would indeed make it possible to be used for full time AFK fighting with minor changes and additions.
However! The reason why I'm sharing this part is to present a solid script for those who wish one for survivability (best run with an auto-healing script as adding one to this one would also hinder the auto-healing script, this is more to support an auto-healing script and most likely to replace a auto-divine fury script), or simply wish to see an example how you can run multiple and even simultaneous timers inside the same script to make the whole script more flexible and as an example how you can avoid wait scripts when you need to make a script which will respond no matter what's the situation.
That being said, I must give my apologies of laziness as well and give credit to those who have earned it:
I hail Guadah on PSL for the great sub for going through the item properties of the items worn by a character. This is great and even though the FC and FCR calculation routines were better to be re-written for this script, that sub alone is worth gracing!
I also hail Nunja for the old school (pre-EasyUO 1.5) way of doing cmpPix, which for some reason does crash my client when ran with other scripts, most likely something to do with #lTargetID, which does sound weird, but the way shown in Nunja's Armer works wonders.
Lastly, I hail Devlin for the simple set-up sub for the weapon abilities. So simple and all that's ever needed in my opinion. It would be wasted time to re-write this when the result would be more or less the same.
I would also like to give special thanks to Yoda for the simple menu layout with clear font and minimized button placement. This one isn't as compact as his menus, but I did want to place some empty space to make it less likely to miss click the buttons.
I also wish to say here that by these credits, I wish that everybody will give credit to where it belongs, those three things are not written by me, even if I did make some changes to those. I did simplify the Nunja's routines, the main principle I learned from his script and I did take what I needed while dropping all the things I saw unneeded. I could have as well just defined variables for FC and FCR to make the user to set those up, but that sub from Guadah is just so good that I thought to save it somehow if I ever need one like that in the future.
Anyway, I'm guessing you are feeling bored with all the praises and talk by now - Assuming you're still reading and didn't just copy the script and ran it like most people tend to do...
Here's the script. Not fully commented, but the features, possible problems and the notes are listed in the comments of the script itself:
Code: Select all
; Shindaril's Spirit
; Version 1.0
; Date: 24.12.2014
; Stripped down from my own script as an example and also to serve as a Christmas Present for the lovely players of Excelsior
; My apologies for only publishing a part of the script as I do not think the staff would appreciate if I made the whole concept public
; I hope this serves as an example how to run multiple timers at the same time as well as how to make the calculations based on the restrictions
; EasyUO has - Mainly the limitation how EasyUO drops the decimals, so you need to base all your calculations on integers to make it work.
; The timers in this script are working properly, but are still a subject to server side lag, which may and will make you fail a casting time check
; inside the script.
; The script does not check for the user's mana for casting the spells, as I've found it not needed with my character, so I left it out to speed the script up slightly.
; It should be obivious, but the script will need the Primary, Secondary and Momentum Strike icons on your game window to work. Also, these three should be
; non-active when the set-up is ran or the script will simply de-activate them instead of activating them.
; Also something to note, the abilities, mainly Momentum Strike, might blink for a few times when activated for the first time. This is due to the script running
; Under 150 lines per loop, which at #lpc 20 means, it'll run three times a second most of the time. Any computer lag within the client will make it so that
; the ability icon won't have time to change color before the script scans it again.
; Features:
; -Auto-cast Curse Weapon when mortally wounded or at critical hp
; -Auto-spam weapon abilities
; -Toggle for auto-casting Consecrate Weapon: On / Off
; -Auto-cast Divine Fury when below set stamina percentage
; -Spellcasting timers based on the duration of the spells as well as the player's casting speed - User cast spells can still make a spell not to be cast
; -Automatically determine the player's equipped FC and FCR - Needs restart if gear is changed to re-calculate these before the reset is added
set #sCnt2 0 ; Let's reset the timer to deal with smaller numbers and thus faster calculations
set %CriticalHP 40 ; This is used with D in #CharStatus in the Curse Weapon loop
set %CurseWeaponWait 330 ; Wait time for Curse Weapon in 10th's of a second
set %CurseWeaponTimer #sCnt2 - %CurseWeaponWait ; Using multiple timers all based on #sCnt2 for fast comparisons and to avoid unnessessary waits
set %ConsecrateWeaponWait 100 ; Wait time for Consecrate Weapon in 10th's of a second
set %ConsecrateWeaponTimer #sCnt2 - %ConsecrateWeaponWait ;
set %CriticalStaminaPercentage 60 ; Dynamic way to avoid the need to change the script every time your stamina changes
set %DivineFuryWait 70 ; Wait time for Divine Fury in 10th's of a second used for anti-spam the spell
set %DivineFuryTimer #sCnt2 - %DivineFuryWait ; To allow anti-spam for the Divine Fury
set %CastingTime 13 ;
set #lpc 20 ; 20 lines per cycle with 20 cycles in a second is enough to do 400 lines in a second, so it's enough for this script...For now...
set %CWOn #False ; Consecrate Weapon auto-casting switch
set %LastCastTime #sCnt2 ; To block new spells while still casting
set %AbilityWait 10 ; To slow down weapon ability spamming
set %AbilityTimer #sCnt2 - %AbilityWait ;
set %Ability 0 ; Stores the selected weapon ability
set %AbilityMinMana 75 ; Mana percentage for weapon abilities
set %UseProtection #True ; For the FC cap restriction
set %SpellLevel 8 ; Precautious move to set this to it's highest possible value in game
if *Save <> 1
{
gosub Setup
}
gosub Init
event ExMsg #CharID 0 20 Setup done, mainloop begins
menu clear ;
set #menubutton none
menu Window Title Shindaril's Spirit
menu window color $FF99FF
menu window transparent 95
menu window size 120 113
menu Font Name Gautami
menu Font Size 8
menu Font Style b
menu Font BGColor $FF99FF
menu Font Color $0000DD
menu text CW 14 0 Consecrate Weapon:
menu button CWon 3 20 60 20 On ; menu Button {name} {x} {y} {width} {height} {text}
menu button CWoff 63 20 60 20 Off
menu button Primary 3 45 60 20 Primary
menu button Secondary 63 45 60 20 Secondary
menu button Momentum 3 65 60 20 Momentum
menu button Clear 63 65 60 20 Clear
menu button Setup 33 90 60 20 Setup
menu show
Main:
gosub CheckMenu
if ( #CharGhost = NO && H notin #CharStatus )
{
gosub CurseWeapon ; Comment this line out if you do not want to auto-cast Curse Weapon when mortally wounded of below the critical HP
gosub Ability
if %CWOn = #True
{
gosub ConsecrateWeapon
}
gosub DivineFury
}
else
{
wait 5
}
goto Main
sub CurseWeapon
if ( %CurseWeaponTimer + %CurseWeaponWait ) <= #sCnt2 && ( %LastCastTime + %CastingTime ) <= #sCnt2
{
if ( D in #CharStatus || ( #Hits * 100 ) / #MaxHits <= %CriticalHP )
{
event macro 15 104
event ExMsg #CHARID 2 13 Mortal Wound!
set %CurseWeaponTimer #sCnt2
set %LastCastTime #sCnt2
set %SpellLevel 1 ; Curse Weapon is 1st level spell
set %CastingTime ( ( ( ( 300 + %SpellLevel * 100 ) / 4 ) + ( 600 - %UserFCR * 100 ) / 4 ) ) ; FC doesn't affect on Necromancy - EasyUO only knows integers, so we need to do the math without decimals
if %CastingTime % 10 <> 0
{
set %CastingTime ( %CastingTime + 5 )
}
set %CastingTime ( %CastingTime / 10 )
}
}
return
sub CheckMenu
if #MenuButton = CWon
{
set %CWCreatures #False
set %CWOn #True
}
if #MenuButton = CWoff
{
set %CWCreatures #False
set %CWOn #False
}
if #MenuButton = Primary
{
set %Ability 1
set %AbilityIconX *PrimaryX
set %AbilityIconY *PrimaryY
set %AbilityColorTest %PrimaryColour
set %AttackEventMacroParam1 35
set %AttackEventMacroParam2 0
}
if #MenuButton = Secondary
{
set %Ability 2
set %AbilityIconX *SecondaryX
set %AbilityIconY *SecondaryY
set %AbilityColorTest %SecondaryColour
set %AttackEventMacroParam1 36
set %AttackEventMacroParam2 0
}
if #MenuButton = Momentum
{
set %Ability 3
set %AbilityIconX *MomentumX
set %AbilityIconY *MomentumY
set %AbilityColorTest %MomentumColour
set %AttackEventMacroParam1 15
set %AttackEventMacroParam2 150
}
if #MenuButton = Clear
{
set %Ability 0
}
if #MenuButton = Setup
{
gosub Setup
}
set #MenuButton #False
return
sub Ability
if ( %Ability <> 0 && %AbilityTimer + %AbilityWait <= #sCnt2 )
{
if ( ( #Mana * 100 ) / #MaxMana > %AbilityMinMana )
{
savePix %AbilityIconX %AbilityIconY 5
if ( #PixCol = %AbilityColorTest )
{
event macro %AttackEventMacroParam1 %AttackEventMacroParam2
set %AbilityTimer #sCnt2
if %Ability = 1
{
savePix %AbilityIconX %AbilityIconY 5
if ( #PixCol <> %AbilityColorTest )
set %PrimaryOnColour #PixCol
}
if %Ability = 2
{
savePix %AbilityIconX %AbilityIconY 5
if ( #PixCol <> %AbilityColorTest )
set %SecondaryOnColour #PixCol
}
}
else
{
if ( %Ability = 1 ) && ( #PixCol <> %PrimaryOnColour )
{
savepix *PrimaryX *PrimaryY 1
set %PrimaryColour #PixCol
set %AbilityColorTest %PrimaryColour
}
if ( %Ability = 2 ) && ( #PixCol <> %SecondaryOnColour )
{
savepix *SecondaryX *SecondaryY 2
set %SecondaryColour #PixCol
set %AbilityColorTest %SecondaryColour
}
}
}
}
return
sub ConsecrateWeapon
if ( %ConsecrateWeaponTimer + %ConsecrateWeaponWait ) <= #sCnt2 && ( %LastCastTime + %CastingTime ) <= #sCnt2
{
event macro 15 203
set %ConsecrateWeaponTimer #sCnt2
set %LastCastTime #sCnt2
set %SpellLevel 0 ; Consecrate Weapon is 0th level spell
set %CastingTime ( ( ( ( 300 + %SpellLevel * 100 ) / 4 - ( %UserFC * 100 ) / 4 ) + ( 700 - %UserFCR * 100 ) / 4 ) )
if %CastingTime % 10 <> 0
{
set %CastingTime ( %CastingTime + 5 )
}
set %CastingTime ( %CastingTime / 10 + 5 )
}
return
sub DivineFury
if ( %DivineFuryTimer + %DivineFuryWait ) <= #sCnt2 && ( %LastCastTime + %CastingTime ) <= #sCnt2
{
if ( #Stamina * 100 ) / #MaxStam <= %CriticalStaminaPercentage && #Mana > 10
{
event macro 15 205
set %DivineFuryTimer #sCnt2
set %LastCastTime #sCnt2
set %SpellLevel 2 ; Divine Fury is 2nd level spell
set %CastingTime ( ( ( ( 300 + %SpellLevel * 100 ) / 4 - ( %UserFC * 100 ) / 4 ) + ( 700 - %UserFCR * 100 ) / 4 ) )
if %CastingTime % 10 <> 0
{
set %CastingTime ( %CastingTime + 5 )
}
set %CastingTime ( %CastingTime / 10 + 5 )
}
}
return
; Setup Subs
sub Setup
display Please move your cursor over the Primary Ability Icon. You have 3 seconds to do so.
wait 3s
set *PrimaryX #CursorX
set *PrimaryY #CursorY
display Please move your cursor over the Secondary Ability Icon. You have 3 seconds to do so.
wait 3s
set *SecondaryX #CursorX
set *SecondaryY #CursorY
display Please move your cursor over the Momentum Strike Ability Icon. You have 3 seconds to do so.
wait 3s
set *MomentumX #CursorX
set *MomentumY #CursorY
savePix *PrimaryX *PrimaryY 1
set %PrimaryColour #PixCol
savePix *SecondaryX *SecondaryY 2
set %SecondaryColour #PixCol
savePix *MomentumX *MomentumY 3
set %MomentumColour #PixCol
set *Save 1
wait 5
return
sub Init
gosub suit_properties Faster Casting
set %UserFC #result
if %UseProtection = #True
{
if %UserFC > 2
{
set %UserFC 2
}
}
else if %UserFC > 4
{
set %UserFC 4
}
gosub suit_properties Faster Cast Recovery
set %UserFCR #result
if %UserFCR > 6
{
set %UserFCR 6
}
savePix *PrimaryX *PrimaryY 1
set %PrimaryColour #PixCol
savePix *SecondaryX *SecondaryY 2
set %SecondaryColour #PixCol
savePix *MomentumX *MomentumY 3
set %MomentumColour #PixCol
set *Save 1
wait 5
return
sub suit_properties
if %0 > 0 && %1 <> N/A
{
finditem * C_ , #charid
if #findkind = -1
return %total
set %oldlpc #LPC
set #LPC 10000
set %total 0
set %line % . %0
goto L , %0
L5:
set %line %4 , #spc , %line
L4:
set %line %3 , #spc , %line
L3:
set %line %2 , #spc , %line
L2:
set %line %1 , #spc , %line
L1:
set %line $ , %line , #spc
str len %line
set %len #strRes
for #findindex 1 #findcnt
{
event property #findid
if %line in #property
{
str pos #property %line
set %pos #strRes + %len
str mid #property %pos 5
set %prop #strRes
str pos %prop $
set %pos #strRes - 1
str left %prop %pos
set %tempval #strRes
str pos %tempval %
if #strRes > 1
{
set %pos #strRes - 1
str left %tempval %pos
set %tempval #strRes
}
set %total %total + %tempval
}
}
set #LPC %oldlpc
return %total
}
return 0
*EDIT*
Fixed a typo (missing space in calculations) and %CastingTime timer issue with chivalry spells.
*EDIT2*
Fixed a missing timer reset on the weapon ability routine, now the Momentum Strike works too.