Dziennik Zadań
Aktualny czas: 28-04-26, 16:47 Witaj! Przejdź do zakładki Logowanie lub Rejestracja


Wątek zamknięty 
[VX] Dziennik Zadań
Yoroiookami Offline
*


Liczba postów: 985
Dołączył: 01-05-13

Pomógł: 137



Post: #1
Dziennik Zadań

Używam tego skryptu na dziennik zadań:
#==============================================================================
#  Quest Journal
#  Version: 1.1
#  Author: modern algebra (rmrk.net)
#  Date: March 24, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Description:
#      Basically, this script is an objective based quest log that allows the
#    user to make quests and reveal them to the characters through specified
#    script calls. It is objective based, meaning that you advance the quest
#    by having the player complete objectives and you can choose when to reveal
#    these objectives and when to set them as complete or as failed. That being
#    said, this script does not build quests, it more or less gives you a
#    graphical interface for showing quest progress. It does run by script
#    call, and so read the instructions carefully if you want to use this script
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#      Basically, set up all of your quests in the module below. The Constants
#    section is annotated, so read the comments near them to determine what you
#    should set these constants to. As you can see, they are filled in with
#    default values currently, and so that should give you an idea of what to
#    do.
#
#      Setting up quests can be a little bit harder. You will have to set one
#    of these up for every quest that you want represented in the scene. Refer
#    to the editable region inside the class Quest for further instructions
#
#      Once they are setup, you can activate them at any time in the game by
#    this code:
#
#      $game_party.quests[quest_id]
#
#    There are several methods you can call that are of relevance. Namely:
#
#        $game_party.quests[quest_id].reveal_objective (objective_id)
#        $game_party.quests[quest_id].conceal_objective (objective_id)
#        $game_party.quests[quest_id].complete_objective (objective_id)
#        $game_party.quests[quest_id].uncomplete_objective (objective_id)
#        $game_party.quests[quest_id].fail_objective (objective_id)
#        $game_party.quests[quest_id].unfail_objective (objective_id)
#        $game_party.quests[quest_id].complete?
#        $game_party.quests[quest_id].failed?
#        $game_party.quests[quest_id].reward_given = true/false
#        $game_party.quests[quest_id].concealed = true/false
#        $game_party.quests.remove (quest_id)
#
#    There are other methods that you can access, but they are irrelevant for
#    the purposes of controlling quest progress. These are fairly self-
#    explanatory methods, but in case they aren't, reveal_objective naturally
#    allows the specified objective to appear in the Quest Journal for browsing
#    by the user. complete_objective notes when an objective is complete, and
#    fail_objective notes when the player has done something that fails this
#    objective. complete? returns true if all primary objectives have been
#    completed and failed? returns true if any primary objective has been
#    failed. reward_given serves the function of a switch. You should
#    essentially make the reward event look like this:
#
#      @> Conditional Branch: Script: $game_party.quests[quest_id].complete?
#        @> Conditional Branch: Script: $game_party.quests[quest_id].reward_given
#          @> ...Thank you or whatever you want the event to say once the reward has been given
#        @> Else
#          @> ...Give Reward
#          @> Script: $game_party.quests[quest_id].reward_given = true
#        @> Branch End
#      @> Branch End
#
#     Later versions of this script will have an auto-reward system and also a
#     Journal to which the player can write notes.
#
#     You can also disable access to the Quest Log at any time with the code:
#       $game_system.quest_disabled = true
#
#     And you can change how it is accessed with the codes:
#    
#       $game_system.quest_keyaccess = true / false  # ON MAP
#       $game_system.quest_menuaccess = true / false # IN MENU
#
#     Also, in a message, \nq[quest_id] will retrieve the name of a quest and
#     print it in a message
#===============================================================================​=
# *** Quest Data
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~
#  This is the configuration class for the Quest Journal
#===============================================================================​=

module ModAlg_QuestData
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  # * Constants
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  # * Editable Region
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  QUESTS_LABEL = 'Quests'        # What you want Quests to be called (eg. 'Missions')
  ACTIVE_QUEST_ICON = 149        # What icon signifies a quest is active
  COMPLETE_QUEST_ICON = 150      # What icon signifies a quest is complete
  FAILED_QUEST_ICON = 179        # What icon signifies a quest is failed
  BULLET_CHARACTER = '●'         # The character used for listing objectives
  ACTIVE_COLOUR = 0              # The colour of a quest that is active
  COMPLETE_COLOUR = 11           # The colour of a quest that is complete
  FAILED_COLOUR = 18             # The colour of a quest that is failed
  MENU_ACCESS = true             # Can the script be accessed through the menu?
  MENU_INDEX = 4                 # If above is true, where in the command window?
  KEY_ACCESS = false             # Can the quest log be accessed by a key        
  MAPKEY_BUTTON = Input::L       # If above is true, which button?
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  # * Quest Data
  #----------------------------------------------------------------------------
  #  Returns skeleton data for the quesr
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  def self.quest_data (id)
    # Set class variables to corresponding arguments
    objectives = []
    name = '??????'
    description = '??????????'
    icon_index = 0
    case id
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * EDITABLE REGION
    #------------------------------------------------------------------------
    #  To set up a quest, first identify it with an ID - this can be anything
    #  as long as it is not the same as another quest, but it is important to
    #  remember this ID as it is the only way to access your quest.
    #    In any case, the format for setting up a quest is:
    #
    #      when <quest_id> # Give the quest an ID number
    #        name = '<quest_name>'
    #        description = '<quest_description>'
    #        objectives[0] = '<first_objective>'
    #        ...
    #        objectives[n] = '<nth objective>'
    #        prime = [<objective_id>, ..., <objective_id>]
    #        icon_index = <quest_icon_index>
    #
    #    Each of these values have an importance.
    #      name is the name of the quest
    #      description is a small blurb explaining the overall goal of the quest
    #      objective[0..n] are short-term goals that lead to the overall goal
    #      primes are which objectives need to be complete before the quest is
    #        considered to be complete
    #      icon_index is the icon that represents the quest
    #
    #    Note that any of the above values can be omitted without throwing an
    #    error, but for the quest to work properly you should at least set the
    #    name, description, and objectives. If you do omit these, the default
    #    values are:
    #  
    #      name = '??????'
    #      description = '??????????'
    #      objectives = []
    #      prime = [all objectives]
    #      icon_index = 0
    #
    #   If you do want to require that all objectives must be satisfied before
    #   the quest is complete, then do not bother defining it. Otherwise, be
    #   sure to set it.
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    when 1 # Fetch
      name = 'Fetch'
      description = 'Martha needs someone to play with her dog'
      objectives[0] = 'Find a stick'
      objectives[1] = 'Throw the stick to the dog'
      objectives[2] = 'Retrieve the stick from the dog'
      icon_index = 79
    when 4 # Cat Retrieval
      name = 'Cat Retrieval'
      description = 'Mrs. Bunderby has lost her cat, and she has employed you to find it.'
      objectives[0] = 'Find the lost cat'
      objectives[1] = 'Climb the tree and retrieve the cat'
      objectives[2] = "Return a cat to Mrs. Bunderby"
      # Set prime objectives in an array based on index
      prime = [0, 2]
      icon_index = 137
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * END EDITABLE REGION
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    end
    return name, description, objectives, prime, icon_index
  end
  
  #==========================================================================​==
  # ** Quest
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​~~
  #  Holds in-game data for a quest
  #==========================================================================​==

  class Quest
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Public Instance Variables
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    attr_reader   :name                # The name of the quest
    attr_reader   :id                  # The ID in $game_party.quests
    attr_reader   :description         # A blurb explaining the quest
    attr_reader   :objectives          # An array of strings holding objectives
    attr_reader   :prime_objectives    # An array of crucial objectives
    attr_reader   :icon_index          # The Icon associated with this quest
    attr_reader   :revealed_objectives # An array of revealed objectives
    attr_reader   :complete_objectives # An array of completed objectives
    attr_reader   :failed_objectives   # An array of failed objectives
    attr_accessor :reward_given        # A switch to ensure only one reward given
    attr_accessor :concealed           # A switch to show or not show the quest
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Object Initialization
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def initialize (id)
      @id = id
      # Set class variables to corresponding arguments
      @name, @description, @objectives, prime, @icon_index = ModAlg_QuestData.quest_data (id)
      # If no primary objectives are specified
      if prime.nil?
        # All objectives become primary
        prime = []
        for i in 0...@objectives.size
          prime.push (i)
        end
      end
      @prime_objectives = prime
      # Initialize non-public arrays
      @revealed_objectives = []
      @complete_objectives = []
      @failed_objectives = []
      @reward_given = false
      @concealed = false
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Reveal Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def reveal_objective (index)
      return if index >= @objectives.size
      # Add to revealed objectives
      @revealed_objectives |= [index]
      # Sort from lowest index to highest index
      @revealed_objectives.sort!
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Conceal Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def conceal_objective (index)
      @revealed_objectives.delete (index)
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Complete Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def complete_objective (index)
      return if index >= @objectives.size
      # If the objective is failed, you cannot complete it.
      return if @failed_objectives.include? (index)
      # Reveal the objective if it was not previously revealed
      reveal_objective (index) unless @revealed_objectives.include? (index)
      # Add to complete objectives
      @complete_objectives |= [index]
      # Sort from lowest index to highest index
      @complete_objectives.sort!
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Uncomplete Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def uncomplete_objective (index)
      @complete_objectives.delete (index)
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Fail Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def fail_objective (index)
      return if index >= @objectives.size
      # Reveal the objective if it has not yet been revealed
      reveal_objective (index) unless @revealed_objectives.include? (index)
      # Add to revealed objectives
      @failed_objectives |= [index]
      # Sort from lowest index to highest index
      @failed_objectives.sort!
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Unfail Objective
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def unfail_objective (index)
      @failed_objectives.delete (index)
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Complete?
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def complete?
      # Check if all prime objectives have been completed
      return (@complete_objectives & @prime_objectives) == @prime_objectives
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Failed?
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def failed?
      # Check if any prime objectives have been failed
      return (@failed_objectives & @prime_objectives) != []
    end
  end
end

#==============================================================================
# ** Ellipse
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Stores an ellipse object.
#==============================================================================

class Ellipse
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  attr_reader   :a # The width of the oval
  attr_reader   :b # The Height of the oval
  attr_reader   :x # the top left x position
  attr_reader   :y # the top left y position
  attr_reader   :h # The x position of the origin
  attr_reader   :k # The y position of the origin
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #     x : the top left x position
  #     y : the top left y position
  #     a : the width of oval from origin to the side
  #     b : the height of oval from origin. If nil, then a is radius of circle
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize (x, y, a, b = nil)
    @x = x
    @y = y
    @a = a
    @b = b.nil? ? a : b
    @h = x + a
    @k = y + @b
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Within?
  #    x : the x coordinate being tested
  #    y : the y coordinate being tested
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def within? (x, y)
    x_square = ((x - @h)*(x - @h)).to_f / (@a*@a)
    y_square = ((y - @k)*(y - @k)).to_f / (@b*@b)
    # If "radius" <= 1, then it must be within the ellipse
    return (x_square + y_square) <= 1
  end
end

#==============================================================================
# ** Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This adds the methods fill_ellipse, outline_ellipse, and fill_rounded_rect
#==============================================================================

class Bitmap
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Outline Ellipse
  #    ellipse : the ellipse being drawn
  #    width   : the width of the bar
  #    colour  : the colour of the outline
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def outline_ellipse (ellipse, colour = font.color, width = 1, steps = 0)
    # For neatness, define local variables a and b to the ellipse variables
    a, b = ellipse.a, ellipse.b
    # Use Ramanujan's approximation of the Circumference of an ellipse
    steps = Math::PI*(3*(a + b) - Math.sqrt((3*a + b)*(a + 3*b))) if steps == 0
    radian_modifier = (2*Math::PI) / steps
    for i in 0...steps
      t = (radian_modifier*i) % (2*Math::PI)
      # Expressed parametrically:
      #   x = h + acos(t), y = k + bsin(t) : where t ranges from 0 to 2pi
      x = (ellipse.h + (a*Math.cos(t)))
      y = (ellipse.k + (b*Math.sin(t)))
      set_pixel (x, y, colour)
    end
    # Thicken the line
    if width > 1
      ellipse = Ellipse.new (ellipse.x + 1, ellipse.y + 1, ellipse.a - 1, ellipse.b - 1)
      outline_ellipse (ellipse, colour, width - 1, steps)
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Fill Ellipse
  #    ellipse : the ellipse being drawn
  #    colour  : the colour of the outline
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def fill_ellipse (ellipse, colour = font.color, steps = 0)
    # For neatness, define local variables a and b to the ellipse variables
    a, b = ellipse.a, ellipse.b
    # Use Ramanujan's approximation of the Circumference of an ellipse
    steps = Math::PI*(3*(a + b) - Math.sqrt((3*a + b)*(a + 3*b))) if steps == 0
    radian_modifier = (2*Math::PI) / steps
    for i in 0...(steps / 2)
      t = (radian_modifier*i) % (2*Math::PI)
      # Expressed parametrically:
      #   x = h + acos(t), y = k + bsin(t) : where t ranges from 0 to 2pi
      x = ellipse.h + (a*Math.cos(t))
      y = ellipse.k - (b*Math.sin(t))
      fill_rect (x, y, 1, 2*(ellipse.k - y), colour)
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Fill Rounded Rectangle
  #    rect    : the rectangle being drawn
  #    colour  : the colour of the outline
  #    w       : the number of pixels to cover by rounding
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  #  Used to fill a rectangle with rounded corners
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def fill_rounded_rect (rect, colour = font.color, w = 8)
    # Draw Body of the rectangle
    fill_rect (rect.x + w, rect.y, rect.width - 2*w, rect.height, colour)
    # Draw Left Vertical Rect
    fill_rect (rect.x, rect.y + w, w, rect.height - 2*w, colour)
    # Draw Right Vertical Rect
    x = rect.x + rect.width - w
    fill_rect (x, rect.y + w, w, rect.height - 2*w, colour)
    # Make a circle
    circle = Ellipse.new (0, 0, w)
    for i in 0...w
      for j in 0...w
        # Upper Left Corner
        set_pixel (rect.x + i, rect.y + j, colour) if circle.within? (i, j)
        # Upper Right Corner
        set_pixel (rect.x + rect.width - w + i, rect.y + j, colour) if circle.within? (i + w, j)
        # Bottom Left Corner
        set_pixel (rect.x + i, rect.y + rect.height - w + j, colour) if circle.within? (i, j + w)
        # Bottom Right Corner
        set_pixel (rect.x + rect.width - w + i, rect.y + rect.height - w + j, colour) if circle.within? (i + w, j + w)
      end
    end
  end
end

#==============================================================================
# ** Window_VarySizeHelp
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window is the same as Window_Help, but with variable size
#==============================================================================

class Window_VarySizeHelp < Window_Help
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize (h_x = 0, h_y = 0, h_width = Graphics.width, h_height = WLH + 32)
    super ()
    self.x, self.y, self.width, self.height = h_x, h_y, h_width, h_height
    contents.dispose
    self.contents = Bitmap.new (h_width - 32, h_height - 32)
    self.contents.font.name = "Comic Sans MS"
  end
end

#==============================================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    new instance variables - quest_disabled, quest_keyaccess
#    aliased method - initialize
#==============================================================================

class Game_System
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  attr_accessor :quest_disabled   # Can you access quest journal at this time
  attr_accessor :quest_keyaccess  # Is it accessible by key?
  attr_accessor :quest_menuaccess # Is it accessible through the menu
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_qst_jrnl_system_init_quests initialize
  def initialize
    # Run Original Method
    modalg_qst_jrnl_system_init_quests
    # Initialize new variables
    @quest_disabled = false
    @quest_keyaccess = ModAlg_QuestData::KEY_ACCESS
    @quest_menuaccess = ModAlg_QuestData::MENU_ACCESS
  end
end

#==============================================================================
# ** Game_Party
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    new instance variable - quests
#    aliased method - initialize
#==============================================================================

class Game_Party
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  attr_reader   :quests
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_qst_jrnl_party_init_quests initialize
  def initialize
    # Run Original Method
    modalg_qst_jrnl_party_init_quests
    # Initialize @quests
    @quests = Game_Quests.new
  end
end

#==============================================================================
# ** Game_Quests
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This class handles Quests. It is a wrapper for the built-in class "Hash".
# The instance of this class is accessed by $game_party.quests
#==============================================================================

class Game_Quests
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize
    @data = {}
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Get Quest
  #    quest_id : the ID of the quest
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def [] (quest_id)
    @data[quest_id] = ModAlg_QuestData::Quest.new (quest_id) if @data[quest_id] == nil
    return @data[quest_id]
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Get Quest List
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def list
    quest_list = @data.values
    quest_list.each { |i| quest_list.delete (i) if i.concealed }
    return quest_list
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Get Completed Quest List
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def completed_list
    complete_quests = []
    list.each { |i| complete_quests.push (i) if i.complete? }
    return complete_quests
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Get Failed Quest List
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def failed_list
    failed_quests = []
    list.each { |i| failed_quests.push (i) if i.failed? }
    return failed_quests
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Get Active Quest List
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def active_list
    return list - failed_list - completed_list
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Revealed?
  #    quest_id : the ID of a checked quest
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def revealed? (quest_id)
    return @data[quest_id] != nil
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Remove Quest
  #    quest_id : the ID of a checked quest
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def remove (quest_id)
    @data.delete (quest_id)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Clear
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def clear
    @data.clear
  end
end

#==============================================================================
# ** Window_Command
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    new instance variable - disabled_commands
#    aliased method - initialize, draw_item
#==============================================================================

class Window_Command
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Public Instance Variable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  attr_reader :disabled_commands
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Initialize
  #     width      : window width
  #     commands   : command string array
  #     column_max : digit count (if 2 or more, horizontal selection)
  #     row_max    : row count (0: match command count)
  #     spacing    : blank space when items are arrange horizontally
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_intlz initialize
  def initialize(width, commands, column_max = 1, row_max = 0, spacing = 32)
    # Initialize new instance variable
    @disabled_commands = []
    # Run Original Method
    modalg_quest_jrnl_intlz (width, commands, column_max, row_max, spacing)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Draw Item
  #     index   : item number
  #     enabled : enabled flag. When false, draw semi-transparently
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_itm_drw draw_item
  def draw_item (index, enabled = true)
    # Run Original Method
    modalg_quest_jrnl_itm_drw (index, enabled)
    enabled ? @disabled_commands.delete (index) : @disabled_commands.push (index)
  end
end

#==============================================================================
# ** Window_Message
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliaed method - convert_special_characters
#==============================================================================

class Window_Message
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Convert Special Characters
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_spec_char_convert convert_special_characters
  def convert_special_characters
    @text.gsub! (/\\NQ\[(\d+)\]/i) { $game_party.quests[$1.to_i] } # Name Quest
    # Run Original Method
    modalg_quest_jrnl_spec_char_convert
  end
end

#==============================================================================
# ** Window_QuestLabel
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window signifies that this is a quest list
#==============================================================================

class Window_QuestLabel < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize
    super (0, 0, 160 + WLH, 32 + WLH)
    create_contents
    contents.font.color = system_color
    contents.font.name = "Comic Sans MS"
    contents.draw_text (0, 0, contents.width, WLH, ModAlg_QuestData::QUESTS_LABEL, 1)
  end
end

#==============================================================================
# ** Window_QuestCategory
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window displays which category is being viewed
#==============================================================================

class Window_QuestCategory < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize
    super (0, WLH + 32, 160 + WLH, 64)
    create_contents
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Refresh
  #    category_index : icon to highlight -
  #                       0 => All, 1 => Active, 2 => Complete, 3 => Failed
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def refresh (category_index = 0)
    contents.clear
    # Retrieve Icon Bitmaps
    bitmap = Cache.system("Iconset")
    icon_index = ModAlg_QuestData::ACTIVE_QUEST_ICON
    active_rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
    icon_index = ModAlg_QuestData::COMPLETE_QUEST_ICON
    complete_rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
    icon_index = ModAlg_QuestData::FAILED_QUEST_ICON
    failed_rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
    # Combine the three icons for the All Icon
    all_icon = Bitmap.new (40, 32)
    all_icon.blt (0, 0, bitmap, complete_rect)
    all_icon.blt (20, 0, bitmap, failed_rect)
    all_icon.blt (8, 10, bitmap, active_rect)
    distance = (contents.width - 112) / 3
    x = 0
    # Draw the 'All' Icon onto the window
    contents.blt (x, 0, all_icon, all_icon.rect, category_index == 0 ? 255 : 128)
    x += 40 + distance
    # Draw the 'Active' Icon onto the window
    contents.blt (x, 4, bitmap, active_rect, category_index == 1 ? 255 : 128)
    x += 24 + distance
    # Draw the 'Complete' Icon onto the window
    contents.blt (x, 4, bitmap, complete_rect, category_index == 2 ? 255 : 128)
    x += 24 + distance
    # Draw the 'Failed' Icon onto the window
    contents.blt (x, 4, bitmap, failed_rect, category_index == 3 ? 255 : 128)
  end
end

#==============================================================================
# ** Window_QuestList
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window displays the list of quests
#==============================================================================

class Window_QuestList < Window_Selectable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize (category_index = 0, index = 0)
    super (0, 64 + (WLH + 32), 160 + WLH, Graphics.height - 64 - 2*(WLH + 32))
    @data = []
    @column_max = 1
    refresh (category_index)
    self.index = index
    self.active = true
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Quest
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def quest
    return @data[self.index]
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Refresh
  #    category_index : List to show -
  #                       0 => All, 1 => Active, 2 => Complete, 3 => Failed
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def refresh (category_index = 0)
    font = Font.new
    @data.clear
    self.index = 0
    # Get the quest list to be drawn
    case category_index
    when 0
      @data = $game_party.quests.list
    when 1
      @data = $game_party.quests.active_list
      font.color = text_color (ModAlg_QuestData::ACTIVE_COLOUR)
    when 2
      @data = $game_party.quests.completed_list
      font.color = text_color (ModAlg_QuestData::COMPLETE_COLOUR)
    when 3
      @data = $game_party.quests.failed_list
      font.color = text_color (ModAlg_QuestData::FAILED_COLOUR)
    end
    @item_max = @data.size
    unless contents == nil
      # Clear Contents
      contents.clear
      return if @data.empty?
      contents.dispose
    end
    # Create Contents
    self.contents = Bitmap.new (width - 32, WLH*@data.size)
    contents.font = font
    contents.font.name = "Comic Sans MS"
    # Draw the Quest Names
    for i in 0...@data.size
      quest = @data[i]
      # If all, distinguish between quest types by colour
      if category_index == 0
        if quest.complete?
          contents.font.color = text_color (ModAlg_QuestData::COMPLETE_COLOUR)
        elsif quest.failed?
          contents.font.color = text_color (ModAlg_QuestData::FAILED_COLOUR)
        else # Active
          contents.font.color = text_color (ModAlg_QuestData::ACTIVE_COLOUR)
        end
      end
      draw_icon (quest.icon_index, 0, i*WLH)
      # Draw the name of the quest
      contents.draw_text (24, i*WLH, contents.width - 24, WLH, quest.name)
    end
  end
end

#==============================================================================
# ** Window_QuestInfo
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  This window displays the information on the quest being viewed
#==============================================================================

class Window_QuestInfo < Window_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def initialize
    super (160 + WLH, 0, Graphics.width - (160 + WLH), Graphics.height - (32 + WLH))
    create_contents
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Refresh
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  def refresh (quest = nil)
    contents.clear
    return if quest == nil
    # Draw the name of the Quest, centred
    contents.font.color = normal_color
    contents.font.name = "Comic Sans MS"
    contents.draw_text (0, 0, contents.width, WLH, quest.name, 1)
    # If the font has set width characters
    if contents.text_size ('w').width == contents.text_size ('i').width
      formatter = Paragrapher::Formatter_2.new
    else
      formatter = Paragrapher::Formatter_2.new
    end
    # Format the description
    desc_bitmap = Bitmap.new (contents.width - 16, (2.4*WLH).to_i)
    desc_bitmap.font.name = "Comic Sans MS"
    desc_bitmap.font.size -= 4
    formatted_desc = formatter.format (quest.description, desc_bitmap)
    # Draw the Description Box
    box_height = [WLH*(formatted_desc.lines.size + 1), 3*WLH].min
    rect = Rect.new (2, (1.5*WLH).to_i, contents.width - 4, box_height)
    contents.fill_rounded_rect (rect, system_color, 10)
    rect.x, rect.y = rect.x + 2, rect.y + 2
    rect.width, rect.height = rect.width - 4, rect.height - 4
    contents.fill_rounded_rect (rect, Color.new (0, 0, 0, 0), 10)
    tw = contents.text_size ('Description').width
    # Draw the description signifier
    contents.fill_rect (32, (1.5*WLH).to_i, tw + 2, 2, Color.new (0, 0, 0, 0))
    contents.font.color = system_color
    contents.font.name = "Comic Sans MS"
    contents.draw_text (33, WLH, tw, WLH, 'Description')
    # Paragraph Artist
    artist = Paragrapher::Artist.new
    # If bitmap is too large
    if formatted_desc.lines.size < 2
      formatted_desc.bitmap = Bitmap.new (contents.width - 16, formatted_desc.lines.size*WLH)
      formatted_desc.bitmap.font.size -= 4
    end
    bmp = artist.draw (formatted_desc)
    # Centre within the box
    y = rect.y + 4 + (rect.height - bmp.height) / 2
    contents.blt (8, y, bmp, bmp.rect)
    bmp.dispose
    y = 2*WLH + rect.height + 4
    # Draw Objectives Signifier Text
    contents.font.color = system_color
    contents.font.name = "Comic Sans MS"
    tw = contents.text_size ('Objectives').width
    contents.draw_text (32, y, tw, WLH, 'Objectives')
    y += WLH
    quest.revealed_objectives.each { |i|
      # Get the correct color
      contents.font.color = quest.complete_objectives.include? (i) ?
        text_color (ModAlg_QuestData::COMPLETE_COLOUR) : quest.failed_objectives.include? (i) ?
        text_color (ModAlg_QuestData::FAILED_COLOUR) : text_color (ModAlg_QuestData::ACTIVE_COLOUR)
      # Get objective
      objective = quest.objectives[i]
      # Draw Bullet
      tw = contents.text_size (ModAlg_QuestData::BULLET_CHARACTER).width
      x = 8
      contents.draw_text (x, y, tw, WLH, ModAlg_QuestData::BULLET_CHARACTER)
      x += tw + 4
      # Format the objective
      obj_bitmap = Bitmap.new (contents.width - x, 2*WLH)
      obj_bitmap.font = contents.font
      obj_bitmap.font.name = "Comic Sans MS"
      obj_bitmap.font.size -= 4
      formatted_obj = formatter.format (objective, obj_bitmap)
      # Draw Objective
      bmp = artist.draw (formatted_obj)
      contents.blt (x, y + 4, bmp, bmp.rect)
      # Modify the Y accordingly
      y += WLH*([formatted_obj.lines.size, 2].min)
    }
  end
end

#==============================================================================
# ** Scene_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased method - update
#==============================================================================

class Scene_Map < Scene_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Frame Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_journal_map_upd_key_access update
  def update
    modalg_quest_journal_map_upd_key_access
    # If the quest log can be accessed by key and is not empty or disabled
    if $game_system.quest_keyaccess && !$game_system.quest_disabled && !$game_party.quests.list.empty?
      $scene = Scene_Quest.new if Input.trigger? (ModAlg_QuestData::MAPKEY_BUTTON)
    end
  end
end

#==============================================================================
# ** Scene_Menu
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased methods - initialize, create_command_window, update_command_selection
#==============================================================================

class Scene_Menu < Scene_Base
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Object Initialization
  #     menu_index : command cursor's initial position
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_init initialize
  def initialize(menu_index = 0)
    modalg_quest_jrnl_init (menu_index)
    return unless $game_system.quest_menuaccess
    if @menu_index == 'Quest'
      @menu_index = ModAlg_QuestData::MENU_INDEX
    elsif @menu_index >= ModAlg_QuestData::MENU_INDEX
      @menu_index += 1
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Create Command Window
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_journal_menu_cmmnd_win_create create_command_window
  def create_command_window
    modalg_quest_journal_menu_cmmnd_win_create
    # If accessed through map, then don't add it to the menu
    return unless $game_system.quest_menuaccess
    c = @command_window.commands
    c.insert (ModAlg_QuestData::MENU_INDEX, ModAlg_QuestData::QUESTS_LABEL)
    width = @command_window.width
    disabled = @command_window.disabled_commands
    @command_window.dispose
    @command_window = Window_Command.new(width, c)
    @command_window.index = @menu_index
    # Disable all of the old commands as well
    disabled.each { |i|
      i += 1 if i >= ModAlg_QuestData::MENU_INDEX
      @command_window.draw_item (i, false)
    }
    if $game_system.quest_disabled || $game_party.quests.list.empty? # If Quest Journal disabled
      @command_window.draw_item (ModAlg_QuestData::MENU_INDEX, false)
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Update Command Selection
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_journal_menu_cmmnd_select_upd update_command_selection
  def update_command_selection
    if $game_system.quest_menuaccess
      changed = false
      if @command_window.index == ModAlg_QuestData::MENU_INDEX && Input.trigger? (Input::C)
        if $game_system.quest_disabled || $game_party.quests.list.empty? # If Quest Journal disabled
          Sound.play_buzzer
        else
          # Open Quest Window
          Sound.play_decision
          $scene = Scene_Quest.new
        end
        return
      end
      # If the command index is greater than it ought to be, make sure
      if @command_window.index > ModAlg_QuestData::MENU_INDEX
        @command_window.index = (@command_window.index - 1) % @command_window.commands.size
        changed = true
      end
    end
    modalg_quest_journal_menu_cmmnd_select_upd
    return unless $game_system.quest_menuaccess
    @command_window.index = (@command_window.index + 1) % @command_window.commands.size if changed
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  # * Update Actor Selection
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_actor_selection_upd update_actor_selection
  def update_actor_selection
    changed = false
    if $game_system.quest_menuaccess && @command_window.index > ModAlg_QuestData::MENU_INDEX
      @command_window.index = (@command_window.index - 1) % @command_window.commands.size
      changed = true
    end
    modalg_quest_jrnl_actor_selection_upd
    return unless $game_system.quest_menuaccess
    @command_window.index = (@command_window.index + 1) % @command_window.commands.size if changed
  end
end

#==============================================================================
# ** Scene_Quest
#------------------------------------------------------------------------------
#  This class performs the quest screen processing.
#==============================================================================

class Scene_Quest < Scene_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     menu_index : command cursor's initial position
  #--------------------------------------------------------------------------
  def initialize(category_index = 0, quest_index = 0)
    @category_index = category_index
    @quest_index = quest_index
  end
  #--------------------------------------------------------------------------
  # * Start processing
  #--------------------------------------------------------------------------
  def start
    super
    create_menu_background
    # Create Windows
    @label_window = Window_QuestLabel.new
    @category_window = Window_QuestCategory.new
    @category_window.refresh (@category_index)
    @list_window = Window_QuestList.new (@category_index, @quest_index)
    @info_window = Window_QuestInfo.new
    @info_window.refresh (@list_window.quest)
    @help_window = Window_VarySizeHelp.new
    @help_window.y = Graphics.height - @help_window.height
    @help_window.set_text ('Use Horizontal Arrow Keys to change categories', 1)
  end
  #--------------------------------------------------------------------------
  # * Termination Processing
  #--------------------------------------------------------------------------
  def terminate
    super
    dispose_menu_background
    @label_window.dispose
    @category_window.dispose
    @list_window.dispose
    @info_window.dispose
    @help_window.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    update_menu_background
    # Since the only possible activity is from @list_window, put it here
    @list_window.update
    if Input.trigger?(Input::B) # If Button B is pressed
      Sound.play_cancel
      # If Returning to Menu
      if $game_system.quest_menuaccess
        $scene = Scene_Menu.new ('Quest')
      else # Returning to Map
        $scene = Scene_Map.new
      end
    elsif Input.trigger? (Input::C) # If C button is pressed
      # Open Journal (eventually)
    elsif Input.trigger? (Input::LEFT) # If Left direction pressed
      # Play Cursor SE
      Sound.play_cursor
      # Refresh Category Window
      @category_index = (@category_index - 1) % 4
      @category_window.refresh (@category_index)
      @list_window.refresh (@category_index)
      @info_window.refresh (@list_window.quest)
    elsif Input.trigger? (Input::RIGHT) # If Right direction pressed
      # Play Cursor SE
      Sound.play_cursor
      # Refresh Category Window
      @category_index = (@category_index + 1) % 4
      @category_window.refresh (@category_index)
      @list_window.refresh (@category_index)
      @info_window.refresh (@list_window.quest)
    # If scrolling through quests
    elsif Input.trigger? (Input::DOWN) || Input.trigger? (Input::UP)
      # Refresh Info Window
      @info_window.refresh (@list_window.quest)
    end
  end
end
I tego formattera:
#==============================================================================
# ** Paragrapher::Formatter 2 (Using Zeriab's Algorithm)
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  This algorithm was written by Zeriab for fonts which have characters of
# the same width. This is like Courier New, UMEGothic and fonts of that sort.
# This algorithm attaches a cost to each line based on the amount of white
# space at the end of that line. It will display the way of writing the text
# with the lowest total cost. In prcatice, this will mean that it will, as
# much as possible, reduce the spacing between letters in a line and make
# the spacing more consistent for each line of the paragraph
#==============================================================================

module Paragrapher
  class Formatter_2
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format (string, specifications)
      f = Formatted_Text.new
      f.lines, f.blank_width, word_lengths, words = [], [], [], []
      tracker = 0
      for i in 0...string.size
        if string[i,1] == " " || i == string.size - 1
          if i == string.size - 1
            i += 1
          end
          word_lengths.push (i - tracker)
          words.push (string[tracker, i - tracker])
          tracker = i + 1
        end
      end
      if specifications.class == Bitmap
        max_width = specifications.width
        f.bitmap = specifications
      elsif specifications.class == Fixnum || specifications.class == Float
        max_width = specifications
        f.bitmap = Bitmap.new (1,1)
      else
        # Error Catching: Bad specification
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      tw = f.bitmap.text_size('a').width
      max_width = [max_width / tw, 180].min
      # Error Catching: Word too long
      if word_lengths.max > max_width
        f = format ('Too long' , specifications)
        p 'One or more words is too long for specified width'
        return f
      end
      position = line_break (word_lengths, max_width)
      lines = give_lines (position, position.size - 1, words)
      max_width *= tw
      for i in 0...lines.size
        line = lines[i]
        f.lines.push (line.scan (/./))
        if i == lines.size - 1
          f.blank_width.push (0)
        else
          text_width = line.size * tw
          extra_space = max_width - text_width
          f.blank_width.push (extra_space.to_f / (line.size.to_f - 1.0))
        end
      end
      if f.bitmap != specifications
        f.bitmap = Bitmap.new (max_width, f.lines.size*32)
      end
      return f
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Line Break (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def line_break(word_lengths, max_length)
        return false  if max_length > 180
        word_lengths.unshift(nil)
        extra_spaces = Table.new(word_lengths.size,word_lengths.size)
        line_prices = Table.new(word_lengths.size,word_lengths.size)
        word_price = []
        position = []
        inf = max_length*max_length + 1
        for i in 1...word_lengths.size
          extra_spaces[i,i] = max_length - word_lengths[i]
          for j in (i+1)..[word_lengths.size-1, max_length/2+i+1].min
              extra_spaces[i,j] = extra_spaces[i,j-1] - word_lengths[j]-1
          end
        end
        for i in 1...word_lengths.size
          for j in i..[word_lengths.size-1, max_length/2+i+1].min
              if extra_spaces[i,j] < 0
                line_prices[i,j] = inf
              elsif j == word_lengths.size-1 and extra_spaces[i,j] >= 0
                line_prices[i,j] = 0
              else
                line_prices[i,j] = extra_spaces[i,j]*extra_spaces[i,j]
              end
        end
        end
        word_price[0] = 0
        for j in 1...word_lengths.size
          word_price[j] = inf
          for ik in 1..j
            i = j - ik + 1
            break  if line_prices[i,j] == inf
            if word_price[i-1] + line_prices[i,j] < word_price[j]
                word_price[j] = word_price[i-1] + line_prices[i,j]
                position[j] = i
              end
          end
        end
        return position
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Give_Lines (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def give_lines(position,last_index,words)
        first_index = position[last_index]
        word_array = []
        if first_index != 1
          word_array = give_lines(position, first_index - 1,words)
        end
        str = ""
        for x in first_index..last_index
          str += ' '  if x != first_index
          str += words[x-1]
        end
        word_array << str
        return word_array
    end
  end
end
Tylko, że ciągle mam z nim jakieś problemy.

Zjada mi literkę 'ą'.
[Obrazek: 6ZLMutB.png]
Przy zamykaniu dziennika wywala mi błąd:
[Obrazek: wPbS559.png]

elsif @menu_index >= ModAlg_QuestData::MENU_INDEX
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #     menu_index : command cursor's initial position
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~​
  alias modalg_quest_jrnl_init initialize
  def initialize(menu_index = 0)
    modalg_quest_jrnl_init (menu_index)
    return unless $game_system.quest_menuaccess
    if @menu_index == 'Quest'
      @menu_index = ModAlg_QuestData::MENU_INDEX
    elsif @menu_index >= ModAlg_QuestData::MENU_INDEX
      @menu_index += 1
    end
  end

[Obrazek: mt4dzY7.png]
[Obrazek: k5KQGOe.png]
11-04-17 18:44
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
AlmostNoRuby Offline
*


Liczba postów: 174
Dołączył: 22-09-16

Pomógł: 33



Post: #2
RE: Dziennik Zadań

Jest problem...
Spoiler: (Otwórz)
u mnie jest jeszcze inny błąd.
Wskazuje on, że brakuje jakiejś klasy Formatted_Text.new
Nie wiem. Może to zależy od rodzaju biblioteki RGSS2? (wiesz, RGSS200E/J .dll, 202E/J itp.)
[EDIT]
*Nie, to nie zależy.
[EDIT2]
Zmieniłem czcionkę i... wyskoczył ten błąd. Co do... ?
[EDIT3]
Zapomniałem wstawić skryptu... i znowu ten błąd. :lol2:

[Obrazek: userbar1.png]
(Ten post był ostatnio modyfikowany: 11-04-17 20:35 przez AlmostNoRuby.)
11-04-17 20:17
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
Yoroiookami Offline
*


Liczba postów: 985
Dołączył: 01-05-13

Pomógł: 137



Post: #3
RE: Dziennik Zadań

#========================================================================
#  Paragraph Formatter (VX)
#  Version: 1.1
#  Author: modern algebra (rmrk.net)
#  Date: March 4, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Apology:
#    The idea behind this script is to easily separate a long string into a paragraph that fits in to
#     the dimensions you specify.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    For ease of use of people who are not neccesarily interested in writing their own algorithm,
#    I have included a facade which you can use simply by this code:
#
#           bitmap.draw_paragraph (x, y, width, height, string)
#
#    where x & y are the x & y coordinates on the specified bitmap, and width and height are the
#    maximum dimensions of the paragraph and string is the text you want to display in
#    paragraph formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  How it works:
#    The paragrapher expects two objects when initialized, a Formatter and an Artist. The idea
#    behind the formatter is that it is expected to take the initial specifications and convert it to a
#    Formatted Text object. Then, the Artist class is expected to interpret the Formatted Text
#    object and draw the paragraph. For details on how each specific algorithm works,  visit the
#    comments above and inside them. It is not necessary to use the default Formatter, Artist, or
#    Formatted Text objects.
#========================================================================

#======================================================================
# ** Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Facade for easy application of the Paragraph Formatter
#======================================================================

class Bitmap
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Formatter
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter
    @p_formatter = $game_system.default_formatter.new if @p_formatter.nil?
    return @p_formatter
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Formatter
  #     formatter : The uninitialized formatter class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter= (formatter)
    @p_formatter = formatter.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist
    @p_artist = $game_system.default_artist.new if @p_artist.nil?
    return @p_artist
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Artist
  #     artist : The uninitialized artist class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist= (artist)
    @p_artist = artist.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * The Facade, which uses default Formatter and Artist to draw the formatted text directly
  #  to a bitmap, such as self.contents
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def draw_paragraph (x, y, max_width, max_height, string)
    bitmap = Bitmap.new (max_width, max_height)
    bitmap.font = self.font
    pg = Paragrapher.new(paragraph_formatter, paragraph_artist)
    bitmap = pg.paragraph (string, bitmap)
    blt (x, y, bitmap, bitmap.rect)
    # Dispose of the proxy bitmap
    bitmap.dispose
  end
end

#========================================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#     new instance variables - default_formatter, default_artist
#     aliased methods - initialize
#========================================================================

class Game_System
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_accessor :default_formatter
  attr_accessor :default_artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias ma_paragraph_formatter_init initialize
  def initialize
    # Run original method
    ma_paragraph_formatter_init
    # Initialize original default format and artist classes
    @default_formatter = Paragrapher::Formatter_2
    @default_artist = Paragrapher::Artist
  end
end

#======================================================================
# ** Paragrapher
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Module containing the objects for the Paragrapher
#======================================================================
module Paragrapher
  #===================================================================
  # Allows the 'Paragrapher.new' command outside of the module to be used
  # rather than having to use 'Paragrapher::Paragrapher.new'
  #===================================================================
  class << self
    def new(*args, &block)
      return Paragrapher.new(*args, &block)
    end
  end
  
  #===================================================================
  # * The Paragrapher class
  #===================================================================
  class Paragrapher
    def initialize(formatter, artist)
      @formatter = formatter
      @artist = artist
    end
    
    def paragraph(string, *specifications)
      f = @formatter.format(string, *specifications)
      return @artist.draw(f)
    end
  end
  
  #===================================================================
  # * The Formatter class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This class converts a string into a formatted text object, which is then
  #  passed on to the Artist class
  #===================================================================
  class Formatter
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #     string         : the string to be formatted
    #     specifications : the desired width of the paragraph, or the bitmap
    #-------------------------------------------------------------------------------------------------------------------
    #  This works on a very simple algorithm. Basically, it just formats the
    #  text by going through each word in the string. If a word
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format(string, specifications)
      # Initializes Formatted_Text object
      f = Formatted_Text.new
      # Checks whether specifications is a bitmap or a number. It then sets
      # max_width and f.bitmap accordingly
      if specifications.is_a? (Bitmap)
        f.bitmap = specifications
        max_width = specifications.width
      elsif specifications.is_a? (Fixnum) || specifications.is_a? (Float)
        max_width = specifications
        f.bitmap = Bitmap.new (max_width, 32)
      else
        # Error Catching: Bad Specifications
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      # Breaks the given string into an array of all it's characters
      temp_word_array = string.scan (/./)
      position = 0
      line_break = 0
      # Initializes f.lines
      f.lines = []
      f.blank_width = []
      for i in 0...temp_word_array.size
        character = temp_word_array[i]
        # Error catching
        if character == "\n"
          p 'This formatter does not recognize line breaks'
          character = " "
        end
        # If at a new word
        if character == " " || i == temp_word_array.size - 1
          # Take into account the last character of the string
          if i == temp_word_array.size - 1
            i += 1
          end
          # If this word fits on the current line
          if f.bitmap.text_size (string[line_break, i-line_break]).width <= max_width
            position = i
          else
            line = temp_word_array[line_break, position-line_break]
            # Adds the first lines to f.lines
            f.lines.push (line)
            # Calculates the blank space left to cover in the line
            line_blank = max_width - f.bitmap.text_size(string[line_break,position-line_break]).width
            # Calculates the necessary distance between letters to make up for
            # line_blank and adds that value to the f.blank_width array
            f.blank_width.push (line_blank.to_f / (line.size.to_f-1.0))
            # Keeps track of the position in the array of each line
            line_break = position + 1
            position = i
          end
        end
      end
      # Adds the last line to f.lines
      f.lines.push (temp_word_array[line_break, temp_word_array.size - line_break])
      # Since the last line is drawn normally, blank_width should be 0
      f.blank_width.push (0)
      if specifications.class == Fixnum
        # Sets up the bitmap if it was unspecified.
        f.bitmap = Bitmap.new(max_width, f.lines.size*32)
      end
      # Returns the Formatted_Text object
      return f
    end
  end
  
  #===================================================================
  # * Formatter 2 (Using Zeriab's Algorithm)
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This algorithm was written by Zeriab for fonts which have characters of the same width.
  #  This is like Courier New, UMEGothic and fonts of that sort. This algorithm attaches a
  #  cost to each line based on the amount of white space at the end of that line. It will
  #  display the way of writing the text with the lowest total cost. In prcatice, this will mean
  #  that it will, as much as possible, reduce the spacing between letters in a line and make
  #  the spacing more consistent for each line of the paragraph
  #===================================================================
  class Formatter_2
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format (string, specifications)
      f = Formatted_Text.new
      f.lines, f.blank_width, word_lengths, words = [], [], [], []
      tracker = 0
      for i in 0...string.size
        if string[i,1] == " " || i == string.size - 1
          if i == string.size - 1
            i += 1
          end
          word_lengths.push (i - tracker)
          words.push (string[tracker, i - tracker])
          tracker = i + 1
        end
      end
      if specifications.class == Bitmap
        max_width = specifications.width
        f.bitmap = specifications
      elsif specifications.class == Fixnum || specifications.class == Float
        max_width = specifications
        f.bitmap = Bitmap.new (1,1)
      else
        # Error Catching: Bad specification
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      tw = f.bitmap.text_size('a').width
      max_width = [max_width / tw, 180].min
      # Error Catching: Word too long
      if word_lengths.max > max_width
        f = format ('Too long' , specifications)
        p 'One or more words is too long for specified width'
        return f
      end
      position = line_break (word_lengths, max_width)
      lines = give_lines (position, position.size - 1, words)
      max_width *= tw
      for i in 0...lines.size
        line = lines[i]
        f.lines.push (line.scan (/./))
        if i == lines.size - 1
          f.blank_width.push (0)
        else
          text_width = line.size * tw
          extra_space = max_width - text_width
          f.blank_width.push (extra_space.to_f / (line.size.to_f - 1.0))
        end
      end
      if f.bitmap != specifications
        f.bitmap = Bitmap.new (max_width, f.lines.size*32)
      end
      return f
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Line Break (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def line_break(word_lengths, max_length)
       return false  if max_length > 180
       word_lengths.unshift(nil)
       extra_spaces = Table.new(word_lengths.size,word_lengths.size)
       line_prices = Table.new(word_lengths.size,word_lengths.size)
       word_price = []
       position = []
       inf = max_length*max_length + 1
       for i in 1...word_lengths.size
         extra_spaces[i,i] = max_length - word_lengths[i]
         for j in (i+1)..[word_lengths.size-1, max_length/2+i+1].min
            extra_spaces[i,j] = extra_spaces[i,j-1] - word_lengths[j]-1
         end
       end
       for i in 1...word_lengths.size
         for j in i..[word_lengths.size-1, max_length/2+i+1].min
            if extra_spaces[i,j] < 0
              line_prices[i,j] = inf
            elsif j == word_lengths.size-1 and extra_spaces[i,j] >= 0
              line_prices[i,j] = 0
            else
              line_prices[i,j] = extra_spaces[i,j]*extra_spaces[i,j]
            end
        end
       end
       word_price[0] = 0
       for j in 1...word_lengths.size
         word_price[j] = inf
         for ik in 1..j
            i = j - ik + 1
            break  if line_prices[i,j] == inf
            if word_price[i-1] + line_prices[i,j] < word_price[j]
              word_price[j] = word_price[i-1] + line_prices[i,j]
              position[j] = i
            end
         end
       end
       return position
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Give_Lines (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def give_lines(position,last_index,words)
       first_index = position[last_index]
       word_array = []
       if first_index != 1
         word_array = give_lines(position, first_index - 1,words)
       end
       str = ""
       for x in first_index..last_index
         str += ' '  if x != first_index
         str += words[x-1]
       end
       word_array << str
       return word_array
    end
  end

  #===================================================================
  # * The Artist class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  Interprets a Formatted Text object and draws the paragraph encoded
  #===================================================================
  class Artist
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Draw
    #     f : Formatted Text Object
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def draw (f)
      # Calculates the necessary distance between lines
      line_distance = f.bitmap.height.to_f / f.lines.size.to_f
      line_distance = [f.bitmap.font.size  + 10, line_distance].min
      # For all lines in the lines array
      for i in 0...f.lines.size
        blank_space = f.blank_width[i]
        position = 0
        # For all indices of the line array
        for j in 0...f.lines[i].size
          word = f.lines[i][j]
          ws = f.bitmap.text_size (word)
          position += blank_space if j != 0
          # Adds blank_space and position, and draws the string located at each index
          f.bitmap.draw_text (position, line_distance*i,ws.width+1,ws.height+1,word)
          # Keeps track of the position we are in in pixels
          position += ws.width
        end
      end
      return f.bitmap
    end
  end
  
  #===================================================================
  # * The Formatted_Text class containing the results of the formatter
  #===================================================================
  class Formatted_Text
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Public Instance Variables
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    attr_accessor :lines       # An array of strings, each a line of the paragraph
    attr_accessor :blank_width # The amount of white space between each letter
    attr_accessor :bitmap      # The bitmap drawn to
  end
end

Jest jeszcze taki formatter (oryginalny), ale miał problem z polskimi znakami i takie tam. :zmienny:

[Obrazek: mt4dzY7.png]
[Obrazek: k5KQGOe.png]
11-04-17 20:31
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
AlmostNoRuby Offline
*


Liczba postów: 174
Dołączył: 22-09-16

Pomógł: 33



Post: #4
RE: Dziennik Zadań

Tak, też go znalazłem. Nie wiem, czy działa po prostu lepiej, czy nie działa. U mnie wszystkie znaki działają normalnie. Zdanie "zażółć gęślą jaźń" przełknął bez problemów.

[Obrazek: userbar1.png]
12-04-17 15:11
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
Yoroiookami Offline
*


Liczba postów: 985
Dołączył: 01-05-13

Pomógł: 137



Post: #5
RE: Dziennik Zadań

Może przez czcionkę? Bo używam Comic Sans. :confuse:

[Obrazek: mt4dzY7.png]
[Obrazek: k5KQGOe.png]
12-04-17 15:29
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
AlmostNoRuby Offline
*


Liczba postów: 174
Dołączył: 22-09-16

Pomógł: 33



Post: #6
RE: Dziennik Zadań

Przy Comic Sans MS też normalnie -_-
Mogę ci nawet projekt wysłać, na którym to testowałem.

[Obrazek: userbar1.png]
12-04-17 19:28
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
Yoroiookami Offline
*


Liczba postów: 985
Dołączył: 01-05-13

Pomógł: 137



Post: #7
RE: Dziennik Zadań

To bardzo cię proszę, wyślij. smiles

[Obrazek: mt4dzY7.png]
[Obrazek: k5KQGOe.png]
12-04-17 22:19
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
AlmostNoRuby Offline
*


Liczba postów: 174
Dołączył: 22-09-16

Pomógł: 33



Post: #8
RE: Dziennik Zadań

https://mfi.re/file/09w75df8elhlamm/trolrorl.7z
Trzymaj mrgreen
A, i nie pytaj, gdzie znalazłem tego nightcore'a i grafikę Kabelka :D
pakiecie też masz plik .dll i jakąś czcionkę.

[Obrazek: userbar1.png]
(Ten post był ostatnio modyfikowany: 13-04-17 11:33 przez AlmostNoRuby.)
13-04-17 11:32
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
Wątek zamknięty 


Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości

Kontakt | Ultima Forum | Wróć do góry | Wróć do forów | Wersja bez grafiki | RSS
Powered By MyBB. © 2013 MyBB Group. All Rights Reserved.
Skórka by Ayene.