Get any map display name?

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
I can use $game_map.display_name to access the display name for the map I'm on, but how do I access the display name of any map?
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
The map names are stored in the map files, i.e. those files named like "Map001". To get the name for an unloaded map, you'd need to temporarily load it using the ID, then access its name like this:

Code:
map_id = 1
temporary_map = load_data(sprintf("Data/Map%03d.rvdata2", map_id))
other_map_name = temporary_map.display_name
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Well that works nicely. Although, I've run into a larger issue I have no idea how to fix. Maybe you could help me out?

I needed this so I can display dynamic NPC locations in Modern Algebra's Quest Journal, and I've set it up to work, but the script doesn't seem to refresh the quest data after loading it for the first time. So even though I may change my map name variable, the displayed name never changes. I don't know enough about Ruby to modify the script to refresh appropriately...

Line 792 is where I've used my variable instead of a string.

I would really appreciate your help!
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
What exactly does line 792 look like for you? Basically, I'm interested in how you're referencing your variable. Also, walk me through how it doesn't refresh. So you start the game and open the journal: what's displayed? Then you change your variable and open the journal: what's displayed? That kind of walk-through is super helpful in troubleshooting.
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Thank you for replying! Let me try to help you help me. :)

So my line 792 looks like :
Code:
q[:location]          = "#{@npc45_loc} "
I inserted into the script, just before line 778 the following (which seems to work fine?) :
Code:
loc_id = $game_variables[80] #The map ID NPC 45 is currently on, set by the NPCs Common Event)
loc_map = load_data(sprintf(
"Data/Map%03d.rvdata2", loc_id))
loc_name = loc_map.display_name
@npc45_loc = loc_name
To answer your questions, when I start the game and open the quest scene, it is empty, of course. My NPC location is dynamic and controlled by a Common Event. I add the quest (via a test event) and when I open the quest scene again, everything looks great. The quest giver location is correctly displaying the name of whatever map my NPC is supposed to be on. Then, if I run my Common Event and the NPC is determined to have moved maps (therefore updating $game_variables[80] to a new integer representing the new map ID), and I reopen the quest scene, the quest giver location has not updated, and still displays the name of the first map he was on. This system is intended to inform the player where all the moving characters are, so he/she doesn't get frustrated if they aren't where they were before. I like the dynamic feel of NPCs having schedules and different places to be, I just don't want it to become a drawback. This magical Marauder's Map feature would be a great integrated solution. :)

A few things I've noticed through testing:

1) my little snipped I've inserted at line 778 isn't run every time the scene is called, but only when a new quest is added. So that's not working.

2) even if the snippet runs (forced to do so by adding another quest and running the code), line 792 (q[:location] = "#{@npc45_loc} ") is not updated. So, the displayed information remains the same, even if the variable @npc45_loc has changed.

Hope that helps. As you can tell, I am not a coder. I add and edit crap through trial and error until I get it to work, which sometimes I never do. :D
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
Ok, so you're already on the right track. You know your code isn't running when you'd like it to. If you scroll up from line 778 to line 610 you should see "def self.setup_quest(quest_id)". Even if you don't entirely understand that line, you should see that it says "setup_quest". So your code is only running when a quest gets setup. Hey you already knew that! :) But now you know why. So we need to move our code somewhere that will be run when the scene is called but only once so that we don't slow the game down.

Let's go looking through the script for the "scene". So, I ctrl+F the word "scene" and find line 2386 "class Scene_Quest < Scene_MenuBase". Ok, so this should be the place. Let's look through what's here. Scrolling down we find on line 2390 "def start" and above it is a comment that says "Start Scene Processing". So this gets run at the start. Cool B), so now we know where we can put our code to run when the scene starts.

But as you've already deduced, even if you trick the code into running, the displayed information remains the same. Boo. So what gives? Well, it has to do with how we're referencing things. Your current line 792 (q[:location] = "#{@npc45_loc} ") says take the *value* of the variable @npc45_loc and store it in a new string as the location. Effectively making a copy of it. What we want to do is tell the location to look directly at the variable. So at a simple level, we should do something like this: q[:location] = @npc45_loc

So that would kind of work, but also not really and then we get into some deeper level ruby stuff about object references and stuff that I can't explain in a short post (like this is a short post anyway lol). Suffice it to say, we need to be a little more meticulous and move our code into its own thing. So here it is:
Code:
module NPC_Locations
  # This stores the dynamic locations of all npcs
  # It needs to be filled with the 'keys' for each
  # npc. A key looks like this - :some_name - if
  # you copy the examples below you should be fine.
  # You can leave the location blank if want like 
  # example #2
  @@locations = {
      :npc45 => "camp"
      :new_npc => ""
  }
  # This links the npcs to their corresponding id
  # in $game_variables
  # Every npc present above needs an entry here
  @@npc_game_vars = {
      :npc45 => 80
      :new_npc => 1
  }
 
  # To then make the quest journal reference our npcs
  # we use the following:
  # q[:location] = NPC_Locations[:npc45]
  # Obviously, replace :npc45 with whatever npc key you need

  def self.[](name)
    @@locations[name]
  end

  def self.[]=(id, newvar)
    @@locations[id].clear
    @@locations[id] << newvar
  end

  def self.update_all()
    @@locations.each_key do |key|
        loc_id = $game_variables[ @@npc_game_vars[key] ]
        loc_map = load_data(sprintf("Data/Map%03d.rvdata2", loc_id))
        loc_name = loc_map.display_name
        NPC_Locations[key] = loc_name
    end
  end

end

class Scene_Quest < Scene_MenuBase
  # Create an alias for the old method so we can call it
  alias MA_start start
  # Add our code to the scene start method
  def start
    # Call the original method
    MA_start
    # Call our update code
    NPC_Locations.update_all()
  end
 
end

Hopefully that makes sense (and works lol, I haven't bug tested it).
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Wow, thanks again. Very detailed assistance!

But..... I may have caused more confusion by trying to simplify things to start with. Let me be completely transparent and show you what I'm doing.

I'm not using $game_variables at all, actually. I have too many NPCs and didn't want to take up tons of variables in the editor's interface. I have a separate snippet that looks like this:
Code:
module DataManager
 
  #--------------------------------------------------------------------------
  # * Create Wrapper Class
  #--------------------------------------------------------------------------
 
  class AAKHash
 
  def initialize(default = nil)
    @data = default || {}
  end

  def [](key)
    @data[key] || 0
  end

  def []=(key, value)
    @data[key] = value
  end
 
end
 
  #--------------------------------------------------------------------------
  # * Create Game Objects
  #--------------------------------------------------------------------------
  class << self
    alias create_game_objects_tablelist_base create_game_objects
  end
  def self.create_game_objects
    create_game_objects_tablelist_base
    $npcs = AAKHash.new
    $cards = AAKHash.new
    $guildloot = AAKHash.new
    $dailysearch = AAKHash.new
    $ingredients = AAKHash.new
  end
  #--------------------------------------------------------------------------
  # * Create Save Contents
  #--------------------------------------------------------------------------
  class << self
    alias make_save_contents_tablelist_base make_save_contents
  end
  def self.make_save_contents
    contents = make_save_contents_tablelist_base
    contents[:npcs] = $npcs
    contents[:cards] = $cards
    contents[:guildloot] = $guildloot
    contents[:dailysearch] = $dailysearch
    contents[:ingredients] = $ingredients
    contents
  end
  #--------------------------------------------------------------------------
  # * Extract Save Contents
  #--------------------------------------------------------------------------
  class << self
    alias extract_save_contents_tablelist_base extract_save_contents
  end
  def self.extract_save_contents(contents)
    extract_save_contents_tablelist_base(contents)
    $npcs = contents[:npcs]
    $cards = contents[:cards]
    $guildloot = contents[:guildloot]
    $dailysearch = contents[:dailysearch]
    $ingredients = contents[:ingredients]
  end

end

This lets me have unlimited "global variables" to use throughout the game, primarily for huge lists of data that I wanted to be easily organized and modifiable, i.e. not using the editor's $game_variables interface.

As I didn't want to include extraneous information and complicate what we were working on, I left this out of my earlier reply. I suppose it wasn't irrelevant after all. So, where I previously said I was using $game_variables[80], I actually just reference the npc location in my hash with $npcs[:npc45_loc]. Does this change things? >.>
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
Yes, but it doesn't change much. So if you look at the code I posted, specifically at this section:
Code:
def self.update_all()
    @@locations.each_key do |key|
        loc_id = $game_variables[ @@npc_game_vars[key] ]
        loc_map = load_data(sprintf("Data/Map%03d.rvdata2", loc_id))
        loc_name = loc_map.display_name
        NPC_Locations[key] = loc_name
    end
  end

It should look pretty familiar. The key difference is this "update_all" method runs once each time the quest scene is opened, and loops through all of the provided "keys". So we change one line:
Code:
def self.update_all()
    @@locations.each_key do |key|
        loc_id = $npcs[key] #### <<<< This one
        loc_map = load_data(sprintf("Data/Map%03d.rvdata2", loc_id))
        loc_name = loc_map.display_name
        NPC_Locations[key] = loc_name
    end
  end
and we make sure that the 'keys' all match. That is, use ":npc45_loc" for the $npcs hash and the @@locations hash. You can also just get rid of the
@@npc_game_vars hash.
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Awesome!

Now that that's fixed, what about this part of your code where we access the quest journal?

Code:
  # To then make the quest journal reference our npcs
  # we use the following:
  # q[:location] = NPC_Locations[:npc45]
  # Obviously, replace :npc45 with whatever npc key you need
How does this specify which quest I'm adding the location to? Or am I not understanding something?
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
That's an example of line 792. Whereas before you used
Code:
q[:location] = "#{@npc45_loc}"
now you'll use
Code:
q[:location] = NPC_Locations[:npc45_loc]
Again, just make sure the "key" you use is consistent across all the hashes (where the key is the ":npc45_loc" bit)
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Right, I remember that. But, I'm referring to which quest in the journal we're accessing, as each journal entry has a
Code:
q[:location] =
At line 778 in the quest script, it says "when 1 #sample quest". So for "when 2" or any further entry, there will be a q[:location] for each of those.
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
I guess I don't quite understand the question, but I'll try to explain what I'm doing better so maybe that will clear things up.

First, I'm assuming that you already have a list of NPCs that give quests. This list lives in your "$npcs" hash. The hash contains a bunch of "keys", which are the identifiers for the NPCs. If I wrote:
Code:
$npcs.each_key { |key|
  print key
}
I would get a list that looks something like this:
:npc1
:npc2
:npc3
etc.
If I'm wrong about that, please correct me.

Second, I'm assuming that you already have some quests built. The first (1) quest lives under line 778 in the quest script where it says "when 1". The second (2) quest lives further down in the quest script where it says "when 2". The third (3) quest lives even further down in the quest script where it says "when 3". And so on and so forth. Each of these quests has a line that looks like:
Code:
q[:location] =
Then it's as simple as matching the NPC's key to the quest. Assuming NPC1 goes with quest 1, the code would look something like this:
Code:
when 1 # Quest 1 - SAMPLE QUEST
  ...
  q[:location] = NPC_Locations[:npc1]
  ...
when 2 # Quest 2
  ...
  q[:location] = NPC_Locations[:npc2]
  ...
when 3 # Quest 3
  ...
  q[:location] = NPC_Locations[:npc3]
  ...
Sorry if that's still not clear. Hopefully it is, but if it isn't, just let me know.
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
I just now realized that what I was seeing in your code was hashed out, and you were referring to the quest script.
Code:
  # To then make the quest journal reference our npcs
  # we use the following:
  # q[:location] = NPC_Locations[:npc45]
  # Obviously, replace :npc45 with whatever npc key you need
I thought we were accessing the quest script with this. Sorry. My fault!

Next, I get an error in your code saying MA_start (found at the bottom) is an uninitialized constant.
 
Last edited:

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
No worries! This stuff can get confusing. I'm glad you figured it out.

Next, I get an error in your code saying MA_start (found at the bottom) is an uninitialized constant.
That's my bad. I sometimes forget some of Ruby's rules. Just change every instance of "MA_start" to "ma_start" (there should be two).
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Oh, good! That's fixed.

How would I go about checking if the map id is 0? Because 1) sometimes an NPC's location id can be set to 0, in which case I would like to display "Unavailable" instead of a map display name, and 2) I'll get an error message if the game tries to load map data for map 0.
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
Just before loading the map data we can check for that, and if it is zero, we can substitute "unavailable" instead. So we modify the "update_all" method again:
Code:
def self.update_all()
   @@locations.each_key do |key|
       loc_id = $npcs[key]
       if loc_id == 0
           loc_name = "Unavailable"
       else
           loc_map = load_data(sprintf("Data/Map%03d.rvdata2", loc_id))
           loc_name = loc_map.display_name
       end       
       NPC_Locations[key] = loc_name
   end
end
 

AeghtyAteKees

Nyctopheliac
Veteran
Joined
May 8, 2013
Messages
33
Reaction score
2
Primarily Uses
Great.

I now get no errors, but no location is displayed in the journal. I believe the journal script is set up so that if no location is specified, it leaves that line out of the window. So either the location isn't being set right, or the journal can't tell it's there.
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
Hmmm.... If you're alright with it, would you mind PM-ing me a link to download your project? At this point, I'm out of ideas on what it could be, and it'll be faster to just directly troubleshoot it.
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
383
Reaction score
91
First Language
English
Primarily Uses
Ok, it was just a simple ordering problem. First, you need to put my code below the quest journal in the script editor. Then you need to swap two lines on my code; update it to look like this:
Code:
class Scene_Quest < Scene_MenuBase
  # Create an alias for the old method so we can call it
  alias ma_start start
  # Add our code to the scene start method
  def start
    # Call our update code
    NPC_Locations.update_all()  #<< Swap these
    # Call the original method
    ma_start                               #<< two lines
  end
end
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

so hopefully tomorrow i get to go home from the hospital i've been here for 5 days already and it's driving me mad. I miss my family like crazy but at least I get to use my own toiletries and my own clothes. My mom is coming to visit soon i can't wait to see her cause i miss her the most. :kaojoy:
Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD

Forum statistics

Threads
105,868
Messages
1,017,074
Members
137,578
Latest member
JamesLightning
Top