=begin
================================================================================
Organized Quest System Version 1.22
Author: KK20 [1/29/2018]
--------------------------------------------------------------------------------
This script is a full-fledged quest system that uses pictures to represent the
different types of quests in the User Interface.
Includes:
~ Different page tabs to organize which quests to display (the four tabs
used are 'All', 'New' (not accepted), 'Accepted', and 'Completed'), which
can be accessed by pressing the 'Shift' key.
~ Player rank determined by number of quests completed
~ A window displaying the quest's information when selected
~ Repeatable quests
~ Some customizable features
--------------------------------------------------------------------------------
[[ Version History ]]
1.22[1/29/2018]
- Fixed an error when changing quest tabs to an empty list, causing a
"can't convert nil into Integer" error (seems to only occur in Ruby 1.9)
1.21[10/14/2015]
- Fixed regular expression used in writing the quest description
1.2 [11/24/13]
- Descriptions now use \n and \v[n] and no longer need to be spaced apart
- Added new features:
* Repeatable Quests
* Can check quest's acceptance status more precisely
* Rewards can have strings in them
1.1 [1/27/13]
- Cleaned up code
- Added new features:
* Map background
* More quest descriptions and use of game variables
- Removed storing data into a Game System variable
1.0 [8/15/12]
- Released script
********************************************************************************
* I N S T R U C T I O N S *
********************************************************************************
-----------------
-Getting Started-
-----------------
To call the quest window, use the following in a script call:
> $scene = Scene_Quest.new
To add quests that are available and can be accepted, use the script call:
> Quest.new(quest_id)
To change the quest to being accepted, use the script call:
> Quest.accept(quest_id)
To complete the quest, use the script call:
> Quest.complete(quest_id)
(Doing this will automatically give the rewards to the player--This includes
the items, EXP, and Gold. No need to event that in!
If you still want to use events to reward, this can be configured below.)
To make a quest repeatable, use the script call:
> Quest.repeat(quest_id)
(In order for a quest to be repeated, the player must complete the quest
at least once. Repeated quests are still considered completed quests,
regardless if the player is accepting it or not.)
######[ NOTE ]################################################################
A quest cannot be accepted if the quest is not currently available. A quest
cannot be completed unless the quest is currently being accepted.
Example: Quest.new(1)
Quest.complete(1)
Result: Quest 1 is still considered "new". The player has completed nothing.
##############################################################################
For conditional branch needs:
To check if the quest is repeatable, use the script call:
> Quest.repeat?(quest_id)
Returns 'true' if the quest is repeatable, 'false' otherwise.
To check if the quest is completed, use the script call:
> Quest.complete?(quest_id)
Returns 'true' if the quest is completed or repeatable, 'false' otherwise.
To check if the quest is currently being accepted, use the script call:
> Quest.accept?(quest_id)
Returns 'true' if the quest is accepted, completed, or repeatable,
'false' otherwise.
To check if the quest can be accepted, use the script call:
> Quest.new?(quest_id)
Returns 'true' if the quest is new, accepted, completed, or repeatable,
'false' otherwise.
######[ NOTE ]################################################################
In the last three commands (thus, excluding Quest.repeat?), you can put a
second parameter to check if the quest is CURRENTLY new, accepted, or
completed. All you have to put is true after your quest ID.
Example: Quest.new?(1, true)
Result: Returns true ONLY if the quest is considered new. If it has been
accepted or completed, it will return false.
##############################################################################
To check how many quests have been completed, use the script call:
> Quest.done
This will return an integer. If you want to, for example, give a reward for
completing 7 quests, use a 'Conditional Branch', select 'Script' and
type in 'Quest.done >= 7' (without the quotes).
----------
-Controls-
----------
Arrow keys to move the cursor around
'C'/'Enter' to view the quest's information
'X'/'Esc' to close the Scene_Quest
'Shift' to change tabs (All -> New -> Accepted -> Completed -> All)
When the quest's information window is being displayed:
You can still use the Arrow keys to view different quests
'C'/'Enter' and 'Shift' have no use.
'X'/'Esc' to remove the quest's information window
----------
-Graphics-
----------
This script uses images stored in 'Graphics/Pictures' to represent the quests.
The script was written in support for 48 x 48 graphics. Your images must be
of this size (no less, no bigger). To configure what graphics you wish to use,
look below for the configuration.
---------------
-Configuration-
---------------
Located below. All the instructions are there.
================================================================================
Credits:
KK20 -> Making this script
game_guy -> Used his 'Quest Log System' as a basis for this script
Blizzard -> Method to turn a long string into a paragraph
================================================================================
=end
module QuestData
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@ S T A R T O F C O N F I G U R A T I O N @
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#=============================================================================
# NPCPicture - Set to 'true' if you want the NPC graphic to be displayed in
# the quest's information window. Set to 'false' if you don't
# want to.
#
# HideReward - Hides the rewards in the quest description until the player has
# completed that quest. Set the quest IDs in the array to use this
# feature. Delete the array and put 'true' to apply this to all
# quests. Create an empty array if you do not wish to use this
# feature. An empty array looks like this--> []
#
# RewardOnComplete - Set to 'true' if you want the player to be rewarded at the
# instance of 'Quest.complete(quest_id)'. 'false' otherwise.
#
# ShowMapBackGround - Sets the opacity of the windows to allow viewing of the
# map. Set to 'true' if you want this option. 'false' otherwise.
#
# ExitScene - Set to the scene you wish to view upon exiting quest scene.
#
# PageTurnSound - Sound effect that plays when player shifts the quest page.
#=============================================================================
NPCPicture = true
HideReward = [1, 5]
RewardOnComplete = true
ShowMapBackGround = true
ExitScene = Scene_Menu.new(0)
PageTurnSound = RPG::AudioFile.new("005-System05", 80)
#=============================================================================
# EXPicon - The graphic used when the quest's information window is brought up.
# It represents EXP gained from the quest. Name it the same as it is
# found in 'Graphics/Icons'.
#
# GoldIcon - Same as above. Represents the gold gained from the quest.
#
# ** If you do not want graphics, simply use an empty string ---> ""
# If you do opt to not use icons, the text will fill in the words for you.
# These are ICONS, so the graphics must be 24 x 24.
#=============================================================================
EXPicon = "exp"
GoldIcon = "gold"
#=============================================================================
# NewQuestPic - The picture you want to represent a quest that hasn't been
# accepted. Name it the same as it is in 'Graphics/Pictures'.
#
# AcceptedQuestPic - Same as above. Represents a quest that has been accepted.
#
# CompletedQuestPic - Same as above. Represents a quest that is complete.
#
# RepeatQuestPic - Same as above. Represents a repeatable quest.
#
# Remember: Graphics must be of size 48 x 48.
#=============================================================================
NewQuestPic = "quest_new"
AcceptedQuestPic = "quest_accepted"
CompletedQuestPic = "quest_complete"
RepeatQuestPic = "quest_repeat"
def self.name(id)
case id
#===========================================================================
# Quest Name - The name of the quest.
# Configure:
# when x then return "name"
# x = Quest ID
# name = Quest name. Use "quotes".
#===========================================================================
when 1 then return "Red Chest of Wonders"
when 2 then return "Spectral Hunter"
when 3 then return "Forever New"
when 4 then return "Dead Weight"
when 5 then return "Stoney Blight"
end
return ""
end
def self.new_description(id)
case id
#===========================================================================
# New Quest Description - Paragraph of the quest's description. This is for
# when the quest is new for the player to accept. If the description
# is really lengthy, the program will adjust the text into paragraph format.
#
# You may use '\n' to create a new line (e.g. "Hello World!\nYou Rock!").
# You may also use '\v[id]' to show a variable in the description. Thus,
# doing something like "Found \v[3] out of \v[4]" will replace the
# instances with the game variables 3 and 4.
#
# Any quests that are not configured will result in using the message
# located between the [] brackets. This text will be centered in the window.
# Do note you cannot use \n or \v to format this text.
#
# Configure:
# when x then return "description"
# x = Quest ID
# description = Quest's description. Use "quotes". Can be quite lengthy.
#===========================================================================
when 1 then return "I just magically spawned on this weird island and this guy is waving at me. There's some red chest sitting next to him. I guess I should say hello..."
when 2 then return "Justin has been shifting his eyes frantically. There must be something troubling him."
when 4 then return "This strong-looking man is grinning a bit too much. Actually...he looks weird. I hope he doesn't--\n\nCrap, he's looking at me."
when 5 then return "*huff* Why...was I so foolish enough...to carry that many rocks?\nWHAT WAS THE POINT?"
end
return ["? ? ?"]
end
def self.accepted_description(id)
case id
#===========================================================================
# Accepted Quest Description - Paragraph of the quest's description. If the
# description is really lengthy, the program will adjust the text into
# paragraph format.
#
# You may use '\n' to create a new line (e.g. "Hello World!\nYou Rock!").
# You may also use '\v[id]' to show a variable in the description. Thus,
# doing something like "Found \v[3] out of \v[4]" will replace the
# instances with the game variables 3 and 4.
#
# Configure:
# when x then return "description"
# x = Quest ID
# description = Quest's description. Use "quotes". Can be quite lengthy.
#===========================================================================
when 1 then return "A guy named Justin wanted us to find a key to open up the red chest he recently found. He isn't sure where this key could be, but I have a strange hunch that it can't be too hard to find. \n \n Let's try checking an obvious place."
when 2 then return "Justin is quite scared of all the ghosts around the area. To make him feel better, we should probably kill a few for him. I think 5 should be good enough. \n \n Killed: \v[1]/5"
when 3 then return "Um, there's no way you can be viewing this description right now. You modded the demo!"
when 4 then return "Strong guy here wants us to find a rock for him.\nTo smash.\nI...\n...why?!"
when 5 then return "\v[3]"
end
return ""
end
def self.completed_description(id)
case id
#===========================================================================
# New Quest Description - Paragraph of the quest's description. This is for
# when the quest has been completed by the player. If the description
# is really lengthy, the program will adjust the text into paragraph format.
#
# You may use '\n' to create a new line (e.g. "Hello World!\nYou Rock!").
# You may also use '\v[id]' to show a variable in the description. Thus,
# doing something like "Found \v[3] out of \v[4]" will replace the
# instances with the game variables 3 and 4.
#
# Any quests that are not configured will result in using the accepted
# quest description (the ones you wrote above).
#
# Configure:
# when x then return "description"
# x = Quest ID
# description = Quest's description. Use "quotes". Can be quite lengthy.
#===========================================================================
when 2 then return "I killed 5 ghosts for Justin. He looks much happier now that there's nothing to scare him anymore. \n \n But now he's just standing there, being a 'useless' NPC. \n What's an NPC anyways?"
when 4 then return "Okay, I was actually stupid enough to bring him back a rock to smash. I don't see the point in all of this.\n\nRocks Smashed: \v[2]"
when 5 then return "Well, that settles that. Glad I got something out of all of this.\n\nBut that's the last time I ever help a pompous braggart."
end
return nil
end
def self.location(id)
case id
#===========================================================================
# Quest Location - Place where the player received the quest.
# Configure:
# when x then return "location"
# x = Quest ID
# location = Map's name. Use "quotes".
#===========================================================================
when 1..5 then return "Mystery Isle"
when 6 then return "Traudsbogen"
end
return "?????"
end
def self.NPC(id)
case id
#===========================================================================
# Quest NPC - The NPC that the player got the quest from. This can be
# displayed in both "string" and/or "picture" format. If using the picture
# format (NPCPicture = true), you must name the NPC the same as the
# image stored in the 'Graphics/Characters' folder. Otherwise, an error
# will occur while running the game.
# Configure:
# when x then return "NPC"
# x = Quest ID
# NPC = Name of the NPC as well as the name of the NPC graphic
#===========================================================================
when 1..2 then return "Justin" # Even though these character graphics are
when 3 then return "Some Woman" # part of the RTP, you still need to copy
when 4..5 then return "Stonemason"# and rename the graphics and put them in
end # your Graphics/Characters folder
return nil
end
def self.exp(id)
case id
#===========================================================================
# Quest Experience - The amount of EXP given for completing the quest.
# Configure:
# when x then return EXP
# x = Quest ID
# EXP = Amount of experience (Player EXP)
#===========================================================================
when 1 then return 5
when 2 then return 50
when 3 then return 69
end
return 0
end
def self.gold(id)
case id
#===========================================================================
# Quest Gold - The amount of gold given (or lost) for completing the quest.
# Configure:
# when x then return Gold
# x = Quest ID
# Gold = Amount of gold given/taken. Use a '-' for lost gold (e.g. -500)
#===========================================================================
when 1 then return 20
when 2 then return 300
when 3 then return 9001
end
return 0
end
def self.reward(id)
case id
#===========================================================================
# Quest Reward - The items given for completing the quest. The amount of
# different items that can be earned should not be more than 5.
#
# You can also put in string values to represent a unique kind of reward.
# If RewardOnComplete is true, the game will ignore rewarding string-
# based values.
#
# Configure:
# when x then return [[item_type, item_id, amount], ...] (max size of 5)
# x = Quest ID
# item_type = Type of item. Refer below:
# 1 = Normal Items (potions, key items, medicine, etc.)
# 2 = Weapon
# 3 = Armor
# item_id = Item's ID located in the database
# amount = Number of items given for completion
#
# For inputing string values, you can copy one of these examples:
# when x then return ["String"]
# when x then return [[1,2,3], "Your Message"]
# when x then return ["You got", [1,1,1], "Nice potion!"]
#===========================================================================
when 1 then return [[1,2,5], "New Quest: Spectral Hunter"] #5 High Potions
when 2 then return [[2,3,1]] #1 Steel Sword
when 3 then return ["This is", "how you", "skip lines", "", "See?"]
when 5 then return [[3,25,1]] #1 Ring of Strength
end
return nil
end
def self.rank(value)
return ''
case value
#===========================================================================
# Quest Rank - The player's rank in terms of completed quests.
# Of course, if you do not wish to use this, simply delete the 'when's
# and the 'end' directly after, leaving only the 'return' left. Then,
# put an empty string after the return like this --> return ""
# Configure:
# when x then return "rank"
# x = The number of completed quests. Use (x..y) for all values in between
# x and y (for example, (3..6) applies for IDs 3, 4, 5, and 6
# rank = The rank of the party. Use "quotes".
#===========================================================================
when 1 then return "Neophyte"
when 2..5 then return "Amateur"
end
return "Beginner"
end # <-- Don't delete this 'end' !
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@ E N D O F C O N F I G U R A T I O N @
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
end
#===============================================================================
module Quest
#Adds the quest under "New", meaning the player has yet to accept it
def self.new(id)
$game_party.add_newquest(id)
end
#Adds the quest under "Accepted", meaning the player is doing the quest
def self.accept(id)
$game_party.accept_quest(id)
end
#Adds the quest under "Completed", meaning the quest is finished. Gives reward.
def self.complete(id)
$game_party.complete(id)
end
#Adds the quest under "New" and "Completed", meaning the quest can be redone
def self.repeat(id)
$game_party.repeat(id)
end
#Checks if the quest is repeatable
def self.repeat?(id)
return $game_party.repeating?(id)
end
#Checks if the quest is completed
def self.complete?(id, only=false)
return $game_party.completed?(id, only)
end
#Checks if the quest is accepted
def self.accept?(id, only=false)
return $game_party.has_quest?(id, only)
end
#Checks if the quest is unaccepted
def self.new?(id, only=false)
return $game_party.has_available?(id, only)
end
#Returns quests completed
def self.done
return ($game_party.quests_completed.dup | $game_party.quests_repeating).size
end
end
#===============================================================================
# Game_Party Class
# : Adds the quest data
#===============================================================================
class Game_Party
attr_accessor :quests_new
attr_accessor :quests_accepted
attr_accessor :quests_completed
attr_accessor :quests_repeating
alias kk20_initialize_again initialize
def initialize
kk20_initialize_again
@quests_new = []
@quests_accepted = []
@quests_completed = []
@quests_repeating = []
end
def add_newquest(id)
unless has_available?(id)
@quests_new.push(id)
end
end
def accept_quest(id)
if !@quests_accepted.include?(id) and @quests_new.include?(id)
@quests_new.delete(id)
@quests_accepted.push(id)
end
end
def complete(id)
if !completed?(id, true) and @quests_accepted.include?(id)
@quests_accepted.delete(id)
@quests_repeating.delete(id)
@quests_completed.push(id)
if QuestData::RewardOnComplete
$game_party.gain_gold(QuestData.gold(id))
$game_party.actors.each{|actor|
unless actor.cant_get_exp?
actor.exp += QuestData.exp(id)
end
}
rewards = QuestData.reward(id)
return if rewards.nil?
#~~begin loop~~
rewards.each{|reward|
next if reward.is_a?(String)
case reward[0]
when 1 then $game_party.gain_item(reward[1], reward[2])
when 2 then $game_party.gain_weapon(reward[1], reward[2])
when 3 then $game_party.gain_armor(reward[1], reward[2])
end
}
#~~end loop~~
end
end
end
def repeat(id)
if completed?(id, true)
@quests_completed.delete(id)
@quests_repeating.push(id)
@quests_new.push(id)
end
end
def repeating?(id)
return @quests_repeating.include?(id)
end
def completed?(id, only=false)
if only
return @quests_completed.include?(id)
else
return (@quests_completed.include?(id) or @quests_repeating.include?(id))
end
end
def has_quest?(id, only=false)
if only
return @quests_accepted.include?(id)
else
return (@quests_accepted.include?(id) or @quests_completed.include?(id) or
@quests_repeating.include?(id))
end
end
def has_available?(id, only=false)
if only
return @quests_new.include?(id)
else
return (@quests_new.include?(id) or @quests_accepted.include?(id) or
@quests_completed.include?(id) or @quests_repeating.include?(id))
end
end
end
#===============================================================================
# Window_Base Class
# : Modified method provided by Blizzard
#===============================================================================
class Window_Base < Window
def draw_even_text(x, y, width, height, text, align = 0)
# Replace all instances of \v[n] to the game variable's value
text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
text.gsub!(/[\V\v]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
# Break up the text into lines
if text["\n"] != nil
lines = text.split("\n")
else
lines = text.split("\\n")
end
result = []
# For each line generated from \n
lines.each{|text_line|
# Divide text into each individual word
words = text_line.split(' ')
current_text = words.shift
# If there were less than two words in that line, just push the text
if words.empty?
result.push(current_text == nil ? "" : current_text)
next
end
# Evaluate each word and determine when text overflows to a new line
words.each_index {|i|
if self.contents.text_size("#{current_text} #{words[i]}").width > width
result.push(current_text)
current_text = words[i]
else
current_text = "#{current_text} #{words[i]}"
end
result.push(current_text) if i >= words.size - 1
}
}
# Draw results to the window
result.each_index {|i|
self.contents.draw_text(x, y + i*height, width, height, result[i], align)}
end
end
#*******************************************************************************
#===============================================================================
# Window for displaying the party's rank and number of new/available/completed quests
#===============================================================================
class Window_QuestRank < Window_Base
def initialize
super (0, 0, 640, 64)
self.contents = Bitmap.new(width-32, height-32)
refresh
end
def refresh
self.contents.clear
quest_rank = QuestData.rank($game_party.quests_completed.size)
self.contents.draw_text(0, 0, 640, 32, "#{quest_rank}")
new = sprintf("%5s", $game_party.quests_new.size.to_s)
accepted = sprintf("%5s", $game_party.quests_accepted.size.to_s)
completed = sprintf("%5s", ($game_party.quests_completed.dup | $game_party.quests_repeating).size.to_s)
self.contents.draw_text(0, 0, 608, 32, "New:#{new} " +
"Accepted:#{accepted} Completed:#{completed}", 2)
end
end
#===============================================================================
# Window for displaying the quest's ID and title
#===============================================================================
class Window_QuestTitle < Window_Base
#Type determines what window to view (0 = All, 1 = New, 2 = Accepted, 3 = Complete)
def initialize(type=0)
super (0, 64, 640, 64)
self.contents = Bitmap.new(width-32,height-32)
@quest_num = 0
@quest_title = ""
@type = type
refresh
end
#Updates the quest /value/'s ID and name
alias kk20_update_quest update
def update(value)
kk20_update_quest
return if @quest_num == value
@quest_num = value
@quest_title = QuestData.name(value)
refresh
end
#Method is called when user shifts the quest tab
def next_page
@type = (@type + 1) % 4
refresh
end
def refresh
self.contents.clear
quest_tab = ""
case @type
when 0 then quest_tab = "ALL"
when 1 then quest_tab = "NEW"
when 2 then quest_tab = "ACCEPTED"
when 3 then quest_tab = "COMPLETED"
end
if @quest_num != 0 and @quest_num != nil
quest_number = sprintf("%03d", @quest_num)
self.contents.draw_text(0, 0, 640, 32, "No. #{quest_number}")
else
self.contents.draw_text(0, 0, 640, 32, "There are no quests here.")
end
self.contents.draw_text(80, 0, 640, 32, "#{@quest_title}")
self.contents.draw_text(0, 0, 600, 32, "<#{quest_tab}>", 2)
end
end
#===============================================================================
# Window for displaying all the quests as pictures
#===============================================================================
class Window_QuestList < Window_Selectable
#Type determines what window to view (0 = All, 1 = New, 2 = Accepted, 3 = Complete)
def initialize(type=0)
super (0, 128, 640, 352)
@column_max = 5
@type = type
refresh
self.index = 0
end
#For information window
def quest
return @data[self.index]
end
#When the player shifts to next page. Also places cursor to new index if nil.
def next_page
@type = (@type + 1) % 4
refresh
if (@data[self.index].nil?)
self.index = [@data.size-1, 0].max
end
end
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
if [0,1].include?(@type)
for i in 0...$game_party.quests_new.size
@data.push($game_party.quests_new[i])
end
end
if [0,2].include?(@type)
for i in 0...$game_party.quests_accepted.size
@data.push($game_party.quests_accepted[i])
end
end
if [0,3].include?(@type)
total = $game_party.quests_completed.dup | $game_party.quests_repeating
for i in 0...total.size
@data.push(total[i]) unless @data.include?(total[i])
end
end
@data.sort! if @data.size > 1
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 64, row_max * 64)
for i in 0...@item_max
draw_item(i)
end
end
end
def draw_item(index)
quest_number = @data[index]
if $game_party.quests_repeating.include?(quest_number)
bitmap = RPG::Cache.picture(QuestData::RepeatQuestPic)
elsif $game_party.quests_new.include?(quest_number)
bitmap = RPG::Cache.picture(QuestData::NewQuestPic)
elsif $game_party.quests_accepted.include?(quest_number)
bitmap = RPG::Cache.picture(QuestData::AcceptedQuestPic)
elsif $game_party.quests_completed.include?(quest_number)
bitmap = RPG::Cache.picture(QuestData::CompletedQuestPic)
end
x = 8 + index % @column_max * (self.width / @column_max)
y = 8 + index / @column_max * 64
self.contents.blt(x, y, bitmap, Rect.new(0, 0, 48, 48), 255)
end
#####################################################
# Modified methods to allow 64x64 selection windows #
#####################################################
def page_row_max
return (self.height) / 64
end
def top_row
return self.oy / 64
end
def top_row=(row)
if row < 0
row = 0
end
if row > row_max - 1
row = row_max - 1
end
self.oy = row * 64
end
def update_cursor_rect
if @index < 0
self.cursor_rect.empty
return
end
row = @index / @column_max
if row < self.top_row
self.top_row = row
end
if row > self.top_row + (self.page_row_max - 1)
self.top_row = row - (self.page_row_max - 1)
end
# Calculate cursor coordinates
x = @index % @column_max * (640 / @column_max)
y = @index / @column_max * 64 - self.oy
# Update cursor rectangle
self.cursor_rect.set(x, y, 64, 64)
end
end
#===============================================================================
# Window to display quest's information
#===============================================================================
class Window_QuestInfo < Window_Base
def initialize(quest_id)
super (0, 0, 640, 480)
self.z = 1000
self.contents = Bitmap.new(width-32,height-32)
@quest = quest_id
refresh
end
def update_quest(quest_id)
if @quest != quest_id
@quest = quest_id
refresh
end
end
def refresh
# Titles of important text------------------------------
self.contents.clear
quest_number = sprintf("%03d", @quest)
self.contents.font.color = system_color
self.contents.draw_text(0, 0, 640, 32, "No. #{quest_number}")
self.contents.draw_text(80, 0, 640, 32, QuestData.name(@quest))
# If quest is completed OR quest is repeatable but not currently accepted
if Quest.repeat?(@quest) && Quest.accept?(@quest, true)
self.contents.font.color = Color.new(0, 230, 255)
self.contents.draw_text(0, 0, 600, 32, "-REPEATING-", 2)
self.contents.font.color = system_color
elsif Quest.complete?(@quest, true) || (Quest.repeat?(@quest) && !Quest.accept?(@quest, true))
self.contents.font.color = Color.new(233, 188, 10)
self.contents.draw_text(0, 0, 600, 32, "-COMPLETED-", 2)
self.contents.font.color = system_color
end
self.contents.draw_text(0, 200, 280, 32, "Requester:")
self.contents.draw_text(0, 360, 280, 32, "Location:")
self.contents.draw_text(320, 200, 280, 32, "Reward(s):")
# Description------------------------------
self.contents.font.color = normal_color
self.contents.fill_rect(0, 40, 640, 5, Color.new(24,184,231,128))
self.contents.font.size = 18
if Quest.complete?(@quest, true) || (Quest.repeat?(@quest) && !Quest.accept?(@quest, true))
unless QuestData.completed_description(@quest).nil?
draw_even_text(0, 58, 640-32, 18, QuestData.completed_description(@quest))
else
draw_even_text(0, 58, 640-32, 18, QuestData.accepted_description(@quest))
end
elsif Quest.accept?(@quest)
draw_even_text(0, 58, 640-32, 18, QuestData.accepted_description(@quest))
else
unless QuestData.new_description(@quest).is_a?(Array)
draw_even_text(0, 58, 640-32, 18, QuestData.new_description(@quest))
else
self.contents.draw_text(0, 103, 640-32, 18, QuestData.new_description(@quest)[0], 1)
end
end
self.contents.fill_rect(0, 180, 640, 5, Color.new(24,184,231,128))
self.contents.fill_rect(300, 180, 5, 320, Color.new(24,184,231,128))
# NPC and Location------------------------------
self.contents.font.size = Font.default_size
if QuestData::NPCPicture and QuestData.NPC(@quest) != nil
bitmap = RPG::Cache.character(QuestData.NPC(@quest), 0)
h = bitmap.height/4
w = bitmap.width/4
self.contents.blt(0, 240, bitmap, Rect.new(0, 0, w, h))
self.contents.draw_text(w+20, h+240, 280, 32, QuestData.NPC(@quest))
else
if QuestData.NPC(@quest) != nil
self.contents.draw_text(20, 240, 280, 32, QuestData.NPC(@quest))
end
end
self.contents.draw_text(20, 400, 280, 32, QuestData.location(@quest))
# Rewards------------------------------
if !((QuestData::HideReward == true or QuestData::HideReward.include?(@quest)) and !Quest.complete?(@quest))
y = 225
exp_string = ""
if QuestData.exp(@quest) != 0
if QuestData::EXPicon != nil and QuestData::EXPicon != ""
bitmap = RPG::Cache.icon(QuestData::EXPicon)
self.contents.blt(340, y, bitmap, Rect.new(0, 0, 32, 32))
else
exp_string = "EXP"
end
self.contents.draw_text(370, y, 280, 32, QuestData.exp(@quest).to_s + " " + exp_string)
y += 24
end
gold_string = ""
if QuestData.gold(@quest) != 0
if QuestData::GoldIcon != nil and QuestData::GoldIcon != ""
bitmap = RPG::Cache.icon(QuestData::GoldIcon)
self.contents.blt(340, y, bitmap, Rect.new(0, 0, 32, 32))
else
gold_string = $data_system.words.gold
end
self.contents.draw_text(370, y, 280, 32, QuestData.gold(@quest).to_s + " " + gold_string)
y += 32
end
if QuestData.reward(@quest) != nil
#~~being loop~~
QuestData.reward(@quest).each_index{|i|
item = QuestData.reward(@quest)[i]
# If string value
if item.is_a?(String)
self.contents.draw_text(370, y, 280, 32, item)
y += 32
next
end
# An actual item
case item[0]
when 1
bitmap = RPG::Cache.icon($data_items[item[1]].icon_name)
self.contents.draw_text(370, y, 280, 32, $data_items[item[1]].name + " x " + item[2].to_s)
when 2
bitmap = RPG::Cache.icon($data_weapons[item[1]].icon_name)
self.contents.draw_text(370, y, 280, 32, $data_weapons[item[1]].name + " x " + item[2].to_s)
when 3
bitmap = RPG::Cache.icon($data_armors[item[1]].icon_name)
self.contents.draw_text(370, y, 280, 32, $data_armors[item[1]].name + " x " + item[2].to_s)
end
self.contents.blt(340, y, bitmap, Rect.new(0, 0, 32, 32))
y += 32
}
#~~end loop~~
end
if QuestData.exp(@quest) == 0 and QuestData.gold(@quest) == 0 and QuestData.reward(@quest) == nil
self.contents.draw_text(370, 225, 280, 32, "None")
end
else #If Quest Reward is hidden
self.contents.draw_text(370, 225, 280, 32, "Unknown")
end
end
end
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# The actual quest scene
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class Scene_Quest
def main
#Creates the windows
@quests_rank = Window_QuestRank.new
@quests_title = Window_QuestTitle.new(0)
@quests_list = Window_QuestList.new(0)
@quest_info = Window_QuestInfo.new(@quests_list.quest)
@quest_info.visible = false
@quests_title.update(@quests_list.quest)
if QuestData::ShowMapBackGround
@map = Spriteset_Map.new
[@quests_rank,@quests_title,@quests_list,@quest_info].each{|win| win.back_opacity = 128}
end
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@map.dispose unless @map.nil?
@quests_rank.dispose
@quests_title.dispose
@quests_list.dispose
end
#------------------------------------------------------------
def update
@map.update unless @map.nil?
@quests_title.update(@quests_list.quest)
@quests_list.update
@quest_info.update_quest(@quests_list.quest) unless !@quest_info.visible
update_controls
end
#------------------------------------------------------------
def update_controls
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
# If quest information is not displayed, exit scene
if !@quest_info.visible
$scene = QuestData::ExitScene
else #If quest info is displayed, return to quest list
@quest_info.visible = false
[@quests_title,@quests_list,@quests_rank].each{|win| win.visible = true}
end
elsif Input.trigger?(Input::C)
#Works only if quest info isn't displayed
if !@quest_info.visible and !@quests_list.quest.nil?
$game_system.se_play($data_system.decision_se)
@quest_info.update_quest(@quests_list.quest)
@quest_info.visible = true
[@quests_title,@quests_list,@quests_rank].each{|win| win.visible = false}
end
elsif Input.trigger?(Input::SHIFT) and !@quest_info.visible
$game_system.se_play(QuestData::PageTurnSound)
@quests_title.next_page
@quests_list.next_page
end
end
end