Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0
Foxkit

Passing information from script to script.

Question

I'm interested in how windows toss information around within scenes, examples of places are in the default Scene_Menu, when you pick skills, equip, or status, you pick a party member and that info is passed on using .index. I'm just curios as to how the called scenes receive this information if they set the index to 0 in the initialize portion of the script. Also, how does Scene_Equip toss info between Window_EquipLeft, Window_EquipRight, and Window_EquipItem. If you hover over a different Item in Window_EquipItem it displays the updated information in Window_EquipLeft. I don't see any specific passing of information besides a small section around line 80 and line 102 of Scene_Equip, and beyond that I'm still extremely fuzzy.

Share this post


Link to post
Share on other sites

5 answers to this question

Recommended Posts

  • 0

Actually, there are two parts in the answer.

 

First, you're wondering about how a scene can access its windows' parameters. It's pretty easy actually. Each object can have some of its variables accessible by other objects using the attr_reader and attr_accessor tags (specifically, they automatically create a method which returns the desired variable, so it may be called like any other methods). The difference is that attr_accessor additionally creates a method to assign values to said variable, which makes it possible for other objects to change the variable's content. Thus, to call for those variables, you just need to have the object's reference - well then, since a scene creates all windows on its own, it just has to keep track of them by holding their reference in a variable. That's the reason why the Window_Xxxxxx.new statements are assigned to variables, so that the scene can still work with them later.

 

Second, you asked how two windows from a same scene may access each other's parameters. That's a little trickier, but obvious if you understand how a scene accesses its windows. In the equip scene, the help window displays details about the currently selected item. Since neither window know of the other's reference, you could use the scene, which know both, to update info in the help window according to the item window's contents. This would sound like:

Get item window's selected weapon
Get weapon's description
Send weapon's description to the help window

However that's not how it's done in RMXP, because the help window's contents needs not be updated each frame, only when the item window's index changes. Thus, we would like the item window to control the help window's contents. To do this, we have no choice, we must tell the item window the reference to the help window. And the object which does that must know both references, that's why we'll have the scene do it: If you search the Scene_Equip's code, you shall find something like:

@item_window.help_window = @help_window

Which in turn allows Window_EquipItem objects to use:

@help_window.set_text(<weapon's description>)

 

I'm just curios as to how the called scenes receive this information if they set the index to 0 in the initialize portion of the script.

Well, it's just initializing the window's index, as could the window itself using:

def initialize
 self.index = 0
 ...
end

Then the window manages its index on its own (using code from their Window_Selectable superclass, which mostly deals with changing index when arrow keys are pressed), and when the scene accesses that index again, it gets its current state.

 

Hope this all makes sense.

Share this post


Link to post
Share on other sites
  • 0

I think it does... so then, could I do something like this using Window_EquipItem() ?

 

Class Window_EquipmentStats < Window_Base
def initialize(id)
super(0, 244, 272, 192)
self.contents = Bitmap.net(width - 32, height - 32)
@item = Window_EquipItem.Item
case @item
when RPG::Weapon
 draw_parameter = draw_weapon_parameter()
when RPG::Armor
 draw_parameter = draw_armor_parameter()
end
@id = id
refresh
end

 

It sounds a lot like some meta programing is going on. So I belive I'm understanding it, but I'm not too sure.

Share this post


Link to post
Share on other sites
  • 0

Actually, Lines 80-102 are close to what you are looking for, 73-117 would be everything.

 

The code you have there will not work, because you are trying to get the "item" attribute from the class rather than the instance of the Window in question. The class doesn't know anything about the selected item of any instance of that class.

 

As per RPG Maker engine architecture, generally a scene creates and manages all objects required for that scene, as well as the scene object facilitates any communications between required objects. And as good Object-Oriented design would dictate, each window should be completely ignorant of other windows. This removes any unnecessary dependencies between windows.

 

In your example (with the equip scene), a systems sequence might be described as such:

Assume the player is currently on some map.

1. Player presses the B key

2. A new Scene_Menu object is instantiated and set as the active scene ($scene)

3. The player selects equip in the command window and input control is transferred to the status window.

note: the index of the status window has a 1-to-1 relationship with the index of the actors in the party.

$game_party.actors[@status_window.index]

would return the currently selected actor of the status window. 0 is the first actor, 1 is the second actor ... and so on.

4. The player selects an actor, and a new Scene_Equip is instantiated with the current index of the status window and set as the active scene.

$scene = Scene_Equip.new(@status_window.index)

5. Scene_Equip uses this index number to get the Game_Actor object to create the necessary equip windows (Right, Left, Item). note: each window simply displays the basic details from the actor object (base stats, equipment stats and equip-able items)

6. Scene_Equip controls communications between windows:

Lines 73 - 78:

    # Set item window to visible
   @item_window1.visible = (@right_window.index == 0)
   @item_window2.visible = (@right_window.index == 1)
   @item_window3.visible = (@right_window.index == 2)
   @item_window4.visible = (@right_window.index == 3)
   @item_window5.visible = (@right_window.index == 4)

 

This sets the item window corresponding to the active equip slot to be visible, and the others invisible.

 

Lines 79 - 93:

	# Get currently equipped item
item1 = @right_window.item
# Set current item window to @item_window
case @right_window.index
when 0
  @item_window = @item_window1
when 1
  @item_window = @item_window2
when 2
  @item_window = @item_window3
when 3
  @item_window = @item_window4
when 4
  @item_window = @item_window5
end

 

1 Item window exists for each possible weapon slot. The currently equipped item (of the selected slot) is stored (item1), and the corresponding item window for that slot is set to the active item window (@item_window)

 

Lines 94 - 98:

	# If right window is active
if @right_window.active
  # Erase parameters for after equipment change
  @left_window.set_new_parameters(nil, nil, nil)
end

This ensures, that if the player is not selecting an item from the item menu, the "new parameters" values will be erased.

 

Lines 99 - 117:

	# If item window is active
if @item_window.active
  # Get currently selected item
  item2 = @item_window.item
  # Change equipment
  last_hp = @actor.hp
  last_sp = @actor.sp
  @actor.equip(@right_window.index, item2 == nil ? 0 : item2.id)
  # Get parameters for after equipment change
  new_atk = @actor.atk
  new_pdef = @actor.pdef
  new_mdef = @actor.mdef
  # Return equipment
  @actor.equip(@right_window.index, item1 == nil ? 0 : item1.id)
  @actor.hp = last_hp
  @actor.sp = last_sp
  # Draw in left window
  @left_window.set_new_parameters(new_atk, new_pdef, new_mdef)
end

This is the code responsible for displaying the new parameters. It works by temporarily equipping the item that is selected in the item window, recording the players new stats re-equipping the original item and passes that information to the left window.

 

So you see, each window doesn't really care about any other window's existence. They simply work on a need-to-know basis and the scene is responsible for distributing external data.

 

You could, however, have also achieved the same effect, except in a way where the windows DID know about each other. This would be exactly as Moonpearl was describing with the help window example. You could have a public attribute so you could link the active item window to the left window, rather than having an instance variable in the Scene:

@left_window.item_window = @item_window1 # ... etc ...

and rework the right window to get any extra information directly from the item window. Or, you could redesign the left/right window to manage ALL the item_windows and make the Scene simply manage the other windows, etc. But I feel those such designs would over complicate the system and create complex dependencies. Ultimately, make things more confusing.

Edited by kellessdee
for completeness

Share this post


Link to post
Share on other sites
  • 0
The code you have there will not work, because you are trying to get the "item" attribute from the class rather than the instance of the Window in question. The class doesn't know anything about the selected item of any instance of that class.

 

Good to know; so to get an instance of something you have to do Name_Of_Class.new correct? What about Line 102?

@item1 = @item_window.item

Is this only working because, a. It's being called in a scene instead of a window? or b. It's being called with @item_window having an instance floating about. I'm assuming that this particular problem is the reason why coding generally gets done on paper first :)

Share this post


Link to post
Share on other sites
  • 0
@item1 = @item_window.item

Is this only working because, a. It's being called in a scene instead of a window? or b. It's being called with @item_window having an instance floating about. I'm assuming that this particular problem is the reason why coding generally gets done on paper first smile.png

Definitely not a. As I explained in my first answer, the scene creates an Window_Item object and stores it reference into its @item_window variable (could be any other name, it doesn't matter the least bit to Ruby). As long as you have the reference to an instance of Window_Item, which is the case here, you can call its item method by writing:

<reference>.item

You could also write the following:

Window_Item.new.item

What we have here is indeed a reference to an instance of Window_Item, so we can call its item method. The reason why we don't do this is because it creates a window "on-the-fly", and since the reference to the window is not stored in a variable, then the window is destroyed right away - it feels pretty dumb to create an object we don't intend to keep just to get one of its properties.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...