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.

help with bug in Battle Report Script

I am running into a bug in my Battle Report Script that is making the game crash. Please note that this version was written from scratch by Sephirothspawn for me, because I was having too many problems with the original battle report script.

Normally I would go to Sephiroth for this problem but he hasn't been on in quite a while and has been very busy, so I'll need to post it here. I tried figuring out what's wrong but I haven't had any luck. I'm not familiar with RGSS enough to find the problem.

Basically, this script works perfectly except for the case where the "Continue Even When Loser" checkbox is selected in the Battle Processing event. If the player loses the battle in this case, then I receive the following error:

battlereporterror3.jpg


The line that it errors on is actually this (a bit lower than 278 in the script below):

@level_up_windows.each {|w| w.dispose}

Here is his script:

Code:
 

#==============================================================================

# ** Battle Report

#------------------------------------------------------------------------------

# SephirothSpawn

# Version 1.0

# 2009-02-24

#==============================================================================

 

#==============================================================================

# ** BattleReport

#==============================================================================

 

module BattleReport

  Excluded_Actors = [9,10,11,13]

  Show_Dummy_Windows = true

  Draw_Face = true

  ME_Switch = 12

  Increment = 15

  #--------------------------------------------------------------------------

  # * Sound Effects

  #--------------------------------------------------------------------------

  Level_Up = RPG::AudioFile.new('056-Right02', 80, 100)

  Learn_Skill = RPG::AudioFile.new('105-Heal01')

  BGS = RPG::AudioFile.new('032-Switch01', 100, 300)

  SE  = RPG::AudioFile.new('006-System06', 70, 150)

end

 

#==============================================================================

# ** BattleReport::Window_Base

#==============================================================================

 

class BattleReport::Window_Base < Window_Base

  #--------------------------------------------------------------------------

  # * Draw Actor Face

  #--------------------------------------------------------------------------

  def draw_actor_face(actor, x, y)

    bitmap = RPG::Cache.character("Faces/" + actor.character_name, actor.character_hue)

    self.contents.blt(x, y, bitmap, Rect.new(0,0,96,96))

  end

  #--------------------------------------------------------------------------

  # * Draw Slant Bar(by SephirothSpawn)

  #--------------------------------------------------------------------------

  def draw_slant_bar(x, y, min, max, width = 152, height = 6,

      bar_color = Color.new(150, 0, 0, 255), end_color = Color.new(255, 255, 60, 255))

    # Draw Border

    for i in 0..height

      self.contents.fill_rect(x + i, y + height - i, width + 1, 1, Color.new(50, 50, 50, 255))

    end

    # Draw Background

    for i in 1..(height - 1)

      r = 100 * (height - i) / height + 0 * i / height

      g = 100 * (height - i) / height + 0 * i / height

      b = 100 * (height - i) / height + 0 * i / height

      a = 255 * (height - i) / height + 255 * i / height

      self.contents.fill_rect(x + i, y + height - i, width, 1, Color.new(r, b, g, a))

    end

    # Draws Bar

    for i in 1..( (min / max.to_f) * width - 1)

      for j in 1..(height - 1)

        r = bar_color.red * (width - i) / width + end_color.red * i / width

        g = bar_color.green * (width - i) / width + end_color.green * i / width

        b = bar_color.blue * (width - i) / width + end_color.blue * i / width

        a = bar_color.alpha * (width - i) / width + end_color.alpha * i / width

        self.contents.fill_rect(x + i + j, y + height - j, 1, 1, Color.new(r, g, b, a))

      end

    end

  end

end

 

#==============================================================================

# ** BattleReport::Window_LevelUp

#==============================================================================

 

class BattleReport::Window_LevelUp < BattleReport::Window_Base

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(actor, exp)

    super(280, 0, 360, 120)

    self.contents = Bitmap.new(width - 32, height - 32)

    @actor = actor

    @exp = exp

    @level = @actor.level

    @skills_size = @actor.skills.size

    refresh

    self.z = 2000

  end

 

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh(exp = @exp)

    @exp = exp

    self.contents.clear

    # Draw Face or Graphic

    if BattleReport::Draw_Face

      draw_actor_face(@actor, 4, 0)

    else

      draw_actor_graphic(@actor, 50, 80)

    end

    self.contents.font.size = 18

    self.contents.font.color = normal_color

    # Draw Name & Level

    draw_actor_name(@actor, 111, 0)

    draw_actor_level(@actor, 186, 0)

    # Draw Bar

    min_bar = @actor.level == 40 ? 1 : @actor.now_exp

    max_bar = @actor.level == 40 ? 1 : @actor.next_exp

    draw_slant_bar(115, 80, min_bar, max_bar, 190, 6,

      bar_color = Color.new(0, 100, 0, 255), end_color = Color.new(0, 255, 0, 255))

    # Draw Exp

    show_next_exp = @actor.level == 40 ? '---' : "#{@actor.next_exp}"

    self.contents.draw_text(115, 24, 300, 32, "Exp: #{@exp}")

    self.contents.draw_text(115, 48, 300, 32, 'Level Up: ' + show_next_exp)

    # If level up

    if @level < @actor.level

      @level = @actor.level

      self.contents.font.color = system_color

      Damages.damage(x + rand(8) + 96, y + rand(8) + 64, 96, 96, 'LEVEL UP!')

      $game_system.se_play(BattleReport::Level_Up)

      if @skills_size < @actor.skills.size

        @skills_size = @actor.skills.size

        $game_system.se_play(BattleReport::Learn_Skill)

        Damages.damage(x + rand(8) + 96, y + rand(8) + 32, 96 + 96, 96, 'Learned Skill!')

      end

    end

  end

end

 

#==============================================================================

# ** BattleReport::Window_Exp

#==============================================================================

 

class BattleReport::Window_Exp < BattleReport::Window_Base

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(exp)

    super(0, 0, 280, 60)

    self.contents = Bitmap.new(width - 32, height - 32)

    self.back_opacity = 255

    refresh(exp)

    self.z = 2000

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh(exp)

    self.contents.clear

    self.contents.font.color = system_color

    self.contents.draw_text(0, 0, 150, 32, "Exp Earned:")

    self.contents.font.color = normal_color

    self.contents.draw_text(180, 0, 54, 32, exp.to_s, 2)

  end

end

 

#==============================================================================

# ** BattleReport::Window_Treasures

#==============================================================================

 

class BattleReport::Window_Treasures < BattleReport::Window_Base

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(money, treasures)

    super(0, 60, 280, 420)

    self.contents = Bitmap.new(width - 32, height - 32)

    refresh(money, treasures)

    self.z = 2000

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh(money, treasures)

    self.contents.clear

    self.contents.font.color = system_color

    self.contents.draw_text(4, 4, contents.width - 4, 32, 'Items Found:')

    self.contents.font.color = normal_color

    # Draw Treasures

    y = 32

    for item in treasures

      draw_item_name(item, 4, y)

      y += 32

    end

    # Draw Gold

    cx = contents.text_size($data_system.words.gold).width

    self.contents.font.color = normal_color

    self.contents.draw_text(4, 340, 220-cx-2, 32, $game_party.gold.to_s, 2)

    self.contents.font.color = normal_color

    self.contents.draw_text(4, 300, 220-cx-2, 32, "+ " + money.to_s, 2)

    self.contents.font.color = system_color

    self.contents.draw_text(124-cx, 340, cx + 100, 32, $data_system.words.gold, 2)

  end

end

 

#==============================================================================

# ** Window_BattleResult

#==============================================================================

 

class Window_BattleResult < Window_Base

  #--------------------------------------------------------------------------

  # * Pubic Instance Variables

  #--------------------------------------------------------------------------

  attr_reader :exp, :gold, :treasures

end

   

#==============================================================================

# ** Game_Actor

#==============================================================================

 

class Game_Actor

  #--------------------------------------------------------------------------

  # * Public Instance Variable

  #--------------------------------------------------------------------------

  attr_accessor :cant_get_exp

  #--------------------------------------------------------------------------

  # * Determine [Can't Get EXP] States

  #--------------------------------------------------------------------------

  alias_method :seph_battlereport_gmactr_cge?, :cant_get_exp?

  def cant_get_exp?

    # Return true if set to cannot get exp

    return true if @cant_get_exp

    # Return Original Result

    return seph_battlereport_gmactr_cge?

  end

  #--------------------------------------------------------------------------

  # * Get the current EXP

  #--------------------------------------------------------------------------

  def now_exp

    return @exp - @exp_list[@level]

  end

  #--------------------------------------------------------------------------

  # * Get the next level's EXP

  #--------------------------------------------------------------------------

  def next_exp

    return @exp_list[@level+1] > 0 ? @exp_list[@level+1] - @exp_list[@level] : 0

  end

end

 

#==============================================================================

# ** Scene_Battle

#==============================================================================

 

class Scene_Battle

  #--------------------------------------------------------------------------

  # * Main Processing

  #--------------------------------------------------------------------------

  alias_method :seph_battlereport_scnbtl_main, :main

  def main

    # Original Main Processing

    seph_battlereport_scnbtl_main

    # Stop ME

    Audio.me_stop

  end

  #--------------------------------------------------------------------------

  # * Battle End

  #--------------------------------------------------------------------------

  alias_method :seph_battlereport_scnbtl_be, :battle_end

  def battle_end(result)

    # Original Battle End

    seph_battlereport_scnbtl_be(result)

    # Turn off Objects

    @status_window.visible = false

    # Run Transition

    Graphics.transition

    # If Victory

    if result == 0

      # Display Battle Report Windows

      display_battle_report

    end

    # Wait for OK

    loop do

      Graphics.update

      Input.update

      break if Input.trigger?(Input::C)

    end

    # Dispose Battle Report Windows

    @level_up_windows.each {|w| w.dispose}

    @exp_window.dispose

    @treasures_window.dispose

  end

  #--------------------------------------------------------------------------

  # * Start After Battle Phase

  #--------------------------------------------------------------------------

  alias_method :seph_battlereport_scnbtl_sp5, :start_phase5

  def start_phase5

    # Set each actor to cannot get exp

    for actor in $game_party.actors

      actor.cant_get_exp = true

    end

    # Save current battle end me

    battle_end_me = $game_system.battle_end_me.dup

    # Set battle end me to nil

    unless $game_switches[BattleReport::ME_Switch]

      $game_system.battle_end_me = nil

    end

    # Original Start Phase 5

    seph_battlereport_scnbtl_sp5

    # Turn off battle result window

    @result_window.visible = false

    # Clear cannot get exp flag

    for actor in $game_party.actors

      actor.cant_get_exp = false

    end

    # Restore battle end me

    $game_system.battle_end_me = battle_end_me

    # Clear main phase flag

    $game_temp.battle_main_phase = false

    # Battle Result

    battle_end(0)

  end

  #--------------------------------------------------------------------------

  # * Display Battle Report

  #--------------------------------------------------------------------------

  def display_battle_report

    # Get exp, gold & treasures

    exp = @result_window.exp

    gld = @result_window.gold

    tsr = @result_window.treasures

    # Setup Level Up Windows

    @level_up_windows = []

    for actor in $game_party.actors

      next if BattleReport::Excluded_Actors.include?(actor.id)

      @level_up_windows << BattleReport::Window_LevelUp.new(actor, exp)

      @level_up_windows.last.y = (@level_up_windows.size - 1) * 120

    end

    # Make Dummy Windows

    if BattleReport::Show_Dummy_Windows

      until @level_up_windows.size == 4

        y = @level_up_windows.size * 120

        @level_up_windows << Window_Base.new(280, y, 360, 120)

        @level_up_windows.last.z = 2000

      end

    end

    # Setup Exp & Treasures Window

    @exp_window = BattleReport::Window_Exp.new(exp)

    @treasures_window = BattleReport::Window_Treasures.new(gld, tsr)

    # Wait for OK

    loop do

      Graphics.update

      Input.update

      break if Input.trigger?(Input::C)

    end

    # Play Battle Report BGS

    $game_system.bgs_play(BattleReport::BGS)

    # Get Increment Value

   # inc = exp / [[BattleReport::Increment, 28].min, 1].max commented out by ImmuneEntity

   

   #modified by ImmuneEntity

   if exp > BattleReport::Increment

     result = exp / BattleReport::Increment

     if result == 1 and exp > BattleReport::Increment

       inc = 2

     else

       inc = result

     end

   else inc = 1

   end

   

    # Frame skip counter

    counter = 5

    # Loop

    loop do

      # Update Graphics & Input

      Graphics.update

      Input.update

      # Frame skip

      if counter > 0

        counter -= 1

        retry

      end

      # Reset Counter

      counter = 5

      # Inc Correction

      inc = [exp, inc].min

      # Get new exp value

      exp -= inc

      # Pass through each actor

      for actor in $game_party.actors

        # Next if actor cannot get exp

        next if actor.cant_get_exp?

        # Gain Exp

        actor.exp += inc

      end

      # Refresh Level Up Windows

      @level_up_windows.each do |window|

        if window.is_a?(BattleReport::Window_LevelUp)

          window.refresh(exp)

        end

      end

      # Refresh Exp Window

      @exp_window.refresh(exp)

      # Break if C button is pressed

      break if Input.trigger?(Input::C) || exp == 0

    end

    # Pass through each actor

    for actor in $game_party.actors

      # Next if actor cannot get exp

      next if actor.cant_get_exp?

      # Gain Exp

      actor.exp += inc

    end

    # Refresh Level Up Windows

    @level_up_windows.each do |window|

      if window.is_a?(BattleReport::Window_LevelUp)

        window.refresh(0)

      end

      window.update

    end

    # Refresh Exp Window

    @exp_window.refresh(0)

    # Stop BGS

    Audio.bgs_stop

    # Play Battle Report SE

    $game_system.se_play(BattleReport::SE)

    # Update Graphics

    Graphics.update

    # Turn on Objects

    @status_window.visible = true

  end

end

 

Any help would be greatly appreciated.
 
I think what happens is the display_battle_report method doesn't get called because result isn't 0, and it would normally make the exp windows and such; thus, they don't exist. Try replacing
[rgss]      @level_up_windows.each {|w| w.dispose}
      @exp_window.dispose
      @treasures_window.dispose
[/rgss]
with
[rgss]      if result == 0
        @level_up_windows.each {|w| w.dispose}
        @exp_window.dispose
        @treasures_window.dispose
      end
[/rgss]
 
Thanks! That made the game stop crashing, however there is still a slight problem where the bottom window that contains actor information (HP, SP, etc) goes to black (which looks glitchy and unattractive), and the player must press Space Bar to make it exit the battle (the battle report is never shown in this "continue when loss" case, which I suppose makes sense). I fixed the first part of the problem by changing this code (this is just a few lines above the other line we were looking at):

Code:
 

 if result == 0

      @status_window.visible = false

    end

 

I added the if statement around that line, and it seems to work. I'm not sure if this is correct or not, because I don't exactly understand what 'result' is.

However, I still have the problem that the player must press Space Bar to return to the map when the battle is over. This isn't desireable because there is no indication that the player must press a key. When the player loses a battle, it goes straight to the Game Over screen without pressing a key, so keeping this consistent would be preferable. Any idea on how to do that?

A second issue that would be nice to have resolved, but is less critical, is that the battle screen displays for about 1-2 frames after the Battle Report is done before returning to the map. Do you know of any way to make it go straight from the battle report to the map?

Thanks.
 

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