• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[Script✓] Unable to access gAbilityNames in field_specials.c

118
Posts
4
Years
I'm trying to make a basic ability tutor which gets all of a Pokémon's abilities and lets you pick between them. This script is a MVP of just trying to load an ability name into a variable. It should speak for itself. I spoke to a friend and even he couldn't help, so I thought I would ask here. If anyone has any ideas, let me know. Thanks!

11cda8834bfbaa867bafe4123e613954.png
 
Last edited:
434
Posts
6
Years
  • Age 37
  • Seen Apr 13, 2024
gAbilityNames[ability] is a constant u8 array, you shouldn't convert that to u8.

You should instead do something like:
Code:
const u8* dummy;
dummy = gAbilityNames[ability];
 
118
Posts
4
Years
gAbilityNames[ability] is a constant u8 array, you shouldn't convert that to u8.

You should instead do something like:
Code:
const u8* dummy;
dummy = gAbilityNames[ability];

Awesome, it compiled! I know enough about programming to muck around in the source code, but I still don't know the ins and outs of C. However, I think that my real issue is bigger than this. All I want to do is get the names of a given Pokemon's possible abilities. Then, I want to assign those names to gstringvars so that I can load them into a script menu. Is there a way to just get a string value from gAbilityNames without dealing with pointers? Sorry for being a newbie; I'm not used to working with C at all.

EDIT:
Code:
void swapAbility(void){
	u8 species=SPECIES_BULBASAUR;
	u16 ability0 = gBaseStats[species].abilities[0];
	u16 ability1 = gBaseStats[species].abilities[1];
	u16 ability2 = gBaseStats[species].abilities[2];
	const u8* dummy;
	dummy=gAbilityNames[ability0];
	StringCopy(gStringVar1, dummy);
	StringCopy(gStringVar2, dummy);
	StringCopy(gStringVar3, dummy);
}
I basically want to do this, but the strings always come up blank.
EDIT 2: Even putting in a string that I know exists doesn't work. I have multiple problems, it seems haha.
EDIT 3: Got it working. Just put the stringvars in the array of text options instead of a text option containing the stringvar. Thanks!
 
Last edited:
853
Posts
3
Years
  • Age 33
  • Seen Nov 9, 2023
EDIT:
Code:
void swapAbility(void){
	u8 species=SPECIES_BULBASAUR;
	u16 ability0 = gBaseStats[species].abilities[0];
	u16 ability1 = gBaseStats[species].abilities[1];
	u16 ability2 = gBaseStats[species].abilities[2];
	const u8* dummy;
	dummy=gAbilityNames[ability0];
	StringCopy(gStringVar1, dummy);
	StringCopy(gStringVar2, dummy);
	StringCopy(gStringVar3, dummy);
}
I basically want to do this, but the strings always come up blank.
EDIT 2: Even putting in a string that I know exists doesn't work. I have multiple problems, it seems haha.
EDIT 3: Got it working. Just put the stringvars in the array of text options instead of a text option containing the stringvar. Thanks!

So is what you have quoted above your original code, or the code that worked?
 
118
Posts
4
Years
So is what you have quoted above your original code, or the code that worked?
It's almost the code that worked, just a little tweaked. Here is the full thing:
Code:
void swapAbility(void){
	u8 species=GetMonData(&gPlayerParty[gSpecialVar_0x800B], MON_DATA_SPECIES);
	u16 ability0 = gBaseStats[species].abilities[0];
	u16 ability1 = gBaseStats[species].abilities[1];
	u16 ability2 = gBaseStats[species].abilities[2];
	const u8* dummy0;
	const u8* dummy1;
	const u8* dummy2;
	dummy0=gAbilityNames[ability0];
	dummy1=gAbilityNames[ability1];
	dummy2=gAbilityNames[ability2];
	StringCopy(gStringVar1, dummy0);
	StringCopy(gStringVar2, dummy1);
	StringCopy(gStringVar3, dummy2);
}

Then, you can just make a selection box where each option is gStringVar1, gStringVar2, and gStringVar3.
 
Last edited:
853
Posts
3
Years
  • Age 33
  • Seen Nov 9, 2023

Cool, and many thanks I'm just getting into decomp myself and this is something I could probably use this too.
I can kind of read this so I get why you start from 0, because most computer things count places starting from 0,
so you're pulling 3 abilities, Im guessing because pokemon have a max 2 abilities and one hidden ability.

What happens when they only have two options, does it still work just fine? ex. gorebyss has 1 ability and 1 hidden ability.

and would you mind explaining what the "dummy" part is for?
 
118
Posts
4
Years
Cool, and many thanks I'm just getting into decomp myself and this is something I could probably use this too.
I can kind of read this so I get why you start from 0, because most computer things count places starting from 0,
so you're pulling 3 abilities, Im guessing because pokemon have a max 2 abilities and one hidden ability.

What happens when they only have two options, does it still work just fine? ex. gorebyss has 1 ability and 1 hidden ability.

and would you mind explaining what the "dummy" part is for?

No problem. In the game, a Pokemon's two normal abilities count as ability "0" and ability "1". The battle engine upgrade adds hidden abilities at ability "2". Keep in mind that this script only gets the names of abilities.

When a Pokemon doesn't have an ability, it returns "-----".

Dummy is just a random name. The variable names don't matter. The important part is that they are copied into the correct string variables which I use later.

I can post the full script if you want, but I'm also about to update my hack with this script in it and I'll include the source code so you can check it out there, too.
 
853
Posts
3
Years
  • Age 33
  • Seen Nov 9, 2023
I can post the full script if you want, but I'm also about to update my hack with this script in it and I'll include the source code so you can check it out there, too.

Cool I'd like an update, I'm assuming you're talking git, so just send me a link and I'll check it out.

Thanks.


sorry took so long to respond, doing a lot of research on all this stuff so I kinda get lost some times.
 
118
Posts
4
Years
Cool I'd like an update, I'm assuming you're talking git, so just send me a link and I'll check it out.

Thanks.


sorry took so long to respond, doing a lot of research on all this stuff so I kinda get lost some times.

Nope, I'm not using Git (Even though I should be).
First, here's the ability switcher map event:
Code:
BattleFrontier_Lounge6_EventScript_Trader::
	lock
	faceplayer
	msgbox BattleFrontier_Lounge6_Text_WouldYouLikeToTrade, MSGBOX_YESNO
	compare VAR_RESULT, NO
	goto_if_eq BattleFrontier_Lounge6_EventScript_DeclineTrade
	msgbox BattleFrontier_Lounge6_Text_PromiseIllBeGoodToIt, MSGBOX_DEFAULT
	special ChoosePartyMon
	waitstate
	copyvar VAR_0x800B, VAR_0x8004
	compare VAR_0x8004, 255
	goto_if_ne BattleFrontier_Lounge6_EventScript_AbilitySwitch
	goto BattleFrontier_Lounge6_EventScript_DeclineTrade
	end 

BattleFrontier_Lounge6_EventScript_AbilitySwitch::
	specialvar VAR_RESULT, ScriptGetPartyMonSpecies
	compare VAR_RESULT, SPECIES_EGG
	goto_if_eq BattleFrontier_Lounge6_Text_WellThatsFineToo
	special swapAbility
	scrollingmultichoice 14, 2, 3, 3, FALSE
	special swapAbility2
	msgbox BattleFrontier_Lounge6_Text_DontTradeForAnythingButMon, MSGBOX_DEFAULT
	release
	end
Here is the field_specials.c code:
Code:
void swapAbility(void){
	u16 species=GetMonData(&gPlayerParty[gSpecialVar_0x800B], MON_DATA_SPECIES);
	u16 ability0 = gBaseStats[species].abilities[0];
	u16 ability1 = gBaseStats[species].abilities[1];
	u16 ability2 = gBaseStats[species].abilities[2];
	const u8* dummy0;
	const u8* dummy1;
	const u8* dummy2;
	dummy0=gAbilityNames[ability0];
	dummy1=gAbilityNames[ability1];
	dummy2=gAbilityNames[ability2];
	StringCopy(gStringVar1, dummy0);
	StringCopy(gStringVar2, dummy1);
	StringCopy(gStringVar3, dummy2);
}
void swapAbility2(void){
	SetMonData(&gPlayerParty[gSpecialVar_0x800B], MON_DATA_ABILITY_NUM, &gSpecialVar_Result);
}
and I used Ghoulslash's custom selection box with three entries:
Code:
static const struct ListMenuItem sSet15[] =
{
    {gStringVar1, 0},
	{gStringVar2, 1},
	{gStringVar3, 2},
};
That's all there is to it. DM me if you have any questions.
 
Last edited:
118
Posts
4
Years
Thanks, I'll probably do so, but it'll probably be a while, I'll have to look more into disassebly first.
But I really appreciate the help on this.

Just a head's up, I found out the display doesn't work correctly with Pokemon not in Gens I-III. I'll try to come up with a fix, but for now, keep in mind that this code isn't 100% working.
EDIT: It was because Species was saved as an 8-bit integer, which meant that any Pokémon with an ID of over 256 would have their species number overflow back to 0. Code above has been edited accordingly.
 
Last edited:
853
Posts
3
Years
  • Age 33
  • Seen Nov 9, 2023
Nice job!

Thanks, I set it on blaze so I could test it at game start. but it works and I'm gonna do some craazy stuff with shedinja, now that I've got that working. :) I'm still a noob so I'll need a lot more research before I can tackle my next task but thank-you.

I'm just so happy that I can do decomp even a little bit now, finishing my main hack feels possible again now. I might make a secondary hack based on this function change if I have time though, now that I'm thinking about it. I'll have to do some tests.
 
Back
Top