¡Bienvenido a Universo Maker!
¿Es esta la primera vez que visitas el foro? Si es así te recomendamos que te registres para tener completo acceso a todas las áreas y secciones del foro, así también podrás participar activamente en la comunidad. Si ya tienes una cuenta, conectate cuanto antes.
Iniciar Sesión Registrarme

No estás conectado. Conéctate o registrate

Ver el tema anterior Ver el tema siguiente Ir abajo Mensaje [Página 1 de 1.]

#1 KPortrait XP el Jue Sep 06, 2018 6:38 am

Reputación del mensaje :100% (1 voto)

kyonides

avatar
KPortrait XP
con KMessage XP


por Kyonides-Arkanthes




Introducción

Bueno ya deben conocer de sobra lo que es un sistema de mensajería en el maker, pero yo me di a la tarea de presentar el mío, aun cuando ya haya varios muy reconocidos o que han dejado de soportar. Viene con instrucciones de uso que los interesados deberían de leer. Eso describe a la perfección lo que hace KMessage XP, con todo y espera para terminar de imprimir el texto en la ventana de diálogo.

KPortrait XP en sí mismo sirve para manejar las faces o retratos. En las instrucciones verán que las llamado retratos, pero me refiero a todo, faces y bustos. Esto incluye animaciones si las tienen por ahí como la de mover la boca o la de abrir y cerrar los ojos.


Código


Versión en Español

Código:
# * KPortrait XP
#   Scripter : Kyonides-Arkanthes
#   2018-08-22 - 1.0.3

#   Este script es de libre uso en demos, pero los desarrolladores que incluyan
#   esto en sus juegos comerciales han de enviarme una copia gratuita del mismo
#   sin excepciones. También yo solicitaría el pago de un monto por haber hecho
#   el presente script.
  
#   Instrucciones

#   Hay dos maneras de configurar un retrato o face. La primera es via llamado
#   a script y la otra sería dejar notas en el evento. Todas esas notas deben
#   quedar en una o dos líneas según el caso. No importara si digitan todo en
#   mayúsculas o no lo hacen, no se fija en esos detalles excepto por cualquier
#   nombre de imagen. Digiten el nombre exacto a toda costa sin la extensión.
#   *Index* o Indice siempre significará posición, o sea, 1, 2 o 3.

#   Puede desplegar hasta tres retratos al mismo tiempo.

# * Llamados a Script *

#   KPortrait.show(nombre, índice, usa_nombre_de_archivo_como_nombre_a_mostrar)

#   KPortrait.show('Aluxes')
#   KPortrait.show('Basil', 2)
#     Tan solo mostrará el retrato de Alexis al lado izquierdo.
#     El de Basil será desplegado a la derecha.

#   KPortrait.options(índice, llave => valor)
#     :lado - puede ser :izq o :centro o :der. Sus respectivos valores numéricos
#       serían 0, 1 y 2, pueden utilizar cualquiera de las dos formas.
#     :alto - puede ser :alto o :arriba, :medio, :bajo o :fondo, o bien, pueden
#       utilizar 0 o 1 o 2, queda a su gusto.
#     :espejo o :flip - Refleja la imagen, valores: true o false.

#   KPortrait.x_pos(posición, índice) # Alineamiento Horizontal
#     Opciones: 0, :izq - Izquierda. 1, :centro - Centro. 2, :der - Derecha

#   KPortrait.y_pos(posición, índice) # Alineamiento Vertical
#     0, :alto o :arriba; 1, :medio;. 2, :bajo o :fondo

#   KPortrait.new_name('Candidato Alexis', índice)
#     Will print the character's name on top of the portrait or face.
#     It would better to set it before you call the show method mentioned above.

#   KPortrait.filename_as_name = true # o false
#    Usa nombre de archivo de KPortrait.show(filename) como nombre de personaje.

#   KPortrait.talk_anime = true # o false
#     Permite al script refrescar la imagen (si habla o cierra ojos).

#   KPortrait.flip! or KPortrait.flip!(índice)
#     El retrato o face será reflejada, si veía a la derecha, lo hará a la izq.

#   KPortrait.show_name! or KPortrait.show_name!(índice)
#   KPortrait.hide_name! or KPortrait.hide_name!(índice)
#     Muestra u oculta el nombre del personaje como Alexis o Mago Malvado

#   KPortrait.clear
#     Todo retrato o face es vaciado y descartado.

# * Comentarios *

#   Ejemplos: Ver Aluxes. o Ver Botan, o Ver Ace Attorney! o Ver Me;

#   Incluyen un punto, una coma o punto y coma o exclamación para permitir que
#   puedan dejar espacios vacíos o raya abajo en el nombre de archivo.

#   Img Numero o Imagen Numero  # Selecciona Imagen 1, 2 o la 3.
#       No se necesita si solo usan la primera de tres todo el tiempo.
#   Ver    # Mostrará alguna imagen.
#   Imagen # Tipo de imagen sin extensión de archivo, sin jpg o png.
#   Oscuro # Aplica oscurecimiento a la imagen (hablante no activo).
#   Limpia Numero # Remueve Oscuridad en imagen número 1, 2 o 3.
#   Limpia Todo   # Remueve Oscuridad en todas las imágenes.
#   Estado Numero # Muestra una animación de la Base de Datos.
#   Reflejo # Refleja o invierte la imagen.
#   Espejo  # Refleja o invierte la imagen.
#   Izq     # Izquierda
#   Centro  # La imagen queda centrada horizontalmente.
#   Der     # Derecha
#   Arriba  # Evidente...
#   Medio   # La imagen queda centrada verticalmente.
#   Abajo o Fondo  # Evidente...
#   Imprima Un Nombre # Lo muestra como nombre del héroe, va al final de línea.
#   Imprima Heroe-6   # Muestra el nombre del héroe, o sea, Félix o Alexis.
#   Imprima Evento    # Muestra el nombre del evento actual.
#   Anima Hablar Si Img 1 Archivo # Activa "animación" de hablar de la imagen.
#   Anima Hablar No

module KPortrait
  FRAMES = { :talk => 3, :idle => 3 } # talk es hablar y idle en espera
  SUFFIXES = ['_talk', '_idle']
  rate = Graphics.frame_rate # entre 20 y 40 cuadros o frames
  TALK_TIMER_MAX = rate / 10
  IDLE_TIMER_MAX = [rate * 2, rate / 8, rate / 8]
  # Constante útil si usarán llamados a script
  FILENAMES = { :aluxes => 'Aluxes' }
  DEFAULT_HEIGHT = 100
  DEFAULT_WIDTH = 100
  @base_x = 80
  @base_y = 296
  @namebox_width = 160
  @sides = { 1 => :izq, 2 => :der, 3 => :centro }
  @heights = { 1 => :abajo, 2 => :abajo, 3 => :abajo }
  @show_name = true
  @filename_as_name = true
  @talk_anime = nil
  @normal_color = Color.new(0,0,0,0)
  @dim_color = Color.new(0,0,0,0)
  @align = [nil, :izq, :der, :centro]
  module_function
  def show(filename, pos=1, priority=true)
    filename = FILENAMES[filename] if filename.class == Symbol
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    sprite.filename = filename
    sprite.bitmap = portrait(filename)
    sprite.color = sprite.dim ? @dim_color.dup : @normal_color
    rect = sprite.src_rect
    new_name(filename, pos) if @show_name and @filename_as_name and priority
    return pos
  end

  def show_talk(pos, name)
    pos, name = @pos, @name if pos == nil or name == nil
    sprite = @talk_sprites[pos]
    sprite.talk_anime = true
    sprite.filename = name
    @pos = pos
    @name = name
  end

  def options(pos, options={})
    flip = options[:espejo] || options[:flip]
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    sprite.mirror = flip
    side = options.delete(:lado)
    height = options.delete(:alto)
    x_pos(pos, side) if side and @sides[pos] != side
    y_pos(pos, height) if height# and @heights[pos] != height
  end

  def x_pos(location, pos=1)
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    widt = sprite.bitmap.width
    nx = case location
    when 0, :izq then @base_x
    when 1, :centro then (640 - widt) / 2
    when 2, :der then 640 - widt - @base_x
    end
    @sides[pos] = location
    @talk_sprites[pos].x = nx
    @face_sprites[pos].x = nx
    @name_sprites[pos].x = nx - 30 if widt < @namebox_width
  end

  def y_pos(location, pos=1, default=nil)
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    heigh = sprite.bitmap.height
    ny = case location
    when 0, :alto, :arriba then @base_y - 100
    when 1, :medio then (460 - heigh) / 2
    when 2, :bajo, :fondo then @base_y - heigh
    end
    @talk_sprites[pos].y = ny
    @face_sprites[pos].y = ny
    @name_sprites[pos].y = ny + 4
  end

  def new_name(text, pos=1)
    @name_sprites[pos].visible = @show_name = true
    bitmap = @name_sprites[pos].bitmap
    bitmap.clear rescue nil
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    new_y = sprite.bitmap.height - 28
    name = text || '?'
    bitmap.outline(0, new_y, @namebox_width, 28, name, 1)
  end

  def dim(boolean, pos=1)
    color = boolean ? @dim_color.dup : @normal_color.dup
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    sprite.dim = boolean
    sprite.color = color
    sprite.dim = boolean
    sprite.color = color
    @name_sprites[pos].dim = boolean
    @name_sprites[pos].color = color
  end

  def state_anime(state_id, pos=1)
    animation = $data_animations[state_id]
    sprites = @talk_anime ? @talk_sprites : @face_sprites
    sprites[pos].animation(animation, true)
  end

  def clear_talk_sprites
    @talk_anime = nil
    1.upto(3) do |n|
      sprite = @talk_sprites[n]
      sprite.talk_anime = nil
      sprite.clear_filename
      sprite.dispose_bitmaps
    end
  end

  def clear
    @all_sprites.each do |sprite|
      sprite.bitmap.clear rescue nil
      sprite.mirror = nil
    end
    1.upto(3) do |n|
      dim(nil, n)
      x_pos(@align[n], n)
      y_pos(:bajo, n, nil)
    end
  end

  def idle_now
    @idle = true
    @talk_anime = nil
    1.upto(3) do |n|
      sprite = @talk_sprites[n]
      sprite.talk_anime = nil
      sprite.idle = @idle
      sprite.update
    end
  end

  def portrait(name)
    begin
      RPG::Cache.load_bitmap('Graphics/Portraits/', name).dup
    rescue
      Bitmap.new(100, 100)
    end
  end
  def update() @all_sprites.each {|sprite| sprite.update } end
  def flip!(pos=1) @talk_sprites[pos].mirror = true end
  def flip?(pos=1) @talk_sprites[pos].mirror end
  def show_name?() @show_name end
  def show_name!() @show_name = true end
  def hide_name!() @show_name = nil end
  class << self
    attr_accessor :talk_anime
    attr_reader :idle, :base_x, :sides, :widths, :heights, :talk_sprites
  end
end

class KPortraitSprite < RPG::Sprite
  DIM_ALPHA = 120
  attr_writer :filename
  attr_reader :dim
  def dim=(boolean) @refresh_dim = @dim = boolean end
  def update
    super
    return unless @refresh_dim
    return if color.alpha == DIM_ALPHA
    color.alpha += 15
    @refresh_dim = nil if color.alpha == DIM_ALPHA
  end
end

class KPortraitTalkSprite < KPortraitSprite
  attr_reader :talk_frames, :idle_frames, :idle
  attr_accessor :talk_anime
  def initialize
    super(nil)
    @timer = KPortrait::TALK_TIMER_MAX
    @talk_index = @idle_index = 0
    @talk_max = KPortrait::FRAMES[:talk]
    @idle_max = KPortrait::FRAMES[:idle]
    self.filename = ''
  end

  def filename=(name)
    @filename = name
    make_frames
  end

  def make_frames
    @talk_frames = []
    @idle_frames = []
    if @filename.empty?
      @talk_max.times { @talk_frames << Bitmap.new(100, 100) }
      @idle_max.times { @idle_frames << Bitmap.new(100, 100) }
    else
      suffix1, suffix2 = KPortrait::SUFFIXES
      name = @filename + suffix1
      bmap = KPortrait.portrait(name)
      bw = bmap.width / @talk_max
      bh = bmap.height
      @talk_max.times do |n|
        @talk_frames << bit = Bitmap.new(bw, bh)
        bit.blt(0, 0, bmap, Rect.new(n * bw, 0, bw, bh))
      end
      bmap.dispose
      name = @filename + suffix2
      bmap = KPortrait.portrait(name)
      bw = bmap.width / @idle_max
      @idle_max.times do |n|
        @idle_frames << bit = Bitmap.new(bw, bmap.height)
        bit.blt(0, 0, bmap, Rect.new(n * bw, 0, bw, bmap.height))
      end
      bmap.dispose
    end
    update_current_bitmap
  end

  def update
    super
    @timer -= 1
    update_current_bitmap if @timer == 0
  end

  def update_current_bitmap
    if @talk_anime
      @timer = KPortrait::TALK_TIMER_MAX
      @talk_index = (@talk_index + 1) % @talk_max
      self.bitmap = @talk_frames[@talk_index]
    elsif @idle
      @idle_index = (@idle_index + 1) % @idle_max
      @timer = KPortrait::IDLE_TIMER_MAX[@idle_index]
      self.bitmap = @idle_frames[@idle_index]
    end
  end

  def idle=(boolean)
    @idle_index = 2 if boolean
    @idle = boolean
  end

  def dispose_bitmaps
    @talk_frames.each {|bit| bit.dispose }
    @idle_frames.each {|bit| bit.dispose }
  end
  def clear_filename() @filename = '' end
end

module KPortrait
  # Constantes necesarias en caso de usar comentarios. ¡No las editen!
  ID_REGEX = /img [\d\w]+ |imagen [\d\w]+/i
  POSITION_REGEX = [/primero/i, /segundo/i, /tercero/i]
  SHOW_REGEX = /ver [\w \-_]+[\.,!;]/i
  CHARACTER_NAME_REGEX = /imprima [\w_\- ]+/i
  HORZ_REGEX = /izq|der|ver|img [\d\w]+ |imagen [\d\w]+| /i
  VERT_REGEX = /medio|arriba|bajo|alto|abajo|centro/i
  def self.make_dummy_sprites
    a = load_data('Data/Actors.rxdata')[1]
    @talk_sprites = {}
    @face_sprites = {}
    @name_sprites = {}
    1.upto(3) do |n|
      @talk_sprites[n] = sprite = KPortraitTalkSprite.new
      sprite.z = 200
      sprite.bitmap = RPG::Cache.battler(a.battler_name, a.battler_hue).dup
      @face_sprites[n] = sprite = KPortraitSprite.new
      sprite.z = 200
      sprite.bitmap = Bitmap.new(DEFAULT_WIDTH + 70, DEFAULT_HEIGHT)
      @name_sprites[n] = sprite = KPortraitSprite.new
      sprite.z = 200
      sprite.bitmap = Bitmap.new(DEFAULT_WIDTH + 70, DEFAULT_HEIGHT)
    end
    @all_sprites = [@talk_sprites[1], @talk_sprites[2], @talk_sprites[3]]
    @all_sprites += [@face_sprites[1], @face_sprites[2], @face_sprites[3]]
    @all_sprites += [@name_sprites[1], @name_sprites[2], @name_sprites[3]]
    clear
  end
  make_dummy_sprites
end

class Game_System
  alias kyon_kportrait_gm_sys_up update
  def update
    KPortrait.update
    kyon_kportrait_gm_sys_up
  end
end

class Game_Event
  def name() @event.name end
end

class Interpreter
  NOTE_CODES = [108, 408]
  alias kyon_kportrait_int_exec_comm execute_command
  def execute_command
    kyon_kportrait_int_exec_comm
    if @list and NOTE_CODES.include?(@list[@index].code)
      note = @list[@index].parameters[0].dup
      return KPortrait.clear if note[/clear/i]
      pos = note[/anima hablar/i] ? check_talk_anime(note) :  check_portrait(note)
      if note[/flip|espejo/i]
        KPortrait.flip!(pos)
        note.gsub!(/flip|espejo/i,'')
      end
      if note[/oscuro/i]
        n = note[/oscuro \d/i]
        n = n ? n[/\d/].to_i : pos
        KPortrait.dim(true, n)
        note.sub!(/oscuro/i,'')
      end
      KPortrait.x_pos(:izq, pos) if note[/izq/i]
      KPortrait.x_pos(:centro, pos) if note[/centro/i]
      KPortrait.x_pos(:right, pos) if note[/der/i]
      KPortrait.y_pos(:top, pos) if note[/alto|arriba/i]
      KPortrait.y_pos(:bajo, pos) if note[/lbajo|fondo/i]
      KPortrait.y_pos(:medio, pos) if note[/medio/i]
    end
    return true
  end

  def check_talk_anime(note)
    note.sub!(/anima hablar/i, '')
    KPortrait.talk_anime = found = note[/si/i] != nil
    if found and
      if (data = note[/img \d+/i])
        pos = data.scan(/\d+/)[0].to_i rescue 1
        name = note[/ver \w+/i].sub(/ver /i,'')
      else
        pos, name = nil, nil
      end
      KPortrait.show_talk(pos, name)
    else
      KPortrait.clear_talk_sprites
    end
    return pos ||= 1
  end

  def check_portrait(note)
    note = note.gsub(/oscuro|espejo|flip/i,'')
    priority = false
    rx1, rx2, rx3 = KPortrait::POSITION_REGEX
    pos = 1 if note[rx1]
    pos = 2 if note[rx2]
    pos = 3 if note[rx3]
    digit = note[/\d/]
    pos ||= digit.to_i
    pos = 1 if pos == 0
    kp = KPortrait
    if note[/limpia/i]
      n = note[/limpia \d/i][/\d/].to_i || pos
      note[/limpia todo/i] ? 3.times{|n| kp.dim(nil, n+1) } : kp.dim(nil, n)
      note.sub!(/limpia todo|limpia \d/i,'')
    end
    if (state = note[/estado \d+/i])
      kp.state_anime(state[/\d+/].to_i, pos)
      note.sub!(/estado \d+/i,'')
    end
    if (name = note[kp::CHARACTER_NAME_REGEX])
      note.sub!(kp::CHARACTER_NAME_REGEX,'')
      name.sub!(/evento/i) do
        inter = $game_system.map_interpreter
        inter.get_character(0).name
      end
      name.sub!(/imprima /i,'')
      name.sub!(/heroe-(\d+)/i){ $game_actors[$1.to_i].name }
      kp.new_name(name.dup, pos)
      priority = true
    end
    return pos if note[kp::SHOW_REGEX] == nil
    priority = !priority
    filename = note.dup.gsub(kp::HORZ_REGEX,'')
    filename.gsub!(kp::VERT_REGEX,'')
    filename.gsub!(kp::ID_REGEX,'')
    filename.gsub!(/img\d|imagen\d|[\.,;! ]/i,'')
    kp.show(filename, pos, priority)
  end
end

Código:
# * KMessage XP
#   2018-08-18 - 0.9.2 - Versión en Español
#   Scripter : Kyonides-Arkanthes

#   Este script es de libre uso en demos, pero los desarrolladores que incluyan
#   esto en sus juegos comerciales han de enviarme una copia gratuita del mismo
#   sin excepciones. También yo solicitaría el pago de un monto por haber hecho
#   el presente script.


# * Advertencia *

#   This script is extremely incompatible with any other Message System that may
#   be available out there! Never try to use several of them at the same time!

# * Type Mashine Writing Style *

#   There are two ways to enable or disable it.

#   Initial Value
#     @type_mashine_style = true # can be either true or false or nil
#   In Game Script Call
#     KMessage.type_mashine_style = true # or false or nil

# * Opciones Disponibles *

#   Pulsa botón Aceptar para saltar las pausas causadas por estas etiquetas:

#   \. - Pausa el proceso de dibujado del mensaje durante 10 seconds
#   \! - Pausa el proceso de dibujado del mensaje durante 20 seconds
#   \< - Pausa el proceso de dibujado del mensaje durante 40 seconds
#   \> - Pausa el proceso de dibujado del mensaje durante 60 seconds
#   B or b - Negrita
#   I or i - Itálica
#   FT[Numero] or ft[Numero] - Tipo de Fuente (Vea Módulo CustomSettings)
#   FS[Numero] or fs[Numero] - Tamaño de Fuente o Font
#   IT[Numero] or it[Numero] - Nombre de Objeto en la Ventana de Diálogo
#   W[Numero] or w[Numero]   - Nombre de Arma en la Ventana de Diálogo
#   A[Numero] or a[Numero]   - Nombre de Armadura en la Ventana de Diálogo
#   SK[Numero] or sk[Numero] - Nombre de Skill en la Ventana de Diálogo

# * Opcional * - ¡No lo utilice sin el script KPortrait XP!

#   WA[Numero] or wa[Numero] - Nombre de Héroe en una ventana aparte
#   WE[Numero] or we[Numero] - Nombre de Evento en una ventana aparte
#   E[Numero] or e[Numero]   - Nombre de Enemigo en una ventana aparte

# * Opciones para KPortrait *
#   \cln1  or  \cln2  or  \cln3  - Limpia Oscuridad en Imagen Número...
#   \dim1  or  \dim2  or  \dim3  - Usa Oscuridad en Imagen Número...
#   \fl1  or  \fl2  or  \fl3     - Invierte Imagen Número...

# * Experimental *
#   JL or jl - Alineación de Texto : A la Izquierda
#   JC or jc - Alineación de Texto : Al Centro
#   JR or jr - Alineación de Texto : A la Derecha

module KMessage
  @type_mashine_style = true # Muestra Diálogo Lento como Máquina de Escribir
  USE_NAME_SUBWINDOW = nil
  FONTS = [Font.default_name, 'Times New Roman', 'Arial', 'Verdana', 'Vivaldi',
    'Comic Sans MS', 'Trebuchet MS', 'UmePlus Gothic', 'Tahoma', 'Castellar']
  def self.type_mashine_style() @type_mashine_style end
  def self.type_mashine_style=(boolean) @type_mashine_style = boolean end
end

class Window_Message
  alias kyon_kmessage_win_mess_init initialize
  alias kyon_kmessage_win_mess_term_mess terminate_message
  alias kyon_kmessage_win_mess_reset_win reset_window
  def initialize
    kyon_kmessage_win_mess_init
    @use_type_mashine = KMessage.type_mashine_style
    @timer = 0
    @clean_pos = @dim_pos = @flip_pos = nil
  end

  def terminate_message
    if @proc
      @proc.call
      @proc = nil
    end
    @last_y = @last_x = @timer = 0
    kyon_kmessage_win_mess_term_mess
    return if @name_window.nil?
    @name_window.dispose
    @clean_pos = @dim_pos = @flip_pos = nil
    @name_window = @text = @finish = @done = nil
  end

  def refresh
    self.contents.clear unless @keep_text
    if @keep_text
      x = @last_x
      y = @last_y
      @last_x = @last_y = @keep_text = nil
    else
      x = y = @cursor_width = 0
      x = 8 if $game_temp.choice_start == 0
    end
    self.contents.font.color = normal_color
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      include_switch_variable(text)
      include_pauses(text)
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) {
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : "" }
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" } #text = $game_temp.message_text
      retrieve_names(text)
      setup_portrait_options(text)
      setup_font(text)
      setup_icon(text)
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      while ((c = text.slice!(/./m)) != nil)# If \\
        case c
        when "\x02" then @timer = 10
        when "\x03" then @timer = 20
        when "\x04" then @timer = 40
        when "\x05" then @timer = 60
        when "\x06" then KPortrait.dim(@clean_pos, nil) rescue nil
        when "\x07" then KPortrait.dim(@dim_pos, true) rescue nil
        when "\x08" then KPortrait.flip!(@flip_pos, true) rescue nil
        end
        if @timer > 0
          @finish = nil
          @keep_text = true
          @last_x = x
          @last_y = y
          break
        end
        if c == "\000"
          c = "\\" # Return to original text
        elsif c == "\001" # If \C[n]
          text.sub!(/\[([0-9]+)\]/, "") # Change text color
          color = $1.to_i
          contents.font.color = text_color(color) if color >= 0 and color <= 7
          next
        elsif c == "\002" # If \G
          if @gold_window == nil # Make gold window
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else @gold_window.y = self.y >= 128 ? 32 : 384 end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          next
        end
        if c == "\\" # Bold or Strong or Emphasis
          contents.font.bold, c = !contents.font.bold, ''
          next
        elsif c == "\@" # Italic
          contents.font.italic, c = !contents.font.italic, ''
          next
        end
        align, c = case c
        when "\[#]" then [0, ''] # \JL \jl Text Alignment : Left-Hand Side
        when "\[^]" then [1, ''] # \JC \jc Text Alignment : Center
        when "\[*]" then [2, ''] # \JR \jr Text Alignment : Right-Hand Side
        else [0, c] end
        if c == "\#" # Font Type
          text.sub!(/\[([0-9]+)\]/, "")
          c, contents.font.name = '', KMessage::FONTS[$1.to_i]
          next
        elsif c == "\<" # Font Size
          text.sub!(/\[([0-9]+)\]/, "")
          c, contents.font.size = '', $1.to_i
          next
        elsif c == "\n"
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          y += 1
          x = y >= $game_temp.choice_start ? 8 : 0
          next
        end
        self.contents.draw_text(x+4, 32*y, 40, 32, c, align)
        x += self.contents.text_size(c).width # Add x to drawn text width
        next if @finish or !@use_type_mashine
        @timer += 1
        @keep_text = true
        @last_x = x
        @last_y = y
        break
      end
      @finish = nil
      @done = (@timer == 0 and (text == nil or text.empty?))
      KPortrait.idle_now if @done
    end
    if $game_temp.choice_max > 0 # If choice
      @item_max = $game_temp.choice_max
      self.active, self.index = true, 0
    elsif $game_temp.num_input_variable_id > 0 # If number input
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
    end
  end

  def include_switch_variable(text)
    begin
      last_text = text.clone
      text.gsub!(/\\v\[([0-9]+)\]/i) { $game_variables[$1.to_i] }
      text.gsub!(/\\s\[([0-9]+)\]/i) { $game_switches[$1.to_i] } # Sw. ID Status
    end until text == last_text
  end

  def include_pauses(text)
    text.gsub!(/\\\./, "\x02")
    text.gsub!(/\\!/, "\x03")
    text.gsub!(/\\</, "\x04")
    text.gsub!(/\\>/, "\x05")
  end

  def retrieve_names(text)
    # Get Actor Name and Open Name Window
    text.gsub!(/\\wa\[([0-9]+)\]/i){ name = $game_actors[$1.to_i].name
      set_name(name); '' }
    # Get Event Name and Open Name Window
    text.gsub!(/\\we\[([0-9]+)\]/i){ name = $game_map.events[$1.to_i].name
      set_name(name); '' }
    # Get Enemy Name
    text.gsub!(/\\e\[([0-9]+)\]/i) {
      $data_enemies[$1.to_i] != nil ? $data_enemies[$1.to_i].name : '' }
    # Get Item Name
    text.gsub!(/\\it\[([0-9]+)\]/i) {
      $data_items[$1.to_i] != nil ? $data_items[$1.to_i].name : '' }
    # Get Weapon Name
    text.gsub!(/\\w\[([0-9]+)\]/i) {
      $data_weapons[$1.to_i] != nil ? $data_weapons[$1.to_i].name : '' }
    # Get Armor Name
    text.gsub!(/\\a\[([0-9]+)\]/i) {
      $data_armors[$1.to_i] != nil ? $data_armors[$1.to_i].name : '' }
    # Get Skill Name
    text.gsub!(/\\sk\[([0-9]+)\]/i) {
      $data_skills[$1.to_i] != nil ? $data_skills[$1.to_i].name : '' }
    # Get Event ID and Variable ID - Return Event name - Current Map
    text.gsub!(/\\ev\[([0-9]+),([0-9]+)\]/i) do
      $game_variables[$2.to_i] = $game_map.events[$1.to_i].name
      $game_variables[$2.to_i]
    end
    # Get Event ID and Variable ID - Return Event name - Not Current Map
    text.gsub!(/\\mev\[([0-9]+),([0-9]+),([0-9]+)\]/i) do
      events = load_data(sprintf("Data/Map%03d.rxdata", $1.to_i)).events
      $game_variables[$3.to_i] = events[$2.to_i].name
      $game_variables[$3.to_i]
    end
  end

  def retrieve_icon(icon)
    icons = { 0 => :'New Quest', 1 => :'Rewards', 2 => :'Failure', 3 => :'Shop',
      4 => :'Inn', 5 => :'Broken Heart', 6 => :'Love', 7 => :'Angry',
      8 => :'Cool', 9 => :'Deadly', 10 => :'Help', 11 => :'Stop', 12 => :'Fine'}
    icons[icon]
  end

  def setup_icon(text)
    sys = $game_system.map_interpreter
    # Show Icon Temporarily
    text.gsub!(/\\[Ss][Ii]\[([0-9])]/) do
      event = sys.get_character(0)
      event.show_icon(retrieve_icon($1.to_i))
      ''
    end
    # Dispose Icon Temporarily or Permanently
    text.gsub!(/\\[Dd][Ii]\[([0-1])]/) do
      event = sys.get_character(0)
      @proc = Proc.new {event.dispose_icon($1.to_i == 1) }
      ''
    end
  end

  def setup_portrait_options(text)
    text.gsub!(/cln\d/i){ @clean_pos = $1[/d/].to_i - 1; "\x06" }
    text.gsub!(/dim\d/i){ @dim_pos = $1[/d/].to_i - 1; "\x07" }
    text.gsub!(/fl\d/i){ @flip_pos = $1[/d/].to_i - 1; "\x08" }
  end

  def setup_font(text)
    text.gsub!(/\\ft\[([0-9]+)\]/i){"\#[#{$1}]"} # Font Type
    text.gsub!(/\\fs\[([0-9]+)\]/i){"\<[#{$1}]"} # Font Size
    text.gsub!(/\\b/i){"\\"} # Bold
    text.gsub!(/\\i/i){"\@"} # Italic
    text.gsub!(/\\jl/i){"\[#]"} # Text Alignment : Left-Hand Side
    text.gsub!(/\\jc/i){"\[^]"} # Text Alignment : Center
    text.gsub!(/\\jr/i){"\[*]"} # Text Alignment : Right-Hand Side
  end

  def reset_window
    kyon_kmessage_win_mess_reset_win
    self.y = 44 if $game_system.message_position == 0
  end

  def set_name(text='', color=nil)
    return unless KMessage::USE_NAME_SUBWINDOW
    @name_window = Window_CharacterName.new(96, self.y - 36)
    width = @name_window.contents.text_size(text).width
    @name_window.new_width = width + 32
    @name_window.contents.font.color = color if color != nil
    @name_window.contents.draw_text(0, -4, width, 28, text, 1)
    @name_window.opacity = self.opacity
    @name_window.back_opacity = self.back_opacity
  end

  def display_message_contents
    self.opacity = 180
    self.visible = @contents_showing = true
    $game_temp.message_window_showing = true
    refresh
    Graphics.frame_reset
  end

  def update
    super
    if @timer > 0
      @timer -= 1
      hit_ok_button if Input.trigger?(Input::C)
      return
    end
    if $game_temp.message_text and !$game_temp.message_text.empty?
      display_message_contents
    end
    if @fade_in
      self.contents_opacity += 24
      if @input_number_window != nil
        @input_number_window.contents_opacity += 24
      end
      @fade_in = false if self.contents_opacity == 255
      return
    end
    if @input_number_window != nil
      @input_number_window.update
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        vid = $game_temp.num_input_variable_id
        $game_variables[vid] = @input_number_window.number
        $game_map.need_refresh = true
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    if @contents_showing
      self.pause = true if $game_temp.choice_max == 0
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      elsif Input.trigger?(Input::C)
        hit_ok_button
      end
      return
    end
    if !@fade_out and $game_temp.message_text != nil
      $game_temp.message_window_showing = @contents_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      @input_number_window.contents_opacity = 0 if @input_number_window != nil
      return @fade_in = true
    end
    return unless self.visible
    @fade_out = true
    self.opacity -= 48
    return if self.opacity > 0
    self.visible = @fade_out = false
    $game_temp.message_window_showing = false
  end

  def hit_ok_button
    if $game_temp.choice_max > 0
      $game_system.se_play($data_system.decision_se)
      $game_temp.choice_proc.call(self.index)
    end
    if @use_type_mashine and !@done
      KPortrait.idle_now
      @finish = true
      @timer = 0
      display_message_contents
      @timer = 5
    else
      terminate_message
    end
  end
end

class Game_Event
  def name() @event.name end
end

class Window_Base
  def new_width=(n)
    self.width = n
    self.contents = Bitmap.new(n - 32, self.height % 32 == 0 ? 32 : 24)
  end
end

class Window_CharacterName < Window_Base
  def initialize(x, y)
    super(x, y, 48, 56)
    self.contents = Bitmap.new(32, 24)
    self.visible = true
    self.z = 9999
  end
end

[*]

Enlaces de Descarga


Español, Inglés


El demo en inglés usa toda la nomenclatura requerida en ese idioma.



[*]Cierto como se tardan SIETE días en aprobar a un nuevo usuario, no puedo dejarles el enlace de descarga... Ópalo Buscapleitos

#2 Re: KPortrait XP el Jue Sep 06, 2018 6:40 am

kyonides

avatar
Como no cupo en el post inicial, les dejo aquí la versión en inglés. Me pareció conveniente hacerlo por si necesitan descargar esa versión del demo o por alguna otra cosa que se les ocurra.

Versión en Inglés

Código:
# * KPortrait XP
#   Scripter : Kyonides-Arkanthes
#   2018-08-22 - 1.0.3

#   This script is free as in beer for demos, but game developers that include
#   it in their commercial games will need to send me a free copy of their game
#   without exceptions! I may also ask them to pay me a certain amount for
#   crafting this script.
  
#   Instructions

#   There are two ways to setup a portrait, first one is via script calls and
#   the latter would be leaving notes on an event. All portrait related
#   notes should be placed on a single line. The script won't care if you
#   typed all words capitalized or not, it's case insensitive, except for any
#   image file name; type the exact file names at all costs!
#   *Index* always stands for position, namely 1, 2 or 3 only.

#   It will display up to three portraits or faces at a time.

# * Script Calls *

#   KPortrait.show(filename, index, use_filename_as_name)

#   KPortrait.show('Aluxes')
#   KPortrait.show('Basil', 2)
#     It will just show Aluxes's portrait (or face) on the left hand side.
#     Basil's face will be shown to the right.

#   KPortrait.options(index, key => value)
#     :side - can be either :left or :center or :right. Their respective numeric
#       values would be 0, 1 and 2, you can use these as well.
#     :height - can be either :top or :upper, :half or :midlow, :low or :bottom.
#       :top can be replaced by 0, :midlow by 1 and :bottom by 2.
#     :mirror or :flip - Flip image, its values are true, false or nil.

#   KPortrait.x_pos(position, index) # Horizontal alignment
#     Options: 0, :left - Left. 1, :center - Center. 2, :right - Right

#   KPortrait.y_pos(position, index) # Vertical alignment
#   0, :top, :upper - Top. 1, :midlow, :half - Center. 2, :low, :bottom - Bottom

#   KPortrait.new_name('Candidate Aluxes', index)
#     Will print the character's name on top of the portrait or face.
#     It would better to set it before you call the show method mentioned above.

#   KPortrait.filename_as_name = true # or false or nil
#     Uses the filename found in KPortrait.show(filename) as a character's name.

#   KPortrait.talk_anime = true # or false or nil
#     Allows the script to update the current sprite

#   KPortrait.flip! or KPortrait.flip!(index)
#     The current portrait or face will be flipped.

#   KPortrait.show_name! or KPortrait.show_name!(index)
#   KPortrait.hide_name! or KPortrait.hide_name!(index)
#     Shows or hides a character's name, i.e. Aluxes or Evil Mage

#   KPortrait.clear
#     The current portrait(s) or face(s) are Reset and image(s) Discarded!

# * Comments *

#   Examples: Show Aluxes. or Show Botan, or Show Ace Attorney! or Show Me;

#   They include a dot, a comma or a semicolon or an exclamation mark to allow
#   you to leave blank spaces or underscores in file names.

#   Pic Number or Picture Number  # Selects Picture 1, 2 or 3
#       Not needed if you only will display one image on screen at a time.
#   Show   # it will show some picture
#   Image  # Type the image file name without file extensions like jpg or png
#   Dim    # Sets Dim Effect
#   Clean Number # Removes Dim Effect on Picture Number (1, 2 or 3)
#   Clean All # Removes All Dim Effects at once
#   State Number # Shows Effect Number from Animation DB
#   Flip   # Mirrors or flips the image
#   Mirror # Mirrors or flips the image
#   Left   # it will place the image to the left
#   Center # it will center the image
#   Right  # it will place the image to the right
#   Top or Upper   # Self explanatory
#   Midlow or Half # Centers the image vertically
#   Low or Bottom  # Self explanatory
#   Print Any Name # Shows character's name on top of it (last part of the line)
#   Print Hero-6   # Shows an actor's name (Felix)
#   Print Event    # Shows current event's name on top of it
#   Talk Anime On Pic 1 Filename # Activates that animation for a given picture
#   Talk Anime Off

module KPortrait
  FRAMES = { :talk => 3, :idle => 3 }
  SUFFIXES = ['_talk', '_idle']
  rate = Graphics.frame_rate # somewhere between 20 and 40 fps
  TALK_TIMER_MAX = rate / 10
  IDLE_TIMER_MAX = [rate * 2, rate / 8, rate / 8]
  # Constant useful only if you are going to use script calls
  FILENAMES = { :aluxes => 'Aluxes' }
  DEFAULT_HEIGHT = 100
  DEFAULT_WIDTH = 100
  @base_x = 80
  @base_y = 296
  @namebox_width = 160
  @sides = { 1 => :left, 2 => :right, 3 => :center }
  @heights = { 1 => :bottom, 2 => :bottom, 3 => :bottom }
  @show_name = true
  @filename_as_name = true
  @talk_anime = nil
  @normal_color = Color.new(0,0,0,0)
  @dim_color = Color.new(0,0,0,0)
  @align = [nil, :left, :right, :center]
  module_function
  def show(filename, pos=1, priority=true)
    filename = FILENAMES[filename] if filename.class == Symbol
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    sprite.filename = filename
    sprite.bitmap = portrait(filename)
    sprite.color = sprite.dim ? @dim_color.dup : @normal_color
    rect = sprite.src_rect
    new_name(filename, pos) if @show_name and @filename_as_name and priority
    return pos
  end

  def show_talk(pos, name)
    pos, name = @pos, @name if pos == nil or name == nil
    sprite = @talk_sprites[pos]
    sprite.talk_anime = true
    sprite.filename = name
    @pos = pos
    @name = name
  end

  def options(pos, options={})
    flip = options[:mirror] || options[:flip]
    if @talk_anime
      @talk_sprites[pos].mirror = flip
    else
      @face_sprites[pos].mirror = flip
    end
    side = options.delete(:side)
    height = options.delete(:height)
    x_pos(pos, side) if side and @sides[pos] != side
    y_pos(pos, height) if height# and @heights[pos] != height
  end

  def x_pos(location, pos=1)
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    widt = sprite.bitmap.width
    nx = case location
    when 0, :left then @base_x
    when 1, :mid, :center then (640 - widt) / 2
    when 2, :right then 640 - widt - @base_x
    end
    @sides[pos] = location
    @talk_sprites[pos].x = nx
    @face_sprites[pos].x = nx
    @name_sprites[pos].x = nx - 30 if widt < @namebox_width
  end

  def y_pos(location, pos=1, default=nil)
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    heigh = sprite.bitmap.height
    ny = case location
    when 0, :top, :upper then @base_y - 100
    when 1, :midlow, :middle, :half then (460 - heigh) / 2
    when 2, :low, :bottom then @base_y - heigh
    end
    @talk_sprites[pos].y = ny
    @face_sprites[pos].y = ny
    @name_sprites[pos].y = ny + 4
  end

  def new_name(text, pos=1)
    @name_sprites[pos].visible = @show_name = true
    bitmap = @name_sprites[pos].bitmap
    bitmap.clear rescue nil
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    new_y = sprite.bitmap.height - 28
    name = text || '?'
    bitmap.outline(0, new_y, @namebox_width, 28, name, 1)
  end

  def dim(boolean, pos=1)
    color = boolean ? @dim_color.dup : @normal_color.dup
    sprite = @talk_anime ? @talk_sprites[pos] : @face_sprites[pos]
    sprite.dim = boolean
    sprite.color = color
    sprite.dim = boolean
    sprite.color = color
    @name_sprites[pos].dim = boolean
    @name_sprites[pos].color = color
  end

  def state_anime(state_id, pos=1)
    animation = $data_animations[state_id]
    sprites = @talk_anime ? @talk_sprites : @face_sprites
    sprites[pos].animation(animation, true)
  end

  def clear_talk_sprites
    @talk_anime = nil
    1.upto(3) do |n|
      sprite = @talk_sprites[n]
      sprite.talk_anime = nil
      sprite.clear_filename
      sprite.dispose_bitmaps
    end
  end

  def clear
    @all_sprites.each do |sprite|
      sprite.bitmap.clear rescue nil
      sprite.mirror = nil
    end
    1.upto(3) do |n|
      dim(nil, n)
      x_pos(@align[n], n)
      y_pos(:bottom, n, nil)
    end
  end

  def idle_now
    @idle = true
    @talk_anime = nil
    1.upto(3) do |n|
      sprite = @talk_sprites[n]
      sprite.talk_anime = nil
      sprite.idle = @idle
      sprite.update
    end
  end

  def portrait(name)
    begin
      RPG::Cache.load_bitmap('Graphics/Portraits/', name).dup
    rescue
      Bitmap.new(100, 100)
    end
  end
  def update() @all_sprites.each {|sprite| sprite.update } end
  def flip!(pos=1) @talk_sprites[pos].mirror = true end
  def flip?(pos=1) @talk_sprites[pos].mirror end
  def show_name?() @show_name end
  def show_name!() @show_name = true end
  def hide_name!() @show_name = nil end
  class << self
    attr_accessor :talk_anime
    attr_reader :idle, :base_x, :sides, :widths, :heights, :talk_sprites
  end
end

class KPortraitSprite < RPG::Sprite
  DIM_ALPHA = 120
  attr_writer :filename
  attr_reader :dim
  def dim=(boolean) @refresh_dim = @dim = boolean end
  def update
    super
    return unless @refresh_dim
    return if color.alpha == DIM_ALPHA
    color.alpha += 15
    @refresh_dim = nil if color.alpha == DIM_ALPHA
  end
end

class KPortraitTalkSprite < KPortraitSprite
  attr_reader :talk_frames, :idle_frames, :idle
  attr_accessor :talk_anime
  def initialize
    super(nil)
    @timer = KPortrait::TALK_TIMER_MAX
    @talk_index = @idle_index = 0
    @talk_max = KPortrait::FRAMES[:talk]
    @idle_max = KPortrait::FRAMES[:idle]
    self.filename = ''
  end

  def filename=(name)
    @filename = name
    make_frames
  end

  def make_frames
    @talk_frames = []
    @idle_frames = []
    if @filename.empty?
      @talk_max.times { @talk_frames << Bitmap.new(100, 100) }
      @idle_max.times { @idle_frames << Bitmap.new(100, 100) }
    else
      suffix1, suffix2 = KPortrait::SUFFIXES
      name = @filename + suffix1
      bmap = KPortrait.portrait(name)
      bw = bmap.width / @talk_max
      bh = bmap.height
      @talk_max.times do |n|
        @talk_frames << bit = Bitmap.new(bw, bh)
        bit.blt(0, 0, bmap, Rect.new(n * bw, 0, bw, bh))
      end
      bmap.dispose
      name = @filename + suffix2
      bmap = KPortrait.portrait(name)
      bw = bmap.width / @idle_max
      @idle_max.times do |n|
        @idle_frames << bit = Bitmap.new(bw, bmap.height)
        bit.blt(0, 0, bmap, Rect.new(n * bw, 0, bw, bmap.height))
      end
      bmap.dispose
    end
    update_current_bitmap
  end

  def update
    super
    @timer -= 1
    update_current_bitmap if @timer == 0
  end

  def update_current_bitmap
    if @talk_anime
      @timer = KPortrait::TALK_TIMER_MAX
      @talk_index = (@talk_index + 1) % @talk_max
      self.bitmap = @talk_frames[@talk_index]
    elsif @idle
      @idle_index = (@idle_index + 1) % @idle_max
      @timer = KPortrait::IDLE_TIMER_MAX[@idle_index]
      self.bitmap = @idle_frames[@idle_index]
    end
  end

  def idle=(boolean)
    @idle_index = 2 if boolean
    @idle = boolean
  end

  def dispose_bitmaps
    @talk_frames.each {|bit| bit.dispose }
    @idle_frames.each {|bit| bit.dispose }
  end
  def clear_filename() @filename = '' end
end

module KPortrait
  # Constants needed in case you prefer to leave notes - DO NOT EDIT THEM!
  ID_REGEX = /Pic[\w]+ [\d\w]+ /i
  POSITION_REGEX = [/first/i, /second/i, /third/i]
  SHOW_REGEX = /Show [\w \-_]+[\.,!;]/i
  CHARACTER_NAME_REGEX = /print [\w_\- ]+/i
  HORZ_REGEX = /left|right|center|show|pic[\w]+ [\d\w]+| /i
  VERT_REGEX = /middle|top|low|upper|bottom|midlow|half|center/i
  def self.make_dummy_sprites
    a = load_data('Data/Actors.rxdata')[1]
    @talk_sprites = {}
    @face_sprites = {}
    @name_sprites = {}
    1.upto(3) do |n|
      @talk_sprites[n] = sprite = KPortraitTalkSprite.new
      sprite.z = 200
      sprite.bitmap = RPG::Cache.battler(a.battler_name, a.battler_hue).dup
      @face_sprites[n] = sprite = KPortraitSprite.new
      sprite.z = 200
      sprite.bitmap = Bitmap.new(DEFAULT_WIDTH + 70, DEFAULT_HEIGHT)
      @name_sprites[n] = sprite = KPortraitSprite.new
      sprite.z = 200
      sprite.bitmap = Bitmap.new(DEFAULT_WIDTH + 70, DEFAULT_HEIGHT)
    end
    @all_sprites = [@talk_sprites[1], @talk_sprites[2], @talk_sprites[3]]
    @all_sprites += [@face_sprites[1], @face_sprites[2], @face_sprites[3]]
    @all_sprites += [@name_sprites[1], @name_sprites[2], @name_sprites[3]]
    clear
  end
  make_dummy_sprites
end

class Game_System
  alias kyon_kportrait_gm_sys_up update
  def update
    KPortrait.update
    kyon_kportrait_gm_sys_up
  end
end

class Game_Event
  def name() @event.name end
end

class Interpreter
  NOTE_CODES = [108, 408]
  alias kyon_kportrait_int_exec_comm execute_command
  def execute_command
    kyon_kportrait_int_exec_comm
    if @list and NOTE_CODES.include?(@list[@index].code)
      note = @list[@index].parameters[0].dup
      return KPortrait.clear if note[/clear/i]
      pos = note[/talk anime/i] ? check_talk_anime(note) :  check_portrait(note)
      if note[/flip|mirror/i]
        KPortrait.flip!(pos)
        note.gsub!(/flip|mirror/i,'')
      end
      if note[/dim/i]
        n = note[/dim \d/i]
        n = n ? n[/\d/].to_i : pos
        KPortrait.dim(true, n)
        note.sub!(/dim/i,'')
      end
      KPortrait.x_pos(:left, pos) if note[/left/i]
      KPortrait.x_pos(:center, pos) if note[/mid|center/i]
      KPortrait.x_pos(:right, pos) if note[/right/i]
      KPortrait.y_pos(:top, pos) if note[/top|upper/i]
      KPortrait.y_pos(:low, pos) if note[/low|bottom/i]
      KPortrait.y_pos(:midlow, pos) if note[/half|midlow/i]
    end
    return true
  end

  def check_talk_anime(note)
    note.sub!(/talk anime /i, '')
    KPortrait.talk_anime = found = note[/on/i] != nil
    if found and
      if (data = note[/pic \d+/i])
        pos = data.scan(/\d+/)[0].to_i rescue 1
        name = note[/show \w+/i].sub(/show /i,'')
      else
        pos, name = nil, nil
      end
      KPortrait.show_talk(pos, name)
    else
      KPortrait.clear_talk_sprites
    end
    return pos ||= 1
  end

  def check_portrait(note)
    note = note.gsub(/dim|mirror|flip/i,'')
    priority = false
    rx1, rx2, rx3 = KPortrait::POSITION_REGEX
    pos = 1 if note[rx1]
    pos = 2 if note[rx2]
    pos = 3 if note[rx3]
    digit = note[/\d/]
    pos ||= digit.to_i
    pos = 1 if pos == 0
    kp = KPortrait
    if note[/clean/i]
      n = note[/clean \d/i][/\d/].to_i || pos
      note[/clean all/i] ? 3.times{|n| kp.dim(nil, n+1) } : kp.dim(nil, n)
      note.sub!(/clean all|clean \d/i,'')
    end
    if (state = note[/state \d+/i])
      kp.state_anime(state[/\d+/].to_i, pos)
      note.sub!(/state \d+/i,'')
    end
    if (name = note[kp::CHARACTER_NAME_REGEX])
      note.sub!(kp::CHARACTER_NAME_REGEX,'')
      name.sub!(/event/i) do
        inter = $game_system.map_interpreter
        inter.get_character(0).name
      end
      name.sub!(/print /i,'')
      name.sub!(/hero-(\d+)/i){ $game_actors[$1.to_i].name }
      kp.new_name(name.dup, pos)
      priority = true
    end
    return pos if note[kp::SHOW_REGEX] == nil
    priority = !priority
    filename = note.dup.gsub(kp::HORZ_REGEX,'')
    filename.gsub!(kp::VERT_REGEX,'')
    filename.gsub!(kp::ID_REGEX,'')
    filename.gsub!(/pic\d|picture\d|[\.,;! ]/i,'')
    kp.show(filename, pos, priority)
  end
end

Código:
# * KMessage XP
#   2018-08-18 - 0.9.2 - English Version
#   Scripter : Kyonides-Arkanthes

#   This script is free as in beer for demos, but game developers that include
#   it in their commercial games will need to send me a free copy of their game
#   without exceptions! I may also ask them to pay me a certain amount for
#   crafting this script.


# * Warning *

#   This script is extremely incompatible with any other Message System that may
#   be available out there! Never try to use several of them at the same time!

# * Type Mashine Writing Style *

#   There are two ways to enable or disable it.

#   Initial Value
#     @type_mashine_style = true # can be either true or false or nil
#   In Game Script Call
#     KMessage.type_mashine_style = true # or false or nil

# * Available Options *

#   Hit OK button to skip waiting pauses produced by some of the following tags:

#   \. - Pauses the message drawing process for 10 seconds
#   \! - Pauses the message drawing process for 20 seconds
#   \< - Pauses the message drawing process for 40 seconds
#   \> - Pauses the message drawing process for 60 seconds
#   B or b - Bold or Strong
#   I or i - Italic
#   FT[Number] or ft[Number] - Font Type (Check out CustomSettings Module!)
#   FS[Number] or fs[Number] - Font Size
#   IT[Number] or it[Number] - Item name displayed on the Message Window!
#   W[Number] or w[Number]   - Weapon name displayed on the Message Window!
#   A[Number] or a[Number]   - Armor name displayed on the Message Window!
#   SK[Number] or sk[Number] - Skill name displayed on the Message Window!

# * Optional * - Do Not Use This if you've included KPortrait XP script!

#   WA[Number] or wa[Number] - Actor's name displayed on a Subwindow!
#   WE[Number] or we[Number] - Event's name displayed on a Subwindow!
#   E[Number] or e[Number]   - Enemy's name displayed on a Subwindow!

# * KPortrait's Options *
#   \cln1  or  \cln2  or  \cln3  - Cleans Dim Effect on Picture Number
#   \dim1  or  \dim2  or  \dim3  - Appies Dim Effect on Picture Number
#   \fl1  or  \fl2  or  \fl3     - Flips Picture Number

# * Experimental *
#   JL or jl - Text Alignment : Left-Hand Side
#   JC or jc - Text Alignment : Center
#   JR or jr - Text Alignment : Right-Hand Side

module KMessage
  @type_mashine_style = true # Slow Dialogue Printing Method?
  USE_NAME_SUBWINDOW = nil
  FONTS = [Font.default_name, 'Times New Roman', 'Arial', 'Verdana', 'Vivaldi',
    'Comic Sans MS', 'Trebuchet MS', 'UmePlus Gothic', 'Tahoma', 'Castellar']
  def self.type_mashine_style() @type_mashine_style end
  def self.type_mashine_style=(boolean) @type_mashine_style = boolean end
end

class Window_Message
  alias kyon_kmessage_win_mess_init initialize
  alias kyon_kmessage_win_mess_term_mess terminate_message
  alias kyon_kmessage_win_mess_reset_win reset_window
  def initialize
    kyon_kmessage_win_mess_init
    @use_type_mashine = KMessage.type_mashine_style
    @timer = 0
    @clean_pos = @dim_pos = @flip_pos = nil
  end

  def terminate_message
    if @proc
      @proc.call
      @proc = nil
    end
    @last_y = @last_x = @timer = 0
    kyon_kmessage_win_mess_term_mess
    return if @name_window.nil?
    @name_window.dispose
    @clean_pos = @dim_pos = @flip_pos = nil
    @name_window = @text = @finish = @done = nil
  end

  def refresh
    self.contents.clear unless @keep_text
    if @keep_text
      x = @last_x
      y = @last_y
      @last_x = @last_y = @keep_text = nil
    else
      x = y = @cursor_width = 0
      x = 8 if $game_temp.choice_start == 0
    end
    self.contents.font.color = normal_color
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      include_switch_variable(text)
      include_pauses(text)
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) {
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : "" }
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" } #text = $game_temp.message_text
      retrieve_names(text)
      setup_portrait_options(text)
      setup_font(text)
      setup_icon(text)
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      while ((c = text.slice!(/./m)) != nil)# If \\
        case c
        when "\x02" then @timer = 10
        when "\x03" then @timer = 20
        when "\x04" then @timer = 40
        when "\x05" then @timer = 60
        when "\x06" then KPortrait.dim(@clean_pos, nil) rescue nil
        when "\x07" then KPortrait.dim(@dim_pos, true) rescue nil
        when "\x08" then KPortrait.flip!(@flip_pos, true) rescue nil
        end
        if @timer > 0
          @finish = nil
          @keep_text = true
          @last_x = x
          @last_y = y
          break
        end
        if c == "\000"
          c = "\\" # Return to original text
        elsif c == "\001" # If \C[n]
          text.sub!(/\[([0-9]+)\]/, "") # Change text color
          color = $1.to_i
          contents.font.color = text_color(color) if color >= 0 and color <= 7
          next
        elsif c == "\002" # If \G
          if @gold_window == nil # Make gold window
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else @gold_window.y = self.y >= 128 ? 32 : 384 end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          next
        end
        if c == "\\" # Bold or Strong or Emphasis
          contents.font.bold, c = !contents.font.bold, ''
          next
        elsif c == "\@" # Italic
          contents.font.italic, c = !contents.font.italic, ''
          next
        end
        align, c = case c
        when "\[#]" then [0, ''] # \JL \jl Text Alignment : Left-Hand Side
        when "\[^]" then [1, ''] # \JC \jc Text Alignment : Center
        when "\[*]" then [2, ''] # \JR \jr Text Alignment : Right-Hand Side
        else [0, c] end
        if c == "\#" # Font Type
          text.sub!(/\[([0-9]+)\]/, "")
          c, contents.font.name = '', KMessage::FONTS[$1.to_i]
          next
        elsif c == "\<" # Font Size
          text.sub!(/\[([0-9]+)\]/, "")
          c, contents.font.size = '', $1.to_i
          next
        elsif c == "\n"
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          y += 1
          x = y >= $game_temp.choice_start ? 8 : 0
          next
        end
        self.contents.draw_text(x+4, 32*y, 40, 32, c, align)
        x += self.contents.text_size(c).width # Add x to drawn text width
        next if @finish or !@use_type_mashine
        @timer += 1
        @keep_text = true
        @last_x = x
        @last_y = y
        break
      end
      @finish = nil
      @done = (@timer == 0 and (text == nil or text.empty?))
      KPortrait.idle_now if @done
    end
    if $game_temp.choice_max > 0 # If choice
      @item_max = $game_temp.choice_max
      self.active, self.index = true, 0
    elsif $game_temp.num_input_variable_id > 0 # If number input
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
    end
  end

  def include_switch_variable(text)
    begin
      last_text = text.clone
      text.gsub!(/\\v\[([0-9]+)\]/i) { $game_variables[$1.to_i] }
      text.gsub!(/\\s\[([0-9]+)\]/i) { $game_switches[$1.to_i] } # Sw. ID Status
    end until text == last_text
  end

  def include_pauses(text)
    text.gsub!(/\\\./, "\x02")
    text.gsub!(/\\!/, "\x03")
    text.gsub!(/\\</, "\x04")
    text.gsub!(/\\>/, "\x05")
  end

  def retrieve_names(text)
    # Get Actor Name and Open Name Window
    text.gsub!(/\\wa\[([0-9]+)\]/i){ name = $game_actors[$1.to_i].name
      set_name(name); '' }
    # Get Event Name and Open Name Window
    text.gsub!(/\\we\[([0-9]+)\]/i){ name = $game_map.events[$1.to_i].name
      set_name(name); '' }
    # Get Enemy Name
    text.gsub!(/\\e\[([0-9]+)\]/i) {
      $data_enemies[$1.to_i] != nil ? $data_enemies[$1.to_i].name : '' }
    # Get Item Name
    text.gsub!(/\\it\[([0-9]+)\]/i) {
      $data_items[$1.to_i] != nil ? $data_items[$1.to_i].name : '' }
    # Get Weapon Name
    text.gsub!(/\\w\[([0-9]+)\]/i) {
      $data_weapons[$1.to_i] != nil ? $data_weapons[$1.to_i].name : '' }
    # Get Armor Name
    text.gsub!(/\\a\[([0-9]+)\]/i) {
      $data_armors[$1.to_i] != nil ? $data_armors[$1.to_i].name : '' }
    # Get Skill Name
    text.gsub!(/\\sk\[([0-9]+)\]/i) {
      $data_skills[$1.to_i] != nil ? $data_skills[$1.to_i].name : '' }
    # Get Event ID and Variable ID - Return Event name - Current Map
    text.gsub!(/\\ev\[([0-9]+),([0-9]+)\]/i) do
      $game_variables[$2.to_i] = $game_map.events[$1.to_i].name
      $game_variables[$2.to_i]
    end
    # Get Event ID and Variable ID - Return Event name - Not Current Map
    text.gsub!(/\\mev\[([0-9]+),([0-9]+),([0-9]+)\]/i) do
      events = load_data(sprintf("Data/Map%03d.rxdata", $1.to_i)).events
      $game_variables[$3.to_i] = events[$2.to_i].name
      $game_variables[$3.to_i]
    end
  end

  def retrieve_icon(icon)
    icons = { 0 => :'New Quest', 1 => :'Rewards', 2 => :'Failure', 3 => :'Shop',
      4 => :'Inn', 5 => :'Broken Heart', 6 => :'Love', 7 => :'Angry',
      8 => :'Cool', 9 => :'Deadly', 10 => :'Help', 11 => :'Stop', 12 => :'Fine'}
    icons[icon]
  end

  def setup_icon(text)
    sys = $game_system.map_interpreter
    # Show Icon Temporarily
    text.gsub!(/\\[Ss][Ii]\[([0-9])]/) do
      event = sys.get_character(0)
      event.show_icon(retrieve_icon($1.to_i))
      ''
    end
    # Dispose Icon Temporarily or Permanently
    text.gsub!(/\\[Dd][Ii]\[([0-1])]/) do
      event = sys.get_character(0)
      @proc = Proc.new {event.dispose_icon($1.to_i == 1) }
      ''
    end
  end

  def setup_portrait_options(text)
    text.gsub!(/cln\d/i){ @clean_pos = $1[/d/].to_i - 1; "\x06" }
    text.gsub!(/dim\d/i){ @dim_pos = $1[/d/].to_i - 1; "\x07" }
    text.gsub!(/fl\d/i){ @flip_pos = $1[/d/].to_i - 1; "\x08" }
  end

  def setup_font(text)
    text.gsub!(/\\ft\[([0-9]+)\]/i){"\#[#{$1}]"} # Font Type
    text.gsub!(/\\fs\[([0-9]+)\]/i){"\<[#{$1}]"} # Font Size
    text.gsub!(/\\b/i){"\\"} # Bold
    text.gsub!(/\\i/i){"\@"} # Italic
    text.gsub!(/\\jl/i){"\[#]"} # Text Alignment : Left-Hand Side
    text.gsub!(/\\jc/i){"\[^]"} # Text Alignment : Center
    text.gsub!(/\\jr/i){"\[*]"} # Text Alignment : Right-Hand Side
  end

  def reset_window
    kyon_kmessage_win_mess_reset_win
    self.y = 44 if $game_system.message_position == 0
  end

  def set_name(text='', color=nil)
    return unless KMessage::USE_NAME_SUBWINDOW
    @name_window = Window_CharacterName.new(96, self.y - 36)
    width = @name_window.contents.text_size(text).width
    @name_window.new_width = width + 32
    @name_window.contents.font.color = color if color != nil
    @name_window.contents.draw_text(0, -4, width, 28, text, 1)
    @name_window.opacity = self.opacity
    @name_window.back_opacity = self.back_opacity
  end

  def display_message_contents
    self.opacity = 180
    self.visible = @contents_showing = true
    $game_temp.message_window_showing = true
    refresh
    Graphics.frame_reset
  end

  def update
    super
    if @timer > 0
      @timer -= 1
      hit_ok_button if Input.trigger?(Input::C)
      return
    end
    if $game_temp.message_text and !$game_temp.message_text.empty?
      display_message_contents
    end
    if @fade_in
      self.contents_opacity += 24
      if @input_number_window != nil
        @input_number_window.contents_opacity += 24
      end
      @fade_in = false if self.contents_opacity == 255
      return
    end
    if @input_number_window != nil
      @input_number_window.update
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        vid = $game_temp.num_input_variable_id
        $game_variables[vid] = @input_number_window.number
        $game_map.need_refresh = true
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    if @contents_showing
      self.pause = true if $game_temp.choice_max == 0
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      elsif Input.trigger?(Input::C)
        hit_ok_button
      end
      return
    end
    if !@fade_out and $game_temp.message_text != nil
      $game_temp.message_window_showing = @contents_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      @input_number_window.contents_opacity = 0 if @input_number_window != nil
      return @fade_in = true
    end
    return unless self.visible
    @fade_out = true
    self.opacity -= 48
    return if self.opacity > 0
    self.visible = @fade_out = false
    $game_temp.message_window_showing = false
  end

  def hit_ok_button
    if $game_temp.choice_max > 0
      $game_system.se_play($data_system.decision_se)
      $game_temp.choice_proc.call(self.index)
    end
    if @use_type_mashine and !@done
      KPortrait.idle_now
      @finish = true
      @timer = 0
      display_message_contents
      @timer = 5
    else
      terminate_message
    end
  end
end

class Game_Event
  def name() @event.name end
end

class Window_Base
  def new_width=(n)
    self.width = n
    self.contents = Bitmap.new(n - 32, self.height % 32 == 0 ? 32 : 24)
  end
end

class Window_CharacterName < Window_Base
  def initialize(x, y)
    super(x, y, 48, 56)
    self.contents = Bitmap.new(32, 24)
    self.visible = true
    self.z = 9999
  end
end

#3 Re: KPortrait XP el Jue Sep 06, 2018 2:05 pm

Ledai

avatar
Gracias por tus aportes; en especial porque son del XP Ópalo Carcajada
Lástima que actualmente ya uso un script de texto para el proyecto, si no tal vez le echara un ojo.
humm se agradecerían unas capturas en el post para ver parte del resultado.

Ópalo Reputación

#4 Re: KPortrait XP el Jue Sep 06, 2018 2:10 pm

kyonides

avatar
Como ópalo lo expuso ya, sin acceso a postear enlaces no podré hacerlo realidad...

Contenido patrocinado


Ver el tema anterior Ver el tema siguiente Volver arriba  Mensaje [Página 1 de 1.]

Permisos de este foro:
No puedes responder a temas en este foro.