Advertiser Content
Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
I found this Script on Relic Castle by Michael "Link". It's supposed to make Pokemon have their hidden abilities like their regular abilities naturally, whether when encountering Pokemon in the wild or when you're gifted a Pokemon or if you're fighting a trainer his/her Pokemon can have a hidden ability if the Pokemon is randomly generated, just like in Pokemon Reborn.
I added the script to my game but the problem is the only abilities the Pokemon gets are the first regular ability or the first hidden ability defined in the PBS. Let's say I add a bunch of abilities to Archen the PBS lines look like this:

Abilities=DEFEATIST,RUNAWAY
HiddenAbility=EARLYBIRD,KEENEYE,SANDRUSH

Every Archen I get have either Defeatist or Early Bird as an ability, it ignores Run Away, Keen Eye and Sand Rush. I tried with over 50 Pokemon with the same results. I have many Fakemon with more than one hidden ability. Some have 6 abilities in total with 2 regular ones and 4 HAs which is the maximum in essentials.
I don't know how to fix the script to work as intended, I replied on the Relic Castle thread but got no response unfortunately.
I also found out that debug mode doesn't list all the Pokemon abilities when using this script like this:


When it should display this:

Can someone help me?
Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
I'm sorry but I'm still a beginner when it comes to scripting, can you explain a bit more in details. I can find my way when messing with abilities and battle related scripts but when it comes to how Ruby gets info from the PBS files and how it uses it I'm completely clueless. For example I have no idea what
dexdata=pbOpenDexData or dexdata.fgetb means. Sorry for asking too much.

mgriffin

Online now
Posted 1 Hour Ago
795 posts
5.6 Years
So Essentials gets data from the PBS in two steps:
1. It takes the PBS file and turns it into a big ol' series of bytes. This happens in the compiler.
2. It takes the compiled bytes, and extracts values from them. This is what pbOpenDexData and fgetb do respectively (specifically fgetb extracts one byte—i.e. a value from 0 to 255, there are other fgetX functions that extract different ranges of values by reading more than just one byte).

It's important to note that once things are compiled into bytes Essentials just uses logic like "the ability bytes are from X to Y", so it's very important that the Xs and Ys are the same in every place in the code they appear. e.g. if your compiler doesn't write the hidden ability bytes to the file, or writes bytes for different data at those locations you'd get some very weird behavior.

But to start with I think you should simply print out what all those values are, so that you can simulate the path that's taken through the code in your head. You can do that with something like
p "abil=#{abil}, h1234=#{h1}, #{h2}, #{h3}, #{h4}"
Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
Alright so I printed the values of abil and h1, h2, h3 and h4 here's what I got, I'll refer to regular ability as RA and hidden as HA:
Spoiler:

Bulbasaur have 1 RA and 1 HA, it got its RA and the result is this:
abil=4, h1234=34, 0, 0, 0
Archen have 2 RA and 3 HA, it got the first defined HA in the PBS file. The result is
abil=2, h1234=48, 0, 51, 0
Fakemon #1 have 2 RA and 1 HA, it got the first defined RA in the PBS file. The result is
abil=1, h1234=128, 0, 0, 0
Fakemon #2 have 2 RA and 3 HA, it got the first defined RA in the PBS file. The result is
abil=5, h1234=154, 0, 107, 0
Fakemon #3 have 2 RA and 4 HA, it got the first defined HA in the PBS file. The result is
abil=2, h1234=56, 0, 107, 0
Fakemon #4 have 2 RA and 2 HA, it got the second defined HA in the PBS file. The result is
abil=4, h1234=148, 0, 151, 0

I'm assuming h1, h2, h3, and h4 are the hidden abilities values and as you can see h2 and h4 are always 0 so I think they're not getting the correct data from the PBS files. How can I change their values since all of them have the same expression
hX=dexdata.fgetb
do I have to change number 40 in this line?
pbDexDataOffset(dexdata,@species,40)
Same thing for ret1 and ret2 I'm also assuming they contain the values of both RA, the first ability have no problems but the second never shows up. I'm guessing I have to change this
pbDexDataOffset(dexdata,@species,2)
Last thing is I don't know how Fakemon #4 got its second HA I tried receiving it again multiple times but I only got either the first RA or first HA. The second HA shows up when I'm using debug to see the abilities list so its values is being imported from the PBS.
You should know that I'm still using %6 instead of %3 in
abil=@abilityflag!=nil ? @abilityflag: (@personalID%3)
Update: I changed every dexdata.fgetb with dexdata.fgetw and it seems to be working so far.

mgriffin

Online now
Posted 1 Hour Ago
795 posts
5.6 Years
Update: I changed every dexdata.fgetb with dexdata.fgetw and it seems to be working so far.
Glad you sorted it out! If you wanted to confirm that you did the right thing you could try checking the compiler to see that it writes two bytes for each ability. I think there's a section for each PBS file, and at the top of each section is a data structure that describes the layout of the bytes. But it's probably unnecessary if you've tested with all four hidden abilities and nothing has broken :)
Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
I don't know how to check the compiler, but I can confirm that all the abilities work. When I use the debug mode to modify a Pokemon I can give it any ability and all of them work. And any Pokemon I get can have any ability assigned to it. Also h2 and h4 aren't 0 anymore, so it should be working fine. Again thanks a lot for all your help I really appreciate it.

mgriffin

Online now
Posted 1 Hour Ago
795 posts
5.6 Years
In case you're curious as to why it was h2 and h4, that's because of endianness. Basically if you write a two-byte number that could fit in one byte, the first byte will contain that number, and the second contains a zero.

Also, it would be great if you could consider posting your fixed version of the resource here (giving credit and linking to the original author and post over on RC).
Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
In case you're curious as to why it was h2 and h4, that's because of endianness. Basically if you write a two-byte number that could fit in one byte, the first byte will contain that number, and the second contains a zero.
I see, thanks about that I still have a long way to completely understand how everything works in Essentials.

Also, it would be great if you could consider posting your fixed version of the resource here (giving credit and linking to the original author and post over on RC).
Sure thing here is the code:
################################################################################
# Ability
################################################################################
# Returns the index of this Pokémon's ability.
  def abilityIndex
    abil=@abilityflag!=nil ? @abilityflag : (@personalID%6)
    return abil
  end

# Returns the ID of this Pokemon's ability.
  def ability
    abil=abilityIndex
    dexdata=pbOpenDexData
      pbDexDataOffset(dexdata,@species,2)
      ret1=dexdata.fgetw
      ret2=dexdata.fgetw
      pbDexDataOffset(dexdata,@species,40)
      h1=dexdata.fgetw
      h2=dexdata.fgetw
      h3=dexdata.fgetw
      h4=dexdata.fgetw
    dexdata.close
    ret=ret1
    if abil==2
      return h1 if h1>0
      abil=(@personalID&1)
    elsif abil==3
      return h2 if h2>0
      abil=(@personalID&1)
    elsif abil==4
      return h3 if h3>0
      abil=(@personalID&1)
    elsif abil==5
      return h4 if h4>0
      abil=(@personalID&1)
    end
    if abil==1
      ret=ret2
      ret=ret1 if ret2==0
    end
    return ret
  end

 # Returns whether this Pokémon has a particular ability.
  def hasAbility?(value=0)
    if value==0
      return self.ability>0
    else
      if value.is_a?(String) || value.is_a?(Symbol)
        value=getID(PBAbilities,value)
      end
      return self.ability==value
    end
    return false
  end
  
# Sets this Pokémon's ability to a particular ability (if possible).
  def setAbility(value)
    @abilityflag=value
  end

  def hasHiddenAbility?
    abil=abilityIndex
    return abil!=nil && abil>=2
  end

# Returns the list of abilities this Pokémon can have.
  def getAbilityList
    abils=[]; ret=[[],[]]
    dexdata=pbOpenDexData
    pbDexDataOffset(dexdata,@species,2)
    abils.push(dexdata.fgetw)
    abils.push(dexdata.fgetw)
    pbDexDataOffset(dexdata,@species,40)
    abils.push(dexdata.fgetw)
    abils.push(dexdata.fgetw)
    abils.push(dexdata.fgetw)
    abils.push(dexdata.fgetw)
    dexdata.close
    for i in 0...abils.length
      next if !abils[i] || abils[i]<=0
      ret[0].push(abils[i]); ret[1].push(i)
    end
    return ret
  end
As for the second block of code it should be the same as indicated the RC post you'll also find the installation steps there just change the first block of code with this one . All the credits goes to Michael from Relic Castle and Marcello (Reborn team).

Maruno

Lead Dev of Pokémon Essentials

England
Seen 3 Days Ago
Posted 3 Days Ago
5,199 posts
11.9 Years
The trouble with scripts like this is that they take a blunderbuss approach to installation. "Replace all this code with mine" despite it being unnecessary to replace most of these methods and it actually removing def hasAbility? in the process. Also, it was made in an older version of Essentials and then just not updated (as you can tell by its use of fgetb which Essentials stopped using for abilities in v16, and by the method I just mentioned being omitted).

  def abilityIndex
    abil=@abilityflag!=nil ? @abilityflag : (@personalID&6)
    return abil
  end
That's all you needed to change. Just that one digit. You don't need to change the debug code at all. Although, to be fair, that makes each hidden ability have 1/6 chance of appearing, and the chances of any unused hidden ability slots is distributed to the two regular abilities (so if you has one hidden ability, it would have 1/6 chance and each of the two regular abilities would have 5/12 chance each so they're not all equally probable). You could fill in hidden ability slots with copies of an ability to alter these probabilities, I guess.

I am of course assuming you're using the latest version of Essentials.
Go to the Essentials Docs Wiki

Essentials Docs Wiki

Follow me on Twitter: @maruno42


Male
Seen 2 Hours Ago
Posted 5 Days Ago
23 posts
5.2 Years
Yes, I'm using the latest Essentials. I had to check a clean copy of Essentials that's where I saw fgetw because that seems the only thing that's changed. The thing is I was checking Reborn script and it was almost identical to the script posted by Michael except it used dexdata,@species,29 instead of dexdata,@species,2 and when I changed %3 to %6 in Reborn it worked but not in my game that's what confused me the most and led me to think that I had to change dexdata,@species,2. But Reborn probably uses an older version of Essentials that's why it had fgetb. I admit that didn't understand the script fully but I tried to look at it logically like why is this different than that etc... so I was changing small details left and right until I changed fgetb and it finally worked.
Also thanks for explaining the abilities probabilities, I'll use your suggestion for filling empty slots.
I also added hasAbility? in the script I posted, thanks for pointing it out.
Advertiser Content