Trilobytes VX Ace #2: Bonus Stat Allocation (v1.11 now available!)

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,371
Reaction score
1,537
First Language
English
Primarily Uses
RMMV

Bonus Stat Allocation version 1.11
Created by Trihan

Introduction
This script allows you to open a scene to assign a specified number of bonus points to an actor's stats. It is highly configurable and can be used for a variety of things. It was originally commissioned by Clyve for a mercenary system, but as it's been 5 years since the commission request and Clyve no longer appears to be part of the community, I decided to release it to the public.

Features
- Open a scene to raise an actor's stats using bonus point allocation.
- Customise icons, stat labels, which stats to show, points required to raise, and points to raise the stat by.
- Can specify a variable that will be set to 1 when assignment is complete if you want to do something after the scene closes.

Screenshots




How to Use
Call the scene by using the script call "bonus_stats(actor_id, points)" replacing actor_id with the ID of the actor you want to assign points to, and points with the number of points to give them. Configuration options such as number of points required to raise are explained in the relevant section of the script.

Demo
No demo available at present.

Script
Code:
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#  ▼ Bonus stats script
#  Author: Trihan
#  Version 1.11
#  Release date: 10/06/2012
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#-------------------------------------------------------------------------------------------------
#  ▼ UPDATES
#-------------------------------------------------------------------------------------------------
# # 03/07/2020. Fixed a bug where setting stat locks would permanently break the
# # list. Added MDEF to default stat list. Changed positive change green colour
# # to be more easily-readable. Added text to show no assignable stats in the
# # event that all available stats are locked.
# # 12/06/2012. Fixed a bug where the actor's initial stat values would show
# # even when calling the script multiple times.
# # 10/06/2012. Added the actor's name, level and class to the title.
# # 10/06/2012. Added a full HP/MP heal to the actor so you don't have to do it
# # with an event command afterwards.
# # 10/06/2012. Fixed a bug where the confirm and cancel windows weren't
# # handling input properly.
# # 10/06/2012. Fixed a bug where the first event command after the script call
# # wouldn't run.
# # 10/06/2012. Fixed a lag issue with the update method of the stats window.
# # 10/06/2012. Added an explanatory line to each stat that shows how many
# # points it requires to raise and how many points it will rise by.
# # 10/06/2012. Added the class notetags for locking out stats.
# # 10/06/2012. Changed the assignment so that the appropriate number of points
# # are calculated and removed automatically, rather than having to assign each
# # one individually.
# # 10/06/2012. Added another array to determine how many points a stat raises
# # by, which is a part of the original commission I forgot to put in.
# # 10/06/2012. Original release
#-------------------------------------------------------------------------------------------------
#  ▼ TERMS OF USAGE
#-------------------------------------------------------------------------------------------------
# #  You are free to adapt this work to suit your needs.
# #  You can use this work for commercial purposes if you like it.
# #  Credit is appreciated.
# #
# # For support:
# # rmrk.net
# # rpgmaker.net
#-------------------------------------------------------------------------------------------------
#  ▼ INTRODUCTION
#-------------------------------------------------------------------------------------------------
# # Enables a script call to show a window via which you can assign a number of
# # bonus points to an actor's stats. This was originally commissioned for a
# # mercenary system but can easily be tailored to other uses.
# #
#-------------------------------------------------------------------------------------------------
#  ▼ INSTRUCTIONS
#-------------------------------------------------------------------------------------------------
# # In an event, put the following in a call script command:
# #
# # bonus_stats(char, points)
# #
# # Where char is the ID number of the actor to whom you wish to assign points,
# # and points is the number of assignable points to give the player.
# #
# # Class notetags:
# #
# # <bonus_lock X>
# #
# # Where X is the ID of the stat as determined by the param_base property of
# # Game_Actor. If a stat is locked out, it won't appear in the window for a
# # character of that class even if it's included in the stats array.
# #
# # You can customise which stats can be added to and how many bonus points it
# # take to raise the stat. More on that in the editable section.
#-------------------------------------------------------------------------------------------------
#  ▼ COMPATIBILITY
#-------------------------------------------------------------------------------------------------
# # List of aliases and overwrites:
# #
# # RPG::Class
# # stat_locks (new attr method)
# # load_class_notetags (new method)
# #
# # DataManager
# # load_database (alias)
# # load_class_notetags (new method)
# #
# # Game_Interpreter
# # bonus_stats (new method)
# #
# # As most functionality in this script is done via custom classes and methods,
# # there shouldn't be any compatibility issues unless using a script that also
# # deals with bonus_stats which may feasibly have the same names for things.
#-------------------------------------------------------------------------------------------------
$imported = {} if $imported.nil?
$imported['statbonus'] = true

BON_CONFIG = {
# ------------------------------------------------------------------------------
# EDITABLE REGION BEGINS HERE
# ------------------------------------------------------------------------------
# :icons - Determines the icons that will be shown for each stat. It is simply
# an array of icon IDs from the icon sheet.
# ------------------------------------------------------------------------------
  :icons  =>  [122, 10, 11, 13, 14, 15, 12, 125],
# ------------------------------------------------------------------------------
# :labels - Determines the labels that will be shown for each stat in the bonus
# window.
# ------------------------------------------------------------------------------
  :labels =>  ["HP", "MP", "Atk", "Def", "Mag", "Mdf", "Agi", "Luck"],
# ------------------------------------------------------------------------------
# :stats - Determines which stats will be shown in the window. As stated above,
# if a stat is locked out for the actor's class (with <bonus_lock X>) it won't
# be shown in the window even if it's included here.
# ------------------------------------------------------------------------------
  :stats  =>  [0, 1, 2, 3, 4, 5, 6, 7],
# ------------------------------------------------------------------------------
# :costs - Determines how many bonus points it takes to raise the appropriate
# stat by the value determined in "raises". For example, if you have "1" for
# costs and "5" for raises, that stat will rise by 5 points for every 1 point
# you spend.
# ------------------------------------------------------------------------------
  :costs  =>  [1, 3, 2, 2, 2, 2, 1, 1],
# ------------------------------------------------------------------------------
# :raises - Determines how many points the stat raises by when you spend the
# number of points determined by "costs".
# ------------------------------------------------------------------------------
  :raises =>  [5, 1, 1, 1, 1, 1, 1, 1],
# ------------------------------------------------------------------------------
# :assignment_var - This is completely optional and was a specific request in
# the original commission. You can specify a variable which will be set to 1
# when assignment is confirmed (so the event that calls the bonus window can do
# something after assignment has finished successfully).
# ------------------------------------------------------------------------------
  :assignment_var =>  23,
# ------------------------------------------------------------------------------
# :points_on_level - This allows you to specify a number of points that will be
# available for assignment when a character gains a level. If set to 0, the
# feature will be disabled. NOT YET IMPLEMENTED.
# ------------------------------------------------------------------------------
  :points_on_level  =>  10,
# ------------------------------------------------------------------------------
# EDITING ANYTHING BEYOND THIS POINT WILL RESULT IN PREMATURE BALDING AND LOSS
# OF EARNINGS.
# ------------------------------------------------------------------------------
}


# ------------------------------------------------------------------------------
# This module determines the regex required for the stat locking notetag.
# ------------------------------------------------------------------------------
module BONUS
 
  module REGEXP
    STAT_LOCK = /<bonus_lock (\d+)>/i
  end
 
end

# ------------------------------------------------------------------------------
# RPG::Class changes
# ------------------------------------------------------------------------------
# stat_locks - new attr method that tracks which stats are "locked" for bonuses.
# load_class_notetags - new method that loads the notetags from the database.
# ------------------------------------------------------------------------------
class RPG::Class
  attr_reader :stat_locks
  #--------------------------------------------------------------------------
    # ● Loads the notetags
    #--------------------------------------------------------------------------
  def load_class_notetags
    @stat_locks = []
        @note.split(/[\r\n]+/).each do |line|
            case line
            when BONUS::REGEXP::STAT_LOCK
        @stat_locks.push($1.to_i)
      end
        end
    end
end

# ------------------------------------------------------------------------------
# DataManager changes
# ------------------------------------------------------------------------------
# load_database - alias created so that notetags can be loaded when the game
# begins.
# load_class_notetags - this just loads the notetags for each class.
# ------------------------------------------------------------------------------
module DataManager
    
  # Initialize Shop Sales data
  class <<self; alias bonus_load_database load_database; end
  #--------------------------------------------------------------------------
    # ● Loads the database
    #--------------------------------------------------------------------------
  def self.load_database
    bonus_load_database
    load_class_notetags
  end
 
  #--------------------------------------------------------------------------
    # ● Loads the notetags
    #--------------------------------------------------------------------------
  def self.load_class_notetags
    for obj in $data_classes
      next if obj.nil?
      obj.load_class_notetags
    end
        puts "Read: Bonus lock notetags"
    end

end

# ------------------------------------------------------------------------------
# Game_Interpreter changes
# ------------------------------------------------------------------------------
# bonus_stats = new method that allows you to use "bonus_stats(char, points)" in
# an event's call script command, where char is the ID of the actor whose stats
# you wish to assign bonuses to, and points is the number of points you wish to
# give the player for assignment.
# ------------------------------------------------------------------------------
class Game_Interpreter
  def bonus_stats(char, points)
    SceneManager.call(Scene_Bonus)
    SceneManager.scene.prepare(char, points)
    Fiber.yield
  end
end

# ------------------------------------------------------------------------------
# Window_BonusTitle - new class
# ------------------------------------------------------------------------------
# All this window really does is show a helpful string to the player explaining
# what the assignment window is for and how to confirm their choice.
# ------------------------------------------------------------------------------
class Window_BonusTitle < Window_Base
  # ----------------------------------------------------------------------------
  # Creates the window centered on the screen with a width of 400 and tall
  # enough to fit two rows of text.
  # ----------------------------------------------------------------------------
  def initialize(char)
    @char = char
    ww = 400
    wh = fitting_height(2)
    wx = (Graphics.width / 2) - (ww / 2)
    super(wx, 0, ww, wh)
    refresh
  end
 
  # ----------------------------------------------------------------------------
  # Draws the title text the window will show along with actor's name and class.
  # ----------------------------------------------------------------------------
  def draw_title
    draw_text(0, 0, contents.width, line_height, "Assign Bonus (ENTER to confirm)", 1)
    draw_text(0, 0, contents.width, line_height*3, sprintf("%s - level %d %s", @char.name, @char.level, @char.class.name), 1)
  end
 
  # ----------------------------------------------------------------------------
  # Refresh the window by drawing the title. No update method needed as this
  # will never change.
  # ----------------------------------------------------------------------------
  def refresh
    draw_title
  end
end

# ------------------------------------------------------------------------------
# Window_BonusStats - new class
# ------------------------------------------------------------------------------
# This is where the magic happens! The bulk of the scene takes place in this
# window, which gives the player an interface for assigning bonus points to
# whichever stats were included in the stats array.
# ------------------------------------------------------------------------------
class Window_BonusStats < Window_Selectable
  # ----------------------------------------------------------------------------
  # Creates the window centered on the screen with a width of 400 and height
  # determined by how many stats need to be displayed.
  # - char is the ID of the actor whose stats will be assigned.
  # - quantity is the number of stats that can be changed.
  # - p_window is the window containing the points value. I do it like this so
  # that I can call the change_points method of the points window from within
  # methods in this class.
  # - bonuses is an array that will store the number of bonus points the player
  # has allocated to each stat in the window.
  # - statups is an array that will store the changes to stats that result from
  # the values in bonuses.
  # ----------------------------------------------------------------------------
  def initialize(char, quantity, points_window, stat_hash)
    @char = char
    @quantity = quantity
    @p_window = points_window
    @bonuses = Array.new(stat_hash[:stats].size, 0)
    @statups = Array.new(stat_hash[:stats].size, 0)
    @stat_hash = stat_hash
    ww = 400
    wh = quantity > 0 ? fitting_height(quantity) : fitting_height(1)
    wx = (Graphics.width / 2) - (ww / 2)
    wy = (Graphics.height / 2) - (wh / 2)
    super(wx, wy, ww, wh)
    refresh
  end
 
  # ----------------------------------------------------------------------------
  # Returns the value of the (stat_index)th array of the statups array.
  # ----------------------------------------------------------------------------
  def get_statup(stat_index)
    return @statups[stat_index]
  end
 
  # ----------------------------------------------------------------------------
  # Calls the stat drawing methods for each stat contained in the array.
  # ----------------------------------------------------------------------------
  def draw_stats
    if @quantity > 0
      for i in 0...@quantity
        draw_stat(i)
        draw_raise(i)
        draw_cost(i)
      end
    else
      draw_text(0, 0, contents.width, line_height, "No assignable stats", 1)
    end
  end
 
  # ----------------------------------------------------------------------------
  # Draws the icon, label, current value (shown in green if a bonus has been
  # applied to it), the number of bonus points that have been applied, and a
  # colon separating the stat value and player selection rectangle.
  # ----------------------------------------------------------------------------
  def draw_stat(i)
    draw_icon(@stat_hash[:icons][i], 0, line_height*i)
    draw_text(30, line_height*i, contents.width, line_height, @stat_hash[:labels][i])
    if @statups[i] > 0
      change_color(Color.new(181, 230, 19, 200))
    end
    draw_text(80, line_height*i, contents.width, line_height, @char.param(@stat_hash[:stats][i]) + @statups[i])
    change_color(normal_color)
    draw_text(120, line_height*i, contents.width, line_height, ":")
    draw_text(160, line_height*i, contents.width, line_height, @bonuses[i])
  end
 
  # ----------------------------------------------------------------------------
  # Draws the number of points required to raise the stat and how many points
  # the stat will be raised by if you spend that many.
  # ----------------------------------------------------------------------------
  def draw_cost(i)
    draw_text(200, line_height*i, contents.width, line_height, sprintf("%dp > +%d", @stat_hash[:costs][i], @stat_hash[:raises][i]))
  end
 
  # ----------------------------------------------------------------------------
  # Draws the value by which a stat has been raised on the far right (in green)
  # but only if the number of spent points has resulted in a change.
  # ----------------------------------------------------------------------------
  def draw_raise(i)
    if @statups[i] > 0
      change_color(Color.new(181,230,19,200))
      draw_text(0, line_height*i, contents.width, line_height, sprintf("+%2d", @statups[i]), 2)
      change_color(normal_color)
    end
  end
 
  # ----------------------------------------------------------------------------
  # Returns the number of columns that the window can show. I don't actually
  # know if I need to specify this to be honest.
  # ----------------------------------------------------------------------------
  def col_max
    return 1
  end
 
  # ----------------------------------------------------------------------------
  # Returns the number of items that can be selected from (the total number of
  # stats being displayed). I didn't think I needed to specify this but I wasn't
  # able to move the cursor without it.
  # ----------------------------------------------------------------------------
  def item_max
    return @quantity
  end
 
  # ----------------------------------------------------------------------------
  # All this does is make the cursor rectangle smaller so it only covers the
  # number input for bonus points rather than stretching all the way across the
  # window.
  # ----------------------------------------------------------------------------
  def update_cursor
    cursor_rect.set(155, line_height*self.index, 32, line_height) if @quantity > 0
  end
 
  # ----------------------------------------------------------------------------
  # When the window refreshes we want to clear the screen then draw our stats.
  # ----------------------------------------------------------------------------
  def refresh
    contents.clear
    draw_stats
  end
 
  # ----------------------------------------------------------------------------
  # The update method covers our input for pressing the left and right arrow
  # keys, and handles the "buzzer" when we either can't assign enough points or
  # the player tries to remove points when none have been spend.
  # It supports holding down the keys to assign points faster. The reason I put
  # a separate @statups calculation and refresh call in each if statement is so
  # that this only happens when the player is pressing or holding a key.
  # There's no point in performing processor-intensive code when there's nothing
  # to change on the screen.
  # ----------------------------------------------------------------------------
  def update
    super
    if self.active && @quantity > 0
      if Input.repeat?(:LEFT)
        if @bonuses[self.index] == 0
          Sound.play_buzzer
        else
          @p_window.change_points(@stat_hash[:costs][self.index])
          @bonuses[self.index] -= @stat_hash[:costs][self.index]
          @statups[self.index] = (@bonuses[self.index] / @stat_hash[:costs][self.index]) * @stat_hash[:raises][self.index]
          refresh
        end
      end
      if Input.repeat?(:RIGHT)
        if @p_window.points < @stat_hash[:costs][self.index]
          Sound.play_buzzer
        else
          @p_window.change_points(-@stat_hash[:costs][self.index])
          @bonuses[self.index] += @stat_hash[:costs][self.index]
          @statups[self.index] = (@bonuses[self.index] / @stat_hash[:costs][self.index]) * @stat_hash[:raises][self.index]
          refresh
        end
      end
    end
  end
end

# ------------------------------------------------------------------------------
# Window_BonusPoints - new class
# ------------------------------------------------------------------------------
# This window displays the number of bonus points the player has to spend, and
# provides methods for manipulating the points value (so that the stats window
# can update the points as the player spends them).
# ------------------------------------------------------------------------------
class Window_BonusPoints < Window_Base
  # ----------------------------------------------------------------------------
  # Creates the window centered on the screen with a width of 400 and tall
  # enough to fit one row of text.
  # - points is the number of available points (which was passed in from the
  # value provided when the event called the script)
  # ----------------------------------------------------------------------------
  def initialize(points)
    @points = points
    ww = 400
    wh = fitting_height(1)
    wx = (Graphics.width / 2) - (ww / 2)
    super(wx, 0, ww, wh)
    refresh
  end
 
  # ----------------------------------------------------------------------------
  # Returns the number of points available to the player.
  # ----------------------------------------------------------------------------
  def points
    @points
  end
 
  # ----------------------------------------------------------------------------
  # Changes the number of points to the provided value. Although I could have
  # done separate methods for adding and subtracting, it's easy enough to
  # subtract points simply by passing a negative value to this one.
  # ----------------------------------------------------------------------------
  def change_points(value)
    @points += value
  end
 
  # ----------------------------------------------------------------------------
  # Draws the number of points on the screen. As the original request stipulated
  # that only 15 points maximum would be allocated at a time, it's set up to
  # format for 2 digits, though it can display more than this. Be aware that the
  # selection rectangle is positioned to have the value centered when the points
  # value is 2 digits, and there's some overlap if you add a third. If you want
  # to provide more than 99 points for the player to assign, you'll have to
  # make the selection rectangle slightly bigger.
  # ----------------------------------------------------------------------------
  def draw_points
    draw_text(0, 0, contents.width, line_height, sprintf("Remaining points: %02d", @points), 1)
  end
 
  # ----------------------------------------------------------------------------
  # Clear the screen, draw the points. Simples!
  # ----------------------------------------------------------------------------
  def refresh
    contents.clear
    draw_points
  end
 
  # ----------------------------------------------------------------------------
  # Points values are going to change as the player adds/subtracts them, so we
  # need to have an update method so the points window will be redrawn.
  # I could actually probably remove this and just call the points window's
  # refresh method when points are changed (which would probably make it process
  # a bit faster) but I haven't had any lag issues with the script so the
  # difference would be negligible.
  # ----------------------------------------------------------------------------
  def update
    refresh
  end
end

# ------------------------------------------------------------------------------
# Window_BonusConfirm - new class
# ------------------------------------------------------------------------------
# Nothing special; just a window that pops up and asks you if you're sure you
# want to confirm your choices. You can either confirm or cancel (which will
# return you to the stats assignment window).
# ------------------------------------------------------------------------------
class Window_BonusConfirm < Window_Command
  # ----------------------------------------------------------------------------
  # Creates the window, opens it (though it'll be hidden on creation) and places
  # it in the center of the screen.
  # ----------------------------------------------------------------------------
  def initialize
    super(0, 0)
    update_placement
    self.openness = 0
    open
    deactivate
  end
 
  # ----------------------------------------------------------------------------
  # Returns the width of the window. I probably didn't need this comment.
  # ----------------------------------------------------------------------------
  def window_width
    return 220
  end
 
  # ----------------------------------------------------------------------------
  # This method just places the window in the center of the screen.
  # ----------------------------------------------------------------------------
  def update_placement
    self.x = (Graphics.width - width) / 2
    self.y = (Graphics.height - height) / 2
  end

  # ----------------------------------------------------------------------------
  # Determines the commands that will be in the window. We have two; one to
  # confirm and one to cancel.
  # ----------------------------------------------------------------------------
  def make_command_list
    add_command("Confirm assignment", :ok)
    add_command("Return to assignment", :cancel)
  end
end

# ------------------------------------------------------------------------------
# Window_BonusCancel - new class
# ------------------------------------------------------------------------------
# This one is kind of like the confirm window only for cancelling. I could
# probably have just made one window and changed the commands in it depending
# on which key the player pressed, but making them separate windows just made
# it easier for me to sort out the flow of what happens when.
# ------------------------------------------------------------------------------
class Window_BonusCancel < Window_Command
  # ----------------------------------------------------------------------------
  # Creates the window, opens it (though it'll be hidden on creation) and places
  # it in the center of the screen.
  # ----------------------------------------------------------------------------
  def initialize
    super(0, 0)
    update_placement
    self.openness = 0
    open
    deactivate
  end
 
  # ----------------------------------------------------------------------------
  # Returns the width of the window. I definitely didn't need this one.
  # ----------------------------------------------------------------------------
  def window_width
    return 220
  end
 
  # ----------------------------------------------------------------------------
  # This method just places the window in the center of the screen.
  # ----------------------------------------------------------------------------
  def update_placement
    self.x = (Graphics.width - width) / 2
    self.y = (Graphics.height - height) / 2
  end

  # ----------------------------------------------------------------------------
  # Determines the commands that will be in the window. We have two; one to
  # confirm and one to cancel.
  # ----------------------------------------------------------------------------
  def make_command_list
    add_command("Cancel assignment", :ok)
    add_command("Return to assignment", :cancel)
  end
end

# ------------------------------------------------------------------------------
# Scene_Bonus - new class
# ------------------------------------------------------------------------------
# And now we create a new scene that brings together all our windows and
# provides handler functions for input.
# ------------------------------------------------------------------------------
class Scene_Bonus < Scene_MenuBase
  # ----------------------------------------------------------------------------
  # First we prepare the scene and create instance variables for the character
  # and points. I did originally use @actor but for some reason when I did this
  # the ID reverted to 1 when the scene started regardless of what was entered
  # in the script call. I think this might be something to do with @actor
  # already having been determined somewhere else.
  # ----------------------------------------------------------------------------
  def prepare(char, points)
    @char = $game_actors[char]
    @points = points
    @stat_hash = {:icons => [], :labels => [], :stats => [], :costs => [], :raises => []}
    for i in 0...BON_CONFIG[:stats].length
      if !@char.class.stat_locks.include?(BON_CONFIG[:stats][i])
        @stat_hash[:icons].push(BON_CONFIG[:icons][i])
        @stat_hash[:labels].push(BON_CONFIG[:labels][i])
        @stat_hash[:stats].push(BON_CONFIG[:stats][i])
        @stat_hash[:costs].push(BON_CONFIG[:costs][i])
        @stat_hash[:raises].push(BON_CONFIG[:raises][i])
      end
    end
  end
 
  # ----------------------------------------------------------------------------
  # And here's where we determine what happens when the scene starts. Fairly
  # simple: we'll create the title window, points window, stats window, confirm
  # window and cancel window, then reposition the points and title windows so
  # that no matter how tall the stats window is, both of them will appear
  # directly above/below it.
  # ----------------------------------------------------------------------------
  def start
    super
    create_title_window
    create_points_window
    create_stats_window
    create_confirm_window
    create_cancel_window
    @points_window.y = @stats_window.height + @stats_window.y
    @title_window.y = @stats_window.y - @title_window.height
  end
 
  # ----------------------------------------------------------------------------
  # Creates the title window, adds it to the viewport.
  # ----------------------------------------------------------------------------
  def create_title_window
    @title_window = Window_BonusTitle.new(@char)
    @title_window.viewport = @viewport
  end
 
  # ----------------------------------------------------------------------------
  # Creates the points window, adds it to the viewport.
  # ----------------------------------------------------------------------------
  def create_points_window
    @points_window = Window_BonusPoints.new(@points)
    @points_window.viewport = @viewport
  end
 
  # ----------------------------------------------------------------------------
  # Creates the stats window, adds it to the viewport, activates it, selects the
  # first options, and set handler methods for input. The first loop here looks
  # through the stat locks for the character's class and removes any matches
  # from the config arrays. This means that the stat will not be shown in the
  # window. This is useful if you're assigning for, say, a class that doesn't
  # use MP.
  # ----------------------------------------------------------------------------
  def create_stats_window
    @stats_window = Window_BonusStats.new(@char, @stat_hash[:stats].length, @points_window, @stat_hash)
    @stats_window.viewport = @viewport
    @stats_window.select(0)
    @stats_window.activate
    @stats_window.set_handler(:ok, method(:show_confirm_window))
    @stats_window.set_handler(:cancel, method(:show_cancel_window))
  end
 
  # ----------------------------------------------------------------------------
  # Creates the confirm window, sets its opacity to 255 (so you can see the text
  # clearly when it's shown over the stats window), hides it (so it isn't
  # visible until it needs to be) and sets handler methods for input.
  # ----------------------------------------------------------------------------
  def create_confirm_window
    @confirm_window = Window_BonusConfirm.new
    @confirm_window.viewport = @viewport
    @confirm_window.back_opacity = 255
    @confirm_window.hide
    @confirm_window.set_handler(:ok, method(:confirm_bonus))
    @confirm_window.set_handler(:cancel, method(:return_to_stats))
  end
 
  # ----------------------------------------------------------------------------
  # Creates the cancel window, sets its opacity to 255 (so you can see the text
  # clearly when it's shown over the stats window), hides it (so it isn't
  # visible until it needs to be) and sets handler methods for input.
  # ----------------------------------------------------------------------------
  def create_cancel_window
    @cancel_window = Window_BonusCancel.new
    @cancel_window.viewport = @viewport
    @cancel_window.back_opacity = 255
    @cancel_window.hide
    @cancel_window.set_handler(:ok, method(:return_scene))
    @cancel_window.set_handler(:cancel, method(:return_to_stats))
  end
 
  # ----------------------------------------------------------------------------
  # This is the handler method for pressing OK on the stats window. It activates
  # and shows the confirm window.
  # ----------------------------------------------------------------------------
  def show_confirm_window
    @confirm_window.show.activate
    @confirm_window.select(0)
  end
 
  # ----------------------------------------------------------------------------
  # This is the handler method for pressing Cancel on the stats window. It
  # activates and shows the cancel window.
  # ----------------------------------------------------------------------------
  def show_cancel_window
    @cancel_window.show.activate
    @cancel_window.select(0)
  end
 
  # ----------------------------------------------------------------------------
  # This is the handler method for pressing OK on the confirm window. It sets
  # the appropriate variable to 1, applies the character's stat bonuses, fully
  # heals them, and returns to the calling scene.
  # ----------------------------------------------------------------------------
  def confirm_bonus
    $game_variables[BON_CONFIG[:assignment_var]] = 1
    for i in 0...@stat_hash[:stats].length
      if @stats_window.get_statup(i) > 0
        @char.add_param(@stat_hash[:stats][i], @stats_window.get_statup(i))
      end
    end
    @char.hp = @char.mhp
    @char.mp = @char.mmp
    SceneManager.return
  end
 
  # ----------------------------------------------------------------------------
  # This is the handler method for pressing Cancel on either the confirm or
  # cancel windows. It hides both (as there's no differentiation between which
  # one was visible when the method was called) and reactivates the stats
  # window.
  # ----------------------------------------------------------------------------
  def return_to_stats
    @confirm_window.hide.deactivate
    @cancel_window.hide.deactivate
    @stats_window.activate
  end
end

FAQ
No questions at present.

Credit and Thanks
- Trihan
- Thanks to Clyve for making the original commission request.
- Navas and Sixth for MDEF suggestion and bug report
 
Last edited:

Navas

Warper
Member
Joined
Dec 20, 2016
Messages
3
Reaction score
0
First Language
Dutch
Primarily Uses
RMVXA
Hello,

Since MP is not being used in my game, how would I replace it with the MDF stat instead?

Thanks in advance!
 

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,136
Reaction score
811
First Language
Hungarian
Primarily Uses
RMVXA
Just a bug report during my coffee break. :p

In the create_stats_window method, you directly modify the value of a constant. Constants are named like that for a reason.
Once yo modify them, they will stay the way they are after the modification permanently (or until they are modified again) during the game.
They will reset to their original state only when the game is restarted.

Not only that, but you also delete elements from an array which is being iterated. This will mess up your iteration greatly, skipping some elements completely.
Technically, you don't iterate the array elements themselves, but the check you use to remove the elements from the array relies on the position of the elements in the array, and results in the same error at the end, the check will get incorrect values since the position of the elements changed in the meantime.

You probably already know these, since this is an old script of yours (assuming from the intro text in the opening post), but regardless, you should fix these things in it.

It's a nice and easy script to use, simple yet effective.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,371
Reaction score
1,537
First Language
English
Primarily Uses
RMMV
Version 1.11 of this script is now available! I've fixed the bug Sixth pointed out and added a couple of new features.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

ESAMarathon on Twitch, now streaming "Eat Girl". Yep, that's the title of a game... Apparently it's a Pacman knockoff.... Which is of course the only logical conclusion one would get from a name like "Eat Girl". :kaopride: I can't believe anybody would think anything else! :kaoback:
Super stoked i just finished my first town in my project, by finished i mean i can always add more decorative aesthetics and the NPCs don't talk yet but the mapping is complete and all the important chess pieces are present!
My brain: Hey, I have an idea how to make the transition to the main story quest in The Wastes more natural!
Me: Good!
My brain: You need to remake the hotel you start out in, it's not realistic enough.
Me: Ok... This was unexpected, but I can do it.
My brain: Now make each hotel floor 5 times as large to match the main part. Oh, you also need to make a bunch of new npcs to fill in the space on these maps.
Me: Crap.
Should be able to release Haxe MV/MZ next weekend.
It look that somehow MZ tracks are messed up (for example battle4 is obviously a theme, castle2 is a ship, ship1 is a scene and so on..). Maybe they just named them after with some ambiguity.

Forum statistics

Threads
100,610
Messages
977,808
Members
132,226
Latest member
iyako
Top