O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

MBS - Chat com NPC por digitação

Iniciado por Brandt, 17/10/2013 às 22:58

17/10/2013 às 22:58 Última edição: 20/01/2017 às 09:24 por King Gerar
[box class=titlebg]
MBS - Chat com NPC por digitação
[/box]
por Masked


[box class=titlebg]Introdução[/box]Esse script foi pedido do matheusco na CRM, atualmente o membro AGS pediu que o script fosse arrumado, então decidi fazer essa versão nova

[box class=titlebg]Características[/box]Esse script cria a opção de inserir uma mensagem em uma caixa de texto ao conversar com um NPC, dependendo do que você escrever, o NPC responderá à mensagem.

[box class=titlebg]Instruções[/box]O MBS - Chat com NPC requer o script MBS - Keyboard Input

Outras informações, nos comentários do script.

[box class=titlebg]Script[/box]
#==============================================================================
# MBS - Chat com NPC por Digitação
#------------------------------------------------------------------------------
# por Masked
#==============================================================================
#==============================================================================
# Instruções
#------------------------------------------------------------------------------
# Para chamar uma conversa com um NPC:
#
# MBS::NPC_Chat.npc_talk('nome do npc')
# Sendo 'nome do npc' o nome do NPC que você usou nas configurações, 
# essencialmente entre aspas simples ou duplas.
#==============================================================================
($imported ||= {})[:mbs_npc_chat] = true
module MBS
  module NPC_Chat
    NPC = {}
#==============================================================================
# Configurações
#------------------------------------------------------------------------------
# Nas configurações, use o modelo:
#
# NPC['nome do npc'] = {
#   'texto'    => { switch: [1, true], message: ['Você escreveu "texto"'] }
#   /(regexp)/ => { switch: [2, true], variables: [1], message: 'Você escreveu "regexp"' }
#   :else      => { switch: [3, true], message: ['Não entendi o que você escreveu', 1] }
#   /sair/     => {  },
#   :exit      => { message: ['Adeus!'] }
# }
#
# No modelo, 'nome do npc' é o nome que você dará à configuração do NPC no
# script, tenha em mente que não é possível criar dois NPCs com o mesmo nome
#
# O 'texto' é o texto que deve ser inserido e que o NPC entenderá, o texto só
# é válido quando escrito exatamente igual ao texto nas configurações,
# a 'switch:' é uma lista com dois itens, o primeiro é o ID da switch que será
# modificada com a ação e o segundo é true (ON) ou false (OFF), e 'message:'
# que tem uma lista com um texto e, opcionalment, o número do fundo da mensagem 
# (0 = normal, 1 = escuro, 2 = transparente) e a posição dela
# (0 = cima, 1 = meio, 2 = baixo)
#
# Para criar um texto para sair da conversa, só crie uma chave no NPC e deixe
# as ações dela vazias.
#
# Você também pode criar uma chave :exit no NPC para definir o que acontece 
# quando o chat é fechado.
#
# O '/(regexp)/' é uma Regexp (Regular Expression), funciona quase como o texto
# mas permite que os 'matches' sejam armazenados em variáveis, listadas na 
# lista 'variables:', e que todos os recursos que uma regexp proporciona sejam
# aplicados.
#
# O :else é usado quando o texto digitado não condiz com nenhum texto esperado.
# Se nenhuma entrada :else for declarada, a ação padrão ELSE_ACTION será 
# executada
#==============================================================================

    # Tamanho máximo padrão para o texto do chat
    DEFAULT_SIZE = 32

    # Ação padrão para excessão
    ELSE_ACTION = { message: ['Não te entendi!'] } # Mostra a mensagem
    
    # Texto padrão a ser inserido para sair do chat
    EXIT = /sair/i
    
    # Ação padrão para sair
    EXIT_ACTION = { message: ['Adeus!'] }
    
    # Texto usado na janela de chat (pode ser deixado em branco)
    INSERT_TEXT = 'Digite algo:'

    # Configuração do NPC 'vendedor'
    NPC['vendedor'] = {
      /quero comprar (\d+) (.+)/i => { switch:  [1, true], variables: [1, 2] },
      /quero vender (\d+) (.+)/i  => { switch:  [2, true], variables: [1, 2] },
      :else                       => { message: ['O quê? Não te entendi!'] },
      :exit                       => { message:  ['Volte sempre!'] }
    }
    
    # Configuração do NPC 'adivinho'
    NPC['adivinho'] = {
      /quero ver minha sorte/i    => { switch: [3, true] },
      :else                       => { message: ['Não te entendi...']  },
    }
    
    # Configuração do NPC 'cheat'
    NPC['cheat'] = {
      /(maçã|apple)/i => { switch:  [4, true] },
      '42'            => { switch:  [5, true] },
      :else           => { message:  ['Código inválido'] },
    }
    
#==============================================================================
# Fim das configurações
#==============================================================================
  end
end

#------------------------------------------------------------------------------
unless $imported[:mbs_keyboard_input]
  raise 'O script MBS - Chat com NPC por Digitação requer o script MBS - Keyboard Input' 
end
#------------------------------------------------------------------------------

#==============================================================================
# ** Game_Interpreter
#==============================================================================
class Game_Interpreter
  #----------------------------------------------------------------------------
  # * Exibição de uma janela de mensagem
  #----------------------------------------------------------------------------
  def show_message(text, background=0, position=2)
    $game_message.background = background
    $game_message.position = position
    $game_message.add(text)
  end
end

#==============================================================================
# ** Window_InputNPC
#==============================================================================
class Window_InputNPC < Window_Base
  attr_reader :done, :input, :npc, :size
  
  #----------------------------------------------------------------------------
  # * Inicialização
  #----------------------------------------------------------------------------
  def initialize(npc, size)
    super(0, Graphics.height-window_height, window_width, window_height)
    Keyboard.utf8(2)
    @done = false
    @size = size
    @npc = npc
    @input = ''
    @frame = 1
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição da altura da janela
  #----------------------------------------------------------------------------
  def window_height
    fitting_height(4)
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição da altura da janela
  #----------------------------------------------------------------------------
  def window_width
    Graphics.width
  end
  
  #----------------------------------------------------------------------------
  # * Atualização
  #----------------------------------------------------------------------------
  def update
    o = @input.dup
    return if @done
    c = Keyboard.utf8(2)
    if c == "\n"
      @done = true
    elsif c == "\b"
      @input.chop!
    elsif c != ''
      if @input.size < @size
        @input += c
      else
        Sound.play_buzzer
      end
    end
    refresh
  end
  
  #----------------------------------------------------------------------------
  # * Renovação
  #----------------------------------------------------------------------------
  def refresh
    self.contents.clear
    change_color(system_color)
    draw_text(0, 0, window_width, self.contents.font.size, MBS::NPC_Chat::INSERT_TEXT)
    change_color(@input.size < @size ? normal_color : crisis_color)
    draw_text(0, window_height/2-self.contents.font.size, window_width, self.contents.font.size, @input + (@frame % 4 == 0 ? '|' : ' '), 1)
    @frame += 1
    @frame %= 50
  end
end

#==============================================================================
# >> MBS::NPC_Chat
#==============================================================================
module MBS::NPC_Chat
  extend self
  
  #----------------------------------------------------------------------------
  # * Execução das ações
  #----------------------------------------------------------------------------
  def run(hash, match=nil)
    if hash[:switch]
      $game_switches[hash[:switch][0].to_i] = hash[:switch][1]
    end
    if hash[:message]
      $game_map.interpreter.show_message(hash[:message][0].to_s, (hash[:message][1] || 0).to_i, (hash[:message][2] || 2).to_i)
    end
    if hash[:variables] && match
      hash[:variables].each_with_index do |v, i|
        $game_variables[v] = match[i]
      end
    end
    @success = true
  end
  
  #----------------------------------------------------------------------------
  # * Chamada de um NPC
  #----------------------------------------------------------------------------
  def npc_talk(name, size=DEFAULT_SIZE)
    if NPC[name]
      return if $game_message.busy?
      @success = false
      if SceneManager.scene.is_a? Scene_Map
        @window = Window_InputNPC.new(NPC[name], size)
        until @window.done
          6.times {Graphics.update}
          @window.update
        end
        NPC[name].each do |k, v|
          next unless k.is_a?(String) || k.is_a?(Regexp)
          next unless v.is_a?(Hash)
          if k.is_a?(Regexp)
            if @window.input =~ k
              run(v, $~)
            end   
          else
            if @window.input == k
              run(v)
            end 
          end
        end
        if @window.input =~ EXIT
          run EXIT_ACTION
        end
        @window.close
        @window.dispose 
        unless @success
          if NPC[name][:else]
            run NPC[name][:else]
          else
            run ELSE_ACTION
          end
          @success = false
        end
        unless @success
          npc_talk(name, size)
        end
      else
        raise 'Não é possível falar com um NPC fora do mapa'
      end
    else
      raise 'NPC "' + name + '" inexistente'
    end
  end
end


[box class=titlebg]Créditos e Agradecimentos[/box]- A mim, por criar e disponibilizar;
- Ao matheusco, pela ideia.
~ Masked

Bem interessante o script. Só queria uma demo para poder testar o script, porque eu sou preguiçoso .

Eu tinha comentado no outro tópico então só passei aqui para reforçar meu comentário. Excelente script, Masked!  Não tem como fazer um sistema de ponta que adivinhe mil frases, mas você fez um ótimo trabalhado nesse. Achei muito interessante!

Viva a lenda!



Obrigado pelos comentários, a demo foi adicionada  :ok:
~ Masked

18/10/2013 às 00:12 #4 Última edição: 18/10/2013 às 00:20 por Kowts
muito bom o script... excelente, esta de parabéns, simplesmente genial, ficou ótimo trabalho.
Não só pela ideia e pelo trabalho mas também pela simplicidade do script.
+ouro
... ... ...

Revivendo o tópico aki galera
mas tem uma coisa...
eu baixei a demo e não esta pegando(parece)
tipo eu digito
espada e aparece a msg q ele não entendeu
tbm digito as outras e nada tbm
alguem poderia ver para mim plis?  :T.T:

Legal. Pena que não dá pra usar o ponto de interrogação, sempre tive vontade de criar algo no estilo CHATROOM.

Ops, vou ver isso Rafaelz.

E Rodrigo, bom que gostou, vou ver aqui se adiciono pontos, é que o script é bem antigo então dá preguiça de mexer nele  :=p:
~ Masked

Está dando um erro quando eu inico o jogo ... Alguem pode arrumar o script? :C por favor
Tudo vai dar certo (y(8.

 :ok:
grande Masked,sempre nos sites de Rpg maker que estou

Atualização :)  (depois de muito, muuuuuito tempo...)



  • Corrigida a penca de bugs que o script tinha, incluindo mal funcionamento em alguns casos e a janela desnecessariamente colossal.
  • O script foi inteiro reescrito, as gambiarras foram (quase) todas tiradas e agora as coisas funcionam menos problematicamente (sem falar na legibilidade do código, que antes tava ó...)
  • Adicionadas opções de customização (uso de Regexes, armazenamento de Matches em variáveis, exibição automática de mensagens...)
  • Suporte a acentos (viva o script de Keyboard Input xD)
  • Agora é possível definir o limite de caracteres para o texto a cada vez que a conversa com qualquer NPC é chamada
~ Masked