Jump to content

Recommended Posts

Posted (edited)

As I said in my intro, I learned VB Express in school, and did really well. I decided to try to make a pokemon program. Anyways, I got up to displaying the OT, but I'm lost now. I know where the OT is in regards to the offset, but I'm stumped how I would convert it.

For one, I have no clue what it converts to, maybe Unicode or ASCII.

So if someone could help me with that, I'd be grateful.

Edited by greentea
  • Replies 89
  • Created
  • Last Reply

Top Posters In This Topic

Posted

It depends on how it's stored.

If it is Unicode or ASCII, then it would appear as a string in a HEX Editor\

If it is an integer, then it would probebly be two bytes long, needing to be converted with something like this:

   'Converts an array of Byte with a length of 2 into an integer
   Function ByteArToInt(ByVal input As Byte()) As Integer
       Dim returnval As Integer = (input(1) * 256) + input(0)
       Return returnval
   End Function
   'Converts an Integer into a byte array with a length of 2 
   Function ConvertIntToByteAr(ByVal input As Integer) As Byte()
       Dim s1 As Byte = (input / 256)
       Dim s2 As Byte = (input Mod 256)
       Dim returnval As Byte() = {s2, s1} 'Because of the needs I had when I wrote this, s1 and s2 were reversed.  If this failes, make it {s1, s2}
       Return returnval
   End Function

First you will need to know how it is stored.

Also, this might go in the Save R&D forum.

Posted

Thanks for moving it, I wasn't sure if it was in save or not since it only has to do with a pkm not a sav.

Well, you obviously converted it in your program, so you figured out just exactly how to convert and display the OT.

I know how to convert the information somewhat, I've been converting it to decimal a few times already. But what if I convert to Unicode? Will it display the OT or what? Exactly how your program displays the OT (except mine is still in a console form like legal.exe since it's easier to program), I want to display mine.

I need to know if it converts properly to Unicode or something. I assume it's not ASCII cause we've got Korean and Japanese to deal with. Like, what values convert to what letters, stuff like that.

Posted

You know, it would help tremendously if you were more specific in the future. I must have totally misread yours and evandixon's posts, but nevertheless I kept seeing "OT" as the trainer ID number, rather than the name. Also, you didn't mention that it was a PKM file specific program (although I think it still fits into save R&D).

But anyway.

Pokémon DS games have their own character table. I have been using a table to convert the DS character codes to their Unicode equivalent values.

And here is that table (courtesy of Sabresite).

  Reveal hidden contents
Posted (edited)

Thanks for that list, I'll check it out.

I got it sorted out and understand it now, thanks a lot for that table, it really helps. What is the best way to do this is what I need to figure out. If I can find a text file with Unicode values and the corresponding character, that would work, I may go look for it. If not, I think I'll have to manually input the character in.

Oh, and sorry for not being specific. I normally am fairly specific with this stuff. I had to go to dinner like ASAP though.

Edited by greentea
Posted
  Reveal hidden contents

Posted (edited)

What a champ Jiggy. And same for Monkey. You guys rock. Next is the PID, but you guys have a page on that, I think I can try to understand that.

You know if Visual Basic Express supports this? I'm hearing it doesn't support Unicode.

Nevermind, I can't do it in console version, but I can in form apparently.

I just wanted to thank you guys again for your help. My program can now read in that information and display the OT for any pokemon correctly. It took me a while to do, had to change from console to form, had to figure out a browse button, how to display it on form, etc., but at last, it works (I mainly used console in school).

I don't know of what concern this is, but I only really use two pieces from those 4 columns. Just the pkm file hex value and the character. Skip the change value, since I read it in to an array, both indexes are the same.

I have some trouble understanding the PID information in the guide by SCV.

http://projectpokemon.org/editingresearch/guidepidiv.php

I understood the PID part, and I printed the PID. But I can't understand the IV part.

iv1= 0x03F2FDE1 & 0x7FFF;

therefore iv1 = 3B + 3A + 39 + 38

^The values of those offsets

But what is 0x7FFF supposed to be? I guess I am to assume it's a decimal constant 32767?

And then in iv2 ( iv2= (0x03F2FDE1 >>0xF) & 0x7FFF; ), I guess >>0xF is a 16 bitshift rightwards? So I'm going to have to convert iv2 to binary and do a bitshift, then convert back to decimal and add the constant 7FFF?

And in HP or Attack for instance, the and value is again a constant I would assume?

Sorry to bother with something that may not be so confusing, but I am definitely confused. I never learned bitwise operands in programming. We covered AND, OR etc in circuitry, but I still never did a bitshift (though from reading the wiki it sounds easy enough). It's also because it's written in an unfamiliar language to myself (VB.NET does everything a lot different than other languages), and the fact that he used "0x03F2FDE1" as an example from the hex, but other things like "0xF" or "0x7FFF" don't occur in the displayed hex.

Edited by codemonkey85
Figured I'd trim down the thread size by merging four consecutive posts.
Posted

If you are just attempting to read a Pokemon's IVs, that page is not the best to help you, since its topic is about how a Wild Pokemon's IVs and PID are generated and how this can be exploited to discover a relationship between the Pokemon's PID and IVs to detect hacked Pokemon. This page is more useful: http://projectpokemon.org/wiki/Pokemon_NDS_Structure

When using a bit shift, you do not need to convert the number to binary since it is already binary in the computer's memory.

A simple function to get stats could be like this:

( IV>>(s*5) ) & 0x1F

Where s is 0-5 depending on:

0 = HP

1 = Att

2 = Def

3 = Spe

4 = SpA

5 = SpD

Posted

iv = 3B + 3A + 39 + 38 'like I described, using the string format method below

'these are to be used for the s value

HP = 0

Attack = 1

Defense = 2

Speed = 3

Special_Attack = 4

Special_Defense = 5

1F = String.Format("{0,2:X2}", data(31)) 'this would be the hex value of the hex offset 1F

(IV >> (s*5)) & 1F

So that is basically what I should use? Just double checking, I'm not going to be working on it in the next few hours anyways, so I might as well.

The program I'm making is fairly far into production actually. I have IV, moves, ability, gender, shiny and OT gender left to code (where I already programmed name, OT, SID, ID, FE, country, hometown, PID).

I'm not looking to code something like a relationship, just display the data much like Pokesav does. I might do a couple of things with the data once it's all displayed, but displaying it is what I need for now.

Posted

"Bits 0-29 - Individual Values

HP ( [0-31] << 0 )

Attack ( [0-31] << 5 )

Defense ( [0-31] << 10 )

Speed ( [0-31] << 15 )

SP Attack ( [0-31] << 20 )

SP Defense ( [0-31] << 25 )

Bit 30 - IsEgg Flag

Bit 31 - IsNicknamed Flag "

From the wiki article, this is how IVs are stored in a Pokemon.

Each IV is exactly 5 bits. The list above shows how far that value is shifted up from the bottom. In order to access that IV data, you need to shift it back down the same number of bits. That's where the >>(s*5) comes in.

You also need to get rid of any bits that aren't part of the IV you are looking at. That's what & 0x1F does.

& represents a bitwise AND operation. Basically, the two numbers being operated on are placed side by side, and each corresponding bit is compared and a new number is generated based on the result of that comparison according to the following table.

1 & 1 = 1

1 & 0 = 0

0 & 1 = 0

0 & 0 = 0

Basically, X & 1 = X, and X & 0 = 0.

0x1F represented in binary is 11111. When the bitwise AND operation is done, the bottom 5 bits of the other number are kept the same, and the rest is changed to 0. That way, you can look at the IV and only the IV.

Posted

Alright, I'll have a good stab at programming it some time today.

In VB.Net, & is used to assign a second item to something, it's almost like another + sign without physically adding them. I have done truth tables before, so I do understand that.

Posted
  greentea said:
In VB.Net, & is used to assign a second item to something, it's almost like another + sign without physically adding them.

That's called "concatenation", FYI. And feel free to post here or contact either Jiggy-Ninja or myself if you have further questions. (I love it when people start programming, it means more help with projects in the future!)

Posted

Oh yea, I'll definitely have a couple more questions. The other VB board I'm getting help on, I think they're starting to get annoyed at me asking questions, but those were all issues with me not knowing how to code it because how much can you learn in one year with a bad class (by bad, I mean stupid, the avg was 68% and I got 100...).

For moves, is there a pattern to them, or do I just have to say "XXXX" is the move Fire Blast for instance? I would have asked the same for ability, but it's just one offset so I could figure that myself.

Dim HP As Integer = 0

Dim Attack As Integer = 1

Dim Defense As Integer = 2

Dim Speed As Integer = 3

Dim Special_Attack As Integer = 4

Dim Special_Defense As Integer = 5

Dim IV As String

Dim Binary As Integer = 31

'sets IV equal to the 4 IV offsets

IV = String.Format("{0,2:X2}", data(41)) + String.Format("{0,2:X2}", data(40)) + String.Format("{0,2:X2}", data(39)) + String.Format("{0,2:X2}", data(38))

'converts IV from hex to integer

Dim value2 As Integer = Integer.Parse(IV, Globalization.NumberStyles.HexNumber)

'in the IV text box, evaluates a rightwards shift of 5, then And 11111

txtIV.AppendText((value2 >> (Attack * 5)) And Binary)

Regardless of whether I convert or not, I do not get the correct number.

Posted

Where mIVsAndEtc is an unsigned 32 bit integer consisting of the values at 0x38-0x3B:

HP = (mIVsAndEtc >> (0)) And &H1F
Attack = (mIVsAndEtc >> (5)) And &H1F
Defense = (mIVsAndEtc >> (10)) And &H1F
Speed = (mIVsAndEtc >> (15)) And &H1F
SpAttack = (mIVsAndEtc >> (20)) And &H1F
SpDefense = (mIVsAndEtc >> (25)) And &H1F

That's basically what my code looks like.

Posted

That's basically what I had, but it doesn't work.

'IV is the hex value of hex offsets 38-3B in little endian

IV = String.Format("{0,2:X2}", data(41)) + String.Format("{0,2:X2}", data(40)) + String.Format("{0,2:X2}", data(39)) + String.Format("{0,2:X2}", data(38))

'value2 is IV converted to integer

Dim value2 As Integer = Integer.Parse(IV, Globalization.NumberStyles.HexNumber)

'exactly what you have, I sometimes use And Binary where Binary is int 31

DEF_IV = ((value2 >> (10)) And &H1F)

When it is in little endian format, I constantly get 0's for any IV. If I do it in big endian, I get wrong answers. This particular file has the IVs: HP = 0, Attack = 6, Defense = 28. When I print the 3 IVs in big endian (as little returns all 0's), I get 0, 8 and 26.

Posted
  greentea said:
'IV is the hex value of hex offsets 38-3B in little endian

IV = String.Format("{0,2:X2}", data(41)) + String.Format("{0,2:X2}", data(40)) + String.Format("{0,2:X2}", data(39)) + String.Format("{0,2:X2}", data(38))

Part of the problem I am seeing is that you are using decimal instead of hexadecimal for your offsets. In VB you use the prefix &H to specify hex instead of decimal; so 38 should actually be &H38, 39 should be &H39, and the next two are actually &H3A and &H3B.

Why are you doing it this way, anyway? How about doing this instead:

IV = BitConverter.ToUInt32(DATA, &H38)

The BitConverter class will automatically put your number together. DATA is your byte array, and &H38 is the starting offset. Easy, right?

Posted (edited)

The offsets are hex. That value does indeed produce a hex. I am using String.Format. X makes the value a hexadecimal.

C0 70 FE 00 is the hex 38-3B for this particular file.

Using the way I wrote it, in little endian.

txtIV.AppendText(IV)

returns "00FE70C0"

NEVERMIND. I got it to work this way. I was using the wrong offsets hahaha.

Now, I've got another couple of questions. Ability and moves, do they follow regular patterns or do I have to just make a chart of them. I'm asking because you had the chart last time, maybe you have more for this =P.

And for gender, nature and shiny, I didn't see any info for it, so I'm kind of in the dark here how to figure it out.

Edited by greentea
Posted

I'm a little stuck on the gender now, and the shiny or not part.

First off, ability and nature were pretty easy. I'll use a text file for the abilities, nature I coded straight in, there's only 25.

With gender, I have a Charizard I was checking. Charizard, according to Serebii, is 87.5% Male (which makes sense). It returned 189 with my code. Since the value is 31, we know it is male, which it is. However, I went and used a Lugia. It returned 166. We know Lugia to be genderless, so the site says it should return 255. Pokesav shows it as genderless.

The code I am using is:

gender = PID mod 256

which is just what the site says "essentially p % 256" which is easier to code than whatever other stuff they were talking about (clearly I didn't get it).

Secondly, we get to shininess. This Lugia I am using, it has a PID that is 9 digits long, so in binary, it is only 27 digits long. These are 32 bit binary numbers, so do I assume the first 5 are 0? Or how else should I go about this. The rest of that code makes sense to me. I know truth tables and all, I understand XOR logic. The code is there and easy enough to do.

Posted

Yes, assume the leading 5 digits are 0.

For Lugia, the 255 is a reference to the gender value that is part of the Pokemon's base stat structure. IE, it's the same as the 31 is for Charizard. It is not what the p % 256 needs to output.

Pokemon with 255 as their base gender value will always be genderless, regardless of what p%256 outputs. Pokemon 254 as the gender value will always be female.

Posted

It is worth asking about this though:

  Quote

Also, if you don't want to do the gender check manually (and if you are not validating the legality or integrity of the Pokémon data all that vigorously), you should see bytes 0x40-0x41.

Posted

It's likely that there's a manual check before or after the PID calculation that checks the Pokemon's

If you think about it, there already has to be a check for 255 to make the Pokemon genderless. It's not that farfetch'd :P to think there's another check for 254, the all female value.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...