[EasyUO] Shindaril's Spirit - A Cristmas Special

If you make a Client-side script you can publish it here for other players to use
Locked
Shindaril
Grandmaster Scribe
Posts: 96
Joined: Tue Jul 01, 2014 12:11 pm

[EasyUO] Shindaril's Spirit - A Cristmas Special

Post by Shindaril »

Hiya everybody and merry Christmas!

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

Lastly, I know this script might have issues for some players, but the main reason for posting this is to show how one can use timers simultaneously. I also do admit that the main loop would be safer to use inside a while loop, but as the script I'm working on for my personal use is still under development, I think it as a very minor issue.


*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.
Locked