Author Topic: READ_BYTE/SHORT/LONG WeiDU features - by Japheth  (Read 5486 times)

Offline Ghreyfain

  • Moderator
  • Planewalker
  • *****
  • Posts: 4705
  • Gender: Male
    • Pocket Plane Group
READ_BYTE/SHORT/LONG WeiDU features - by Japheth
« on: April 01, 2004, 03:44:47 AM »
READ_BYTE/SHORT/LONG 

READ_BYTE, READ_SHORT and READ_LONG can be potentially powerful functions when used in conjunction with IF_EVAL.

Here's a brief demonstration.

The scenario: I want to make all longswords in the game do 1D6 damage, rather than their normal 1D8. To do that manually would be a pain, so why not use the great feature of READ_BYTE/LONG/SHORT?

Here's how it's done.

First of all, we need to copy all the items so they are ready to be patched. Here's how we do that:

COPY_EXISTING_REGEXP ~.*\.itm~ ~override~

All this does is copy all files with a .itm extension to the override folder.

Next, we read the item category offset into a variable. We'll use the variable name "type".

READ_BYTE "0x1c" "type"

I found the offset by looking at an item file in Near Infinity. The variable
"type" can really be anything, it's just what I've chosen.

Now that we're done reading that into a variable, we can now WRITE_SHORT the values we want to give our new longswords. Namely, 6 for damage and 1 for dice size. (Or, 1D6 for simplicity sake.)

WRITE_SHORT 0x88 6
WRITE_SHORT 0x8a 1

0x88 is the offset for dicesize and 0x8a is the offset for # of dice. Again, I
found these offsets using Near Infinity beforehand.

Finally, we tell WeiDU that we only want to do this if the item file is infact a
longsword.

IF_EVAL ("%type%" = "0x14")

So, to call back our variable, you just wrap it with % signs. 0x14 is just the
value for longsword. If you look at the Category offset in Near Infinity (which is 0x1c), and scroll down in the box below, you'll see Longsword (20).
The 20 just represents the decimal value. 0x14 is just 20 in hexadecimal.

So, to loop through the logic again, this is what we're saying:

If the category is longsword, make the dice size 6 and the dice damage 1. If it's not a longsword, ignore it and don't copy it over.

And that's it. Now all items with the category Longsword will have 1D6 as their dice damage. Pretty neat eh? Obviously you can do many, many other types of thing with these functions. So go ahead and experiment!

Here's the full code:

COPY_EXISTING_REGEXP ~.*\.itm~ ~override~
READ_BYTE "0x1c" "type"

WRITE_SHORT 0x88 6
WRITE_SHORT 0x8a 1

IF_EVAL ("%type%" = "0x14")

Oh yeah, and if you're going "But I don't know when to READ_SHORT or WRITE_LONG! It's so damn confusing!", don't worry, cause it kind of is. Here's a very brief synopsis.

Use READ/WRITE_SHORT for anything that is two bytes. You can determine this easily by looking at the field you want to change in NI and subtrating the next listed field's offset from the offset of the field you want to change.

For example, if I wanted to change Bodhi's Max HP here's what I would do. First look at her creature file in NI. (She has many, but for the sake of argument, we'll use bodhi.cre). If you look at the Max HP field, it says it's offset is 26h. The next field in the creature file is Animation ID, which is 28h. So, subtracting 28h from 26h gives you 2h. The perfect WRITE_SHORT size.

Use READ/WRITE_LONG for anything that is 4 bytes. Use the above example to figure this out as well.

Use READ/WRITE_BYTE for anything that is one byte. Again, use the above example to figure this out.

Use WRITE_ASCII for things like death variable, dialogues, scripts, etc. Note, that if you're WRITE_ASCIIing to say, the death variable, and the previous death variable entry is longer than the one you're writing, then you'll have spillover after WRITE_ASCIIing. To avoid this, embed a null character at the end of your string.

So, if I have WRITE_ASCII 0x280 ~Guy~, I would want to put a null character right after the y in Guy. You can do this by using a hex editor and inserting 00 after the y.

These are by no means "hard and fast" rules, but generally they ring true. However, there could be times when you need to WRITE_LONG twice if the field is 8 bytes long, etc.

And that, as they say, is that.
Earn Money Sleeping.

Offline Fyorl

  • Planewalker
  • *****
  • Posts: 28
Re: READ_BYTE/SHORT/LONG WeiDU features - by Japheth
« Reply #1 on: May 23, 2006, 12:43:33 PM »
erm I'm still confused, you read a byte into a variable and then you write two shorts but they don't seem to go anywhere. Where are you writing the shorts to?

Offline Grim Squeaker

  • Fallen
  • Planewalker
  • *****
  • Posts: 1019
  • Gender: Male
Re: READ_BYTE/SHORT/LONG WeiDU features - by Japheth
« Reply #2 on: May 23, 2006, 04:17:58 PM »
erm I'm still confused, you read a byte into a variable and then you write two shorts but they don't seem to go anywhere. Where are you writing the shorts to?

One this quite an old tutorial.  There are much more recent examples.  In answer to your question:

Code: [Select]
COPY_EXISTING_REGEXP ~.*\.itm~ ~override~
    READ_BYTE "0x1c" "type"
    WRITE_SHORT 0x88 6
    WRITE_SHORT 0x8a 1
    IF_EVAL ("%type%" = "0x14")

Well you're reading from the 0x1c'th byte in the file (28th in decimal) and store that as the variable called 'type'.  Then you're writing to two positions in the file starting at the 0x88'th and 0x8a'th bytes in the file (thats 136th and 138th in decimal).

"You alone can make my song take flight..."

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: