The PokéCommunity Forums

The PokéCommunity Forums (https://www.pokecommunity.com/index.php)
-   Binary ROM Hacking (https://www.pokecommunity.com/forumdisplay.php?f=284)
-   -   Script NPCs are invisible until player moves after script (https://www.pokecommunity.com/showthread.php?t=445883)

wcbvei234 February 28th, 2021 10:10 PM

NPCs are invisible until player moves after script
 
Hey all =] Coming back to romhacking after a long hiatus. For this issue, I have a piece of code. It detects whether the player has received their starter Pokemon. If they have, these two guards will move to new permanent positions to let them out of Pallet Town and into yonder world. I finally cracked the code for this--well--code to work: flags. I set the flags for the guards' new positions (new NPCs entirely on AdvanceMap) when the game begins. After the guards see the player has a Pokemon, I set the flags for the guards' OLD positions so they disappear from the map (this is all using the "person ID" box in AdvanceMap) and clear the flags for the guards' NEW positions so they appear permanently in these new positions. I'm super happy to have come this far, as it's been a project of mine to figure it out on my own. Sadly now I reach out to the community to see if anyone can polish this code.

My issue with it right now is that, while the code works completely well, the guards at the new positions after setting/clearing flags are invisible until the player takes a step in any direction. Of course this breaks the immersion, so I'm wondering if anyone has any insight. I thought maybe adding some movement to the NPCs after clearing and setting flags? I made it so after the old guards disappear and the new ones (should) appear that the new guards face right or left and then the direction they should be facing, but that didn't help as they are still invisible until the player takes a step. Thoughts? As always I appreciate you guys!

Here's the code:
Spoiler:
#dynamic 0x800000

#org @start
lock
checkflag 0x200
if 0x1 goto @goAhead
goto @sorry

#org @sorry
msgbox @text 0x6
release
end

#org @text
= Hey, no sneaking out of town!\nYou should know how dangerous\lit can be out there.\pYou're allowed out once you\nhave your own Pokémon.

#org @goAhead
msgbox @textInterrupted 0x6
getplayerpos 0x5005 0x5006
compare 0x5005 0x0C
if 0x1 goto @sorryLeft
compare 0x5005 0x0D
if 0x1 goto @sorryRight

#org @textInterrupted
= Hey, no sneaking out of town!\nYou should--

#org @sorryLeft
applymovement 0x8 @sorryPoint
waitmovement 0x0
pause 0x060
msgbox @passage 0x6
closeonkeypress
applymovement MOVE_PLAYER @moveBack
waitmovement 0x0
applymovement 0x8 @moveOut
waitmovement 0x0
applymovement 0x9 @moveOutToo
waitmovement 0x0
setflag 0x253
goto @nextFlag

#org @sorryRight
applymovement 0x9 @sorryPoint
waitmovement 0x0
pause 0x060
msgbox @passage 0x6
closeonkeypress
applymovement MOVE_PLAYER @moveBack
waitmovement 0x0
applymovement 0x8 @moveOut
waitmovement 0x0
applymovement 0x9 @moveOutToo
waitmovement 0x0
goto @nextFlag

#org @sorryPoint
#raw 0x62
#raw 0xFE

#org @passage
= Holy shit! Nice GROWLITHE!\nYou're free to go.\pJust don't get yourself hurt\nout there, okay?

#org @moveBack
#raw 0x10
#raw 0x01
#raw 0xFE

#org @moveOut
#raw 0x10
#raw 0x12
#raw 0x03
#raw 0x60
#raw 0xFE

#org @moveOutToo
#raw 0x10
#raw 0x13
#raw 0x02
#raw 0x60
#raw 0xFE

#org @nextFlag
setflag 0x254
goto @nextNextFlag

#org @nextNextFlag
clearflag 0x251
goto @finalFlag

#org @finalFlag
clearflag 0x252
applymovement 0x10 @faceRight
waitmovement 0x0
applymovement 0x11 @faceLeft
waitmovement 0x0
release
end

#org @faceRight
#raw 0x02
#raw 0x03
#raw 0xFE

#org @faceLeft
#raw 0x03
#raw 0x02
#raw 0xFE

Meister_anon~Master_o f_None February 28th, 2021 11:54 PM

Quote:

Originally Posted by wcbvei234 (Post 10297997)
Hey all =] C

Post some screen shots of where they are when the block you first, and then show before and after they appear at the new positions.

Also what is this part of the code for?

"getplayerpos 0x5005 0x5006"

wcbvei234 March 1st, 2021 12:16 AM

Quote:

Originally Posted by Meister_anon~Master_o f_None (Post 10298104)
Post some screen shots of where they are when the block you first, and then show before and after they appear at the new positions.

I'll spoil the images since there's a lot of them. So this first one is where the guards are initially posted:


This is a little bit of what the guards say when the player has their first Pokemon:


This is the guard moving in action (the other one already moved--they aren't in sync which is okay for me):


After they move to where they should be (and where the "new guards" NPCs should be), they disappear:


Finally, when the player takes a step in any direction, the new guards appear facing in the correct direction, and (not pictured here) their simple text scripts run just fine:


Quote:

Originally Posted by Meister_anon~Master_o f_None (Post 10298104)
Also what is this part of the code for?

"getplayerpos 0x5005 0x5006"

That section of the code calls the player's current position and stores it (the X,Y coordinates) in the variables of 5005 and 5006. I use those coordinates to determine which guard the player is speaking to so the code knows which guard should put up the ! above his head. Technically I could just have both of them put up the exclamation point, but I figure this adds a little more immersion so it doesn't seem like two people are saying the exact same thing.

Meister_anon~Master_o f_None March 1st, 2021 12:26 AM

Ah, ok I'll read the whole thing in a second. or when I wake up. but the position thing could have prob been done,
by just using a different offset for each guard.

Just use dynamic scripts and you could have pasted the same script in for each and they would have been completely separate.

That way you wouldn't need the getplayerpos command.

Meister_anon~Master_o f_None March 1st, 2021 12:34 AM

Quote:

Originally Posted by wcbvei234 (Post 10298126)
I.

Ok read through the whole thing, it would look much better if they were in sync, don't know why they would be out of sync, but maybe if you put a pause in or something it would keep them together.

But anyway, your problem is solved by changing your movement script.
Either make those first gaurds move into the new positions.

Or set a new flag/variable so the new guards don't appear until after you've already left town.

Assuming you haven't changed too much in your story I'd recommend setting it to the veridian city poke mart event flag.


That way when you come back to town they will already be there.

Personally haven't experimented much with pre-existing flags, but I'm pretty sure that's not a temporary one, so it should be permanent.

Asith March 2nd, 2021 1:14 AM

Just randomly thought of my own solution if you're still looking. It's probably not the most efficient way but it's what I'd do and it'd work.
Essentially I recommend you use the movesprite2 command. It moves a sprite to a new xy position permanently. This completely gets rid of your need for making a second set of sprites and controlling their visibility with flags.

To briefly describe what you need to do, keep most of your script the same, but after you move the guards (keep the movement commands since we need to see the animation) use movesprite2 [people #] [x] [y] to permanently move both guards to new positions. You might need to applymovement to get them facing the right way again afterwards. Now your guards are permanently open! You don't need to clear their flags (or even assign flags to them in the first place).
But wait, now this whole script runs again if you talk to them later, instead of your new basic text. That's why you do need one flag that is set after this event just so it doesn't happen twice. The guards' script should then be:
checkflag [flag]
if 0x1 goto @basictext
{Your whole guard checking\moving script, with setflag [flag] after the guards move}
end

@basictext
{basic text script}
end


Let me know if that was unclear

wcbvei234 March 2nd, 2021 4:57 PM

Quote:

Originally Posted by Asith (Post 10299603)
Let me know if that was unclear

It was really clear, don't worry! I get what you mean. I took your advice and simplified a LOT; I removed the second set of sprites that were the new positions of the guards, I cut down a decent chunk of code for the guards because I removed a handful of flags and variables, and I removed some testing script tiles in game. You got my hopes up here because I did some reading elsewhere and people have confirmed that movesprite2 is how you permanently move a sprite's location in the game; however, I'm having a bit of trouble with it.

Here's the code:

Spoiler:
#dynamic 0x800000

#org @start
lock
checkflag 0x251
if 0x1 goto @newPositions
checkflag 0x200
if 0x1 goto @goAhead
goto @sorry

#org @sorry
msgbox @text 0x6
release
end

#org @text
= Hey, no sneaking out of town!\nYou should know how dangerous\lit can be out there.\pYou're allowed out once you\nhave your own Pokémon.

#org @goAhead
msgbox @textInterrupted 0x6
getplayerpos 0x5005 0x5006
compare 0x5005 0x0C
if 0x1 goto @sorryLeft
compare 0x5005 0x0D
if 0x1 goto @sorryRight

#org @textInterrupted
= Hey, no sneaking out of town!\nYou should--

#org @sorryLeft
applymovement 0x8 @sorryPoint
waitmovement 0x0
pause 0x060
msgbox @passage 0x6
closeonkeypress
applymovement 0x8 @moveOut
applymovement 0x9 @moveOutToo
waitmovement 0x0
movesprite2 0x8 0x0B 0x02
movesprite2 0x9 0x0E 0x02
applymovement 0x8 @turn
applymovement 0x9 @turnToo
waitmovement 0x0
setflag 0x251
release
end

#org @sorryRight
applymovement 0x9 @sorryPoint
waitmovement 0x0
pause 0x060
msgbox @passage 0x6
closeonkeypress
applymovement 0x8 @moveOut
applymovement 0x9 @moveOutToo
waitmovement 0x0
movesprite2 0x8 0x0B 0x02
movesprite2 0x9 0x0E 0x02
applymovement 0x8 @turn
applymovement 0x9 @turnToo
waitmovement 0x0
setflag 0x251
release
end

#org @sorryPoint
#raw 0x62
#raw 0xFE

#org @passage
= Holy shit! Nice GROWLITHE!\nYou're free to go.\pJust don't get yourself hurt\nout there, okay?

#org @moveOut
#raw 0x10
#raw 0x12
#raw 0xFE

#org @moveOutToo
#raw 0x10
#raw 0x13
#raw 0xFE

#org @turn
#raw 0x03
#raw 0xFE

#org @turnToo
#raw 0x02
#raw 0xFE

#org @newPositions
faceplayer
msgbox @msg 0x6
release
end

#org @msg
= Be safe out there, kid!


So to paraphrase the code: @moveOut and @moveOutToo have the guards walk to their new permanent positions, then I use movesprite2 on both sprites to the respective X/Y coordinates that they just walked to, and I use some more applymovement to both of them just to turn their heads to face inwards. The code works just fine while I'm in Pallet Town; it runs just as it should, and it detects if it's already been ran with the new flag of 0x251. The issue is after I leave Pallet Town--they return to their original positions and not the ones I instated with movesprite2.

Here are some images:

This one shows that the code still detects the player's starter Pokemon:


This one shows that the guards move to their new positions correctly:


This one shows that the guards' code understands that the initial movement/talk has already taken place:


And then the trouble happens--they move back to their original positions:


However, the code still recognizes that it's already taken place:


This leads me to believe that it's something to do with the movesprite2 command, but maybe I'm missing something in my code. Let me know if you have any more suggestions--I think we're on the right track!

Asith March 3rd, 2021 3:32 AM

Quote:

Originally Posted by wcbvei234 (Post 10300525)
It was really clear, don't worry! I get what you mean. I took your advice and simplified a LOT; I removed the second set of sprites that were the new positions of the guards, I cut down a decent chunk of code for the guards because I removed a handful of flags and variables, and I removed some testing script tiles in game. You got my hopes up here because I did some reading elsewhere and people have confirmed that movesprite2 is how you permanently move a sprite's location in the game; however, I'm having a bit of trouble with it.

Hmm, alright, I may have overlooked something with movesprite2. I now believe that that command only functions properly in level scripts. Admittedly I've only ever used it in level scripts myself, but I didn't think that was an actual limitation of the command. In any case, you've now got a fully working solution that I just tested on a fresh rom!
So, we're gonna move the movesprite2 commands out of your code and into their own level script. You can literally just cut them out, and probably condense your applymovements into one movement now that nothing's in the way there.

What you then need is a level script for Pallet Town with this exact code:

#dynamic 0x800000
#org @levelscript

checkflag 0x251
if 0x1 goto @move
end

#org @move
movesprite2 0x8 0xB 0x2
movesprite2 0x9 0xE 0x2
end


It checks for the flag you put on the event earlier and moves the guards if you've talked to them successfully. I added this as a new level script under Byte 5 - On entering map/On menu close, and left the other Pallet Town scripts there. If you don't need the default ones, you could also just replace them with this new code. Additionally, if you ever need to add a different new level script to Pallet Town, you can just put this self-contained bit of code in it with a goto or a call. Basically, it's not as serious a change as it sounds

Ultimately this'll work smoothly and the player won't notice that a level script is being called now. Happy hacking!

wcbvei234 March 3rd, 2021 1:20 PM

Quote:

Originally Posted by Asith (Post 10301434)
Ultimately this'll work smoothly and the player won't notice that a level script is being called now. Happy hacking!

Success! It works perfectly! Thanks a bunch for your insight! I had to do some digging around and perfect my knowledge on what level scripts actually are, but we got it in the end lol. On that note, could you tell me the difference between level script type 03 and type 05? I heard somewhere that people more commonly use type 03, but when I tried using that on this level script, it failed to load when I walked back into Pallet Town--it works perfectly with type 05 like you said though. I feel like there's a lot of contradictive information out there about the types of level scripts, so since you fixed up my code using it: what are your thoughts on the two types of 03 vs 05?

kalarie March 3rd, 2021 2:55 PM

@wcbvei234

A type 03 level script loads once on entering the map and not when returning to the overworld from the pokedex or the pokemon menu.

A type 05 level script loads everytime when returning to the overworld.


All times are GMT -8. The time now is 9:19 AM.


Like our Facebook Page Follow us on Twitter © 2002 - 2018 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2016 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.

Acknowledgements
Use of PokéCommunity Assets
vB Optimise by DragonByte Technologies Ltd © 2023.