How do I display parameters to create a custom status menu?

Status
Not open for further replies.

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
Hi all.

I'm using Sixth's wonderful biographies script ( https://forums.rpgmakerweb.com/inde...-scene-morality-system-v1-3-22-01-2015.36046/ ) for VX Ace.

I would like it to replace the default status screen so I am attempting to replace manually-inputted fields (Age, height, weight, gender) with the actors' stats.

The lines in question are from line 983 onward, with the inputted text between the speech marks. I'm guessing that I simply replace the text with the relevant command to display an actor's ATK/DEF, etc. stat but I can't find what that would be.

Can anyone help?
 

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
Alternatively, having cast around yet again on Google, if no specific stat recall command exists, I could use (a lot of) variables tied into an actor's stats and then have the script display those instead.

The only problem being that I don't know how to get menus to display variables.

I've mocked up a screenshot if that helps. I've changed the labels no problem. It's the numbers I need help with.
 

Attachments

  • Screenshot of profile.png
    Screenshot of profile.png
    341.8 KB · Views: 10

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
UPDATE:

Okay, so I've cast around again and I can't find anything that really deals with this so it's clearly more complex than I originally thought. But what I have found are the script commands for displaying specific stats within a status menu:

def draw_parameters(x, y)
draw_actor_param(@actor, x, y + line_height * 0, 2)
draw_actor_param(@actor, x, y + line_height * 1, 3)
end

…which came from

https://steamcommunity.com/app/220700/discussions/0/598199244885842016/

So I'm thinking that if I remove the categories that come as part of the text, I can replace them with these (and alter the x and y properties to position them correctly). The only thing is that it writes out the name of the parameter, but that's not a problem if I'm using it to replace the biography fields, and I'm sure the font can be altered so it matches with the rest, right?

Removing the existing fields was easy: I just gave them large negative x values to move them off the screen. Now it should be a case of adding additional code near the bottom of the script to add the relevant parameters... I'm guessing.

Now here's where it gets murky, because I don't know scripting, but I do know how to cut and paste. So I went into the Window_status script and found these:

def draw_block3(y)
draw_parameters(32, y)
draw_equipments(288, y)
end

def draw_parameters(x, y)
6.times {|i| draw_actor_param(@actor, x, y + line_height * i, i + 2) }
end

I'm assuming (and please correct me if I'm wrong) that the first part tells it what to put in the default status box and the second part tells it how to do it.

Anyway, I copied those into Sixth's script (removing the part about drawing equipment) and it came up with the attached error.

Given that the code was copied directly from the game's default script, I can't see how it's a fault with the wording. My assumption is that the term line_height needs defining, but I can't see anything like that in the default script.

Surely this can't be that hard, right? Can anyone help?
 

Attachments

  • Script error.png
    Script error.png
    23.5 KB · Views: 0

Traverse

Veteran
Veteran
Joined
Jul 3, 2014
Messages
163
Reaction score
104
First Language
English
Primarily Uses
You put that in the wrong place. Sort of.

Well, you tried. To be fair, knowing where exactly to insert changes DOES require you to know how to read the code and be able to work out how the script itself is doing things. It's arguably half or more of learning how to script because even if you knew Ruby and all the syntax you would still need to read through the default codebase in the engine to know where to insert any additional features you wanted to code.

And when you are trying to modify someone else's script, you then need to read through their stuff and work out how it interacts with the default codebase. Depending on how big and messily it was coded, it CAN be that hard.

But anyway.

That code you copied is only meant to work within the Window_Status class, which isn't being used or modified by Sixth's script. Sixth's script instead uses some custom Window subclasses called Bio_Info and Bio_Bio that do not contain... well, a lot of the stuff that snippet you copied would need to work.

And from the error message, it seems you inserted it somewhere in Scene_SBio. If there was anywhere you would have needed to insert that code, it would have been in Bio_Bio. But it wouldn't have worked anyway - it's not Window_Status, it doesn't contain or call any Method called "draw_block3()" and if you tried to force it to run, you'd get a whole bunch of errors because stuff like "@actor" and "draw_equipments" don't exist within it anyway. It is a Window subclass so it does contain "line_height" and "draw_actor_param()" but doesn't have the stuff specific to Window_Status.

The way the default engine is structured that you have the Scene_ classes, which represent the different types of screens the player is shown. Scene_Title is the title screen, Scene_Battle is the battle screen, Scene_Map is the map, Scene_Menu the main menu, etc, etc. And within those screens, whenever some window that uses the windowskin is drawn, it's done by a separate piece of code labelled Window_something.

These Window_xxx classes are all subclasses built from the superclass named Window, which isn't actually visible in the script editor. It's one of the bits of code hidden in the RGSS3 dll and you need to check the help file to see what it does and what Methods are in it. The main thing that Window does is chop up the windowskin graphic file and arrange the pieces so it actually looks like a message window. The subclasses and sub-subclasses like Window_Selectable and Window_Command then add extra functionality like selectable buttons. Or are made to draw specific things. They can be as big as the whole screen like Window_Status, which draws all the parameter text. Or very small and only used for one thing one thing, like Window_Gold (which you know, just draws the party gold).

Sixth's script does the same thing, basically. He made a new Scene called Scene_SBio (and modified Scene_Menu's Window_MenuCommand to add a new button to open the Biography Menu) and a bunch of Window subclasses to contain all the text and faces and pictures and whatever.... except he didn't name them Window_xxx, he named them "Bio_Title" and "Bio_Info" and "Bio_Bio". You can still tell they're Window subclasses though, because they obviously show the windowskin and their superclass is Window_Base, a subclass of Window.

Now, where does all the text and data that they draw actually come from? Sometimes it's specified in the code of the window itself, other times it refers to other bits of code for it.

The stuff in the Biography Menu windows not specified in those windows themselves, they take it from the thing present at the top of the script - a Module called Sixth_Actor_Bio.

The contents of this Module are the "settings" that the user of the script is instructed to change in order to customize the script.

Unfortunately, that also means that this idea:
I'm guessing that I simply replace the text with the relevant command to display an actor's ATK/DEF, etc. stat but I can't find what that would be.
Will not work.

Irrespective of which slot they are placed in the script editor, Modules all get loaded before any of the classes (including Scene classes, so before you even see the title screen of the game). But the data you want to display - party member parameters - is all located within a class called Game_Party (or to be precise, an instance of the class that is located in a variable called "$game_party") and at the time when all the stuff in Sixth_Actor_Bio is being set up, Game_Party has not yet been created. Your party literally does not exist when the settings for the script are being processed.

Thus trying to directly refer to "$game_party.members[0].atk" or anything similar in the script settings will just get you an error message.

If you want the windows in that menu to display that stuff, you will need to modify them to directly refer to the data in $game_party instead of reading the settings in Sixth_Actor_Bio. For reference, the individual party members within $game_party are Game_Actor objects.

Judging from your mockup, the window you want to modify is Bio_Bio. You can look at how Window_Status does it to get some idea of how parameter text is drawn and what to do.

Bio_Bio obviously does not do things quite the same way - for example, whereas Window_Status is given the actor that was selected by the player back in Scene_Menu and jumps directly to their page upon opening, the Biography Menu only ever starts on the party leader's page and its windows are hardcoded to initialize with the settings corresponding to the party leader. It will actually crash if you try to open it with zero party members/no leader (meanwhile Scene_Menu just greys out the Status option entirely if you have no members).

That said, the important thing to note is that, at the end of the day, all drawing of text in a window is ultimately done through a Method called "draw_text()" which all window classes inherit all the way down from the hidden Window superclass*. As long as you keep that in mind, you'll be able to force it to show something or other by playing around with it.

*EDIT: To be more precise, it's from the hidden Bitmap class, not Window. One of the things Window does is to create an instance of Bitmap called "contents", on which everything in the window (text, icons, gauges, etc) is drawn, usually by one of 3 Methods - either "draw_text()", "blt()" or "fill_rect()" or more rarely one of the variants of "blt()" and "fill_rect()" like "gradient_fill_rect()" in the case of some gauges.
 
Last edited:

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
I feel very small and primitive.

I'm going to need to read this a few more times. But from what you're saying, it SHOULD be possible, just not by using the code from the Window_Status script because Sixth's script has nothing to do with it and so it won't work because it uses methods and terms that are not defined by Sixth's script. All of the information on the bio_bio window is generated within the script itself. But surely the data from the second window (the HP, TP and MP values) are being drawn from the game data? If I can see how that window does it, the bio_bio window could be made to do the same/something similar?

I've done lots of Googling about how to create status menus and I've found how to reorder/omit stats within the Window_Status script but literally NOTHING on how to recall the game data and display it in a menu. This is also not helped by this being my first foray into RGSS and don't know the individual commands. But if I Google RGSS3 dll, that should help, right?

Thank you very, very much indeed for that epic, detailed reply. I feel smarter just by being in the same topic thread as you!
 

Traverse

Veteran
Veteran
Joined
Jul 3, 2014
Messages
163
Reaction score
104
First Language
English
Primarily Uses
All of the information on the bio_bio window is generated within the script itself. But surely the data from the second window (the HP, TP and MP values) are being drawn from the game data? If I can see how that window does it, the bio_bio window could be made to do the same/something similar?
Basically, yes.

If you check how the second window (Bio_Info) does it, you will see this:
Ruby:
class Bio_Info < Window_Base
  include Sixth_Actor_Bio

  def initialize
    pos = Window_Setup[:info][:pos]
    size = Window_Setup[:info][:size]
    super(pos[0],pos[1],size[0],size[1])
    self.windowskin = Cache.system(Window_Setup[:info][:skin])
    self.opacity = Window_Setup[:info][:opacity]
    refresh($game_party.members[0])
  end

  def refresh(actor)
    contents.clear
    xp = actor.get_xp_info
    xc1 = get_color_sixth(Font_Setup[:xp_bar][:gcolor][0])
    xc2 = get_color_sixth(Font_Setup[:xp_bar][:gcolor][1])
    draw_bio_pic(actor) if Show_Data.include?(:pic)
    draw_bio_info_i(actor,:state)
    draw_bio_info_g(:hp_bar,actor.hp,actor.mhp,actor.hp_rate,
                    hp_gauge_color1,hp_gauge_color2,hp_color(actor),normal_color)
    draw_bio_info_g(:mp_bar,actor.mp,actor.mmp,actor.mp_rate,
                    mp_gauge_color1,mp_gauge_color2,mp_color(actor),normal_color)
...
...
The "initialize" method is the first method called automatically when an instance of a class is created.

You can see where it calls its "refresh()" Method, that's where the window is checking your $game_party for the actor data. The argument passed to it has been hardcoded to be $game_party.members[0], or in other words the first member/party leader.

What about the other actors in your party? Well, the way he's done it, he's set up Scene_SBio to detect button input so that when the player presses the button to flip pages, Scene_SBio manually calls "refresh()" for all its windows - except this time instead of $game_party.members[0] the argument passed into it is the next actor up on the list (i.e. "@info.refresh($game_party.members[@current])" with "@current" being a variable that increments if you press the button for the next page or decrements if you press the button for the previous page). Which is also different from how Window_Status handles it, since in Window_Status the input detection code is handled in the window itself, not from Scene_Status.

The methods where it does the actual drawing like "draw_bio_info_g" you can see where it boils down to "draw_text()":
Ruby:
  def draw_bio_info_g(sym,d1,d2,rate,c1,c2,c3,c4)
    return unless Show_Data.include?(sym)
    i = InfoPos_Setup[sym]
    draw_gauge(i[:pos][0],i[:pos][1],i[:size][0],rate,c1,c2)
    xi1 = i[:pos][0]+i[:offset][0]
    xi2 = i[:pos][0]
    yi = i[:pos][1]+i[:offset][1]
    change_the_font(Font_Setup[sym][:type],Font_Setup[sym][:size])
    change_color(get_color_sixth(Font_Setup[sym][:color][0]))
    draw_text(xi1,yi,i[:size][0],i[:size][1],Text_Setup[sym],i[:align][0])
    draw_current_and_max_values(xi2,yi,i[:size][0],d1,d2,c3,c4)
  end
The format it takes is "draw_text(x, y, width, height, text, alignment)". Alignment is an optional argument, it defaults to 0 (left-aligned) if nothing is given.

The other lines you see before it are just for setting up the font and calculating x and y position to draw the text at. If you look at "draw_current_and_max_values()", which comes from Window_Base, you'll see it ends up calling draw_text() a bunch of times too.
 
Last edited:

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
So draw_text is the basic command and anything else like draw_actor_parameters is a method that is utilising it (albeit through a sequence of other defined methods?)

Would it be possible to take those sections of code that you highlighted above, copy them into the bio_bio window, fart about with them a bit so that they draw a number and not a bar and change it so that they are linked to actor stats like attack, defense, and so on?

Thank you so, so much for your efforts to explain what is actually happening in the script. Like I said, I am very new to RGSS or indeed any kind of programming language so this is making my head spin a little but I've learned so much just from your explanations. I managed to figure a little bit out for myself, like having to define the processes so the script knew what I was talking about, but there is so much more to this than I was ever going to get just by fiddling with it by myself. I feel like I understand maybe 60% of what you've said right now so I'm going to have to pick over it a few more times.
 

Roninator2

Gamer
Veteran
Joined
May 22, 2016
Messages
2,822
Reaction score
623
First Language
English
Primarily Uses
RMVXA
So draw_text is the basic command and anything else like draw_actor_parameters is a method that is utilising it (albeit through a sequence of other defined methods?)

Would it be possible to take those sections of code that you highlighted above, copy them into the bio_bio window, fart about with them a bit so that they draw a number and not a bar and change it so that they are linked to actor stats like attack, defense, and so on?
What traverse said is very good. I normally don't read through so much text but this was good for me too.
I was able to use part of that info and make a change which worked.
Then I noticed that the information Traverse was giving was totally spot on.

When you look at Bio_Bio class and inside is the refresh method.
There is the call to draw_bio_info
Which has two parameters supplied to the method call.
The first is the reference to the associated name of the data, (age, written as :age => "Age") under text_setup.
The second goes to the Actor_Info_Setup and pulls the associated data that is referenced for the actor id.
So knowing that we want the text "Age" to show up, or "Attack" (because you changed it), then we just need to make the second part point to the reference actor data.
As Traverse pointed out the class does not make reference to actors.
So then we would add that in.
That's where it becomes unsure, how do we make reference to the actor.
Well there is in the initialize section a reference to $game_party.members[0]
Well that's certainly the actor, but we can't use that in the refresh as it would always use actor 0 for the data. But Initialize is where data for the whole class is made. and not generally (that I have ever seen) called again.
So if we were to put the reference to the actor into a variable we should be able to make reference to it.
Normally local variables (without a $ or @) only exist in the method they are created. If the variable is to be used throughout the class then a Instance variable is preferred. ( @ )
Now we can also see that in the initialize, refresh is called, so we must put our reference to the actor before this.
@(whatever name you wish to use) = $game_party.members[0]

I completely missed the fact that...
The refresh method already has actor referenced.
def refresh(actor,page)
so...
Then in the draw_bio_info we can substitute the Actor_Info_Setup part for the actor data.
actor.atk
actor.def
actor.agi
actor.luk

Then it will pass that onto the method draw_bio_info which is in Window_Base
Looking in that method you can see it does a draw_text and all the positional data is already configured in the script for that field i.e. :age, etc

And as Traverse stated the script does well in updating the reference actor id. So here you don't have to worry about it always showing actor 0 data.

Now when making changes it is always best to make a new script entry under the script you are changing and put the code you will need in there.

Since we are making changes to initialize where the change is before the end of the method and after the beginning, we need to copy the entire method and make our changes in the new script.
Also the same for refresh.
 
Last edited:

Traverse

Veteran
Veteran
Joined
Jul 3, 2014
Messages
163
Reaction score
104
First Language
English
Primarily Uses
Would it be possible to take those sections of code that you highlighted above, copy them into the bio_bio window, fart about with them a bit so that they draw a number and not a bar and change it so that they are linked to actor stats like attack, defense, and so on?
You could, but there's no need. The script already provides a Method that draws just text/numbers without any bars (or you could also just use the basic "draw_text()" directly too). That Method is named "draw_bio_info()":
Ruby:
  def draw_bio_info(sym,data=nil,pos2=nil)
    return unless Show_Data.include?(sym)
    change_the_font(Font_Setup[sym][:type],Font_Setup[sym][:size])
    change_color(get_color_sixth(Font_Setup[sym][:color][0]))
    i = InfoPos_Setup[sym]
    draw_text(i[:pos][0],i[:pos][1],i[:size][0],i[:size][1],Text_Setup[sym],i[:align][0])
    if !data.nil?
      change_color(get_color_sixth(Font_Setup[sym][:color][1]))
      if !pos2.nil?
        draw_text(pos2[0],pos2[1],i[:size][0],i[:size][1],data,i[:align][1])
      else
        draw_text(i[:pos][0],i[:pos][1],i[:size][0],i[:size][1],data,i[:align][1])
      end
    end
  end
Sixth modified the default Window_Base class to add this additional Method, which he then uses in all of his subwindows.

If you check Bio_Bio's refresh() Method, you'll see this is the very one used there to draw the age/height/etc text. If you keep reading Bio_Info's refresh() method (further down past the bit I quoted) you will see it also uses it to draw the actor's name, class, nickname, etc.

In all the times Bio_Bio calls it, it never gets passed any information from actor itself, it just looks at the fixed settings in Sixth_Actor_Bio that correspond to the database ID of the actor - i.e. "Actor_Info_Setup[actor.id][:age]".

But it CAN take values directly from the actor. Bio_Info actually uses it that way:
Ruby:
def refresh(actor)
...
...
    draw_bio_info(:name,actor.name)
    draw_bio_info(:class,actor.class.name)
    draw_bio_info(:level,actor.level,InfoPos_Setup[:level][:pos2])
    draw_bio_info(:nickname,actor.nickname)
end
As you can see, it's pulling the name, nickname, level and class name text directly from the actor. The first argument (":name", ":nickname", ":class", etc.) is there to check the corresponding font and display position settings specified in Sixth_Actor_Bio.

But the second argument is the text data. When you look at how the method has been coded, you can see the second argument is the one eventually passed onto the basic "draw_text()" as the text to be printed. So if you change "actor.nickname" to "actor.atk", you will see it draw the actor's ATK value instead of its nickname (you can check Game_Actor and it's superclasses Game_Battler and Game_BattlerBase for all the data and values an actor contains, the parameter abbreviations are all listed in Game_BattlerBase).

IMO, the "cleanest" way to alter the script would probably be to modify the "draw_bio_info()" calls in Bio_Bio's refresh() method to use the actor parameters instead of looking at the script settings.

Or else just replace them with calls to the basic "draw_text()" using the actor parameters as the text.
 

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
You, my good sirs, are ruddy legends!

It has definitely helped reading this again at 10 in the morning rather than 8 at night. I am now almost certain I know what you are talking about. I'm going to have a tinker later on and let you know how it goes.
 

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
kaPOOOOOOOWWWWWWWW!!!

GOT IT!

Works a charm now, as you can see from the screenshot. Plus, I can confirm that the stats are accurate for each actor. It turns out that it was just a minor tweak to four lines of code (in the script screenshot), so it was deceptively simple. It would have been so much easier for you to just tell me what to put but, as it says on a poster in my kids' nursery, "if you do it for me, all I learn is that you can do it better than me." I have learned so much about how this all works and fits together. Thank you very much for taking the time to teach me that.

I know I should just quit while I'm ahead but... what if I wanted to put some of the manual text fields back in addition to the stats (i.e. fields that display weapon type, elemental affinity and stat flaws). These would be constant and specific to each actor, so would be perfectly well handled by the unmodified script. I could use the commands that Sixth wrote originally, but would just need to create more of them.

Presumably, I would need to put extra lines into the bio_bio refresh method, but would also need to add the relevant settings to the module as well, which I could copy and paste.

Going to try it. *game explodes, probably*

Regardless, consider yourself well and truly credited. Expect to see yourself under "technical support" or some such in about 19 years when I finally finish the whole project!
 

Attachments

  • Screenshot of profile 2.png
    Screenshot of profile 2.png
    353.6 KB · Views: 6
  • Screenshot of script.png
    Screenshot of script.png
    109.3 KB · Views: 7

FourthDimension

Villager
Member
Joined
Mar 31, 2019
Messages
14
Reaction score
1
First Language
English
Primarily Uses
RMVXA
Bosh!

Aside from a little bit of repositioning/reformatting, here is the finished result!
 

Attachments

  • Finished status screen.png
    Finished status screen.png
    356.7 KB · Views: 8

slimmmeiske2

Little Red Riding Hood
Global Mod
Joined
Sep 6, 2012
Messages
8,033
Reaction score
5,334
First Language
Dutch
Primarily Uses
RMXP

@FourthDimension , please avoid double posting, as it is against the forum rules. You can use the "Edit" function on your posts to add additional information you've forgotten or respond to multiple people. You can review our forum rules here. Thank you.


If your querry is solved, please report this post and we'll close the thread.

Edit:

This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.

 
Last edited:
Status
Not open for further replies.

Latest Threads

Latest Posts

Latest Profile Posts

I'm moving on from RMXP finally. I've been stuck in a difficult decision between XP and MZ, and I've given up and moved on to MZ. Overall I'm really liking it, I wish tilesets were easier to setup like XP, but it's actually not that bad!
Have you ever gone full 'Ship of Theseus' while frankenspriting? Because I just did.
I saw my new eye doctor today, he reminds me of Satoru Iwata for some reason
I've been using a modified version of a script called Multiple Messages. It makes my text boxes look like a Mario & Luigi game! There is something about it that bothers me a little bit, but I shouldn't worry about that now.

Side note, Mist's walking animation is almost perfectly in sync with Loose Yourself by Eminem.
Starting work on some stuff for the community. Hopefully it will be fun, and useful to somebody.

Forum statistics

Threads
107,773
Messages
1,032,038
Members
139,915
Latest member
nick7626
Top