Skeetendo

’Cause all games were better on the GBC

You are not logged in.

  • Index
  • → Help/Question
  • → [Pokecrystal] Creating a state that changes a sprite palette

#1 2016-09-10 15:11:32

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 358/496

[Pokecrystal] Creating a state that changes a sprite palette

I'm helping my friend out with a hack and we are trying to recreate the Pinkan Berry effect from the Orange Islands anime.

I theorized the best way to do this would be to create a Pinkan state, like Sleep or Paralysis, to do this. I thought it might be possible since certain moves can temporarily change a sprite's palette, such as defense curl or minimize.

After some digging, all I can really find are these calls for animations:

anim_obp0

followed by a value such as $e4 or $54. I do not know what these are referencing.

Here is an image illustrating what I'm attempting to do.
2BXw4S3.png

Essentially, it would be a universal palette for every sprite, as a state. It can be cured if an item was coded to do so. Feeding a Pokemon the berry would induce this state.

If anyone has some ideas let me know :p

Offline

#2 2016-09-10 18:07:13

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 359/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Sorry for the double post.

So far, I have added the palette itself and included it within the palette pointers for pokemon, hopefully this is a good first step.

PinkanPalette:            INCLUDE "gfx/pics/pinkan.pal"

I'm going to see how the shiny code works and see if instead of checking stats, it can check a status like poison does and see if I can work with that.

EDIT: Yeah, that doesn't really seem to help at all. Does anyone have an idea of how I can do this?

Last edited by Kuroko Aizawa (2016-09-10 21:12:49)

Offline

#3 2016-09-10 22:00:12

Rangi
Member
Registered: 2016-05-09
Post 192/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

Using a status effect would either prevent Pinkan Pokémon from being poisoned/burned/etc, or make them lose their color when they get status.

Crystal has a CaughtData byte for each Pokémon that stores its caught location (look at wram.asm, main.asm:SetCaughtData, and event/poke_seer.asm for how it works). You could check this byte when viewing the stat screen, or for a wild battle, check the player's current location and use the Pinkan palette if they're on that island. If you don't care about Poké Seer accuracy, have the Pinkan Berry edit the caught location.

I would suggest editing gfx/pics/palette_pointers.asm so that palette #0 has normal pink and shiny pink, then edit gfx/color.asm:GetMonPalettePointer to only execute "add hl, bc" if the Pokémon is not supposed to be pink.

Last edited by Rangi (2016-09-10 22:04:12)


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#4 2016-09-10 22:25:57

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 360/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Rangi wrote:

Using a status effect would either prevent Pinkan Pokémon from being poisoned/burned/etc, or make them lose their color when they get status.

Crystal has a CaughtData byte for each Pokémon that stores its caught location (look at wram.asm, main.asm:SetCaughtData, and event/poke_seer.asm for how it works). You could check this byte when viewing the stat screen, or for a wild battle, check the player's current location and use the Pinkan palette if they're on that island. If you don't care about Poké Seer accuracy, have the Pinkan Berry edit the caught location.

I would suggest editing gfx/pics/palette_pointers.asm so that palette #0 has normal pink and shiny pink, then edit gfx/color.asm:GetMonPalettePointer to only execute "add hl, bc" if the Pokémon is not supposed to be pink.

Yeah, it's supposed to be a temporary effect, in the anime it's explained that it's temporary, and only permanent if they have eaten it their whole life. I thought it would be neat to make it a temporary thing. I want it to purposely be a status, which, yes, would prevent them from being burned or poisoned, frozen, etc.

Rangi wrote:

If you don't care about Poké Seer accuracy, have the Pinkan Berry edit the caught location.

I would suggest editing gfx/pics/palette_pointers.asm so that palette #0 has normal pink and shiny pink, then edit gfx/color.asm:GetMonPalettePointer to only execute "add hl, bc" if the Pokémon is not supposed to be pink.

Would this allow every Pokemon to reference the same palette? That sounds like a good idea and while not quite what I was thinking that could work just as well.

Offline

#5 2016-09-10 22:31:54

Rangi
Member
Registered: 2016-05-09
Post 193/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

Would this allow every Pokemon to reference the same palette? That sounds like a good idea and while not quite what I was thinking that could work just as well.

Yes, they'd all be referencing the 0th/first palette. Just check for PNK status instead of location and your plan should work.

Also, it would be neat if you encounter wild Pokémon that already have the PNK status on Pinkan Island. Kind of like how Pokémon in Headbutt trees are sometimes asleep. (Look around "call CheckSleepingTreeMon" in battle/core.asm.)

Last edited by Rangi (2016-09-10 22:34:03)


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#6 2016-09-10 22:39:22

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 361/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Rangi wrote:

Would this allow every Pokemon to reference the same palette? That sounds like a good idea and while not quite what I was thinking that could work just as well.

Yes, they'd all be referencing the 0th/first palette. Just check for PNK status instead of location and your plan should work.

Also, it would be neat if you encounter wild Pokémon that already have the PNK status on Pinkan Island. Kind of like how Pokémon in Headbutt trees are sometimes asleep. (Look around "call CheckSleepingTreeMon" in battle/core.asm.)

Haha, yes! That's exactly what I was thinking. The whole reason I went with this approach xD

Offline

#7 2016-09-10 22:44:32

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 362/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Rangi wrote:

I would suggest editing gfx/pics/palette_pointers.asm so that palette #0 has normal pink and shiny pink, then edit gfx/color.asm:GetMonPalettePointer to only execute "add hl, bc" if the Pokémon is not supposed to be pink.

I just have another quick question about this, will I have to add a function to check for the PNK status, because it's looking like this:

GetMonPalettePointer:
    ld l, a
    ld h, $0
    add hl, hl
    add hl, hl
    add hl, hl
    ld bc, PokemonPalettes
    add hl, bc
    ret

GetMonNormalOrShinyPalettePointer:
    push bc
    call GetMonPalettePointer
    pop bc
    push hl
    call CheckShininess
    pop hl
    ret nc
rept 4
    inc hl
endr
    ret

How do I tell it "Pokémon is not supposed to be pink?"

Offline

#8 2016-09-10 22:46:42

Rangi
Member
Registered: 2016-05-09
Post 194/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

Haha, yes! That's exactly what I was thinking. The whole reason I went with this approach xD

Cool. :) Have you gotten far mapping out the Orange Islands? Are there any official sources to refer to, besides the overview map and the anime?


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#9 2016-09-10 22:52:53

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 363/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Rangi wrote:

Haha, yes! That's exactly what I was thinking. The whole reason I went with this approach xD

Cool. :) Have you gotten far mapping out the Orange Islands? Are there any official sources to refer to, besides the overview map and the anime?

My friend is pretty much going off of the anime, but we've been citing some stuff from Naranja as well, because I think Serg!o did a lot right with his hack that we can use. I don't think anything has been mapped yet, but I did make a world map for him (which I believe I've posted in the custom graphics thread).

Offline

#10 2016-09-10 23:00:59

Rangi
Member
Registered: 2016-05-09
Post 195/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

How do I tell it "Pokémon is not supposed to be pink?"

Before bc gets overwritten with PokemonPalettes in GetMonPalettePointer, it contains the address of the Pokémon's DVs (which CheckShininess uses to determine shininess). Pokémon data structures are defined with the box_struct and party_struct macros, themselves defined in macros/wram.asm. You can see that Status is 10 bytes past DVs, so you could write some routine like this:

CheckPink:
    push bc
rept 10 ; maybe 9 or 11, not sure about off-by-one errors here
    inc bc
endr
    ld a, [bc]
    ; now compare a to PNK and return 0 or 1
    pop bc
    ret

Since status conditions only exist outside the PC, things get a bit complicated. You can either add a check for it the player is viewing a deposited Pokémon, and if so don't use the pink palette; or move the status into the box_struct instead of one of the Poké Seer bytes.

You can start by ignoring the box/party distinction, but then when you view a deposited Pokémon's stats, it will be reading whatever byte is just past the box_struct and treating it as the status. Not a major problem, really.

Last edited by Rangi (2016-09-10 23:07:15)


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#11 2016-09-10 23:12:48

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 364/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

The PC shouldn't be too big of an issue, since it's a temporary status anyway, I think I'm starting to understand. After implementing the function, I should have to use:

call CheckPink

somewhere in GetMonPalettePointer, but in order to tell it what to do if it's not pink, won't I have to add another function like ".NotShiny"? I apologize, I'm not very good with assembly, referencing the crib sheet I have just tells me what a function does, although bluntly.

EDIT: Oh boy xD So now it seems there's no built in way to just inflict status on pokemon out of battle, so there goes that plan. I'm trying to add a function for the Pinkan Berry but it seems there is only item capability of curing stat effects and not giving them :s

I think I'll go ahead and make it based off of location for now.

Last edited by Kuroko Aizawa (2016-09-10 23:49:15)

Offline

#12 2016-09-10 23:47:46

Rangi
Member
Registered: 2016-05-09
Post 196/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

in order to tell it what to do if it's not pink, won't I have to add another function like ".NotShiny"?

Yes, you'd do something like this:

GetMonPalettePointer:
    call CheckPink ; return 0 in a if not pink, 1 if pink
    jr nz, .pink
    ld l, a
    ld h, $0
    add hl, hl
    add hl, hl
    add hl, hl
    ld bc, PokemonPalettes
    add hl, bc
    ret

.pink:
    ld hl, PokemonPalettes
    ret

ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#13 2016-09-10 23:56:31

Rangi
Member
Registered: 2016-05-09
Post 197/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

So now it seems there's no built in way to just inflict status on pokemon out of battle, so there goes that plan. I'm trying to add a function for the Pinkan Berry but it seems there is only item capability of curing stat effects and not giving them :s

Then write one! Look at the code for MiracleBerry and base it on that. The core action would be:

ld a, MON_STATUS
    call GetPartyParamLocation
    ld a, (1 << PNK)
    ld [hl], a

Edit: I haven't tested this, but here's a try:

PinkanBerry:
    ; Choose a Pokémon to use it on
    ld b, PARTYMENUACTION_HEALING_ITEM
    call UseItem_SelectMon
    ; Exit early if the player canceled
    jp c, PinkanBerry_ExitMenu

    ; Get the chosen Pokémon's current status
    ld a, MON_STATUS
    call GetPartyParamLocation
    ; If it's already pink, no effect
    ld a, [hl]
    and (1 << PNK)
    jp nz, NoEffectMessage

    ; Make it pink
    ld a, (1 << PNK)
    ld [hl], a
    ; Play a sound effect
    call Play_SFX_FULL_HEAL

    ; Describe the effect
    ; TODO:
    ; • add PARTYMENUTEXT_MAKE_PINK after the other PARTYMENUTEXT consts in constants/item_constants.asm
    ; • add your text to .MenuActionTexts in engine.party_menu.asm
    ld b, PARTYMENUTEXT_MAKE_PINK
    ld [PartyMenuActionText], a
    call ItemActionTextWaitButton
    ; Use up the Pinkan Berry
    call UseDisposableItem
    call ClearPalettes
    ret

PinkanBerry_ExitMenu:
    ; wItemEffectSucceeded of 0 means it was canceled
    ; it's set to 1 by default before calling PinkanBerry
    xor a
    ld [wItemEffectSucceeded], a
    call ClearPalettes
    ret

Last edited by Rangi (2016-09-11 00:07:48)


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#14 2016-09-11 00:05:40

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 365/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

vub63gq.png

It's still not referencing anything properly yet, but at least I know the palette is working. Going to look into the seer some more to see if I can work out how to make it check for location code. I don't see any instance of it making an exception for a certain location, so that bit is going to be tricky. I think Route 29 for starters will be good for a test map.

EDIT: Hmm, okay. Give me a few minutes, I'll see if I can sort it out xD

Last edited by Kuroko Aizawa (2016-09-11 00:07:21)

Offline

#15 2016-09-11 00:23:09

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 366/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

const PARTYMENUTEXT_MAKE_PINK
.Text_MakePink:
    text_jump MakePinkText
    db "@"
MakePinkText::
    text_from_ram StringBuffer1
    text " has"
    line "turned pink!"
    done

I've done all of the above. I think all that's left now is somehow connecting checkpink values to the PNK status effect.

Last edited by Kuroko Aizawa (2016-09-11 01:34:25)

Offline

#16 2016-09-11 00:28:27

Rangi
Member
Registered: 2016-05-09
Post 198/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

I think this would work:

CheckPink:
    push bc
rept 10
    inc bc
endr
    ld a, [bc]
    cp (1 << PNK)
    pop bc
    ret

ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#17 2016-09-11 00:31:57

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 367/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Ok, so I tried that out, and everything is still #0's palette by default. Also, the Pinkan Berry is not usable, it can only be given to pokemon to hold. This might be due to me replacing Item19 with the PinkanBerry.

I'm still looking at it, I'll update this post if I figure it out.

EDIT: So I've got a functioning berry in the game, when you use it, it says "(Pokemon) was cured of poison."

Not sure why it's displaying that text, but on top of that it doesn't seem to do anything, as my cyndaquil was still normal status. I'll keep plugging at it :)

Last edited by Kuroko Aizawa (2016-09-11 01:46:24)

Offline

#18 2016-09-11 01:47:21

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 368/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Ok, so I think it was a typo on my part, when defining the status itself, but upon fixing that I'm hit with some error regarding ALL_STATUS:

ERROR:  main.asm(254) -> engine/color.asm(874) :
        Expression must be 8-bit
ERROR:  main.asm(355) -> items/item_effects.asm(2841) :
        Expression must be 8-bit
ERROR:  main.asm(355) -> items/item_effects.asm(2845) :
        Expression must be 8-bit
ERROR:  main.asm(1712) -> battle/core.asm(4597) :
        Expression must be 8-bit
ERROR:  main.asm(1712) -> battle/core.asm(4628) :
        Expression must be 8-bit
ERROR:  main.asm(1712) -> battle/core.asm(4629) :
        Expression must be 8-bit
C:\cygwin\usr\local\bin\rgbasm.exe: Assembly aborted in pass 1 (6 errors)!
make: *** [Makefile:52: main.o] Error 1

My guess is that somewhere PNK isn't defined as a status and the game is trying to figure out why it isn't included :s back to searching.

EDIT: After some more messing around, I'm wondering if the engine can't support any more statuses? The conflicting code is most certainly this:

; status
const_value SET 3
    const PSN
    const BRN
    const FRZ
    const PAR
    const SLP ; 7 turns
    const PNK

ALL_STATUS EQU (1 << PSN) + (1 << BRN) + (1 << FRZ) + (1 << PAR) + (1 << PNK) + SLP

I think I'm going to just work with location, instead of status. This is proving to be a lot of work for something that could be abused anyway (as in, status infliction immunity).

Last edited by Kuroko Aizawa (2016-09-11 02:16:11)

Offline

#19 2016-09-11 02:31:38

Rangi
Member
Registered: 2016-05-09
Post 199/823

Re: [Pokecrystal] Creating a state that changes a sprite palette

Try this:

const_value SET 2
    const PNK
    const PSN
    const BRN
    const FRZ
    const PAR
    const SLP ; 7 turns

Status conditions are stored in one 8-bit byte. Bits 3 to 7 are used for PSN through SLP. Pretty sure 0, 1, and 2 are unused.

Last edited by Rangi (2016-09-11 02:32:23)


ROM hack: Pokémon Polished Crystal (GitHub) — version 2.2.0 released!

Offline

#20 2016-09-11 02:54:56

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 369/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

Rangi wrote:

Try this:

const_value SET 2
    const PNK
    const PSN
    const BRN
    const FRZ
    const PAR
    const SLP ; 7 turns

Status conditions are stored in one 8-bit byte. Bits 3 to 7 are used for PSN through SLP. Pretty sure 0, 1, and 2 are unused.

Ok, now we are getting somewhere. So, it ended up doing something, however, it said my cyndaquil was cured of paralysis, and then it put it to SLP xD So we are definitely on the right track here.

EDIT: by changing  "ld b, PARTYMENUTEXT_MAKE_PINK" to "ld a, PARTYMENUTEXT_MAKE_PINK", I was able to get it to display the correct text. All that's left is getting the correct status afflicted. Then I can try to fix the code that checks for the status.

Last edited by Kuroko Aizawa (2016-09-11 03:04:33)

Offline

#21 2016-09-11 12:55:00

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 370/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

So I kept trying to rearrange the constants of the statuses but nothing is really working. The only way I can get the status afflicted to change to something else is by putting PNK at the end, and then it will default to whatever is first in the order. However, if PNK is first in order, it will default to SLP. I don't understand, maybe there is somewhere else I need to define PNK.

; status
const_value SET 2
    const PSN
    const BRN
    const FRZ
    const PAR
    const SLP ; 7 turns
    const PNK

EDIT: So here's an update. I have the PNK status inflicting normally, which is great, but when you go into battle, after selecting a move the status becomes SLP, I've tested this with other status afflictions and others do not have this effect. Still looking into it.

Last edited by Kuroko Aizawa (2016-09-11 17:14:21)

Offline

#22 2016-09-11 17:23:20

comet
Member
Registered: 2012-04-09
Post 662/679

Re: [Pokecrystal] Creating a state that changes a sprite palette

Whoever defined the SLP constant did not think it through. Unlike the other constants, SLP is a mask for the number of turns to be asleep (up to 7).

SLP EQU 7
const_value = 3
    const PSN
    const BRN
    const FRZ
    const PAR
    const PNK

Last edited by comet (2016-09-11 17:24:43)

Offline

#23 2016-09-11 17:29:54

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 371/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

comet wrote:

Whoever defined the SLP constant did not think it through. Unlike the other constants, SLP is a mask for the number of turns to be asleep (up to 7).

SLP EQU 7
const_value = 3
    const PSN
    const BRN
    const FRZ
    const PAR
    const PNK

Beautiful, that fixed it, Comet!

That means we are at the last step, which is fixing the check here:

CheckPink:
    push bc
rept 10
    inc bc
endr
    ld a, [bc]
    cp (1 << PNK)
    pop bc
    ret

GetMonPalettePointer:
    call CheckPink ; return 0 in a if not pink, 1 if pink
    jr nz, .pink
    ld l, a
    ld h, $0
    add hl, hl
    add hl, hl
    add hl, hl
    ld bc, PokemonPalettes
    add hl, bc
    ret

.pink:
    ld hl, PokemonPalettes
    ret

Going to need to brush up on my z80 for this, but let's see if I can figure out what's not working here.

EDIT: Correct me if I'm wrong, but I think the issue is in CheckPink. I don't see anything wrong with GetMonPalettePointer.

EDIT2: As far as I can tell it's just checking for status with nothing to relay it to, but I could be mistaken. I suck at this lol.

Last edited by Kuroko Aizawa (2016-09-11 17:49:41)

Offline

#24 2016-09-11 18:08:33

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 3,384/3,506

Re: [Pokecrystal] Creating a state that changes a sprite palette

Your logic appears to be backwards. Try changing "jr nz, .pink" to "jr z, .pink" instead. The cp function returns z if the comparison matched, and nz if it did not. Also, a =/= 0 if they are pink, a = whatever their status byte is regardless of their status. You loaded a with it, and did a comparison. Nothing about that changed the value in a, all it did was change the z and c flags depending on the results of that comparison. The value in a will still be the same as what you loaded it with before the comparison.

Last edited by Mateo (2016-09-11 18:11:47)

Offline

#25 2016-09-11 21:48:22

Kuroko Aizawa
Member
Registered: 2011-12-01
Post 372/496

Re: [Pokecrystal] Creating a state that changes a sprite palette

CheckPink:
    push af
 push bc
    rept 9
    inc bc
endr
    ld a, [bc]
    cp (1 << PNK)
    pop bc
 pop af
    ret

GetMonPalettePointer:
    call CheckPink ; return 0 in a if not pink, 1 if pink
    jr z, .pink
    ld l, a
    ld h, $0
    add hl, hl
    add hl, hl
    add hl, hl
    ld bc, PokemonPalettes
    add hl, bc
    ret

.pink:
    ld hl, PokemonPalettes
    ret

We've nearly got it done now, this code seems to apply to all of the sprites and fixes the palette issues we had, however it still isn't checking for the PNK status properly yet. So close xD

Offline

  • Index
  • → Help/Question
  • → [Pokecrystal] Creating a state that changes a sprite palette

Board footer

Powered by FluxBB