Ok, I knew my quest log needed improvement, so a couple days ago I went to fix it up.
HOLY. FUCKING. SHIT.
This thing was the worst piece of coding I had ever friggin seen. I had the description window as a Window_Selectable with the index at -1. I don't know why it had an update_cursor_rect method. The method used to draw the descriptions was long and laggy and stupid, as was the method for making descriptions. I have no idea how this thing didn't time out every time it was called.
So, I basically rewrote the entire thing. It's much cleaner and easier to use, has no limitations for lines of description or anything, much less lag, much easier to setup quests and objectives.
You'll need to set the script up to display the lists. Press CTRL+F and search for QSETUP.
The way quests work now is much, MUCH easier.
@questname[Quest Number] = "Name of Quest"
@description[Quest Number] = ["line 1", "line 2", "line 3", "etc"]
The description needs to be in an array, even if it's just 1 line. Same goes for objectives.
@objectives[Quest Number] = ["objective 1", "objective2", "etc"]
...Wait, that's it? Yep. No desclines/objlines/BREAKLINE/line limits/having to add a blank description line/etc.
You don't need to add any objectives, either. Note that this is just one list. To make the completed quest list, just copy/paste this again, change the class name to Quest_Data2, and set it up accordingly.
Activating quests is easier, too. qupdate is set up differently now.
$game_temp.qupdate[Quest Number][Objective Number] = true
For objective number, setting 0 to true will show the quest on the list. 1 and up are the objectives for the quest.
You'll notice I only included the script for the first list.
This is your test. The script is set by default to use Quest_Data2 for the completed quest lists.
If you follow the instructions, you'll have no problem here. If you don't, you're too stupid to be using scripts.
DerVVulfman made this small edit of the default menu that adds in a Quest Log option:
There's also a few pictures you need to.
You can make your own using them as a template,
so your quest log can look however you like.
In Graphics/Icons:
Needs to be named 'InProgressIcon'
Needs to be named 'CompletedIcon'
To call it, put '$scene = Scene_Quests.new' in a slot in your menu. You can call different lists using Scene_Quests.new(list number).
This needs to be set up in the Quest Window script.
If it's being called from the map, find '$scene = Scene_Menu.new' in both lists and
change it to '$scene = Scene_Map.new'.
Up/Down arrows scroll through the list, Left/Right changes lists.
Credit Jaberwocky if you use this.
I've explained very clearly how to set this up. I'm not gonna type the same thing twice because you couldn't be bothered to read this post. If you have questions that are answered here, go run your face into a cinder block.
HOLY. FUCKING. SHIT.
This thing was the worst piece of coding I had ever friggin seen. I had the description window as a Window_Selectable with the index at -1. I don't know why it had an update_cursor_rect method. The method used to draw the descriptions was long and laggy and stupid, as was the method for making descriptions. I have no idea how this thing didn't time out every time it was called.
So, I basically rewrote the entire thing. It's much cleaner and easier to use, has no limitations for lines of description or anything, much less lag, much easier to setup quests and objectives.
Code:
#-------------------------------------------------------------------------------
# Jaberwocky's Quest Log
#
#
# FGSDF
#-------------------------------------------------------------------------------
class Bitmap
# Draws an outline around the text,
# both the outline color and the color of the
# text inside can be anything.
def draw_text_outline_custom(x, y, wid, hei, text, align, outlinecolor, insidecolor)
if $qdata.useoutlines == true
self.font.color = outlinecolor
draw_text(x + 1,y + 1,wid,hei,text, align)
draw_text(x + 1,y - 1,wid,hei,text, align)
draw_text(x - 1,y - 1,wid,hei,text, align)
draw_text(x - 1,y + 1,wid,hei,text, align)
end
self.font.color = insidecolor
draw_text(x,y,wid,hei,text, align)
end
end
class Scene_Quests
attr_accessor :questids
attr_accessor :command_window
attr_accessor :questswitches
# QSETUP This is the initialize method.
# It's where you set up which list will load:
def initialize(list = 1)
@quest_index = 0
@currentlist = list
# Right here. The format is:
# when A
# $qdata = B.new
# @questswitches = $game_temp.C
#
# A is the number called in $scene = Scene_Quests.new(Number)
# B is the class name for the list.
# C is the variable name for the quest list. Don't put the @ part with it here.
case list
when 1
$qdata = Quest_Data.new
@questswitches = $game_temp.qupdate
when 2
$qdata = Quest_Data2.new
@questswitches = $game_temp.qupdate2
end
end
def main
# Displays the background pictures:
@backpic = Sprite.new
@backpic.bitmap = RPG::Cache.picture("Menuback")
@backpic.z = 990
@questback = Sprite.new
@questback.bitmap = RPG::Cache.picture($qdata.backpicture)
@questback.z = 991
# Creates the quest list based on how many quests are active on that list:
questwin = []
@questids = []
# QSETUP This is one of the for branches that will need changing once your game is complete.
# More about that later.
for i in 1...10000
if @questswitches[i][0] == true
questwin.push($qdata.questname[i])
@questids.push(i)
end
end
if questwin.size == 0
questwin.push($qdata.questname[0])
@questids.push(0)
end
@command_window = Window_Qmand.new(182, questwin)
@command_window.index = @quest_index
@command_window.opacity = 0
@command_window.z = 1100
# This makes the window for the description text and objectives:
@status_window = Quest.new
@status_window.x = 160
@status_window.y = 75
@status_window.z = 1100
@status_window.opacity = 0
Graphics.transition
loop do
Graphics.update
Input.update
update_command
if $scene != self
break
end
end
Graphics.freeze
@command_window.contents.clear
@command_window.dispose
@status_window.contents.clear
@status_window.dispose
@backpic.dispose
@questback.dispose
end
end
#-------------------------------------------------------------------------------
# Updates the quest data, and switches between lists:
#-------------------------------------------------------------------------------
def update_command
if Input.repeat?(Input::UP)
if @command_window.index == 0
@command_window.index = @questids.size - 1
else
@command_window.index -= 1
end
unless @questids.size == 1
$game_system.se_play($data_system.cursor_se) unless @questids.size == 1
@status_window.refresh
end
end
if Input.repeat?(Input::DOWN)
if @command_window.index == @questids.size - 1
@command_window.index = 0
else
@command_window.index += 1
end
unless @questids.size == 1
$game_system.se_play($data_system.cursor_se)
@status_window.refresh
end
end
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Menu.new(4)
return
end
# QSETUP This is where you set up how it switches between lists.
# If you want to have say, 2 parties, each with different lists,
# this is where you would set up how it switches between lists.
# The format is simple:
# when listnumber
# $scene = Scene_Quests.new(list number to switch to)
#
# So if lists 1/2 are for the first party, and you want lists 3/4 to be for the second party,
# You'd just set up list 3 to switch to list 4 and list 4 to switch to list 3.
if Input.trigger?(Input::LEFT)
$game_system.se_play($data_system.cursor_se)
case @currentlist
when 1
$scene = Scene_Quests.new(2)
when 2
$scene = Scene_Quests.new(1)
end
end
if Input.trigger?(Input::RIGHT)
$game_system.se_play($data_system.cursor_se)
case @currentlist
when 1
$scene = Scene_Quests.new(2)
when 2
$scene = Scene_Quests.new(1)
end
end
end
#-------------------------------------------------------------------------------
# This creates the description text and the objectives
# for the the quests in progress. Objectives change colors
# and have an icon next to them.
#-------------------------------------------------------------------------------
class Quest < Window_Base
def initialize
super(0, 0, 480, 480)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
self.contents.clear
y = 0
for i in 0...$qdata.description[$scene.questids[$scene.command_window.index]].size
self.contents.draw_text_outline_custom(2, 24 * y, 480, 32, $qdata.description[$scene.questids[$scene.command_window.index]][i],0, $qdata.descoutline, $qdata.desctext)
y += 1
end
for i in 0...$qdata.objectives[$scene.questids[$scene.command_window.index]].size
y += 1
if $scene.questswitches[$scene.questids[$scene.command_window.index]][i + 1] == true
bitmap = RPG::Cache.icon("CompletedIcon")
self.contents.blt(0, 4 + ( y * 24) , bitmap, Rect.new(0, 0, 18, 18))
self.contents.draw_text_outline_custom(24, 0 + (y * 24), 456, 24, $qdata.objectives[$scene.questids[$scene.command_window.index]][i], 0, $qdata.compoutline, $qdata.comptext)
else
bitmap = RPG::Cache.icon("InProgressIcon")
self.contents.blt(0, 4 + ( y * 24) , bitmap, Rect.new(0, 0, 18, 18))
self.contents.draw_text_outline_custom(24, 0 + (y * 24), 456, 24, $qdata.objectives[$scene.questids[$scene.command_window.index]][i], 0, $qdata.incompoutline, $qdata.incomptext)
end
end
end
end
#-------------------------------------------------------------------------------
# This is for the list of quests on the left:
#-------------------------------------------------------------------------------
class Window_Qmand < Window_Selectable
def initialize(width, commands)
super(-10, 50, width, 380)
self.contents = Bitmap.new(width - 32, commands.size * 32)
@commands = commands
@item_max = @commands.size
self.index = 0
refresh
end
def refresh
self.contents.clear
for i in [email=0...@commands.size]0...@commands.size[/email]
self.contents.draw_text_outline_custom(0, 32 * i, self.contents.width, 32,@commands[i],1, $qdata.menuoutline, $qdata.menutext)
end
end
end
class Game_Temp
# QSETUP This is where you add the variables that control the quests on the lists.
attr_accessor :qupdate
attr_accessor :qupdate2
# You'll need one of these for every list. The script is setup by default to
# use qupdate for the first list and qupdate2 for the second.
#You can change these if you want.
alias asdfghjkl initialize
def initialize
asdfghjkl
# You'll need to add any new quest variables here, like this:
@qupdate = []
@qupdate2 = []
for i in 0...10000
# And here, too, like this:
@qupdate[i] = []
@qupdate2[i] = []
end
# That 10000 there is the maximum number of quests per list.
# Once your game is completely finished, count the number of quests on each list.
# There'll be a for loop like this in each of the quest lists.
# Replace the 10000 there with the number of quests on the list.
# This will lower the amount of time it takes to read the list.
# Do the same to the 10000 both here and in the main method up at the top,
# with the highest number of quests your lists have.
end
end
class Scene_Save < Scene_File
alias qwertyuiop write_save_data
def write_save_data(file)
qwertyuiop(file)
# QSETUP You'll need to add any new quest variables here, too, like this:
Marshal.dump($game_temp.qupdate, file)
Marshal.dump($game_temp.qupdate2, file)
end
end
class Scene_Load < Scene_File
alias zxcvbnm read_save_data
def read_save_data(file)
zxcvbnm(file)
# QSETUP Also need to add any new quest variable here, like this:
$game_temp.qupdate = Marshal.load(file)
$game_temp.qupdate2 = Marshal.load(file)
end
end
Code:
#-------------------------------------------------------------------------------
# This class holds all the data for the quests.
# If you want a new quest, add it in here.
# This is the class name. If you add another list, you need a different class name.
# It's a good idea to just use Quest_Data2/3/4/5/6/etc...
class Quest_Data
attr_accessor :description, :questname, :objectives,
:useoutlines, :descoutline, :desctext, :incompoutline,
:incomptext, :compoutline, :comptext, :menuoutline,
:menutext, :backpicture
def initialize
@questname = []
@description = []
@objectives = []
for i in 0...10000
@description[i] = []
@objectives[i] = []
end
# These are options you can change:
# These control the colors of the text.
# The code for this is:
# Color.new(Amount of Red, Amount of Green, Amount of Blue, Opacity)
# Each of these can be set from 0-255, 255 being the highest.
@useoutlines = true# Set to false if you don't want the text to have an outline
@descoutline = Color.new (0, 0, 0, 255)# Outline color for description text
@desctext = Color.new (255, 255, 255, 255)# Text color for description text
@incompoutline = Color.new(0, 0, 0, 255)# Outline color for incomplete objectives
@incomptext = Color.new(255, 0, 0, 255)# Text color for incomplete objectives
@compoutline = Color.new(0, 0, 0, 255)# Outline color for completed objectives
@comptext = Color.new(0, 255, 0, 255)# Text color for completed objectives
@menuoutline = Color.new(0, 0, 0, 255)# Outline color the in progress list
@menutext = Color.new(255, 255, 255, 255)# Text color for the in progress list
#-------------------------------------------------------------------------------
# This is the filename of the background picture for quests in progress:
@backpicture = "InProgressQuestScroll"
# It needs to be placed in the Graphics/Pictures folder.
#-------------------------------------------------------------------------------
# This is the data that is displayed when there are no quests active.
# I'll be using it to explain how to set up a quest, too:
@questname[0] = "No Quests" # This will be the name of your quest.
# This is the description for the quest. The format is:
# @description[quest number] = ["line 1", "line 2", "line 3", "etc..."]
# Note that if you have too many lines of description you can run out of room
# for objectives.
@description[0] = ["I am not currently on any quests."]
# The format is the same for @objectives if the quest has any.
#-------------------------------------------------------------------------------
# Quest 1
@questname[1] = "Get some rest!"
@description[1] = ["Even with 2 years of training,",
"I was unable to best Pengzoda...",
"Why has he shown himself after all this time?",
"What are these 'things at work' he spoke of?",
"Why did he spare my life a second time?",
"...Not that I'm complaining about that one...", " ",
"These are questions for another time.",
"Right now I need to make it back to my house",
"and rest so I can recover from this injury."]
@objectives[1] = ["-Make it back to your house",
"-Rest so that your wound can recover"]
end
end
@questname[Quest Number] = "Name of Quest"
@description[Quest Number] = ["line 1", "line 2", "line 3", "etc"]
The description needs to be in an array, even if it's just 1 line. Same goes for objectives.
@objectives[Quest Number] = ["objective 1", "objective2", "etc"]
...Wait, that's it? Yep. No desclines/objlines/BREAKLINE/line limits/having to add a blank description line/etc.
You don't need to add any objectives, either. Note that this is just one list. To make the completed quest list, just copy/paste this again, change the class name to Quest_Data2, and set it up accordingly.
Activating quests is easier, too. qupdate is set up differently now.
$game_temp.qupdate[Quest Number][Objective Number] = true
For objective number, setting 0 to true will show the quest on the list. 1 and up are the objectives for the quest.
You'll notice I only included the script for the first list.
This is your test. The script is set by default to use Quest_Data2 for the completed quest lists.
If you follow the instructions, you'll have no problem here. If you don't, you're too stupid to be using scripts.
DerVVulfman made this small edit of the default menu that adds in a Quest Log option:
Code:
#-------------------------------------------------------------------------------
# This rewrite of Scene_Main just adds the Quests option into the menu, and it
# makes the number of menu features longer.
#
# I did not edit any other window in the system, so you will see the QUIT option
# print overtop of the Game Time window in the screen. I merely wanted to show
# how to call the Quest Window from a menu or script.
#-------------------------------------------------------------------------------
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Make command window
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
# Changed the s5 from Save to Quests, added an s7 to make the list longer
s5 = "Quests"
s6 = "Save"
s7 = "End Game"
# Added the s7 to the command window
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6, s7])
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# Make play time window
@playtime_window = Window_PlayTime.new
@playtime_window.x = 0
@playtime_window.y = 224
# Make steps window
@steps_window = Window_Steps.new
@steps_window.x = 0
@steps_window.y = 320
# Make gold window
@gold_window = Window_Gold.new
@gold_window.x = 0
@gold_window.y = 416
# Make status window
@status_window = Window_MenuStatus.new
@status_window.x = 160
@status_window.y = 0
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
end
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to item screen
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
# Changed #4 to the Quest menu (instead of save)
when 4 # quest
# This is for quests now:
$scene = Scene_Quests.new
# Changed 5 on down to keep save and quit in the menu...
when 5 # save
# If saving is forbidden
if $game_system.save_disabled
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to save screen
$scene = Scene_Save.new
when 6 # end game
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_End.new
end
return
end
end
end
You can make your own using them as a template,
so your quest log can look however you like.
Example for an in progress list:
Example for a completed list:
Example for a background image:

Example for a completed list:

Example for a background image:



To call it, put '$scene = Scene_Quests.new' in a slot in your menu. You can call different lists using Scene_Quests.new(list number).
This needs to be set up in the Quest Window script.
If it's being called from the map, find '$scene = Scene_Menu.new' in both lists and
change it to '$scene = Scene_Map.new'.
Up/Down arrows scroll through the list, Left/Right changes lists.
Credit Jaberwocky if you use this.
I've explained very clearly how to set this up. I'm not gonna type the same thing twice because you couldn't be bothered to read this post. If you have questions that are answered here, go run your face into a cinder block.
A Quests In Progress list, showing the description, and different colored objectives with their icons
Yes, I know Franz is a stupid name o_O;
What the list looks like when you have no quests active
A Completed Quests list
You can have a near endless amount of quests

Yes, I know Franz is a stupid name o_O;
What the list looks like when you have no quests active

A Completed Quests list

You can have a near endless amount of quests
