• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Which Pokémon Masters protagonist do you like most? Let us know by casting a vote in our Masters favorite protagonist poll here!
  • Red, Hilda, Paxton, or Kellyn - which Pokémon protagonist is your favorite? Let us know by voting in our poll!
  • 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] NPCs are invisible until player moves after script

  • 19
    Posts
    5
    Years
    • Seen Jan 9, 2022
    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:
     
    Last edited:
    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"
     
    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:
    Spoiler:


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


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


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


    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:
    Spoiler:


    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.
     
    Last edited:
    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.
     

    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.
     
    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
     
    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:


    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:
    Spoiler:


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


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


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


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


    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!
     
    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!
     
    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?
     
    Back
    Top