Introduction
This script allows the game developer to create categories within their Skills menu, both for the main menu and default battle-system. But not only that, you can hide certain skills from display, and define the order in which these categories appear in the menu.
Features
Separation of Skills into categories using element tagging
Hide some skills using a custom hide element
Define different menus for Field and Battle use
Script
The Script
Code:
#==============================================================================
# ** Fast Skill Grouping
#------------------------------------------------------------------------------
# by DerVVulfman
# version 1.2
# 06-12-2023 (MM/DD/YYYY)
# RGSS / RMXP
#==============================================================================
#
# INTRODUCTION:
#
# This script allows the game developer to create categories within their
# Skills menu, both for the main menu and default battle-system. But not
# only that, you can hide certain skills from display, and define the order
# in which these categories appear in the menu.
#
# It is designed based solely upon the default RPGMaker XP set of scripts,
# has no frills other than what was stated, and performs several rewrites.
#
#------------------------------------------------------------------------------
#
# WHAT IS ELEMENT TAGGING:
#
# It is the process of creating a custom element in the 'System Database',
# and then assigning the element to the skills within the Skills Database.
# This script allows you to use the IDs of the elements to create the indi-
# vidual groups.
#
#------------------------------------------------------------------------------
#
# Rewrites the following methods:
# * Window_Skill : refresh
# * Scene_Battle : update_phase3_skill_select
#
# Aliases (Attaches code to) the following methods:
# * Game_Battler : elements_correct
# * Window_Skill : initialize
# * Scene_Skill : main
# * Scene_Skill : update
# * Scene_Skill : update_skill
# * Scene_Battle : start_skill_select
# * Scene_Battle : end_skill_select
#
#------------------------------------------------------------------------------
#
# THANKS AND CREDIT:
#
# Credit goes to CarlosDavilla for noticing issues with the element system
# that inverted healing damage and battle system window cursor control.
#
#------------------------------------------------------------------------------
#
# TERMS OF USE:
#
# Free for use, even in commercial projects. Only due credit is required,
# including those listed within Thanks and Credits.
#
#==============================================================================
module Group
#--------------------------------------------------------------------------
SKILLS = {} # Do not touch
#--------------------------------------------------------------------------
# SKILL GROUP BREAKDOWN
# ---------------------
# Here, you create your individual skill groups. Please note that the order
# they appear is based on the 'KEY' for each SKILL entry in numeric order.
#
# Elem Group Name Group Description
# ==== ============ ==================
SKILLS[0] = [ 17, "Heal", "Healing skills" ]
SKILLS[1] = [ 19, "Fight", "Battle skills" ]
SKILLS[2] = [ 0, "All", "All skills" ]
# SKILL ORDER ARRAYS
# ------------------
# The S_MENU setting holds the keys of above SKILL entries for those groups
# that appear in the main menu Items list. Likewise, the S_BATTLE setting
# holds the keys for SKILL entries for those groups that appear within the
# default battle system Skill menu. The S_BATTLE setting must have values.
#
S_MENU = nil
S_BATTLE = [0,1]
# SKILL HIDING ELEMENT
# --------------------
# This setting holds the ID of an element that can be applied to any skill
# that the game developer does not want to be visible in inventory.
#
S_HIDE = nil
# ELEMENT EFFECT IGNORE
# ---------------------
# This setting is an array of elements that are being used to group skills
# and should not affect any element 'rate' determinations.
#
IGNORE = [17, 18, 19]
end
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# This class deals with battlers. It's used as a superclass for the Game_Actor
# and Game_Enemy classes.
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias game_battler_sgrouping_elements_correct elements_correct
#--------------------------------------------------------------------------
# * Calculating Element Correction
# element_set : element
#--------------------------------------------------------------------------
def elements_correct(element_set)
# Create a duplicate of the element set
# - Do not erase from the original element set lest tagging is removed
copy_element_set = element_set.dup
# Eliminate the Group Ignore elements from calculations
for i in Group::IGNORE
copy_element_set.delete(i) if copy_element_set.include?(i)
end
# Original call
return game_battler_sgrouping_elements_correct(copy_element_set)
end
end
#==============================================================================
# ** Window_Skill
#------------------------------------------------------------------------------
# This window displays usable skills on the skill and battle screens.
#==============================================================================
class Window_Skill < Window_Selectable
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias window_skill_sgrouping_initialize initialize
#--------------------------------------------------------------------------
# * Object Initialization
# actor : actor
#--------------------------------------------------------------------------
def initialize(actor)
# Original call
window_skill_sgrouping_initialize(actor)
# Set new alignment of window
self.y += 64
self.height -= 64
self.index = -1
self.active = false
# Add list of commands
@elements = []
key_list = Group::SKILLS.keys
key_list = Group::S_MENU unless Group::S_MENU.nil?
key_list = Group::S_BATTLE if $game_temp.in_battle
for key in key_list
@elements.push (Group::SKILLS[key][0] )
end
end
#--------------------------------------------------------------------------
# * Skill number
#--------------------------------------------------------------------------
def skill_number
return @data.size
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
# Add/Refresh item list
refresh_list
# Get item list size
@item_max = @data.size
# Exit if no content
return unless @item_max > 0
# Make a bit map and draw all items
self.contents = Bitmap.new(width - 32, row_max * 32)
for i in 0...@item_max
draw_item(i)
end
end
#--------------------------------------------------------------------------
# * Refresh List
#--------------------------------------------------------------------------
def refresh_list
# Get element id (individual group or in battle)
element = @elements[$scene.group_id] unless @elements.nil?
e_id = (element.nil?) ? -3 : element
# Set up data array
@data = []
# Add item
for i in 0...@actor.skills.size
skill = $data_skills[@actor.skills[i]]
@data.push(skill) if refresh_test(skill, e_id)
end
end
#--------------------------------------------------------------------------
# * Refresh List
# data : data item
# id : element_id
#--------------------------------------------------------------------------
def refresh_test(data, id)
data_set = data.element_set
effective = false
effective = true if data_set.include?(id) # Element ID test
effective = true if id == 0 # All Permit
effective = false if data_set.include?(Group::S_HIDE) # Block if hidden
return effective
end
end
#==============================================================================
# ** Window_SkillGroup
#------------------------------------------------------------------------------
# This window allows the targeting of a select group of skills.
#==============================================================================
class Window_SkillGroup < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 128, 640, 64)
self.contents = Bitmap.new(width - 32, height - 32)
# Add list of commands
@commands = []
@helps = []
key_list = Group::SKILLS.keys
key_list = Group::S_MENU unless Group::S_MENU.nil?
key_list = Group::S_BATTLE if $game_temp.in_battle
for key in key_list
@commands.push(Group::SKILLS[key][1])
@helps.push (Group::SKILLS[key][2] )
end
self.y = 64 if $game_temp.in_battle
@item_max = @commands.size
@column_max = @commands.size
@item_width = (width - 32) / @commands.size
self.index = 0
self.z = 2000
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
for i in 0...@commands.size
rect = Rect.new(@item_width * i, 0, @item_width, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
self.contents.font.color = system_color
self.contents.draw_text(rect, @commands[i], 1)
end
end
#--------------------------------------------------------------------------
# * Update Cursor Rectangle
#--------------------------------------------------------------------------
def update_cursor_rect
return if index == -1
self.cursor_rect.set(@item_width * index, 0, @item_width, 32)
end
#--------------------------------------------------------------------------
# * Help Text Update
#--------------------------------------------------------------------------
def update_help
text = @helps[self.index]
@help_window.set_text(text)
end
end
#==============================================================================
# ** Scene_Skill
#------------------------------------------------------------------------------
# This class performs skill screen processing.
#==============================================================================
class Scene_Skill
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias scene_skill_sgrouping_main main
alias scene_skill_sgrouping_update update
alias scene_skill_sgrouping_update_item update_skill
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :group_id # index of group item list
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Create group window
@group_window = Window_SkillGroup.new
#@group_window.y = 64
# Original call
scene_skill_sgrouping_main
# Delete group window
@group_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
@target_window.z = 2100
# Original call
scene_skill_sgrouping_update
# Update windows
@group_window.update
# Call group window if group window is active
return update_group if @group_window.active
end
#--------------------------------------------------------------------------
# * Frame Update (if skill window is active)
#--------------------------------------------------------------------------
def update_skill
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Erase item / show groupt window
@group_window.active = true
@group_window.visible = true
@skill_window.active = false
@skill_window.index = -1
# Refresh Input (clears target input)
Input.update
return
end
# Exit if L or R button was pressed
return if Input.repeat?(Input::L) || Input.repeat?(Input::R)
# Original call
scene_skill_sgrouping_update_item
end
#--------------------------------------------------------------------------
# * Frame Update (when group window is active)
#--------------------------------------------------------------------------
def update_group
# Update group item based on group index
if @group_id != @group_window.index
# Set group value and refresh
@group_id = @group_window.index
@group_window.help_window = @help_window
@skill_window.refresh
end
return if update_group_cancel?
return if update_group_decision?
return if update_group_next_actor?
return if update_group_prev_actor?
end
#--------------------------------------------------------------------------
# * Frame Update (when exiting group window)
#--------------------------------------------------------------------------
def update_group_cancel?
return false unless Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to menu screen
$scene = Scene_Menu.new(1)
return true
end
#--------------------------------------------------------------------------
# * Frame Update (when selecting in group window)
#--------------------------------------------------------------------------
def update_group_decision?
return false unless Input.trigger?(Input::C)
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Erase target window
@skill_window.active = true
@skill_window.index = 0
@group_window.active = false
return true
end
#--------------------------------------------------------------------------
# * Frame Update (when choosing next actor)
#--------------------------------------------------------------------------
def update_group_next_actor?
return false unless Input.trigger?(Input::R)
# Play cursor SE
$game_system.se_play($data_system.cursor_se)
# To next actor
@actor_index += 1
@actor_index %= $game_party.actors.size
# Switch to different skill screen
$scene = Scene_Skill.new(@actor_index)
return true
end
#--------------------------------------------------------------------------
# * Frame Update (when choosing previous actor)
#--------------------------------------------------------------------------
def update_group_prev_actor?
return false unless Input.trigger?(Input::L)
# Play cursor SE
$game_system.se_play($data_system.cursor_se)
# To previous actor
@actor_index += $game_party.actors.size - 1
@actor_index %= $game_party.actors.size
# Switch to different skill screen
$scene = Scene_Skill.new(@actor_index)
return true
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias scene_battle_sgrouping_start_skill_select start_skill_select
alias scene_battle_sgrouping_end_skill_select end_skill_select
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :group_id # index of group item list
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : skill selection)
#--------------------------------------------------------------------------
def update_phase3_skill_select
# Update Windows
update_phase3_skill_select_window
# Update group item based on group index
update_phase3_skill_select_group
# Exit if cancel or decidion
return if update_phase3_skill_select_cancel?
return if update_phase3_skill_select_decision?
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : item group update)
#--------------------------------------------------------------------------
def update_phase3_skill_select_window
# Active/inactive decision
if @skill_group_select
@skill_window.active = false
@skill_group_window.active = true
else
@skill_window.active = true
@skill_group_window.active = false
@skill_window.help_window = @help_window
end
# Visibility
@skill_window.visible = true
@skill_group_window.visible = true
@skill_group_window.update
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : item group update)
#--------------------------------------------------------------------------
def update_phase3_skill_select_group
# Update window
@skill_window.update
# Exit if group is current
return if @group_id == @skill_group_window.index
# Set group value and refresh
@group_id = @skill_group_window.index
@skill_group_window.help_window = @help_window
@skill_window.refresh
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : skill selection cancelled)
#--------------------------------------------------------------------------
def update_phase3_skill_select_cancel?
# Exit false unless B Button was pressed
return false unless Input.trigger?(Input::B)
# Perform cancel SE
$game_system.se_play($data_system.cancel_se)
if @skill_group_select
end_skill_select
else
@skill_group_select = true
@skill_window.index = -1
end
return true
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : skill selection decided)
#--------------------------------------------------------------------------
def update_phase3_skill_select_decision?
# Exit false unless C Button was pressed
return false unless Input.trigger?(Input::C)
if @skill_group_select
$game_system.se_play($data_system.decision_se)
@skill_group_select = false
@skill_window.index = 0
else
@skill = @skill_window.skill
if @skill == nil || !@active_battler.skill_can_use?(@skill.id)
$game_system.se_play($data_system.buzzer_se)
return true
end
@help_window.visible = false
$game_system.se_play($data_system.decision_se)
@active_battler.current_action.skill_id = @skill.id
@skill_window.visible = false
if @skill.scope == 1
start_enemy_select
elsif @skill.scope == 3 or @skill.scope == 5
start_actor_select
else
end_skill_select
phase3_next_actor
end
end
return true
end
#--------------------------------------------------------------------------
# * Start Item Select
#--------------------------------------------------------------------------
def start_skill_select
# Original call
scene_battle_sgrouping_start_skill_select
# Dispose and recreate Skill Window
@skill_window.dispose
@skill_window = Window_Skill.new(@active_battler)
# Create Item Group Window
@skill_group_window = Window_SkillGroup.new
@skill_group_window.back_opacity = 160
@skill_group_select = true
@group_id = nil
end
#--------------------------------------------------------------------------
# * End Skill Selection
#--------------------------------------------------------------------------
def end_skill_select
# Original call
scene_battle_sgrouping_end_skill_select
# Skill Group dispose
@skill_group_window.dispose
@skill_group_window = nil
end
end
Instructions
Build into the script.
FAQ
No customization is built into the script other than those listed.
Compatibility
Meant for the default RPGMaker XP system, some methods rewritten and altered.
Thanks and Credits
Credit goes to CarlosDavilla for noticing issues with the element system that inverted healing damage and battle system window cursor control.
Terms and Conditions
Free for use, even in commercial projects. Only due credit is required, including those listed within Thanks and Credits.
RE: Fast Skill Grouping - yamina-chan - 06-15-2021
So here I am, looking through cool things everyone's been working on in the time I've been away.
Inlcuding this script, which seems plenty usefull to me. :D
But I get the feeling you got the helpfull notes within the script mixed up with one of your other works, as they talk about items, weapons and armors instead of skills. ;)
Still, looking forward to maybe trying this out on the weekend to see what it actually looks like in game. Especially the ability to maybe hide certain skills from the battle menu but not the overworld menu would be fantastic. :D
RE: Fast Skill Grouping - DerVVulfman - 06-16-2021
(06-15-2021, 01:51 PM)yamina-chan Wrote: But I get the feeling you got the helpfull notes within the script mixed up with one of your other works, as they talk about items, weapons and armors instead of skills. ;)
Yup. The technique of Skill Grouping is not unlike Item Grouping, and I basically did a quick edit job of a matching Item script. I merely neglected to update the instructions to promote skills alone.
Done now. No syntax/logical/coding content has changed.
RE: Fast Skill Grouping - DerVVulfman - 06-12-2023
BUMP!!!
To version 1.2
After two years, CarlosDavilla notified me of issues with the script. It caused damage when the skill meant to heal and the skill selection window would not allow the cursor to move when a skill was meant to be selected in battle.
For this, the method which dealt with corrected element sets was altered, now merely using attached code instead of a rewrite. And a simple addition of an update command added into the Battle code to fix the window cursor issue was made.
Due credit now goes to CarlosDavilla for notifying me of these issues.