MBS - Chat com NPC por digitação

10 Respostas   2761 Visualizações

0 Membros e 1 Visitante estão vendo este tópico.

Brandt

Tópico criado em: 17/10/2013 às 22:58 - Última modificação por King Gerar em 20/01/2017 às 09:24

MBS - Chat com NPC por digitação
por Masked


Introdução
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

Características
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.

Instruções
O MBS - Chat com NPC requer o script MBS - Keyboard Input

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

Script
Código: [Selecionar]
#==============================================================================
# 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

Créditos e Agradecimentos
- A mim, por criar e disponibilizar;
- Ao matheusco, pela ideia.
~ Masked

Ds

  • Veterano
  • *
  • Posts: 640
  • Ouros: 184
  • Don't!
Resposta 1: 17/10/2013 às 23:13

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

VincentVII

  • Veterano
  • *
  • Posts: 2263
  • Ouros: 878
  • Voltando aos poucos!
Resposta 2: 17/10/2013 às 23:36

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!

Brandt

Resposta 3: 18/10/2013 às 00:02

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

Kowts

  • *
  • Posts: 96
  • Ouros: 104
  • Remember an apple a day keeps the doctor away!!!
Resposta 4: 18/10/2013 às 00:12 - Última modificação por Kowts em 18/10/2013 às 00:20

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
... ... ...

Rafaelz98

  • *
  • Posts: 31
  • Ouros: 0
  • Sem dor, Sem vitória.
Resposta 5: 21/01/2014 às 17:24

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:

RodrigoAijo

Resposta 6: 21/01/2014 às 19:34

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

Brandt

Resposta 7: 21/01/2014 às 20:07

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

katumblo

  • *
  • Posts: 555
  • Ouros: 211
  • Aposentado esperando o Uthred pagar minha aposent.
  • Equipamentos "Este era muito usado nas famosas e aclamadas justas. A pequena abertura era só para a visão mesmo. Ainda bem que guardei um." "O azul da cota de malha e o dourado da ombreira contrastam com o aço forte e resistente desta armadura." "Quando reerguemos nossa CRM, árduas foram as batalhas, e sempre tivemos em mãos nossos escudos. Este representa nossas defesas, e nele, as engrenagens que nos move." "Se não lhe dão a glória, conquiste-a com uma beleza dessas. Confie em mim, não há odalisca que resista."
Resposta 8: 01/03/2014 às 00:31

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

shinobida

  • *
  • Posts: 1
  • Ouros: 0
Resposta 9: 07/05/2014 às 18:27

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

Brandt

Resposta 10: 05/02/2015 às 03:28

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