Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - modern algebra

1
RMVX Script Database / Re: [VX] Quest Journal
January 28, 2012, 03:31:02 pm
Sorry for not responding earlier, but I haven't been around. Anyway, the problem can be fixed by doing something like this:


q = $game_party.quests[20]
q.complete_objective(0)


Hopefully that helps.
2
Tasks / Re: RGSS Questions and Answers
April 26, 2011, 12:12:02 am
I'm talking about Window too. It sets it to nil if you don't pass a viewport to the initialize method, but if you create the window like:


Window.new (viewport)


then the viewport method will return the viewport you passed and it will operate on the window. You might be right that it's never used though.
3
Tasks / Re: RGSS Questions and Answers
April 25, 2011, 10:00:31 pm
I think the viewport is set when you initialize the window, and you can pass it as an argument to the initialize method. The only time I've ever used it is when I am showing a non-opaque window over another window that isn't the same size. I just changed the dimensions of the viewport so that it excluded the area where the new window popped up for as long as the new window was visible - that way, the contents of the bottom window didn't obscure the contents of the top one. There are probably more profitable uses.
4
RMXP Script Database / Re: [XP] Tons of Add-ons
December 06, 2010, 08:15:24 pm
haha, no! I am very disappointed in him and intend to come down on him with the crushing force of a sledgehammer for this egregious error :P
5
RMXP Script Database / Re: [XP] Tons of Add-ons
December 02, 2010, 07:51:23 pm
Hey, somebody reported an error with this script: http://rmrk.net/index.php/topic,40930.msg468940.html#msg468940

I didn't look at it in-depth, but it seemed like game_guy just forgot to add an attr_accessor for :MONSTER_AREAS in Game_System. Anyway, figured you'd want to know.
6
RMVX Script Database / Re: [VX] Scene Tutorial
May 28, 2009, 11:56:49 pm
I currently have no intentions to make an XP version. SOrry :(

Though, to be honest, I don't imagine it would require much changes. I will look into it tomorrow maybe and if it seems easy enough, I will do it.
7
RMVX Script Database / Re: [VX] Quest Journal
March 03, 2009, 03:06:49 pm
I did not make a simple method to do that, namely because this was intended as a visual way to represent quests, and the original intention was  that quest progress would be created and tracked through eventing means, such as turning a switch on when that matters. That may have been an oversight on my part. Anyway, there is a code that can be used, but it's long:
$game_party.quests[quest_id].complete_objectives.include? (objective_id)



For revealing all of the objectives, and just checking them off, when they are complete, yeah. All you need to do is use the code:

$game_party.quests[quest_id].reveal_objective (objective_id)


And that wil reveal the objective in the quest menu.

$game_party.quests[quest_id].complete_objective (objective_id)


completes it. So just use reveal_objective on all objectives at the start of the quest and then complete them one by one.
8
(A) $game_temp is not initialized until new game or Continue are selected, thus you are trying to use a method on a nil variable.

(B) It wouldn't work straight from the title because common events are updated in $game_map ~ meaning $game_map must exist and be updating.

There might be more that I'm missing since this is just off the top of my head, but the bottom line is that you should initialize all your $game_ variables ~ there might be a few you can ignore, but since you're calling Scene_Map you'll need at least all the $game_ variables involvedin operating that. I wouldn't mix common events in with this type of script though - better to design your own scene.
9
RMVX Script Database / [VX] Scene Tutorial
January 09, 2009, 07:48:39 pm
Scene Tutorial
Authors: modern algebra
Version: 1.0
Type: Utility for Creating Tutorials in Scripted Scenes
Key Term: Misc System



Introduction

This script allows you to create tutorials for the scenes in your game, such as for the menu or for the battle system, by freezing user input and allowing you to control the movement of the scene through a special tutorial common event.



Features


  • Create tutorials for your complicated scenes so that nobody is left without guidance.
  • Full control over input to the scene allows you to cover any of the features of your scene inside the scene itself.
  • Allows for the use of a number of event commands within the scene you are giving the tutorial, including, but not limited to, Show Text, Show Choics, Conditional Branch, and more.
  • Creating these tutorials, while it has a steep learning curve, is still pretty intuitive and easy once you get a hang of it.



Screenshots

Spoiler: ShowHide




Demo

Demo


Script

Spoiler: ShowHide


#==============================================================================
#  Scene Tutorial
#  Version 1.0
#  Author: modern algebra (rmrk.net)
#  Date: September 15, 2008
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Description:
#    This script allows you to freeze user input for a scene and run a special
#   common event that controls input. Effectively, this allows you to run a
#   scene and direct a tutorial to that scene that explains what the scene is.
#   So, if you ever wanted to give the players to your game a tutorial on
#   using the Menu scene, then this is the script for you.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Instructions:
#    Okay, this script can be slightly difficult to use, so you have to pay
#   careful attention to the instructions.
#
#    To start a tutorial, you must use a call script with this code:
#
#        $tutorial.start (scene, common event id)
#
#    where scene is the name of the scene to call, (like Scene_Menu or
#   Scene_Battle) and common event ID is the ID of the common event that
#   controls the tutorial. Now, that's the easy part. Setting up the controller
#   common event will be tricky at first, but once you get the hang of it,
#   you'll be fine. Now, read the instructions very carefully:
#
#    The Standard Wait Variable - You set what Variable this will be at line
#   200. The value of this variable determines how many frames to wait for
#   after each command.
#
#    The controller common event is similar to a regular common event in some
#   ways but many of the commands will be unavailable to you while others will
#   be irrelevant and others still will have a different effect than you would
#   expect. In the instructions, I will go over the functions of what will be
#   the most important commands in making a scene tutorial, but I just wanted
#   to warn you that many commands will not work as you expect them to. (For
#   instance, pictures, screen tone etc... will only work in a battle or map
#   tutorial). So, depending on how the scene is built, some things are
#   possible while others are not. Note, however, that in a number of cases,
#   you can simulate the effect that is not possible. That being said, it can
#   get quite convoluted, but that was as far as I was willing to go with this
#   script. I apologize for the difficulty.
#
#    Anyway, there are a couple of specialized commands that have their function
#   changed from what they would normally do. These are:
#
#      Control Variable
#      Set Move Route
#
#    These have been changed so that rather than do what they would normally,
#   they instead interpret input. Since player input is frozen during a
#   tutorial, scene movement is handled by you, the game creator. It is done
#   through these two commands. This can be rather non-intuitive, but for each
#   value of 0 through 19, a button is attached. It is similar for Set Move
#   Route, but let's go over the variable way of setting input first.
#
#    To set it, it must be a single variable set to a constant. If any other
#   option is chosen, then the Control Variable command will function normally.
#   Also, the control variable command will behave normally if the variable you
#   choose is the one you choose for setting standard wait time. Anyway, here
#   is the list of values and their effects:
#
#      0  - Down Cursor
#      1  - Left Cursor
#      2  - Right Cursor
#      3  - Up Cursor
#      4  - Button A
#      5  - Button B
#      6  - Button C
#      7  - Button X
#      8  - Button Y
#      9  - Button Z
#      10 - Button L
#      11 - Button R
#      12 - SHIFT
#      13 - CTRL
#      14 - ALT
#      15 - F5
#      16 - F6
#      17 - F7
#      18 - F8
#      19 - F9
#
#    If you want to wait some frames, the Wait command will work normally.
#
#    Set Move Route has a similar set of moves attached. They are:
#      Move Down             - Down Cursor
#      Move Left             - Left Cursor
#      Move Right            - Right Cursor
#      Move Up               - Up Cursor
#      Move Lower Left       - Button A
#      Move Lower Right      - Button B
#      Move Upper Left       - Button C
#      Move Upper Right      - Button X
#      Move at Random        - Button Y
#      Move Toward Player    - Button Z
#      Move Away from Player - Button L
#      One Step Forward      - Button R
#      One Step Backward     - SHIFT
#      Jump                  - CTRL
#      Wait                  - Waits for however many frames
#      Turn Down             - ALT
#      Turn Left             - F5
#      Turn Right            - F6
#      Turn Up               - F7
#      Turn 90 Left          - F8
#      Turn 90 Right         - F9
#
#   So basically, using those commands will make the scene react as if the
#  corresponding button had just been pressed.
#==============================================================================
# *** Input
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - trigger?, press?, repeat?
#==============================================================================

module Input
  class << self
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Frame Update
    #````````````````````````````````````````````````````````````````````````
    #  Updates tutorial as well if it exists. It does it in Input as all scenes
    # update Input every frame
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    alias modalg_tutorials_update_9rt update
    def update
      $tutorial.update if $tutorial.active?
      # Run Original Method
      modalg_tutorials_update_9rt
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Trigger?
    #````````````````````````````````````````````````````````````````````````
    #  If Tutorial is running, freezes input and accepts only tutorial input
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    alias modalg_tut_frz_inpt_trig_dj5 trigger?
    def trigger? (key)
      return $tutorial.button == key if $tutorial.active? && !$tutorial.upd_input
      # Run Original Method
      modalg_tut_frz_inpt_trig_dj5 (key)
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Repeat?
    #````````````````````````````````````````````````````````````````````````
    #  If Tutorial is running, freezes input and accepts only tutorial input
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    alias modalg_rpt_tutorial_upd_8fn repeat?
    def repeat? (key)
      return $tutorial.button == key if $tutorial.active? && !$tutorial.upd_input
      # Run Original Method
      modalg_rpt_tutorial_upd_8fn (key)
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Press?
    #````````````````````````````````````````````````````````````````````````
    #  If Tutorial is running, freezes input and accepts only tutorial input
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    alias modalg_tut_prs_frz_inpt_9nfg press?
    def press? (key)
      return $tutorial.button == key if $tutorial.active? && !$tutorial.upd_input
      # Run Original Method
      modalg_tut_prs_frz_inpt_9nfg (key)
    end
  end
end

#==============================================================================
# ** Tutorial Guide
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  This class handles the interpretation of the common event for a tutorial
#==============================================================================

class Game_TutorialGuide < Game_Interpreter
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Constant
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # STANDARD WAIT VARIABLE is the ID of the event variable that holds a
  #  standard wait between input commands. Basically, if this is set to 2,
  #  then Variable with ID 2 will control the wait between actions. So, if
  #  Variable with ID 2 is set to 4, then it will wait four frames before
  #  executing the next command in the common event
  STANDARD_WAIT_VARIABLE = 2
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize
    super
    @wait_frames = 0
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Control Variable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_122
    if @params[3] == 0 || @params[0] == STANDARD_WAIT_VARIABLE
      command_input (@params[4] + 1)
    else
      super
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Move Route
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_205
    @move_route = @params[1].list
    @moveroute_index = 0
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Wait
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_230
    command_wait (@params[0])
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Frame Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update
    # Wait
    if @wait_frames > 0
      @wait_frames -= 1
      return
    end
    # Execute Move Route Input
    unless @move_route.nil?
      loop do
        # Move on once move route exhausted
        if @moveroute_index >= (@move_route.size - 1)
          @move_route = nil
          @moveroute_index = 0
          break
        end
        # Execute Input command
        command_move (@move_route[@moveroute_index])
        @moveroute_index += 1
        return if @wait_frames > 0
      end
    end
    return false if @list.nil?
    return if !execute_command # Execute event command
    @index += 1 
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Command Input
  #    button_code : the key a button corresponds to.
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_input (button_value)
    $tutorial.button = case button_value
    when 1 then Input::DOWN      # Cursor Down
    when 2 then Input::LEFT      # Cursor Left
    when 3 then Input::RIGHT     # Cursor Right
    when 4 then Input::UP        # Cursor Up
    when 5 then Input::A         # Press A
    when 6 then Input::B         # Press B
    when 7 then Input::C         # Press C
    when 8 then Input::X         # Press X
    when 9 then Input::Y         # Press Y
    when 10 then Input::Z        # Press Z
    when 11 then Input::L        # Press L
    when 12 then Input::R        # Press R
    when 13 then Input::SHIFT    # Press SHIFT
    when 14 then Input::CTRL     # Press CTRL
    when 15 then Input::ALT      # Press ALT
    when 16 then Input::F5       # Press F5
    when 17 then Input::F6       # Press F6
    when 18 then Input::F7       # Press F7
    when 19 then Input::F8       # Press F8
    when 20 then Input::F9       # Press F9
    end
    @wait_frames = $game_variables[STANDARD_WAIT_VARIABLE]
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Command Move
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_move (command)
    command_input (command.code) if command.code < 15
    command_wait (command.parameters[0] - 1) if command.code == 15
    command_input (command.code - 1) if command.code.between? (16, 21)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Command Wait
  #    duration : the number of frames to wait
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def command_wait (duration)
    # Wait Frames - Subtract Standard wait frames tacked on by previous command
    @wait_frames = duration
  end
end

#==============================================================================
# ** Tutorial
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  This class basically interprets a common event and navigates a scene by the
# codes used in that common event
#==============================================================================

class Tutorial
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_reader   :upd_input
  attr_accessor :button
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def initialize
    # Initialize variables
    @button = false
    @upd_input = false
    @active = false
    @tutorial_guide = Game_TutorialGuide.new
    @index = 0
    @wait_frames = 0
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Start
  #    scene           : the scene to guide through
  #    common_event_id : the navigation common event
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def start (scene, common_event_id)
    # Get Common Event
    @tutorial_guide.setup ($data_common_events[common_event_id].list)
    # Initialize Scene
    $scene = scene.new
    @active = true
    # Initialize Message window here because uses $game variables.
    if @message_window.nil?
      @game_message = Game_Message.new
      @message_window = Window_Message.new
      @message_window.z = 210
    end
    # Reset Saved values
    if $scene.is_a? (Scene_Menu)
      $game_party.last_item_id = 0
      $game_party.last_actor_index = 0
      $game_party.last_target_index = 0
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update
    if @real_game_message.nil?
      @real_game_message = $game_message
      $game_message = @game_message
    end
    @button = nil
    @upd_input = true
    @message_window.update
    @upd_input = false
    if $game_message.visible
      $game_message = @real_game_message
      @real_game_message = nil
      return
    end
    @active = false if @tutorial_guide.update == false
    $game_message = @real_game_message
    @real_game_message = nil
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Active?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def active?
    return @active
  end
end

#==============================================================================
# ** Scene_Title
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - start
#==============================================================================

class Scene_Title
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Load Database
  #``````````````````````````````````````````````````````````````````````````
  #  Initialize $tutorial
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_tutorial_scenes_ldb_init_nf4 load_database
  def load_database
    # Run Original Method
    modalg_tutorial_scenes_ldb_init_nf4
    # Initialize Tutorial
    $tutorial = Tutorial.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Load Battle Test Database
  #``````````````````````````````````````````````````````````````````````````
  #  Initialize $tutorial
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_tutrl_scn_lbtdb_ak42 load_bt_database
  def load_bt_database
    # Run Original Method
    modalg_tutrl_scn_lbtdb_ak42
    # Initialize Tutorial
    $tutorial = Tutorial.new
  end
end



Instructions

Instructions are quite long and can be found in the Header of the Script. Be sure to read them all in order to understand how you can best use this script. Also, I suggest you copy out the special commands on a piece of paper so that you won't have to refer back to the script when making your tutorials.

I suggest also that you download the demo, as that will give you a better idea of how to set up the tutorial common events.


Compatibility

May not work on some exotic scenes, or with some scripts that significantly alter the Input module or the way it is used.


Credits and Thanks


  • modern algebra



Author's Notes

Nothing too interesting to say. This script was fun to make however, so thank you to grafikal006 for the request.
10
RMVX Script Database / Re: [VX] Quest Journal
January 09, 2009, 07:33:58 pm
Whoa, I haven't been here for a long time. Thanks for doing that Blizzard. :) I didn't know I could link to attached files like that.
11
RMVX Script Database / [VX] Sound Emitting Areas
July 26, 2008, 11:59:26 pm
Sound Emitting Area
Authors: modern algebra
Version: 1.0b
Type: Music Environment Effect
Key Term: Environment Add-on



Introduction

This script allows you to set a bgm, bgs, se, or me to areas and itdynamically changes the volume depending on how far the player is from the area, creating the impression that the sound is emitting from that area.


Version History


  • <Version 1.0> - Original Release July 26, 2008




Features


  • Can set a bgm, bgs, se, or me

  • Smooth volume transition

  • Allows you to set SE repetition by frames and with variance

  • Lots of options for configuring each sound




Screenshots

Not applicable for this script. See the Demo for a better understanding of the script.


Demo

http://www.sendspace.com/file/n2nu5f


Script
Spoiler: ShowHide

#==============================================================================
#  Sound Emitting Areas (VX)
#  Version 1.0b
#  Author: modern algebra (rmrk.net)
#  Date: July 26, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Description:
#    This script allows you to set a bgm, bgs, se, or me to areas and it
#    dynamically changes the volume depending on how far the player is from the
#    area, creating the impression that the sound is emitting from that area.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    See the CONFIGURABLE REGION at line 45
#==============================================================================

#==============================================================================
# ** RPG::Area
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    new instance variables - se_frames, se_frame_variance, me_frames,
#                             me_frame_variance
#    new methods - setup_sound_emissions, bgm, bgs, me, se, bgm?, bgs?, se?,
#                me?, volume, update_se, update_me
#==============================================================================

class RPG::Area
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_reader   :se_frames
  attr_reader   :se_frame_variance
  attr_reader   :me_frames
  attr_reader   :me_frame_variance
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Setup Sound Emissions
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def setup_sound_emissions
    # Set Default Values
    @bgs_name, @bgs_pitch, @bgs_radius, @bgs_max_volume = '', 100, 10, 100
    @bgm_name, @bgm_pitch, @bgm_radius, @bgm_max_volume = '', 100, 10, 100
    @se_name, @se_pitch, @se_radius, @se_max_volume = '', 100, 10, 100
    @me_name, @me_pitch, @me_radius, @me_max_volume = '', 100, 10, 100
    @se_frames, @se_frame_variance, @me_frames, @me_frame_variance = 20, 0, 20, 0
    case @id
    #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    #  !*!*! CONFIGURABLE REGION
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #  Set this region up in this way:
    #   
    #    when area_id
    #      @bgm_name = 'Name of BGM you wish to emit'
    #      @bgm_pitch = the pitch of the BGM, from 50 to 150
    #      @bgm_radius = the radius, in squares, of BGM range.
    #      @bgm_max_volume = The maximum volume of the BGM
    #      @bgs_name = 'Name of BGS you wish to emit'
    #      @bgs_pitch = the pitch of the BGS, from 50 to 150
    #      @bgs_radius = the radius, in squares, of BGS range.
    #      @bgs_max_volume = The maximum volume of the BGS
    #      @se_name = 'Name of SE you wish this area to emit'
    #      @se_pitch = the pitch of the SE, from 50 to 150
    #      @se_radius = the radius, in squares, of the SE range
    #      @se_max_volume = the maximum volume of the SE
    #      @se_frames = the average number of frames between playing the SE
    #      @se_frame_variance = how many more or less frames off the average is the range
    #      @me_name = 'Name of ME you wish this area to emit'
    #      @me_pitch = the pitch of the ME, from 50 to 150
    #      @me_radius = the radius, in squares, of the ME range
    #      @me_max_volume = the maximum volume of the ME
    #      @me_frames = the average number of frames between playing the ME
    #      @me_frame_variance = how many more or less frames off the average is the range
    #
    #  You can omit any of the above stats and they will set to default values,
    #    which are there are no names set, pitch = 100, radius = 10,
    #    max_volume = 100, frames = 20, and frame_variance = 0.
    #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    when 1 # Waterfall
      # BGS
      @bgs_name = 'River'
      @bgs_radius = 15
      @bgs_max_volume = 110
    when 4 # Chicken Coop
      # SE
      @se_name = 'Chicken'
      @se_max_volume = 75
      @se_frames = 120        # 120 average number of frames between chicken SE
      @se_frame_variance = 40 # [(120-40) - (120+40)] = 80-160 => Frame Range
    #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    #  !*!*! END CONFIGURABLE REGION
    #////////////////////////////////////////////////////////////////////////
    end
    # Initialize frame counts
    @se_frame_count = @se_frames + rand (2*@se_frame_variance) - @se_frame_variance
    @me_frame_count = @me_frames + rand (2*@me_frame_variance) - @me_frame_variance
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Sound
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_sound
    bgm.play if @bgm_name != ''
    bgs.play if @bgs_name != ''
    update_se if @se_name != ''
    update_me if @me_name != ''
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * BGM
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def bgm
    @bgm = RPG::BGM.new (@bgm_name, 0, @bgm_pitch) if @bgm == nil
    @bgm.volume = volume (@bgm_radius, @bgm_max_volume)
    return @bgm
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * BGS
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def bgs
    @bgs = RPG::BGS.new (@bgs_name, 0, @bgs_pitch) if @bgs == nil
    @bgs.volume = volume (@bgs_radius, @bgs_max_volume)
    return @bgs
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * SE
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def se
    @se = RPG::SE.new (@se_name, 0, @se_pitch) if @se == nil
    @se.volume = volume (@se_radius, @se_max_volume)
    return @se
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * SE Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_se
    if @se_frame_count == 0
      se.play
      @se_frame_count = @se_frames + rand (2*@se_frame_variance) - @se_frame_variance
    else
      @se_frame_count -= 1
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * ME
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def me
    @me = RPG::ME.new (@me_name, 0, @me_pitch) if @me == nil
    @me.volume = volume (@me_radius, @me_max_volume)
    return @me
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * ME Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_me
    if @me_frame_count == 0
      me.play
      @me_frame_count = @me_frames + rand (2*@me_frame_variance) - @me_frame_variance
    else
      @me_frame_count -= 1
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Volume
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def volume (radius, max_volume)
    x, y = $game_player.x, $game_player.y
    # Determine distance between position and the sound emitting object
    xd, yd = x - @rect.x, y - @rect.y
    # Evaluate X distance
    xd > 0 ? xd = x.between? (@rect.x, @rect.x + @rect.width) ? 0 : xd - @rect.width : xd *= -1
    # Evaluate Y distance
    yd > 0 ? yd = y.between? (@rect.y, @rect.y + @rect.height) ? 0 :yd - @rect.height : yd *= -1
    # Calculate the total distance
    total_distance = Math.sqrt(xd*xd + yd*yd).ceil.to_i
    # Get the percentage of max volume
    percent = (total_distance.to_f / radius.to_f)*100
    percent = (100 - [percent, 100].min).to_f / 100.0
    return (percent*max_volume.to_f).to_i
  end
end

#==============================================================================
# ** Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased method - update, setup
#==============================================================================

class Game_Map
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Setup
  #    map_id : the ID of the map
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_dynamic_snd_emit_stup_rn4 setup
  def setup(map_id)
    # Run Original Method
    modalg_dynamic_snd_emit_stup_rn4 (map_id)
    # Get all areas that belong to this map
    @areas = []
    $data_areas.values.each { |area| @areas.push (area) if map_id == area.map_id }
    # Ensure Area Sound Effects are setup
    @areas.each { |i| i.setup_sound_emissions if i.se_frames == nil }
    @advanced_areas_included = false
    begin
      # Test for exception thrown on .active?
      $data_areas[1].active?
      @advanced_areas_included = true
    rescue
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_dyn_sound_emitting_objects_upd_4h3 update
  def update
    # Run Original Map
    modalg_dyn_sound_emitting_objects_upd_4h3
    # For all area
    @areas.each { |area|
      next if @advanced_areas_included && !area.active?
      area.update_sound
    }
  end
end



Instructions

See inside the script.


Compatibility

There should not be any Compatibility errors. If there are, post either here or RMRK.net .


Credits and Thanks


  • modern algebra




Author's Notes

Please post at rmrk.net for the swiftest support, as I am not as active here as I should be.

This script is based off of the version I wrote for RMXP with a number of significant alterations. This script is completely compatible with my Advanced Areas script, and I recommend it if you do not want the sounds playing all the time, as the Advanced Areas script includes a way to turn the area off by a switch and this script will recognize that command as well.
12
Sorry, there is now a sendspace link for the demo  :-[

I'm glad you guys like it though.
13
Composite Characters / Visual Equipment
Authors: modern algebra
Version: 1.0
Type: Graphic Add-on
Key Term: Player / Party / Troop Add-on



Introduction

This script allows you to create character sets from multiple character sheets, layering them on top of each other. It also allows you to set character graphics to armors and weapons, and these character sets will be layered on top of the character, thus making it a Visual Equipment script as well.


Features


  • Easy configuration

  • Hundreds of unique characters can be made from a limited set of resources.

  • Allows you to set hue for character sheets, meaning each resource can have hundreds of distinct colours.

  • Allows any weapon or armor to have any number of character sets stacked onto the character upon equip.

  • Events and Actors can also be set up so that they are composed of multiple character sets




Screenshots

Spoiler: ShowHide

All character sets seen composed of this one character sheet, with all resources taken from the character generator here: http://www.famitsu.com/freegame/tool/chibi/index1.html
Spoiler: ShowHide



Demo

Download


Script

Spoiler: ShowHide

#==============================================================================
#  Composite Characters / Visual Equipment
#  Version 1.2
#  Author: modern algebra (rmrk.net)
#  Date: May 29, 2009
#  Original Release Date: July 5, 2008
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Instructions:
#
#    Place this script in between Materials and Main in the Script Editor
#
#    Basically, to work this script you need to do two things. 1) Setup your
#  actors default character sets - you will see a full set of instructions at
#  line xx. Now, to set a graphic for an armor or weapon, all you need to do
#  is place this code in the Notes box of the item:
#
#    \CG[<Name of Character Set>, <index in character set>, <hue>, <z>]
#
#  If you leave out index, it defaults to 0 and if you leave out hue, it also
#  defaults to 0. You can put more than one graphic to an armor or weapon and
#  they will stack by priority (z). Things with lower priority are drawn first.
#
#    Setting up an Event is similar - all you need to do is place a comment at
#  the very beginning of the event and put in the same code to generate a
#  composite character set for the event. Same rules apply, and remember, you
#  can stack character sets.
#
#  EXAMPLES:
#    \cg[Actor1, 2]        # Character Set = Actor1 : index = 2 : hue = 0 : z = 0
#    \CG[Evil]             # Character Set = Evil   : index = 0 : hue = 0 : z = 0
#    \cG[Actor2, 3, 50, 2] # Character Set = Actor2 : index = 3 : hue = 50 : z = 2
#
#    You can now remove and add graphics to the actor using the following codes
#  in a script call:
#
#   remove_graphic_from_actor (actor_id, index)
#   remove_graphic_from_actor (actor_id, graphic_name, graphic_index, graphic_hue)
#   add_graphic_to_actor (actor_id, graphic_name, graphic_index, graphic_hue, index)
#
#  where:
#    actor_id      : the ID of the actor whose graphic you are changing
#    index         : the index of the graphic in the actor's composite_character
#    graphic_name  : the name of the character set
#    graphic_index : the index of the character file in the set
#    graphic_hue   : the hue of the graphic
#
#    Also, the Change Actor Graphic event command now adds character sets to
#  the current set. You can clear an actor's character set with the code:
#
#    clear_character_graphic (actor_id)
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Compatibility:
#
#    Unfortunately, I did need to overwrite some methods for this script, and
#  as such there are likely to be compatibility problems. I know that my
#  Extra Movement Frames Script certainly will not work with this script, and
#  any script that tampers with the way a character set is drawn will also
#  likely encounter problems. Now, this is not to say that any script that
#  draws a character set will be incompatible - as long as that scripter uses
#  the draw_actor_graphic method of Window_Base it should work fine - it is
#  only scripts that change the way a character set is drawn that will cause
#  problems. Also, I tamper with the load_gamedata method of Window_SaveFile,
#  and so if another script overwrites that then there will again be
#  compatibility issues. If you find a script that seems to cause problems,
#  please post at the topic at rmrk.net and I will try my best to assist you.
#
#    Diedrupo's Caterpillar Script does not work immediately. A fix is posted
#  in this script's topic at rmrk.net.
#    Tankentai Sideview Battle System will not use composite character sprites
#  without a fix. That fix is also posted in this script's topic at rmrk.net
#==============================================================================

#==============================================================================
# *** module Cache
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new method - composite_character
#==============================================================================

module Cache
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Composite Character
  #    char_array : An array holding the names of all parts of a graphic
  #``````````````````````````````````````````````````````````````````````````
  #  Composes a single character bitmap out of all the ones given.
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def self.composite_character (char_array)
    @cache = {} if @cache == nil
    # Blank bitmap if there is nothing in the array.
    @cache[char_array] = Bitmap.new (32, 32) if char_array.empty?
    # If not in the cache
    if !@cache.include? (char_array) || @cache[char_array].disposed?
      # Create a template bitmap
      bitmap = Bitmap.new (32, 32)
      # Add in all other graphics
      char_array.each { |i|
        name, index, hue = i[0], i[1], i[2]
        # Bypass self.character in order to allow for setting hue
        bmp = load_bitmap ("Graphics/Characters/", name, hue)
        sign = name[/^[\!\$]./]
        # Get the width and height of the single character
        if sign != nil && sign.include? ('$')
          wdth, hght = bmp.width, bmp.height
        else
          wdth = bmp.width / 4
          hght = bmp.height / 2
        end
        # Expand bitmap if necessary
        if bitmap.width < wdth || bitmap.height < hght
          # Recreate bitmap
          temp_bmp = bitmap.dup
          bitmap = Bitmap.new ([temp_bmp.width, wdth].max, [temp_bmp.height, hght].max)
          bitmap.blt (0, 0, temp_bmp, temp_bmp.rect)
          temp_bmp.dispose
        end
        # Draw new character graphic onto bitmap
        src_rect = Rect.new ((index%4)*wdth, (index/4)*hght, wdth, hght)
        bitmap.blt (0, 0, bmp, src_rect)
      }
      @cache[char_array] = bitmap
    end
    return @cache[char_array]
  end
end

#==============================================================================
# ** RPG::BaseItem
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new method - character_graphics
#==============================================================================

class RPG::BaseItem
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Character Graphics
  #``````````````````````````````````````````````````````````````````````````
  #  Retrieves Character Graphics from Note Field
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def character_graphics
    graphics = []
    # Retrieve Note Field
    text = self.note.dup
    while text.sub! (/\\cg\[([^,\]]+),*\s*(\d*),*\s*(\d*),*\s*(\d*)\]/i) { '' } != nil
      a = [$1.to_s, ($2 != nil ? $2.to_i : 0), ($3 != nil ? $3.to_i : 0), ($4 != nil ? $4.to_i : 0)]
      graphics.push (a)
    end
    return graphics
  end
end

#==============================================================================
# ** Game_Actor
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new methods - composite_character, clear_character
#    aliased methods - initialize, change_equip, set_graphic
#    new public instance variables - ma_composite_character, ma_return_composite
#==============================================================================

class Game_Actor
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_accessor :ma_composite_character
  attr_accessor :ma_return_composite
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initalization
  #`````````````````````````````````````````````````````````````````````````
  #  Initializes stacked_character variable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_arclght_vsual_equip_init_4t6h initialize
  def initialize (id)
    # Run Original Method
    modalg_arclght_vsual_equip_init_4t6h (id)
    @ma_composite_character = []
    @ma_return_composite = false
    case @actor_id
    #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    # EDITABLE REGION
    #|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    #  An actor will automatically have whatever you set in the database
    #  as a bottom layer for him, but if you need to have other character
    #  sets piled on top, then put them in this format:
    #
    #  when <actor_id>
    #    @ma_composite_character.push (['graphic_name', index, hue, z])
    #      *for as many graphics as you want - first ones drawn first. If you
    #       want to know what each is, see the Instructions in the header.
    #       The z value allows you to set priority. So, something with -1
    #       z will be drawn below anything with a greater z value
    #/////////////////////////////////////////////////////////////////////
    when 1 # 1st Actor
      # Create Hair Sprite
      @ma_composite_character.push (['VisEquipSample', 1, 100])
    when 3 # 3rd Actor
      # Create skin sprite with different hue
      @ma_composite_character.push (['VisEquipSample', 0, 20])
      # Create Hair Sprites
      @ma_composite_character.push (['VisEquipSample', 2, 75])
      @ma_composite_character.push (['VisEquipSample', 3, 75])
    #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    # END EDITABLE REGION
    #/////////////////////////////////////////////////////////////////////
    end
    @ma_composite_character.each { |i|
      i[1] = 0 if i[1] == nil
      i[2] = 0 if i[2] == nil
      i[3] = 0 if i[3] == nil
    }
    @ma_composite_character.unshift ([@character_name, @character_index, 0, -1]) if @character_name != ''
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Composite Character
  #``````````````````````````````````````````````````````````````````````````
  #  Returns Graphic Array for the actor
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def composite_character
    armor_graphics = []
    weapon_graphics = []
    # Body Armor, then Helmet, then Shield, then all others
    dup_armors = armors.dup
    for i in 0...2
      j = 2 - i
      armor_graphics += dup_armors[j].character_graphics if dup_armors[j] != nil
      dup_armors.delete_at (j)
    end
    # If there is some multi-equip script, will get accessories and rest in order
    dup_armors.each { |armr| armor_graphics += armr.character_graphics if armr != nil }
    weapons.each { |wpn| weapon_graphics += wpn.character_graphics if wpn != nil }
    cg = @ma_composite_character + armor_graphics + weapon_graphics
    cg.sort! { |a, b| a[3] <=> b[3] }
    return cg
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Change Graphics
  #     character_name  : new character graphic filename
  #     character_index : new character graphic index
  #     face_name       : new face graphic filename
  #     face_index      : new face graphic index
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias ma_cgve_st_grphic_evnt_6ht3 set_graphic
  def set_graphic(character_name, character_index, face_name, face_index)
    old_char_name, old_char_index = @character_name, @character_index
    # Run Original Method
    ma_cgve_st_grphic_evnt_6ht3 (character_name, character_index, face_name, face_index)
    # Find old character name
    count = 0
    @ma_composite_character.each { |char|
      count += 1
      break if char[0] == old_char_name && char[1] == old_char_index
    }
    # Put in new character directly after old one
    @ma_composite_character.insert (count, [@character_name, @character_index, 0, -1])
    $game_player.refresh
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Clear Graphic
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def clear_graphic
    @ma_composite_character.clear
    @ma_composite_character.push ([@character_name, @character_index, 0, -1])
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Character Name
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modrnalgbra_comp_char_retrn_charctrnm_6gd4 character_name
  def character_name
    # If asking for composite character, return it instead
    if @ma_return_composite
      @ma_return_composite = false
      return self.composite_character
    end
    return modrnalgbra_comp_char_retrn_charctrnm_6gd4
  end
end

#==============================================================================
# ** Game_Character
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new instance variable - composite_character
#==============================================================================

class Game_Character
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_reader :composite_character
end

#==============================================================================
# ** Game_Event
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased methods - setup
#==============================================================================

class Game_Event
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Event page setup
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias malgbr_rclgh_req_comp_char_setup_5msk setup
  def setup(new_page)
    malgbr_rclgh_req_comp_char_setup_5msk (new_page)
    # Create Composite Character
    @composite_character = []
    @composite_character.push ([@character_name, @character_index, 0, -1]) unless @character_name.nil?
    # If page == nil, return
    return if @page == nil
    # Retrieve  first line comments
    comments = []
    @page.list.each { |i| i.code == 108 || i.code == 408 ? comments.push (i) : break }
    # Evaluate comments for \CG codes
    comments.each { |i|
      text = i.parameters[0].dup
      while text.sub! (/\\cg\[([^,\]]+),*\s*(\d*),*\s*(\d*),*\s*(\d*)\]/i) { '' } != nil
        a = [$1.to_s, ($2 != nil ? $2.to_i : 0), ($3 != nil ? $3.to_i : 0), ($4 != nil ? $4.to_i : 0)]
        @composite_character.push (a)
      end
    }
    # Sort Composite Characters by z value.
    @composite_character.sort! { |a, b| a[3] <=> b[3] }
  end
end

#==============================================================================
# ** Game_Player
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - refresh
#==============================================================================

class Game_Player
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Refresh
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias mdalg_arc_comp_character_find_rfrsh_8kwi refresh
  def refresh
    mdalg_arc_comp_character_find_rfrsh_8kwi
    return if $game_party.members.empty?
    @composite_character = $game_party.members[0].composite_character
  end
end

#==============================================================================
# ** Game_Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new method - clear_character_graphic
#==============================================================================

class Game_Interpreter
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Clear Character Graphic
  #    actor_id : the ID of the actor to be cleared
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def clear_character_graphic (actor_id)
    $game_actors[actor_id].clear_graphic
    $game_player.refresh
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Remove Graphic From Character
  #    actor_id : the ID of the actor
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def remove_graphic_from_actor (actor_id, *args)
    actor = $game_actors[actor_id]
    if args[0].is_a? (Integer)
      index = args[0]
    else
      index = 0
      # Find index of the specified character set
      for composite in actor.ma_composite_character
        if (args[0] != nil || args[0] == composite[0]) &&
             (args[1] != nil || args[1] == composite[1]) &&
             (args[2] != nil || args[2] == composite[2])
          break
        end
        index += 1
      end
    end
    # Delete graphic from array
    actor.ma_composite_character.delete_at (index)
    $game_player.refresh
    return index
  end

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Add Graphic To Character
  #    actor_id                        : the ID of the actor
  #    char_name, char_index, char_hue : character graphic specifications
  #    index                           : where to insert the new graphic
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def add_graphic_to_actor (actor_id, char_name, char_index = 0, char_hue = 0, z = 0, index = nil)
    actor = $game_actors[actor_id]
    index = actor.ma_composite_character.size if index.nil?
    actor.ma_composite_character.insert (index, [char_name, char_index, char_hue, z])
    $game_player.refresh
  end
end

#==============================================================================
# ** Sprite_Character
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - update_bitmap
#==============================================================================

class Sprite_Character
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Transfer Origin Bitmap
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modern_alg_arclightrequest_visual_equip_bmp_update update_bitmap
  def update_bitmap
    if @tile_id != @character.tile_id or
       @character_name != @character.character_name or
       @character_index != @character.character_index ||
       @composite_character != @character.composite_character
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_index = 0
      @composite_character = @character.composite_character
      if @tile_id > 0
        sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32;
        sy = @tile_id % 256 / 8 % 16 * 32;
        self.bitmap = tileset_bitmap(@tile_id)
        self.src_rect.set(sx, sy, 32, 32)
        self.ox = 16
        self.oy = 32
      else
        if @composite_character == nil
          # Regular Character Picture
          self.bitmap = Cache.character(@character_name)
          sign = @character_name[/^[\!\$]./]
          if sign != nil and sign.include?('$')
            @cw = bitmap.width / 3
            @ch = bitmap.height / 4
          else
            @cw = bitmap.width / 12
            @ch = bitmap.height / 8
          end
        else
          self.bitmap = Cache.composite_character(@composite_character)
          @cw = self.bitmap.width / 3
          @ch = self.bitmap.height / 4
        end
          self.ox = @cw / 2
          self.oy = @ch
      end
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Transfer Origin Rectangle
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_src_rect
    if @tile_id == 0
      index = 0
      pattern = @character.pattern < 3 ? @character.pattern : 1
      sx = (index % 4 * 3 + pattern) * @cw
      sy = (index / 4 * 4 + (@character.direction - 2) / 2) * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
  end
end

#==============================================================================
# ** Window_Base
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    overwritten method - draw_character_graphic
#==============================================================================

class Window_Base 
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Draw Actor Walking Graphic
  #     actor : actor or comp character array
  #     x     : draw spot x-coordinate
  #     y     : draw spot y-coordinate
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def draw_actor_graphic(actor, x, y)
    composite_character = actor.is_a? (Array) ? actor : actor.composite_character
    bitmap = Cache.composite_character (composite_character)
    cw = bitmap.width / 3
    ch = bitmap.height / 4
    rect = Rect.new (cw, 0, cw, ch)
    self.contents.blt (x - (cw / 2), y - ch, bitmap, rect)
  end
end

#==============================================================================
# ** Window_SaveFile
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    overwritten_methods - draw_party_characters
#==============================================================================

class Window_SaveFile < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Draw Party Characters
  #     x : Draw spot X coordinate
  #     y : Draw spot Y coordinate
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def draw_party_characters(x, y)
    for i in 0...@characters.size
      draw_actor_graphic (@characters[i][0], x + i * 48, y)
    end
  end
end

#==============================================================================
# ** Scene_File
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - write_save_data
#==============================================================================

class Scene_File
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Write Save Data
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modrnbra_wrt_svdata_comp_chactes_63gb5 write_save_data
  def write_save_data (*args)
    # Set it to return composite characters
    $game_party.members.each { |actor| actor.ma_return_composite = true }
    # Run Original Method
    modrnbra_wrt_svdata_comp_chactes_63gb5 (*args)
  end
end

#==============================================================================
# ** Scene_Equip (For compatibility with KGC
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - terminate
#==============================================================================

class Scene_Equip
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Terminate
  #     updates game_player equipment
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_trmnte_cg_equipment_k8g9c terminate
  def terminate
    # RUn Original Method
    modalg_trmnte_cg_equipment_k8g9c
    $game_player.refresh
  end
end



Instructions

Please see inside script for detailed instructions.


Compatibility

Any scripts that play around with the way character sets are drawn will undoubtedly have some problems with this script. If you encounter any problems, please post the error and the script that is causing the problem and I will see if I can make them compatible.


Credits and Thanks


  • modern algebra

  • Thanks to arclight, for the request




Author's Notes

You can post here for support and I will try to help when I log in, but as I am not as active here as I should be, please post in this topic at rmrk for swiftest response.

If this link dies, then try to notify me and in the meantime, the topic at rmrk will have an active link.
14
Looks good!
15
RMVX Script Database / Re: [VX] Advanced Areas
March 26, 2008, 01:10:32 pm
Ah.

No, this script won't work in XP - I wrote a different script that would. I think it's on the old forum : (

But in VX, areas are already built in - all this script does is add two options to it - encounter rate and the ability to activate and deactivate areas with a switch.

But yeah, you're right. I guess that it does have some relevance in an ABS if they allow for regular battles
16
RMVX Script Database / Re: [VX] Advanced Areas
March 26, 2008, 12:27:25 pm
Blizz-ABS works in VX? That's pretty wicked. But in any case, this script would be kind of useless in an ABS anyway. If I remember correctly, you set events as enemies: you wouldn't use areas to determine encounters. I'll add it to the Compatibility Issues List anyway
17
RMVX Script Database / Re: [VX] Quest Journal
March 26, 2008, 10:11:07 am
Oh. I'll fix that right after I get back from class

That was a dumb mistake. Go to line 582 and find this line:


modalg_quest_jrnl_intlz (width, commands, column_max = 1, row_max = 0, spacing = 32)


Replace it with:


modalg_quest_jrnl_intlz (width, commands, column_max, row_max, spacing)


I uploaded the script with this problem fixed.
18
RMVX Script Database / [VX] Paragraph Formatter
March 25, 2008, 03:49:32 pm
Paragraph Formatter (VX Edition)
Authors: modern algebra
Version: 1.1
Type: Message Add-on
Key Term: Message Add-on



Introduction

This is a scripting tool. It's purpose is to allow the user to input an unbroken string and have returned a paragraph which has the ends of each line in line with each other. It serves roughly the same function as does the justifying option in Microsoft Word. See the screenshots if you are still confused.


Version History

The Version History refers to the original script made for XP

  • Version 1.1 -  Jan 20, 2008: Better Error Catching; Better comments; Better facade
  • Version 1.0 - Nov 2, 2007: Original Script.


Current Algorithms:


  • Formatter (generic)
  • Artist (generic)
  • Formatter_2 (based off Zeriab's algorithm, written for fonts with unvarying character width)


Planned Future Versions


  • Probably add some better formatting and Artist classes as I get better at scripting. As well, any other scripter is welcome to add their own formatting methods to the script.



Features


  • A nice, easy way to display long strings in a paragraph format
  • Easy to add and modify at runtime, allowing for the switching between formatting classes for each situation
  • You can write your own formatter or artist classes and use the paragraphing tool to suit your situation.
  • Highly customizable.



Screenshots

Spoiler: ShowHide



Script

Spoiler: ShowHide

#========================================================================
#  Paragraph Formatter (VX)
#  Version: 1.1
#  Author: modern algebra (rmrk.net)
#  Date: March 4, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Apology:
#    The idea behind this script is to easily separate a long string into a paragraph that fits in to
#     the dimensions you specify.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    For ease of use of people who are not neccesarily interested in writing their own algorithm,
#    I have included a facade which you can use simply by this code:
#
#           bitmap.draw_paragraph (x, y, width, height, string)
#
#    where x & y are the x & y coordinates on the specified bitmap, and width and height are the
#    maximum dimensions of the paragraph and string is the text you want to display in
#    paragraph formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  How it works:
#    The paragrapher expects two objects when initialized, a Formatter and an Artist. The idea
#    behind the formatter is that it is expected to take the initial specifications and convert it to a
#    Formatted Text object. Then, the Artist class is expected to interpret the Formatted Text
#    object and draw the paragraph. For details on how each specific algorithm works,  visit the
#    comments above and inside them. It is not necessary to use the default Formatter, Artist, or
#    Formatted Text objects.
#========================================================================

#======================================================================
# ** Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Facade for easy application of the Paragraph Formatter
#======================================================================

class Bitmap
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Formatter
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter
    @p_formatter = $game_system.default_formatter.new if @p_formatter.nil?
    return @p_formatter
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Formatter
  #     formatter : The uninitialized formatter class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter= (formatter)
    @p_formatter = formatter.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist
    @p_artist = $game_system.default_artist.new if @p_artist.nil?
    return @p_artist
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Artist
  #     artist : The uninitialized artist class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist= (artist)
    @p_artist = artist.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * The Facade, which uses default Formatter and Artist to draw the formatted text directly
  #  to a bitmap, such as self.contents
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def draw_paragraph (x, y, max_width, max_height, string)
    bitmap = Bitmap.new (max_width, max_height)
    bitmap.font = self.font
    pg = Paragrapher.new(paragraph_formatter, paragraph_artist)
    bitmap = pg.paragraph (string, bitmap)
    blt (x, y, bitmap, bitmap.rect)
    # Dispose of the proxy bitmap
    bitmap.dispose
  end
end

#========================================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#     new instance variables - default_formatter, default_artist
#     aliased methods - initialize
#========================================================================

class Game_System
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_accessor :default_formatter
  attr_accessor :default_artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias ma_paragraph_formatter_init initialize
  def initialize
    # Run original method
    ma_paragraph_formatter_init
    # Initialize original default format and artist classes
    @default_formatter = Paragrapher::Formatter_2
    @default_artist = Paragrapher::Artist
  end
end

#======================================================================
# ** Paragrapher
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Module containing the objects for the Paragrapher
#======================================================================
module Paragrapher
  #===================================================================
  # Allows the 'Paragrapher.new' command outside of the module to be used
  # rather than having to use 'Paragrapher::Paragrapher.new'
  #===================================================================
  class << self
    def new(*args, &block)
      return Paragrapher.new(*args, &block)
    end
  end
 
  #===================================================================
  # * The Paragrapher class
  #===================================================================
  class Paragrapher
    def initialize(formatter, artist)
      @formatter = formatter
      @artist = artist
    end
   
    def paragraph(string, *specifications)
      f = @formatter.format(string, *specifications)
      return @artist.draw(f)
    end
  end
 
  #===================================================================
  # * The Formatter class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This class converts a string into a formatted text object, which is then
  #  passed on to the Artist class
  #===================================================================
  class Formatter
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #     string         : the string to be formatted
    #     specifications : the desired width of the paragraph, or the bitmap
    #-------------------------------------------------------------------------------------------------------------------
    #  This works on a very simple algorithm. Basically, it just formats the
    #  text by going through each word in the string. If a word
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format(string, specifications)
      # Initializes Formatted_Text object
      f = Formatted_Text.new
      # Checks whether specifications is a bitmap or a number. It then sets
      # max_width and f.bitmap accordingly
      if specifications.class == Bitmap
        f.bitmap = specifications
        max_width = specifications.width
      elsif specifications.class == Fixnum || specifications.class == Float
        max_width = specifications
        f.bitmap = Bitmap.new (max_width, 32)
      else
        # Error Catching: Bad Specifications
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      # Breaks the given string into an array of all it's characters
      temp_word_array = string.scan (/./)
      position = 0
      line_break = 0
      # Initializes f.lines
      f.lines = []
      f.blank_width = []
      for i in 0...temp_word_array.size
        character = temp_word_array[i]
        # Error catching
        if character == "\n"
          p 'This formatter does not recognize line breaks'
          character = " "
        end
        # If at a new word
        if character == " " || i == temp_word_array.size - 1
          # Take into account the last character of the string
          if i == temp_word_array.size - 1
            i += 1
          end
          # If this word fits on the current line
          if f.bitmap.text_size (string[line_break, i-line_break]).width <= max_width
            position = i
          else
            line = temp_word_array[line_break, position-line_break]
            # Adds the first lines to f.lines
            f.lines.push (line)
            # Calculates the blank space left to cover in the line
            line_blank = max_width - f.bitmap.text_size(string[line_break,position-line_break]).width
            # Calculates the necessary distance between letters to make up for
            # line_blank and adds that value to the f.blank_width array
            f.blank_width.push (line_blank.to_f / (line.size.to_f-1.0))
            # Keeps track of the position in the array of each line
            line_break = position + 1
            position = i
          end
        end
      end
      # Adds the last line to f.lines
      f.lines.push (temp_word_array[line_break, temp_word_array.size - line_break])
      # Since the last line is drawn normally, blank_width should be 0
      f.blank_width.push (0)
      if specifications.class == Fixnum
        # Sets up the bitmap if it was unspecified.
        f.bitmap = Bitmap.new(max_width, f.lines.size*32)
      end
      # Returns the Formatted_Text object
      return f
    end
  end
 
  #===================================================================
  # * Formatter 2 (Using Zeriab's Algorithm)
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This algorithm was written by Zeriab for fonts which have characters of the same width.
  #  This is like Courier New, UMEGothic and fonts of that sort. This algorithm attaches a
  #  cost to each line based on the amount of white space at the end of that line. It will
  #  display the way of writing the text with the lowest total cost. In prcatice, this will mean
  #  that it will, as much as possible, reduce the spacing between letters in a line and make
  #  the spacing more consistent for each line of the paragraph
  #===================================================================
  class Formatter_2
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format (string, specifications)
      f = Formatted_Text.new
      f.lines, f.blank_width, word_lengths, words = [], [], [], []
      tracker = 0
      for i in 0...string.size
        if string[i,1] == " " || i == string.size - 1
          if i == string.size - 1
            i += 1
          end
          word_lengths.push (i - tracker)
          words.push (string[tracker, i - tracker])
          tracker = i + 1
        end
      end
      if specifications.class == Bitmap
        max_width = specifications.width
        f.bitmap = specifications
      elsif specifications.class == Fixnum || specifications.class == Float
        max_width = specifications
        f.bitmap = Bitmap.new (1,1)
      else
        # Error Catching: Bad specification
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      tw = f.bitmap.text_size('a').width
      max_width = [max_width / tw, 180].min
      # Error Catching: Word too long
      if word_lengths.max > max_width
        f = format ('Too long' , specifications)
        p 'One or more words is too long for specified width'
        return f
      end
      position = line_break (word_lengths, max_width)
      lines = give_lines (position, position.size - 1, words)
      max_width *= tw
      for i in 0...lines.size
        line = lines[i]
        f.lines.push (line.scan (/./))
        if i == lines.size - 1
          f.blank_width.push (0)
        else
          text_width = line.size * tw
          extra_space = max_width - text_width
          f.blank_width.push (extra_space.to_f / (line.size.to_f - 1.0))
        end
      end
      if f.bitmap != specifications
        f.bitmap = Bitmap.new (max_width, f.lines.size*32)
      end
      return f
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Line Break (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def line_break(word_lengths, max_length)
    return false  if max_length > 180
    word_lengths.unshift(nil)
    extra_spaces = Table.new(word_lengths.size,word_lengths.size)
    line_prices = Table.new(word_lengths.size,word_lengths.size)
    word_price = []
    position = []
    inf = max_length*max_length + 1
    for i in 1...word_lengths.size
      extra_spaces[i,i] = max_length - word_lengths[i]
      for j in (i+1)..[word_lengths.size-1, max_length/2+i+1].min
      extra_spaces[i,j] = extra_spaces[i,j-1] - word_lengths[j]-1
      end
    end
    for i in 1...word_lengths.size
      for j in i..[word_lengths.size-1, max_length/2+i+1].min
      if extra_spaces[i,j] < 0
        line_prices[i,j] = inf
      elsif j == word_lengths.size-1 and extra_spaces[i,j] >= 0
        line_prices[i,j] = 0
      else
        line_prices[i,j] = extra_spaces[i,j]*extra_spaces[i,j]
      end
        end
    end
    word_price[0] = 0
    for j in 1...word_lengths.size
      word_price[j] = inf
      for ik in 1..j
      i = j - ik + 1
      break  if line_prices[i,j] == inf
      if word_price[i-1] + line_prices[i,j] < word_price[j]
        word_price[j] = word_price[i-1] + line_prices[i,j]
        position[j] = i
      end
      end
    end
    return position
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Give_Lines (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def give_lines(position,last_index,words)
    first_index = position[last_index]
    word_array = []
    if first_index != 1
      word_array = give_lines(position, first_index - 1,words)
    end
    str = ""
    for x in first_index..last_index
      str += ' '  if x != first_index
      str += words[x-1]
    end
    word_array << str
    return word_array
    end
  end

  #===================================================================
  # * The Artist class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  Interprets a Formatted Text object and draws the paragraph encoded
  #===================================================================
  class Artist
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Draw
    #     f : Formatted Text Object
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def draw (f)
      # Calculates the necessary distance between lines
      line_distance = f.bitmap.height.to_f / f.lines.size.to_f
      line_distance = [f.bitmap.font.size  + 10, line_distance].min
      # For all lines in the lines array
      for i in 0...f.lines.size
        blank_space = f.blank_width[i]
        position = 0
        # For all indices of the line array
        for j in 0...f.lines[i].size
          word = f.lines[i][j]
          ws = f.bitmap.text_size (word)
          position += blank_space if j != 0
          # Adds blank_space and position, and draws the string located at each index
          f.bitmap.draw_text (position, line_distance*i,ws.width+1,ws.height+1,word)
          # Keeps track of the position we are in in pixels
          position += ws.width
        end
      end
      return f.bitmap
    end
  end
 
  #===================================================================
  # * The Formatted_Text class containing the results of the formatter
  #===================================================================
  class Formatted_Text
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Public Instance Variables
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    attr_accessor :lines       # An array of strings, each a line of the paragraph
    attr_accessor :blank_width # The amount of white space between each letter
    attr_accessor :bitmap      # The bitmap drawn to
  end
end



Instructions

As a scripter's tool, it can be quite heavy for non-scripters to use. That is why I wrote a facade for common use of the tool. Naturally, you will still need some scripting knowledge, but the facade allows for this code:


bitmap.draw_paragraph (x, y, max_width, max_height, string)


where bitmap is the bitmap you are drawing to. This can be self.contents in a window, or any instance of the bitmap class.

It can be used like this, if you want to draw the paragraph in a different way:
    
    formatter = <formatter class you want to use>
    artist = <artist class you want to use>
    specifications = <max width, or bitmap>
    pg = Paragrapher.new (formatter, artist)
    text_bitmap = pg.paragraph (string, specifications)
    bitmap.blt (x, y, text_bitmap, Rect.new (0,0,text_bitmap.width, text_bitmap.height))


Basically, you choose your formatter and artist class at runtime. This means that if you want to use Paragraph::Formatter_2, because you are using a font with set width for all characters, then you would choose that here. Currently, there is only one Artist class, Paragraph::Artist, but of course you can make your own if it does not suit you. You can either specify a bitmap or a fixnum. The fixnum would just be the max width, and the paragrapher would create a bitmap which was at font_size 22, default font name, and it would space each line 32 pixels. With a bitmap, you specify max_width, max_height, font and font size, and anything else that has an effect. Naturally, bitmap in the code is the bitmap you are drawing the paragraph on. If you have any questions, just ask.

Also, the text_size method of Bitmap does not, in fact, work properly. In a little while I will post a way to get around this problem as it can get in the way of drawing nice paragraphs.

Put the scripts above main and below the default scripts.

For more pertinent instructions, see the header of the script


Credits and Thanks


  • Zeriab, for the idea, the motivation, and the instruction, as well as one of the algorithms
  • modern algebra, for the sloppy code :P



Author's Notes

Support will be provided anywhere that I (modern algebra) posts the script. At forums where it is posted by anyone else, I make no guarantees. I am willing to write formatting or artist methods to deal with any instances for which current algorithms are inapplicable or inefficient, as well as dealing with any bugs in the current algorithms.

This script was inspired by Zeriab, and pretty much everything that is good about this script is due to Zeriab. Zeriab deserves more credit for this script then I do, rightly, but since the world isn't just... :P Anyway, he deserves all my thanks for being an excellent teacher.

Further, this script is pretty much directly brought over from the version I made for XP. Any changes I have made are minor. Thus, if anyone runs into bugs, they may be an oversight on my part as I didn't see anything in the script that was dependent on RGSS or that would cause problems when put in RGSS2. In any case, please notify me if you run into problems.
19
RMVX Script Database / [VX] Advanced Areas
March 25, 2008, 03:47:38 pm
Advanced Areas
Authors: modern algebra
Version: 1.0
Type: Map Configuration
Key Term: Environment Add-on



Introduction

Adds a couple of options to areas. If anyone has any ideas for more, please tell me.


Features


  • Allows you to marry an in-game switch to an area, thus allowing it to be turned on and off at will. This can be useful if say, after some event in your game, like a volcano erupting, you want different monsters to pop up

  • Allows you to set an encounter step for each area. Where two areas conflict, it takes the smallest encounter step




Screenshots

N/A


Demo

N/A


Script
Spoiler: ShowHide

#==============================================================================
#  Advanced Areas
#  Version 1.0
#  Author: modern algebra
#  Date: March 12, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    Set up the database below in the Editable Regions. Both are set up in the
#    same way, and they look like this:
#
#      when id
#        rate/switch = value
#
#    You only need to set it if it is not default. If an area has no switch,
#    then don't set it up. If you want the encounter step to be the same as
#    the parent map, then do not set it up. In any case, just so we are clear,
#    I provided a few examples in the Editable Regions. Feel free to
#    replace/delete them once you know what you're doing.
#==============================================================================

#==============================================================================
# ** RPG::Area
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#    new methods - encounter_step, active?
#==============================================================================

class RPG::Area
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Encounter Rate
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def encounter_step
    rate = $game_map.encounter_step
    # Branch by ID
    case @id
    #----------------------------------------------------------------------
    #  EDITABLE REGION
    #----------------------------------------------------------------------
    when 1
      rate = 10
    when 3
      rate = 15
    #----------------------------------------------------------------------
    #  END EDITABLE REGION
    #----------------------------------------------------------------------
    end
    return rate
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Active?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def active?
    switch = 0
    case @id
    #----------------------------------------------------------------------
    #  EDITABLE REGION                                                   
    #----------------------------------------------------------------------
    when 1
      switch = 1
    when 4
      switch = 1
    #----------------------------------------------------------------------
    #  END EDITABLE REGION
    #----------------------------------------------------------------------
    end
    return true if switch == 0
    return $game_switches[switch]
  end
end

#==============================================================================
# ** Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased method - encounter_step
#==============================================================================

class Game_Map
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Encounter Step
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_advncd_areas_step_encntr encounter_step
  def encounter_step
    # Get original Map Encounter Step
    encounter_rates = [modalg_advncd_areas_step_encntr]
    # Get all the areas the player is in. For ne
    $data_areas.values.each { |i| encounter_rates.push (i.encounter_step) if i.map_id == @map && $game_player.in_area? (i) }
    return encounter_rates.min
  end
end

#==============================================================================
# ** Game_Player
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased methods - in_area?
#==============================================================================

class Game_Player
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * In Area?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_advnced_areas_area_in? in_area?
  def in_area? (area)
    return false unless area.active?
    modalg_advnced_areas_area_in? (area)
  end
end



Instructions

See inside the script.


Compatibility

This script will not work with Blizz-ABS


Credits and Thanks


  • modern algebra

  • Jensen for the request




Author's Notes

Just post here if you have any errors. I will try to fix them. If you have any ideas about good options to add to the areas, please post here and if I think they are good I will write them in.
20
RMVX Script Database / [VX] Quest Journal
March 25, 2008, 03:45:04 pm
Quest Journal
Authors: modern algebra
Version: 1.1
Type: Quest Log/Mission System
Key Term: Misc System



Introduction

This script provides a graphical interface for viewing quest progress. It is an objective based quest log, meaning you can choose to reveal, conceal, complete, or fail any objective at any time. You can also specify which objectives need to be completed for the quest to be complete. It requires a fair amount of customization and designing the quests is entirely left up to you.


Version History


  • <Version 1.1> A minor bug fix involving quests with ID 4. A few added functions for tracking quests, including the ability to conceal given quests as well as uncompleting and unfailing objectives. Released April 10, 2008.
  • <Version 1.0> Original script released March 25, 2008. Includes functioning Quest tracking



Planned Future Versions


  • <Version 2.0> Add in a fully functional journal option with Keyboard input, allowing the player to write notes on each quest if he/she chooses to.




Features


  • Customizable and every quest can be specified uniquely

  • Accepts a large amount of quests, though I would suggest removing some periodically if you have more than 200 quests

  • Relies on Script calls to set and advance objectives

  • Built in access to the menu or you can set a key and call it from the map



Screenshots

Spoiler: ShowHide



Demo

Download Link. To retrieve the script, take it directly from the demo. It is located below the (materials) slot and is titled Quest Journal. If you do not already have the Paragraph Formatter, you will also need that.


Script

This script also REQUIRES the Paragraph Formatter. Get it here: http://forum.chaos-project.com/index.php?topic=838.0

This script is too long to post here. Please retrieve it from the demo.



Instructions

Basically, set up all of your quests in the module below. The Constants section is annotated, so read the comments near them to determine what you should set these constants to. As you can see, they are filled in with default values currently, and so that should give you an idea of what to do.

  Setting up quests can be a little bit harder. You will have to set one these up for every quest that you want represented in the scene. Refer to the editable region inside the class Quest for further instructions

  Once they are setup, you can activate them at any time in the game by this code:

$game_party.quests[quest_id]


There are several methods you can call that are of relevance. Namely:


$game_party.quests[quest_id].reveal_objective (objective_id)
$game_party.quests[quest_id].conceal_objective (objective_id)
$game_party.quests[quest_id].complete_objective (objective_id)
$game_party.quests[quest_id].fail_objective (objective_id)
$game_party.quests[quest_id].complete?
$game_party.quests[quest_id].failed?
$game_party.quests[quest_id].reward_given


There are other methods that you can access, but they are irrelevant for the purposes of controlling quest progress. These are fairly self-explanatory methods, but in case they aren't, reveal_objective naturally allows the specified objective to appear in the Quest Journal for browsing by the user. complete_objective notes when an objective is complete, and fail_objective notes when the player has done something that fails this objective. complete? returns true if all primary objectives have been completed and failed? returns true if any primary objective has been failed. reward_given serves the function of a switch. You should essentially make the reward event look like this:


@> Conditional Branch: Script: $game_party.quests[quest_id].complete?
  @> Conditional Branch: Script: $game_party.quests[quest_id].reward_given
     @> ...Thank you or whatever you want the event to say once the reward has been given
  @> Else
     @> ...Give Reward
     @> Script: $game_party.quests[quest_id].reward_given = true
  @> Branch End
@> Branch End


Later versions of this script will have an auto-reward system and also a Journal to which the player can write notes.

  You can also disable access to the Quest Log at any time with the code:

$game_system.quest_disabled = true


And you can change how it is accessed with the codes:
   

$game_system.quest_keyaccess = true / false  # ON MAP
$game_system.quest_menuaccess = true / false # IN MENU


  Also, in a message, \nq[quest_id] will retrieve the name of a quest and print it in a message


Compatibility

There may be problems with other scripts that add features to the menu.


Credits and Thanks


  • modern algebra





Author's Notes

Just post here if you are having problems. Please include any error messages and describe your problem in detail.

Nothing too much to say, though I did try a couple of new things. Namely, I wrote some methods for drawing ellipses and stuff - thus we get the rounded rectangle - a lot of code for a small, poorly done graphical effect, but whatever. I also tried making the Quests option slide into the menu flawlessly, but it was not as simple as I thought it would be. It appears to work now, but problems still might arise. I hope they don't. The other thing I did that was kind of fun was that I made the scene fit no matter what you have the resolution as. So, if you resize your screen, my scene still ought to look like it belongs. With all of that, my script became obscenely long, but it's worth it, I promise :P