The RPG Maker Resource Kit

RMRK RPG Maker Creation => VX => VX Scripts Database => Topic started by: Zylos on March 17, 2011, 07:29:00 AM

Title: Checkpoints and Continues (VX)
Post by: Zylos on March 17, 2011, 07:29:00 AM
Checkpoints and Continues (VX)
Version: 1.0
Author: Zylos
Date: March 16, 2011


Description


This script allows the game creator to easily set up checkpoint spots for the player to respawn to after the party has been defeated. The creator simply calls this script in an event on the map (such as during a map transfer or after an important cutscene), then when the player reaches what would normally be a game over, they will be allowed to continue the game from the exact spot marked by the creator. Additionally, the creator may allow the player a set number of continues or lives before it is game over for good.

Features


Screenshots

(https://rmrk.net/proxy.php?request=http%3A%2F%2Fi254.photobucket.com%2Falbums%2Fhh99%2FZylos_2007%2Fcontinue.png&hash=ac6cbd4f2b4c2b7f7910ddf907d3c6f2867f2ac6)

Instructions


Spoiler for:
http://i254.photobucket.com/albums/hh99/Zylos_2007/Continue-1.png

Script


Code: [Select]
#==============================================================================
#  Checkpoints and Continues (VX)
#  Version: 1.0
#  Author: Zylos (rmrk.net)
#  Date: March 16, 2011
#------------------------------------------------------------------------------
#  Description:
#
#   This script allows the game creator to easily set up checkpoint spots for
#   the player to respawn to after the party has been defeated. The creator
#   simply calls this script in an event on the map (such as during a map
#   transfer or after an important cutscene), then when the player reaches what
#   would normally be a gameover, they will be allowed to continue the game
#   from the exact spot marked by the creator. Additionally, the creator may
#   allow the player a set number of continues or lives before it is gameover
#   for good.
#
#------------------------------------------------------------------------------
#  Instructions:
#   
#     - Place this script in the materials section, above Main.
#     - Check the settings of this script in the editable region below these
#       instructions to make sure they are to your needs.
#     - Use the script command in an event and type in "checkpoint" without
#       the quotes. This will create a checkpoint at that exact point.
#       Checkpoints are also automatically created upon the start of a new
#       game, saving the game, and loading a save file.
#
#==============================================================================

module Continue_Checkpoint
  #============================================================================
  # EDITABLE REGION:
  #============================================================================
 
  #============================================================================
  #   Continues_Enabled determines whether the player is allowed to continue or
  #   not when they have reached a gameover screen. In essence, it determines
  #   whether this script is turned on or off. This may be turned off in the
  #   game by calling "$game_system.continues_enabled = false".
  #============================================================================
  Continues_Enabled = true
  #============================================================================
  #   Number_Of_Continues sets the number of times the player is allowed to
  #   continue from a checkpoint before finally getting a gameover. Setting
  #   this to a negative number lets the player continue without a limited
  #   number of continues. You may add to this number ingame by calling
  #   "$game_system.lives += 1" and subtract similarly.
  #============================================================================
  Number_Of_Continues = -1
  #============================================================================
  #   Continue_Graphic is the image used to replace the gameover screen if the
  #   player is allowed to continue from a checkpoint. If the picture does not
  #   exist in the games system folder, then the default gameover screen will
  #   be used. Editable with "$game_system.continue_graphic = 'imagename'".
  #============================================================================
  Continue_Graphic = "Continue.png"
  #============================================================================
  #   Return_To_Title determines whether the player should return to the title
  #   screen if they choose not to continue from a checkpoint, or whether the
  #   game simply shuts down. This is useful for instances where the player
  #   can do battle before the title screen comes up. Editable with
  #   "$game_system.return_to_title = true/false".
  #============================================================================
  Return_To_Title = true
 
  #============================================================================
  # END EDITABLE REGION
  #============================================================================
end

#==============================================================================
# ** Game_System
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Initializing the checkpoint system here, in the event of the player having
#  maps before the title screen.
#==============================================================================

class Game_System
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :continues_enabled
  attr_accessor :lives
  attr_accessor :continue_graphic
  attr_accessor :return_to_title
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  alias_method :quicksave_data, :initialize
  def initialize
    quicksave_data
    @continues_enabled = Continue_Checkpoint::Continues_Enabled
    @lives = Continue_Checkpoint::Number_Of_Continues
    @continue_graphic = Continue_Checkpoint::Continue_Graphic
    @return_to_title = Continue_Checkpoint::Return_To_Title
    create_checkpoint
  end
  #--------------------------------------------------------------------------
  # * Creating Checkpoint Class
  #--------------------------------------------------------------------------
  def create_checkpoint
    $game_checkpoint = Game_Checkpoint.new
    $game_checkpoint.do_erase
  end
end

#==============================================================================
# ** Game_Checkpoint
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Creates and loads the data from checkpoints.
#==============================================================================

class Game_Checkpoint
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :quicksave 
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    @quicksave = []
    @quicksave[15] = ""
  end
  #--------------------------------------------------------------------------
  # * Execute Erasure
  #--------------------------------------------------------------------------
  def do_erase
    for i in @quicksave
      i = ""
    end
  end 
  #--------------------------------------------------------------------------
  # * Execute Save
  #--------------------------------------------------------------------------
  def do_quicksave
    do_erase
    write_quicksave_data
  end
  #--------------------------------------------------------------------------
  # * Execute Load
  #--------------------------------------------------------------------------
  def do_quickload
    if @quicksave[15] == "true"
      read_quicksave_data
      $scene = Scene_Map.new
      RPG::BGM.fade(1500)
      Graphics.fadeout(60)
      Graphics.wait(40)
      @last_bgm.play
      @last_bgs.play
    else
      $game_temp          = Game_Temp.new
      $game_message       = Game_Message.new
      num_of_lives        = $game_system.lives
      $game_system        = Game_System.new
      $game_system.lives  = num_of_lives
      $game_switches      = Game_Switches.new
      $game_variables     = Game_Variables.new
      $game_self_switches = Game_SelfSwitches.new
      $game_actors        = Game_Actors.new
      $game_party         = Game_Party.new
      $game_troop         = Game_Troop.new
      $game_map           = Game_Map.new
      $game_player        = Game_Player.new
      $game_party.setup_starting_members            # Initial party
      $game_map.setup($data_system.start_map_id)    # Initial map position
      $game_player.moveto($data_system.start_x, $data_system.start_y)
      $game_player.refresh
      $scene = Scene_Map.new
      RPG::BGM.fade(1500)
      Graphics.fadeout(60)
      Graphics.wait(40)
      Graphics.frame_count = 0
      RPG::BGM.stop
      $game_map.autoplay
    end
  end 
  #--------------------------------------------------------------------------
  # * Write Quicksave Data
  #     file : write file object (opened)
  #-------------------------------------------------------------------------- 
  def write_quicksave_data
    characters = []
    for actor in $game_party.members
      characters.push([actor.character_name, actor.character_index])
    end
    $game_system.version_id = $data_system.version_id
    @last_bgm = RPG::BGM::last
    @last_bgs = RPG::BGS::last
    @quicksave[1] = Marshal.dump(characters)
    @quicksave[2] = Marshal.dump(Graphics.frame_count)
    @quicksave[3] = Marshal.dump(@last_bgm)
    @quicksave[4] = Marshal.dump(@last_bgs)
    @quicksave[5] = Marshal.dump($game_system)
    @quicksave[6] = Marshal.dump($game_message)
    @quicksave[7] = Marshal.dump($game_switches)
    @quicksave[8] = Marshal.dump($game_variables)
    @quicksave[9] = Marshal.dump($game_self_switches)
    @quicksave[10] = Marshal.dump($game_actors)
    @quicksave[11] = Marshal.dump($game_party)
    @quicksave[12] = Marshal.dump($game_troop)
    @quicksave[13] = Marshal.dump($game_map)
    @quicksave[14] = Marshal.dump($game_player)
    @quicksave[15] = "true"
  end
  #--------------------------------------------------------------------------
  # * Read Quicksave Data
  #     file : file object for reading (opened)
  #--------------------------------------------------------------------------
  def read_quicksave_data
    characters           = Marshal.load(@quicksave[1])
    Graphics.frame_count = Marshal.load(@quicksave[2])
    @last_bgm            = Marshal.load(@quicksave[3])
    @last_bgs            = Marshal.load(@quicksave[4])
    $game_system         = Marshal.load(@quicksave[5])
    $game_message        = Marshal.load(@quicksave[6])
    $game_switches       = Marshal.load(@quicksave[7])
    $game_variables      = Marshal.load(@quicksave[8])
    $game_self_switches  = Marshal.load(@quicksave[9])
    $game_actors         = Marshal.load(@quicksave[10])
    $game_party          = Marshal.load(@quicksave[11])
    $game_troop          = Marshal.load(@quicksave[12])
    $game_map            = Marshal.load(@quicksave[13])
    $game_player         = Marshal.load(@quicksave[14])
    if $game_system.version_id != $data_system.version_id
      $game_map.setup($game_map.map_id)
      $game_player.center($game_player.x, $game_player.y)
    end
  end
end

#==============================================================================
# ** Scene_File
#------------------------------------------------------------------------------
#  Modifying the save screen to create new checkpoints.
#==============================================================================

class Scene_File
  #--------------------------------------------------------------------------
  # * Execute Save
  #--------------------------------------------------------------------------
  alias_method :quicksave_1, :do_save
  def do_save
    quicksave_1
    $game_checkpoint.do_quicksave
  end
  #--------------------------------------------------------------------------
  # * Execute Load
  #--------------------------------------------------------------------------
  alias_method :quicksave_2, :do_load
  def do_load
    quicksave_2
    $game_checkpoint.do_quicksave
  end
end

#==============================================================================
# ** Game_Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Adding the checkpoint call script.
#==============================================================================

class Game_Interpreter
  #--------------------------------------------------------------------------
  # * Checkpoint
  #--------------------------------------------------------------------------
  def checkpoint
    $game_checkpoint.do_quicksave
  end
  #--------------------------------------------------------------------------
  # * Checkpoint Load
  #--------------------------------------------------------------------------
  def checkpoint_load
    $game_checkpoint.do_quickload
  end 
end

#==============================================================================
# ** Scene_Gameover
#------------------------------------------------------------------------------
#  Modifying the gameover screen to include continuing from checkpoints.
#==============================================================================

class Scene_Gameover
  #--------------------------------------------------------------------------
  # * Start processing
  #--------------------------------------------------------------------------
  alias_method :continuing1, :start
  def start
    continuing1
    if $BTEST
      $game_system.continues_enabled = false
    end
    if $game_system.lives != 0 and $game_system.continues_enabled
      create_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Post-Start Processing
  #--------------------------------------------------------------------------
  def post_start
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      open_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Pre-termination Processing
  #--------------------------------------------------------------------------
  def pre_terminate
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      close_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Termination Processing
  #-------------------------------------------------------------------------- 
  alias_method :continuing2, :terminate
  def terminate
    continuing2
    if $game_system.lives != 0 and $game_system.continues_enabled
      dispose_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      if @command_window.openness == 255
        @command_window.update
        if Input.trigger?(Input::C)
          case @command_window.index
          when 0    #Continue
            Sound.play_load
            RPG::ME.stop
            close_command_window
            num_of_lives = $game_system.lives
            $game_checkpoint.do_quickload
            $game_system.lives = num_of_lives
            if $game_system.lives > 0
              $game_system.lives -= 1
            end
          when 1    #Return to Title
            if $game_system.return_to_title == true
              Sound.play_decision
              RPG::BGM.fade(800)
              RPG::BGS.fade(800)
              RPG::ME.fade(800)
              $scene = Scene_Title.new
              close_command_window
              Graphics.fadeout(60)
            else    #Shutdown
              Sound.play_decision
              close_command_window
              RPG::BGM.fade(800)
              RPG::BGS.fade(800)
              RPG::ME.fade(800)
              $scene = nil
            end
          end
        end
      end
    else
      if Input.trigger?(Input::C)
        $scene = Scene_Title.new
        Graphics.fadeout(120)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Create Game Over Graphic
  #--------------------------------------------------------------------------
  def create_gameover_graphic
    @sprite = Sprite.new
    file = $game_system.continue_graphic
    file_exist = FileTest.exist?("Graphics/System/" + file)
    continue_on = $game_system.continues_enabled
    if $BTEST
      continue_on = false
    end
    if file_exist==true and $game_system.lives !=0 and continue_on == true
      @sprite.bitmap = Cache.system("Continue")
    else
      @sprite.bitmap = Cache.system("GameOver")
    end
  end
  #--------------------------------------------------------------------------
  # * Create Command Window
  #--------------------------------------------------------------------------
  def create_command_window
    s1=$game_system.lives>0 ? "Continue: "+"#{$game_system.lives}":"Continue"
    s2=$game_system.return_to_title ? Vocab::to_title : Vocab::shutdown
    @command_window = Window_Command.new(173, [s1, s2])
    @command_window.x = (544 - @command_window.width) / 2
    @command_window.y = 264
    @command_window.openness = 0
  end
  #--------------------------------------------------------------------------
  # * Dispose of Command Window
  #--------------------------------------------------------------------------
  def dispose_command_window
    @command_window.dispose
  end
  #--------------------------------------------------------------------------
  # * Open Command Window
  #--------------------------------------------------------------------------
  def open_command_window
    @command_window.open
    begin
      @command_window.update
      Graphics.update
    end until @command_window.openness == 255
  end
  #--------------------------------------------------------------------------
  # * Close Command Window
  #--------------------------------------------------------------------------
  def close_command_window
    @command_window.close
    begin
      @command_window.update
      Graphics.update
    end until @command_window.openness == 0
  end
end

Credit

Thanks
Demo

See attached.
Title: Re: Checkpoints and Continues (VX)
Post by: Infinate X on March 17, 2011, 05:38:31 PM
Awesome script!
Title: Re: Checkpoints and Continues (VX)
Post by: tSwitch on March 31, 2011, 12:39:49 PM
Zylos wrote a script?
:O

Nice.
Title: Re: Checkpoints and Continues (VX)
Post by: pacdiggity on April 01, 2011, 10:50:19 AM
Zylos wrote several scripts.
They are all nice.
This one, imo, offers the best feature. It's a great idea and will help with most platformers (you're making a platformer in VX?) or slow-paced kinda-action games (like mine :P).
The mastermind one is hella cool too. ;)
Title: Re: Checkpoints and Continues (VX)
Post by: qJusticeOne5 on May 20, 2011, 02:36:33 PM
nice script...
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 16, 2011, 03:25:03 AM
I'm using an evented game over screen. Would it be possible to call the continue option from an event and forgo the continue screen entirely?
Title: Re: Checkpoints and Continues (VX)
Post by: Zylos on October 16, 2011, 03:26:37 AM
You mean like using a call script to automatically return to the checkpoint?

You should be able to do so with "$game_checkpoint.do_quickload", I believe.
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 16, 2011, 03:53:06 AM
Yeah, I think that would work, but how do I bypass the continue screen?
Title: Re: Checkpoints and Continues (VX)
Post by: Zylos on October 16, 2011, 04:08:15 AM
Oh, even better, I forgot you could simply use "checkpoint_load" in a script call slot, and it'll load from the last checkpoint. The default game over will work as normal if you turn the script off in the edit region, but the checkpoint_load command will still work just the same for you.
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 18, 2011, 04:28:02 AM
Okay, I'm derping again. Since I'm calling it from the game over map, it auto-checkpoints at the game over map transition. .-.
Is there a way to stop this?
Title: Re: Checkpoints and Continues (VX)
Post by: Zylos on October 18, 2011, 04:52:54 AM
Is your game over map an actual map, or a script that you're calling?
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 18, 2011, 05:23:47 AM
Actual map.
Title: Re: Checkpoints and Continues (VX)
Post by: Zylos on October 18, 2011, 05:27:55 AM
Hm. It shouldn't be making another checkpoint unless you specifically have an event creating one. Are you certain that there are no events with the checkpoint code in them running during the transition or in a common event?
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 18, 2011, 05:39:49 AM
As far as I can see, no, but I do have a habit of overlooking things, so I'll keep looking.
Title: Re: Checkpoints and Continues (VX)
Post by: Zylos on October 18, 2011, 05:43:07 AM
No loops or parallel processes or anything with them? As far as I've been able to test, it can't create them without the checkpoint code in an event.
Title: Re: Checkpoints and Continues (VX)
Post by: Acolyte on October 18, 2011, 11:20:25 PM
Found the problem. There was a rogue checkpoint set to parallel process. :facepalm: