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.

[VX] and [XP] Self Variables

Self Variables
Version 1.0
By: DrakoShade

What it Does
This script adds Self-Variables (like Self-Switches, but more than two options) to your events.  Treat them like what they are--  a hybrid between Global Variables and Self-Switches.  Each event will only want to look at and modify its own, so you can make a single event that uses @self_variable[1], copy-and-paste it 50 times on 10 different maps, and each one of them will be looking at its very own @self_variable[1], for whatever internal conditional branches or page conditions you told the original to use.

Features
  • Number of self_variables not inherently limited.
  • Easy usage within events.
  • Each event page can use either a Game Variable or a Self Variable as a condition.

Script
Code:
#==============================================================================
# ** Game_SelfVariables
#------------------------------------------------------------------------------
#  This class handles self variables. It's a wrapper for the built-in class
#  "Hash." Refer to "$game_self_variables" for the instance of this class.
#==============================================================================

class Game_SelfVariables
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    @data = {}
  end
  #--------------------------------------------------------------------------
  # * Get Self Variable
  #     key : key
  #--------------------------------------------------------------------------
  def [](key)
    return @data[key] == nil ? 0 : @data[key]
  end
  #--------------------------------------------------------------------------
  # * Set Self Variable
  #     key   : key
  #     value : the variable's value
  #--------------------------------------------------------------------------
  def []=(key, value)
    @data[key] = [[value, -99999999].max, 99999999].min
  end
end


#==============================================================================
# ** Self Variable Interpreter
#------------------------------------------------------------------------------
# This class handles the translation of $game_self_variables into an array
# so that any individual event can treat its own self_variables as such.  It's
# pretends to be an Array, so far as the interaction requires.
#==============================================================================

class SelfVarInterpreter
  attr_accessor :key
  #---------------------------------------------------------------------------
  # * Object Initialization
  #     key = [$game_map.map_id, @event_id]
  #---------------------------------------------------------------------------
  def initialize
    @key = [0, 0]
  end
  #---------------------------------------------------------------------------
  # * Get Self Variable
  #     variable_id : variable's ID
  #---------------------------------------------------------------------------
  def [](variable_id)
    key = [@key[0], @key[1], variable_id]
    return $game_self_variables[key]
  end
  #---------------------------------------------------------------------------
  # * Set Self Variable
  #     variable_id : variable's ID
  #     value       : the variable's value
  #---------------------------------------------------------------------------
  def []=(variable_id, value)
    key = [@key[0], @key[1], variable_id]
    $game_self_variables[key] = value
    $game_map.need_refresh = true
  end
end


#==============================================================================
# ** Interpreter
#==============================================================================

class Interpreter
  #---------------------------------------------------------------------------
  # * Initialize
  #---------------------------------------------------------------------------
  alias ds_self_variables_initialize initialize
  def initialize(depth = 0, main = false)
    @self_variables = SelfVarInterpreter.new
    ds_self_variables_initialize(depth, main)
  end
  #---------------------------------------------------------------------------
  # * Setup
  #---------------------------------------------------------------------------
  alias ds_self_variables_setup setup
  def setup(list, event_id)
    ds_self_variables_setup(list, event_id)
    @self_variables.key = [@map_id, @event_id]
  end
end



#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# Change the Refresh method to seek out comments containing "use self_variable"
# and, if it finds one, use the self_variables instead of game_variables to
# determine whether a page is active.
#==============================================================================

class Game_Event
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    # Initialize local variable: new_page
    new_page = nil
    # If not temporarily erased
    unless @erased
      # Check in order of large event pages
      for page in @event.pages.reverse
        # Make possible referrence for event condition with c
        c = page.condition
        # Switch 1 condition confirmation
        if c.switch1_valid
          if $game_switches[c.switch1_id] == false
            next
          end
        end
        # Switch 2 condition confirmation
        if c.switch2_valid
          if $game_switches[c.switch2_id] == false
            next
          end
        end
        # Variable condition confirmation
        if c.variable_valid
          #--------------------------------------------------------------------
          # Changes begin here.
          #--------------------------------------------------------------------
          for i in 0...page.list.size
            if page.list[i].code == 108
              if page.list[i].parameters[0].include?("use self variable")
                use_self_variable = true
              end
            end
          end
          if use_self_variable == true
            key = [@map_id, @id, c.variable_id]
            if $game_self_variables[key] < c.variable_value
              next
            end
          else
            if $game_variables[c.variable_id] < c.variable_value
              next
            end
          end
          #--------------------------------------------------------------------
          # Changes end here.
          #--------------------------------------------------------------------
        end
        # Self switch condition confirmation
        if c.self_switch_valid
          key = [@map_id, @event.id, c.self_switch_ch]
          if $game_self_switches[key] != true
            next
          end
        end
        # Set local variable: new_page
        new_page = page
        # Remove loop
        break
      end
    end
    # If event page is the same as last time
    if new_page == @page
      # End method
      return
    end
    # Set @page as current event page
    @page = new_page
    # Clear starting flag
    clear_starting
    # If no page fulfills conditions
    if @page == nil
      # Set each instance variable
      @tile_id = 0
      @character_name = ""
      @character_hue = 0
      @move_type = 0
      @through = true
      @trigger = nil
      @list = nil
      @interpreter = nil
      # End method
      return
    end
    # Set each instance variable
    @tile_id = @page.graphic.tile_id
    @character_name = @page.graphic.character_name
    @character_hue = @page.graphic.character_hue
    if @original_direction != @page.graphic.direction
      @direction = @page.graphic.direction
      @original_direction = @direction
      @prelock_direction = 0
    end
    if @original_pattern != @page.graphic.pattern
      @pattern = @page.graphic.pattern
      @original_pattern = @pattern
    end
    @opacity = @page.graphic.opacity
    @blend_type = @page.graphic.blend_type
    @move_type = @page.move_type
    @move_speed = @page.move_speed
    @move_frequency = @page.move_frequency
    @move_route = @page.move_route
    @move_route_index = 0
    @move_route_forcing = false
    @walk_anime = @page.walk_anime
    @step_anime = @page.step_anime
    @direction_fix = @page.direction_fix
    @through = @page.through
    @always_on_top = @page.always_on_top
    @trigger = @page.trigger
    @list = @page.list
    @interpreter = nil
    # If trigger is [parallel process]
    if @trigger == 4
      # Create parallel process interpreter
      @interpreter = Interpreter.new
    end
    # Auto event start determinant
    check_event_trigger_auto
  end
end


#==============================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
# Aliases are made to properly initialize self variables.
#==============================================================================

class Scene_Title
  alias ds_self_variables_command_new_game command_new_game
  def command_new_game
    $game_self_variables = Game_SelfVariables.new
    ds_self_variables_command_new_game
  end
  
  alias ds_self_variables_battle_test battle_test
  def battle_test
    $game_self_variables = Game_SelfVariables.new
    ds_self_variables_battle_test
  end
end

#==============================================================================
# ** Scene_Save
#------------------------------------------------------------------------------
# Adding $game_self_variables.
#==============================================================================

class Scene_Save
  alias ds_self_variables_write_save_data write_save_data
  def write_save_data(file)
    ds_self_variables_write_save_data(file)
    Marshal.dump($game_self_variables, file)
  end
end

#==============================================================================
# ** Scene_Load
#------------------------------------------------------------------------------
# Adding $game_self_variables.
#==============================================================================

class Scene_Load
  alias ds_self_variables_read_save_data read_save_data
  def read_save_data(file)
    ds_self_variables_read_save_data(file)
    $game_self_variables        = Marshal.load(file)
  end
end

Code:
#==============================================================================
# ** Game_SelfVariables
#------------------------------------------------------------------------------
#  This class handles self variables. It's a wrapper for the built-in class
#  "Hash." Refer to "$game_self_variables" for the instance of this class.
#==============================================================================

class Game_SelfVariables
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    @data = {}
  end
  #--------------------------------------------------------------------------
  # * Get Self Variable
  #     key : key
  #--------------------------------------------------------------------------
  def [](key)
    return @data[key] == nil ? 0 : @data[key]
  end
  #--------------------------------------------------------------------------
  # * Set Self Variable
  #     key   : key
  #     value : the variable's value
  #--------------------------------------------------------------------------
  def []=(key, value)
    @data[key] = [[value, -99999999].max, 99999999].min
  end
end


#==============================================================================
# ** Self Variable Interpreter
#------------------------------------------------------------------------------
# This class handles the translation of $game_self_variables into an array
# so that any individual event can treat its own self_variables as such.  It's
# pretends to be an Array, so far as the interaction requires.
#==============================================================================

class SelfVarInterpreter
  attr_accessor :key
  #---------------------------------------------------------------------------
  # * Object Initialization
  #     key = [$game_map.map_id, @event_id]
  #---------------------------------------------------------------------------
  def initialize
    @key = [0, 0]
  end
  #---------------------------------------------------------------------------
  # * Get Self Variable
  #     variable_id : variable's ID
  #---------------------------------------------------------------------------
  def [](variable_id)
    key = [@key[0], @key[1], variable_id]
    return $game_self_variables[key]
  end
  #---------------------------------------------------------------------------
  # * Set Self Variable
  #     variable_id : variable's ID
  #     value       : the variable's value
  #---------------------------------------------------------------------------
  def []=(variable_id, value)
    key = [@key[0], @key[1], variable_id]
    $game_self_variables[key] = value
    $game_map.need_refresh = true
  end
end


#==============================================================================
# ** Game_Interpreter
#==============================================================================

class Game_Interpreter
  
  #---------------------------------------------------------------------------
  # * Initialize
  #---------------------------------------------------------------------------
  alias ds_self_variables_initialize initialize
  def initialize(depth = 0, main = false)
    @self_variables = SelfVarInterpreter.new
    ds_self_variables_initialize(depth, main)
  end
  #---------------------------------------------------------------------------
  # * Setup
  #---------------------------------------------------------------------------
  alias ds_self_variables_setup setup
  def setup(list, event_id)
    ds_self_variables_setup(list, event_id)
    @self_variables.key = [@map_id, @event_id]
  end
end

#==============================================================================
# ** Game_Event
#==============================================================================

class Game_Event
  
  #--------------------------------------------------------------------------
  # * Determine if Event Page Conditions are Met
  #--------------------------------------------------------------------------
  def conditions_met?(page)
    c = page.condition
    if c.switch1_valid      # Swtich 1
      return false if $game_switches[c.switch1_id] == false
    end
    if c.switch2_valid      # Swtich 2
      return false if $game_switches[c.switch2_id] == false
    end
    if c.variable_valid     # Variable
      #----------------------------------------------------------------------
      # Changes begin here.
      #----------------------------------------------------------------------
      for i in 0...page.list.size
        if page.list[i].code == 108
          if page.list[i].parameters[0].include?("use self variable")
            use_self_variable = true
          end
        end
      end
      if use_self_variable == true
        key = [@map_id, @id, c.variable_id]
        return false if $game_self_variables[key] < c.variable_value
      else
        return false if $game_variables[c.variable_id] < c.variable_value
      end
      #----------------------------------------------------------------------
      # Changes end here.
      #----------------------------------------------------------------------
    end
    if c.self_switch_valid  # Self switch
      key = [@map_id, @event.id, c.self_switch_ch]
      return false if $game_self_switches[key] != true
    end
    if c.item_valid         # Item
      item = $data_items[c.item_id]
      return false if $game_party.item_number(item) == 0
    end
    if c.actor_valid        # Actor
      actor = $game_actors[c.actor_id]
      return false unless $game_party.members.include?(actor)
    end
    return true   # Conditions met
  end
end


#==============================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
# Appropriate aliasing made here to create the $game_self_variables hash.
#==============================================================================
class Scene_Title
  alias ds_self_variables_create_game_objects create_game_objects
  def create_game_objects
    $game_self_variables = Game_SelfVariables.new
    ds_self_variables_create_game_objects
  end
end

#==============================================================================
# ** Scene_File
#------------------------------------------------------------------------------
# Self variables added to save_data and load_data.
#==============================================================================
class Scene_File
  alias ds_self_variables_write_save_data write_save_data
  def write_save_data(file)
    ds_self_variables_write_save_data(file)
    Marshal.dump($game_self_variables, file)
  end
  
  alias ds_self_variables_read_save_data read_save_data
  def read_save_data(file)
    ds_self_variables_read_save_data(file)
    $game_self_variables = Marshal.load(file)
  end
end

Instructions
Installation
For RMXP: Paste above main.
For RMVX: Paste in the Materials section.

Usage
To call a specific self_variable from outside the event that owns it, use the following:
Code:
$game_self_variables[[map_id, event_id, variable_id]]
For example:
Code:
$game_self_variables[[1, 3, 2]] += 1
Event 3 on Map 1 would have its self_variable 2 modified by adding 1.  Hopefully, that makes sense.

This script was designed, however, to be made use of from within the event itself.  To call an event's self_variables from the Script command or the Script option of a Conditional Branch, it's much simpler:
Code:
@self_variables[variable]
Thus, if Event 3 on Map 1 needs to add 1 to its Variable 2, you do this within the event
Code:
@self_variables[2] += 1

In order to use a self_variable in place of a game_variable when determining page conditions, simply include the following comment on the page in question:
Code:
use self variable
Unfortunately, you cannot use both types of variable in page conditions.

Compatibility
Not even tested with SDK.  Compatibility doubtful.  For RMXP, not compatible with anything else that alters the refresh method of Game_Event.
For RMVX, not compatible with anything that alters the conditions_met? method of Game_Event.

To Do
  • SDK version of the RMXP script
  • Clean up code
  • Reformat post when I'm more awake.

Parting Comments
Both versions of this script worked through the testing I was able to do.  If errors creep up, please be specific about how you got them, and exactly what error you received.
 

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