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.

[RMXP] Character Transition on Out of SP

I was wondering if someone could please help me modify SandGolem's Out of SP Death script:
Code:
class Game_Battler
  alias voith_0spdeath_sp sp=
  def sp=(sp)
    voith_0spdeath_sp(sp)
    if @sp < 1
      self.hp=(0)
    end
  end
end
So that when death happens it uses the "random_to_014-Warrior02" animation (a character transition) if the character dying is actor 1. Also after that call it must use wait 20 frames and somehow delay gameover for 20 frames and still show dead status (dead status not needed but wanted). I am not sure how this could be done so, please help me out here.

Here is the character transition script just in case:
Code:
#==============================================================================
# ** Character Transition
#------------------------------------------------------------------------------
# Rataime
# Version 1.1
# 22/05/2007 (2007-05-22)
#
# convert.exe is an ImageMagick binary. Their license is very permissive and
# can be found here : http://www.imagemagick.org/script/license.php
# Basically, you can redistribute it (even in commercial bundles)
# as long as you credit ImageMagick.
#------------------------------------------------------------------------------
# This script allows you to generate and use characters transitions, ie going
# from one character sprite to another (or a blank one) in the same way you
# can use transitions from one scene to another. All you will need is a
# transition file like those for maps, but smaller.
#
# Given that the Bitmap class is not really powerful, I'm using an external
# binary from ImageMagick called convert.exe. The first time you request a
# specific animation (example : 001-fighter01 to 002-fighter02 facing down using
# a circle transition), the animation bitmap will have to be generated. You'll
# see quite a lot of terminal windows opening and closing, this is quite ugly,
# but the good news is you can delete convert.exe if you're sure you have
# generated every transition you need.
#
# To start a transition, first configure a new animation. Its name must be
# transition_to_character, where transition is the transition name and character
# the final charset name. Example : random_to_002-Fighter02. You can use 'none'
# without the quotes to make your sprite dissapear. The number of frames of the
# animation will be the number of frames of the transition (shortcut : 1=>21)
# Then, after adding this animation's id to the CHARACTER_TRANSITION_ANIMATION_LIST,
# playing it over a character will start the transition. 
#------------------------------------------------------------------------------
# Additionnal notes :
#
# - You may want to prevent the player/event from moving during an animation.
#   The animation will be displayed where the animation was started, but it
#   doesn't automatically prevent the hero (or any other event) from moving.
# - Regarding encryption, the script cannot generate new transitions from
#   encrypted archives. However, it'll play previously generated transitions 
#   or generate transitions from RTP sprites or local folders just fine.
# - You should use a transition and characters of the same size. It might work, 
#   but I don't want to know what will happen otherwise (weird things, probably)
# - The script assumes everything is PNG. You should use PNG anyway. 
# - The script needs the events to have been properly loaded and displayed once.
#   Just use a wait 1 frame to prevent the script from crashing
# - There should be no lag from using the transition, only from generating it.
#==============================================================================


# The folder where the transitions and results are stored.
CHARACTER_TRANSITION_FOLDER = 'Graphics/Character_transition/'

# The list of active animations. EDIT ME !
# Note : 101..103 is equivalent to [101, 102, 103]
CHARACTER_TRANSITION_ANIMATION_LIST = 102..112

# If your computer is slow/unlucky enough to cause hanging errors when generating
# animations, set those to true. It will be slower but won't crash.
# You can try to set the first one to false and see if it works for you.
CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING = true
CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE = false

#The following constant isn't used. Yet.
#CHARACTER_TRANSITION_BLOODY_SCRIPT_YOU_ARE_GOING_TO_REGRET_HANGING_ON_ME = false

#------------------------------------------------------------------------------
# * SDK Log Script and Check requirements if you want to use those.
#------------------------------------------------------------------------------
#SDK.log('Character_Transition', 'rataime', 1.00, '05.16.2007')
#SDK.check_requirements(2, [1,2])

#==============================================================================
# ** Sprite_Character
#==============================================================================

class Sprite_Character < RPG::Sprite
  
  alias rataime_character_transition_update update
  
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    # If an animation included in the list is currently played on this event...
    if CHARACTER_TRANSITION_ANIMATION_LIST.include?(@character.animation_id) or
        @transition != nil
      # The first time, it generates the transition parameters 
      if @transition == nil
        animation = $data_animations[@character.animation_id]
        @transition = RPG::Character_Transition.new
        @transition.animation_id = animation
        @transition.name, @transition.to = animation.name.split('_to_')
        if @character.character_name == ''
          @transition.from = 'none'
          if @transition.to != 'none'            
            # If we can't get the dimentions of the sprites from the current
            # character because it is invisible, we have to load the expected result
            # and get our data from it.
            to_bitmap = RPG::Cache.character(@transition.to, 0)
            @cw = to_bitmap.width/4
            @ch = to_bitmap.height/4
            sx = @character.pattern * @cw
            sy = (@character.direction - 2) / 2 * @ch
            @transition.rect = Rect.new(sx, sy, @cw, @ch)
            to_bitmap = nil
          end
        else
          @transition.from = @character.character_name
          @transition.rect = self.src_rect
        end
        if @transition.to == @transition.from
          @transition = nil
          @character.animation_id = 0
          return
        end
        @transition.character = @character
        if animation.frame_max != 1
          @transition.frame_max = animation.frame_max
        end

        # The character's bitmap is changed to the transition set
        self.bitmap = @transition.bitmap
        # The character's graphic is changed to what it will be after the
        # transition
        # IF THE SCRIPT CRASH HERE, READ THE LAST ADDITIONNAL NOTE ABOVE
        self.ox = @cw / 2 
        self.oy = @ch
      end
      # A bit of maths to know where to take the frame from
      quotient, modulus = (@transition.frame - 1 ).divmod(5)
      sx = (modulus) * @cw
      sy = quotient * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
      super
      @transition.frame += 1
      # If the animation has ended, we tell the character it has.
      if @transition.frame == @transition.frame_max + 1
        if @transition.to == 'none'
          @character.set_character_name('')
        else
          @character.set_character_name(@transition.to)
        end
        @transition = nil
        @character.animation_id = 0
      end
      # Anyway, we return without using the standard update
      return
    end
    # If no correct animation is played, things stay the same as usual
    rataime_character_transition_update
  end
end

#==============================================================================
# ** Module RPG::Cache
#==============================================================================
module RPG
  module Cache
    # A standard Cache function, except there are 3 parameters
    def self.character_transition(subfolder, filename, hue)
      self.load_bitmap(CHARACTER_TRANSITION_FOLDER + subfolder, filename, hue)
    end
  end
end

#==============================================================================
# ** Game_Character 
#==============================================================================
class Game_Character
  #--------------------------------------------------------------------------
  # * set_character_name
  #--------------------------------------------------------------------------
  def set_character_name(name)
    @character_name = name
  end
  
end

#==============================================================================
# ** RPG::Character_Transition
#------------------------------------------------------------------------------
# Better having a new class than setting lots of variables in the Sprite class
#==============================================================================
module RPG
  class Character_Transition
    #--------------------------------------------------------------------------
    # Initialise
    #--------------------------------------------------------------------------
    def initialize
      @animation_id = 0
      @name = ''
      @from = ''
      @to = ''
      @frame_max = 21
      @frame = 1
      @character = nil
      @rect = nil
    end
    attr_accessor :animation_id
    attr_accessor :name
    attr_accessor :from
    attr_accessor :to
    attr_accessor :character
    attr_accessor :frame_max
    attr_accessor :frame
    attr_accessor :rect
    #--------------------------------------------------------------------------
    # Bitmap : return the bitmap containing the animation frames
    #--------------------------------------------------------------------------
    def bitmap
      id = @character.pattern.to_s + @character.direction.to_s
      # If it doesn't exist for this particular transition in this particular
      # configuration (eg : facing up), we generate it.
      if !FileTest.exist?(CHARACTER_TRANSITION_FOLDER + @name + '/' + @from \
                        + '_' + @to + '_' + id + '_' + @frame_max.to_s + '.png')
        self.generate(id)
      end
      # Anyway, we cache the bitmap and return it.
      return RPG::Cache.character_transition( @name + '/', 
            @from + '_' + @to + '_' + id + '_' + @frame_max.to_s,
            @character.character_hue)
    end
    #--------------------------------------------------------------------------
    # Generate : generate the actual  animation bitmap
    #--------------------------------------------------------------------------
    def generate(id = '02')
      
      if !FileTest.exist?('convert.exe')
        p 'Error : cannot find convert.exe'
        raise
      end
      
      src_dir = CHARACTER_TRANSITION_FOLDER
      dir = src_dir + @name + '/'
      if !FileTest.directory?(dir)
        Dir.mkdir(dir)
      end
      
      rect = @rect
      
      animation_file = @from + '_' + @to + '_' + id + '_' + @frame_max.to_s \
                       + '.png'
      
      # We get the RTP path
      rgssGetRTPPath  = Win32API.new('RGSS102E','RGSSGetRTPPath','l','l')
      rgssGetPathWithRTP = Win32API.new("RGSS102E","RGSSGetPathWithRTP","l","p")
      rtp_folder = rgssGetPathWithRTP.call(rgssGetRTPPath.call(1)).gsub("\\", '/')
      
      # If the transition isn't to invisibility, we check both the character folder
      # in the project and the one in the RTP to get the starting bitmap.
      if @from!='none'
        if FileTest.exist?('./Graphics/Characters/' + @from + '.png')
          file_from = './Graphics/Characters/' + @from + '.png'
        elsif FileTest.exist?(rtp_folder + '/Graphics/Characters/' + @from + '.png')
          file_from = rtp_folder + '/Graphics/Characters/' + @from + '.png'
        else
          p 'Error in character transition : file ' + @from + '.png not found.'
          raise
        end
        # Once found, we crop it to have only the relevant pose
        arg = 'convert.exe "' + file_from + '" -quiet  -crop ' + rect.width.to_s + 'x' \
            + rect.height.to_s + '+' + rect.x.to_s + '+' + rect.y.to_s + ' +repage  ' \
            + dir + 'from.png'
        system(arg)
        file_from = dir + 'from.png'
      else
        file_from = dir + 'none.png'
      end
      
      # Same here, with the final bitmap
      if @to!='none'
        if FileTest.exist?('./Graphics/Characters/' + @to + '.png')
          file_to = './Graphics/Characters/' + @to + '.png'
        elsif FileTest.exist?(rtp_folder + '/Graphics/Characters/' + @to + '.png')
          file_to = rtp_folder + '/Graphics/Characters/' + @to + '.png'
        else
          p 'Error in character transition : file ' + @to + '.png not found.'
          raise
        end
        
        arg = 'convert.exe "' + file_to + '" -quiet  -crop ' + rect.width.to_s + 'x' \
            + rect.height.to_s + '+' + rect.x.to_s + '+' + rect.y.to_s + ' +repage  ' \
            + dir + 'to.png'     
        system(arg)
        file_to = dir + 'to.png'
      else
        file_to = dir + 'none.png'
      end
                  
      transition = src_dir + @name + '.png'

      frames = @frame_max
      
      # Hanging prevention
      Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
      
      # We generate an empty picture we're going to use for various purposes
      arg = 'convert -size ' + rect.width.to_s + 'x' + rect.height.to_s + \
            ' xc:#00000000 ' + dir + 'none.png'
      system(arg)
      
      # We generate the map of the sprites' visible areas
      # It seems complex, but there is a bug in convert.exe that prevented a
      # direct copy-and-paste-over while keeping the transparency.
      arg = 'convert.exe '+file_to+' -channel matte -negate -separate  +matte ' \
            + dir + 'matte_out.png'
      system(arg)
      arg = 'convert.exe '+file_from+' -channel matte -negate -separate  +matte ' \
            + dir + 'matte_in.png'
      system(arg)
    
      # For each frame, we are going to generate the corresponding graphic
      for i in 0..frames-1
        value = i.to_s
        percent = (5*i).to_s
        # Generating the transition mask
        arg =  'convert.exe '+ transition +' -black-threshold '+ percent \
                +'% -white-threshold '+ percent +'% -negate '+ dir + value + '.png'
        system(arg)
        # Composing it with the "to" file alpha mask (the map of visible areas)
        arg = 'convert.exe '+ dir + value + '.png ' + dir + 'matte_out.png '\
              + '-compose Multiply  -composite '+ dir + value + '_out.png'
        system(arg)
        
       # Hanging prevention
        Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
        
        # Also composing it with the "from" file alpha mask
        arg = 'convert.exe '+ dir + value + '.png -negate ' + dir + 'matte_in.png '\
              + '-compose Multiply  -composite '+ dir + value + '_in.png'
        system(arg)
        
        # Applying the 1st mask on the "to" file and pasting it on the transparent canevas
        arg = 'convert.exe '+ dir + 'none.png '+ file_to +' '+ dir + value \
                + '_out.png -compose Copy -composite '+ dir + value + '.png'
        system(arg)
        
        # Applying the 2nd mask on the "from" file and pasting it on the previous image
        arg = 'convert.exe '+ dir + value + '.png ' + file_from +' '+ dir + value \
                + '_in.png -compose Copy -composite '+ dir + value + '.png'
        system(arg)
        
        # Deleting the temporary frame files
        File.delete(dir + value + '_in.png')
        File.delete(dir + value + '_out.png')
        
        # Better safe than soERROR : SCRIPT HANGED
        Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING
      end
      # Deleting the temporary masks, source and background files
      File.delete(dir + 'matte_in.png')
      File.delete(dir + 'matte_out.png')
      File.delete(file_from)
      File.delete(file_to)
      File.delete(dir + 'none.png') if FileTest.exist?(dir + 'none.png')
      # Prepare the animation rows
      for i in 0..(frames-1)/5
        arg = 'convert.exe '
        for j in 0..4
          num = (5*i + j).to_s
          arg = arg + dir + num + '.png ' 
        end
        arg = arg + '+append ' + dir + 'row' + i.to_s + '.png'
        system(arg)
      end
      # Hanging prevention
      Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
      # Paste the rows together
      arg = 'convert.exe '
      for i in 0..(frames-1)/5
        arg = arg + dir + 'row' + i.to_s + '.png '
      end
      arg = arg + '-background none -append ' + dir + animation_file
      system(arg)
      # Delete the temporary row files
      for i in 0..(frames-1)/5
        File.delete(dir + 'row' + i.to_s + '.png ')
      end
      # Delete the temporary individual frames
      for i in 0..frames-1
        File.delete(dir + i.to_s + '.png ')
      end
    end      
          
  end
end
   

Just incase you didn't know this is for XP.
 

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