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

Progressively Revealing Region Maps (With Marin's Better Region Maps)

17
Posts
5
Years
    • Seen Feb 21, 2021
    Hello Everyone! I recently finished a thread where I inquired about progressively revealing the region map to the player, i.e., the player starts with a blank map without any routes or towns, and as the player travels to each new area, the map gets updated to reveal each new location on the map. With the suggestions of a few great people in this community, I managed to code a working solution to this. This script modify's Marin's Better Region Map script. If you don't already have it, I highly suggest using it! This is for Pokemon Essentials 17.2 but I imagine it will work with other versions of Essentials.

    With this guide I'll go over all the details of what my modification does as well as provide some tips at the end with using it. If you have any questions, feel free to send me a message or reply to this thread. I'll be more than happy to help out where I can!

    To start off, you need to go to Settings to create a new setting for your game. This is an array that will store all of the necessary route info, modeled after the REGIONMAPEXTRAS setting already existing, which is the Hidden Island feature (Berth and Faraday Islands) that are in base Essentials. Marin's script doesn't use this feature, so I made a new variable for my own modification. In Settings, I placed this under the REGIONMAPEXTRAS (Line 280):

    Code:
    #===============================================================================
    # * A set of arrays for hidden routes and towns that will be shown when the
    #      player enters the map.  Each Array must contain the following:
    #      - Region number.
    #      - Map ID.
    #      - X coordinate of the graphic on the map (pixel)
    #      - Y coordinate of the graphic on the map (pixel)
    #      - Name of the graphic, found in the Graphics/Pictures/Routes folder.
    #      - Name of Route/Town in townmap.txt
    #      - (optional, set=0 for no switch) Game Switch to reveal this 
    #         map location to player (can't fly to location)
    #===============================================================================
    HIDDENROUTES = [
       [0,81,80,160,"townNewbreezeTown","Newbreeze Town",0],
       [0,32,64,160,"route4","Route 4",0],
       [0,48,160,192,"townOldparkTown","Oldpark Town",67]
    ]

    I've set out the different variables in the array there. The Map ID is the map id that triggers the route to appear once the player enters it. You can do some interesting things with this variable, more about this in the tips at the end. I've also added a Game Switch functionality. If you want to show a far away location to the player, simply set the switch (in my example, switch 67) via an event script and the location will now be displayed on the player's map. This can be turned off later too, hiding the location on the map (see tips below). Setting this to 0 removes this feature for that particular location, as there is no "switch 0."

    You will now need to create a new folder in your Graphics/Pictures Folder called "Routes" where you'll be placing all the individual routes and towns. I've included some personal examples of two towns and a route that connects them. You can view my example towns and routes here. As well as my blank region map where the routes and towns will be added in later.

    Now that the setting is complete, the rest of the modifications will all be in Marin's BetterRegionMap script.

    We first need to redefine what region to display. Replace this line (line 48):

    Code:
          @region = region || $PokemonGlobal.region

    with this:

    Code:
        if region == nil
          @region = pbGetMetadata($game_map.map_id,MetadataMapPosition)[0]
        else
          @region = region || $PokemonGlobal.region
        end

    Next, below this line: "@window["player"] = Sprite.new(@mapvp)" (line 72)

    Paste this:

    Code:
    #-----------------------------------
    #-----------------------------------
        for route in HIDDENROUTES
          if ($PokemonGlobal.visitedMaps[route[1]] && @region == route[0]) ||
             ($game_switches[route[6]] && @region == route[0])
            @window[route[4]] = Sprite.new(@mapvp)
            @window[route[4]].bmp("Graphics/Pictures/Routes/#{route[4]}")
            @window[route[4]].x = route[2] - 4 #Not sure why, but there is an offset of 4
            @window[route[4]].y = route[3] - 4
          end
        end
    #-----------------------------------
    #-----------------------------------

    You will also need to modify the "if @show_player" statement a little bit too.

    Below this line: "@window["player"].y = TileHeight * player[2] + (TileHeight / 2.0)"

    Paste this:

    Code:
    @window["player"].z = 1 #so the player icon shows above routes

    And lastly, at around line 360 you will need to replace the entire "def update_text" routine with this slightly modified version in order to hide the information text that appears on the map until the player has visited the map ID outlined in the HIDDENROUTES array.

    Replace the full "def update_text" with this:

    Code:
    #-----------------------------------
    #-----------------------------------
      def update_text
        location = @data[2].find do |e|
          e[0] == $PokemonGlobal.regionMapSel[0] &&
          e[1] == $PokemonGlobal.regionMapSel[1]
        end
        
        text = ""
        poi = ""
        
        for route in HIDDENROUTES
          if ($PokemonGlobal.visitedMaps[route[1]] && @region == route[0]) || 
             ($game_switches[route[6]] && @region == route[0])
            text = location[2] if location && (location[2] == route[5])
            poi = location[3] if location && location[3] && (location[2] == route[5])
          end
        end
          
        @sprites["txt"].draw([
            [pbGetMessage(MessageTypes::RegionNames,@region), 16, 0, 0,
                Color.new(255,255,255), Color.new(0,0,0)],
            [text, 16, 354, 0, Color.new(255,255,255), Color.new(0,0,0)],
            [poi, 496, 354, 1, Color.new(255,255,255), Color.new(0,0,0)]
        ], true)
      end
    #-----------------------------------
    #-----------------------------------

    And that's it! Your routes will now display progressively as the player adventures forth into your wide wide region! Every time the player steps onto a new map, the map id is saved by Essentials as a "visited map" something Essentials keeps track of naturally. Here are some screenshots to show what I mean using my example pictures provided above. As the player moves from Newbreeze Town to Route 4 then to Oldpark Town, each route and town gets revealed along with some trees that I included in the images with each.

    This will then reveal the visited route or town when the player steps onto the map. This code completely overhauls how routes are displayed, so every single town and route needs to be listed in the HIDDENROUTES array. It sounds like a lot, but as long as you keep up with it as you create new maps, it isn't as much work. The hardest part is cutting up your routes individually, but that is really just time consuming.

    Some tips:
    The same effect can be done with base Essentials if you don't wish to use Better Region Maps. Simply add the routes and towns into the REGIONMAPEXTRAS array in Settings to take advantage of the Hidden Islands feature. This method uses switches, so you'll need to dedicate a large number of switches for each route and town.

    If you wish for a town or route, or whatever custom feature you want on the map, to be visible from the very beginning, in the HIDDENROUTES array, make the Map ID 1 (the intro map) instead of whatever map id the place actually is. This will make the place appear on the map right from the very beginning of the game. You can also do this for a series of towns and routes you want to appear all at once, simply make the map id of each entry in the HIDDENROUTES array to be the same, then they will all appear on the map together once the player enters that one Map ID. By doing this for all routes and towns, you can essentially have a fully loaded in map, opening up the possibility to use a Hidden Island-like feature in Marin's Better Region Map.

    This code will even allow you to change a route on the fly (say a landslide happens and the route now goes South instead of East). If you set the map ID in the HIDDENROUTES array to a location that the player can't visit (like creating a dumby map that's only one tile big, just for this purpose) and use a Switch to show the route when the player first visits, the route will display on the map. When the landslide happens, simply use an event to turn the switch off for the Eastbound route and turn the switch on for the Southbound route. The map will change to show the Southbound route instead!

    With the Game Switch variable in HIDDENROUTES, you can set a location to Switch 14, the s:PBDayNight.isDay? switch to check whether or not it's day. By tying this to a location, say some mysterious cave with a legendary in it, you can display the cave on the player's map only when it's day time. Likewise, you can tie this to Switch 19 to check if it's a certain weekday. If you set the map ID for the location in HIDDENROUTES to be a map id the player can't visit then this location will always be hidden on the map even after the player has visited the mysterious cave. By playing around with the map ID and Switches, you can create some pretty awesome living maps that change as the player explores your world!

    That's everything! I was thinking of making a more "light" version of this where the map appears normal without you having to create all of the points in the HIDDENROUTES array but still have the ability to hide some routes from the player until they discover them. This would be exactly what the Hidden Islands feature in base Essentials was, just with Better Region Maps. If someone would like this, I'll look into modifying my code to get it working. But for now, Enjoy!
     
    Last edited:
    153
    Posts
    4
    Years
    • Seen Feb 4, 2020
    Glad you made it to the script and tutorial section :)

    What line of code should we use in an event to reveal one map independently, without entering the road next to it? For example a character tells you there is a wonderful land faraway on the map and draws its location on your map, then you would have this location more or less revealed but nothing in between.
     
    17
    Posts
    5
    Years
    • Seen Feb 21, 2021
    Glad you made it to the script and tutorial section :)

    What line of code should we use in an event to reveal one map independently, without entering the road next to it? For example a character tells you there is a wonderful land faraway on the map and draws its location on your map, then you would have this location more or less revealed but nothing in between.

    Thanks! And thank you for the suggestion! I hadn't thought about that scenario, so I added a few modifications to my code (edited the post). And luckily you suggested it too! I found a bug with Marin's original code, it wouldn't load different regions properly. Namely if you entered a new region, for example moving from Kanto to Johto, if you opened up the town map, it would take two tries in order to open the Johto map. then when you go back to Kanto, the Kanto town map wouldn't ever show, it would be stuck on Johto's map. So after a few hours of bug zapping I managed to learn how the game determines which region the player is standing in and apply that knowledge to Marin's script! I've included this solution in my original post, so be sure to update your script! I've changed every section a little bit to incorporate your idea and to squash that bug.

    So to fully answer your question, I added a new variable for HIDDENROUTES array at the end, this will allow you to reveal a location on a map with a Game Switch. Setting this variable to 0 is the default if you don't want a switch to open up the far away location. If the player happens to get there before you reveal it to them, the location will still be revealed like any other route, the switch won't interfere with the display if it's turned on afterwards. This addition really added a whole lot of new functionality to my code, so thanks for suggesting this (read the tips)! My code now works on multiple regions, so you can reveal a far away location on an alternate region map as well. Granted that you show the player the other region map with an event script of:
    Code:
    pbBetterRegionMap(1)
    with replacing the "1" with whatever region it is. This is the same code to open up a wall map in a Pokemon Center using Better Region Map. pbShowMap does not work with Marin's Better Region Map.
     
    Last edited:
    153
    Posts
    4
    Years
    • Seen Feb 4, 2020
    Simply awesome.

    So if I understand it well, if I set this last number to 50 it will make so if I activate switch 50 the map will be revealed and then if I swith it off the map won't be displayed anymore. And if I visited the map myself then even switching the switch off won't hide the map anymore. Is that right?

    Now what if I want a map to appear in different positions, like a moving island vanishing during the day then appearing again somewhere else the next night? I guess this has to be made by having multiple entries to this map which are coordinated by the appearance of mysterymap1,mysterymap2 and so on. So I have to create like 7 entries to my mystery map and close them to open them only when it's the good day of the week and together to this reveal the location on the map. or I could generate a random number which determines where the mystery map appears tonight. but then I have an issue. If indeed, as I asked above, the map is forever revealed when I visit it once, it will create a bug with the fact that another location is randomly generated the next night (2 times the same "city" will be drawn on the map in different locations, then 3 if I go to the same city from another entry point and another location is revealed the next day)

    Sorry, looks like each time I have a question it makes you work more xD
     
    Last edited:
    17
    Posts
    5
    Years
    • Seen Feb 21, 2021
    So if I understand it well, if I set this last number to 50 it will make so if I activate switch 50 the map will be revealed and then if I swith it off the map won't be displayed anymore. And if I visited the map myself then even switching the switch off won't hide the map anymore. Is that right?

    That is correct! The line:
    Code:
    if ($PokemonGlobal.visitedMaps[route[1]] && @region == route[0]) ||
       ($game_switches[route[6]] && @region == route[0])
    First checks to see if the player has visited the Map ID set in HIDDENROUTES, if so, it will always display the location on the map (I can't seem to find a line of code that can modify which locations have been visited, so I simply reference this mysterious list to check if the player has visited or not). OR it checks to see if the switch has been activated, displaying the location if the switch is on. Only one of these needs to be true for the location to display. As a note, displaying the location on the map doesn't let the player fly to it, it's built in to essentials that a flying is only possible if the player has been to the map at least once.

    Now what if I want a map to appear in different positions, like a moving island vanishing during the day then appearing again somewhere else the next night? I guess this has to be made by having multiple entries to this map which are coordinated by the appearance of mysterymap1,mysterymap2 and so on. So I have to create like 7 entries to my mystery map and close them to open them only when it's the good day of the week and together to this reveal the location on the map. or I could generate a random number which determines where the mystery map appears tonight. but then I have an issue. If indeed, as I asked above, the map is forever revealed when I visit it once, it will create a bug with the fact that another location is randomly generated the next night (2 times the same "city" will be drawn on the map in different locations, then 3 if I go to the same city from another entry point and another location is revealed the next day)

    Sorry, looks like each time I have a question it makes you work more xD

    This is possible without any bugs! And don't worry about more work, it's fun to solve problems like this. Besides, what you're asking for is already possible!

    By having multiple entries in HIDDENROUTES, you can set each entry to a different switch and a different X and Y coordinate. You can reference the same picture file though, so you won't need multiple different mysterymap1 images in the Routes folder. The bug you're referring to is only an issue if you set the trigger to be a specific map ID that the player visits. By setting the Map ID to a map the player can never visit (a dumby map), the only trigger that will activate the mystery location is a Switch. I've whipped up an example HIDDENROUTES array for you to help explain what I mean:

    Code:
    HIDDENROUTES = [
       [0,100,10,16,"mysterymap1,"Vanishing Island",65],
       [0,100,64,80,"mysterymap1","Vanishing Island",66],
       [0,100,32,120,"mysterymap1","Vanishing Island",67]
    ]
    Note: "Vanishing City" should be whatever you called this location in townmap.txt. This is what my code looks for to display the town name and points of interest on the map. "mysterymap1" is simply the image name in the Routes folder, there is no limit on how many times you can reference this name in the array.

    (Side note: Even if the name appears more than once and is displayed more than once, all instances will appear on the map without issue. For example, reusing the same big red city image a few times for the different cities on the map. You only need to have one largeCity.png image for all the different cities, simply just reference the one image in the array like I did there for each time you need to put a large city on the map.)

    Suppose that this Vanishing Island's real map ID is 75. In my example, the Map ID is set to 100, this is a newly created map that exists only as a scapegoat for this sort of trick with this code. The player can't access it, it's simply just a number in order to ensure that the first argument (if the player visited) will always be false. Which means the only way for the location to appear is if one of the Switches, 65, 66, or 67, are ON, even after the player has visited the Vanishing Island (as it's real Map ID is something else, not 100). These Switches can be whatever switch you want, for example you can set switch 65's name to be s:pbIsWeekday(-1,5) which will check if the day is Friday only, turning the switch on. Likewise, 66 can be set to s:pbIsWeekday(-1,6) to check if it's Saturday and Switch 67 can be s:pbIsWeekday(-1,0) to check if it's Sunday. This will then make sure that the location will only show up on the map in one location and only during those specific days. The rest of the week, it will not appear on the map, even after the player has visited.

    If you want a random day of the week for the Vanishing Island to appear, you might have to get creative with the Switch's name or in game events. s:pbIsWeekday(-1,rand(7)) will generate a random day number from 0 (Sunday) to 6 (Saturday) but it generates this random number every time the player takes a step or presses a button (it is constantly refreshing to check what day it is). So in order to have a random variable determine when the Vanishing Island will appear, you will have to get creative with some sort of event scripting or create a new "def randomDay" script somewhere in PField_Time that you can call to check if the random number generated there is equal to pbIsWeekday(-1,5) (Friday). This new script would need to check once a day and return the same variable once set every day, otherwise the player could abuse it by loading the game up, checking if the Island is there, closing the game, and checking again. I'm not sure where to begin coding this, but perhaps you can ask the kind people on here for help with that! It's also a little out of the scope for my code in this thread :)

    Hopefully this answered your question! I got a little carried away.
     
    153
    Posts
    4
    Years
    • Seen Feb 4, 2020
    It definitely did! Thank you.

    Actually my head is just too full of ideas for my own game's sake and I wanted to know how to do this even though it has no room in my story. My game is for educational purposes (for my pupils as I'm a teacher) and the story tries to be as realistic as it can be, even mixing pokemons with real living species and giving scientific explanations on how such creatures can exist. So a mysterious flying island is not a priority for me now but I am grateful to know how to do it now thanks to your investment.

    What I might try to add soon however is a 2 or 3 layers map because I'm using the real world as a map and I'd like to add some geographic notions in the game. So would like to have the possibility to switch from an entire world perspective and the city I'm in and even maybe neighborhood to be more realistic.
    I'll dig into this when I'm done doing explicative cinematics for my game :p
     
    Back
    Top