I'm going to be honest, I just assumed the demo had the most up to date version and didn't check :(
I've tested the paragraph formatter, there are some small changes necessary before it works with XP (it's literally 1 line of code, but if I didn't include it it would have several errors).
CODE
#==============================================================================
# Paragraph Formatter (XP)
# Version: 2.0
# Author: modern algebra (rmrk.net)
# Date: September 10, 2009
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
# The idea behind this script is to easily separate a long string into a
# paragraph that fits in to the dimensions you specify. More than that, you
# can also justify the paragraph
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 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 form. You can easily change which
# formatter or artist classes you want to use with the codes:
#
# bitmap.paragraph_formatter = Paragrapher::<formatter_name>
# bitmap.paragraph_artist = Paragrapher::<artist_name
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 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
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new attr_writer - paragraph_formatter, paragraph_artist
# new methods - paragraph_formatter, paragraph_artist, draw_paragraph
#==============================================================================
class Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_writer :paragraph_formatter # The formatting class for Paragraphing
attr_writer :paragraph_artist # The artist class for Paragraphing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def paragraph_formatter
@paragraph_formatter = $game_system.default_formatter if @paragraph_formatter.nil?
return @paragraph_formatter.new
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Artist
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def paragraph_artist
@paragraph_artist = $game_system.default_artist if @paragraph_artist.nil?
return @paragraph_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.dup
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
#==============================================================================
# *** Paragrapher
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Module containing the objects for the Paragrapher
#==============================================================================
module Paragrapher
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * New
#``````````````````````````````````````````````````````````````````````````
# 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
#==========================================================================
# ** Formatted_Text
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Bundles together the result of a Formatter class
#==========================================================================
Formatted_Text = Struct.new (:lines, :blank_width, :bitmap)
#==========================================================================
# ** Paragrapher
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This struct has accessible attributes and can easily paragraph objects.
#==========================================================================
class Paragrapher < Struct.new (:formatter, :artist)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Paragraph
# string : the string to be broken into lines
# specifications : the other arguments required for the Formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def paragraph(string, *specifications)
f = formatter.format (string, *specifications)
return artist.draw (f)
end
end
#==========================================================================
==
# ** Formatter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
# This class converts a string into a formatted text object
#==========================================================================
==
class Formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Format
# string : the string to be formatted
# specifications : the desired width of the paragraph, or a bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def format (string, specifications)
@string = string
# Checks whether specifications is a bitmap or a number. It then sets
# max_width and f.bitmap accordingly
if specifications.is_a? (Bitmap)
bitmap = specifications
@max_width = specifications.width
elsif specifications.is_a? (Numeric)
@max_width = specifications
bitmap = Bitmap.new (@max_width, 32)
else
# Error Catching: Incorrect Specifications
f = format ('Specifications Error', Bitmap.new (200, 64))
p 'Specifications Error: Please Pass Numeric or Bitmap'
return f
end
# Initializes Formatted_Text object
@format_text = Formatted_Text.new ([], [], bitmap)
@line_break = 0
@last_word = 0
for i in 0...@string.size
format_character (i)
end
# Adds the last line to f.lines
@format_text.lines.push ( @string[@line_break, @string.size - @line_break].scan (/./) )
# Since the last line is drawn normally, blank_width should be 0
@format_text.blank_width.push (0)
height = @format_text.lines.size*32
@format_text.bitmap = Bitmap.new (@max_width, height) if specifications.is_a? (Numeric)
# Returns the Formatted_Text object
formatted_text = @format_text.dup
@format_text = nil
return formatted_text
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Format Character
# i : index of position in the string
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def format_character (i)
character = @string[i, 1]
# If at the end of a word
if character == "\n" || character == " " || i == @string.size - 1
i += 1 if i == @string.size - 1 # Account for possible overlap at end
# If this word fits on the current line
substring = @string[@line_break, i - @line_break]
if @format_text.bitmap.text_size (substring).width > @max_width
next_line (@last_word)
end
if character == "\n"
next_line (i)
@format_text.blank_width[-1] = 0
end
@last_word = i
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Proceed to Next Line
# last_word : the index of the beginning of the previous word
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def next_line (last_word)
line = @string[@line_break, last_word - @line_break]
# Adds current line to f.lines
@format_text.lines.push ( line.scan (/./) )
# Calculates the blank space left to cover in the line
line_blank = @max_width - @format_text.bitmap.text_size(line).width
@format_text.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 = last_word + 1
end
end
#==========================================================================
==
# ** Artist
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
# Interprets a Formatted Text object and returns a bitmap of the paragraph
#==========================================================================
==
class Artist
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw
# f : Formatted Text Object
# justify_text : boolean value on whether to justify text
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw (f, justify_text = true)
# Calculates the necessary distance between lines
line_distance = f.bitmap.height.to_f / f.lines.size.to_f
line_distance = [f.bitmap.font.size + 4, 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
string = f.lines[i][j]
tw = f.bitmap.text_size (string).width
# Draws the string located at each index
f.bitmap.draw_text (position, line_distance*i, tw, line_distance, string)
# Keeps track of the position we are in in pixels
position += tw
position += blank_space if justify_text
end
end
return f.bitmap
end
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
@default_artist = Paragrapher::Artist
end
end
CODE
#==============================================================================
# Quest Journal
# Version: 2.1c
# Author: modern algebra (rmrk.net)
# Date: February 17, 2012
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This script provides a graphical interface for showing quest progress. It
# is objective based, meaning that you choose when to reveal objectives and
# you can set it so that they show up as complete or failed. That said, this
# script does not build quests for you; it is only a supplementary scene for
# showing them. As such, you need to event all of the quests yourself and
# update quest progress via script call. Therefore, pay close attention to
# the instructions both here and in the EDITABLE REGIONS.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# As with the previous version, all of the configuration is done in the
# QuestData module. While it is not necessary, it is recommended that you
# separate the configuration module from the rest of the script by cutting
# and pasting it into its own section (as you will see if you have the demo).
# If you wish to do that, you must cut everything from the first line down to
# the final end of the module. The first lines of the body script should be
# the equals bar right above # ** Game_Quest. Again, that is only to make
# things neater and has no functional relevance; it's up to you.
#
# That said, you can go to EDITABLE REGION A at line 242 to configure the
# default settings for the script. This ranges from the functional settings
# at line 244 (such as whether access is from the menu or the map or which
# categories are shown in the scene) to the graphical settings at line 267
# (such as which icons to use for categories and what names should be given
# to various headings). All of these will work fine without modification, of
# course, but even if do not want to configure now, you should familiarize
# yourself with all the settings so that you can make the best use of your
# script. I have included tons of settings so that you can make the Quest
# Journal unique for your game, even down to the order in which each section
# of the info window is drawn. A brief description of each setting is
# included either to the left or directly above each constant.
#
# EDITABLE REGION B is the real heart of the script however - this is where
# you fill in all of the details for the quests. Read the instructions at
# line 389 very carefully!
#
# You can activate and access a quest with this code in the Script event
# command:
#
# (quest (quest_id))
# quest_id : the integer ID of the quest you want to access
#
# From that, you can access or alter any relevant data stored in the quest,
# like name, description, objectives, etc... Example:
# (quest (1)).name = "Rest in Pieces"
#
# More relevantly, when it comes to controlling the progress of quests the
# following codes can be used in a Script event command. The arguments are
# the same for each command so I only explain them once. All of them are
# pretty self-explanatory and using any of them will activate the quest
# (unless you are using the MANUAL REVEAL setting at line 263).
#
# reveal_objective (quest_id, objective_id_1, ..., objective_id_n)
# quest_id : the integer ID of the quest you want to access.
# objective_id_1, ..., objective_id_n : a list of the IDs of the
# objectives you want to operate on. It can be as few as one or as
# many as all of them.
# Will show the listed objectives in the Quest's information
# conceal_objective (quest_id, objective_id_1, ..., objective_id_n)
# Will hide the listed objectives in the Quest's information
# complete_objective (quest_id, objective_id_1, ..., objective_id_n)
# Changes the colour of the listed objectives to the completed colour.
# The quest is completed once all prime objectives are.
# uncomplete_objective (quest_id, objective_id_1, ..., objective_id_n)
# Changes the status of the listed complete objectives back to active
# fail_objective (quest_id, objective_id_1, ..., objective_id_n)
# Changes the colour of the listed objectives to the failed colour.
# The quest is failed once one prime objective is.
# unfail_objective (quest_id, objective_id_1, ..., objective_id_n)
# Changes the status of the listed failed objectives back to active
# change_reward_status (quest_id, value)
# value : either true or false. If excluded, defaults to true.
# Totally optional, but this is just a personal switch which you can
# turn on when the reward is given. You can then make it a condition
# so you don't reward the players more than once. (see line 146)
#
# EXAMPLES:
# reveal_objective (1, 0)
# This would reveal the first objective of the quest with ID 1
# complete_objective (6, 2, 3)
# This would complete the third & fourth objectives of the quest with ID 6
# change_reward_status (8)
# This would set the reward switch to true for the quest with ID 8.
#
# Another new feature is the ability to set rewards that will show up in the
# menu (see EDITABLE REGION B). In addition to that, you can use the following
# code to automatically distribute the specified rewards for a quest if the
# quest is complete and no reward has yet been given:
#
# give_quest_reward (quest_id)
# quest_id : the ID of the quest whose rewards you want to distribute
#
# Of course, it can only distribute the rewards of type 0-4 (items, weapons,
# armors, gold, or exp). It won't distribute rewards you specify by string.
# To that end though, you can also use this code in a conditional branch and
# it will be satisfied only if it distributes the rewards. Thus, if you
# wanted to add some special rewards or do things like that, you can just put
# that in the branch for when it is true.
#
# Other codes for the Script event command that can be useful are:
#
# reset_quest (quest_id)
# quest_id : the integer ID of the quest you want to access.
# This will re-initialize the quest, meaning all quest progress to
# date will be lost
# remove_quest (quest_id)
# Deactivates the quest and resets it
# conceal_quest (quest_id)
# Deactivates the quest so it won't show up in the scene, but progress
# is saved
# reveal_quest (quest_id)
# Activates or reactivates the quest. This command is NECESSARY if
# MANUAL_REVEAL at line 263 is true or it has previously been
# concealed. Otherwise, it is sufficient just to operate on the quest
# change_quest_access (:symbol)
# :symbol must be one of six options (include the colon!):
# :disable - prevents access to the quest scene (greys out in menu)
# :enable - enables access to the quest scene
# :disable_menu - this removes the quest option from the menu
# :enable_menu - this adds the quest option to the menu
# :disable_map - this prevents access by key from the map
# :enable_map - this allows access by key to the map
# change_quest_background ("bg_filename", bg_opacity)
# bg_filename : the filename of the picture for the background in
# the Pictures folder
# bg_opacity : the opacity of the background graphic. If excluded,
# this defaults to the value of the setting at line 269.
# change_quest_windows ("windowskin_filename", window_opacity)
# windowskin_filename : the name of the Window graphic in System folder
# window_opacity : the opacity of the windows. If excluded, this
# defaults to the value of the setting at line 271.
#
# Also, there are a few codes that can be used in the Script command of a
# conditional branch. I note here that all of these are optional. You could
# use switch and variable checks and monitor quest progress solely through
# events. However, these commands make it a little easier and they are:
#
# quest_revealed? (quest_id)
# quest_id : the integer ID of the quest you want to access.
# This is satisfied if the quest has been activated.
# objective_revealed? (quest_id, objective_id_1, ... objective_id_n)
# objective_id_1, ..., objective_id_n : a list of the IDs of the
# objectives you want to operate on. It can be as few as one or as
# many as all of them.
# This is satisfied if the listed objectives have been revealed
# quest_complete? (quest_id)
# This is satisfied if all prime objectives of the quest are complete
# objective_complete? (quest_id, objective_id_1, ... objective_id_n)
# This is satisfied if all the listed objectives have been completed
# quest_failed? (quest_id)
# This is satisfied if any prime objective of the quest is failed
# objective_failed? (quest_id, objective_id_1, ... objective_id_n)
# This is satisfied if all the listed objectives have been failed
# quest_rewarded? (quest_id)
# This is satisfied if you have changed the reward status to true.
#
# If you want to call the Quest scene from an event, you use the following
# code in a call script:
#
# call_quest
# call_quest (quest_id)
# quest_id : ID of the quest you want to open the scene on
#
# If you do not specify a quest_id (line 168) then it will simply open the
# scene as it would normally. If you do specify a quest_id (line 169) then it
# will open the scene on that quest so long as it has been revealed and it is
# normally accessible through the quest menu.
#
# It will only give the rewards which are specified by the array. It will
# obviously not distribute any rewards you identified by String. It will do
# nothing if the reward_given boolean is true or if the quest is not yet
# complete. As such, you can also use this in a conditional branch and it
# will return true only if it gives the reward.
#
# Finally, a new feature in version 2.0 is the ability to have quest shops
# where the player can pay money to have a quest revealed. Setting it up is a
# little more complicated as it is all done in the script call and so you need
# to be careful not to spill over lines. Essentially, to identify the
# purchable quest you need to create an array like this:
# [quest_ID, cost, [o1, o2, ..., on], switch_ID]
# quest_ID : ID of the quest available for purchase
# cost : the price to buy the quest
# [o1, ..., on] : an array of the objectives revealed when the quest
# is purchased. If you exclude this, all objectives are revealed.
# switch_ID : this is the ID of a switch. When that switch is ON
# the quest will be available for purchase. Otherwise it won't. If
# excluded, the quest will always be available for sale at this shop
# You need one of those for every quest available at the shop and you put
# them all in another array and you pass it to the following code:
#
# call_quest_shop (quest_array, "ShopName")
# quest_array : the array of the above elements
# "ShopName" : the name of the shop. Allows you to differentiate
# quest givers (defaults to the value at line 357 if excluded).
#
# All of that is further complicated by the line length limit in the script
# command. In order to avoid this, it is better to create the array before
# calling the shop. See the example for how this can be done.
#
# EXAMPLE:
# a = []
# a.push ([1, 50, [0]], [4, 80, 1])
# a.push ([3, 100], [5, 75, [0,1], 1])
# call_quest_shop (a, "Fighter's Guild")
#
# The first line creates the array. The second line adds two quests to it: the
# quest with ID 1 will cost 50 Gold and, if purchased, will reveal the first
# objective; the quest with ID 4 will cost 80 Gold but will only show up if
# the switch with ID 1 is ON. It will reveal all objectives when purchased.
# The third line adds two more quests: the quest with ID 3 will cost 100 Gold
# and all objectives will be revealed when it is purchased; the quest with ID
# 5 will cost 75 gold but will only show up when switch 1 is ON. If purchased,
# it will reveal the first two objectives.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Compatibility:
#
# This script automatically adds itself to the default menu if you turn that
# feature on. It will also automatically add itself to the menu if you use
# Dargor's Custom Commands, YEM Main Menu Melody, Full Status Custom Menu
# System, or Phantasia-esque Custom Menu System. It must be below them though!
#==============================================================================
$imported = {} unless $imported
$imported["QuestJournal2.1"] = true
#==============================================================================
# *** Quest Data
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the configuration module for the Quest Journal
#==============================================================================
module QuestData
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION A
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||
# Functional Configuration
# CATEGORIES - this is an array describing which categories are available for
# the Quest Journal and the order in which they appear. The options are
# :all, :active, :complete, and :failed. You can also create custom
# categories which include only quests that are specifically added. To do
# so, just make up a symbol name (:name, so like :primary or :secondary or
# :companion or etc...) and add it to the array. Then, go to line 273 and
# associate an icon with the SAME symbol. Then, when you are setting up the
# quests at line 388, all you need to do is add that SAME symbol to the
# custom_categories attribute
CATEGORIES = [:all, :active, :complete, :failed]
# SORT_TYPE - This is how the quests are sorted. This value can be :id (sort
# by ID), :revealed (sort by order they were revealed), :alphabet (sort
# alphabetically by name), :level (sort by level) or :none. You can add
SORT_TYPE = :revealed # reverse to any to flip. (IE. :revealedreverse)
MENU_ACCESS = true # Can the script be accessed through the menu?
MENU_INDEX = 4 # If above is true, where in the command window?
KEY_ACCESS = false # Can the quest log be accessed by a key
MAPKEY_BUTTON = Input::L # If above is true, which button?
# MANUAL_REVEAL - whether you need to manually reveal every quest with the
# reveal_quest command or whether they are automatically revealed as soon as
# they are operated on (I.e. when you reveal, complete, etc.. objectives)
MANUAL_REVEAL = false
# Graphical Configuration
BG_PICTURE = "" # The filename of the background picture
BG_OPACITY = 255 # The opacity of the background picture, if used
WINDOWS_SKIN = "001-Blue01" # The skin of the windows in the Quest Scene
WINDOWS_OPACITY = 200 # The opacity of the windows in the Quest scene
LIST_WIDTH = 184 # The width, in pixels, of the left-hand windows
# ICONS - here is where you set up what icons are used for various things in
# the script, like categories, gold, exp, or even for the menu option if you
# are using one of the supported CMSes. If you have added custom categories
# at line 245, then you should also add a line for each of the new categories
# under the same format. Don't forget the comma at the end!
ICONS = {
:all => 0, # If 0, combines :active, :complete, and :failed
:active => '020-Accessory05', # Icon representing active quest list
:complete => '001-Weapon01', # Icon representing complete quest list
:failed => '050-Skill07', # Icon representing failed quest list
:menu => '', # Quests icon if using one of the supported CMSes
:gold => '', # Icon for gold if used as a reward
:exp => '', # Icon for exp if used as a reward
:level => 0, # Icon for level. Simply prints integer out if 0
:client => '', # Icon for client
:location => '', # Icon for Location
}
# For the following colours, you can use either an integer, in which case it
# takes its colour from that index of the windowskin palette, or you can use
# an array in the form [Red, Green, Blue, Alpha] (Alpha can be excluded)
COLOURS = {
:active => 0, # The colour of a quest that is active
:complete => 1, # The colour of a quest that is complete
:failed => 2, # The colour of a quest that is failed
:label => 3, # The colour for the label
:content => 4, # The colour for the main content of the window
:subtitle => 5 # The colour for the subtitles
}
VOCAB_QUESTS = "Quests" # What you want Quests to be called (eg. 'Missions')
# LABEL_FONTNAME - The name of the font used for the label window. If "" or
# [], then it just uses the default font.
LABEL_FONTNAME = ""
# LABEL_FONTSIZE - The size of the text in the label window. When 0, it will
# be automatically fitted to the window size (since it is dynamic)
LABEL_FONTSIZE = 0
LABEL_BOLD = false # Whether the label should be bold
# Info Window
# INFO_LAYOUT - this allows you to choose the vertical order in which each
# section of the quest information is drawn. The sections are - :banner,
# :name, :client, :level, :location, :description, :objectives, & :rewards.
# If you put two in an array, then they will be drawn at the same position.
INFO_LAYOUT = [:banner, :name, [:client, :level], :location, :description,
:objectives, :rewards]
# NAME_FONTNAME - The name of the font used for the quest name in the info
# window. If "" or [], then it just uses the default font.
NAME_FONTNAME = ""
NAME_FONTSIZE = 20 # Size of the font used for the name
NAME_BOLD = true # Whether the Name
# CONTENT_FONTNAME - The name of the font used for the actual content of the
# description, objectives. If "" or [], then it just uses the default font.
CONTENT_FONTNAME = ""
# SUBTITLE FONTNAME - The font used for the subtitles in the info window
# (The subtitles are: Description, Objectives, Rewards)
SUBTITLE_FONTNAME = ""
SUBTITLE_FONTSIZE = 20 # Size of the subtitles in quest info window
SUBTITLE_BOLD = true # Whether to embolden the subtitles
VOCAB_CLIENT = "Client:"
# CLIENT_WIDTH - The horizontal space available for client. If 0, it will
# take a little over half of the screen
CLIENT_WIDTH = 0
VOCAB_LOCATION = "Locale:"# The text used to identify the location
# LOCATION_WIDTH - The horizontal space available for location. If 0, it will
# take a little over half of the screen
LOCATION_WIDTH = 0
LEVEL_SPACE = 16 # The spacing between each level icon, if using icon
VOCAB_DESCRIPTION = "Description" # The word to identify the description text
DESC_FONTSIZE = 20 # The size of the font used in the description
VOCAB_OBJECTIVES = "Objectives" # The word to identify the objectives list
OBJECTIVE_BULLET = "—" # The character used for listing objectives
OBJ_FONTSIZE = 20 # The size of the font used for objectives
VOCAB_REWARDS = "Rewards" # The word to identify the Rewards list
REWARD_BULLET = "" # The character used for listing rewards
REWARD_FONTSIZE = 20 # The size of the font for each reward
ITEM_NUMBER_PREFACE = "x" # When reward amount > 1, this prefaces it.
VOCAB_EXP = "EXP" # The word used for experience, if used in rewards
DRAW_VOCAB_GOLD = true # Whether to draw the Gold vocab or only use icon
# VOCAB_HELP_GENERAL - The phrase in the help window when the list is active
VOCAB_HELP_GENERAL = "Use the horizontal directional keys to switch categories"
# VOCAB_HELP_SELECTED - The phrase in the help window when info is active
VOCAB_HELP_SELECTED = "Use the vertical directional keys to scroll up and down"
# Alignment of text in the Help Window - 0 => Left; 1 => Centre; 2 => Right
HELP_ALIGNMENT = 1
JUSTIFY_PARAGRAPHS = false# Whether Description/objectives are justified.
# Quest Shop Configuration
VOCAB_PURCHASE = "Quest Shop" # What you want the shop to be called
PURCHASE_USE_GOLD_ICON = true # Whether to use gold icon in Quest Shop
PURCHASE_INFO_LAYOUT = [:banner, :name, [:client, :level], :location,
:description, :objectives, :rewards] # Same as line 310, but for the Shop
PURCHASE_SE = ["Shop", 80] # The sound played when a quest is bought
PURCHASE_LIST_WIDTH = 224 # The list width for the purchase scene
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||
# END EDITABLE REGION A
#////////////////////////////////////////////////////////////////////////////
ICONS.default = 0
COLOURS.default = 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~
# * Quest Data
#````````````````````````````````````````````````````````````````````````````
# Returns skeleton data for the quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~
def self.quest_data (id)
# Set class variables to corresponding arguments
banner = ""
name = "??????"
description = "??????????"
client = ""
location = ""
objectives = []
prime = nil
rewards = []
level = 0
common_event = 0
icon_index = '049-Skill06'
custom_categories = []
case id
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION B
#````````````````````````````````````````````````````````````````````````
# To set up a quest, first identify it with an ID - this can be anything
# as long as it is not the same as another quest, but it is important to
# remember this ID as it is the only way to access your quest.
# In any case, the format for setting up a quest is:
#
# when <quest_id> # Give the quest an ID number
# banner = "filename"
# name = "quest_name"
# client = "person who gave the quest"
# location = "place to go for the quest"
# description = "quest_description"
# objectives[0] = "first_objective"
# ...
# objectives[n] = "(n - 1)th objective"
# prime = [objective_id, ..., objective_id]
# rewards = [ [type, id, amount], ..., [type, id], "text" ]
# level = integer
# common_event = id
# icon_index = quest_icon_index
# custom_categories.push (:symbol_1, ..., :symbol_n)
#
# Each of these values have an importance.
# banner is the name of a picture that can be shown at the top
# name is the name of the quest
# description is a small blurb explaining the overall goal of the quest
# client is the name of the person who gave the quest
# location is the place to go to to complete the quest
# objective[0..n] are short-term goals that lead to the overall goal
# primes are which objectives need to be complete before the quest is
# considered to be complete
# rewards will list the items you suggest. Note that there is no
# automatic gain - it simply lists them in the scene - you will need
# to give them out. The format is simple, [type, id, amount] where
# type identifies whether it is an item (0), weapon (1), armor (2),
# gold (3), or exp (4). id is the item ID (or the amount of gold or
# exp). amount only applies if it is an item, weapon or armor and it
# is how much of the item is given. If excluded, it won't draw it at
# all but if it is included, it will draw even if only 1. You can
# also just put a string ("text") and it will write that out.
# level is the difficulty of the quest
# common_event is the ID of a common event which is immediately called
# when the quest is first completed.
# icon_index is the icon that represents the quest
# custom_categories is a new feature which allows you to define which
# quests belong in special categories. All you need to do is add the
# appropriate symbol (which corresponds to an included category at
# line 245) and it will be added. Then, when the player scrolls over
# to that category, this quest, if revealed, will be there.
#
# Note that any of the above values can be omitted without throwing an
# error, but for the quest to work properly you should at least set the
# name, description, and objectives. If you do omit these, the default
# values are:
#
# banner = ""
# name = "??????"
# description = "??????????"
# client = ""
# location = ""
# objectives = []
# prime = [all objectives]
# rewards = []
# level = 0
# common_event = 0
# icon_index = 0
# custom_categories = []
#
# If you do want to require that all objectives must be satisfied before
# the quest is complete, then do not bother defining it. Otherwise, be
# sure to set it. If you are using the Special Codes Formatter, recall
# that all codes must be prefaced with \\, not just \.
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
when 1 # Quest 1
name = "Quest 1"
banner = "" # If using, must be a file from the Pictures folder
description = "This is the first quest the players receive. It probably involves playing fetch with lazy humans."
client = ""
location = ""
objectives[0] = "The first objective (ID 0)"
objectives[1] = "Do this next (ID 1)"
objectives[2] = "Return to collect your reward"
prime = [0, 1] # You only need to complete the first two objectives.
rewards = [ [0, 1, 3], [3, 100] ] # A potion and 100 Gold
level = 0
common_event = 0
icon_index = '002-Weapon02'
custom_categories = []
when 4 # Quest 4 <- Remember: Quest IDs MUST be unique!
name = "Lovely Lucy"
description = "Pursue the affections of \\c[6]Lucy\\c[0]"
objectives[0] = "Buy her a present from the vendor"
objectives[1] = "Take her out to dinner"
objectives[2] = "Walk her back to her home"
rewards = [ [4, 50], "\\icon[137]A kiss from Lucy" ]
icon_index = '003-Weapon03'
# Note that anything I don't want, like banner, prime, common_event, and
# custom_categories, I can exclude and it wll resort to default ("",
# [0, 1, 2], 0, and [])
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE REGION B
#////////////////////////////////////////////////////////////////////////
end
unless prime
prime = []
objectives.each_index { |i| prime.push (i) }
end
return banner, name, description, client, location, objectives, prime,
rewards, level, common_event, icon_index, custom_categories
end
end
class Bitmap
def clear_rect(*args)
color = Color.new(0, 0, 0, 0)
args << color
fill_rect(*args)
end
end
#==============================================================================
# ** Game_Quest
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Holds in-game data for a quest
#==============================================================================
class Game_Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_reader :revealed_objectives # An array of revealed objectives
attr_reader :complete_objectives # An array of completed objectives
attr_reader :failed_objectives # An array of failed objectives
attr_reader :id # The ID in $game_party.quests
attr_reader :name # The name of the quest
attr_reader :level # The difficulty level of the quest
attr_accessor :banner # Picture shown at top
attr_accessor :description # A blurb explaining the quest
attr_accessor :client # Name of quest-giver
attr_accessor :location # Place to do the quest
attr_accessor :objectives # An array of strings holding objectives
attr_accessor :prime_objectives # An array of crucial objectives
attr_accessor :rewards # An array of reward components
attr_accessor :common_event_id # ID of common event called at completion
attr_accessor :icon_index # The Icon associated with this quest
attr_accessor :custom_categories # An array of category symbols
attr_accessor :reward_given # A switch to ensure only one reward given
attr_accessor :concealed # A switch to show or not show the quest
attr_accessor :cost # The cost (if in a quest shop)
# Rewarded?
alias rewarded? reward_given
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (id, cost = -1)
@id = id
@cost = cost
reset
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reset
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reset
# Set variables to corresponding arguments
@banner, @name, @description, @client, @location, @objectives,
@prime_objectives, @rewards, @level, @common_event_id, @icon_index,
@custom_categories = QuestData.quest_data (id)
# Initialize non-public arrays
@revealed_objectives, @complete_objectives, @failed_objectives = [], [], []
@reward_given = false
@concealed = QuestData::MANUAL_REVEAL
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reveal Objective
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reveal_objective (*obj)
for i in obj do obj.delete (i) if i >= @objectives.size end
@revealed_objectives |= obj # Add to revealed objectives
@revealed_objectives.sort! # Sort from lowest index to highest index
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Complete Objective
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def complete_objective (*obj)
for i in obj
# Can't complete if failed or non-existent
obj.delete (i) if i >= @objectives.size || @failed_objectives.include? (i)
# Reveal the objective if it was not previously revealed
reveal_objective (i) unless @revealed_objectives.include? (i)
end
@complete_objectives |= obj # Add to complete objectives
@complete_objectives.sort! # Sort from lowest index to highest index
if complete?
$game_temp.common_event_id = @common_event_id # Call common event
@common_event_id = 0 # Don't call it again
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Fail Objective
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def fail_objective (*obj)
for i in obj
obj.delete (i) if i >= @objectives.size
# Reveal the objective if it was not previously revealed
reveal_objective (i) unless @revealed_objectives.include? (i)
end
@failed_objectives |= obj # Add to revealed objectives
@failed_objectives.sort! # Sort from lowest index to highest index
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Undo Objective operations
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def conceal_objective (*obj)
obj.each { |index| @revealed_objectives.delete (index) }
end
def uncomplete_objective (*obj)
for i in obj do @complete_objectives.delete (i) end
end
def unfail_objective (*obj)
for i in obj do @failed_objectives.delete (i) end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Objective Status Checks
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def objective_revealed? (*obj)
return (obj - @revealed_objectives).empty?
end
def objective_complete? (*obj)
return (obj - @complete_objectives).empty?
end
def objective_failed? (*obj)
return (obj - @failed_objectives).empty?
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Complete?
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def complete?
# Check if all prime objectives have been completed
return (@complete_objectives & @prime_objectives) == @prime_objectives
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Failed?
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def failed?
# Check if any prime objectives have been failed
return !(@failed_objectives & @prime_objectives).empty?
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Sortable values
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def name= (string)
@name = string
$game_party.quests.refresh_sort (:alphabet)
end
def level= (value)
@level = value
$game_party.quests.refresh_sort (:level)
end
def concealed= (value)
@concealed = value
value ? $game_party.quests.conceal_quest (id) : $game_party.quests.reveal_quest (id)
end
end
#==============================================================================
# ** Game_Quests
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class handles Quests. It is a wrapper for the built-in class "Hash".
# The instance of this class is accessed by $game_party.quests
#==============================================================================
class Game_Quests
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize
@data = {}
@id_sort = []
@revealed_sort = []
@alphabet_sort = []
@level_sort = []
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Quest
# quest_id : the ID of the quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def [] (quest_id)
return Game_Quest.new (0) unless quest_id.is_a? (Integer)
if @data[quest_id] == nil
@data[quest_id] = Game_Quest.new (quest_id)
reveal_quest (quest_id) unless @data[quest_id].concealed
end
return @data[quest_id]
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Quest List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def list
quest_list = []
type = $game_system.quest_sort_type.to_s
reverse = !(type.sub! (/reverse/i) { "" }).nil?
case type.to_sym
when :id
@id_sort.each { |id| quest_list.push (@data[id]) }
when :revealed
@revealed_sort.each { |id| quest_list.push (@data[id]) }
when :alphabet
@alphabet_sort.each { |id| quest_list.push (@data[id]) }
when :level
@level_sort.each { |id| quest_list.push (@data[id]) }
else
quest_list = @data.values
end
quest_list.each { |i| quest_list.delete (i) if i.concealed }
return reverse ? quest_list.reverse : quest_list
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Completed Quest List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def completed_list
complete_quests = []
list.each { |i| complete_quests.push (i) if i.complete? }
return complete_quests
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Failed Quest List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def failed_list
failed_quests = []
list.each { |i| failed_quests.push (i) if i.failed? }
return failed_quests
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Active Quest List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def active_list
return list - failed_list - completed_list
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Category List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def category_list (category)
case category
when :all then return list
when :active then return active_list
when :complete then return completed_list
when :failed then return failed_list
else
quest_list = []
list.each { |quest| quest_list.push (quest) if quest.custom_categories.include? (category) }
return quest_list
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Location
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_location (quest_id)
return nil, nil unless @data[quest_id]
# Check all categories
for i in 0...QuestData::CATEGORIES.size
index = category_list (QuestData::CATEGORIES[i]).index (@data[quest_id])
return i, index if index != nil
end
return nil, nil
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Revealed?
# quest_id : the ID of a checked quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def revealed? (quest_id)
return !@data[quest_id].nil? && !@data[quest_id].concealed
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Remove Quest
# quest_id : the ID of the quest to delete
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def remove (quest_id)
conceal_quest (quest_id)
@data.delete (quest_id)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Clear
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def clear
@data.clear
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reveal Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reveal_quest (quest_id)
return if !@data[quest_id] ||@id_sort.include? (quest_id)
$game_system.last_quest_id = quest_id # Open to this quest next time
# Save sorting order in separate arrays to avoid resorting every time
@revealed_sort.push (quest_id)
sorted = false
for i in 0...@id_sort.size
if @id_sort[i] > quest_id
@id_sort.insert (i, quest_id)
sorted = true
break
end
end
@id_sort.push (quest_id) unless sorted
sorted = false
for i in 0...@alphabet_sort.size
if @data[@alphabet_sort[i]].name.downcase > @data[quest_id].name.downcase
@alphabet_sort.insert (i, quest_id)
sorted = true
break
end
end
@alphabet_sort.push (quest_id) unless sorted
sorted = false
for i in 0...@level_sort.size
if @data[@level_sort[i]].level > @data[quest_id].level
@level_sort.insert (i, quest_id)
sorted = true
break
end
end
@level_sort.push (quest_id) unless sorted
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Conceal Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def conceal_quest (quest_id)
[@revealed_sort, @alphabet_sort, @id_sort, @level_sort].each { |ary| ary.delete (quest_id) }
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Refresh Sort ~ In case the name or level of a quest is changed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def refresh_sort (sort_type)
case sort_type
when :alphabet
s = @data.values.sort { |a, b| a.name.downcase <=> b.name.downcase }
@alphabet_sort.clear
s.each { |quest| @alphabet_sort.push (quest.id) }
when :level
s = @data.values.sort { |a, b| a.level <=> b.level }
@level_sort.clear
s.each { |quest| @level_sort.push (quest.id) }
end
end
end
#==============================================================================
# ** Game_Temp
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new instance variables - quest_shop_array, quest_shop_name
#==============================================================================
class Game_Temp
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :quest_shop_array
attr_accessor :quest_shop_name
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias maba_qjrnl_iniz_5uv1 initialize
def initialize (*args)
maba_qjrnl_iniz_5uv1 (*args)
@quest_shop_array = []
@quest_shop_name = QuestData::VOCAB_PURCHASE
end
end
#==============================================================================
# ** Game_System
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new instance variables - quest_disabled; qj_bg_picture; qj_bg_opacity;
# qj_windowskin; qj_window_opacity; last_quest_id
# aliased method - initialize
#==============================================================================
class Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_reader :quest_menuaccess # Is it accessible through the menu
attr_accessor :quest_disabled # Can you access quest journal at this time
attr_accessor :quest_keyaccess # Is it accessible by key?
attr_accessor :quest_sort_type # The type of sorting to use
attr_accessor :qj_bg_picture # The filename of the background graphic
attr_accessor :qj_bg_opacity # The opacity of the background picture
attr_accessor :qj_windowskin # The skin of the windows in the quest scene
attr_accessor :qj_window_opacity # The opacity of windows in the quest scene
attr_accessor :last_quest_cat # The last [category, index] of quest viewed
attr_accessor :last_quest_id # The ID of the last quest viewed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modlg_qstjrnl_iniz_4rd2 initialize
def initialize (*args)
# Run Original Method
modlg_qstjrnl_iniz_4rd2 (*args)
# Initialize new variables
@quest_menuaccess = QuestData::MENU_ACCESS
@quest_disabled = false
@quest_keyaccess = QuestData::KEY_ACCESS
@quest_sort_type = QuestData::SORT_TYPE
@qj_bg_picture = QuestData::BG_PICTURE
@qj_bg_opacity = QuestData::BG_OPACITY
@qj_windowskin = QuestData::WINDOWS_SKIN
@qj_window_opacity = QuestData::WINDOWS_OPACITY
@last_quest_cat = 0
@last_quest_id = 0
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Quest Access
# Not simply accessor so I could add in compatibility
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def quest_menuaccess= (value)
@quest_menuaccess = value
# Full Status Menu / Phantasia-esque Compatibility
@fscms_command_list ? c = @fscms_command_list : (@tpcms_command_list ? c = @tpcms_command_list : return)
value ? (c.insert (QuestData::MENU_INDEX, :quest2) unless c.include? (:quest2)) :
c.delete (:quest2)
end
end
#==============================================================================
# ** Game_Party
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new instance variable - quests
# aliased method - initialize
#==============================================================================
class Game_Party
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_reader :quests
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modalg_qst_jrnl_party_init_quests initialize
def initialize
# Run Original Method
modalg_qst_jrnl_party_init_quests
# Initialize @quests
@quests = Game_Quests.new
end
end
#==============================================================================
# ** Game_Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - change_quest_access; change_quest_background; remove_quest;
# quest; reveal_objective; conceal_objective; complete_objective;
# uncomplete_objective; fail_objective; unfail_objective; quest_revealed?;
# quest_complete?; quest_failed?; change_reward_status
#==============================================================================
class Game_Interpreter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Call Quest Scene
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def call_quest (quest_id = 0)
$game_system.se_play($data_system.decision_se)
$game_system.last_quest_id = quest_id if quest_id != 0 && quest_revealed? (quest_id)
$game_temp.next_scene = "quest"
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Call Quest Shop
# quest_array : a series of arrays in form [a, b, [c1, c2, ..., cn], d]
# a is the Quest ID; b is the Purchase Cost; [c1, ..., cn] is a list
# of which objectives are revealed when the quest is bought (it can be
# excluded and if so, then it will reveal them all); d is the ID of an
# enabling switch, meaning it will only show up if that switch is ON
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def call_quest_shop (quest_array, shop_name = QuestData::VOCAB_PURCHASE)
$game_temp.next_scene = "quest shop"
$game_temp.quest_shop_array = quest_array
$game_temp.quest_shop_name = shop_name
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change Quest Access
# sym - :enable, :disable, :enable_menu, :disable_menu, :enable_map, or
# :disable_map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def change_quest_access (sym)
case sym
when :enable then $game_system.quest_disabled = false
when :disable then $game_system.quest_disabled = true
when :enable_menu then $game_system.quest_menuaccess = true
when :disable_menu then $game_system.quest_menuaccess = false
when :enable_map then $game_system.quest_keyaccess = true
when :disable_map then $game_system.quest_keyaccess = false
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change Quest Background
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def change_quest_background (picture, opacity = $game_system.qj_bg_opacity)
$game_system.qj_bg_picture = picture
$game_system.qj_bg_opacity = opacity
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change Quest Windows
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def change_quest_windows (skin, opacity = $game_system.qj_window_opacity)
$game_system.qj_windowskin = skin
$game_system.qj_window_opacity = opacity
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reset Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reset_quest (id)
quest (id).reset
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Remove Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def remove_quest (id)
$game_party.quests.remove (id)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reveal/Conceal Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reveal_quest (id)
$game_party.quests[id].concealed = false
end
def conceal_quest (id)
$game_party.quests[id].concealed = true
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Quest
# id : Returns the quest object with that ID
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def quest (id)
return $game_party.quests[id]
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Quest Revealed?
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def quest_revealed? (id)
return $game_party.quests.revealed? (id)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Facade for Quest methods:
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[:reveal_objective, :conceal_objective, :complete_objective,
:uncomplete_objective, :fail_objective, :unfail_objective].each { |method|
define_method (method) { |id, *obj| quest (id).send (method, *obj) }
}
[:objective_revealed?, :objective_complete?, :objective_failed?].each { |method|
define_method (method) { |id, *obj| quest_revealed? (id) && quest (id).send (method, *obj) }
}
[:reset, :complete?, :rewarded?, :failed?].each { |method|
define_method ("quest_#{method}".to_sym) { |id| quest_revealed? (id) && quest (id).send (method) }
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Give Quest Reward
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def give_quest_reward (quest_id)
return false if !quest_complete? (quest_id) || quest_rewarded? (quest_id)
params = @params.dup
(quest (quest_id)).rewards.each { |reward|
next unless reward.is_a? (Array)
@params = [reward[1], 0, 0, (reward[2] ? reward[2] : 1)]
case reward[0]
when 0 then command_126 # Item
when 1 then command_127 # Weapon
when 2 then command_128 # Armor
when 3 # Gold
@params = [0, 0, reward[1]]
command_125
when 4 # Experience
@params = [0, 0, 0, reward[1], true]
command_315
end
}
@params = params
change_reward_status (quest_id, true)
return true
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change Reward Status
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def change_reward_status (id, value = true)
quest (id).reward_given = value
end
end
#==============================================================================
# ** Window_Base
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - text_color
#==============================================================================
class Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Text Color
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malbr_questj2_txtcol_5rf1 text_color
def text_color (color, *args)
return ( color.is_a? (Array) ? Color.new (*color) : malbr_questj2_txtcol_5rf1 (color, *args) )
end
def draw_icon(icon_name, x, y, enabled = true)
opacity = enabled ? 255 : 122
bitmap = RPG::Cache.icon (icon_name)
self.contents.blt(x, y, bitmap, bitmap.rect, opacity)
end
end
#==============================================================================
# ** Window_Message
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - convert_special_characters
#==============================================================================
class Window_Message
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Convert Special Characters
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_qstjrnl_refresh_6yh2 refresh
def refresh (*args)
# Run Original Method
@text.gsub! (/\\NQ\[(\d+)\]/i) { $game_party.quests[$1.to_i].name } # Name Quest
ma_qstjrnl_refresh_6yh2 (*args)
end
end
if Object.const_defined? (:Paragrapher) && Paragrapher.const_defined? (:Formatter_SpecialCodes)
class Paragrapher::Formatter_SpecialCodes
alias mlg_qstj_prfrmsub_5th2 perform_substitution
def perform_substitution (*args)
text = mlg_qstj_prfrmsub_5th2 (*args)
text.gsub! (/\\NQ\[(\d+)\]/i) { $game_party.quests[$1.to_i].name } # Monster Name
return text
end
end
end
#==============================================================================
# ** Window_QuestLabel
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window shows the quest label at the top of the scene
#==============================================================================
class Window_QuestLabel < Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (width = QuestData::LIST_WIDTH, height = 32 + 32, text = QuestData::VOCAB_QUESTS)
super (0, 0, width, height)
self.contents = Bitmap.new(width - 32, height - 32)
self.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
self.opacity = $game_system.qj_window_opacity
# Draw contents
self.contents.font.name = QuestData::LABEL_FONTNAME unless QuestData::LABEL_FONTNAME.empty?
if QuestData::LABEL_FONTSIZE == 0
self.contents.font.size = [height - 36, 28].min
# Fit it by width
while (contents.text_size (text).width > contents.width) && contents.font.size > Font.default_size
contents.font.size -= 1
end
else
contents.font.size = QuestData::LABEL_FONTSIZE
end
self.contents.font.bold = QuestData::LABEL_BOLD
self.contents.font.color = text_color (QuestData::COLOURS[:label])
self.contents.draw_text (contents.rect, text, 1)
end
end
#==============================================================================
# ** Window_QuestPurchaseGold
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This is the gold window for the Quest Purchase scene
#==============================================================================
class Window_QuestPurchaseGold < Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (y, width = QuestData::PURCHASE_LIST_WIDTH)
super (0, y, width, 32 + 32)
self.contents = Bitmap.new(width - 32, height - 32)
self.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
self.opacity = $game_system.qj_window_opacity
refresh
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Refresh
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def refresh
self.contents.clear
if QuestData::PURCHASE_USE_GOLD_ICON
draw_icon (QuestData::ICONS[:gold], 0, 0)
x = 28
else
x = 4
end
draw_currency_value ($game_party.gold, x, 0, contents.width - x)
end
end
#==============================================================================
# ** Window_QuestCategory
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window allows you to select between which list to show
#==============================================================================
class Window_QuestCategory < Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (category_index = 0, width = QuestData::LIST_WIDTH)
hght = 56
@all_index = QuestData::CATEGORIES.index (:all)
hght += 8 if @all_index && QuestData::ICONS[:all] == 0
super (0, 32 + 32, width, hght)
self.contents = Bitmap.new (width - 32, height - 32)
self.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
self.opacity = $game_system.qj_window_opacity
total = 24*QuestData::CATEGORIES.size
total += 16 if hght == 64
@spacing = (contents.width - total) / (QuestData::CATEGORIES.size - 1)
refresh (category_index)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Refresh
# category_index : icon to highlight -
# 0 => All, 1 => Active, 2 => Complete, 3 => Failed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def refresh (category_index = 0)
contents.clear
for i in 0...QuestData::CATEGORIES.size
draw_item (i, i == category_index)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Category
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_item (index, enabled = false)
x = index*(24 + @spacing)
x += 16 if @all_index && index > @all_index && contents.height == 32
category = QuestData::CATEGORIES[index]
if @all_index != index || contents.height == 24
y = (contents.height == 32 ? 4 : 0)
self.contents.clear_rect (x, y, 24, 24)
draw_icon (QuestData::ICONS[category], x, y, enabled)
else
self.contents.clear_rect (x, 0, 40, 32)
draw_icon (QuestData::ICONS[:complete], x, 0, enabled)
draw_icon (QuestData::ICONS[:failed], x + 16, 0, enabled)
draw_icon (QuestData::ICONS[:active], x + 8, 8, enabled)
end
end
end
#==============================================================================
# ** Window_QuestList
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window shows a list of quests
#==============================================================================
class Window_QuestList < Window_Command
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (free, width = QuestData::LIST_WIDTH, category = QuestData::CATEGORIES[0], quest_index = 0)
super (width, [Game_Quest.new(0, 0)] * 8)
self.height = 288
self.contents = Bitmap.new(width - 32, height - 32)
change_list (category)
self.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
self.opacity = $game_system.qj_window_opacity
self.index = quest_index
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change List
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def change_list (list_type)
if list_type.is_a? (Array)
@commands = list_type # List passed directly
else
@commands = $game_party.quests.category_list (list_type)
@commands = [] if @commands.nil?
end
@item_max = @commands.size
self.contents = Bitmap.new (contents.width, [self.height - 32, @item_max*32].max)
self.index = 0
refresh
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def quest
return @commands[self.index]
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Item
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_item(index, enabled = true)
rect = Rect.new(0, index * 32, self.contents.width, 32)
self.contents.clear_rect(rect)
self.contents.font.color.alpha = (enabled ? 255 : 128)
quest = @commands[index]
draw_icon (quest.icon_index, rect.x, rect.y, enabled)
rect.x += 28
rect.width -= 28
if quest.cost > -1 # Draw the quest's cost if > -1
self.contents.font.color = text_color (QuestData::COLOURS[:active])
self.contents.draw_text (rect, quest.cost.to_s, 2)
rect.width -= (self.contents.text_size (quest.cost.to_s).width + 6)
else
self.contents.font.color = text_color (quest.complete? ?
QuestData::COLOURS[:complete] : (quest.failed? ?
QuestData::COLOURS[:failed] : QuestData::COLOURS[:active]))
end
self.contents.draw_text(rect, quest.name)
end
end
#==============================================================================
# ** Window QuestInfo
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window shows the details of each quest
#==============================================================================
class Window_QuestInfo < Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (height = 480 - (32 + 32), x = QuestData::LIST_WIDTH, layout = QuestData::INFO_LAYOUT)
super (x, 0, 640 - x, height)
self.contents = Bitmap.new(width - 32, height - 32)
@layout = layout
self.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
self.opacity = $game_system.qj_window_opacity
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Refresh
# quest : the Quest object to show
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def refresh (quest)
contents.clear
if quest.nil?
self.contents = Bitmap.new(width - 32, height - 32)
return
end
@quest = quest
# Get the Paragrapher
if !Object.const_defined? (:Paragrapher) || !Paragrapher.const_defined? (:Formatter)
p "This script requires the Paragraph Formatter 2.0! You can get it at RMRK:",
" http://rmrk.net/index.php/topic,25129.0.html", "The Special Codes Formatter is supported, but you still need the base script."
else
if Paragrapher.const_defined? (:Formatter_SpecialCodes)
@paragrapher = Paragrapher.new (Paragrapher::Formatter_SpecialCodes.new, Paragrapher::Artist_SpecialCodes.new)
else
@paragrapher = Paragrapher.new (contents.paragraph_formatter, contents.paragraph_artist)
end
end
# Calculate the size of the bitmap
h = 0
set_font (0)
for subtitle in @layout do h += calculate_height_req (subtitle) end
self.contents = Bitmap.new (contents.width, [h, self.height - 32].max)
# Draw everything in the specified order
y = 0
for subtitle in @layout
if subtitle.is_a? (Array)
max_y = y
# Draw on same line if an array
for i in subtitle
y_plus = draw_section (i, y) # Don't track since on same line
max_y = y_plus if y_plus > max_y
end
y = max_y
else
y = draw_section (subtitle, y)
end
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Calculate Height Requirement
# section : a symbol for the heading it is asking about
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calculate_height_req (section)
# Calculate the amount of vertical space needed for each section
case section
when Array then calculate_height_req(section.max { |a, b|
calculate_height_req(a) <=> calculate_height_req(b) })
when :banner then return RPG::Cache.picture (@quest.banner).height unless @quest.banner.empty?
when :name then return 32 unless @quest.name.empty?
when :level then return 32 unless @quest.level <= 0
when :client then return 32 unless @quest.client.empty?
when :location then return 32 unless @quest.location.empty?
when :description
if @paragrapher && !@quest.description.empty?
# Create formatted text object for the description & check total size
bmp = Bitmap.new (contents.width - 16, 32)
bmp.font = contents.font.dup
bmp.font.size = QuestData::DESC_FONTSIZE
@desc_ft = @paragrapher.formatter.format (@quest.description, bmp)
return (@desc_ft.lines.size*bmp.font.size) + ((3*32) / 2) + 4
end
when :objectives
if @paragrapher && !@quest.revealed_objectives.empty?
# Create formatted text objects for the objectives & check total size
tw = self.contents.text_size (QuestData::OBJECTIVE_BULLET).width
bmp = Bitmap.new (contents.width - 12 - tw, 32)
bmp.font = contents.font.dup
bmp.font.size = QuestData::OBJ_FONTSIZE
h = 32
@objs_ft = []
for i in @quest.revealed_objectives
ft = @paragrapher.formatter.format (@quest.objectives[i], bmp)
h += (ft.lines.size * bmp.font.size) + 2
@objs_ft.push (ft)
end
return h + 2
end
when :rewards then return 32*(@quest.rewards.size + 1) unless @quest.rewards.empty?
end
return 0
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Section
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_section (section, y)
set_font (0)
case section
when :banner then y = draw_banner (y)
when :name then y = draw_name (y)
when :level then y = draw_level (y)
when :client then y = draw_client (y)
when :location then y = draw_location (y)
when :description then y = draw_description (y)
when :objectives then y = draw_objectives (y)
when :rewards then y = draw_rewards (y)
end
return y
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Banner
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_banner (y)
return y if @quest.banner.empty?
banner = RPG::Cache.picture (@quest.banner)
self.contents.blt ((contents.width - banner.width) / 2, y, banner, banner.rect)
return y + banner.height
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Name
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_name (y)
return y if @quest.name.empty?
self.contents.font.name = QuestData::NAME_FONTNAME.empty? ? Font.default_name : QuestData::NAME_FONTNAME
self.contents.font.size = QuestData::NAME_FONTSIZE == 0 ? Font.default_size : QuestData::NAME_FONTSIZE
self.contents.font.bold = QuestData::NAME_BOLD
self.contents.font.color = text_color (@quest.complete? ?
QuestData::COLOURS[:complete] : (@quest.failed? ?
QuestData::COLOURS[:failed] : QuestData::COLOURS[:active]))
self.contents.draw_text (0, y, self.contents.width, 32, @quest.name, 1)
return y + 32
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Level
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_level (y)
return y if @quest.level < 1
if QuestData::ICONS[:level] != 0
x = self.contents.width - 24
@quest.level.times do
draw_icon (QuestData::ICONS[:level], x, y)
x -= QuestData::LEVEL_SPACE
end
else
set_font (1)
self.contents.draw_text (0, y, contents.width, 32, @quest.level.to_s, 2)
end
return y + 32
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Client
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_client (y)
return y if @quest.client.empty?
x = 0
if QuestData::ICONS[:client] != 0
draw_icon (QuestData::ICONS[:client], x, y)
x += 28
end
if !QuestData::VOCAB_CLIENT.empty?
set_font (1)
self.contents.draw_text (x, y, 80, 32, QuestData::VOCAB_CLIENT)
x += 80
end
set_font (0)
wdth = QuestData::CLIENT_WIDTH == 0 ? (contents.width - ((5*QuestData::LEVEL_SPACE) + 8)) : QuestData::CLIENT_WIDTH
self.contents.draw_text (x, y, wdth - x, 32, @quest.client, 2)
return y + 32
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Location
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_location (y)
return y if @quest.location.empty?
x = 0
if QuestData::ICONS[:location] != 0
draw_icon (QuestData::ICONS[:location], x, y)
x += 28
end
if !QuestData::VOCAB_LOCATION.empty?
set_font (1)
self.contents.draw_text (x, y, 80, 32, QuestData::VOCAB_LOCATION)
x += 80
end
set_font (0)
wdth = QuestData::LOCATION_WIDTH == 0 ? (contents.width - ((5*QuestData::LEVEL_SPACE) + 8)) : QuestData::LOCATION_WIDTH
self.contents.draw_text (x, y, wdth - x, 32, @quest.location, 2)
return y + 32
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Description
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_description (y)
return y if !@paragrapher || @quest.description.empty?
# Setup the bitmap of appropriate size for drawing the description
hght = @desc_ft.lines.size * @desc_ft.bitmap.font.size
font = @desc_ft.bitmap.font.dup
@desc_ft.bitmap.dispose
@desc_ft.bitmap = Bitmap.new (self.contents.width, hght)
@desc_ft.bitmap.font = font
set_font (1)
rect = Rect.new (2, y + (32 / 2), self.contents.width - 4, hght + 32)
rect2 = Rect.new (4, y + (32 / 2) + 2, self.contents.width - 8, hght + 32 - 4)
# Make Box
if Bitmap.method_defined? (:fill_rounded_rect) # Bitmap Addons
self.contents.fill_rounded_rect (rect, self.contents.font.color)
self.contents.fill_rounded_rect (rect2, Color.new (0, 0, 0, 0))
else
self.contents.fill_rect (rect, self.contents.font.color)
self.contents.clear_rect (rect2)
end
# Clear rect for the Description Label
tw = self.contents.text_size (QuestData::VOCAB_DESCRIPTION).width
self.contents.clear_rect (32, y, tw + 4, 32)
# Draw Description Label
self.contents.draw_text (34, y, tw + 2, 32, QuestData::VOCAB_DESCRIPTION)
set_font (0)
# Draw Description paragraph
@paragrapher.artist.draw (@desc_ft, QuestData::JUSTIFY_PARAGRAPHS)
self.contents.blt (8, y + 32, @desc_ft.bitmap, @desc_ft.bitmap.rect)
@desc_ft.bitmap.dispose
@desc_ft = nil
return rect.y + rect.height + 4
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Objectives
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_objectives (y)
return y if !@paragrapher || @quest.revealed_objectives.empty?
set_font (1)
self.contents.draw_text (32, y, contents.width - 32, 32, QuestData::VOCAB_OBJECTIVES)
tw = self.contents.text_size (QuestData::OBJECTIVE_BULLET).width
y += 32
bmp = @objs_ft[0].bitmap
for i in 0...@quest.revealed_objectives.size
# Draw Bullet
set_font (1)
self.contents.draw_text (8, y, tw, 32, QuestData::OBJECTIVE_BULLET)
set_font (0)
ft = @objs_ft[i]
ft.bitmap = Bitmap.new (contents.width, ft.lines.size*bmp.font.size)
ft.bitmap.font = bmp.font.dup
obj = @quest.revealed_objectives[i]
# Get the correct color
ft.bitmap.font.color = text_color (@quest.objective_complete? (obj) ?
QuestData::COLOURS[:complete] : (@quest.objective_failed? (obj) ?
QuestData::COLOURS[:failed] : QuestData::COLOURS[:active]))
@paragrapher.artist.draw (ft, QuestData::JUSTIFY_PARAGRAPHS)
self.contents.blt (12 + tw, y + 2, ft.bitmap, ft.bitmap.rect)
# Modify the Y accordingly
y += 2 + ((ft.bitmap.font.size)*ft.lines.size)
ft.bitmap.dispose
end
bmp.dispose
@objs_ft.clear
return y + 2
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Rewards
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def draw_rewards (y)
return y if @quest.rewards.empty?
set_font (1)
self.contents.draw_text (32, y, contents.width - 32, 32, QuestData::VOCAB_REWARDS)
x = QuestData::REWARD_BULLET.empty? ? 8 : 12 + (contents.text_size (QuestData::REWARD_BULLET).width)
y += 32
for reward in @quest.rewards
# Draw Bullet
set_font (1)
self.contents.draw_text (8, y, 100, 32, QuestData::REWARD_BULLET)
set_font (0)
self.contents.font.size = QuestData::REWARD_FONTSIZE
if reward.is_a? (Array)
item = nil
case reward[0]
when 0 then item = $data_items[reward[1]]
when 1 then item = $data_weapons[reward[1]]
when 2 then item = $data_armors[reward[1]]
when 3 # Gold
draw_icon (QuestData::ICONS[:gold], x, y)
self.contents.font.color = normal_color
self.contents.draw_text (x + 24, y, contents.width - x - 24, 32, reward[1].to_s)
if QuestData::DRAW_VOCAB_GOLD
tw = self.contents.text_size(reward[1].to_s).width
self.contents.font.color = system_color
self.contents.draw_text(x + tw + 28, y, contents.width - x - 28 - tw, 32, 'Gold')
end
when 4 # Exp
draw_icon (QuestData::ICONS[:exp], x, y)
self.contents.font.color = normal_color
self.contents.draw_text (x + 24, y, contents.width - x - 24, 32, reward[1].to_s)
tw = self.contents.text_size(reward[1].to_s).width
self.contents.font.color = system_color
self.contents.draw_text(x + tw + 28, y, contents.width - x - 28 - tw, 32, QuestData::VOCAB_EXP)
end
# Draw Item
if item != nil
draw_item_name (item, x, y)
unless reward[2].nil? # Draw Number
contents.font.color = system_color
tw = contents.text_size (item.name).width + 28
contents.draw_text (x + tw, y, 100, 32, "#{QuestData::ITEM_NUMBER_PREFACE}#{reward[2]}")
end
end
else
set_font (0)
# Allow use of special codes if Special Codes Formatter available
if Object.const_defined? (:Paragrapher) && Paragrapher.const_defined? (:Formatter_SpecialCodes)
bmp = Bitmap.new (contents.width - x, 32)
bmp.font = contents.font.dup
bmp.font.size = QuestData::REWARD_FONTSIZE
@paragrapher.paragraph (reward, bmp)
self.contents.blt (x, y, bmp, bmp.rect)
bmp.dispose
else
self.contents.draw_text (x, y, contents.width - x, 32, reward)
end
end
y += 32
end
return y
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reset Font
# 0 => Content Font; 1 => Subtitle Font
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def set_font (type = 0)
case type
when 0 # Content
self.contents.font.name = QuestData::CONTENT_FONTNAME.empty? ? Font.default_name : QuestData::CONTENT_FONTNAME
self.contents.font.size = Font.default_size
self.contents.font.bold = false
self.contents.font.color = normal_color
when 1 # Subtitle
self.contents.font.name = QuestData::SUBTITLE_FONTNAME.empty? ? Font.default_name : QuestData::SUBTITLE_FONTNAME
self.contents.font.size = QuestData::SUBTITLE_FONTSIZE == 0 ? Font.default_size : QuestData::SUBTITLE_FONTSIZE
self.contents.font.bold = QuestData::SUBTITLE_BOLD
self.contents.font.color = system_color
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Colors
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def normal_color
return text_color (QuestData::COLOURS[:content])
end
def system_color
return text_color (QuestData::COLOURS[:subtitle])
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
if Input.press? (Input::DOWN)
self.oy = [self.oy + 3, contents.height - self.height + 32].min
elsif Input.press? (Input::UP)
self.oy = [self.oy - 3, 0].max
end
end
end
#==============================================================================
# ** Window_Command
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# aliased methods - initialize
# created methods - index, modalg_real_index
#==============================================================================
class Window_Command
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias modalg_quest_journal_cmd_initialize initialize
def initialize(width, commands)
@is_menu = $scene.is_a?(Scene_Menu) and ModAlg_QuestData::MENU_ACCESS
if @is_menu
commands.insert(ModAlg_QuestData::MENU_INDEX, 'Quest')
end
modalg_quest_journal_cmd_initialize(width, commands)
if @is_menu
self.height = 224
end
end
#--------------------------------------------------------------------------
# * Index
#--------------------------------------------------------------------------
def index
if @is_menu and @index >= ModAlg_QuestData::MENU_INDEX
return @index - 1
else
return @index
end
end
#--------------------------------------------------------------------------
# * Real Index
#--------------------------------------------------------------------------
def modalg_real_index
return @index
end
end
#==============================================================================
# ** Scene_Menu
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# aliased methods - update command
# overwritten methods - initialize
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(index = 0)
if index >= ModAlg_QuestData::MENU_INDEX
if $scene.is_a? Scene_Quest
@menu_index = index
else
@menu_index = index + 1
end
else
@menu_index = index
end
end
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
alias modalg_quest_journal_menu_update_command update_command
def update_command
modalg_quest_journal_menu_update_command
quest_index = ModAlg_QuestData::MENU_INDEX
if $scene != self or @command_window.active == false
return if $scene.is_a?(Scene_Map)
if @command_window.modalg_real_index == quest_index
@status_window.active = false
@status_window.index = -1
$game_system.quest_menuaccess = true
$scene = Scene_Quest.new
end
end
end
end
#==============================================================================
# ** Scene Quest
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class handles the quest scene processing
#==============================================================================
class Scene_Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (*args)
if args.size == 0 # Last Quest ID
cat_ind = $game_system.last_quest_cat
cat = QuestData::CATEGORIES[cat_ind]
ind = ($game_party.quests.category_list (cat)).index ($game_party.quests[$game_system.last_quest_id])
if !ind.nil?
@category_index, @quest_index = cat_ind, ind
else
@category_index, @quest_index = $game_party.quests.get_location ($game_system.last_quest_id)
end
else
@category_index = args[0] < QuestData::CATEGORIES.size ? args[0] : 0
@quest_index = args[1]
end
@category_index = 0 if @category_index.nil?
@quest_index = 0 if @quest_index.nil?
@info_window_active = false
@from_menu = $scene.is_a? (Scene_Menu)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Main Processing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def main
start
Graphics.transition
loop do
Graphics.update
Input.update
update
break if $scene != self
end
Graphics.freeze
terminate
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Start Processing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def start
#create_menu_background
# Create Background picture
unless $game_system.qj_bg_picture.empty?
@bg_sprite = Sprite.new
@bg_sprite.bitmap = RPG::Cache.picture ($game_system.qj_bg_picture)
@bg_sprite.opacity = $game_system.qj_bg_opacity
end
free_space = 480 - 96 - 2*32
if QuestData::CATEGORIES.size > 1
@category_window = Window_QuestCategory.new (@category_index)
free_space -= @category_window.height
end
@label_window = Window_QuestLabel.new (QuestData::LIST_WIDTH, 32 + 32 + (free_space % 32))
y = @label_window.height
if @category_window
@category_window.y = y
y += @category_window.height
end
@list_window = Window_QuestList.new (free_space, QuestData::LIST_WIDTH, QuestData::CATEGORIES[@category_index], @quest_index)
@list_window.y = y
@list_window.active = true
@info_window = Window_QuestInfo.new
@info_window.refresh (@list_window.quest)
# Create Help Window
@help_window = Window_Help.new
@help_window.windowskin = RPG::Cache.windowskin ($game_system.qj_windowskin)
@help_window.opacity = $game_system.qj_window_opacity
@help_window.y = 480 - @help_window.height
@help_window.width = 640
@help_window.contents = Bitmap.new(640 - 32, 64 - 32)
@help_window.set_text (QuestData::VOCAB_HELP_GENERAL, QuestData::HELP_ALIGNMENT)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Terminate Process
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def terminate
#dispose_menu_background
if @bg_sprite # Dispose Background Sprite
@bg_sprite.bitmap.dispose
@bg_sprite.dispose
end
@label_window.dispose
@category_window.dispose if @category_window
@list_window.dispose
@info_window.dispose
@help_window.dispose
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
#update_menu_background
if @list_window.active
update_list_window
elsif @info_window_active
update_info_window
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update List Window
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_list_window
@list_window.update
update_category_window if @category_window
if Input.trigger?(Input::B) # If Button B is pressed
$game_system.se_play($data_system.cancel_se)
return_scene
elsif Input.trigger? (Input::C) # If C button is pressed
action_pressed_from_list
# If scrolling through quests
elsif Input.press? (Input::DOWN) || Input.press? (Input::UP)
# Refresh Info Window
@info_window.refresh (@list_window.quest)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Category Window
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_category_window
# If category window exists and horizontal arrow triggered
if (Input.trigger? (Input::LEFT) || Input.trigger? (Input::RIGHT))
add_int = Input.trigger? (Input::LEFT) ? -1 : 1
@category_index = (@category_index + add_int) % QuestData::CATEGORIES.size
# Play Cursor SE
$game_system.se_play($data_system.cursor_se)
# Refresh Windows
@category_window.refresh (@category_index)
@list_window.change_list (QuestData::CATEGORIES[@category_index])
@info_window.refresh (@list_window.quest)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Info Window
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_info_window
@info_window.update
if Input.trigger? (Input::B) || Input.trigger? (Input::C)
$game_system.se_play($data_system.cancel_se)
@info_window_active = false
@info_window.oy = 0
@list_window.active = true
@help_window.set_text (QuestData::VOCAB_HELP_GENERAL, QuestData::HELP_ALIGNMENT)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * C Button Pressed
# I put this as its own method in case I want to write any patches which
# modifies what happens when C is pressed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def action_pressed_from_list
if @info_window.contents.height > @info_window.height - 32
$game_system.se_play($data_system.decision_se)
@info_window_active = true
@list_window.active = false
@help_window.set_text (QuestData::VOCAB_HELP_SELECTED, QuestData::HELP_ALIGNMENT)
else
$game_system.se_play($data_system.buzzer_se)
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Return Scene
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def return_scene
unless @list_window.quest.nil? # Save Position
$game_system.last_quest_id = @list_window.quest.id
$game_system.last_quest_cat = @category_index
end
# Exit Quest Scene
$scene = @from_menu ? Scene_Menu.new (QuestData::MENU_INDEX) : Scene_Map.new
end
end
#==============================================================================
# ** Scene_QuestPurchase
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class handles processing for purchasing quests
#==============================================================================
class Scene_QuestPurchase < Scene_Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (quest_array = [], shop_name = QuestData::VOCAB_PURCHASE)
@quest_list, @quest_reveals = [], []
quest_array.each { |quest_a|
quest = Game_Quest.new (quest_a[0], (quest_a[1] ? quest_a[1] : -1))
# Add if no switch condition or condition met and not already revealed
if quest_a[3]
reveals = quest_a[2]
switch = quest_a[3]
else
if quest_a[2].is_a? (Array)
reveals = quest_a[2]
switch = nil
else
reveals = []
quest.objectives.each_index { |i| reveals.push (i) }
switch = quest_a[2]
end
end
if (switch.nil? || $game_switches[switch]) && !$game_party.quests.revealed? (quest_a[0])
# Reveal all objectives if want to show them
quest.reveal_objective (*reveals)
@quest_list.push (quest)
@quest_reveals.push (reveals)
end
}
@shop_name = shop_name
@info_window_active = false
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Start Processing
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def start
create_menu_background
# Create Background picture
unless $game_system.qj_bg_picture.empty?
@bg_sprite = Sprite.new
@bg_sprite.bitmap = RPG::Cache.windowskin ($game_system.qj_bg_picture)
@bg_sprite.opacity = $game_system.qj_bg_opacity
end
wlh = 32
fs = 480 - (96 + 2*32)
@label_window = Window_QuestLabel.new (QuestData::PURCHASE_LIST_WIDTH, 32 + 32 + (fs % 24), @shop_name)
@list_window = Window_QuestList.new (fs, QuestData::PURCHASE_LIST_WIDTH, @quest_list)
@list_window.y = @label_window.height
@list_window.active = true
for i in 0...@quest_list.size
@list_window.draw_item (i, false) if $game_party.gold < @quest_list[i].cost
end
@info_window = Window_QuestInfo.new (480, QuestData::PURCHASE_LIST_WIDTH, QuestData::PURCHASE_INFO_LAYOUT)
@info_window.refresh (@list_window.quest)
# Create Gold Window
@gold_window = Window_QuestPurchaseGold.new (@list_window.y + @list_window.height)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Terminate Process
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def terminate
dispose_menu_background
if @bg_sprite # Dispose Background Sprite
@bg_sprite.bitmap.dispose
@bg_sprite.dispose
end
@label_window.dispose
@list_window.dispose
@info_window.dispose
@gold_window.dispose
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Info Window
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_info_window
@info_window.update
if Input.trigger? (Input::B)
$game_system.se_play($data_system.cancel_se)
@info_window_active = false
@info_window.oy = 0
@list_window.active = true
elsif Input.trigger? (Input::C)
purchase_quest
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * C Button Pressed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def action_pressed_from_list
if @info_window.contents.height > @info_window.height - 32
$game_system.se_play($data_system.decision_se)
@info_window_active = true
@list_window.active = false
else
purchase_quest
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Purchase Quest
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def purchase_quest
if @list_window.quest.nil? || $game_party.gold < @list_window.quest.cost
$game_system.se_play($data_system.buzzer_se)
else
(RPG::SE.new (*QuestData::PURCHASE_SE)).play # Play Purchase SE
$game_party.lose_gold (@list_window.quest.cost) unless @list_window.quest.cost < 0
quest = $game_party.quests[@list_window.quest.id] # Create Quest
$game_party.quests.reveal_quest (@list_window.quest.id) # Reveal Quest
quest.reveal_objective (*@quest_reveals[@list_window.index])
quest.concealed = false
@quest_list.delete_at (@list_window.index)
@quest_reveals.delete_at (@list_window.index)
@list_window.change_list (@quest_list)
for i in 0...@quest_list.size
@list_window.draw_item (i, false) if $game_party.gold < @quest_list[i].cost
end
@info_window.refresh (@list_window.quest)
@gold_window.refresh
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Return Scene
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def return_scene
$scene = Scene_Map.new
end
end
How's that?