Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

how could I modify a hash trough script calls???

I created a hash like this one:

Code:
Suspects =
 {
  Person 1 => {Age => Job},
  Person 2 => {Age => Job},
  Person 3 => {Age => Job}
 }
How could I add more keys to this hash per script calls? How could I change the age or the job value? What should I do in order to display every single value in this hash on different parts of window and not just like a single string?

I would like to see something like this:

Window 1
  Person 1 (or 2 or 3)

Window 2
  Age

Window 3
  Job
 

khmp

Sponsor

Can the person have only one age and one job? If that's a yes, just let the person be a key and have that key reference an array.

Code:
Suspects = 
{
  Person1 => [Age, Job],
}

Now because its capitalized I'm assuming it's a Constant and if that's the case if you want to add items to that hash during run time you're going to need to copy the data in that hash to another source that's dynamic. Like a global or something and just use the Constant as a starting point.

From now on to answer the rest of the questions I'm going to assume you have a global called 'suspects'.

Copying the data over:
Code:
$suspects = Hash.new(Suspects)

Adding an item:
Code:
$suspects.store(Person2, [Age, Job])
# or
$suspects[Person2] = [Age, Job]

Let's say you want to iterate through your hash:
Code:
age, job = 0, 1 # Just an intuitive way to index suspect's data.

$suspects.each do |person, data|
  p person                # Prints the person's name.
  p data[age]             # Prints the person's age.
  p data[job]             # Prints the person's job.
end

If you want to keep it the current way as a hash referencing a hash.
Code:
age, job = 0, 1 # Just an intuitive way to index suspect's data.

$suspects.each do |person, data|
  p person                # Prints the person's name.
  d = data.shift          # Get the first element as an array.
  p d[age]                # Prints the person's age.
  p d[job]                # Prints the person's job.
end
 
well, yes, of course. I mean, I would like to include new keys in game so this sort of detective guy may be able to find any new suspects.
i.e.
an event includes a script call that would add a 4th suspect
Person 4 => {Age => Job}
it should be always the same thing
of course I know I should create an array or something like that so it's possible to show the age and the job of the suspects
Age = [20, 22, 30, 50]
Job = ['Technician', 'Scientist', 'Senior Executive', 'Teacher']

Person 4 => {30 => 'Technician'}
 
I see you used p to print it, but how could I show that in a default rmxp window not a Windows window?
I know I can set it up like this self.contents.draw_text(x, y, width, height, text, align) but how do I force the game to display every single element in this hash in different parts of a window or on different windows?

i.e.

height = 32
self.contents.draw_text(0, 0, self.width - 32, height, Suspect's name only, align)
self.contents.draw_text(64, 32, self.width - 32, height, Age only, align)
self.contents.draw_text(128, 64, self.width - 32, height, Job only, align)

Would the following code work if found inside a window script?

$suspects.each do |person, age, job|
  #p person                # Prints the person's name.
  self.contents.draw_text(0, 0, self.width - 32, height, person, align)
end
 
I still have another question...

I also noticed that the game will always show the keys I created even if I saved the game and went to the title screen to start playing a new game... The only way I've found that may not let you get keys you didn't collect yet was to shut down and reopen the game... It doesn't seem to be really effective if you need to shut down first. What could I do now?
 

khmp

Sponsor

Ok I assume you have a scene for all this stuff to go into and a custom window to display this information.

Code:
@windows = Array.new
$suspects.each do |suspect_name, data|
  # Inside this windows initialize save the data that will be drawn to it.
  @windows << Window_Whatever.new(suspect_name, data)
  # Move the window so it doesn't overlap.
  @windows[@windows.size - 1].x = 20
  @windows[@windows.size - 1].y = (@windows.size - 1) * @windows[@windows.size - 1].height
end

You'll need something like that, if you want every suspect to have their own window. The setting of @x and y is just something I came up with. The placement of the windows is up to you.

Next Question:
This deals with filtering of the hash. You may want to include a piece of data within the original hash that determines whether the object is available or hidden. A boolean would be great for this. I'll continue the example from my previous idea of an array within a hash.

Code:
Suspects = 
{
  Person1 => [Age, Job, true],
  Person2 => [Age, Job, false],
}

$suspects = Hash.new(Suspects)

age, job, open = 0, 1, 2 # Just an intuitive way to index suspect's data.

$suspects.each do |person, data|
  if data[open]
    p person                # Prints the person's name.
    p data[age]             # Prints the person's age.
    p data[job]             # Prints the person's job.
  end
end

One last thing. The method "each" for a hash requires two symbols. One to represent the key the other will represent the value which is pointed to by the key. You can't do three symbols. You have to parse through the value on your own which requires knowledge of what object it will be. The code you have below is wrong:
Code:
$suspects.each do |person, age, job|
  #p person                # Prints the person's name.
  self.contents.draw_text(0, 0, self.width - 32, height, person, align)
end
Correct Example:
Code:
Hash.each do |key, value|

end
 
Thanks, khmp. That may help me even if I could already force the game to display it (it's still look like garbage since I forgot to setup a few things he he he). I guess I still need to take a look at how a window becomes a selectable one without causing so much troubles he he.

But there's still the "phantom key" problem that allows the player to see the keys collected in a previously saved game while you started a new game...
 

khmp

Sponsor

Um don't you want to see the suspects you collected when loading a save game in which you already found the suspects in question.

Player starts new game.
Suspect1 is available, Suspect2 is hidden.
Player discovers Suspect2, Suspect2 is available.
Player saves game.
Player quits.

Player loads save game.
Suspect1 is available, Suspect2 is available

Is that what you are describing?
 
I created 3 keys through script calls. I'm using the $suspects = Hash.new(Suspects) method you described earlier.
The hero or the detective in this case collected 3 keys or suspects. I went to an event and he printed 3 keys on a normal window, not a rgss window. I opened the respective scene and it showed the same 3 keys. Till now I would say it works fine, but I saved the game to check what happened if I started a new game.

I don't want to play the saved game so I choose to start a new game instead.

I haven't found any suspects yet (no keys) but if I talk to an event that should print the hash even if it's empty, it still shows the 3 keys I collected in my saved game, which isn't the one I'm playing now but a whole new game.

The detective didn't find any suspects yet. Even so I visited the event that prints the hash on a normal window, not on a rgss window. He printed all the 3 keys, but I haven't added them to the hash, yet.

Why does that event still remember I had 3 keys?
 

khmp

Sponsor

Ok I see now. The problem is that $suspects isn't being reset. Because its a global is has scope till the program is terminated. By the same token nor is it being saved.

Code:
class Game_System
  attr_accessor :suspects
  alias_method :shbl_suspects_initialize, :initialize
  def initialize
    shbl_suspects_initialize
    suspects = Hash.new
  end
end

It'll require that you change your code to reflect that "suspects" is now inside "$game_system".
 
eh, well, yes, it's true, it wasn't saved. Now I already saved the info with Marshal.dump and loaded it with Marshal.load

Actually I preferred the clear method, I mean, to enter $suspects.clear inside a script. I wanted to make sure there was no need to create the hashes I needed inside Game_System and it was possible actually. I discovered I just needed to alias the command_new_game method in Scene_Title, there I included the clear method ($suspects.clear).
Now I won't find any hash keys if I talk to the event that would print them on screen.

By the way, the hashes are inside a module, Suspects module he he he. It's quite useful.

Thanks for reading my posts.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top