=begin
#==============================================================================#
# AMN State Info Viewer
# Version 1.02
# Author: AMoonlessNight
# Date: 20 Apr 2020
# Latest: 20 Apr 2020
#==============================================================================#
# UPDATE LOG
#------------------------------------------------------------------------------#
# 20 Apr 2020 - created the script
# (1.02) - added some aesthetic features
#==============================================================================#
# TERMS OF USE
#------------------------------------------------------------------------------#
# - Please credit AMoonlessNight or A-Moonless-Night
# - Free for non-commercial use; contact for commercial use
# - Credit Kread-EX and follow their terms of use
# - If you would like to edit/adjust this script, please make edits as a new
# script (do not edit this script directly) and provide proper credit
# - I'd love to see your game if you end up using one of my scripts
#==============================================================================#
Requires Traits Namer script by Kread-EX: grimoirecastle.wordpress.com
This script makes a scene to view all of the states in the game. Using Kread-EX's
Traits Namer script, you can see all the state's features. You can also see
the removal conditions.
States will be hidden if their name is blank. If you would like to hide certain
states, use the following notetag in the state's notes:
<no show>
--------------------------------------------------------------------------------
To call the state viewer scene, use the following:
Scene_StateMenu
e.g. SceneManager.scene.call(Scene_StateMenu)
--------------------------------------------------------------------------------
You can adjust aesthetic options below.
If the state has too many features, you can use the PGUP and PGDN keys to scroll.
=end
#==============================================================================
# ** EDITABLE REGION BELOW
#------------------------------------------------------------------------------
# Change the values in the area below to suit your needs.
#==============================================================================
module AMN_StateConfig
# The width for the state list window
LIST_WINDOW_WIDTH = 180
# Whether to draw lines to separate the different sections
DRAW_HEADER_LINES = true
# Whether to draw the state name in the data window in bold or not
STATE_NAME_BOLD = true
# The colour for the state name in the data window.
# Should be an integer that refers to the windowskin palette.
STATE_NAME_COLOUR = 0
# The colour for the header line and text in the data window.
# Should be an integer that refers to the windowskin palette.
HEADER_COLOUR = 12
# The colour for each identifier (e.g. what comes before the colon).
# Should be an integer that refers to the windowskin palette.
ID_COLOUR = 4
end
module AMN_StatesVocab
RESTRICTION_TYPE = ["None", "Attack enemy", "Attack enemy or ally", # 0, 1, 2
"Attack ally", "Cannot act"] # 3, 4
REMOVAL_TIMING = ["False", "At end of action", "At end of turn"] # 0, 1, 2
RESTRICTION = "Restriction:"
REMOVAL_BATTLE_END = "Remove at battle end: "
REMOVAL_RESTRICTION = "Remove by restriction: "
REMOVAL_AUTO = "Remove automatically"
TURNS = "turns"
REMOVE_DAMAGE = "%d%% chance to remove by damage"
REMOVE_WALKING = "Remove after: %d steps"
REMOVAL_TURNS = "Remove after: %s %s"
#==============================================================================
# ** END OF EDITABLE REGION
#------------------------------------------------------------------------------
# Please do not edit below this point unless you know what you are doing.
#==============================================================================
def self.restriction(value)
sprintf("%s %s", RESTRICTION, RESTRICTION_TYPE[value])
end
def self.auto_removal(value)
sprintf("%s: %s", REMOVAL_AUTO, REMOVAL_TIMING[value])
end
def self.turns_string(state)
turns = state.max_turns > 1 ? TURNS : TURNS[0..-2]
text = sprintf(REMOVAL_TURNS, state.turns_string, turns)
end
def self.removal_conditions_text(state)
cond = []
#~ cond << restriction(state.restriction) if state.restriction > 0
cond << REMOVAL_BATTLE_END + "#{state.remove_at_battle_end}".capitalize
cond << REMOVAL_RESTRICTION + "#{state.remove_by_restriction}".capitalize if state.restriction > 0
cond << auto_removal(state.auto_removal_timing)
cond << turns_string(state) if state.auto_removal_timing > 0
cond << sprintf(REMOVE_DAMAGE, state.chance_by_damage) if state.remove_by_damage
cond << sprintf(REMOVE_WALKING, state.steps_to_remove) if state.remove_by_walking
cond
end
end
class RPG::State
def viewable?
return false if self.note =~ /<no[ -_]+show>/i
return false if name.empty? || name =~ /\A\s*\Z/
return true
end
def turns_string
@min_turns == @max_turns ? "#{@max_turns}" : "#{@min_turns}–#{@max_turns}"
end
def removal_conditions_text
AMN_StatesVocab.removal_conditions_text(self)
end
def expanded_features
feats = @features
feats = [(AMN_StatesVocab.restriction(@restriction))] + feats if @restriction > 0
feats
end
end
class Window_Base < Window
def draw_state_name(state, x, y, width)
draw_icon(state.icon_index, x, y)
draw_text(x + 28, y, width, line_height, state.name)
end
end
class Window_StateList < Window_Selectable
def initialize(x, y, width, height)
super(x, y, width, height)
@data = []
refresh
end
def item_max; @data ? @data.size : 1; end
def item
@data && index >= 0 ? @data[index] : nil
end
def include?(item)
item && item.viewable?
end
def make_item_list
@data = $data_states.select {|item| include?(item) }
end
def draw_item(index)
item = @data[index]
if item
rect = item_rect(index)
rect.width -= 4
draw_state_name(item, rect.x, rect.y, rect.width)
end
end
def data_window=(data_window)
@data_window = data_window
call_update_help
end
def call_update_help
super
update_data if active && @data_window
end
def update_help
@help_window.set_item(item)
end
def update_data
@data_window.set_item(item)
end
def refresh
make_item_list
create_contents
draw_all_items
end
def process_pageup
end
def process_pagedown
end
def cursor_pagedown
end
def cursor_pageup
end
end
class Window_DataInfo < Window_Base
def initialize(x, y, width, height)
super(x, y, width, height)
end
def set_item(item)
if item != @item
@item = item
refresh
end
end
def clear
set_item(nil)
end
def refresh
contents.clear
draw_data_info
end
def draw_data_info
end
end
class Window_DataStates < Window_DataInfo
include AMN_StateConfig
def initialize(*args)
super(*args)
refresh
end
def refresh
update_all_text_height
create_contents
super
self.oy = 0
@scroll_pos = 0
end
def update
super
update_scroll_down if Input.press?(:R) && scrollable?
update_scroll_up if Input.press?(:L) && scrollable?
end
def update_all_text_height
@all_text_height = 1
if @item
height = state_conditions_text.compact.size + @item.expanded_features.compact.size
@all_text_height = line_height * (height + 2.25)
end
end
def state_conditions_text
@item ? @item.removal_conditions_text : []
end
def scrollable?
@all_text_height && @all_text_height > contents_window_height
end
def contents_height
@all_text_height && @all_text_height > contents_window_height ? @all_text_height : super
end
def contents_window_height
height - standard_padding * 2
end
def update_scroll_down
if @scroll_pos <= @all_text_height - contents_window_height
@scroll_pos += 1
self.oy = @scroll_pos
end
end
def update_scroll_up
if @scroll_pos >= 0
@scroll_pos -= 1
self.oy = @scroll_pos
end
end
def reset_font_settings
change_color(normal_color)
contents.font.bold = Font.default_bold
contents.font.italic = Font.default_italic
end
def draw_horz_line(x, y, width = contents_width, colour = header_colour)
line_y = y + line_height / 2 - 1
contents.fill_rect(x, line_y, width, 2, colour)
end
def draw_horz_line_w_shadow(x, y, width = contents_width, colour = header_colour)
draw_horz_line(x + 1, y + 1, width, Color.new(0,0,0,translucent_alpha))
draw_horz_line(x, y, width, colour)
end
def header_colour; text_color(HEADER_COLOUR); end
def id_colour; text_color(ID_COLOUR); end
def state_name_colour; text_color(STATE_NAME_COLOUR); end
def draw_data_info
return unless @item
change_color(state_name_colour)
contents.font.size = Font.default_size
contents.font.bold = STATE_NAME_BOLD
draw_state_name(@item, 0, 0, contents_width)
reset_font_settings
draw_horz_line_w_shadow(0, line_height * 1.25) if DRAW_HEADER_LINES
draw_line_header(line_height * 1.25, "Removal Conditions")
line = 2.25
line += draw_restrictions(line)
if @item.expanded_features.compact.size > 0
draw_horz_line_w_shadow(0, line_height * line) if DRAW_HEADER_LINES
draw_line_header(line_height * line, "Features")
line += 1
line += draw_features(line)
end
contents.font.size = Font.default_size
end
def draw_line_header(y, text)
change_color(header_colour)
contents.font.size = Font.default_size - 2
dx = DRAW_HEADER_LINES ? 24 : 4
contents.clear_rect(24, y, text_size(text).width + 8, line_height + 4) if DRAW_HEADER_LINES
draw_text(dx, y, contents_width, line_height, text)
end
def draw_restrictions(line)
contents.font.size = Font.default_size - 4
state_conditions_text.each_with_index do |cond, i|
next if cond.nil?
# split the line to change the colour after the first colon
res = cond.partition(":")
res = '\c[' + AMN_StateConfig::ID_COLOUR.to_s + ']' + res[0] + res[1] + '\c[0]' + res.last
draw_text_ex(4, line_height * (i + line), res)
end
return state_conditions_text.size
end
def draw_features(line)
contents.font.size = Font.default_size - 4
change_color(system_color)
@item.expanded_features.each_with_index do |f, i|
next if f.nil?
if f.is_a?(RPG::BaseItem::Feature)
name = KRX::TraitsNamer.feature_name(f.code, f.data_id, f.value)
else name = f
end
# split the line to change the colour after the first colon
res = name.partition(":")
res = '\c[' + AMN_StateConfig::ID_COLOUR.to_s + ']' + res[0] + res[1] + '\c[0]' + res.last
draw_text_ex(4, line_height * (i + line ), res)
end
return @item.features.size
end
end
class Scene_StateMenu < Scene_MenuBase
def start
super
create_help_window
create_data_window
create_list_window
end
def create_data_window
dy = @help_window.height
dx = AMN_StateConfig::LIST_WINDOW_WIDTH
@data_window = Window_DataStates.new(dx, dy, Graphics.width - dx, Graphics.height - dy)
end
def create_list_window
dy = @help_window.height
dw = @data_window.x
@list_window = Window_StateList.new(0, dy, dw, Graphics.height - dy)
@list_window.help_window = @help_window
@list_window.data_window = @data_window
@list_window.set_handler(:cancel, method(:return_scene))
@list_window.activate.select(0)
end
end