Code:
# * KDiurnalis XP
# Scripter : Kyonides Arkanthes
# v 1.0.5 - 2022-06-16
# * Non Plug & Play Script * #
# The Party's Journal Script!
# Tweak this script's CONSTANTS in order to customize the Journal Menu's GUI.
# You can find them under the KDiurnalis module.
# * Aliased Method * #
# Scene_Load#on_decision
# * Script Calls * #
# - Open Journal Scene - 2 Options
# $scene = KDiurnalis::Scene.new
# KDiurnalis.open!
# - Add New Journal Page Steps - #
# -- Step 1
# Location: can be replaced with a "String" or :map for current map name.
# $game_party.add_journal_entry("Title", Location)
# -- Step 2
# Add as many Message Windows and lines of text as you wish!
# -- Step 3
# - Stop Using Message Windows as Journal Entry's Page Contents
# Simply stop adding any more message windows!
module KDiurnalis
LOAD_OPENS_JOURNAL = true
SHOW_DATES = nil
# Place the Backdrop in the Titles directory.
# Options: "Filename" or nil
BACKDROP = "backdrop circles blue"
TITLE = "%s's Journal"
TITLE_ALIGN = 1
NO_ENTRY = "No Entry Found"
module Start
TITLE = "My New Adventure"
LOCATION = "Home"
TEXT = []
TEXT << "My history begins today."
TEXT << "I am very excited indeed."
end
PAGES_FOUND = "%s Pages Found"
PAGES_LABEL = "Page %s/%s"
PAGES_LABEL_ALIGN = 2
HELP_WIN_OPACITY = 160
# Window's Coordinates = [X, Y, Width, Height, Opacity]
LIST_WIN_COORD = [16, 84, 180, 384, 160]
DUMMY_WIN_COORD = [224, 84, 388, 84, 160]
INFO_WIN_COORD = [224, 84, 388, 352, 160]
# * End of Setup * #
extend self
attr_accessor :use_message_window
def open!() $scene = Scene.new end
def after_load_scene
open! if LOAD_OPENS_JOURNAL
end
def end_of_entry!() @use_message_window = nil end
alias :end_of_message! :end_of_entry!
class KDJournal
def initialize
@dates = []
date = KDDate.new
entry = KDEntry.new(Start::TITLE.dup)
entry.location = Start::LOCATION
entry.texts = Start::TEXT.dup
date.add_entry(entry)
add_date(date)
end
def add_date(date)
@dates.unshift(date)
@last_date = date
end
def map(&blk) @dates.map(&blk) end
def last() @dates[-1] end
def [](pos) @dates[pos] end
def empty?() @dates.empty? end
def any?() @dates.any? end
def size() @dates.size end
attr_reader :dates, :last_date
end
class KDDate
def initialize
time = Time.now
@year = time.year
@month = time.month
@month_name = time.strftime("%b")
@day = time.mday
@day_name = time.strftime("%a")
@title = "#{@month_name} #{@day}, #{@year}"
@entries = []
end
def same_date?(nyear, nmonth, nday)
nyear == @year && nmonth == @month && nday == @day
end
def add_entry(entry)
@entries << entry
@last_entry = entry
end
attr_reader :year, :month, :month_name, :day, :day_name, :entries, :last_entry
attr_accessor :title
end
class KDEntry
def initialize(new_title)
@title = new_title
@location = ""
@texts = []
end
attr_reader :title
attr_accessor :texts, :location
end
class KDHelpWindow < Window_Base
def initialize
x, w = 80, Graphics.width
super(x, 12, w - x * 2, 56)
self.contents = Bitmap.new(width - 32, height - 32)
end
def set_text(text, align=0)
return if text == @text or align == @align
@text = text
@align = align
refresh
end
def refresh
contents.clear
contents.draw_text(0, 0, width - 32, 24, @text, @align)
end
end
class KDListWindow < Window_Selectable
def initialize(wx, wy, w, h)
@data = []
super
@data = $game_party.journal_entries
@item_max = @data.size
refresh
@index = 0
end
def draw_item(index)
item = @data[index]
contents.draw_text(4, index * 32, width - 32, 32, item.title)
end
def refresh
self.contents = Bitmap.new(width - 32, row_max * 32)
@item_max.times{|i| draw_item(i) }
end
def update_help() @help_window.index = @index end
def item() @data[@index] end
end
class KDDummyWindow < Window_Base
def initialize(wx, wy, w, h)
super
@index = 0
self.contents = Bitmap.new(width - 32, h - 32)
refresh
end
def refresh
contents.clear
date = $game_party.journal_entries[@index]
pages = sprintf(PAGES_FOUND, date.entries.size)
contents.draw_text(0, 0, width - 32, 24, pages)
end
def index=(pos)
return if @index == pos
@index = pos
refresh
end
end
class KDInfoWindow < Window_Base
def show_entries(entry)
self.visible = true
@entries = entry
@total = @entries.size
@index = @total - 1
@entry = @entries.last
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
def refresh
contents.clear
w = width - 32
f = contents.font
f.bold = true
contents.draw_text(0, 0, w, 24, @entry.title, 1)
contents.draw_text(4, 32, w, 24, @entry.location)
f.bold = false
ly = 64
@entry.texts.each do |text|
contents.draw_text(4, ly, w, 24, text)
ly += 24
end
ly = height - 56
pages = sprintf(PAGES_LABEL, @index + 1, @entries.size)
contents.draw_text(0, ly, w, 24, pages, PAGES_LABEL_ALIGN)
end
def update
if Input.trigger?(Input::LEFT)
return $game_system.se_play($data_system.buzzer_se) if @total == 1
$game_system.se_play($data_system.cursor_se)
@index = (@index - 1) % @total
@entry = @entries[@index]
refresh
return
elsif Input.trigger?(Input::RIGHT)
return $game_system.se_play($data_system.buzzer_se) if @total == 1
$game_system.se_play($data_system.cursor_se)
@index = (@index + 1) % @total
@entry = @entries[@index]
refresh
end
end
def clear() contents.clear end
end
class Scene
def main
start
Graphics.transition
while @stage
Graphics.update
Input.update
update
end
Graphics.freeze
terminate
end
def start
@stage = SHOW_DATES ? :list : :info
lx, ly, lw, lh, lbo = LIST_WIN_COORD
dx, dy, dw, dh, dbo = DUMMY_WIN_COORD
ix, iy, iw, ih, ibo = INFO_WIN_COORD
if BACKDROP
@backdrop = Sprite.new
@backdrop.bitmap = RPG::Cache.title(BACKDROP).dup
else
@backdrop = Spriteset_Map.new
end
@help_window = KDHelpWindow.new
text = sprintf(TITLE, $game_party.leader.name)
@help_window.set_text(text, TITLE_ALIGN)
@help_window.back_opacity = HELP_WIN_OPACITY
@list_window = KDListWindow.new(lx, ly, lw, lh)
@list_window.back_opacity = lbo
@list_window.visible = SHOW_DATES
@dummy_window = KDDummyWindow.new(dx, dy, dw, dh)
@dummy_window.back_opacity = dbo
@dummy_window.visible = SHOW_DATES
@list_window.help_window = @dummy_window
@info_window = KDInfoWindow.new(ix, iy, iw, ih)
@info_window.back_opacity = ibo
@info_window.visible = !SHOW_DATES
open_last_entry
end
def open_last_entry
if SHOW_DATES
date = @list_window.item
@info_window.show_entries(date.entries)
else
entries = $game_party.journal_entries.map{|date| date.entries }
entries = entries.flatten
@info_window.show_entries(entries)
end
@stage = :info
end
def terminate
@help_window.dispose
@list_window.dispose
@dummy_window.dispose
@info_window.dispose
@backdrop.bitmap.dispose if BACKDROP
@backdrop.dispose
end
def update
case @stage
when :list
update_list
when :info
update_info
end
end
def update_list
@list_window.update
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
return @stage = nil
elsif Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
@dummy_window.visible = false
open_last_entry
end
end
def update_info
@info_window.update
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
unless SHOW_DATES
$scene = Scene_Map.new
return @stage = nil
end
@info_window.visible = false
@info_window.clear
@dummy_window.visible = true
@stage = :list
end
end
end
end
unless $HIDDENCHEST or $MKXP
module Graphics
def self.width() 640 end
def self.height() 480 end
end
end
class Game_Party
alias :kyon_diurnalis_gm_pty_init :initialize
def initialize
kyon_diurnalis_gm_pty_init
@journal_entries = KDiurnalis::KDJournal.new
end
def add_journal_entry(title, place)
place = $game_map.map_name if place == :map
date = @journal_entries.last_date
time = Time.now
KDiurnalis.use_message_window = true
entry = KDiurnalis::KDEntry.new(title)
entry.location = place
if date and date.same_date?(time.year, time.month, time.day)
date.add_entry(entry)
else
date = KDiurnalis::KDDate.new
date.add_entry(entry)
@journal_entries.add_date(date)
end
end
def total_journal_entries?(n)
@journal_entries.size == n
end
def last_journal_entry_pages?(n)
@journal_entries.last.entries.size == n
end
def leader() @actors[0] end
attr_reader :journal_entries
end
class Game_Map
alias :kyon_diurnalis_gm_map_setup :setup
def setup(map_id)
kyon_diurnalis_gm_map_setup(map_id)
@map_name = load_data("Data/MapInfos.rxdata")[map_id].name
end
attr_reader :map_name
end
class Game_Event
def name() @event.name end
def name=(text) @event.name = text end
end
class Interpreter
alias :kyon_diurnalis_gm_int_comm_101 :command_101
def process_journal_entries
date = $game_party.journal_entries.last_date
entry = date.last_entry
command = @list[@index]
codes = [101, 401]
while codes.include?(command.code)
line = command.parameters[0]
line.gsub!(/\\N\[([0-9]+)\]/i) { $game_actors[$1.to_i].name }
line.gsub!(/\\E\[([0-9]+)\]/i) { $game_map.events[$1.to_i].name }
entry.texts << line
@index += 1
command = @list[@index]
end
KDiurnalis.end_of_message!
false
end
def command_101
if KDiurnalis.use_message_window
process_journal_entries
else
kyon_diurnalis_gm_int_comm_101
end
end
end
class Scene_Load
alias :kyon_diurnalis_scn_load_on_dec on_decision
def on_decision(filename)
kyon_diurnalis_scn_load_on_dec(filename)
KDiurnalis.after_load_scene
end
end