Difference between revisions of "Razor Enhanced Basics"

From UO Eventine Wiki
Jump to navigation Jump to search
Line 287: Line 287:
 
Misc.SendMessage('Script End', 32)
 
Misc.SendMessage('Script End', 32)
 
‎</syntaxhighlight>
 
‎</syntaxhighlight>
 +
 +
'''BREAKDOWN:'''
 +
 +
So let's go through the changes made to achieve this.
 +
 +
'''itemidswloc = [[0x0DF0, 88, 264], [0x410A, 49, 138]]''' This array has been changed. Instead of one Array this becomes essentially an array stored inside an array. The first thing stored in this array is the ItemID, and next are the X and Y location values inside a chest (when an item is in a container and you inspect it the x and y shown are the x y inside the container).
 +
 +
'''for id in itemidswloc:''' Here we have gone so it will cycle one by one each item in the array at the top and let us compare the item with the values inside the array.
 +
 +
'''if i.ItemID == id[0]:''' This is stating if the ItemID matches the ItemID in the array (id[0] would mean the first spot in the array where the ItemID always is).
 +
 +
'''Items.Move(i, tcont, -1, id[1], id[2])''' Now we are moving the if it was correct to the container but telling the server what location inside the container to drop it in (id[1] represents the 2nd parameter inside the array and id[2] represents the third and final one inside the array).
 +
 +
Using this should explain how using arrays in different ways can be useful.
  
 
=Import=
 
=Import=

Revision as of 01:21, 25 June 2023

This page will add some basics to know and help when coding things in Razor Enhanced. The attempt on writing this is to make it as easy as possible to understand some things and will just give a basic example and try to not get too technical to keep learning as easy.

Important Things To Know

Here are a few important things to remember when writing scripts.

  • Check if need to Indent Make sure to always check when needing an indent or not on your code. This can always be a cause for a script not working.
  • Don't Forget Pauses Misc.Pause(timeint) is a very important thing to remember. A lot of times when forgetting to use a pause or the right pause you can sometimes end up with a script that does not work properly and you cannot figure out why. Sometimes having this too low or non-existent can result in crashes.
  • Containers Should Always Wait for Contents Items.WaitForContents(container,timeint) should always be used when opening a container with a script before having it look through the contents to ensure that razor enhanced can go through every item.
  • Connected Player.Connected is the best to use with using a while instead of true. using 'while True:" will result in the script running as long as razor enhanced is loaded. 'while Player.Connected:" will only run when the player is connected and stop if logged out.

Indent

An Indent is a very important part of Python. Indents can be made by hitting the Tab key or space bar to create 4 empty spaces. Using Indents are required to add actions or responses to use when a query/condition is met.


EXAMPLE:

If Player.Hits < 20:
    Player.ChatSay("Health is low!")
    Misc.Pause(3500)  
Misc.Pause(50)
Misc.SendMessage("No Longer inside Query")
‎

With this above example, we can see that when the query of if your player has less than 20 hitpoints, it will say 'Health is low!" and then pause for 3.5 seconds. It will then exit after as there are no more direct lines beneath that are in the same indent. This will result in a pause of 50ms and the send message "No Longer inside Query" to go if your hitpoints are 20 or over, or it will go after the above condition (If Player.Hits < 20) actions are finished.


Having actions for a query/condition met inside the first would require a new indent to be placed.


EXAMPLE:

If Player.Hits < 20:
    Player.ChatSay("Health is low!")
    Misc.Pause(3500)
    If Player.Stam > 200:
        Player.ChatSay("But our stamina is over 200!")
        Misc.Pause(2500)
Misc.Pause(50)
Misc.SendMessage("No Longer inside Query")
‎

With this code, we added a check to see when our hits are under 20 if our stamina is over 200. This query/condition when met will result in it having the player say "But our stamina is over 200!" and then pause for 2500. This query/condition can only be accessed if the first query/condition is met of the player's hit points being under 20.

Functions

A function can be a sample of code to run that is only called upon when needed and will not force razor enhanced to only call it when part of the code requires it.

EXAMPLE:

self = Mobiles.FindBySerial(Player.Serial)

def castHealOnSelf():
    Spells.Cast("Greater Heal")
    Target.WaitForTarget(3500,False)
    Target.TargetExecute(self)
    
while Player.Connected:
    if Player.Hits < 50:
        castHealOnSelf()
    Misc.Pause(650)

BREAKDOWN:

self = Mobiles.FindBySerial(Player.Serial) This code is setting the 'self' variable to be linked to the player and tells Razor Enhanced that the variable is also a mobile so we can call on it later without having to write too much code every time.

def castHealOnSelf(): is the function that can be called at any time in this script by using "castHealOnSelf()". This will run all lines that are indented under it before a line that is not indented appears, which in this case, is 3 lines.

notice the next three lines are indented to tell razor enhanced they will run with the above function

Spells.Cast("Greater Heal") tells the game to cast the spell "Greater Heal".

Target.WaitForTarget(3500,False) is telling the script to not go further until a target appears on screen or 3500ms goes past (3.5 seconds). If the target does not appear it will just continue through as well so setting the wait time can vary on latency or your ISP's (Internet Service Provider's) routing to a server.

Target.TargetExecute(self) is having the spell target yourself with the 'self' variable we set at the top stating it is for your player.

notice the indent has gone away. this means this will happen when the script runs and is not part of the function that was written above it.

while Player.Connected: means that the code will run as long as the player is connected to the game. If they are not this code will stop.

notice the next three lines are indented so they will only run if your player is connected to the game.

if Player.Hits < 50: is a condition that needs to be met to run the following lines again. This one will only run the below code if your hit points go under 50.

notice the double indent below. this means that the function calling below will only happen if this condition above is made.'

castHealOnSelf() is where the script itself is calling the function to heal yourself we set above.

notice that below only one indent here which means it will happen only when the player is connected.

Misc.Pause(650) is set to pause for 650ms either after the healing function runs to heal yourself, or your hits are above 50 and do not go to the function . It is always good to have a pause here when this script will loop of some sort to help your pc from a potential crash from running too fast and having an error occur.


We could also use this same function with parameters if we need to do some specific things when a query/condition is met on a thing.

EXAMPLE:

pausetime = 650 

def DoMove(scont, tcont):
    Items.UseItem(scont)
    Items.WaitForContents(scont,2500)
    for i in scont.Contains: 
        Items.Move(i,tcont,-1)
        Misc.Pause(pausetime)
    Misc.SendMessage('Done Moving Items', 32)

source = Target.PromptTarget('Select Source Container')
sourcecont = Items.FindBySerial(source)
target = Target.PromptTarget('Select Target Container')
targetcont = Items.FindBySerial(target)
if sourcecont and targetcont:
    DoMove(sourcecont, targetcont)  
Misc.SendMessage('Script End', 32)

BREAKDOWN:

pausetime = 650 is setting a variable to a pause time that we can use for all pauses in this script in case we wanted more than one to save time having to remember changing more than one pause. This would allow you to change all the timers at once with one variable change.

def DoMove(scont, tcont): is a function that has two incoming parameters 'scont' and 'tcont' which you will see later in the script will be sent as Items and since their itemid are stored in RE as Containers it will know they can be accessed as containers.

notice below we have an indent again to make sure that all the lines underneath with this indent or further will only happen when this function is called upon.

Items.UseItem(scont) simulates a double click on an item. so in this case it will open 'scont' with a double click.

Items.WaitForContents(scont,2500) will not continue past until either all the contents are loaded from the server on the 'scont' or 2500ms (2.5 seconds) have passed. This is used to make sure you don't miss an item when having the script look through them.

for i in scont.Contains: This will go through every item inside the 'scont' 1 at a time and do anything indented directly under this tells Razor to do.

notice below an indent here to show that the indent that is now 2 indents wide will all work inside the above "for" statement.

Items.Move(i,tcont,-1) this is telling razor enhanced that the item it is on (i) is to be moved to the 'tcont' container. the -1 represents any amount. (setting amount to 3 on a stackable item would result in moving only 3 of the stack).

Misc.Pause(pausetime) is telling the script to pause before any more actions for the set time at the top of the script with 'pausetime' variable being called.

notice below we went back to only one indent. This means this action will only run after the 'for' statement has finished.

Misc.SendMessage('Done Moving Items', 32) is telling the client to simulate a system message on the left that says "Done Moving Items" with a hue of 32.

notice below that the indents are gone this means these actions will run when you hit play unlike the function above which needs to be called.

source = Target.PromptTarget('Select Source Container') is sending a target to your client to have you target an item that will be your source container. This will return the serial of the container.

sourcecont = Items.FindBySerial(source) is setting the item you selected by the target as an item to Razor Enhanced so it knows it is an item.

target= Target.PromptTarget('Select Target Container') is sending a target to your client to have you target an item that will be your source container. This will return the serial of the container.

targetcont = Items.FindBySerial(target) is setting the item you selected by the target as an item to Razor Enhanced so it knows it is an item.

if sourcecont and targetcont: this is having razor enhanced to make sure both items exist.

notice below the indent here. this is saying that this next line will only happen if razor enhanced determines 'sourcecont' and 'targetcont' both exist.

DoMove(sourcecont, targetcont) this is calling the function of DoMove with two parameters that were needed for the function . It is sending first 'sourcecont' (the source container you targeted) and 'targetcont' (the target container you targeted).

notice below the indent has moved again. this is to let you know we are no longer only doing this if the 'sourcecont' and 'targetcont' exist, it will happen even if they do not.

Misc.SendMessage('Script End', 32) is telling the client to simulate a system message on the left that says "Script End" with a hue of 32. The script will end after this.


But what if we only wanted to move a few items of a specific itemid? We can do so by editing the above example below.

EXAMPLE:

pausetime = 650 

def DoMove(scont, tcont):
    Items.UseItem(scont)
    Items.WaitForContents(scont,2500)
    for i in scont.Contains:
        if i.ItemID == 0x0DF0:
            Items.Move(i,tcont,-1)
            Misc.Pause(pausetime)
        elif i.ItemID == 0x410A:
            Items.Move(i,tcont,-1)
            Misc.Pause(pausetime)
    Misc.SendMessage('Done Moving Items', 32)

source = Target.PromptTarget('Select Source Container')
sourcecont = Items.FindBySerial(source)
target = Target.PromptTarget('Select Target Container')
targetcont = Items.FindBySerial(target)
if sourcecont and targetcont:
    DoMove(sourcecont, targetcont)  
Misc.SendMessage('Script End', 32)

BREAKDOWN:

This code is essentially the same with a few changes put in that we will discuss here. inside the function DoMove(scont, tcont) we can see a few lines added in extra.

if i.ItemID == 0x0DF0: will check if the itemid of each item matches this itemid.

Items.Move(i,tcont,-1) this is telling razor enhanced that the item it is on (i) is to be moved to the 'tcont' container. the -1 represents any amount. (setting amount to 3 on a stackable item would result in moving only 3 of the stack).

Misc.Pause(pausetime) is telling the script to pause before any more actions for the set time at the top of the script with 'pausetime' variable being called.

elif i.ItemID == 0x410A: will check if the itemid of each item matches this itemid. We used elif so it does not try to move an item twice if say one condition was if the itemid was a certain id and the other was checking for the hue.


These were the only lines added to check on this setting for itemids. You could do the same to check for hue with i.Hue instead of i.ItemID.

Lists

Filter Lists

Arrays

Arrays can be a good way to store multiple ids to a variable to call on to use for lots of different purposes.


Say we wanted to use an array to store ItemIDs for items that we can move using code we used from the functions section. Here is an example below.

EXAMPLE:

itemids = [0x0DF0, 0x410A]

pausetime = 650 

def DoMove(scont, tcont):
    Items.UseItem(scont)
    Items.WaitForContents(scont,2500)
    for i in scont.Contains:
        if i.ItemID in itemids:
            Items.Move(i,tcont,-1)
            Misc.Pause(pausetime)
    Misc.SendMessage('Done Moving Items', 32)

source = Target.PromptTarget('Select Source Container')
sourcecont = Items.FindBySerial(source)
target = Target.PromptTarget('Select Target Container')
targetcont = Items.FindBySerial(target)
if sourcecont and targetcont:
    DoMove(sourcecont, targetcont)  
Misc.SendMessage('Script End', 32)
‎


BREAKDOWN:

We will breakdown a few of the new settings that are shown here to use an array to find an item specific to the itemid.

itemids = [0x0DF0, 0x410A] is a built array holding two ItemIDs. You could add more by adding a comma and a new ItemID.


if i.ItemID in itemids: Is where checking to see if the ItemID is in the array that we set at the top.

By using this change we can add more items that we could move faster and have editing to add remove more items easier.


It is possible you want your chest to be organized nice and neat. You can use an array to help with this! Below I will give an example of using an array to move items from one container to another by ItemID to a specific location in the container (so they are stacked ontop of each other looking like the 1 item instead of cluttered all over).

EXAMPLE:

itemidswloc = [[0x0DF0, 88, 264], [0x410A, 49, 138]]

pausetime = 650 

def DoMove(scont, tcont):
    Items.UseItem(scont)
    Items.WaitForContents(scont,2500)
    for i in scont.Contains:
        for id in itemidswloc:
            if i.ItemID == id[0]:
                Items.Move(i, tcont, -1, id[1], id[2])
                Misc.Pause(pausetime)
    Misc.SendMessage('Done Moving Items', 32)

source = Target.PromptTarget('Select Source Container')
sourcecont = Items.FindBySerial(source)
target = Target.PromptTarget('Select Target Container')
targetcont = Items.FindBySerial(target)
if sourcecont and targetcont:
    DoMove(sourcecont, targetcont)  
Misc.SendMessage('Script End', 32)
‎

BREAKDOWN:

So let's go through the changes made to achieve this.

itemidswloc = [[0x0DF0, 88, 264], [0x410A, 49, 138]] This array has been changed. Instead of one Array this becomes essentially an array stored inside an array. The first thing stored in this array is the ItemID, and next are the X and Y location values inside a chest (when an item is in a container and you inspect it the x and y shown are the x y inside the container).

for id in itemidswloc: Here we have gone so it will cycle one by one each item in the array at the top and let us compare the item with the values inside the array.

if i.ItemID == id[0]: This is stating if the ItemID matches the ItemID in the array (id[0] would mean the first spot in the array where the ItemID always is).

Items.Move(i, tcont, -1, id[1], id[2]) Now we are moving the if it was correct to the container but telling the server what location inside the container to drop it in (id[1] represents the 2nd parameter inside the array and id[2] represents the third and final one inside the array).

Using this should explain how using arrays in different ways can be useful.

Import

Gumps

Looping