ScriptUO

Official ScriptUO EasyUO Scripts => Scripting Tutorials => Topic started by: Cerveza on February 24, 2009, 10:18:21 AM

Title: Tutorial 4 - Your First Script - Part 2 (maybe your second script?)
Post by: Cerveza on February 24, 2009, 10:18:21 AM
Ok, you should have read Basic Script Flow (http://www.scriptuo.com/index.php?topic=976.0) and Your First Script (http://www.scriptuo.com/index.php?topic=977.0) already. If not go back and read them before continuing.

In this script, your going to be modifying your "Drink Cure Potion" script to drink Greater Heal potions. After you see this, you should be able to add in Total Refreshes on your own  ;)

You know the flow of a script, and you see how to drink a cure potion. Now we want to add in a condition to drink a heal potion as well. When scripting it's very important to keep redundant work to a minimum. You don't want to have repetitive coding in your script. If you can do the same functions using the same code, then just use a gosub to that section of code.

Here's what I'm talking about... we want to drink a cure potion. We already know how to find one, and drink one. Well now we're adding in a heal potion. Whats the difference between drinking the two? Really only the item itself is different right? One is NUF (cure potion) and one is UUF (heal potion). So do we really need ALL the code twice for this?

In this lesson you'll be learning how to send a variable to a sub routine! Oh yeah, you'll learn what sub routines are LOL. And you get the bonus included lesson on TIMERS!

So... here we go.

1 - What do we want to do?
Drink a cure when poisoned and drink a heal when hurt

2 - Define it line by line
If poisoned - find cure - drink it
If hurt - find heal - drink it

The biggest difference in this script is that the script will continue if one of the potions isn't found. I mean why stop the cures just because a heal isn't found?

Ok.... lets get to scripting.

Header:
Code: [Select]
;=================================================================
; Script Name: Cerveza's Cure And Heal Pot Drinker
; Author: Cerveza
; Version: 1.0
; Shard OSI / FS: OSI / FS OK
; Revision Date: 2/24/2009
; Purpose: Drink Cure/Heal Potions when needed
; Globals: None
;=================================================================

Ok, thats the easy part, now lets get to work. We need to do a little setup now. First thing we need to know is "when do we want to drink a heal potion"?

Lets say we drink a heal pot when our HP's go down 40 points. "But that'll be different for each player" you scream... Yes, yes it is. But we are scripters, damnit! We can make this happen... watch:

Code: [Select]
set %healpotHP ( #maxHits - 40 )
"Dayum" - you all collectively say... "thats some slick coding there. This Cerveza dude is saying that no matter what our maximum hit points are, he'll subtract 40 from it and make a variable he can use later in the script to use as a trigger for drinking a heal potion."

Then a squeeky voice in the back says, "but I wanna drink it at 30". Ok squeeky, we'll change it JUST FOR YOU

Code: [Select]
set %healLEVEL 40 ; change this to HOW MANY HP's DOWN to drink a heal pot... squeeky sux
set %healpotHP ( #maxHits - %healLEVEL )

Happy now squeeky? You could also just use the original ONE line code and put a comment after it so users know to change the level.

Ok now the surprise. TIMERS - YEAH!

Since Heal Potions have a 10 second timer between uses, we need to make sure we know when one was drank (drunk? dranken? drunken?) quaffed last. So... what do we know about timers? They keep track of time. I guess thats all we really need to know about them.

Now how do we use a timer in this case? We DO NOT want to stop the script for 10 seconds while we wait out the GH timer. That's a definate no-no. So what we need to do is set a time to allow the heal potions to be quaffed again.

Code: [Select]
set %timer_pot_heal #sCnt
That line sets the variable %timer_pot_heal to the "seconds" timer. There are other timers you can use but #sCnt makes the most sense for this application.

When we get to the actually drinking of the greater heal I'll show how the variable %set_pot_timer works. For now just know that the instant the script begins, #sCnt will be GREATER then %set_pot_timer. Because the variable isn't changing but the #sCnt is always advancing.

Ok, enough side tracking, lets get working on this script. Header - done, mainloop/script/subs next.

Code: [Select]
SUO:
repeat

if C in #charStatus
  gosub DrinkIt NUF

if #hits < %healpotHP && #sCnt > %timer_pot_heal
  {
    gosub DrinkIt UUF
    set %timer_pot_heal ( #sCnt + 10 )
  }
wait 5

until #CharGhost = YES
while #CharGhost = YES
  wait 0
GoTo SUO

sub DrinkIt
  wait 5
  findItem %1 C_ , #backpackID
  if #findKind = -1
    return
  set #lobjectID #findID
  set #ltargetKind 1
  event macro 17 0
return

Ok, the cure portion should look familiar, with the exception of the gosub.

gosub DrinkIt NUF

This line tells the script to go execute the section of code in the sub routine named DrinkIt and sent a variable of NUF. In the sub routine you see that the item Type to drink is %1 now. Sub routines can have multiple parameters.

%1 is the first parameter, %2 the second, etc... %0 shows the number of parameters sent to the sub.

There's also new stuff in the heal portion.

if #hits < %healpotHP && #sCnt > %timer_pot_heal

This says, "if the current hits is less then the hit points you set earlier AND (&& means AND) the current time is more then the variable" then execute the next line, which is to gosub to the DrinkIt sub with the parameter %1 set as UUF.

Now, after the sub routine is finished... and you should recognize the sub routine because it is the first script we wrote back in the Cure Pot days.... you return to the exact spot that sent you to the sub routine with a "return" statement. NEVER USE A GOTO OUT OF A SUB!!

When you return to the main loop you'll execute the next line of code, which is

set %timer_pot_heal ( #sCnt + 10 )

What are we doing?! We're setting the new heal potion timer to 10 seconds in the future. That means that for the next 10 seconds, the variable %timer_pot_heal will be GREATER then #sCnt!! See, I told you I'd show you how we can use the timer. Now when the script hits the line:

if #hits < %healpotHP && #sCnt > %timer_pot_heal

It will check the current hit points, if they are lower then our 40 down, then it will check the timer... OMG #sCnt is NOT greater then %timer_pot_heal, so the IF statement is NOT true and the next line (or section in the {} ) will NOT be executed, it will be skipped over.

Coding is fun! Here's the whole thing completed:

Code: [Select]
;=================================================================
; Script Name: Cerveza's Cure And Heal Pot Drinker
; Author: Cerveza
; Version: 1.0
; Shard OSI / FS: OSI / FS OK
; Revision Date: 2/24/2009
; Purpose: Drink Cure/Heal Potions when needed
; Globals: None
;=================================================================

;************************ Setup **********************************
set %healpotHP ( #maxHits - 40 ) ; change this for how many points down to drink heal
set %timer_pot_heal #sCnt

;*********************** MainLoop ********************************
SUO:
repeat
  
  if C in #charStatus
    gosub DrinkIt NUF
  
  if #hits < %healpotHP && #sCnt > %timer_pot_heal
  {
    gosub DrinkIt UUF
    set %timer_pot_heal ( #sCnt + 10 )
  }
  wait 5
  
until #CharGhost = YES
while #CharGhost = YES
  wait 0
GoTo SUO

;************************ Subs ***********************************
sub DrinkIt
  wait 5
  findItem %1 C_ , #backpackID
  if #findKind = -1
    return
  set #lobjectID #findID
  set #ltargetKind 1
  event macro 17 0
return
Title: Re: 4 - Your First Script - Part 2 (maybe your second script?)
Post by: camotbik on December 28, 2009, 12:39:32 PM
Finally a normal explanation of timers, thank you )
Title: Re: Tutorial 4 - Your First Script - Part 2 (maybe your second script?)
Post by: Cerveza on September 20, 2011, 06:32:24 AM
stickied