[XP] Diary

Started by ForeverZer0, December 18, 2010, 03:14:01 pm

Previous topic - Next topic

ForeverZer0

December 18, 2010, 03:14:01 pm Last Edit: January 07, 2014, 03:34:37 pm by KK20
Diary
Authors: ForeverZer0
Version: 1.11
Type: Misc Add-on
Key Term: Misc Add-on



Introduction

This is a basic script that will allow you to keep a "diary" or notepad in your game. It is very simple to use, and uses a simple interface for displaying the notes.


Features


  • Group your notes into "chapters".
  • Automatically formats text to fit on each line in a legible format.
  • Simple script call to add text.
  • Option to define each note in the script editor, then simply use a script call to add it.
  • Option to use the map as the background.



Screenshots

None.


Demo

None.


Script

Here's the script.
Spoiler: ShowHide

#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Diary Scene
# Author: ForeverZer0
# Version: 1.11
# Date: 1.17.2014
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#
# Introduction:
#
#   This is a basic script that will allow you to keep a "diary" or notepad in
#   your game. It is very simple to use, and uses a simple interface for
#   displaying the notes.
#
# Features:
#
#   - Group your notes into "chapters". 
#   - Automatically formats text to fit on each line in a legible format.
#   - Simple script call to add text.
#   - Option to define each note in the script editor, then simply use a script
#     call to add it.
#   - Option to use the map as the background.
#
# Instructions:
#
#   - Place script above main, and below default scripts.
#   - Make configurations below.
#   - To call the scene, use this syntax:  $scene = Scene_Diary.new
#   - To add an entry, use this syntax:
#
#     Diary.add_entry(CHAPTER, TEXT)
#     
#     CHAPTER: An arbitrary integer to define what group to add the note to.
#     TEXT: Either a string which will be the text added to the diary, or an
#           integer which will return the string defined in the configuration
#           below. The second method will make it easier to make long notes
#           without filling up the little script call box.
#
# Author's Notes:
#
#  - Please be sure to report any bugs/issues with the script. Enjoy!
#
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

module Diary
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#                         BEGIN CONFIGURATION
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  MAP_BACKGROUND = true
  # Set to true if you would like the map to show behind the window.
  RETURN_SCENE = Scene_Map
  # The scene that the game returns to when you exit the diary.
  SCENE_ARGUMENTS = []
  # Define any arguments that may need called with scene if need be. Place them
  # in the array in the order in which they are normally called.
 
  def self.chapter_name(chapter)
    # Define the names of the "chapters".
    # when CHAPTER then "CHAPTER_NAME"
    return case chapter
    when 1 then 'Millenium Fair'
    when 2 then 'What Happened to Marle?'
    end
  end
 
  def self.entry(index)
    # Define the strings that correspond with each index. The index can be called
    # instead of actual text to add an entry.
    # when INDEX then "TEXT"
    return case index
    when 0 then 'I forgot today was the day of the big fair!I was supposed to go and see
Lucca\'s new invention.'
    when 1 then 'I need to escort Marle around the fair, and maybe play a few games.'
    when 2 then 'Marle was sucked into the vortex. I think it had something to do with
that pendant that she was wearing...'
    when 3 then 'This place is very strange, and everyone talks funny. It\'s all vaguely
the same, yet different. Where am I?'
    when 4 then 'Here\'s how you can skip lines.\n\nThat made a line break. Now to see
your value stored in variable 5: \v[5]'
    end
  end

#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#                           END CONFIGURATION
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
  def self.add_entry(chapter, text)
    # Add the chapter number if it does not exist.
    if $game_party.diary[chapter] == nil
      $game_party.diary[chapter] = []
    end
    if text.is_a?(String)
      # Add the new entry to the end of the chapter.
      $game_party.diary[chapter].push(text)
    elsif text.is_a?(Integer)
      # Get the defined note if the text is a number.
      $game_party.diary[chapter].push(self.entry(text))
    end
  end
end

#===============================================================================
# ** Window_Diary
#===============================================================================

class Window_Diary < Window_Base
 
  attr_reader :lines
 
  def initialize
    super(0, 64, 640, 416)
    self.back_opacity = Diary::MAP_BACKGROUND ? 160 : 255
    self.contents = Bitmap.new(width - 32, height - 32)
    @lines = []
  end
 
  def chapter=(chapter)
    # Reset the current entries.
    entries = $game_party.diary[chapter]
    entries = [''] if entries == nil
    # Divide the current entries into lines based off the text size and length.
    @lines = entries.collect {|text| self.contents.slice_text(text, 608) }
    @lines.flatten!
    refresh
  end
 
  def refresh
    # Dispose bitmap, returning if no lines are defined.
    self.contents.clear
    return if @lines.size == 0
    self.contents.dispose
    # Create bitmap to contain the lines.
    self.contents = Bitmap.new(self.width - 32, @lines.size * 32)
    # Draw each line.
    @lines.each_index {|i| self.contents.draw_text(0, i*32, 608, 32, @lines[i])}
  end
end

#===============================================================================
# ** Bitmap
#===============================================================================
   
class Bitmap
 
  # Blizzard's slice_text method. Updated by KK20 to include
  #  \n     -  New line
  #  \v[ID] -  Variable
  def slice_text(text, width)
    # Replace all instances of \v[n] to the game variable's value
    text.gsub!("\v") {"\\v"}
    text.gsub!("\V") {"\\v"}
    text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
    # Break up the text into lines
    lines = text.split("\\n")
    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.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
      }
    }
    return result
  end
end

#===============================================================================
# ** Scene_Diary
#===============================================================================

class Scene_Diary
 
  def main
    # Create the windows.
    @sprites = [Window_Help.new, Window_Diary.new]
    if Diary::MAP_BACKGROUND
      @sprites.push(Spriteset_Map.new)
      @sprites[0].back_opacity = 160
    end
    @keys = $game_party.diary.keys.sort
    @names = @keys.collect {|chapter| Diary.chapter_name(chapter) }
    # Find current index, setting to first chapter if undefined.
    @index = @keys.index(Diary.chapter_name(@chapter))
    @index = 0 if @index == nil
    # Set the information for each window.
    @sprites[0].set_text(@names[@index] == nil ? '' : @names[@index], 1)
    @sprites[1].chapter = @keys[@index]
    # Transition Graphics.
    Graphics.transition
    # Main loop.
    loop { Graphics.update; Input.update; update; break if $scene != self }
    # Dispose windows.
    Graphics.freeze
    @sprites.each {|sprite| sprite.dispose }
  end
 
  def update
    # Branch by what input is recieved.
    if Input.repeat?(Input::UP) || Input.trigger?(Input::UP)
      $game_system.se_play($data_system.cursor_se)
      @sprites[1].oy -= 32 if @sprites[1].oy if @sprites[1].oy > 0
    elsif Input.repeat?(Input::DOWN) || Input.trigger?(Input::DOWN)
      $game_system.se_play($data_system.cursor_se)
      @sprites[1].oy += 32 if @sprites[1].oy < (@sprites[1].contents.height-384)
    elsif Input.trigger?(Input::L) || Input.trigger?(Input::R)
      $game_system.se_play($data_system.decision_se)
      # Change the current index.
      @index += Input.trigger?(Input::L) ? -1 : 1
      @index %= @keys.size
      # Display the name of the current chapter in the header.
      @sprites[0].set_text(@names[@index], 1)
      # Change the current chapter.
      @sprites[1].chapter = @keys[@index]
    elsif Input.trigger?(Input::B)
      # Play cancel SE and return to the defined scene.
      $game_system.se_play($data_system.cancel_se)
      args, scene = Diary::SCENE_ARGUMENTS, Diary::RETURN_SCENE
      $scene = (args == []) ? scene.new : scene.new(*args)
    end
  end
 
end

#===============================================================================
# ** Game_Party
#===============================================================================

class Game_Party
 
  attr_accessor :diary
 
  alias zer0_diary_init initialize
  def initialize
    zer0_diary_init
    @diary = {}
  end
end



Instructions

Place script below default scripts, and above "Main".
Instructions are in the script.


Compatibility

No known issues.


Credits and Thanks


  • ForeverZer0, for the script.
  • Blizzard, for the "slice_text" method I always steal.
  • Lauros, for requesting it.
  • KK20, for modified "slice_text" method and bug fix



Author's Notes

Please report any bugs/issues/suggestions. I will be happy to fix them.
Enjoy!
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Lauros

The script is !Awesome!, i dont find any bugs, is exactly what i need, is perfect!!!!!

Agckuu Coceg

I don't know why, but when I'm using your script with absolutely new project, I'm got that error:

QuoteScript 'Window_Help' line 26: TypeError occured.
Cannot convert nil into string

In Window_Help that line is:
Quoteself.contents.draw_text(4, 0, self.width - 40, 32, text, align)


And I'm interesting, why I get that error and maybe only I?
I'm not retarded, but I'm busy. Sorry for patience.


ForeverZer0

It what happens when the text being sent to draw is undefined. The text argument is nil. It has to be a string. You are likely attempting to add an entry that does not have a chapter name defined in the config.

i.e. Trying to read an entry in chapter 5, when chapter 5 does not have a title defined. It could be a bug, I honestly forgot to test it without any entries already present. I just used a script call to add entries, with a call at the end to call the scene when testing it. I'll check it out tonight and see if it needs fixed, or just a configuation error.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Agckuu Coceg

I also tried to find out yesterday, and realized the problem. This error can occur not only when you put the wrong chapter and text, but if you don't put a script call of chapter before run the Journal script. I'm see something like that on the Quest Log of game_guy, and only then realized.
I'm not retarded, but I'm busy. Sorry for patience.


ForeverZer0

* Updates to v.1.1 *

Fixed bug.
Game won't crash if Diary is opened and no entries have been added yet.
Thank you Agckuu Coceg for pointing that out.  ;)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Vexus

Huge necropost I know but...

Is there anyway I can "update" the text of a chapter by script call without the script making it a new page?

Better explanation:

You add chapter 1 and for now it shows you need to go x place, once you reach the place something happens and you take note on the diary but if you script call to add the updated text it will assume it's a new page instead of having the text updated.

So is there anyway to have let's say chapter one showing piece per piece via script call or at the very least a command that deletes the entry from the diary so adding the updated version would take it's place?

Thanks
Current Project/s:

ForeverZer0

All data is stored in $game_party.diary. You can change it as you need by adding or removing values.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Vexus

Would you mind giving me an example on how would I remove chapter 1 text included so I could add another chapter 1 with updated text please?

Thanks
Current Project/s:

KK20

Deletes all the text in the following chapter:
$game_party.diary[chapter] = []





   


   
   


   
   

Other Projects
RPG Maker XP AceUpgrade RMXP to RMVXA performance!
XPA TilemapTilemap rewrite with many features, including custom resolution!



Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Vexus

Current Project/s:

theneonheart

Hi, I'm using this script in my game, and it seems to be working, the only thing is whenever I add an entry, it posts the entry twice in the window, one right after the other...

I was wondering if you might know what could cause this?

I am using CCOA's UMS http://www.rmxpunlimited.net/forums/files/file/63-ccoas-ums-18/, thought that might have something to do with it. But otherwise I have no clue.
My Games: ExXception Draft - A Cyberpunk Detective Story with a Twist of the Paranormal

KK20

The message system should have, in no way, any effect on the Diary script. Problem solving tip: If you think another script is causing the problem, remove the script and see if the problem persists.

Most likely what you are doing is calling Diary.add_entry twice. I even went as far as to try using the two scripts together--I got no errors.





   


   
   


   
   

Other Projects
RPG Maker XP AceUpgrade RMXP to RMVXA performance!
XPA TilemapTilemap rewrite with many features, including custom resolution!



Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Launian

Hello. I'm just wondering: is there any way I can put line jumps on the script? I've been fooling around with it, and I can't figure it out.

What I need is to make some sort of list, something like:

Hotkeys:

1 - Equipment Window
2 - Item Window
3 - Status Window
...


Something like that. Any ideas?

If I were to leave tonight, would your hand try to reach me?

KK20

Quote from: Launian on September 27, 2012, 03:39:42 pm
Hello. I'm just wondering: is there any way I can put line jumps on the script? I've been fooling around with it, and I can't figure it out.

Clicky





   


   
   


   
   

Other Projects
RPG Maker XP AceUpgrade RMXP to RMVXA performance!
XPA TilemapTilemap rewrite with many features, including custom resolution!



Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Launian

Quote from: KK20 on September 27, 2012, 07:56:53 pm
Quote from: Launian on September 27, 2012, 03:39:42 pm
Hello. I'm just wondering: is there any way I can put line jumps on the script? I've been fooling around with it, and I can't figure it out.

Clicky


Thank you so much! =D Worked great.

If I were to leave tonight, would your hand try to reach me?

pickedlastjake

Hey there, I'm pretty n00bish to RGSS and Ruby in general. But I'm trying to learn by reading and using different scripts in my game. I put this script into my game, and I love it! It is exactly what I needed. The only problem is, and its quite probably due to the fact that I'm very new to all this, is that when I have more than one chapter added I can't see any of the chapters except the first one. When I press up and down with the window open it makes the sound but doesn't display any of the other pages. If you could let me in on why this might happen that'd be awesome!

KK20

It's the L and R buttons (default are Q and W keys). Up and Down only scroll down the current chapter, for long entries.





   


   
   


   
   

Other Projects
RPG Maker XP AceUpgrade RMXP to RMVXA performance!
XPA TilemapTilemap rewrite with many features, including custom resolution!



Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

MarkHest

For some reason when I make a the script call for a new chapter it won't happen. It stays at the lowest chapter I created. Is it meant to count down?

To describe my problem: When I make a script call for chapter 1 it works fine. Then when I make a script call for starting chapter 2 it won't happen and starts at chapter 1. However, If I start by using chapter 2 and then make a script call for going to chapter 1, it works :???:

I'm not doing anything wrong, am I?: ShowHide
 
   

KK20

Well, since it's a diary, all chapters you add to it are kept in memory. Of course it should start off with Chapter 1 first.
To swap between different chapters,
Quote from: KK20 on December 06, 2012, 08:42:41 pm
It's the L and R buttons (default are Q and W keys). Up and Down only scroll down the current chapter, for long entries.

If you want to clear out your diary of everything

$game_party.diary.clear





   


   
   


   
   

Other Projects
RPG Maker XP AceUpgrade RMXP to RMVXA performance!
XPA TilemapTilemap rewrite with many features, including custom resolution!



Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!