McPaul

On my way to become a controversial and hated member.

He/ Him
Switzerland
Seen 1 Week Ago
Posted 2 Weeks Ago
243 posts
2.9 Years
Hello! I have a problem with adding fuctions to items.

Here is an explanation:

If I do this:

const u8 gItemEffect_HondewBerry[10] = {
[4] = ITEM4_EV_SPATK | ITEM4_EV_SPDEF | ITEM4_FRIENDSHIP_ALL,
[5] = 1,
[6] = 1,
[7] = 10,
[8] = 5,
[9] = 2,
};

I get these error messages:

Spoiler:
In file included from src/pokemon.c:1349:
src/data/pokemon/item_effects.h:374: `ITEM4_EV_SPATK' undeclared here (not in a function)
src/data/pokemon/item_effects.h:374: `ITEM4_EV_SPDEF' undeclared here (not in a function)
src/data/pokemon/item_effects.h:374: `ITEM4_FRIENDSHIP_ALL' undeclared here (not in a function)
src/data/pokemon/item_effects.h:374: initializer element for `gItemEffect_HondewBerry[4]' is not constant
src/data/pokemon/item_effects.h:380: initializer element for `gItemEffect_HondewBerry' is not constant
Makefile:252: recipe for target 'build/emerald/src/pokemon.o' failed
make: *** [build/emerald/src/pokemon.o] Error 1


But if I obey what the compilator wants me to do and put [5] = ITEM5_EV_SPATK | ITEM5_EV_SPDEF | ITEM5_FRIENDSHIP_ALL, I must sacrifice a friendship gain line.

What can I do to avoid sacrifices?

McPaul

On my way to become a controversial and hated member.

He/ Him
Switzerland
Seen 1 Week Ago
Posted 2 Weeks Ago
243 posts
2.9 Years
Any item specialist here?

BluRose

blu rass

Age 19
Male
michigan tech
Seen 9 Hours Ago
Posted 5 Days Ago
801 posts
6.8 Years
alright hello let's look at this function really quickly. it's a mess, so buckle up

https://github.com/pret/pokeemerald/blob/master/src/pokemon.c#L4641

we're gonna scroll all the way down to

https://github.com/pret/pokeemerald/blob/master/src/pokemon.c#L4816

this is where the ev's and shtuff are located. the pp and other stuff.
that case 4 is referencing the 4th gItemEffect element.
so the stuff that goes under [4] = ITEM4_... | ITEM4_... are hardcoded constants that the code reads. you can not move the ITEM5 stuff to ITEM4 without rewriting the code. if you did, it would be treated as if it were like a revive or something.

that being said, you don't have to make any sacrifices; every time that something uses a variable amount as specified on some parameter, it uses itemEffect[var_3C], incrementing var_3C after the effect of the vitamin is applied.
var_3C at its instantiation is set to 6.

https://github.com/pret/pokeemerald/blob/master/include/constants/item_effects.h#L52

if you look in the gItemEffect constant definitions, everything element 6 and above is something specified by the item itself. i believe that the vitamins will probably have like 10 there, a potion will have 20, a hyper potion 100, a max potion 0xFF, etc.

so let's actually take a look at the hondew berry right quick:

const u8 gItemEffect_HondewBerry[10] = {
    [5] = ITEM5_EV_SPATK | ITEM5_FRIENDSHIP_ALL,
    [6] = -10,
    [7] = 10,
    [8] = 5,
    [9] = 2,
};
basically, the way you can think of this is that the game will apply everything in the order the code finds it
that doesn't make sense by itself so i'll explain:

the code starts with [0], finds nothing, then moves on to [1]
the code finds nothing in [1], then moves on to [2]
and bam nothing there either
this continues until [5] where it finds ITEM5_EV_SPATK. note that this is the least significant bitfield that it encounters, i.e. ITEM5_EV_SPATK is less than ITEM5_FRIENDSHIP_ALL

so it then takes a look at itemEffect[var_3C]. var_3C is currently 6 (because the code found nothing that required a variable value in [0] through [4]), so it takes a look at itemEffect[6] (-10), and essentially adds that to the current EV value in special attack. there's obviously code for getting the evs down to 100 if the evs are above 100, but that's beside the point
var_3C being used for the first time, it is incremented to 7.

it continues searching through [5], where it hits ITEM5_FRIENDSHIP_ALL, which is really actually ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID | ITEM5_FRIENDSHIP_HIGH.
what this means?

it hits ITEM5_FRIENDSHIP_LOW. it checks if the mon's friendship is low, applies itemEffect[var_3C] if it is, then increments var_3C
i.e. [7] is the value used for ITEM5_FRIENDSHIP_LOW.

this then makes [8] the value used for ITEM5_FRIENDSHIP_MID and then [9] the value used for ITEM5_FRIENDSHIP_HIGH

does that make sense overall?


edit: to then actually go into it, let's say i wanted my hondew berry to heal my pokemon halfway as well as revive it while also giving my pokemon 10 ev's in both hp and special defense. and screw it, we'll only let it raise our pokemon's friendship by 50 if and only if the mon is in the middle friendship range:

const u8 gItemEffect_HondewBerry[10] = { // this 10 is actually the highest number you use below +1.  it is 10 here because i only go to [9]
    [4] = ITEM4_REVIVE | ITEM4_HEAL_HP | ITEM4_EV_HP, // ITEM4_EV_HP < ITEM4_HEAL_HP so it is checked first, and then ITEM4_REVIVE doesn't take a parameter (no incrementing var_3C)
    [5] = ITEM5_EV_SPDEF | ITEM5_FRIENDSHIP_MID,
    [6] = 10, // raise hp ev by 10
    [7] = ITEM6_HEAL_HALF, // heal hp by half
    [8] = 10, // raise spdef ev by 10
    [9] = 50; // raise friendship by 50 only if in middle range
};
one other thing to note is that for some reason [4] checks for pp raise before anything else. the code just checks for it before going in on the loop for some reason (see here)
heyo check out my github:

BluRosie

also on discord: BluRose#0412

McPaul

On my way to become a controversial and hated member.

He/ Him
Switzerland
Seen 1 Week Ago
Posted 2 Weeks Ago
243 posts
2.9 Years
Wow! You're one hell of a guy! Thank you! I'll look on it better later as I'm on my phone right now.

I made EV berries raise EVs by 1 instead of lowering EV because all EV are maxed out in my hack so lowering them makes no sense.

As Special Attack and Special Defense share the same IV and the same EV like in GSC Calcium and Hondew Berry have to raise Special Attack and Special Defense at the same time that's why I'm losing hair at this and I finally had to sacrifice friendship lines at first but maybe not thanks to you!