Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 3817 miembros registrados.
El último usuario registrado es mendo89.

Nuestros miembros han publicado un total de 86235 mensajes en 12290 argumentos.

Bugs internos

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP Bugs internos

Mensaje por Wecoc el 2013-05-25, 23:19

Hace tiempo que quería postear algo así xD

Como ya sabréis, el maker no está hecho de la mejor manera posible que digamos xD
Y tiene sus bugs.
No hay nada peor que los bugs internos. Pero algunos creo que se podrían arreglar, y pensé "Joer, conviene hacerlo". Por eso creo éste topic, para que citéis los bugs internos que conozcáis y digais si conocéis alguna solución ya encontrada o si sabéis cómo se podría intentar solucionar o los solucionéis... vaya, para encontrarle remedio a la cosa xDDD

# ================================================
# ** Allá voy
# ================================================

En el maker hay un bug que hace que cuando tú haces una llamada de script y le pones que algo sea false se cuelga todo
Código:
a = false

Código:
$game_system.timer_working = false


Todo esto hace que el juego se vaya a la porra al instante D:

Hay algunas maneras de "solucionarlo" a corto plazo
Código:
a = false
result = true

Código:
a = false
return true


Estas cosas dejan de crashear el juego.
Pero igualmente no deja de ser un bug.

Éste por suerte tiene solución, solo hay que copiar el siguiente script encima de main:
http://forum.chaos-project.com/index.php/topic,938.0.html

------

Pongo uno que me tiene chasmado en mi proyecto xDD (vaya, que me jode mucho)

Cuando tu personaje se mueve a una velocidad con decimales, hay un pequeño desolapamiento entre el scroll de los mapas y el de los eventos.



En general no se debería notar demasiado, pero en según qué casos (por ejemplo si usas eventos para completar el mapeado) es un bug jodido.

Intenté arreglar ese bug por mi mano pero no pude.

------

Otro bug es el de las músicas, que no loopean bien. Lo comenté hace poco en otro post, y allí propuse una posible solución:
http://www.mundo-maker.com/t8425-cosa-rara-audio-retardo#68022

------

Y finalmente creo que solo conozco otro, que sí tiene solución y es muy conocida. Es el bug de cuando pulsas F12 que sale el error 'stack level too deep', la solución es poner detrás de todos lo alias lo siguiente: unless $@

Poned otros bugs si los conocéis.

RESUMEN

- Bug de los false en eval (Interpreter Script Call)
Post: Bugs Internos #68069
Solución: Chaos Project - Interpreter Script Call Fix

- Bug de las velocidades con decimales
Post: Bugs Internos #68069
Solución: ¡Sólo se encontró parcialmente! Bugs Internos #68199

- Músicas no loopean bien (mp3 / wav)
Post: Bugs Internos #68069
Solución: No se encontró, así que se recomienda usar ogg.

- F12 Stack Level Too Deep
Post: Bugs Internos #68069
Solución: Bugs Internos #68069

- Bug al quitar y restaurar Sprite Battler
Post: Bugs Internos #68074
Solución: Bugs Internos #68074

- Bug Teletransportar + Colisionar
Post: Bugs Internos #68087
Solución: Bugs Internos #79027

- Bug Tiles y Carácteres (Configuración Regional)
Post: Bugs Internos #68095
Solución: No creo que haya solución posible puesto que no es el mismo tipo de bug que los que estamos tratando.

- Bug del Proceso Paralelo en el primer mapa
Post: Bugs Internos #68301
Solución: Mundo Maker - Map Calling

- Bug de Mostrar Animación en pantalla a múltiples sprites
Post: Bugs Internos #68543
Solución: No se pudo encontrar por el momento


Última edición por Wecoc el 2014-04-15, 13:08, editado 4 veces
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Ledai el 2013-05-26, 00:16

Bug localizado al llamar en la batalla defauld un evento común que quite un aliado del grupo y después de ello, llamar a otro evento que añada al aliado mediante objeto o habilidad...

Ejemplo: http://www.mundo-maker.com/t7631-xp-enginer-invocacion

Arreglo de Orochii:
Pero ya encontré el problema xD... el problema es una cosilla con el script default xD, una tontería xD. El problema ocurre cuando el actor #3 por ejemplo, está al comienzo de la batalla, y es sacado. Luego reaparece en el mismo espacio que antes.
Eso se soluciona con una línea de código en el lugar correcto C:...

Ve a Sprite_Battler, y busca ésto...
CÓDIGO:
Código:
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If battler is nil
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
Omití el resto, pero es el pedazo más grande del script @,@ nada más necesitamos ver ese pedacito del comienzo.
Deja esa parte algo así:
CÓDIGO:
Código:
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If battler is nil
    if @battler == nil
      @battler_name = nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end

Eso solucionará el problema. Lo que pasa es que el juego borra la imagen, pero no la variable donde le dice qué imagen tiene cargada. Entonces, cuando reestableces al mismo héroe, no vuelve a cargar la imagen, porque piensa que ya la tiene cargada xD. La línea que se agrega, @battler_name = nil, digamos le recuerda al juego que no está mostrando nada.

Eso sería C:, hasta los default tienen bugs eh xD,
Orochii Zouveleki
avatar
Ledai
Aventurero
Aventurero

0/3

Créditos 3985

Gracias : 181

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por J&L el 2013-05-26, 08:29

El del des-solapamiento de charas me llevó de cabeza.

Pero sin duda el bug que más me impactó fue uno que nadie ha descrito todavía y que a lo mejor sólo me sucede a mí...

El caso es que el personaje activa un evento con la condición de que el jugador lo toque que está a la misma altura en el otro extremo del mapa. Por ejemplo:

Azul = Evento en colisionar
P = Jugador


[_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_]
[_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_]
[_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [P]
[_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_] [_]

Esto hace que si teletransporto al jugador a ese extremo, se activará el evento al otro lado que normalmente está ahí para pasar de un mapa a otro y hará que el jugador se salte un mapa entero.
avatar
J&L
Soñador
Soñador

0/3

Créditos 331

Gracias : 5

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por silvanash el 2013-05-26, 14:05

Existe otro bug que es bastante irritante:

No sé si alguno de vosotros ha cambiado alguna vez la configuración regional de su ordenador a una en la que no haya tildes ni caracteres propios del español. El caso es que si lo haces y abres un proyecto con el Maker, el propio Maker te borrará todas las tildes y los caracteres del español, obligándote a volver a cambiar la configuración regional y re-escribir todo. El bug sólo aparece si intentas abrir el proyecto una vez cambiada la configuración regional, así que bastaría con no tocar el Maker mientras tanto.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 1627

Gracias : 229

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por youkai el 2013-05-26, 14:23

Creo que es mejor que dejemos el tema...a este paso vamos a despalillar el maker XDDDD

Por cierto, J&L, creo que ese error es solo tuyo...por lo menos probe eso y la verdad que no me sucede.

Y Wec, para arreglar el error del retrazo en el update de los charas coge:
Código:
    # Update character sprites
    for sprite in @character_sprites
      sprite.update
    end
Y ponlo encima de:
Código:
@tilemap.update
No estoy para nada seguro si eso funcionara pero en teoria deberia de servir XD

Ya no tengo nada mas que decir...no conozco ningun otro bug(que recuerde ahora)
Saludos,
¥oukai
avatar
youkai
Soñador
Soñador

0/3

Créditos 280

Gracias : 10

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2013-05-26, 17:20

No youkai, así no solucionas nada, pero ¿y poniendo distance = distance.round debajo de
distance = 2 ** @move_speed ? O_o"

O bien poniendo simplemente
distance = (2 ** @move_speed).round

Como sea esto es una tremenda tontería xDDD
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por orochii el 2013-05-26, 17:47

Seh, lo arregla, aunque... lo malo (?) es que ahora no habrá diferencia entre usar 4.9 y 5 :C. Aún así, contar con el doble de velocidades que en lo default basta >:) (1 1.5 2 2.5 etc etc).

Estaba viendo por cierto los métodos de cálculo de posición de los eventos, y me encontré con ésto, para el screen_x:
Código:
return (@real_x - $game_map.display_x + 3) / 4 + 16
Éste es el cálculo del ox del tilemap en cambio...
Código:
@tilemap.ox = $game_map.display_x / 4
Mi pregunta es, ¿porqué ese ajuste tan random de 3px xD? Lo quité, y aunque no arregla "nuestro error", no veo cambio visible xD.

Agh, ni idea,
Zorrochii
avatar
orochii
Reportero

0/3

Créditos 7463

Gracias : 368

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por gerrtunk el 2013-05-29, 09:36

Conocia el de =false me jodio con mi script de saltado de escenas ya que hay que marcar ciertas cosas con el interpeter activando con lineas =true. Al final pregunte y saque el porque y lo solucione, poniend =true en la linea final. Conocia el del f12 y el de los loops. Para los loops, teneis que reencodear la musica que tengais problemas, id provando, yo uso el program fre:ac, opensource diria, y convirtiendo a Lame mp3 y fin.
avatar
gerrtunk
Principiante
Principiante

0/3

Créditos 364

Gracias : 22

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Dorvin el 2013-05-29, 11:02

@Wecoc escribió:
------

Pongo uno que me tiene chasmado en mi proyecto xDD (vaya, que me jode mucho)

Cuando tu personaje se mueve a una velocidad con decimales, hay un pequeño desolapamiento entre el scroll de los mapas y el de los eventos.



En general no se debería notar demasiado, pero en según qué casos (por ejemplo si usas eventos para completar el mapeado) es un bug jodido.

Intenté arreglar ese bug por mi mano pero no pude.

------

Por dios que alguien encuentre solución ha esto! Yo uso mucho los eventos para mapear y me perjudicaba tanto que acabe quitando los decimales para que todo se viese bien... TT
Maldito maker! XD
Realmente, podemos vivir sin decimales pero realmente es necesaria un punto intermedio porque del 5 al 6 ya canvia la velocidad una burrada! O_o
avatar
Dorvin
Veterano
Veterano

0/3

Créditos 475

Gracias : 22

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por gerrtunk el 2013-05-29, 12:29

A malas comentadlo en algun foro ingles con mas scripters y tal, yo no os puedo ayudar.
Añado que el xp se relantiza a veces, como un pequeño lapso en el scroll al moverse pero sin k tnega k ver exactamente con el rendimiento. No es la gran cosa i solo le psa a algunas personas.
avatar
gerrtunk
Principiante
Principiante

0/3

Créditos 364

Gracias : 22

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2013-05-29, 13:33

Dorvin, si usas velocidades medias prueba con lo que dije
Código:
distance = (2 ** @move_speed).round
O según me dijo Blizzard, aún mejor así para convertirlo del todo a Integer.
Código:
distance = (2 ** @move_speed).round.to_i
Esto iría a la línea 81 del Game_Character 2

Y si usas otros valores como por ejemplo 3.6, 3.7 ... he llegado a la conclusión de que no hay solución posible y elegante, ya que la distancia sale con un montón de decimales y si intentas ajustalo al entero para que los eventos vayan a tiempo con el display, luego lo que va a saltos es el gráfico del personaje y se ve bastante mal, no hay manera posible de cuadrarlo todo >_<

Cuando pueda intentaré de nuevo lo del update de las canciones. Reconozco que tampoco lo intenté con demasiado empeño xD La solución que das gerrtunk no está mal pero mp3 es muy difícil conseguir un "subformato" que no quede cortado no pese más de la cuenta y no pierda calidad. O al menos eso me parece vaya xD así que intentaré solucionarlo via código una vez más, mejor.
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2013-06-02, 23:48

Sobre lo del bug del loop de las canciones

He estado intentando lo mismo un poco más y parece que ahora me funciona, aunque no lo tengo del todo claro. De momento solo he conseguido que funcione en frecuencia normal y más lento, pero más rápido de 100 no consigo que se adapte bien.

También, en principio solo funciona con mp3, no con midi (igualmente con midi ya bucleaba bien)

Me gustaría que lo probárais vosotros con diferentes canciones y me dijérais si os funcionó bien o no el edit.

Poned esto encima de main, que es el MCI Audio:
Código:
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# MCI Audio Player
# Author: ForeverZer0
# Version: 1.2
# Date: 7.8.2012
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#                            VERSION HISTORY
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# v.1.0  4.29.2012
#  - Original Release
#
# v.1.1  4.29.2012
#  - Fixed a typo
#  - Added instructions for ensuring all channels stop when player closes game
#  - Added RPG Maker VX compatibility
#  - Added RPG Maker VX Ace compatibility
#  - Fixed duration to ensure a minimum of 1 frame, else nothing happens
#  - Added "start position" argument to "play" call. This ensures VXA
#    functionality, as well as a minor improvement to the system
#
# v.1.2  7.8.2012
#  - Fixed incorrect filepaths that mixed forward and backward slashes
#  - Fixed a bug that would cause full paths to files not to play sometimes
#  - Added an enumerator for iterating Audio mixers ("Audio.each_mixer")
#  - Added methods to Game_System for memorizing/restoring audio
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#
# Introduction:
#
#  This script acts a either a drop-in replacement or enhancement to the
#  built-in Audio module. It contains a plethora of functions that the default
#  player lacks, such as seek, pause, record, fade in/out, and many more. It
#  works by totally bypassing the built-in audio library, and directly
#  accessing Window's "winmm" library using Ruby's Win32API. This library is
#  home to the Media Control Interface, or MCI, which provides functions for
#  manipulating audio and video. This allows for much more control over sound,
#  and the ability for RPG Maker to play additional audio formats, since all
#  that is needed is to distribute the appropriate codecs along with your game
#  in order to use them.
#
# Features:
#
#  - Full seek functions, accurate to the millisecond
#  - Ability to read file lengths
#  - Ability to pause and resume a playing file
#  - Functions for transitioning from one volume to another over a given number
#    frames, to both lower and higher volumes
#  - Can create as many mixers as needed, which allows to play multiple sounds
#    simultaneously, which gives the ability to play more than one BGM or BGS
#    at a time
#  - Record function to capture input from the user (.wav format only)
#  - Ability to set volume to left and right speaker independently
#  - Mute functions
#  - Can set the speed of playback
#  - Ability to set treble and bass (Not all devices support this)
#  - Searches RTP files and uses them automatically if file is not local
#  - Easy access for additional calls to the Media Control Interface
#  - No porting external libraries with your game, all functioning is done
#    within the script and the operating system
#  - Can use any audio format you wish, so long as the appropriate codec is
#    installed on the host computer
#  - Full compatibility with RMXP, RMVX, and RMVX Ace
#  - Memorize and restore all/some channels
#
# Instructions:
#
#  - Scroll below to make the setting for what RPG Maker version you are using
#  - Place script anywhere above Main
#  - Only one setting (below) to set the MCI player as default audio player,
#    which is by default "true". If false, the MCI player will only be used for
#    special circumstances via script calls
#  - There are a whole bunch of new script calls available for the Audio module
#    There is full documentation if you look below, which I reccomend that you
#    look at if you choose to use this script, but most are self-explanatory.
#    Here is a partial list, words in caps are arguments that need replaced.

#    - play(FILENAME, VOLUME, SPEED, REPEAT)
#    - pause
#    - restart
#    - pause
#    - resume
#    - stop
#    - close
#    - volume/volume=
#    - set_volume_left(VOLUME)
#    - set_volume_right(VOLUME)
#    - mute
#    - fade(DURATION, FRAMES)
#    - speed/speed=
#    - duration
#    - position/position=
#    - seek(MILLISECOND)
#    - playing?
#    - paused?
#    - recording?
#    - treble/treble=
#    - bass/bass=
#    - status
#    - record(BITS_PER_SAMPLE, SAMPLERATE, CHANNELS)
#    - save(FILENAME)
#   
#    To play a sound on a mixer is pretty straightforward, you don't even need
#    to create a mixer first, that is done automatically. All you need to do
#    is use a unique name for each mixer you want to control, and use the
#    above methods on it. For example, to play a file:
#
#    Audio['myName'].play('myFile.mp3')
#
#    From here on, you can access the same mixer using 'myName' as the key to
#    perform further actions. Such as...
#
#    Audio['myName'].pause            - Pauses playback
#    Audio['myName'].resume          - Resumes playback
#    Audio['myName'].volume = 50      - Sets volume to fifty
#    Audio['myName'].fade(80, 0)      - Fades volume to 0 in 80 frames
#    Audio['myName'].fade(240, 100)  - Transitions volume to 100 in 6 seconds
#    Audio['myName'].record          - Begins recording
#    Audio['myName'].save('file.wav') - Saves recorded file
#    Audio['myName'].seek(4500)      - Sets playback position to 4.5 seconds
#
#    As you can see, all mixers are accessed in a hash-like way via the Audio
#    module. By default, 'BGM', 'BGS', 'ME', and 'SE' are mixers used as
#    replacements for the built-in audio library, so use names other them if
#    creating additional mixers.
#
#    There is also a script call to make a call using mciSendString if you are
#    familiar with the library at all. I simplified it down a bit, but it can
#    be used with the following snippet:
#
#        Audio.mci_eval(MCI_COMMAND)
#
#    For more information about using MCI commands, please see the full
#    documentation at MSDN.
#
# http://msdn.microsoft.com/en-us/library/windows/desktop/dd743572(v=vs.85).aspx
#
#    There are also a few methods available via the Game_System class for
#    memorizing/restoring audio at its current position.
#
#    ex.
#
#    $game_system.memorize_audio              - Memorize all channels
#    $game_system.memorize_audio('BGM')        - Memorize BGM channel
#    $game_system.memorize_audio('BGM', 'BGS') - Memorize BGM and BGS channels
#    $game_system.restore_audio                - Restore all channels
#    $game_system.restore_audio('BGM')        - Restore BGM channel
#    $game_system.restore_audio('BGM', 'BGS')  - Restore BGM and BGS channels
#
#    You can use as many arguments for each method as you wish. Omitting
#    arguments will simply have it memorize/restore all channels.
#
# Compatibility:
#
#  - Not tested on Linux running under Wine. If anyone tests this, let me know.
#  - Not compatible with DREAM.
#
# Credits/Thanks:
#
#  - ForeverZer0, for the script
#
# Authors Notes:
#
#  - Changing pitch will be different. MCI does not have a function for this,
#    so I am changing the speed as a generic substitute. Changing the speed
#    does change the pitch, but it true sound pitch alters the sampling rate
#    as well, which this player does not. You have a couple alternatives if
#    you absolutely need the pitch change:
#
#    1. Edit the files using an external editor and import it
#    2. Use the default system to play such sounds using the alias names.
#
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

#===============================================================================
# ** Audio
#===============================================================================

module Audio

  # Set true/false if the MCI Player should be the default audio controller. It
  # will maintain all the same functionality as the standard control, and all
  # normal calls to the Audio module will work as normal, but it will also
  # extend the its functionality. If false, RMXP's standard library will be used
  # and this player will only be used for custom mixers.
  MCI_DEFAULT = true
 
  # Due to vast differences in how the format is handled, some of this player's
  # features do not work with MIDI, most notably volume control, which also
  # effects fading. I have created alternate controls to control MIDI volume,
  # but they can only work with the sacrifice of many other functions, and the
  # volume applies to ALL playing MIDIs, not just the one the volume is applied
  # to. I decided this was not worth it, so I omitted volume control. If you
  # are willing to make them sacrifices, you can enable this mode by setting
  # MIDI_MODE to true. If you your game relies heavily on MIDI, but you still
  # would like to use this script, there are conversion programs available,
  # which I can assist you with if need be.
  MIDI_MODE = false
 
  # Enter the code for the version of RPG Maker you are using this script for.
  #  RMXP  = 0
  #  RMVX  = 1
  #  RMVXA = 2
  RPG_VERSION = 0
 
#===============================================================================
# ** Mixer
#-------------------------------------------------------------------------------
# This class acts a wrapper for Window's Media Control Interface (MCI).
#===============================================================================

  MCISendString = Win32API.new('winmm', 'mciSendString', 'PPLL', 'L')
  MIDIOutSetVolume = Win32API.new('winmm', 'midiOutSetVolume', 'LL', 'L')

  class Mixer
   
    attr_reader :name          # The arbitrary name of the mixer
    attr_reader :filepath      # The path of the currently loaded file
    attr_reader :repeat        # Flag if playback is set to repeat
   
    #---------------------------------------------------------------------------
    # * Object Initialization
    #    name    : The unique name of the mixer
    #---------------------------------------------------------------------------
    def initialize(name)
      @name = name
      @fade_duration = 0
      @fade_volume = 0
      @opened = false
      @repeat = false
      @midi = false
    end
    #---------------------------------------------------------------------------
    # * Load a file and prepare for playback
    #    filename  : The path to the file.
    #---------------------------------------------------------------------------
    def open(filename)
      if File.exists?(filename)
        path = filename
      else
        path = Dir::glob(filename + '.*')[0]
        if path == nil
          directory = File.dirname(filename)
          if RTP.subfolder?(directory)
            file = File.basename(filename)
            path = RTP[directory].find {|f| File.basename(f, '.*') == file }
          end
        end
      end
      @filepath = path.gsub(/\\/, '/')
      if MIDI_MODE && ['.mid', '.midi'].include?(File.extname(path))
        @midi = true
        cmd = "open \"#{path}\" type sequencer alias #{@name}"
      else
        cmd = "open \"#{path}\" type mpegvideo alias #{@name}"
      end
      MCISendString.call(cmd, nil, 0, 0)
      MCISendString.call("set #{@name} time format milliseconds", nil, 0, 0)
      MCISendString.call("set #{@name} seek exactly on", nil, 0, 0)
      @opened = true
    end
    #---------------------------------------------------------------------------
    # * Began playback on the mixer
    #    filename  : The name of the file to play
    #    volume    : The volume to play the file at
    #    speed    : The speed to play the the fule at
    #    repeat    : Flag if playback should loop after done playing
    #    start    : The position, in milliseconds, to begin playback at
    #---------------------------------------------------------------------------
    def play(filename, volume = 100, speed = 100, repeat = false, start = 0)
      self.close
      self.open(filename)
      self.speed = speed
      if MIDI_MODE && @midi
        @midi_master = @midi_right = @midi_left = volume * 10
        self.set_volume(volume)
        MCISendString.call("play #{@name} from 0", nil, 0, 0)
        return
      end
      self.set_volume(volume)
      @repeat = repeat
      if start != 0
        MCISendString.call("seek #{@name} to #{start}", nil, 0, 0)
      else
        MCISendString.call("seek #{@name} to start", nil, 0, 0)
      end
      MCISendString.call("play #{@name}#{repeat ? ' repeat' : ''}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Restarts playback of the currently loaded file from the beginning
    #---------------------------------------------------------------------------
    def restart
      MCISendString.call("seek #{@name} to start", nil, 0, 0)
      MCISendString.call("play #{@name}#{repeat ? ' repeat' : ''}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Pause playback and maintain current position
    #---------------------------------------------------------------------------
    def pause
      MCISendString.call("pause #{@name}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Resume playback on a paused mixer from previous position
    #---------------------------------------------------------------------------
    def resume
      MCISendString.call("resume #{@name}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Stops playback, setting position back to the start
    #---------------------------------------------------------------------------
    def stop
      MCISendString.call("seek #{@name} to start", nil, 0, 0)
      MCISendString.call("stop #{@name}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Closes the opened file and frees it from memory
    #---------------------------------------------------------------------------
    def close
      MCISendString.call("close #{@name}", nil, 0, 0)
      @filepath = nil
      @opened = false
    end
    #---------------------------------------------------------------------------
    # * Gets the actual volume of the mixer, an integer from 0 to 1000
    #---------------------------------------------------------------------------
    def real_volume
      if MIDI_MODE && @midi
        return @midi_master
      else
        data = "\0" * 128
        MCISendString.call("status #{@name} volume", data, 128, 0)
        return data.delete("\0").to_i
      end
    end
    #---------------------------------------------------------------------------
    # * Sets the actual volume of the mixer
    #    value    : The volume level, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def real_volume=(value)
      self.set_real_volume(value)
    end
    #---------------------------------------------------------------------------
    # * Sets the actual volume of the mixer
    #    value    : The volume level, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def set_real_volume(value)
      vol = [0, [value, 1000].min].max
      if MIDI_MODE && @midi
        @midi_master = value
        self.set_midi_volume(value, value)
      else
        MCISendString.call("setaudio #{@name} volume to #{vol}", nil, 0, 0)
      end
    end
    #---------------------------------------------------------------------------
    # * Returns the volume of the mixer
    #---------------------------------------------------------------------------
    def volume
      return self.real_volume / 10   
    end
    #---------------------------------------------------------------------------
    # * Sets the volume of the mixer
    #    value    : The volume level, integer between 0 and 100
    #---------------------------------------------------------------------------
    def volume=(value)
      value = [0, [value, 100].min].max
      self.set_real_volume(value * 10)
    end
    #---------------------------------------------------------------------------
    # * Sets the volume of the mixer
    #    value    : The volume level, integer between 0 and 100
    #---------------------------------------------------------------------------
    def set_volume(value)
      value = [0, [value, 100].min].max
      self.set_real_volume(value * 10)
    end
    #---------------------------------------------------------------------------
    # * Set the volume of the mixer in the left speaker only
    #    value  : Volume level, integer between 0 and 100
    #---------------------------------------------------------------------------
    def set_volume_left(value)
      vol = [0, [value * 10, 1000].min].max
      if MIDI_MODE && @midi
        self.set_midi_volume(value, @midi_right)
      else
        MCISendString.call("setaudio #{@name} left volume to #{vol}", nil, 0, 0)
      end
    end
    #---------------------------------------------------------------------------
    # * Set the volume of the mixer in the right speaker only
    #    value  : Volume level, integer between 0 and 100
    #---------------------------------------------------------------------------
    def set_volume_right(value)
      vol = [0, [value * 10, 1000].min].max
      if MIDI_MODE && @midi
        self.set_midi_volume(@midi_left, value)
      else
        MCISendString.call("setaudio #{@name} right volume to #{vol}", nil, 0, 0)
      end
    end
    #---------------------------------------------------------------------------
    # * Special handling for adjusting MIDI volume. MCI cannot handle the volume
    #  for this format directly, so we need to precalculate the channels and
    #  make the call to the MIDI synthesizer ourselves.
    #    left    : The volume of the left channel
    #    right  : The volume of the right channel
    #
    #  NOTE:
    #  It is recommended that you do not call this method directly.
    #---------------------------------------------------------------------------
    def set_midi_volume(left, right)
      @midi_left, @midi_right = left, right
      left = (0xFFFF * (left / 1000.0)).round
      right = (0xFFFF * (right / 1000.0)).round
      vol = right.to_s(16) + left.to_s(16)
      MIDIOutSetVolume.call(0, vol.to_i(16))
    end
    #---------------------------------------------------------------------------
    # * Mutes sound from the mixer
    #    bool    : True/false flag to mute/unmute sound
    #---------------------------------------------------------------------------
    def mute(bool)
      MCISendString.call("setaudio #{@name} #{bool ? 'on' : 'off'}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Transition volume to another volume
    #    duration    : The number of frames the transition will take
    #    target      : The target volume to transition to
    #---------------------------------------------------------------------------
    def fade(duration, target = 0)
      @fade_volume = target * 10
      @fade_duration = [duration, 1].max
    end
    #---------------------------------------------------------------------------
    # * Returns the current speed of playback  (100 = normal)
    #---------------------------------------------------------------------------
    def speed
      data = "\0" * 256
      MCISendString.call("status #{@name} speed", data, 256, 0)
      data.delete!("\0")
      return data.to_i / 10
    end
    #---------------------------------------------------------------------------
    # * Set the current speed of playback
    #    value  : The rate of playback to set
    #---------------------------------------------------------------------------
    def speed=(value)
      set_speed(value)
    end
    #---------------------------------------------------------------------------
    # * Set the current speed of playback
    #    value  : The rate of playback to set
    #---------------------------------------------------------------------------
    def set_speed(value)
      value = [0, [2000, value * 10].min].max
      MCISendString.call("set #{@name} speed #{value}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Gets the length of the loaded file in milliseconds
    #---------------------------------------------------------------------------
    def duration
      if self.playing?
        length = "\0" * 256
        MCISendString.call("status #{@name} length", length, 256, 0)
        length.delete!("\0")
        return length.to_i
      end
      return 0
    end
    #---------------------------------------------------------------------------
    # * Returns duration as a string in normal MM:SS format
    #---------------------------------------------------------------------------
    def duration_string
      seconds = self.duration / 1000
      return sprintf('%2d:%02d', seconds / 60, seconds % 60)
    end
    #---------------------------------------------------------------------------
    # * Returns the current position of playback, in milliseconds
    #---------------------------------------------------------------------------
    def position
      pos = "\0" * 256
      MCISendString.call("status #{@name} position", pos, 256, 0)
      pos.delete!("\0")
      return pos.to_i
    end
    #---------------------------------------------------------------------------
    # * Returns current position as a string in normal MM:SS format
    #---------------------------------------------------------------------------
    def position_string
      seconds = self.position / 1000
      return sprintf('%2d:%02d', seconds / 60, seconds % 60)
    end
    #---------------------------------------------------------------------------
    # * Sets the current playback position
    #    value  : The time in milliseconds to set current playback
    #---------------------------------------------------------------------------
    def position=(value)
      self.seek(value)
    end
    #---------------------------------------------------------------------------
    # * Sets the current playback position
    #    value  : The time in milliseconds to set current playback
    #---------------------------------------------------------------------------
    def seek(value)
      cmd = "#{self.playing? ? 'play' : 'seek'} #{@name} from #{value}"
      MCISendString.call(cmd, nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Returns tha "playing" status of the mixer
    #---------------------------------------------------------------------------
    def playing?
      return self.status == 'playing'
    end
    #---------------------------------------------------------------------------
    # * Returns tha "paused" status of the mixer
    #---------------------------------------------------------------------------
    def paused?
      return self.status == 'paused'
    end
    #---------------------------------------------------------------------------
    # * Returns true/false if file is currently loaded for playback
    #---------------------------------------------------------------------------
    def opened?
      return @opened
    end
    #---------------------------------------------------------------------------
    # * Returns true/false if mixer is currently recording
    #---------------------------------------------------------------------------
    def recording?
      return self.status == 'recording'
    end
    #---------------------------------------------------------------------------
    # * Returns the mixer's bass value
    #---------------------------------------------------------------------------
    def treble
      data = "\0" * 128
      MCISendString.call("status #{@name} treble", data, 128, 0)
      data.delete!("\0")
      return data.to_i
    end
    #---------------------------------------------------------------------------
    # * Set mixer treble
    #    value  : Treble value, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def treble=(value)
      set_treble(value)
    end
    #---------------------------------------------------------------------------
    # * Set mixer treble
    #    value  : Treble value, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def set_treble(value)
      value = [0, [value, 1000].min].max
      MCISendString.call("setaudio #{@name} treble to #{value}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Returns the mixer's bass value
    #---------------------------------------------------------------------------
    def bass
      data = "\0" * 128
      MCISendString.call("status #{@name} bass", data, 128, 0)
      data.delete!("\0")
      return data.to_i
    end
    #---------------------------------------------------------------------------
    # * Set mixer bass
    #    value  : Bass value, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def bass=(value)
      set_bass(value)
    end
    #---------------------------------------------------------------------------
    # * Set mixer bass
    #    value  : Bass value, integer between 0 and 1000
    #---------------------------------------------------------------------------
    def set_bass(value)
      value = [0, [value, 1000].min].max
      MCISendString.call("setaudio #{@name} bass to #{value}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Gets the current status
    #---------------------------------------------------------------------------
    def status
      data = "\0" * 256
      MCISendString.call("status #{@name} mode", data, 256, 0)
      return data.delete("\0")
    end
    #---------------------------------------------------------------------------
    # * Begins recording from the input, typically the PC's microphone
    #    bits_ps    : Bits per sample the file will be recorded at
    #    sample_rate : Sample rate the the file will be recorded at
    #    channels    : Number of channels that will be opened for recording
    #
    #  * WARNING *
    #    Make sure that "stop", "close" or "save" is performed on this mixer
    #    within a reasonable of amount of time. While the mixer is recording,
    #    the file is held in RAM, which will become very large if left without
    #    closing it, and eventually slow down the PC and/or crash the game.
    #    Basically I'm just saying "don't forget you are recording"
    #---------------------------------------------------------------------------
    def record(bits_ps = 16, sample_rate = 44100, channels = 2)
      self.close
      MCISendString.call("open new type waveaudio alias #{@name}", nil, 0, 0)
      MCISendString.call("set #{@name} bitspersample #{bits_ps}", nil, 0, 0)
      MCISendString.call("set #{@name} samplespersec #{sample_rate}", nil, 0, 0)
      MCISendString.call("set #{@name} channels #{channels}", nil, 0, 0)
      MCISendString.call("record #{@name}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Saves a recording into WAV format
    #    filename  : The path of the file t save, must have '.wav' extension
    #---------------------------------------------------------------------------
    def save(filename)
      if self.recording?
        MCISendString.call("stop #{@name}", nil, 0, 0)
      end
      if File.extname(filename) != '.wav'
        filename += '.wav'
      end
      MCISendString.call("save #{@name} #{filename}", nil, 0, 0)
      MCISendString.call("close #{@name}", nil, 0, 0)
    end
    #---------------------------------------------------------------------------
    # * Frame update
    #---------------------------------------------------------------------------
    def update
      if @fade_duration >= 1
        d = @fade_duration
        self.set_real_volume((self.real_volume * (d - 1) + @fade_volume) / d)
        @fade_duration -= 1
      end
    end
  end

#===============================================================================
# ** Audio
#-------------------------------------------------------------------------------
# The metaclass of the Audio module. This class is a wrapper between the default
# audio controls and the MCI Player controls.
#===============================================================================
 
  class << self
    #---------------------------------------------------------------------------
    # * Use MCI Player play function
    #---------------------------------------------------------------------------
    alias mci_bgm_play bgm_play
    def bgm_play(filename, volume = 100, pitch = 100, start = 0)
      if MCI_DEFAULT
        mixer_play('BGM', filename, volume, pitch, true, start)
      elsif RPG_VERSION == 2
        mci_bgm_play(filename, volume, pitch, start)
      else
        mci_bgm_play(filename, volume, pitch)
      end
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player play function
    #---------------------------------------------------------------------------
    alias mci_bgs_play bgs_play
    def bgs_play(filename, volume = 100, pitch = 100, start = 0)
      if MCI_DEFAULT
        mixer_play('BGS', filename, volume, pitch, true, start)
      elsif RPG_VERSION == 2
        mci_bgs_play(filename, volume, pitch, start)
      else
        mci_bgs_play(filename, volume, pitch)
      end
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player play function
    #---------------------------------------------------------------------------
    alias mci_me_play me_play
    def me_play(filename, volume = 100, pitch = 100, start = 0)
      if MCI_DEFAULT
        mixer_play('ME', filename, volume, pitch, false, start)
      elsif RPG_VERSION == 2
        mci_me_play(filename, volume, pitch, start)
      else
        mci_me_play(filename, volume, pitch)
      end
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player play function
    #---------------------------------------------------------------------------
    alias mci_se_play se_play
    def se_play(filename, volume = 100, pitch = 100, start = 0)
      if MCI_DEFAULT
        mixer_play('SE', filename, volume, pitch, false, start)
      elsif RPG_VERSION == 2
        mci_se_play(filename, volume, pitch, start)
      else
        mci_se_play(filename, volume, pitch, start)
      end
    end
    #---------------------------------------------------------------------------
    # Use MCI Player to play a file on a mixer using given parameters
    #---------------------------------------------------------------------------
    def mixer_play(mixer_name, filename, volume, pitch, repeat, start = 0)
      self[mixer_name].play(filename, volume, pitch, repeat, start)
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player stop
    #---------------------------------------------------------------------------
    alias mci_bgm_stop bgm_stop
    def bgm_stop
      MCI_DEFAULT ? @mixers['BGM'].stop : mci_bgm_stop
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player stop
    #---------------------------------------------------------------------------
    alias mci_bgs_stop bgs_stop
    def bgs_stop
      MCI_DEFAULT ? @mixers['BGS'].stop : mci_bgs_stop
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player stop
    #---------------------------------------------------------------------------
    alias mci_me_stop me_stop
    def me_stop
      MCI_DEFAULT ? @mixers['ME'].stop : mci_me_stop
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player stop
    #---------------------------------------------------------------------------
    alias mci_se_stop se_stop
    def se_stop
      MCI_DEFAULT ? @mixers['SE'].stop : mci_se_stop
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player fade
    #---------------------------------------------------------------------------
    alias mci_bgm_fade bgm_fade
    def bgm_fade(time)
      rate = RPG_VERSION == 0 ? 40 : 60
      MCI_DEFAULT ? @mixers['BGM'].fade((time / 1000) * rate) :
        mci_bgm_fade(time)
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player fade
    #---------------------------------------------------------------------------
    alias mci_bgs_fade bgs_fade
    def bgs_fade(time)
      rate = RPG_VERSION == 0 ? 40 : 60
      MCI_DEFAULT ? @mixers['BGS'].fade((time / 1000) * rate) :
        mci_bgs_fade(time)
    end
    #---------------------------------------------------------------------------
    # * Use MCI Player fade
    #---------------------------------------------------------------------------
    alias mci_me_fade me_fade
    def me_fade(time)
      rate = RPG_VERSION == 0 ? 40 : 60
      MCI_DEFAULT ? @mixers['ME'].fade((time / 1000) * rate) :
        mci_me_fade(time)
    end
  end
  #-----------------------------------------------------------------------------
  # * Gives hash-type access of the mixers of the module
  #-----------------------------------------------------------------------------
  def self.[](mixer_name)
    unless @mixers.has_key?(mixer_name)
      @mixers[mixer_name] = Mixer.new(mixer_name)
    end
    return @mixers[mixer_name]
  end
  #-----------------------------------------------------------------------------
  # * Frame update
  #-----------------------------------------------------------------------------
  def self.update
    @mixers.each_value {|mixer| mixer.update }
  end
  #-----------------------------------------------------------------------------
  # * Simplified method for making calls directly to the Media Command Interface
  #-----------------------------------------------------------------------------
  def self.mci_eval(command)
    data = "\0" * 256
    MCISendString.call(command, data, 256, 0)
    return data.delete("\0")
  end
  #-----------------------------------------------------------------------------
  # * Iterator for the Audio mixers
  #-----------------------------------------------------------------------------
  def self.each_mixer
    @mixers.each_value {|mixer| yield mixer }
  end
  #-----------------------------------------------------------------------------
  # * Object initialization
  #-----------------------------------------------------------------------------
  def self.init
    if @mixers != nil
      # Don't remove this, it prevents memory leaks when F12 us used to restart
      MCISendString.call('close all', nil, 0, 0)
    end
    @mixers = {}
    ['BGM', 'BGS', 'ME', 'SE'].each {|name| @mixers[name] = Mixer.new(name) }
  end 
end

#===============================================================================
# ** Graphics
#-------------------------------------------------------------------------------
# Syncs the audio update used for fade effects with the frame update
#===============================================================================
module Graphics
 
  class << self
   
    alias mci_player_update update
    def update
      mci_player_update
      Audio.update
    end
  end
end

#===============================================================================
# ** RTP
#-------------------------------------------------------------------------------
# Provides functions for getting the games RTP path(s) and files
#===============================================================================

module RTP
 
  # RMXP
  if Audio::RPG_VERSION == 0
    SUBFOLDERS = [
      'Graphics/Animations', 'Graphics/Autotiles', 'Graphics/Battlebacks',
      'Graphics/Battlers', 'Graphics/Characters', 'Graphics/Fogs',
      'Graphics/Gameovers', 'Graphics/Icons', 'Graphics/Panoramas',
      'Graphics/Pictures', 'Graphics/Tilesets', 'Graphics/Titles',
      'Graphics/Transitions', 'Graphics/Windowskins', 'Audio/BGM',
      'Audio/BGS', 'Audio/ME', 'Audio/SE'
    ]
  # RMVX
  elsif Audio::RPG_VERSION == 1
    SUBFOLDERS = [
      'Graphics/Animations', 'Graphics/Battlers', 'Graphics/Characters',
      'Graphics/Faces', 'Graphics/Parallaxes', 'Graphics/Pictures',
      'Graphics/System', 'Audio/BGM', 'Audio/BGS', 'Audio/ME', 'Audio/SE'
    ]
  # RMVXA
  elsif Audio::RPG_VERSION == 2
    SUBFOLDERS = [
      'Graphics/Animations', 'Graphics/Battlers', 'Graphics/Characters',
      'Graphics/Faces', 'Graphics/Parallaxes', 'Graphics/Pictures',
      'Graphics/System', 'Audio/BGM', 'Audio/BGS', 'Audio/ME', 'Audio/SE'
    ]
  end
  #-----------------------------------------------------------------------------
  # * Object initialization
  #-----------------------------------------------------------------------------
  def self.init
    @ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'PPPPLP', 'L')
    @library = "\0" * 256
    @ini.call('Game', 'Library', '', @library, 256, '.\\Game.ini')
    @library.delete!("\0")
    @rtp_path = Win32API.new(@library, 'RGSSGetRTPPath', 'L', 'L')
    @path_with_rtp = Win32API.new(@library, 'RGSSGetPathWithRTP', 'L', 'P')
    @directories = {}
    SUBFOLDERS.each {|folder| @directories[folder] = entries(folder) }
    @initialized = true
  end
  #-----------------------------------------------------------------------------
  # * Returns an array of the full paths of all the game's installed RTPs
  #-----------------------------------------------------------------------------
  def self.paths
    paths = [1, 2, 3].collect {|id| @path_with_rtp.call(@rtp_path.call(id)) }
    paths = paths.find_all {|path| path != '' }
    # This is kind of a crappy way of doing this until the RMVX call works...
    common = File.join(ENV['CommonProgramFiles'], 'Enterbrain')
    common = case Audio::RPG_VERSION
    when 0 then File.join(common, 'RGSS', 'Standard')
    when 1 then File.join(common, 'RGSS2', 'RPGVX')
    when 2 then File.join(common, 'RGSS3', 'RPGVXAce')
    end
    if !paths.include?(common) && File.directory?(common)
      paths.push(common)
    end
    return paths
  end
  #-----------------------------------------------------------------------------
  # * Gives hash-like access to the RTP subfolders
  #-----------------------------------------------------------------------------
  def self.[](folder)
    return subfolder?(folder) ? @directories[folder] : []
  end
  #-----------------------------------------------------------------------------
  # * Returns true/false if the given subfolder exists
  #-----------------------------------------------------------------------------
  def self.subfolder?(folder)
    return @directories.has_key?(folder)
  end
  #-----------------------------------------------------------------------------
  # * Get a complete list of full paths of files found in the given subfolder
  #  subfolder  : The RTP folder whose files you want to get
  #-----------------------------------------------------------------------------
  def self.entries(subfolder)
    files = []
    paths.each {|path|
      dir = path + '\\' + subfolder
      if File.directory?(dir)
        files = (Dir.entries(dir) - ['.', '..']).collect {|f| dir + '\\' + f }
      end
    }
    return files
  end
end

#===============================================================================
# ** Game_System
#===============================================================================

class Game_System
  #-----------------------------------------------------------------------------
  # * Public Instance Variables
  #-----------------------------------------------------------------------------
  attr_accessor :memorized_audio
  #-----------------------------------------------------------------------------
  # * Memorize Audio
  #      channels : Names of channels, or omit argument to memorize all channels
  #-----------------------------------------------------------------------------
  def memorize_audio(*channels)
    @audio_memory = {}
    if channels.empty?
      Audio.each_mixer {|m|
        data = [m.filepath, m.volume, m.speed, m.repeat, m.position]
        @audio_memory[m.name] = data
      }
    else
      channels.each {|channel|
        m = Audio[channel]
        data = [m.filepath, m.volume, m.speed, m.repeat, m.position]
        @audio_memory[channel] = data
      }
    end
  end
  #-----------------------------------------------------------------------------
  # * Restore Audio
  #      channels : Names of channels, or omit argument to restore all channels
  #-----------------------------------------------------------------------------
  def restore_audio(*channels)
    unless @audio_memory == nil || @audio_memory.empty?
      keys = channels.empty? ? @audio_memory.keys : channels
      keys.each {|name|
        data = @audio_memory[name]
        if data != nil && data[0] != nil
          Audio[name].play(data[0], data[1], data[2], data[3])
          Audio[name].seek(data[4])
          @audio_memory.delete(name)
        end
      }
    end
  end
end

# Intialize the MCI Player
RTP.init
Audio.init

Y luego debajo poned mi script:

Código:
module Audio
  class Mixer   
    #---------------------------------------------------------------------------
    # * New update
    #---------------------------------------------------------------------------
    alias upd_wecoc update
    def update
      case speed
      when 10...100
        if position >= ((duration / (100 / speed.to_f)) - speed).round
          a1 = playing? ? 'play' : 'seek'
          a2 = repeat ? ' repeat' : ''
          cmd = "#{a1} #{@name} #{a2} from 60"
          MCISendString.call(cmd, nil, 0, 0)
        end
      when 101...2000
        #???
      end
      upd_wecoc
    end
  end
end

Otra cosa, que me olvidaba.
Lo hice para XP pero en otros funciona igual pero cambiando una cosa.
No sé si en VX y VXAce había el bug o no, según he oído en el Ace no.
En todo caso si lo probáis, tendréis que cambiar la siguiente línea del primer script:
Código:
RPG_VERSION = 0
Si es en VX ponéis 1 y si es Ace ponéis 2

==========================================

Y J&L, lo he probado y también me sucede ese bug, pasa que no lo había entendido bien xD
Lo explicaré un poco mejor.

Estás en un mapa (Mapa1) que tiene un evento con detonante Colisionar. Ese evento lo que hace es teletransportar al personaje a cualquier lugar del Mapa2. Resulta que en el Mapa2 en las mismas coordenadas que en el Mapa1 hay otro evento con detonante Colisionar, que hace cualquier cosa.

El problema es que al pulsar el evento del Mapa1, te teletransportas al Mapa2 y también se activa el evento del Mapa2, cuando no debería.

Miraré a ver qué puedo hacer para solucionar eso. Aún así de entrada de diré que lo que recomiendo siempre para eventos que teletransporten es usar Toparse con héroe, queda mejor visualmente. También hay que tener en cuenta que cuando te teletransportas encima de un evento con detonante Colisionar éste también se activa directamente, y esto a veces causa que el personaje se teletransporte de uno al otro hasta el infinito (cosa que con Toparse con Héroe no pasa).

==========================================

Hay otro bug en el RPG maker XP que no se comentó; el bug del proceso paralelo en el mapa 1 (aunque puede pasar en otros casos pero es raro xD). Resulta que cuando tú cambias de la escena de título a la escena del mapa al iniciar el juego; las cosas no se inician al mismo tiempo.

- Primero empiezan a funcionar los eventos con proceso paralelo.
- Luego empieza la transición gráfica del título al mapa, proceso que dura 20 frames.
- Luego se carga $game_map y todas sus cosas.
- Finalmente empiezan a funcionar los eventos con inicio automático, así como la música del mapa, etc.

El problema es que si empieza a funcionar algo en el proceso paralelo en relación al mapa (ya sea movimiento de otro evento, cosas de fogs, panoramas, códigos tipo $game_map.data, etc) como $game_map aún no se cargó, salta un error "inexplicable" nada más iniciar el juego.

Encontré dos soluciones sencillas a este bug:

La primera: Si pones un esperar en el principio del proceso paralelo para darle tiempo al $game_map a cargarse, ya no habrá problema. Con un Esperar 20 frames debería arreglarse. Pero claro según qué sea lo que quieras loopear un Esperar 20 frames cada vez puede ser no deseable.

La segunda es en el primer mapa usar Inicio Automático, ni que sea para activar un interruptor que luego active un proceso paralelo si es que realmente se necesita algo en loop. Como el Inicio Automático empieza cuando "ya no hay peligro", problema solucionado.
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por gerrtunk el 2013-06-03, 08:27

Pues mira primera noticia que tengo de que el loop se demora unos segundos. Yo creia que hablavas del bug que hace que algunas musicas nunca loopen, y este se soluciona convirtiendolas.

Sobre el lag yo nunca note en el default, solo en el MCI con los sonidos default, habia un pequeña demora al iniciarlos, incluso instalando el k lite codecs pack, se me soluciono convirtiendo los sonidos a mp3 lame y tal.

Realmente la parte de audio es lo peor de los rpgmaker, no solo en lo default, tambien por limitaciones base grandes y bugs varios diversos.
avatar
gerrtunk
Principiante
Principiante

0/3

Créditos 364

Gracias : 22

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2013-06-11, 21:44

Me alertaron de otro bug, en las animaciones.
Cuando se muestra una animación de esas que ocupan toda la pantalla (position == 3), debería mostrarse solo una, pero se muestran tantas como enemigos hay en el mapa (o aliados si la lanza un boss). Si es una batalla contra muchos enemigos se notan los problemas de opacidad que ésto conlleva.

Ahí hice el script que lo soluciona, creo que no da error, no debería darlo vaya. Posteadlo encima de main.

Código:
class Scene_Battle
  def update_phase4_step4
    if @animation2_id != 0 and $data_animations[@animation2_id].position == 3
      @target_battlers[0].animation_id = @animation2_id
    else
      for target in @target_battlers
        target.animation_id = @animation2_id
      end
    end
    for target in @target_battlers
      target.animation_hit = (target.damage != "Miss")
    end
    @wait_count = 8
    @phase4_step = 5
  end
end


Última edición por Wecoc el 2014-08-17, 22:24, editado 2 veces
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por J&L el 2013-06-11, 23:03

¿Ves? Sabía que no podía ser sólo yo. Yo normalmente uso colisionar con un condicional de mirando a X dirección. Así el personaje puede dar la vuelta nada más aparecer en el filo de un mapa para regresar al anterior.

He encontrado una manera muy muy fácil de solucionar el problema así que no hace falta que te molestes, aunque agradezco que hayas llegado al fondo de la cuestión.
avatar
J&L
Soñador
Soñador

0/3

Créditos 331

Gracias : 5

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2014-04-15, 13:04

Vengo a recuperar ésto después de tantísimo tiempo porque estábamos haciendo un buen trabajo.
He editado el primer post con un resumen de lo logrado por el momento.

La solución que dí al último post no es correcta. Me percaté que el maker lo hace de esa forma por los flash. Aunque la animación de pantalla tenga que mostrarse solo una vez independientemente de la cantidad de battlers a los que afecta (si es una animación de pantalla), los flash sí tienen que mostrarse individualmente. En mi "arreglo" todo se mostraba solo en el primer battler, flash incluído. Me dí cuenta de ésto hace mucho pero no lo comenté porque no supe arreglarlo por mí mismo.

La solución de dí para los de las músicas es demasiado chapucera y no la recomiendo.
Mi recomendación es usar ogg, puesto que parece que no dan ese problema. No soluciona el bug pero sí el problema xDD

Vayamos a lo interesante, he solucionado el bug de J&L, era muy sencillo pero en ese entonces no caí en que puediera ser eso xD

Aquí tenéis el bugfix de eso, pegad encima de main:

Código:
class Game_Event
  alias transferring_fix_cet_auto check_event_trigger_auto unless $@
  def check_event_trigger_auto
    if @trigger == 2 and $game_temp.transition_processing
      return
    end
    transferring_fix_cet_auto
  end
end





¡Y a seguir intentando arreglar los que aún no tienen arreglo!

PD.- Quizá fue egoísta por mi parte solo aceptar los de XP, o quizá es que simplemente la cosa fue así xD Mejor no mezclar distintos makers aquí, y solo hablar del XP, pero se puede crear un post similar para cualquiera de los otros maker.

Edit importante:

He estado intentando arreglar el "Bug de Mostrar Animación en pantalla a múltiples sprites".
Parece que funciona bien ahora, pero no estoy muy seguro de que así sea (porque está como medio reciclado de otra cosa que intenté hace tiempo), así que os pido que lo testeéis, porfavor.

Código:
module RPG
  class Sprite < ::Sprite
    def animation(animation, hit=true, show=true)
      dispose_animation
      @_animation = animation
      return if @_animation == nil
      @_animation_hit = hit
      @_animation_duration = @_animation.frame_max
      animation_name = @_animation.animation_name
      animation_hue = @_animation.animation_hue
      bitmap = RPG::Cache.animation(animation_name, animation_hue)
      if @@_reference_count.include?(bitmap)
        @@_reference_count[bitmap] += 1
      else
        @@_reference_count[bitmap] = 1
      end
      @_animation_sprites = []
      if @_animation.position != 3 or not @@_animations.include?(animation)
        for i in 0..15
          sprite = ::Sprite.new(self.viewport)
          sprite.bitmap = bitmap
          sprite.visible = false
          @_animation_sprites.push(sprite)
        end
        unless @@_animations.include?(animation)
          @@_animations.push(animation)
        end
      end
      update_animation(show)
    end
 
    def loop_animation(animation, show=true)
      return if animation == @_loop_animation
      dispose_loop_animation
      @_loop_animation = animation
      return if @_loop_animation == nil
      @_loop_animation_index = 0
      animation_name = @_loop_animation.animation_name
      animation_hue = @_loop_animation.animation_hue
      bitmap = RPG::Cache.animation(animation_name, animation_hue)
      if @@_reference_count.include?(bitmap)
        @@_reference_count[bitmap] += 1
      else
        @@_reference_count[bitmap] = 1
      end
      @_loop_animation_sprites = []
      for i in 0..15
        sprite = ::Sprite.new(self.viewport)
        sprite.bitmap = bitmap
        sprite.visible = false
        @_loop_animation_sprites.push(sprite)
      end
      update_loop_animation(show)
    end
 
    def update_animation(show=true)
      if @_animation_duration > 0
        frame_index = @_animation.frame_max - @_animation_duration
        cell_data = @_animation.frames[frame_index].cell_data
        position = @_animation.position
        animation_set_sprites(@_animation_sprites, cell_data, position, show)
        for timing in @_animation.timings
          if timing.frame == frame_index
            animation_process_timing(timing, @_animation_hit)
          end
        end
      else
        dispose_animation
      end
    end
 
    def update_loop_animation(show=true)
      frame_index = @_loop_animation_index
      cell_data = @_loop_animation.frames[frame_index].cell_data
      position = @_loop_animation.position
      animation_set_sprites(@_loop_animation_sprites, cell_data, position, show)
      for timing in @_loop_animation.timings
        if timing.frame == frame_index
          animation_process_timing(timing, true)
        end
      end
    end
 
    def animation_set_sprites(sprites, cell_data, position, show=true)
      for i in 0..15
        sprite = sprites[i]
        pattern = cell_data[i, 0]
        if sprite == nil or pattern == nil or pattern == -1
          sprite.visible = false if sprite != nil
          next
        end
        sprite.visible = show
        sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
        if position == 3
          if self.viewport != nil
            sprite.x = self.viewport.rect.width / 2
            sprite.y = self.viewport.rect.height - 160
          else
            sprite.x = 320
            sprite.y = 240
          end
        else
          sprite.x = self.x - self.ox + self.src_rect.width / 2
          sprite.y = self.y - self.oy + self.src_rect.height / 2
          sprite.y -= self.src_rect.height / 4 if position == 0
          sprite.y += self.src_rect.height / 4 if position == 2
        end
        sprite.x += cell_data[i, 1]
        sprite.y += cell_data[i, 2]
        sprite.z = 2000
        sprite.ox = 96
        sprite.oy = 96
        sprite.zoom_x = cell_data[i, 3] / 100.0
        sprite.zoom_y = cell_data[i, 3] / 100.0
        sprite.angle = cell_data[i, 4]
        sprite.mirror = (cell_data[i, 5] == 1)
        sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
        sprite.blend_type = cell_data[i, 7]
      end
    end
  end
end

class Game_Battler
  attr_accessor :show_animation
  alias show_animation_ini initialize unless $@
  def initialize(*args)
    show_animation_ini(*args)
    @show_animation = true
  end
end

class Scene_Battle
  def update_phase4_step4
    if @animation2_id != 0 and $data_animations[@animation2_id].position == 3
      for target in @target_battlers
        target.show_animation = false
      end
    end
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = (target.damage != "Miss")
    end
    @wait_count = 8
    @phase4_step = 5
  end
end

class Sprite_Battler < RPG::Sprite
  def update
    super
    if @battler == nil
      @battler_name = nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    if @battler.battler_name != @battler_name or
      @battler.battler_hue != @battler_hue
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
      @width = bitmap.width
      @height = bitmap.height
      self.ox = @width / 2
      self.oy = @height
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    if @battler.damage == nil and
      @battler.state_animation_id != @state_animation_id
      @state_animation_id = @battler.state_animation_id
      loop_animation($data_animations[@state_animation_id])
    end
    if @battler.is_a?(Game_Actor) and @battler_visible
      if $game_temp.battle_main_phase
        self.opacity += 3 if self.opacity < 255
      else
        self.opacity -= 3 if self.opacity > 207
      end
    end
    if @battler.blink
      blink_on
    else
      blink_off
    end
    unless @battler_visible
      if not @battler.hidden and not @battler.dead? and
        (@battler.damage == nil or @battler.damage_pop)
        appear
        @battler_visible = true
      end
    end
    if @battler_visible
      if @battler.hidden
        $game_system.se_play($data_system.escape_se)
        escape
        @battler_visible = false
      end
      if @battler.white_flash
        whiten
        @battler.white_flash = false
      end
      if @battler.animation_id != 0
        animation = $data_animations[@battler.animation_id]
        animation(animation, @battler.animation_hit, @battler.show_animation)
        @battler.animation_id = 0
      end
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
        @battler.damage = nil
        @battler.critical = false
        @battler.damage_pop = false
      end
      if @battler.damage == nil and @battler.dead?
        if @battler.is_a?(Game_Enemy)
          $game_system.se_play($data_system.enemy_collapse_se)
        else
          $game_system.se_play($data_system.actor_collapse_se)
        end
        collapse
        @battler_visible = false
      end
    end
    self.x = @battler.screen_x
    self.y = @battler.screen_y
    self.z = @battler.screen_z
  end
end


Edit: Creí haber encontrado otro bug interno con la interacción de los eventos pero resultó no ser interno en realidad xDD


Última edición por Wecoc el 2014-04-20, 14:26, editado 1 vez
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2014-06-20, 23:18

He detectado un nuevo Bug interno del XP (al menos en mi versión) mientras hacía un script que estamos haciendo conjuntamente con Eron (bueno, yo solo le ayudo)

Por suerte tiene fácil solución xD

En Estados hay un tipo de restricción llamada "Inhabilitad Magias" (que debería ser Inhabilitar pero ahí no me meto xD)

Eso debería hacer que en menú al seleccionar Habilidades y luego intentar seleccionar el actor con dicho estado, no te dejara hacerlo.
Pero no, porque la variable restricción con esa propiedad es 1 y en el menú sale >= 2 (no atacar - no defenderse - no mover // lo cual en menú no tiene demasiado sentido xD)

Además hay otro problema; tú pones restriction >= 1 y va de perlas, no te deja entrar en Scene_Skill con ese actor. ¡Pero te deja entrar con otro e ir a ese con Q / W! xDDD

Aquí el script que arregla todo ese follón. Lamentablemente es un bug situado en el update y hace de mal aliasear (?) así que es un tochote... Si lo preferís podéis cambiarlo en el default, ya puse en el script unos comentarios dónde pone ## BUGFIX para que os orientéis mejor con todo ésto.

Código:
class Scene_Menu
  def update_status
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Make command window active
      @command_window.active = true
      @status_window.active = false
      @status_window.index = -1
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Branch by command window cursor position
      case @command_window.index
      when 1  # skill
        # If this actor's action limit is 2 or more
        if $game_party.actors[@status_window.index].restriction >= 1 ## BUGFIX
          # Play buzzer SE
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        # Play decision SE
        $game_system.se_play($data_system.decision_se)
        # Switch to skill screen
        $scene = Scene_Skill.new(@status_window.index)
      when 2  # equipment
        # Play decision SE
        $game_system.se_play($data_system.decision_se)
        # Switch to equipment screen
        $scene = Scene_Equip.new(@status_window.index)
      when 3  # status
        # Play decision SE
        $game_system.se_play($data_system.decision_se)
        # Switch to status screen
        $scene = Scene_Status.new(@status_window.index)
      end
      return
    end
  end
end

class Scene_Skill
  #--------------------------------------------------------------------------
  # * Frame Update (if skill window is active)
  #--------------------------------------------------------------------------
  def update_skill
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Switch to menu screen
      $scene = Scene_Menu.new(1)
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Get currently selected data on the skill window
      @skill = @skill_window.skill
      # If unable to use
      if @skill == nil or not @actor.skill_can_use?(@skill.id)
        # Play buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # If effect scope is ally
      if @skill.scope >= 3
        # Activate target window
        @skill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.visible = true
        @target_window.active = true
        # Set cursor position to effect scope (single / all)
        if @skill.scope == 4 || @skill.scope == 6
          @target_window.index = -1
        elsif @skill.scope == 7
          @target_window.index = @actor_index - 10
        else
          @target_window.index = 0
        end
      # If effect scope is other than ally
      else
        # If common event ID is valid
        if @skill.common_event_id > 0
          # Common event call reservation
          $game_temp.common_event_id = @skill.common_event_id
          # Play use skill SE
          $game_system.se_play(@skill.menu_se)
          # Use up SP
          @actor.sp -= @skill.sp_cost
          # Remake each window content
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          # Switch to map screen
          $scene = Scene_Map.new
          return
        end
      end
      return
    end
    # If R button was pressed
    if Input.trigger?(Input::R) ## BUGFIX
      if $game_party.actors.size == 1
        # $game_system.se_play($data_system.buzzer_se)
        return
      end
      actor_index = @actor_index
      loop do
        @actor_index += 1
        @actor_index %= $game_party.actors.size
        unless $game_party.actors[@actor_index].restriction >= 1
          break
        end
        if @actor_index == actor_index
          break
        end
      end
      if @actor_index == actor_index
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.cursor_se)
      $scene = Scene_Skill.new(@actor_index)
      return
    end
    # If L button was pressed
    if Input.trigger?(Input::L) ## BUGFIX
      if $game_party.actors.size == 1
        # $game_system.se_play($data_system.buzzer_se)
        return
      end
      actor_index = @actor_index
      loop do
        @actor_index -= 1
        @actor_index %= $game_party.actors.size
        unless $game_party.actors[@actor_index].restriction >= 1
          break
        end
        if @actor_index == actor_index
          break
        end
      end
      if @actor_index == actor_index
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.cursor_se)
      $scene = Scene_Skill.new(@actor_index)
      return
    end
  end
end


A sus mercedes me hallo.
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por orochii el 2014-06-21, 02:40

x'DDDDDDDDDDDDD vaya qué gran metida de patas esa x'D. No recuerdo si eso lo había cambiado yo en mi Dreki, o si ni lo había pensado porque el silencio se quita al final de batalla :D?.

Pero le echaré un vistazo.
avatar
orochii
Reportero

0/3

Créditos 7463

Gracias : 368

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2014-08-17, 13:43

He universalizado éste topic llevándolo a Chaos Project: LINK
LittleDrago ha hecho tres bugfixes 100 veces más concisos que los que había hecho yo... dita sea xD
Y además salió un nuevo bug al que *cruzo dedos* ya le hice su bugfix.
Podéis seguir comentando bugs aquí, porque hay más, y los seguiré resolviendo y/o "botando" hacia allí. ¡Entre las dos comunidades haremos más!
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Wecoc el 2015-09-12, 17:36

He detectado un nuevo bug interno en RPG maker XP.

La imagen del bug se explica por sí sola:



Explicado rápidamente, puedes interactuar con un evento aunque esté fuera de tu "alcance" (o tú fuera del suyo), la interacción va por simple coordenada. El peor caso es con colisionar...

Lo he arreglado con éste precioso script:

Código:
class Game_Character
  attr_accessor :passable_touch
  alias passable_touch_ini initialize unless $@
  def initialize
    passable_touch_ini
    @passable_touch = false
  end
 
  def no_event_passable?(x, y, d)
    new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
    new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
    return true  if @passable_touch == true
    return false unless $game_map.valid?(new_x, new_y)
    return true  if @through
    return false unless $game_map.passable?(x, y, d, self)
    return false unless $game_map.passable?(new_x, new_y, 10 - d)
    return true
  end
end

class Game_Event < Game_Character
  alias collision_passable_fix check_event_trigger_touch unless $@
  def check_event_trigger_touch(new_x, new_y)
    if @x != new_x
      d = (@x < new_x ? 6 : 4)
    elsif @y != new_y
      d = (@y < new_y ? 2 : 8)
    end
    if (@x == new_x) and (@y == new_y) or no_event_passable?(@x, @y, d)
      collision_passable_fix(new_x, new_y)
    end
  end
end

class Game_Player < Game_Character
  def check_event_trigger_there(triggers)
    result = false
    if $game_system.map_interpreter.running?
      return result
    end
    new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
    new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
    for event in $game_map.events.values
      if event.x == new_x and event.y == new_y and
        triggers.include?(event.trigger)
        if not event.jumping? and not event.over_trigger?
          passable = no_event_passable?(@x, @y, @direction)
          if event.passable_touch == true or passable
            event.start
            result = true
          end
        end
      end
    end
    if result == false
      if $game_map.counter?(new_x, new_y)
        new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
        new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
        for event in $game_map.events.values
          if event.x == new_x and event.y == new_y and
            triggers.include?(event.trigger)
            if not event.jumping? and not event.over_trigger?
              passable = no_event_passable?(@x, @y, @direction)
              if event.passable_touch == true or passable
                event.start
                result = true
              end
            end
          end
        end
      end
    end
    return result
  end
 
  def check_event_trigger_touch(x, y)
    result = false
    if $game_system.map_interpreter.running?
      return result
    end
    for event in $game_map.events.values
      if event.x == x and event.y == y and [1,2].include?(event.trigger)
        if not event.jumping? and not event.over_trigger?
          passable = no_event_passable?(@x, @y, @direction)
          if event.passable_touch == true or passable
            event.start
            result = true
          end
        end
      end
    end
    return result
  end
end

Si el personaje no puede pasar hacia el evento (sin contar la pasabilidad del propio evento), tampoco puede interactuar con él.

Y además usando $game_map.events[ID].passable_touch = true/false puedes desactivar el efecto, para eventos en los que necesites una interacción default (como ese boss del XAS que es un pájaro al borde de un acantilado, por ejemplo xD)
avatar
Wecoc
Administrador
Administrador



Créditos 12103

Gracias : 522

Volver arriba Ir abajo

RPG Maker XP Re: Bugs internos

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


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