#=============================================================#
# QUEST SYSTEM BY JAKO DRAKO GIVE CREDIT #
#-------------------------------------------------------------------------------------------------------------------------#
# Creates a system to allow the player gain quests. All quests are stored in the $game_questbook variable. #
# Each quest has a name, location, presenter, reward, task, and a set of old tasks. Rewards can be either #
# money, items, or experience. #
#----------------------------------------------------------------------------------------------------------------#
# Assign quest code: $game_questbook.assign_quest(index) #
# Update quest code: $game_questbook.update_quest(index, new location, new task) #
# Finish quest code: $game_questbook.complete_quest(index) #
#===============================================================================
#
# BEGIN CODE #
#--------------------------------------------------------------
# CLASS: Game_Quest
# Summary: A quest that can be recorded in a Game_QuestBook object
#--------------------------------------------------------------
class Game_Quest
attr_accessor :available
attr_accessor :shift_count
# name = quest name
# location = where the hero must go to complete the quest
# presenter = name of person who gives the quest
# reward_type = string, "Gold", "Item", "Exp", or "none"
# reward_var = amount of gold, item id, or amount of exp
# if reward_type = "none", pass 0 for reward_var
# description = what the hero must do to accomplish the task
def initialize(name, location, presenter, reward_type, reward_var, description)
@name = name
@location = location
@presenter = presenter
if reward_type.downcase == "none"
@reward = nil
else
@reward = Game_Reward.new(reward_type, reward_var)
end
@description = description
@previous_descriptions = []
@available = false
@complete = false
@temp_status = ""
@status = "Incomplete"
@shift_count = 0
end
# gives the hero the reward if it exists and updates the variables
def finish_quest
if @available and not @complete
@complete = true
unless @reward == nil
@reward.receive
end
@status = "Complete!"
end
end
# change the quest location or description while
# hero is doing it
def update_quest(new_location, new_description)
@location = new_location
if @description != new_description
@previous_descriptions.unshift(@description)
@shift_count += 1
end
@description = new_description
@temp_status = @status
@status = "Updated"
end
# Returns the name of the quest or " " if unavailable
def name
if @available
return @name
else
return " "
end
end
# Returns the location of the quest or "" if unavailable
def location
if @available
return @location
else
return ""
end
end
# Returns the presenter of the quest or "" if unavailable
def presenter
if @available
return @presenter
else
return ""
end
end
# Returns the Game_Reward object of the quest if the quest is available
def reward
if @available
return @reward
end
end
# Returns the current task of the quest or "" if unavailable
def description
if @available
return @description
else
return ""
end
end
# Returns a previous task of the quest if it has been updated
def old_description(index)
if @available
if @previous_descriptions[index] != nil
return @previous_descriptions[index]
else
return ""
end
else
return ""
end
end
# Returns "Incomplete", "Complete!", or "Updated"
def status
if @available
return @status
else
return ""
end
end
# Resets the status of the quest after it has been updated and viewed once
def status_viewed
if @status == "Updated"
@status = @temp_status
end
end
end
#--------------------------------------------------------------
# CLASS: Game_Reward
# Summary: A class that is to be used by the Game_Quest class
# to give the hero a reward after completing a quest
#--------------------------------------------------------------
class Game_Reward
attr_accessor :reward_type
# Initialize(tpye, initializer)
# type = string, "Gold", "Item", or "Exp"
# initializer = integer, amount of gold, item id, or amount of exp
def initialize(type, initializer)
@type = type
@reward_var = initializer
end
# Gives the party the reward
def receive
reward_window = Window_Reward.new(self)
case @type.downcase
when "gold"
$game_party.gain_gold(@reward_var)
when "item"
$game_party.gain_item(@reward_var, 1)
when "exp"
for actor in $game_party.actors
if actor.cant_get_exp == false
last_level = actor.level
actor.exp += @reward_var
if actor.level > last_level
levelup_window = Window_LevelUp.new(actor)
end
end
end
end
end
# Returns a string of the reward
# if gold: "<x> <currency>"
# if item: "<item name>"
# if exp: "<x> Exp"
def text
case @type.downcase
when "gold"
reward_text = @reward_var.to_s + " " + $data_system.words.gold
when "item"
reward_text = $data_items[@reward_var].name
when "exp"
reward_text = @reward_var.to_s + " Exp"
else
reward_text = ""
end
return reward_text
end
def icon
case @type.downcase
when "gold"
# Set icon for gold rewards
reward_icon = RPG::Cache.icon("032-Item01")
when "item"
# Set icon for item rewards
reward_icon = RPG::Cache.icon("034-Item03")
when "exp"
# Set icon for exp rewards
reward_icon = RPG::Cache.icon("050-Skill07")
end
return reward_icon
end
end
#--------------------------------------------------------------
# CLASS: Game_QuestBook
# Summary: Works like an array of Game_Quest objects with
# a few Game_Quest specific methods.
#--------------------------------------------------------------
class Game_QuestBook
def initialize()
@quests = []
end
def [](index)
return @quests[index]
end
# Number of quests
def quest_count
return @quests.length
end
# Creates a new Game_Quest object
def add_quest(quest)
@quests.push(quest)
end
# Makes the indexed quest available for the player to see
def assign_quest(index)
@quests[index - 1].available = true
window = Window_QuestUpdate.new(true)
end
# Creates a new location and task for the indexed quest
def update_quest(index, new_location, new_description)
@quests[index - 1].update_quest(new_location, new_description)
window = Window_QuestUpdate.new(false)
end
def complete_quest(index)
@quests[index - 1].finish_quest
end
end
#--------------------------------------------------------------
# CLASS: Window_QuestList
# Summary: A window that displays all quests in the game and
# the information specific to the available ones.
#--------------------------------------------------------------
class Window_QuestList < Window_Selectable
attr_accessor :quest_index
def initialize(quest_book)
@quest_book = quest_book
super(0, 64, 640, 416)
@item_max = @quest_book.quest_count
@quest_index = 0
@cursor_index = 0
# top_quest and bottom_quest are used to display the list of
# quests only 11 at a time and to scroll the list.
@top_quest = 0
@bottom_quest = [@top_quest + 10, @item_max - 1].min
self.contents = Bitmap.new(self.width - 32, @item_max * 32 + 32)
self.contents.font.name = "Tahoma"
self.contents.font.size = 12
refresh
end
def refresh
self.contents.clear
# Create the list labels
self.contents.font.color = system_color
self.contents.draw_text(0, 0, 58, 32, "Name")
self.contents.draw_text(170, 0, 81, 32, "Location")
self.contents.draw_text(340, 0, 92, 32, "Presenter")
self.contents.draw_text(503, 0, 100, 32, "Status")
j = 0
# Draw the items in the list between the quests indexed by
# top_quest and bottom_quest
for i in @top_quest..@bottom_quest
draw_quest(i, j)
j += 1
end
end
def update
if self.active and @item_max > 0 and @quest_index >= 0
# Input processing for DOWN ARROW
if Input.trigger? (Input::DOWN) and @quest_index < @item_max - 1
$game_system.se_play($data_system.cursor_se)
@quest_index += 1
@cursor_index += 1
if @cursor_index > 10
@cursor_index = 10
@top_quest += 1
@bottom_quest += 1
refresh
end
end
# Input processing for UP ARROW
if Input.trigger? (Input::UP) and @quest_index > 0
$game_system.se_play($data_system.cursor_se)
@quest_index -= 1
@cursor_index -= 1
if @cursor_index < 0
@cursor_index = 0
@top_quest -= 1
@bottom_quest -=1
refresh
end
end
end
# Update the help window
if self.active and @help_window != nil
update_help
end
# Update the cursor
update_cursor_rect
end
# Draw the cursor
def update_cursor_rect
if @cursor_index < 0
self.cursor_rect.empty
return
end
row = @cursor_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
cursor_width = self.width - 32
x = 0
y = @cursor_index * 32 + 32
self.cursor_rect.set(x, y, cursor_width, 32)
end
# Draw the status of the a specific quest
def draw_quest(quest_index, y_index)
quest = @quest_book[quest_index]
self.contents.font.color = normal_color
if quest.available == false or quest.status == "Complete!"
self.contents.font.color = disabled_color
end
x = 0
y = y_index * 32 + 32
self.contents.draw_text(x, y, contents.text_size(quest.name).width, 32, quest.name)
x += 170
self.contents.draw_text(x, y, contents.text_size(quest.location).width, 32, quest.location)
x += 170
self.contents.draw_text(x, y, contents.text_size(quest.presenter).width, 32, quest.presenter)
x += 163
self.contents.draw_text(x, y, contents.text_size(quest.status).width, 32, quest.status)
quest.status_viewed
end
# Update the help window. Displays the current task of the quest highlighted
def update_help
@help_window.set_text(@quest_book[@quest_index].description)
end
end
#--------------------------------------------------------------
# CLASS: Window_QuestInfo
# Summary: Displays information on a specific quest.
#--------------------------------------------------------------
class Window_QuestInfo < Window_Base
def initialize(quest)
super(0, 0, 640, 480)
@quest = quest
self.contents = Bitmap.new(self.width - 32, self.height - 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
generate_text
update
end
def generate_text
self.contents.font.color = system_color
self.contents.draw_text(0, 32, 130, 32, "Presented by:")
location_width = [contents.text_size(@quest.location).width, 82].max
self.contents.draw_text(608 - location_width, 32, 82, 32, "Location")
self.contents.draw_text(0, 96, 78, 32, "Reward:")
self.contents.draw_text(0, 128, 51, 32, "Task:")
self.contents.draw_text(0, 192, 36, 32, "Old:")
self.contents.font.color = normal_color
text_width = contents.text_size(@quest.name).width
self.contents.draw_text(0, 0, text_width, 32, @quest.name)
text_width = contents.text_size(@quest.status).width
self.contents.draw_text(608 - text_width, 0, text_width, 32, @quest.status)
@quest.status_viewed
text_width = contents.text_size(@quest.presenter).width
self.contents.draw_text(0, 64, text_width, 32, @quest.presenter)
self.contents.draw_text(608 - location_width, 64, location_width, 32, @quest.location)
if @quest.reward == nil
self.contents.draw_text(83, 96, 96, 32, "No reward")
else
text_width = contents.text_size(@quest.reward.text).width
self.contents.blt(83, 100, @quest.reward.icon, Rect.new(0, 0, 24, 24))
self.contents.draw_text(110, 96, text_width, 32, @quest.reward.text)
end
text_width = contents.text_size(@quest.description).width
self.contents.draw_text(0, 160, 608, 32, @quest.description)
for i in 0...([@quest.shift_count, 7].min)
y = 224 + 32 * i
text_width = contents.text_size(@quest.old_description(i)).width
self.contents.draw_text(0, y, text_width, 32, @quest.old_description(i))
end
end
def update
loop do
Graphics.update
Input.update
# Close the window if input is received
if Input.trigger? (Input::C)
$game_system.se_play($data_system.cancel_se)
break
end
if Input.trigger? (Input::B)
$game_system.se_play($data_system.cancel_se)
break
end
end
dispose
end
end
#--------------------------------------------------------------
# CLASS: Window_Reward
# Summary: A simple class that shows the reward received after
# completing a quest and then waits for input from the player to
# terminate itself.
#--------------------------------------------------------------
class Window_Reward < Window_Base
def initialize(reward)
window_width = [112, reward.text.length * 15 + 32].max
super(320 - window_width / 2, 144, window_width, 96)
self.contents = Bitmap.new(window_width - 32, 64)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
self.contents.font.color = normal_color
self.contents.draw_text(0, 0, 78, 32, "Reward:")
self.contents.draw_text(0, 32, window_width, 32, reward.text)
update
end
def update
loop do
Graphics.update
Input.update
#Close the window if input is received
if Input.trigger? (Input::C)
$game_system.se_play($data_system.decision_se)
break
end
if Input.trigger? (Input::B)
$game_system.se_play($data_system.decision_se)
break
end
end
Input.update
dispose
end
end
#--------------------------------------------------------------
# CLASS: Window_LevelUp
# Summary: A simple class that shows the text "[actor name] Level Up!"
# then waits for input from the player to terminate itself.
#--------------------------------------------------------------
class Window_LevelUp < Window_Base
def initialize(actor)
#Generate text
@text = actor.name + " Level Up!"
window_width = actor.name.length * 12 + 129
super(320 - window_width / 2, 176, window_width, 64)
self.contents = Bitmap.new(self.width - 32, 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
self.contents.font.color = normal_color
self.contents.draw_text(0, 0, self.width - 32, 32, @text)
update
end
def update
loop do
Graphics.update
Input.update
#Close the window if input is received
if Input.trigger? (Input::C)
$game_system.se_play($data_system.decision_se)
break
end
if Input.trigger? (Input::B)
$game_system.se_play($data_system.decision_se)
break
end
end
Input.update
dispose
end
end
#--------------------------------------------------------------
# CLASS: Window_QuestUpdate
# Summary: A window that is displayed when a quest is updated or received.
#--------------------------------------------------------------
class Window_QuestUpdate < Window_Base
# Pass in true or false. If true, displays "New Quest!". If false, displays "Quest Updated!"
def initialize(new)
if new
width = 141
else
width = 177
end
super(320 - width / 2, 176, width, 64)
self.contents = Bitmap.new(self.width - 32, self.height - 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
self.contents.font.color = normal_color
if new
self.contents.draw_text(0, 0, self.width - 32, 32, "New Quest!")
else
self.contents.draw_text(0, 0, self.width - 32, 32, "Quest Updated!")
end
update
end
def update
loop do
Graphics.update
Input.update
# Close the window if input is received
if Input.trigger? (Input::B)
$game_system.se_play($data_system.decision_se)
break
end
if Input.trigger? (Input::C)
$game_system.se_play($data_system.decision_se)
break
end
end
Input.update
dispose
end
end
#--------------------------------------------------------------
# CLASS: Scene_QuestBook
# Summary: Displays the list of available quests and allows the player
# to select a specific quest for more information. Uses the Window_QuestList,
# Window_Help, and Window_QuestInfo classes.
#--------------------------------------------------------------
class Scene_QuestBook
def main
# Window with list of quests
@quest_window = Window_QuestList.new($game_questbook)
# Window displaying task of highlighted quest
@help_window = Window_Help.new
@quest_window.help_window = @help_window
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@quest_window.dispose
@help_window.dispose
end
def update
# Update the windows
@quest_window.update
@help_window.update
# Cancel button (B) Returns to the item menu.
if Input.trigger? (Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Item.new
end
# Select button (C) Selects the highlighted quest for viewing
if Input.trigger? (Input::C)
if $game_questbook[@quest_window.quest_index].available
# Code for if the selected quest is available to the player
$game_system.se_play($data_system.decision_se)
# Disable the quest list window and help window
@quest_window.active = false
@quest_window.visible = false
@help_window.active = false
@help_window.visible = false
# Create a new Window_QuestInfo object to display
# information about the selected quest
@info_window = Window_QuestInfo.new($game_questbook[@quest_window.quest_index])
# Enable the quest list window and the help window
@quest_window.active = true
@quest_window.visible = true
@help_window.active = true
@help_window.visible = true
@quest_window.refresh
else
# Code for if the selected quest is unavailable to the player
$game_system.se_play($data_system.buzzer_se)
return
end
end
end
end
#--------------------------------------------------------------
# Extra code for class Scene_Title
# Summary: This is where all the quests are created.
#--------------------------------------------------------------
class Scene_Title
def command_new_game
$game_system.se_play($data_system.decision_se)
Audio.bgm_stop
Graphics.frame_count = 0
$game_temp = Game_Temp.new
$game_system = Game_System.new
$game_switches = Game_Switches.new
$game_variables = Game_Variables.new
$game_self_switches = Game_SelfSwitches.new
$game_screen = Game_Screen.new
$game_actors = Game_Actors.new
$game_party = Game_Party.new
$game_troop = Game_Troop.new
$game_map = Game_Map.new
$game_player = Game_Player.new
# QUESTS
$game_questbook = Game_QuestBook.new()
# Create all quests here
# Format: $game_questbook.add_quest("<name>", "<location>", "<presenter>", "gold/item/exp/none", 0/<gold amount/item id/exp amount>, "<first task>")
# Note: Item ID is found in the database
# QUESTS
quest1 = Game_Quest.new("Quest title", "Location", "Presenter", "gold/item/exp/none",0/<gold amount/item id/exp amount>, "Task")
$game_questbook.add_quest(quest1)
$game_party.setup_starting_members
$game_map.setup($data_system.start_map_id)
$game_player.moveto($data_system.start_x, $data_system.start_y)
$game_player.refresh
$game_map.autoplay
$game_map.update
$scene = Scene_Map.new
end
end
#--------------------------------------------------------------
# Extra code for Scene_Save
# Summary: Saves the questbook of the player. ($game_questbook)
#--------------------------------------------------------------
class Scene_Save < Scene_File
alias original_write write_save_data
def write_save_data(file)
original_write(file)
Marshal.dump($game_questbook, file)
end
end
#--------------------------------------------------------------
# Extra code for Scene_Load
# Summary: Loads the questbook of the player. ($game_questbook)
#--------------------------------------------------------------
class Scene_Load < Scene_File
alias original_read read_save_data
def read_save_data(file)
original_read(file)
$game_questbook = Marshal.load(file)
end
end