11-24-2009, 06:28 AM
This time I chose to use a book-like format, because it fits better with my new menu-in-the-works than the scroll thing does. The code's a lot cleaner, the quests are easier to manage and organize, and you have -complete- control over the placement of everything in the description.
Features
- Organize your quests into categories!
- Faster loading!
- Less save-bloating!
- Easier quest data organization!
- Multi-page descriptions!
- Quest-specific variables!
- Ability to change font size, color, and name!
- Ability to use icons and pictures in descriptions!
- Greater control over objectives!
- Message codes for displaying various data in your description!
- HOLY CRAP MORE CUSTOMIZATION THAN YOU'LL EVER NEED FOR ANYTHING EVER
- Probably some other stuff that I forgot!
- wakka wakka wakka
- I am a SALAD BOAT
- VROOM VROOOM
- pinecone
Changelog
v.2.1.3
Woops.
Bugfixes:
-Fixed a bug causing the quest display to refresh itself more than neccessary.
-Fixed a bug where the category title would be drawn based on all categories in the list instead of based on only active categories.
-Fixed several other bugs caused by the above problem.
v.2.1.2
Bugfixes:
-Fixed a bug where the draw text instruction types would default to the window's default font/size/color instead of the category list's default font/size/color
New stuff:
-Added support for spaces in quest variable names and in the \\s message code
-Confirm button now closes quest window when called directly to a quest (So books and stuff will behave more like a message box)
-Updated demo
Scripts
Setup
Here's a few pictures for you to use for the background:
Book graphic
First version of the book graphic in blinding white (Size is off by like 1 pixel)
And here's some crappy next/previous page pictures:
Alright, onto the setup.
In Scene_Title, locate the following line:
$game_system = Game_System.new
In the default title, it should be on line 32.
Add this line right below it:
$game_system.load_quest_data
Next, stick the following anywhere below Game_Party:
To call the quest window, simply use
Quest_Window.new(x, y, z, list key, selfupdate, mode)
x, y, and z are the coordinates, obviously.
Don't know what a list key is? Read the instructions below.
selfupdate and mode are optional.
If selfupdate is set to true, the window will function as it's own scene of sorts, meaning you could, say, call it from an event on the map without interrupting Scene_Map. If you don't know what that means, you'll probably want to have this set to true all the time.
mode is an array that lets you... 'skip' sections of the quest window.
Here's the various settings for it:
[0]
This is the default setting for the mode. It'll open up to the specified list.
[1, category key, headertext]
This will skip the category list and open up a category directly. 'headertext' is what will be displayed at the top of the first page. You still need to specify a list key, as it'll use that for formatting. Useful if you, say... don't want to use the category seperation feature. You'd be able to use a category as the entire quest log, if you wanted.
[2, quest key]
This will skip everything and jump right to a quest. Usefor for things like books or notes laying around.
What the crap post size limit D8
Features
- Organize your quests into categories!
- Faster loading!
- Less save-bloating!
- Easier quest data organization!
- Multi-page descriptions!
- Quest-specific variables!
- Ability to change font size, color, and name!
- Ability to use icons and pictures in descriptions!
- Greater control over objectives!
- Message codes for displaying various data in your description!
- HOLY CRAP MORE CUSTOMIZATION THAN YOU'LL EVER NEED FOR ANYTHING EVER
- Probably some other stuff that I forgot!
- wakka wakka wakka
- I am a SALAD BOAT
- VROOM VROOOM
- pinecone
Changelog
v.2.1.3
Woops.
Bugfixes:
-Fixed a bug causing the quest display to refresh itself more than neccessary.
-Fixed a bug where the category title would be drawn based on all categories in the list instead of based on only active categories.
-Fixed several other bugs caused by the above problem.
v.2.1.2
Bugfixes:
-Fixed a bug where the draw text instruction types would default to the window's default font/size/color instead of the category list's default font/size/color
New stuff:
-Added support for spaces in quest variable names and in the \\s message code
-Confirm button now closes quest window when called directly to a quest (So books and stuff will behave more like a message box)
-Updated demo
Scripts
Quest Data
Code:
class Game_System
def load_quest_data
$data_quests = {}
#$data_quests["hash key"] = Quest_Data.new(
# "name", [description code], [objective code], {initial quest variables(optional)})
$data_quests["fishtalk"] = Quest_Data.new("Talk with Fish",
[[0, [0, [4, 4], "Cat wants me to ask Fish if"]], [0, [0, [4, 24], "it's ok to eat him."]]],
[[0, 1, [0, [4, 44], ["I need to get Fish's response.", "Fish said no."]]]])
$data_quests["cat quest 2"] = Quest_Data.new("Cat's Query",
[[0, [0, [4, 4], "Cat wants to know how Fish is"]], [0, [0, [4, 24], "breathing outside of water."]],
[0, [0, [4, 60], "Being a cat, Cat is too damn lazy"]], [0, [0, [4, 80], "to ask Fish himself."]]],
[])
$data_quests["cat quest done"] = Quest_Data.new("Lazy Cat",
[[0, [0, [4, 4], "Cat can ask his own stupid"]], [0, [0, [4, 24], "questions from now on."]]],
[])
$data_quests["trees"] = Quest_Data.new("Oh, nuts",
[[0, [0, [4, 4], "This tree wants me to find"]], [0, [0, [4, 24], "its missing acorns."]],
[2, [0, [290, 4], [1, 1]]], [0, [0, [310, 260], "A nice enough sort.", nil, 15]],
[0, [0, [4, 100], "I have found \\qv[nuts found]/5 acorns."]]],
[[0, 0, [0, [4, 120], ["I should return these to that tree."]]]], {"nuts found" => 0})
$data_quests["trees done"] = Quest_Data.new("Oh, nuts",
[[1, [0, [-80, 4], [1, "hat2"]]], [0, [0, [4, 232], "That tree gave me its"]],
[0, [0, [4, 252], "old 'brocap'."]], [0, [0, [4, 270], "I think I look smashing in it."]]],
[])
$data_quests["sign1"] = Quest_Data.new("",
[[0, [0, [4, 4], "You can call the script directly to a quest,"]],
[0, [0, [4, 24], "like this sign does. This lets you create"]],
[0, [0, [4, 44], "books and other media for your game..."]],
[0, [0, [4, 74], "...such as this sign."]], [0, [0, [4, 120], "You can also skip the category list and"]],
[0, [0, [4, 140], "jump directly to a category, if you wanted to."]]], [])
end
end
Quest Handling
Code:
class Quest_Data
attr_accessor :description
attr_accessor :objectives
attr_accessor :name
attr_accessor :data
def initialize(name, description, objectives, data = {})
@name = name
@description = description
@objectives = objectives
@data = data
end
end
class Quest_List_Data
attr_accessor :data
attr_accessor :stages
attr_reader :id
def initialize(quest_id)
@data = $data_quests[quest_id].data
@stages = []
for obj in $data_quests[quest_id].objectives
@stages.push(obj[1])
end
@id = quest_id
end
def name
return $data_quests[@id].name
end
def description
return $data_quests[@id].description
end
def objectives
return $data_quests[@id].objectives
end
end
class Quest_List
attr_accessor :quests
attr_accessor :lists
attr_accessor :order
attr_accessor :settings
def initialize
@quests = {}
@order = {}
@lists = {}
@settings = [1, 2] # Default inventory, default battlers
@lists['wat'] = Category_List.new
@lists['wat'].windowskin = "001-Blue01"
@lists['wat'].categories = [["Not Finished", "list1"], ["Not Not Finished", "Finished"]]
@lists["signboard"] = Category_List.new
@lists["signboard"].windowskin = "001-Blue01"
@lists["signboard"].background = ["terriblesign", -16, -24] # Remember that there's a 16x16 buffer on windows
end
def has_quest?(quest_id)
return @quests.include?(quest_id)
end
def add(quest_id, list_name)
return if $data_quests[quest_id].nil?
if @order[list_name].nil?
@order[list_name] = []
end
return if @order[list_name].include?(quest_id)
@order[list_name].push(quest_id)
add_quest(quest_id)
end
def remove(quest_id, list_name)
return if $data_quests[quest_id].nil?
return if @order[list_name].nil?
return if @order[list_name].empty?
return unless @order[list_name].include?(quest_id)
@order[list_name].delete(quest_id)
end
def add_quest(quest_id)
return if $data_quests[quest_id].nil?
return if @quests.include?(quest_id)
@quests[quest_id] = Quest_List_Data.new(quest_id)
end
def remove_quest(quest_id, erase = false)
@quests.delete(quest_id) if erase
for list in @order.keys
@order[list].delete(quest_id)
end
end
def reset_quest(quest_id, create = true)
return unless @quests.include?(quest_id) if create == false
@quests.delete(quest_id)
add_quest(quest_id)
end
def replace(new_quest, rep_quest, list_name)
return if new_quest == rep_quest # EASIEST REPLACEMENT EVER
return if $data_quests[new_quest].nil? or $data_quests[rep_quest].nil?
return if @order[list_name].nil?
return if @order[list_name].empty?
return if @order[list_name].include?(new_quest)
return unless @order[list_name].include?(rep_quest)
@order[list_name][@order[list_name].index(rep_quest)] = new_quest
add_quest(new_quest)
end
def erase_list(list_name)
@order.delete(list_name)
end
def create_list(list_name)
return unless @order[list_name].nil?
@order[list_name] = []
end
end
class Category_List
attr_accessor :categories
attr_accessor :title
attr_accessor :font
attr_accessor :background
attr_accessor :windowskin
attr_accessor :ipp
attr_accessor :animation
attr_accessor :empty_text
attr_accessor :audio
attr_accessor :formatting
attr_accessor :page_graphics
def initialize
# These are the defaults. You have to set them for the category list itself
# if you want it to be different.
@title = "Table of Contents"
# Font [[Title Font, Size, Color], [Category Font, Size, Color]]
@font = [[Font.default_name, 24, Color.new(0, 0, 0)], [Font.default_name, 20, Color.new(0, 0, 0)]]
# Background [filename, x offset, y offset]
@background = ["BookBack2.png", 5, 8]
@windowskin = "Pengu Speech 1.png"
# Items per page. Will require adjusting of @formatting if you change it.
@ipp = 11
# Animation ID (defined in script)
@animation = -1
# Text to display when there are no valid categories
@empty_text = ""
# Audio
@audio = [["Audio/SE/046-Book01", 100, 100], ["Audio/SE/046-Book01", 100, 100],
["Audio/SE/046-Book01", 100, 90], ["Audio/SE/046-Book01", 100, 90],
["Audio/SE/" + $data_system.cursor_se.name, $data_system.cursor_se.volume, $data_system.cursor_se.pitch],
["Audio/SE/046-Book01", 100, 100]]
# Formatting: [Distance from one page to the next, distance between list items, width of page, offset from top, cursor margin]
@formatting = [261, 26, 235, 12, 8]
# Page Graphics: [prevpage, nextpage]
@page_graphics = ["prevpage.png", "nextpage.png"]
# Same as before
@categories = []
end
end
Quest Window
Code:
class Quest_Window < Window_Base
attr_reader :close_book
def initialize(x, y, z, list_index, auto = false, mode = [0])
super(x-16, y-16, 535, 386)
self.contents = Bitmap.new(width-32, height-32)
self.contents.font.color = normal_color
self.z = z
@list = $game_party.quests.lists[list_index]
@background = Sprite.new
@background.bitmap = RPG::Cache.picture(@list.background[0])
@background.x = self.x + @list.background[1]
@background.y = self.y + @list.background[2]
@background.z = self.z - 10
self.opacity = 0
@cursor_coord = []
@index = [0, 0, ""]
@last_index = -2
@last_page = 0
@page = [0,0,0]
@close_book = false
@phase = 0
@mode = mode
setup_toc
setup_toc_cursor
check_mode
refresh
update_loop if auto
end
def update_loop
loop do
Graphics.update
Input.update
update
break if @close_book
end
dispose
Input.update
end
def check_mode
se = @list.audio[2]
Audio.se_play(se[0], se[1], se[2])
case @mode[0]
when 1 # Directly to category [1, category key, header text]
@phase = 1
setup_category_cursor
when 2 # Directly to quest [2, quest key]
@phase = 2
end
end
def dispose
@background.dispose
super
end
def setup_toc
@toc = [[]]
@pagemax = []
@indexmax = [-1, 0]
i = 0
count = 1
val = -1
for catg in @list.categories
val += 1
next if $game_party.quests.order[catg[1]].nil?
next if $game_party.quests.order[catg[1]].empty?
if count > @list.ipp * 2
count = 0
i += 1
@toc.push([])
end
@toc[i].push(catg)
count += 1
@indexmax[0] += 1
end
if @indexmax[0] == -1
@phase = -1
@toc[0].push([@list.empty_text])
end
@pagemax[0] = i
end
def setup_questlist
@indexmax[1] = $game_party.quests.order[@toc[@page[1]][@index[0]][1]].size - 1
@pagemax[1] = $game_party.quests.order[@toc[@page[1]][@index[0]][1]].size / (@list.ipp * 2)
end
def update
if [-1, 0].include?(@phase)
indexnum = 0
elsif @phase == 1
indexnum = 1
elsif @phase == 2
indexnum = 2
end
if Input.repeat?(Input::DOWN)
if [0, 1].include?(@phase)
temp = @index[indexnum] / @list.ipp
@index[indexnum] += 1
if @index[indexnum] > @indexmax[indexnum]
@index[indexnum] -= (@indexmax[indexnum] + 1) % @list.ipp
elsif @index[indexnum] / @list.ipp != temp
@index[indexnum] -= @list.ipp
end
end
end
if Input.repeat?(Input::UP)
if [0, 1].include?(@phase)
temp = @index[indexnum] / @list.ipp
@index[indexnum] -= 1
if @index[indexnum] < 0 or @index[indexnum] / @list.ipp != temp
@index[indexnum] = [(@index[indexnum] + @list.ipp), @indexmax[indexnum]].min
end
end
end
if Input.repeat?(Input::RIGHT)
if [0, 1].include?(@phase)
if @index[indexnum] == @indexmax[indexnum]
@index[indexnum] = 0
else
@index[indexnum] += @list.ipp
@index[indexnum] = @indexmax[indexnum] if @index[indexnum] > @indexmax[indexnum]
end
elsif @phase == 2
@page[2] += 1
@page[2] = 0 if @page[2] > @pagemax[2]
end
end
if Input.repeat?(Input::LEFT)
if [0, 1].include?(@phase)
if @index[indexnum] == 0
@index[indexnum] = @indexmax[indexnum]
else
@index[indexnum] -= @list.ipp
@index[indexnum] = 0 if @index[indexnum] < 0
end
elsif @phase == 2
@page[2] -= 1
@page[2] = @pagemax[2] if @page[2] < 0
end
end
if [-1, 0, 1].include?(@phase)
@page[indexnum] = (@index[indexnum] / (@list.ipp * 2))
end
if Input.trigger?(Input::C)
if @phase == 0
@phase = 1
setup_questlist
setup_category_cursor
@last_index = -1
@last_page = - 1
se = @list.audio[0]
Audio.se_play(se[0], se[1], se[2])
return
elsif @phase == 1
@phase = 2
@last_index = -1
@last_page = - 1
se = @list.audio[1]
Audio.se_play(se[0], se[1], se[2])
return
elsif @phase == 2 and @mode[0] == 2
@close_book = true
se = @list.audio[2]
Audio.se_play(se[0], se[1], se[2])
return
end
end
if Input.trigger?(Input::B)
if [-1, 0].include?(@phase) or (@phase == 1 and @mode[0] == 1) or
(@phase == 2 and @mode[0] == 2)
@close_book = true
se = @list.audio[2]
Audio.se_play(se[0], se[1], se[2])
return
elsif [1, 2].include?(@phase)
@index[1] = 0 if @phase == 1
@phase -= 1
@last_index = -1
@last_page = - 1
@page[2] = 0
se = @list.audio[3]
Audio.se_play(se[0], se[1], se[2])
return
end
end
if [0, 1].include?(@phase)
if @index[indexnum] != @last_index
unless @page[indexnum] != @last_page or @last_index == -2
se = @list.audio[4]
Audio.se_play(se[0], se[1], se[2])
end
@last_index = @index[indexnum]
self.cursor_rect.set(@cursor_coord[indexnum][@index[indexnum]][0], @cursor_coord[indexnum][@index[indexnum]][1], @cursor_coord[indexnum][@index[indexnum]][2],30)
end
end
if @page[indexnum] != @last_page
unless @last_page == - 1
se = @list.audio[5]
Audio.se_play(se[0], se[1], se[2])
if @page[indexnum] < @last_page
if @page[indexnum] + 1 < @last_page
page_left_many
else
page_left
end
else
if @page[indexnum] - 1 > @last_page
page_right_many
else
page_right
end
end
end
@last_page = @page[indexnum]
refresh
end
end
def refresh
self.contents.clear
if [-1, 0, 1].include?(@phase)
if [-1, 0].include?(@phase)
pagenum = 0
pagemaxnum = 0
headertext = @list.title
loopvals = @toc[@page[0]]
else
pagenum = 1
@pagemax[1] = 0
pagemaxnum = 1
if @mode[0] == 1
headertext = @mode[2]
loopvals = $game_party.quests.order[@mode[1]]
else
headertext = @toc[@page[1]][@index[0]][0]
loopvals = $game_party.quests.order[@toc[@page[1]][@index[0]][1]]
end
end
offset = @list.formatting[3]
if @page[pagenum] == 0
self.contents.font.name = @list.font[0][0]
self.contents.font.size = @list.font[0][1]
self.contents.font.color = @list.font[0][2]
text = headertext.dup
fontcheck = check_title_codes(text)
self.contents.font.name = fontcheck[0] unless fontcheck[0].nil?
self.contents.font.size = fontcheck[1] + 5 unless fontcheck[1].nil?
self.contents.font.color = fontcheck[2] unless fontcheck[2].nil?
self.contents.draw_text(0, 0, @list.formatting[2], 32, text, 1)
end
y = 0
x = 0
for asdf in loopvals
self.contents.font.name = @list.font[1][0]
self.contents.font.size = @list.font[1][1]
self.contents.font.color = @list.font[1][2]
if @phase == 1
name = $game_party.quests.quests[asdf].name.dup
else
name = asdf[0].dup
end
fontcheck = check_title_codes(name)
self.contents.font.name = fontcheck[0] unless fontcheck[0].nil?
self.contents.font.size = fontcheck[1] unless fontcheck[1].nil?
self.contents.font.color = fontcheck[2] unless fontcheck[2].nil?
y += 1
if y > @list.ipp
y = 1
x += 1
end
break if x >= 2
self.contents.draw_text(x * @list.formatting[0], offset + (y * @list.formatting[1]), @list.formatting[2], 32, name, 1)
end
if @page[pagenum] + 1 <= @pagemax[pagemaxnum]
bitmap = RPG::Cache.picture(@list.page_graphics[1])
self.contents.blt(self.contents.width - bitmap.width, self.contents.height - bitmap.height, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height))
end
if @page[pagenum] > 0
bitmap = RPG::Cache.picture(@list.page_graphics[0])
self.contents.blt(0, self.contents.height - bitmap.height, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height))
end
elsif @phase == 2
self.cursor_rect.empty
draw_description
end
end
def setup_toc_cursor
duck = 0
@cursor_coord[0] = []
for cat in @toc
x = 0
y = 0
for dog in cat
y += 1
if y > @list.ipp
y = 1
x += 1
end
if x >= 2
x = 0
end
self.contents.font.name = @list.font[1][0]
self.contents.font.size = @list.font[1][1]
self.contents.font.color = @list.font[1][2]
zebra = dog[0].dup
fontcheck = check_title_codes(zebra)
self.contents.font.name = fontcheck[0] unless fontcheck[0].nil?
self.contents.font.size = fontcheck[1] unless fontcheck[1].nil?
self.contents.font.color = fontcheck[2] unless fontcheck[2].nil?
@cursor_coord[0][duck] = [x * @list.formatting[0] + (@list.formatting[2] / 2) - @list.formatting[4] - (self.contents.text_size(zebra).width / 2), @list.formatting[3] + (y * @list.formatting[1]), self.contents.text_size(zebra).width + (@list.formatting[4] * 2)]
duck += 1
end
end
end
def setup_category_cursor
x = 0
y = 0
moose = 0
@cursor_coord[1] = []
if @mode[0] == 1
loopvals = $game_party.quests.order[@mode[1]]
else
loopvals = $game_party.quests.order[@toc[@page[0]][@index[0]][1]]
end
for cow in loopvals
badger = $game_party.quests.quests[cow].name
y += 1
if y > @list.ipp
y = 1
x += 1
end
if x >= 2
x = 0
end
self.contents.font.name = @list.font[1][0]
self.contents.font.size = @list.font[1][1]
self.contents.font.color = @list.font[1][2]
mushroom = badger.dup
fontcheck = check_title_codes(mushroom)
self.contents.font.name = fontcheck[0] unless fontcheck[0].nil?
self.contents.font.size = fontcheck[1] unless fontcheck[1].nil?
self.contents.font.color = fontcheck[2] unless fontcheck[2].nil?
@cursor_coord[1][moose] = [x * @list.formatting[0] + (@list.formatting[2] / 2) - @list.formatting[4] - (self.contents.text_size(mushroom).width / 2), @list.formatting[3] + (y * @list.formatting[1]), self.contents.text_size(mushroom).width + (@list.formatting[4] * 2)]
moose += 1
end
end
def check_title_codes(text)
fn = nil
fs = nil
fc = nil
text.gsub!(/\\[Ff][Nn]\[([0-9]+)\]/) do
fn = title_fonts($1.to_i)
""
end
text.gsub!(/\\[Ff][Ss]\[([0-9]+)\]/) do
fs = $1.to_i
""
end
text.gsub!(/\\[Ff][Cc]\[([0-9]+),([0-9]+),([0-9]+)\]/) do
fc = Color.new($1.to_i, $2.to_i, $3.to_i)
""
end
return [fn, fs, fc]
end
def page_left
end
def page_right
end
def page_left_many
end
def page_right_many
end
def title_fonts(type)
case type
when 0
return Font.default_name
when 1
return "Verdana"
end
end
end
Message Codes and Instruction Types
Code:
class Quest_Window < Window_Base
def draw_description
case @mode[0]
when 0
@index[2] = $game_party.quests.order[@list.categories[@indexvals[@index[0]]][1]][@index[1]]
when 1
@index[2] = $game_party.quests.order[@mode[1]][@index[1]]
when 2
@index[2] = @mode[1]
end
quest = $game_party.quests.quests[@index[2]]
pages = []
page_graphics = @list.page_graphics.dup
for line in quest.description
pages.push(line[1][0])
next unless @page[2] == line[1][0]
case line[0]
when 0 # Draw Text
x = line[1][1][0]
y = line[1][1][1]
t1 = line[1][2].dup
fc = line[1][3]
fs = line[1][4]
ft = line[1][5]
fc = @list.font[1][2] if fc.nil?
fs = @list.font[1][1] if fs.nil?
ft = @list.font[1][0] if ft.nil?
self.contents.font.color = fc
self.contents.font.size = fs
self.contents.font.name = ft
t = check_codes(t1)
h = self.contents.text_size(t).height
self.contents.draw_text(x, y, 1000, h, t)
when 1 # Draw Graphic
x = line[1][1][0]
y = line[1][1][1]
w = line[1][1][2]
h = line[1][1][3]
o = line[1][1][4]
w = 1.0 if w.nil?
h = 1.0 if h.nil?
o = 255 if o.nil?
gt = line[1][2][0]
gn = line[1][2][1]
if gt == 0
bitmap = RPG::Cache.icon(gn)
elsif gt == 1
bitmap = RPG::Cache.picture(gn)
end
self.contents.stretch_blt(Rect.new(x, y, bitmap.width * w, bitmap.height * h), bitmap, Rect.new(0, 0, bitmap.width, bitmap.height), o)
when 2 # Draw battler
x = line[1][1][0]
y = line[1][1][1]
o = line[1][1][2]
o = 255 if o.nil?
if line[1][2][0] == 0
actor = $game_actors[line[1][2][1]]
elsif line[1][2][0] == 1
actor = $data_enemies[line[1][2][1]]
end
case $game_party.quests.settings[1]
when 0 # Jaber's animation system [page, [x, y, opacity], [actor/enemy, id], pose, frame]
graphic = actor.battle_graphic + actor.stance + line[1][3]
bitmap = RPG::Cache.battler(graphic, 0)
self.contents.blt(x - ((bitmap.width / $game_temp.pose_frames(graphic)) / 2), y - bitmap.height, bitmap,
Rect.new(((bitmap.width / $game_temp.pose_frames(graphic)) * line[1][4]), 0, bitmap.width / $game_temp.pose_frames(graphic), bitmap.height), o)
if line[1][2][0] == 0
equip_graphics = []
eqind = -1
for equip in actor.slot_data
eqind += 1
equip_data = $game_temp.get_data(actor.equipment[eqind])
next if equip_data == nil or equip_data.battle_graphic == nil
hand = eqind == 0 ? "_R" : eqind == 1 ? "_L" : "_"
equip_pic = actor.battle_graphic + actor.stance + hand + equip_data.battle_graphic + line[1][3]
equip_graphics.push([equip_data.priority, equip_pic])
end
equip_graphics.sort!
for equip in equip_graphics
bitmap = RPG::Cache.battler(equip[1], 0)
if bitmap.nil?
p equip[1]
next
end
self.contents.blt(x - ((bitmap.width / $game_temp.pose_frames(graphic)) / 2), y - bitmap.height, bitmap,
Rect.new(((bitmap.width / $game_temp.pose_frames(graphic)) * line[1][4]), 0, bitmap.width / $game_temp.pose_frames(graphic), bitmap.height), o)
end
end
when 1 # Minkoff's animation system [page, [x, y], [actor/enemy, id], pose#, frame#]
if line[1][2][0] == 0
bitmap = RPG::Cache.battlers(actor.battler_name, actor.battler_hue)
o = MNK_TRANSLUCENCY if MNK_TRANSLUCENT_ACTOR.include?(actor.id)
if DEFAULT_ACTOR or DEFAULT_ACTOR_ID.include?(actor.id)
x_div = 1
y_div = 1
pose = 0
frame = 0
else
x_div = MNK_FRAMES
y_div = MNK_POSES
if MNK_FRAMES_ACTOR != nil and MNK_FRAMES_ACTOR[actor.id] != nil
x_div = MNK_FRAMES_ACTOR[actor.id]
end
if MNK_POSES_ACTOR != nil and MNK_POSES_ACTOR[actor.id] != nil
y_div = MNK_POSES_ACTOR[actor.id]
end
# WHY COULDN'T YOU MAKE THE POSE CRAP EASIER DVV D:
pose = line[1][3]
frame = line[1][4]
case line[1][3]
when 0
pose = MNK_APOSE1[actor.id] if MNK_APOSE1[actor.id] != nil
when 1
pose = MNK_APOSE2[actor.id] if MNK_APOSE2[actor.id] != nil
when 2
pose = MNK_APOSE3[actor.id] if MNK_APOSE3[actor.id] != nil
when 3
pose = MNK_APOSE4[actor.id] if MNK_APOSE4[actor.id] != nil
when 4
pose = MNK_APOSE5[actor.id] if MNK_APOSE5[actor.id] != nil
when 5
pose = MNK_APOSE6[actor.id] if MNK_APOSE6[actor.id] != nil
when 6
pose = MNK_APOSE7[actor.id] if MNK_APOSE7[actor.id] != nil
when 7
pose = MNK_APOSE8[actor.id] if MNK_APOSE8[actor.id] != nil
when 8
pose = MNK_APOSE9[actor.id] if MNK_APOSE9[actor.id] != nil
when 9
pose = MNK_APOSE10[actor.id] if MNK_APOSE10[actor.id] != nil
when 10
pose = MNK_APOSE11[actor.id] if MNK_APOSE11[actor.id] != nil
end
if MNK_FRAMES_PER_POSE[pose] != nil
x_div = MNK_FRAMES_PER_POSE[pose]
end
# I DON'T KNOW HOW THE MNK_POSES_FR_ THING WORKS SORRY
end
elsif line[1][2][0] == 1
bitmap = RPG::Cache.battlers(actor.battler_name, actor.battler_hue)
o = MNK_TRANSLUCENCY if MNK_TRANSLUCENT_ENEMY.include?(actor.id)
if DEFAULT_ENEMY or DEFAULT_ENEMY_ID.include?(actor.id)
x_div = 1
y_div = 1
pose = 0
frame = 0
else
x_div = MNK_FRAMES
y_div = MNK_POSES
if MNK_FRAMES_ENEMY != nil and MNK_FRAMES_ENEMY[actor.id] != nil
x_div = MNK_FRAMES_ENEMY[actor.id]
end
if MNK_POSES_ENEMY != nil and MNK_POSES_ENEMY[actor.id] != nil
y_div = MNK_POSES_ENEMY[actor.id]
end
pose = line[1][3]
frame = line[1][4]
case line[1][3]
when 0
pose = MNK_EPOSE1[actor.id] if MNK_EPOSE1[actor.id] != nil
when 1
pose = MNK_EPOSE2[actor.id] if MNK_EPOSE2[actor.id] != nil
when 2
pose = MNK_EPOSE3[actor.id] if MNK_EPOSE3[actor.id] != nil
when 3
pose = MNK_EPOSE4[actor.id] if MNK_EPOSE4[actor.id] != nil
when 4
pose = MNK_EPOSE5[actor.id] if MNK_EPOSE5[actor.id] != nil
when 5
pose = MNK_EPOSE6[actor.id] if MNK_EPOSE6[actor.id] != nil
when 6
pose = MNK_EPOSE7[actor.id] if MNK_EPOSE7[actor.id] != nil
when 7
pose = MNK_EPOSE8[actor.id] if MNK_EPOSE8[actor.id] != nil
when 8
pose = MNK_EPOSE9[actor.id] if MNK_EPOSE9[actor.id] != nil
when 9
pose = MNK_EPOSE10[actor.id] if MNK_EPOSE10[actor.id] != nil
when 10
pose = MNK_EPOSE11[actor.id] if MNK_EPOSE11[actor.id] != nil
end
end
end
self.contents.blt(x, y, bitmap, Rect.new((bitmap.width / x_div) * frame, (bitmap.height / y_div) * pose, bitmap.width / x_div, bitmap.height / y_div), o)
when 2 # Default battlers [page, [x, y, opacity], [actor/enemy, id]]
bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
self.contents.blt(x, y, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height), o)
end
when 3 # Draw Characterset [page, [x, y, opacity], [type, data], [#frames, #directions, facing, frame]]
case line[1][2][0] # For type:
when 0 # Use actor ID, [0, actor id]
cn = $game_actors[line[1][2][1]].character_name
ch = $game_actors[line[1][2][1]].character_hue
when 1 # Use filename, [1, filename, hue number]
cn = line[1][2][1]
ch = line[1][2][2]
end
x = line[1][1][0]
y = line[1][1][1]
o = line[1][1][2]
o = 255 if o.nil?
w = line[3][0]
h = line[3][1]
d = line[3][2]
f = line[3][3]
bitmap = RPG::Cache.character(cn, ch)
self.contents.blt(x, y, bitmap, Rect.new(x + ((bitmap.width / w) * f), y + ((bitmap.height / h) * d),
bitmap.width / w, bitmap.height / h), o)
#
end
end
count = -1
for line in quest.objectives
count += 1
obj = quest.stages[count]
next if obj == 0
pages.push(line[2][0])
next unless @page[2] == line[2][0]
case line[0]
when 0 # Draw Text
x = line[2][1][0]
y = line[2][1][1]
t1 = line[2][2][obj-1].dup
fc = line[2][3]
fs = line[2][4]
ft = line[2][5]
fc = @list.font[1][2] if fc.nil?
fs = @list.font[1][1] if fs.nil?
ft = @list.font[1][0] if ft.nil?
self.contents.font.color = fc
self.contents.font.size = fs
self.contents.font.name = ft
t = check_codes(t1)
h = self.contents.text_size(t).height
self.contents.draw_text(x, y, 1000, h, t)
when 1 # Draw Graphic
x = line[2][1][0]
y = line[2][1][1]
w = line[2][1][2]
h = line[2][1][3]
o = line[2][1][4]
w = 1.0 if w.nil?
h = 1.0 if h.nil?
o = 255 if o.nil?
gt = line[2][2][obj-1][0]
gn = line[2][2][obj-1][1]
if gt == 0
bitmap = RPG::Cache.icon(gn)
elsif gt == 1
bitmap = RPG::Cache.picture(gn)
end
self.contents.stretch_blt(Rect.new(x, y, bitmap.width * w, bitmap.height * h), bitmap, Rect.new(0, 0, bitmap.width, bitmap.height), o)
when 2 # Draw battler
x = line[2][1][0]
y = line[2][1][1]
o = line[1][1][2]
o = 255 if o.nil?
if line[2][2][obj-1][0] == 0
actor = $game_actors[line[2][2][obj-1][1]]
elsif line[2][2][obj-1][0] == 1
actor = $data_enemies[line[2][2][obj-1][1]]
end
case $game_party.quests.settings[1]
when 0 # Jaber's animation system
graphic = actor.battle_graphic + actor.stance + line[2][3][obj-1]
bitmap = RPG::Cache.battler(graphic, 0)
self.contents.blt(x - ((bitmap.width / $game_temp.pose_frames(graphic)) / 2), y - bitmap.height, bitmap,
Rect.new(((bitmap.width / $game_temp.pose_frames(graphic)) * line[2][4][obj-1]), 0, bitmap.width / $game_temp.pose_frames(graphic), bitmap.height), o)
if line[1][1][obj-1][0] == 0
equip_graphics = []
eqind = -1
for equip in actor.slot_data
eqind += 1
equip_data = $game_temp.get_data(actor.equipment[eqind])
next if equip_data == nil or equip_data.battle_graphic == nil
hand = eqind == 0 ? "_R" : eqind == 1 ? "_L" : "_"
equip_pic = actor.battle_graphic + actor.stance + hand + equip_data.battle_graphic + line[2][3][obj-1]
equip_graphics.push([equip_data.priority, equip_pic])
end
equip_graphics.sort!
for equip in equip_graphics
bitmap = RPG::Cache.battler(equip[1], 0)
if bitmap.nil?
p equip[1]
next
end
self.contents.blt(x - ((bitmap.width / $game_temp.pose_frames(graphic)) / 2), y - bitmap.height, bitmap,
Rect.new(((bitmap.width / $game_temp.pose_frames(graphic)) * line[2][4][obj-1]), 0, bitmap.width / $game_temp.pose_frames(graphic), bitmap.height), o)
end
end
when 1 # Minkoff's animation system [page, [x, y], [actor/enemy, id], pose#, frame#]
if line[1][2][obj-1][0] == 0
bitmap = RPG::Cache.battlers(actor.battler_name, actor.battler_hue)
o = MNK_TRANSLUCENCY if MNK_TRANSLUCENT_ACTOR.include?(actor.id)
if DEFAULT_ACTOR or DEFAULT_ACTOR_ID.include?(actor.id)
x_div = 1
y_div = 1
pose = 0
frame = 0
else
x_div = MNK_FRAMES
y_div = MNK_POSES
if MNK_FRAMES_ACTOR != nil and MNK_FRAMES_ACTOR[actor.id] != nil
x_div = MNK_FRAMES_ACTOR[actor.id]
end
if MNK_POSES_ACTOR != nil and MNK_POSES_ACTOR[actor.id] != nil
y_div = MNK_POSES_ACTOR[actor.id]
end
pose = line[1][3][obj-1]
frame = line[1][4][obj-1]
case line[1][3]
when 0
pose = MNK_APOSE1[actor.id] if MNK_APOSE1[actor.id] != nil
when 1
pose = MNK_APOSE2[actor.id] if MNK_APOSE2[actor.id] != nil
when 2
pose = MNK_APOSE3[actor.id] if MNK_APOSE3[actor.id] != nil
when 3
pose = MNK_APOSE4[actor.id] if MNK_APOSE4[actor.id] != nil
when 4
pose = MNK_APOSE5[actor.id] if MNK_APOSE5[actor.id] != nil
when 5
pose = MNK_APOSE6[actor.id] if MNK_APOSE6[actor.id] != nil
when 6
pose = MNK_APOSE7[actor.id] if MNK_APOSE7[actor.id] != nil
when 7
pose = MNK_APOSE8[actor.id] if MNK_APOSE8[actor.id] != nil
when 8
pose = MNK_APOSE9[actor.id] if MNK_APOSE9[actor.id] != nil
when 9
pose = MNK_APOSE10[actor.id] if MNK_APOSE10[actor.id] != nil
when 10
pose = MNK_APOSE11[actor.id] if MNK_APOSE11[actor.id] != nil
end
if MNK_FRAMES_PER_POSE[pose] != nil
x_div = MNK_FRAMES_PER_POSE[pose]
end
end
elsif line[1][2][obj-1][0] == 1
bitmap = RPG::Cache.battlers(actor.battler_name, actor.battler_hue)
o = MNK_TRANSLUCENCY if MNK_TRANSLUCENT_ENEMY.include?(actor.id)
if DEFAULT_ENEMY or DEFAULT_ENEMY_ID.include?(actor.id)
x_div = 1
y_div = 1
pose = 0
frame = 0
else
x_div = MNK_FRAMES
y_div = MNK_POSES
if MNK_FRAMES_ENEMY != nil and MNK_FRAMES_ENEMY[actor.id] != nil
x_div = MNK_FRAMES_ENEMY[actor.id]
end
if MNK_POSES_ENEMY != nil and MNK_POSES_ENEMY[actor.id] != nil
y_div = MNK_POSES_ENEMY[actor.id]
end
pose = line[1][3][obj-1]
frame = line[1][4][obj-1]
case line[1][3][obj-1]
when 0
pose = MNK_EPOSE1[actor.id] if MNK_EPOSE1[actor.id] != nil
when 1
pose = MNK_EPOSE2[actor.id] if MNK_EPOSE2[actor.id] != nil
when 2
pose = MNK_EPOSE3[actor.id] if MNK_EPOSE3[actor.id] != nil
when 3
pose = MNK_EPOSE4[actor.id] if MNK_EPOSE4[actor.id] != nil
when 4
pose = MNK_EPOSE5[actor.id] if MNK_EPOSE5[actor.id] != nil
when 5
pose = MNK_EPOSE6[actor.id] if MNK_EPOSE6[actor.id] != nil
when 6
pose = MNK_EPOSE7[actor.id] if MNK_EPOSE7[actor.id] != nil
when 7
pose = MNK_EPOSE8[actor.id] if MNK_EPOSE8[actor.id] != nil
when 8
pose = MNK_EPOSE9[actor.id] if MNK_EPOSE9[actor.id] != nil
when 9
pose = MNK_EPOSE10[actor.id] if MNK_EPOSE10[actor.id] != nil
when 10
pose = MNK_EPOSE11[actor.id] if MNK_EPOSE11[actor.id] != nil
end
end
end
self.contents.blt(x, y, bitmap, Rect.new((bitmap.width / x_div) * frame, (bitmap.height / y_div) * pose, bitmap.width / x_div, bitmap.height / y_div), o)
when 2 # Default battlers
bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
self.contents.blt(x, y, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height), o)
end
when 3 # Draw Characterset
case line[1][2][obj-1][0]
when 0 # Use actor ID
cn = $game_actors[line[1][2][obj-1][1]].character_name
ch = $game_actors[line[1][2][obj-1][1]].character_hue
when 1 # Use filename
cn = line[1][2][obj-1][1]
ch = line[1][2][obj-1][2]
end
x = line[1][1][0]
y = line[1][1][1]
o = line[1][1][2]
o = 255 if o.nil?
w = line[3][0][obj-1]
h = line[3][1][obj-1]
d = line[3][2][obj-1]
f = line[3][3][obj-1]
bitmap = RPG::Cache.character(cn, ch)
self.contents.blt(x, y, bitmap, Rect.new(x + ((bitmap.width / w) * f), y + ((bitmap.height / h) * d),
bitmap.width / w, bitmap.height / h), o)
#
end
end
@pagemax[2] = pages.max
if @page[2] + 1 <= @pagemax[2]
bitmap = RPG::Cache.picture(page_graphics[1])
self.contents.blt(self.contents.width - bitmap.width, self.contents.height - bitmap.height, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height))
end
if @page[2] > 0
bitmap = RPG::Cache.picture(page_graphics[0])
self.contents.blt(0, self.contents.height - bitmap.height, bitmap, Rect.new(0, 0, bitmap.width, bitmap.height))
end
end
def check_codes(text)
text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
text.gsub!(/\\[Ss]\[([0-9]+),([\w\s]*),([\w\s]*)\]/) { $game_switches[$1.to_i] == true ? $2 : $3 }
text.gsub!(/\\[Gg]/) { $game_party.gold }
text.gsub!(/\\[Qq][Vv]\[([\w\s]*)\]/) { $game_party.quests.quests[@index[2]].data[$1] }
text.gsub!(/\\[Ii][Tt][Ee][Mm]\[([0-9]+)\]/) { $data_items[$1.to_i].name }
text.gsub!(/\\[Ww][Ee][Aa][Pp][Oo][Nn]\[([0-9]+)\]/) { $data_weapons[$1.to_i].name }
text.gsub!(/\\[Aa][Rr][Mm][Oo][Rr]\[([0-9]+)\]/) { $data_armors[$1.to_i].name }
text.gsub!(/\\[Ss][Kk][Ii][Ll][Ll]\[([0-9]+)\]/) { $data_skills[$1.to_i].name }
text.gsub!(/\\[Aa][Cc][Tt][Oo][Rr]\[([0-9]+)\]/) { $data_actors[$1.to_i].name }
text.gsub!(/\\[Ee][Nn][Ee][Mm][Yy]\[([0-9]+)\]/) { $data_enemies[$1.to_i].name }
text.gsub!(/\\[Cc][Ll][Aa][Ss][Ss]\[([0-9]+)\]/) { $data_classes[$1.to_i].name }
text.gsub!(/\\[Aa][Cc][Ll][Aa][Ss][Ss]\[([0-9]+)\]/) { $data_classes[$game_actors[$1.to_i].class_id].name }
case $game_party.quests.settings[0]
when 0 # For my inventory grid [mode, bag index, type, id]
text.gsub!(/\\[Hh][Ee][Ll][Dd]\[([01]),([0-9]+),([0-9]+),([0-9]+)\]/) do
if $1.to_i == 0 # Use $game_party
case $2.to_i
when 0 # Party item bag
$game_party.item_bag.item_amount([$3.to_i, $4.to_i]).to_s
else
$game_party.actors[$2.to_i].item_bag.item_amount([$3.to_i, $4.to_i]).to_s
end
elsif $1.to_i == 1 # Use $game_actors
$game_actors[$2.to_i].item_bag.item_amount([$3.to_i, $4.to_i]).to_s
end
end
when 1 # For everyone else's less insane inventory systems [type, id]
text.gsub!(/\\[Ii][Hh][Ee][Ll][Dd]\[([012]),([0-9]+)\]/) do
case $1.to_i
when 0 # Items
$game_party.item_number($2.to_i).to_s
when 1 # Weapons
$game_party.weapon_number($2.to_i).to_s
when 2 # Armor
$game_party.armor_number($2.to_i).to_s
end
end
end
text.gsub!(/\\[Ss][Tt][Aa][Tt]\[([012]),([0-9]+),(\w*)\]/) do
case $1.to_i
when 0
chara = $game_party.actors[$2.to_i]
when 1
chara = $game_actors[$2.to_i]
when 2
chara = $data_enemies[$2.to_i]
end
case $3
when "hp"
chara.hp.to_s
when "maxhp"
chara.maxhp.to_s
when "sp"
chara.sp.to_s
when "maxsp"
chara.maxsp.to_s
when "bmaxhp"
chara.base_maxhp.to_s
when "bmaxsp"
chara.base_maxsp.to_s
when "atk"
chara.base_atk.to_s
when "str"
chara.base_str.to_s
when "int"
chara.base_int.to_s
when "dex"
chara.base_dex.to_s
when "agi"
chara.base_agi.to_s
when "pdef"
chara.base_pdef.to_s
when "mdef"
chara.base_mdef.to_s
when "eva"
chara.base_eva.to_s
# Don't use any of the following or your game will asplode.
when "tp"
chara.tp.to_s
when "atk0"
chara.base_atk(0).to_s
when "atk1"
chara.base_atk(1).to_s
when "dmg0"
chara.basedmg(0).to_s
when "dmg1"
chara.basedmg(1).to_s
when "mdmg0"
chara.magdmg(0).to_s
when "mdmg1"
chara.magdmg(1).to_s
when "acc"
chara.base_acc.to_s
when "altdmg0"
chara.altbasedmg(0).to_s
when "altdmg1"
chara.altbasedmg(1).to_s
when "delay"
chara.delay.to_s
when "matk0"
chara.base_matk(0).to_s
when "matk1"
chara.base_matk(1).to_s
when "macc"
chara.base_macc.to_s
else
""
end
end
return text
end
end
Setup
Here's a few pictures for you to use for the background:
Book graphic
First version of the book graphic in blinding white (Size is off by like 1 pixel)
And here's some crappy next/previous page pictures:
Alright, onto the setup.
In Scene_Title, locate the following line:
$game_system = Game_System.new
In the default title, it should be on line 32.
Add this line right below it:
$game_system.load_quest_data
Next, stick the following anywhere below Game_Party:
Code:
class Game_Party
attr_accessor :quests
alias eveningguvnr initialize
def initialize
eveningguvnr
@quests = Quest_List.new
end
end
To call the quest window, simply use
Quest_Window.new(x, y, z, list key, selfupdate, mode)
x, y, and z are the coordinates, obviously.
Don't know what a list key is? Read the instructions below.
selfupdate and mode are optional.
If selfupdate is set to true, the window will function as it's own scene of sorts, meaning you could, say, call it from an event on the map without interrupting Scene_Map. If you don't know what that means, you'll probably want to have this set to true all the time.
mode is an array that lets you... 'skip' sections of the quest window.
Here's the various settings for it:
[0]
This is the default setting for the mode. It'll open up to the specified list.
[1, category key, headertext]
This will skip the category list and open up a category directly. 'headertext' is what will be displayed at the top of the first page. You still need to specify a list key, as it'll use that for formatting. Useful if you, say... don't want to use the category seperation feature. You'd be able to use a category as the entire quest log, if you wanted.
[2, quest key]
This will skip everything and jump right to a quest. Usefor for things like books or notes laying around.
What the crap post size limit D8