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.

Window_Help

PX

Member

Hi there!
You know, Window_Help is used for Scene_Skill (also for other Scenes). I want to enlarge the Window_Help class because I want to show power and type of the skill. Here's my code:

Code:
class Window_SkillHelp < Window_Base

  def initialize
    super(0, 0, 640, 128)
    self.contents = Bitmap.new(width - 32, height - 32)
  end

  def set_text(text, align = 0)
    if text != @text or align != @align 
      # Redraw text
      self.contents.clear
      self.contents.font.color = normal_color
      self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
      @text = text
      @align = align
      @actor = nil
    end
  end

  def skill
    return @data[self.index]
  end 

  def draw_item(index)
    skill = @data[index]
    x = 4 + index % 1 * (288 + 32)
    y = index / 2 * 32
    opacity = self.contents.font.color == normal_color ? 255 : 128
    self.visible = true
    self.contents.font.color = system_color
    self.contents.draw_text(x, y + 64, 192, 32, "Power", 0)
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 64, y + 64, 48, 32, skill.power.to_s, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(x + 160, y + 64, 192, 32, "Hit Chance", 0)
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 288, y + 64, 48, 32, skill.hit.to_s, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(x + 384, y + 64, 48, 32, "Type", 0)
    self.contents.font.color = normal_color
    if skill.variance > 0 
     self.contents.draw_text(x + 452, y, 192, 32, "M. Attack", 0)
     else
     self.contents.draw_text(x + 452, y, 192, 32, "P. Attack", 0)
    end
  end
end

There isn't any RGSS-error, but my Window_Help shows just the description text!!! Height and Width of the Window are ok, but the part where my informations should be shown remains empty! Help!
 

khmp

Sponsor

Well the most likely reason you aren't seeing a change is that the code is never being called. You say the window size is correct meaning it's at least being created in place of the normal help window in Scene_Skill.

So the top of Scene_Skill's main should be this:

Code:
def main
  # Get actor
  @actor = $game_party.actors[@actor_index]
  # Make help window, status window, and skill window
  @help_window = Window_SkillHelp.new # <- The line that changed
  @status_window = Window_SkillStatus.new(@actor)
  @skill_window = Window_Skill.new(@actor)
  # Associate help window
  @skill_window.help_window = @help_window
  # Make target window (set to invisible / inactive)
  @target_window = Window_Target.new
  @target_window.visible = false
  @target_window.active = false
  ..
end

The next thing after creation of the window is that the call from set_text(text,align) should instead be the draw_item(index) method you created. This is, after all, the data you want to see. So let's head over to Window_Skill. The one responsible for calling set_text(text,align). All the way at the bottom there's:

Code:
#------------------------------------------------------------------
# * Help Text Update
#------------------------------------------------------------------
def update_help
  @help_window.set_text(self.skill == nil ? "" : self.skill.description)
end

should instead be:

Code:
#------------------------------------------------------------------
# * Help Text Update
#------------------------------------------------------------------
def update_help
  @help_window.draw_item(self.skill == nil ? "" : self.skill.id)
end

Alright time to stick it all together and make it Script Compatible friendly(er). ':| In the script editor. Above main and below Scene_Debug & Window_SkillHelp insert a line. Name it Scene_Skill, paste in.

Code:
class Window_Skill
  # !Override! : update_help
  #------------------------------------------------------------------
  # * Help Text Update
  #------------------------------------------------------------------
  def update_help
    @help_window.draw_item(self.skill == nil ? -1 : self.skill.id)
  end
end

class Scene_Skill
  # !Override! : main
  #------------------------------------------------------------------
  # * Main Processing
  #------------------------------------------------------------------  
  def main
    # Get actor
    @actor = $game_party.actors[@actor_index]
    # Make help window, status window, and skill window
    @help_window = Window_SkillHelp.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill.new(@actor)
    # Associate help window
    @skill_window.help_window = @help_window
    # Make target window (set to invisible / inactive)
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    # Execute transition
    Graphics.transition
    # Main loop
    loop do
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Frame update
      update
      # Abort loop if screen is changed
      if $scene != self
        break
      end
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of windows
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
  end
end

Don't forget to set the actor for the Window_SkillHelp. Otherwise you'll crash when you get to draw_item. And lastly at the top of your draw_item code the line:

Code:
skill = @data[index]

I think it should be:

Code:
# Return if invalid index
return if index == -1
# Grab the skill from the actor
skill = $data_skills[@actor.skills[index]]

As for further suggestions for your window you can group some of those draw_text calls to avoid setting the font_color every other line. And you might want to investigate how to avoid redrawing that text every frame.

Good luck with it P-Games! :thumb:
 

khmp

Sponsor

Yes you're right there is no error now because that line isn't being reached. The compiling seems to occur at run time and it will catch things like a code block missing an 'end' but as for incorrectly assigned variables it won't say there's anything wrong with them until the line is reached. Like how about this.

Code:
begin
  # The next four lines are totally legal even though they make syntactically no sense. 
  # Once btrue is assigned true however it will crash saying index is nil among other things.
  # That's because the code block is actually being executed.
  btrue = false
  if btrue 
    skill = data[index]
  end
  
  # Prepare for transition
  Graphics.freeze
  # Make scene object (title screen)
  $scene = Scene_Title.new
  # Call main method as long as $scene is effective
  while $scene != nil
    $scene.main
  end
  # Fade out
  Graphics.transition(20)
rescue Errno::ENOENT
  # Supplement Errno::ENOENT exception
  # If unable to open file, display message and end
  filename = $!.message.sub("No such file or directory - ", "")
  print("Unable to find file #{filename}.")
end

I was foreseeing an error you would run into. I might be wrong, and if I am. I am sorry.
 

khmp

Sponsor

I posted the main code because I wanted to show that invalid syntax hidden within a code block will not error out. btrue is just a variable I made for the example. Let's start from the beginning back to your problem.

I'll put it into steps and try to explain it differently so you understand why I am doing something.

1.) First we want to create the window in Scene_Skill. We want it to replace the help window that normally appears in that scene. So the script would go:

Code:
class Scene_Skill
  # !Override! : main
  #------------------------------------------------------------------
  # * Main Processing
  #------------------------------------------------------------------  
  def main
    # Get actor
    @actor = $game_party.actors[@actor_index]
    # Make help window, status window, and skill window
    @help_window = Window_SkillHelp.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill.new(@actor)
    # Associate help window
    @skill_window.help_window = @help_window
    # Make target window (set to invisible / inactive)
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    # Execute transition
    Graphics.transition
    # Main loop
    loop do
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Frame update
      update
      # Abort loop if screen is changed
      if $scene != self
        break
      end
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of windows
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
  end
end

@help_window = Window_SkillHelp.new. This line, which is also above, creates your window in the scene making it visible.

2.) Window_Skill which is used in Scene_Skill needs to be altered to accommodate your Window_SkillHelp. That's because in order for your window to be notified to display the information we need to change update_help of Window_Skill. To do that we change update_help. So here's the script to do that:

Code:
class Window_Skill
  # !Override! : update_help
  #------------------------------------------------------------------
  # * Help Text Update
  #------------------------------------------------------------------
  def update_help
    @help_window.draw_item(self.skill == nil ? -1 : self.skill.id)
  end
end

3.) We wrap it up by sticking the code below Scene_Debug and above Main in the script editor.

Code:
class Window_Skill
  # !Override! : update_help
  #------------------------------------------------------------------
  # * Help Text Update
  #------------------------------------------------------------------
  def update_help
    @help_window.draw_item(self.skill == nil ? -1 : self.skill.id)
  end
end

class Scene_Skill
  # !Override! : main
  #------------------------------------------------------------------
  # * Main Processing
  #------------------------------------------------------------------  
  def main
    # Get actor
    @actor = $game_party.actors[@actor_index]
    # Make help window, status window, and skill window
    @help_window = Window_SkillHelp.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill.new(@actor)
    # Associate help window
    @skill_window.help_window = @help_window
    # Make target window (set to invisible / inactive)
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    # Execute transition
    Graphics.transition
    # Main loop
    loop do
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Frame update
      update
      # Abort loop if screen is changed
      if $scene != self
        break
      end
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of windows
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
  end
end

If you have any problem with implementing the script, or any problems what so ever just ask.

Good luck P-Games! :thumb:
 

PX

Member

1. The first code you posted in your last post: should I create a new script for this or is it just a part of my Scene_Skill? I think that it's just a part, am I right? I knew it also before that I have to make the window visible in Scene_Skill - it was everytime visible.

2. The second post: the first part of this code goes in Window_Skill at the end, right? The second part is the same you posted in the first post... ok^^

3. And then you give me again the first part of the second code... it seems a little weird... I'm going on with trying it... please help me again.

greetz
 

khmp

Sponsor

Ah ok here is where the misunderstanding lies I believe. Ruby lets you redefine a method an infinite amount of times. You do not need to replace any code to get this to work. What happens is when you put the code from my last post found under step 3 in the script editor it will override or take precedence over the previous function of the same name. I will do an example.

Code:
class Example
  def do_stuff
    p 3
  end
end

Now let's say we want to override that function we just redefine the method definition within the class namespace again.

Code:
class Example
  def do_stuff
    p 3
  end
  def do_stuff
    p 4
  end
end

Whenever you call Example.do_stuff it will look at the last definition of do_stuff and execute it. In this case it will print the number 4 in a messagebox. Now let's bring that idea to your problem. See we need to change some things in some of the classes but we want to avoid directly changing them. It is a bad practice to do so. Instead we are going to override these methods that need to be changed because of reasons explained above.

Lets open the script editor and in the list of scripts on the left insert a line above main but below Scene_Debug. If you have any other scripts there put it below them. Now insert the following code:

Code:
class Window_Skill
  # !Override! : update_help
  #------------------------------------------------------------------
  # * Help Text Update
  #------------------------------------------------------------------
  def update_help
    @help_window.draw_item(self.skill == nil ? -1 : self.skill.id)
  end
end

class Scene_Skill
  # !Override! : main
  #------------------------------------------------------------------
  # * Main Processing
  #------------------------------------------------------------------  
  def main
    # Get actor
    @actor = $game_party.actors[@actor_index]
    # Make help window, status window, and skill window
    @help_window = Window_SkillHelp.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill.new(@actor)
    # Associate help window
    @skill_window.help_window = @help_window
    # Make target window (set to invisible / inactive)
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    # Execute transition
    Graphics.transition
    # Main loop
    loop do
      # Update game screen
      Graphics.update
      # Update input information
      Input.update
      # Frame update
      update
      # Abort loop if screen is changed
      if $scene != self
        break
      end
    end
    # Prepare for transition
    Graphics.freeze
    # Dispose of windows
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
  end
end

Good luck with it P-Games! :thumb:
 

khmp

Sponsor

Alright I think this will solve it. Replace that line of code with these two.

Code:
# Return if invalid index
return if index == -1
# Grab the skill from the actor
skill = $data_skills[@actor.skills[index]]

If you still have an error I'd say its because @actor is nil. But update me and tell me if it stills errors out on you.

Good luck P-Games! :thumb:
 

khmp

Sponsor

To prevent any further quessing on my part could you package the game and host it on megaupload/rapidshare etc. So I can download it and look at it. If it isn't too much trouble that is.
 

khmp

Sponsor

Alright as with the pm this is also the solution to your problem below:

Code:
#==============================================================================
# ** Window_SkillHelp
#------------------------------------------------------------------------------
#  This window shows skill and item explanations along with actor status.
#==============================================================================

class Window_SkillHelp < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, 640, 128)
    @index = -1
    self.contents = Bitmap.new(width - 32, height - 32)
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #     index : item number
  #--------------------------------------------------------------------------
  def draw_item(index)
    # Return if invalid index
    return if index == -1 || @index == index
    # Return if that skill is nil
    return if $data_skills[index] == nil
    @index = index
    # The skill found at the index
    skill = $data_skills[index]
    x, y = 0, 0
    # Time to draw the skill information
    self.contents.clear
    self.contents.font.color = system_color
    self.contents.draw_text(x, y + 64, 192, 32, "St?rke")
    self.contents.draw_text(x + 160, y + 64, 192, 32, "Trefferchance")
    self.contents.draw_text(x + 384, y + 64, 48, 32, "Typ")
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 64, y + 64, 48, 32, skill.power.to_s)
    self.contents.draw_text(x + 288, y + 64, 48, 32, skill.hit.to_s)
    if skill.variance > 0 
     self.contents.draw_text(x + 452, y, 192, 32, "M. Angriff")
     else
     self.contents.draw_text(x + 452, y, 192, 32, "P. Angriff")
    end
  end
end

Good luck with your game P-Games!:thumb:
 

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