Documentación de WeiDU

Westley Weimer
weimer@cs.berkeley.edu




Índice
1 Sobre WeiDU

La página principal de WeiDU es: http://www.cs.berkeley.edu/~weimer/bgate/. Te recomiendo encarecidamente que descargues la última versión.

WeiDU está diseñado para hacer más fácil la escritura y distribución de modificaciones de los juegos del Infinity Engine. Puede cargar y modificar los recursos del Infinity Engine de acuerdo a las ordenes que introduzcas. WeiDU es ideal para empaquetar modificaciones que incluyan diálogo o que deban ser compatibles con otras modificaciones.

Seré honesto: Al principio, WeiDU es más difícil de usar que algunas de sus alternaticas. Sin embargo, la mayoría de los usuarios dicen que: 1) Las alternativas son insuficientes porque carecen de la capacidad que sólo WeiDU ofrece, y 2) WeiDU te engancha y mejora con el tiempo.

Eres bienvenido/a a usar estas utilidades para crear y distribuír tus propios módulos del Infinity Engine. Esta utilidad está bajo la GNU General Public License , pero puedes distribuir una copia binaria sin modificar de WeiDU.EXE (sin el código fuente) con tu módulo si lo deseas.

Decidí crear mis propias utilidades de DLG y TLK del Infinity Engine porque no pude conseguir que el TeamBG DLG Editor y el Mass Converter trabajaran correctamente. No analizaban las cadenas gramaticalmente o mutilaban los textos o fallaban aleatoriamente... estaba completamente mal. Además eran todos GUIs (Grafic User Interface). Como un creyente de Unix estaba enamorado de las utilidades de líneas de comando y como un estudiante de investigación PL, me encanta hacer pequeños lenguajes y compiladores. WeiDU fue originalmente una familia de pequeños programas con nombres poco imaginativos como DC, DD y TP. El término ``WeiDU'', más atractivo (el cual rima con ``IDU'', Eye-Dee-You) fué acuñado por Jason Compton y Ghreyfain, autores notables de módulos de Baldur's Gate II.

2 ¡No tengas miedo!

Paso a paso, una guía para principiantes de WeiDU:
  1. No temas. Muchos como tu son niños en la era GUI. Pero los programas que trabajan con líneas de comando pueden ser tus amigos, y al final te darás cuenta de que trabajan más rápido y, si, son más fáciles de usar.

  2. La mejor forma de aprender como escribir código en formato D de WeiDU es Leyendo código escrito en formato D de WeiDU. Comienza decompilando los DLGs existentes en el juego que entiendas y léelos completamente. Compara como aparecen en WeiDU con como aparecen en otras herramientas de edición del BG2, herramientas con las cuales te sientes más a gusto, como el Near Infinity o el Infinity Explorer.

  3. La mejor manera de escribir código en formato D de WeiDU es leer código escrito en formato D de WeiDU, Parte 2. Un creciente número de paquetes de adiciones al BG2 están siendo creadas usando WeiDU. Hay una lista disponible en http://www.cs.berkeley.edu/~weimer/bgate/weidumods.html. Estos pueden ayudarte a entender los rasgos avanzados de WeiDU, como el anexo de diálogo, scripts y la edición de los 2DA, y la introducción de objetos/conjuros/criaturas trabajando en el escenario del ``mundo real''. Intenta descargar algunos para entender COMO trabajan.

  4. Echa un vistazo a algunos de los ejemplos de este documento. Hay un tutorial de WeiDU muy bueno (escrito por Japheth) disponible en http://dragon-forge.fwstudios.net/tutorial-weidu.htm. Si te estás sintiendo abrumado, empieza con ese, que también cubre la instalación. Ghreyfain también tiene un tutorial de ``Cómo crear un NPC con WeiDU'' en http://forums.db-forge.com/forgottenwars/index.php?board=13;action=display;threadid=678

  5. Finalmente, hay un foro de discusión de WeiDU en http://forums.fwstudios.net/index.php?act=SF&f=50.
3 D y DLG: Conceptos básicos

Esta sección es una introdicción suave a como están estructurados los archivos DLG del Infinity Engine. Primero, vamos a usar WeiDU para crear SCSARLES.D y echar un vistazo al diálogo de Sir Sarles.

Puedes instalar WeiDU.exe en cualquier parte de tu sistema. Sin embargo, te recomiendo que lo coloques en el directorio de instalación de tu Baldur's Gate 2. Aún así, WeiDU usará el Registro de Windows para intentar localizar los archivos del BG2.

Para lograr el efecto descrito, abre una ventana DOS y colócate en tu directorio del BG2. Luego solo escribe el texto en rojo en la linea de comandos del DOS.

C:\Archivos de Programa\Black Isle\BGII - SoA\> weidu SCSARLES.DLG


Esto creará un archivo de texto llamado SCSARLES.D en el directorio actual. Ábrelo con el NotePad o el Microsoft Word o algo de eso. Solo es un archivo de texto que describe el diálogo del juego.

Se verá algo así como:
// creator  : c:\bgate\weidu\weidu.asm.exe
// argument : SCSARLES.DLG
// game     : C:\Program Files\Black Isle\BGII - SoA
// source   : C:\Program Files\Black Isle\BGII - SoA\data\Dialog.bif
// dialog   : C:\Program Files\Black Isle\BGII - SoA\\t{DIALOG.}\ttref{TLK}
// dialogF  : (none)

BEGIN ~SCSARLES~

IF ~NumTimesTalkedTo(0)~ THEN BEGIN 0 // from:
  SAY #28655 /* ~¿Quién es? ¿Se puede saber por qué me has interrumpido mientras
    meditaba? A mi musa creativa hay que despertarla dulcemente y tu
    estruendo no es nada apropiado.~ [SARLES02] */
  IF ~~ THEN REPLY #28656 /* ~Perdón. Te dejaré con tus
    pensamientos.~ */ GOTO 1
  IF ~~ THEN REPLY #28657 /* ~Lo siento, pero he venido en busca de tu
    talento para un encargo artístico.~ */
      DO ~SetGlobal("TalkedToSarles","GLOBAL",1)~ GOTO 2
END

IF ~~ THEN BEGIN 1 // from: 0.0
  SAY #28661 /* ~Entonces olvidaré incluso que alguna vez estuviste aquí. Lo cierto es que es 
    increíblemente fácil de hacer.~ */
  IF ~~ THEN DO ~SetNumTimesTalkedTo(0)~ EXIT
END
Los diálogos en los juegos del Infinity Engine se comportan como máquinas de estado finito. Si no estás familiarizado con el concepto de máquinas de estado finito, mira http://whatis.techtarget.com/definition/0,,sid9_gci213052,00.html or http://www.c3.lanl.gov/mega-math/workbk/machine/mabkgd.html. Cada bloque de la forma:
  IF ~Condición inicial~ THEN BEGIN situación1 
    SAY ~Algo~
    IF ~Condición de respuesta~ THEN REPLY ~Texto de respuesta~ GOTO situación2
  END
representa una situación (más detalles abajo). Cuando el jugador comienza una conversación con un NPC, el engine del juego explora a través de todas las situaciones en el archivo DLG de ese personaje en un orden especial de carga (WEIGHT) y toma la única que tiene una "Condición Inicial" no-vacía y verdadera. Si ninguna situación tiene una "Condición Inicial" no-vacía y verdadera, entonces consigues que aparezca el mensaje ``Bob - No tiene nada para decirte.''. No te preocupes por el de carga por ahora.

El interlocutor (en este caso, Sir Sarles) entonces dirá cualquier cosa que aparezca luego de SAY. Las líneas REPLY representan las respuestas que el personaje del jugador puede regresar. Si la "Condición de Respuesta" es verdadera, al jugador le es concedida la opción de decir el "Texto de Respuesta" y moverse a otra situación en el diálogo (donde Sarles probablemente dirá algo más).

Recuerda: SAY es para lo que dicen los NPCs, REPLY es para lo que los jugadores responden. Si lo piensas bien, notarás que todos los diálogos en los juegos del Infinity Engine están estructurados de esta manera.

Las condiciones tienen la misma sintaxis que se usa en los scripts BCS en el Infinity Engine. Necesitarás aprender scripting del Infinity Engine dentro de poco. Las cadenas (de caracteres o strings en los lenguajes de programación) son definidas entre tildes o "" (a tu elección, pero WeiDU esa el tilde por defecto). Después de SAY o REPLY o JOURNAL puedes dar dos cadenas en lugar de una. La primera es usada con el DIALOG.TLK, la segunda es usada con el DIALOGF.TLK (para las lenguas extranjeras, cuando el personaje principal es femenino). Si no das dos cadenas, la única que diste se usa para ambos.

También puedes usar simples números precedidos con un signo de número (como #1234) para especificar una referencia dentro del directorio del DIALOG.TLK. Esto es útil cuando estás modificando diálogos existentes (digamos, el Espíritu del Destino en ToB). Entonces si un usuario extranjero instala tu diálogo, mantendrá todas las versiones extranjeras de las cadenas que no cambiaste o añadiste. Normalmente los números de referencia de las cadenas son puestos a la derecha después de la palabra clave SAY y la frase es puesta luego en comentarios. La línea de comando --text hace que el texto sea emitido junto con su número de referencia en comentarios.

También puedes indicar que un archivo de sonido (WAV/WAVC) debe ser asociado con la cadena dada, este incluye un nombre de recurso de no más de 8 letras, en [corchetes] luego de la frase, como en:
  SAY ~Hola~ [HELLO]
Los comentarios son al estilo de C/C++: desde // hasta el fin de la línea es un comentario, como lo es /* todo entre estos signos (barra y estrella) */. Los comentarios son ignorados por WeiDU. Son para tu beneficio. Ejemplo::
  SAY ~Hola~ [HELLO]   // esto es un comentario... ¡y aquí termina!
  IF /* Esto también es un comentario */ ~~ THEN EXIT
Las respuestas también pueden contener acciones (usando la palabra clave DO), la cual se comporta igual que las acciones de los scripts BCS del Infinity Engine. También pueden agregar entradas al diario, terminar el diálogo o transferirlo a otro hablante.

Ejemplos:
  IF ~~ THEN BEGIN 2 // from: 0.1
La línea marca el comienzo de la situación 2 en el diálogo. El comentario te dice que puede ser alcanzado en la primera transicion de la respuesta de la situación 0.
  IF ~~ THEN REPLY ~Perdón. Te dejaré con tus pensamientos
~ // #28656 
      GOTO 1
Este REPLY siempre puede ser elegido e involucra el texto hablado "Perdón...". Ese texto es la cadena con el número de referencia 28656. Si el jugador elige esa respuesta, se translada a la situación 1.

Finalmente, una transición también puede tomar esta forma:
  COPY_TRANS filename label
N. del T: Filename: Nombre del Archivo. Label: Etiqueta

Durante el proceso, COPY_TRANS será reemplazado por todas las transiciones de la situación "label" del archivo "filename". Las copias ocupan un puesto antes de todas las otras acciones D.

4 Formato de diálogo D

El formato de archivo D es una manera de describir los diálogos del Infinity Engine y los diálogos de sus modulos en un formato portable y sencillo de comprender. Soporta traducciones a idiomas extranjeros y te permite escribir extensiones a los diálogos ya existentes del juego sin forzarte e escribir de vuelta la parte que no se modificará. Esto te permitirá escribir módulos que trabajen con otros módulos escritos por otras personas.

El formato de archivoD es presentado aquí en un extenso libre contexto con notaciones gramáticales . Si no estás familiarizado con los CFGs, echa un vistazo a http://www.wikipedia.com/wiki/Context-free_grammar, http://cs.wpi.edu/~kal/PLT/PLT2.1.2.html o http://www.cs.rochester.edu/users/faculty/nelson/courses/csc_173/grammars/cfg.html. Sin embargo, no necesitas realmente comprender un CFG como es debido.

Para tener una idea real de como funcionan, usa WeiDU para crear JAHEIRA.D para ti y míralo en el editor de texto. También puedes explorar los directorios examples y test que vienen con WeiDU.

Todas las palabras clave de sintaxis son dadas en COURIER MAYÚSCULA. Todas las otras palabras clave son complementarias. Notas:
Archivo D   Un archivo D es un archivo de texto que contiene un número de Acciones D. Los Archivos D le dicen a WeiDU como crear y modificar los archivos DLG del Infinity Engine.
Es Acción D lista Un archivo D es una lista de acciones D. Generalmente la primera y única es BEGIN, la cual define el contenido de un nuevo diálogo. Otras acciones D pueden ser usados para modificar diálogos existentes.
 
Acción D   Una acción D le dice a WeiDU como crear o modificar archivos DLG del Infinity Engine.
Es BEGIN Nombre del Archivo [ nonPausing ] situación lista BEGIN le dice a WeiDU que tu estás creando un nuevo archivo DLG. Cualquier archivo DLG con el mismo nombre será sobreescrito. El nuevo archivo DLG contiene exactamente las situaciones en la lista. Si fijas nonPausing en un entero distinto a cero, el juego no ``parará el tiempo'' mientras las conversaciones toman lugar. Por defecto, el tiempo se detiene durante las conversaciones.
o APPEND Nombre del Archivo situación lista END Esto le dice a WeiDU que coloque las situaciones dadas al final de un archivo filename.DLG ya existente.
o CHAIN [ IF [ WEIGHT #weight ] stateTriggerString THEN ] entryFilename entryLabel chainText lista chainEpilogue Esto indica a WeiDU como hacer una larga conversación en la cual el personaje del jugador puede no decir nada. Esto es útil cuando quieres que los NPCs hablen entre ellos por largo tiempo. CHAIN y sus amigos, INTERJECT y INTERJECT_COPY_TRANS pueden ser extremadamente eficientes cuando estás escribiendo conversasiones no triviales. Mira los ejemplos para hacerte la idea. CHAIN solo adjuntará a los diálogos existentes. No puedes usar CHAIN para crear un nuevo DLG.
o INTERJECT entryFilename entryLabel globalVariable chainText lista exitFilename exitLabel Se comporta como CHAIN excepto que el chainText es guardado adicionalmente por el predicado transicion Global("globalVariable","GLOBAL",0) y acompañado por la acción SetGlobal("globalVariable","GLOBAL",1). Si tomas globalVariable para ser único, esto se asegurará de que chainText es visto sólo una vez por juego. Esto es útil para hacer interjecciones.
o INTERJECT_COPY_TRANS entryFilename entryLabel globalVariable chainText lista Esto se comporta justo como INTERJECT excepto que el exitFilename y el exitLabel no estás presentes. En lugar de eso, En lugar de eso, cuando quiera que el diálogo desapareciera del chainText lo seguiría una copia de las transiciones que estaban en la situación con stateLabel originalmente. Esto es conveniente para hacer interjecciones rápidas para NPCs que no cambien el flujo verdadero de la conversación. Mira la transicion COPY_TRANS para más información acerca de esta idea.
o EXTEND_TOP archivo stateLabel lista [ #positionNumber ] transicion lista END Esto instruye a WeiDU a añadir todas las transiciones en lista hasta la cima de la lista de transicion para las situaciones especificadas en archivo.DLG (el cual debe YA existir).
Si es dada una positionNumber, WeiDU intertará las transiciones justo entre las trassiciones ya existentes #positionNumber y #positionNumber+1 en las situaciones para el archivo dado. La primer transicion lleva el número 1.
o EXTEND_BOTTOM archivo stateNumber lista [ #positionNumber ] transicion lista END Se comporta como EXTEND_TOP pero agrega las transiciones al final de la lista.
o ADD_STATE_TRIGGER archivo stateNumber stateTriggerString [ stateNumber lista ] Esto instruye a WeiDu para añadir la stateTriggerString a todas las situaciones con los stateNumbers dados en el archivo archivo.DLG (el cual debe YA existir). Esto es conveniente para añadir condiciones extra a las situaciones de un diálogo ya existente.
o ADD_TRANS_TRIGGER archivo stateNumber transTriggerString [ stateNumber lista ] Esto instruye a WeiDU para añadir la transTriggerString a todas las transiciones en todas las situaciones con los stateNumbers dados en el archivo archivo.DLG (el cual debe YA existir). Esto en muy usado en conjuncion con EXTEND_BOTTOM para hacer una nueva bifurcación en una situacion existente. Usa ADD_TRANS_TRIGGER para añadir la negación de algun predicado de todas las transiciones existentes, luego usa EXTEND_BOTTOM para añadir una transicion con ese predicado para esa situacion.
o REPLACE archivo situación lista END Esto instruye a WeiDU para cargar archivo.DLG y remplazar algunas de sus situaciones con la nuevas descirptas en la lista de la situación. Todas las situaciones deben tener stateLabels numéricos (por ejemplo, "5" o "67"). Una nueva situación con la etiqueta X reemplazará a la vieja situación de número X.
o SET_WEIGHT archivo stateLabel #stateWeight Esto instruye a WeiDU para cambiar destructivamente el WEIGHT de la situación dada en archivo.DLG (el cual YA debe existir). Esto puede ser usado sólo para reparar o controlar los diálogos existentes. Nunca uses SET_WEIGHT si puedes evitarlo.
o REPLACE_SAY archivo stateLabel sayString Esto instruye a WeiDU para cambiar destructivamente el sayString de la situación dada en archivo.DLG (el cual DEBE existir). Esto debe ser usado solamente para reparar o controlar los diálogos existentes. Nunca uses REPLACE_SAY si puedes evitarlo.
o REPLACE_STATE_TRIGGER archivo stateNumber stateTriggerString [ stateNumber lista ] Esto instruye a WeiDU para colocar destructivamente las stateTriggerString de todas las situaciones con los stateNumbers dados en el archivo archivo.DLG (El cual debe YA existir). Esto debe ser usado con cuidado.
o REPLACE_TRIGGER_TEXT archivo oldText newText Esto instruye a WeiDU para reemplazar todas las ocurrencias de oldText (texto viejo) (el cual puede ser un regexp) en los stateTriggerStrings y los transTriggerStrings de archivo.DLG (El cual DEBE existir). Esto debe ser usado solamente para reparar o controlar los diálogos existentes. Nunca lo uses si puedes evitarlo.
o REPLACE_ACTION_TEXT archivo oldText newText Esto instruye a WeiDU para reemplazar destructivamente todas las ocurrencias de oldText (texto viejo) (el cual puede ser un regexp) en las stateActionStrings de archivo.DLG (el cual DEBE existir). Esto puede ser usado solamente para reparar o controlar los diálogos existentes. Nunca uses esto si puedes evitarlo.
 
chainEpilogue   Determina donde el diálogo debe llegar a su fin en CHAIN.
Es END archivo stateNumber Transfiere la situación dada in el archivo de diálogo dado.
o EXTERN archivo stateNumber Transfiere la situación dada in el archivo de diálogo dado.
o COPY_TRANS archivo stateNumber Al final del texto de CHAIN, copia todas las transiciones de la situación dada en el archivo dado. Esto es útil para las interjecciones (ver INTERJECT).
o EXIT Al final del texto CHAIN, para finalizar el diálogo.
 
situación   En los juegos del Engine Infinity, esta es la unidad fundamental de diálogo.
Es IF [ WEIGHT #weightNumber ] stateTriggerString THEN BEGIN stateLabel SAY sayText [ = SayText ... ] transicion lista END Cuando comienzas a hablar con una criatira que usa un archivo DLG, el Engine Infinity busca a través de todas las situaciones en ese archivo en orden de WEIGHT creciente y selecciona y selecciona la primera que encuentra de la cual el stateTriggerString es verdadero y no-vacío. La criatura dirá entonces todo lo del sayText asociado. Finalmente, las transiciones son evaluadas en orden de abajo hacia arriba (i.e., reversa). Si una transicion es encontrada con untransTriggerString que es evaluada como Verdadera y no replyText, esatransicion es ejecutada de inmediato. De otra manera, todas las transiciones son presentadas como opciones para el personaje del jugador.
Si una stateLabel es un entero, este es llamado un stateNumber. Todas las situaciones en los archivos DLG que vienen con el juego original usan stateNumbers. Solo los archivos D usan cadenas de caracteres simbólicas para las stateLabels.
Si se incluye más de un pedazo de sayText, esto es llamado Multisay.
o APPENDI archivo situación lista END Esto se comporta justo como el APPEND de la Acción D pero es considerado unasituación. Evita su uso.
o CHAIN2 entryFilename entryLabel chain2Text lista exitFilename exitLabel Esto se comporta como el CHAIN de una Acción D pero es considerado una situación. En fin, chain2Text es ligeramente distinto de chainText. Evita esta construcción.
 
transición   Las transiciones determinan como fluye el diálogo desde una situación a otra.
Es IF transTriggerString THEN transFeature lista transNext Si la transTriggerString es evaluado como Verdadero o está vacío, esta transición es fiable. Si no contiene replyText dentro de su lista de transFeature, es tomado inmediatamente. De otra manera, el replyText es presentado como una opción para el usuario. Si la transición es tomada, ninguna acción en la lista de transFeature es ejecutada y el diálogo fluye desde el punto indicado por el transNext. Las transiciones son evaluadas en "orden inverso". Así, la última respuesta para una situación es chequeada primero. Si su transTriggerString es avaluada como Verdadero y no tiene texto REPLY, esa transición es tomada inmediatamente. Mira SAREV25A, la situación 1 por un ejemplo de una situación con toda clase de transiciones.
o COPY_TRANS archivo stateLabel Esto instruye a WeiDU para copiar todas las transiciones de la situación con la stateLabel dada en archivo.DLG. Esta copia tiene lugar antes de todas las otras Acciones D.
Por ejemplo, esta es una lista de transición válida:
IF ~Before()~ THEN GOTO mi_situación
COPY_TRANS PLAYER1 33
IF ~After()~ THEN EXTERN SOLA 55
 
transFeature   Estos son rasgos o acciones asociadas con la toma de una transición.
Es REPLY replyText Si esta transición es tomada, el PJ dice el replyText.
o DO stateActionString Si esta transición es tomada, la stateActionString es ejecutada.
o JOURNAL texto Si esta transición es tomada, el texto es añadido al diario del PJ.
o SOLVED_JOURNAL texto Si esta transición es tomada, el texto es añadido a la sección ``Gestas cumplidas'' del diario del PJ.
o UNSOLVED_JOURNAL texto Si esta transición es tomada, el texto es añadido a la sección ''Gestas'' del diario del PJ.
o FLAGS entero Esto te permite fijar los rasgos asociados con la transición directa usando el formato binario de los archivos DLG. ¡No uses esto!
 
transNext   Esto determina a donde fluye el diálogo luego de que una transición ha sido tomada.
Es GOTO stateLabel El diálogo continúa en la situación con la etiqueta stateLabel en el mismo archivo DLG de la situación actual.
o EXTERN archivo stateLabel El diálogo continúa en la situación con la etiqueta stateLabel en el archivo archivo.DLG.
o EXIT La conversación termina.
 
chainText   Esto es una rápida taquigrafía para enlazar muchos pequeños pedazos de diálogo cuando el PJ no está diciendo nada.
Es [ IF transTriggerString THEN ] sayText = sayText ...  
seguido por Si el transTriggerString es Verdadero o si no está presente, cada sayText es dicho en orden por el hablante actual. [ == fileName [ IF transTriggerString THEN ] sayText = sayText ... ] El == (son dos signos de igual (=) consecutivos) marca el comienzo de un nuevo hablador (indicado por fileName). Si el transTriggerString es verdadero o no está presente, este nuevo hablador dice todo lo de su sayText en orden.
 
texto   Esto representa las cadenas (de carácteres) que son mostradas a el jugador, y no las cadenas que el juego usa internamente para los predicados y las acciones.
Es cadena [ [WAVEFILE] ] La cadena dada es usada para ambos: jugadores femeninos y masculinos. El [WAVEFILE] opcional es el sonido asociado.
o cadena [ [WAVEFILE] ] cadena [ [WAVEFILE] ] La primer cadena y archivo de sonido son usados si el PJ es masculino, la segunda cadena y archivo de sonido son usados si el PJ es femenino. Esto es útil principalmente para las versiones internacionales (no hablantes de inglés) de los juegos del Engine Infinity.
o #entero La cadena con el número de referencia #entero del DIALOG.TLK debe ser usada de forma inalterada.
o @entero La última definición de la cadena de traducción @entero, dada en algún archivo TRA debe ser usado.

5 Opciones de las líneas de comando

WeiDU es una utilidad de líneas de comando. Los GUIs están disponibles, pero este documento solo describe la evocación de líneas de comando. Usa el DOS Shell ("command" o "cmd") para correr WeiDU. Tu controlas su comportemiento escribiendo argumentos para él a través de las líneas de comando.

Tu invocas WeiDU tipeando WeiDU mientras estás situado en su directorio, y luego cualquier número de opciones y archivos, como los descriptos abajo.
   
Tipos de Archivos de Entrada:  
ARCHIVO.D Compila el ARCHIVO en un DLG.
ARCHIVO.DLG Descompila el ARCHIVO en un D.
ARCHIVO.TLK Usa ARCHIVO como el archivo de entrada principal TLK para todas las operaciones.
ARCHIVO.TP o ARCHIVO.TP2 Lee el ARCHIVO y pregunta al usuario si instalar, reinstalar o desinstalar sus Componentes TP2s.
ARCHIVO.TRA Usa ARCHIVO como una fuente de cadenas de traducción cuando procesa los archivos D.
ARCHIVO.ITM o ARCHIVO.EFF o ARCHIVO.SPL Enlista todos los efectos en el ARCHIVO.
 
Opciones de Entrada Generales:  
--game X Fija el directorio principal del juego en X. WeiDU busca por el CHITIN.KEY y el DIALOG.TLK en el directorio principal del juego. Cuando sea iniciado, WeiDU buscará en el directorio actual y usará el Registro de Windows para encontrar tu juego. Si esto falla, necesitarás usar WeiDU usando el interruptor --game para definir el directorio del BG2. WeiDU también buscará por el BG1, IWD y PST.
--nogame No cargar ninguno de los archivos del juego por defecto
--search X Busca en X por los archivos entrados (acumulativo)
--tlkin X Usar X como DIALOG.TLK
--ftlkin X Usar X como DIALOGF.TLK
--tlkmerge X Anexa las cadenas de X en el DIALOG.TLK cargado.
--autotp Usar DIALOG[F].TLK, leer todos los archivos TP2 y hacer una anotación.
--yes Contestar todas las preguntas de los TP2 con 'Yes'
--uninstall Contestar todas las preguntas de los TP2 con 'Uninstall'
 
Opciones de Salida Generales:
--out X Dirige todos los archivos de salida al directorio X
--backup X Hacer backup de los archivos del directorio X antes de sobreescribirlos
--tlkout X Emite X como nuevo DIALOG.TLK. Debes especificar esta opción para las nuevas cadenas en tus archivos D o TP2 o TRA para mostrar en el juego.
--ftlkout X Emite X como nuevo DIALOGF.TLK
 
Opciones D:
--transin X Usar el archivo TRA de traducción X (acumulativo)
--testtrans Chequea todos los archivos de traducción TRA especificados
--noheader No emite los comentarios de encabezado D
--nofrom No emite los comentarios D del tipo // from:
--nocom No emitir NINGUNO de los comentarios D
--text Emitir cadenas de texto con referencias en los comentarios
--dout X Nombrar un archivo D de salida para emitir (acumulativo)
--traify X Convertir el archivo D o TP2 llamado X para usar TRAs. Usa --dout para especificar el nombre para el recientemente creado archivoTRA.
--traify# X Usar con --traify. Comienza el archivo TRA desde la cadena de traducción @X en vez de @0.
--transref Emitir los números de referencia de las cadenas en los archivos TRA.
--trans Emitir los archivos D y TRA acoplados cuando se descompila un DLG.
 
Opciones de Cadenas TLK:
--traify-tlk Emitir un archivo TRA para el archivo TLK especificado (ver --textout --min --strfind)
--make-tlk X Hacer un archivo TLK para el archivo TRA X (acumulativo, ver --tlkout)
--string X Mostrar la referencia de cadena #X (acumulativo)
--strfind X Mostrar las cadenas que contengan X (acumulativo, regexp permitido)
--strapp X Adicionar la cadena X a el DIALOG.TLK (acumulativo)
 
Opciones BIFF:
--textout X Colocar el texto de salida en el archivo X
--textapp X Adicionar el texto de salida al final del archivo X
--list-biffs Enumerar todos los archivos BIFF en el CHITIN.KEY.
--list-files Enumerar todos los recursos en el CHITIN.KEY.
--biff X Enumerar los contenidos del archivo BIFF X (acumulativo)
--biff-type X Examinar todos los recursos BIFF con la extensión X ... (acumulativo)
--biff-str X ... y enlistar aquellos que contengan X (acumulativo, regexp permitido)
--biff-name X Asumir que los objetos matizados tienen un nombre de strref en el offset X
--biff-get X Extraer el recurso X de los BIFF del juego (acumulativo, regexp permitido)
 
Opciones ARE/ITM/SPL/EFF:
--automate X Automáticamente crea un archivo TP2 para los recursos en el directorio X
--automate-min X Sólo automate las cadenas de referencia sobre X
--list-eff X Enlista los efectos en el recurso X
 
Opciones de Comparación:
--cmp-from X Emite los WRITE_BYTEs para convertir este archivo ...
--cmp-to X ... es este otro.
--dcmp-from X Emite los REPLACEs para convertir este archivo DLG ...
--dcmp-to X ... en este otro.
--tcmp-from X Comparar este archivo TRA (o directorio de archivos TRA files)...
--tcmp-to X ... con este otro (o este directorio).
--tlkcmp-from X Emitir los STRING_SETs para convertir este archivo TLK ...
--tlkcmp-to X ... en este otro.
 
Opciones de datos:
--log X Apuntar las salidas y detalles en X
--autolog Apuntar las salidas y detalles en WSETUP.DEBUG
 
Opciones de Ayuda:
-help Muestra una concisa lista de opciones
--help Muestra una concisa lista de opciones

6 Usos de Ejemplo:
7 Tutoriales de WeiDU

Esta sección incluye tutoriales de partes específicas de WeiDU. Muchos de ellos fueron aportados por usuarios como tu.

7.1 Multi-SAY
Este turorial fue amablemente aportado por Jason Compton.

Aunque una simple línea SAY puede ser de cualquier tamaño, por asuntos de estilo (particularmente en BG2) esta es considerada una buena forma de separar las lineas muy largas en pedazos más pequeños.

Fácilmente uno puede crear una serie de simples bolques de SAY, usando GOTO para el próximo, pero si no hay condiciones especiales siendo chequeadas o acciones siendo tomadas, puedes enlazar muy fácilmente bastantes líneas a la vez.

Digamos que tienes un NPC de escenario eneñando una lección acerca del Proyecto de ley de los Derechos de la Constitución de USA.
BEGIN TEACHER

IF ~NumTimesTalkedTo(0)~ THEN BEGIN constitution_1
  SAY ~On September 25, 1789, the First Congress of the United States
    therefore proposed to the state legislatures 12 amendments to the
    Constitution that met arguments most frequently advanced against it. The
    first two proposed amendments, which concerned the number of constituents
    for each Representative and the compensation of Congressmen, were not
    ratified. Articles 3 to 12, however, ratified by three- fourths of the
    state legislatures, constitute the first 10 amendments of the
    Constitution, known as the Bill of Rights.~
  IF ~~ THEN EXIT
END 
Este es un bloque de diálogo perfectamente válido, pero es extremadamente largo, y probablemente se salga de la ventana de diálogo de los jugadores con baja resolución.

En vez de dividir cada sentencia en una nueva situaión explícita, podemos usar el Multi-SAY y ahorrarnos mucho tecleo. El Multi-SAY es llamado con el signo = (igual), el cual le dice a WeiDU que "el hablante actual debe decir otra línea aquí."

Así es como se vería esa situación D con Multi-SAY:
IF ~NumTimesTalkedTo(0)~ THEN BEGIN constitution_1
  SAY ~On September 25, 1789, the First Congress of the United States
  therefore proposed to the state legislatures 12 amendments to the
  Constitution that met arguments most frequently advanced against it.~
      =
  ~The first two proposed amendments, which concerned the number of
  constituents for each Representative and the compensation of Congressmen,
  were not ratified.~
      =
  ~Articles 3 to 12, however, ratified by three-fourths of the state
  legislatures, constitute the first 10 amendments of the Constitution,
  known as the Bill of Rights.~
  IF ~~ THEN EXIT
END
Esto creará tres situaciones de diálogo, separados por una simple transición de "Continuar".

Y así es como actúa el Multi-SAY en resumidas cuentas. Note que (siempre con WeiDU) los ENTERs y los espacios en blanco antes y después de el signo = son totalmente opcionales, y son usados aquí sólo por ilustración.
SAY ~Uno~ = ~Dos~ = ~Tres~ 
es perfectamente válido también.

Puedes usar Multi-SAY dentro de casi cualquier situación, y puedes usarlo en una Acción D APPEND. Esto es válido:
APPEND J#KLSYJ
  IF ~~ THEN BEGIN Renal1_1
    SAY ~De acuerdo, . Puedo aceptar eso... tienes razón, hay
    asuntos mayores a considerar.~ 
      = 
    ~Pero espero que entiendas por qué dije algo, porque sería
    molesto tener a alguien tan cerca mío, en un rol como ese.~
    IF ~~ THEN EXIT
  END                            // Fin de la situación Renal1_1
END                             // Fin de APPEND J#KLSYJ
Sin embargo, no puedes usar Multi-SAY dentro de REPLACE, porque la naturaleza de REPLACE es cambiar (o reemplazar) una situacióntate simple, mientras que la naturaleza del Multi-SAY is crear múltiples situaciones.

7.2 CHAIN
Este tutorial fue amablemente aportado por Jason Compton.

CHAIN es una extensión del concepto de Multi-SAY, solo que con mútiples participantes. Si tienes dos NPCs hablando de acá para allá por un perídodo de tiempo prolongado, y no necesitas hacer ningún chequeo de condiciones especiales o acciones para que ellos hablen, puede resultar muy tedioso hacer un bloque separado IF/THEN/BEGIN/SAY para cada línea.

Imagina una conversación como esta: Si quieres añadir este pequeño banter a tu juego, podrías hacerlo con 11 bloques APPEND, uno por cada línea, o ahorrar un poco de tiempo duplicando las líneas seguidas de Kelsey e Imoen con Multisay dentro de sus APPENDs, entonces solo necesitarías 9. En realidad, podrías quitar con 2 bloques de APPEND (recuerda que las situaciones no tienen por qué ser escritas en el orden en que son dichas, así que puedes mecionar todas las líneas de Kelsey primero y luego todas las de Immy tan largas como las etiquetas enlacen la conversación correctamente), un con 5 declaraciones de situación y uno con 4. Pero hay una manera aún mejor, y esa es usar CHAIN. Trabaja muy parecido al Multi-SAY. Tu esas = para indicar que el interlocutor actual debe hablar de nuevo, y == (dos signos de igual consecutivos) para indicar que un nuevo interlocutor debe tomar la palabra.

Note como en WeiDU 82, CHAIN ahora puede definir disparadores de situaciones, ejecutar acciones DO, y terminar con un EXIT o COPY_TRANS. Esto significa que para los banters más simples entre NPC/NPC, donde el PJ no tiene oportunidad de hablar, no nececitas usar nada más.

Observa y comprende como este diálogo trabaja usando un CHAIN.
CHAIN
  IF ~Global("KelseyImoenPizza","LOCALS",0)
      InParty("Imoen2")
      See("Imoen2")
      !StateCheck("Imoen2",STATE_SLEEPING)~ THEN BJKLSY pizzachain
  ~Imoen, ¿Qué te gusta en tu pizza?~
DO ~SetGlobal("KelseyImoenPizza","LOCALS",1)~
  == IMOEN2J
  ~Oregano.~
  =
  ~Oh, y quizás con un poco de albahaca mezclada.~
  == BJKLSY
  ~Bueno, si, ¿pero algo más?~
  == IMOEN2J
  ~La salsa es buena.~
  == BJKLSY
  ~(risas) No estás siendo muy útil, Imoen.~
  == IMOEN2J
  ~Mendrugo. Me gusta el mendrugo en mi pizza. Mendrugo cocido es mejor.~
  == BJKLSY
  ~¿Quieres que te haga esa pizza o no?~
  =
  ~Fue TU idea.~
  == IMOEN2J
  ~No puedo decidir. No importa, sólo tengo yogurt.~
  == BJKLSY
  ~(suspiro)~
EXIT 
Note como trabaja este diálogo.

Usamos la declaración CHAIN para definir el gatillo de la situación (las condiciones de comienzo que deben ser verdaderas) y asignarlas a BJKLSY.DLG. La etiqueta "pizzachain" es más que nada para tener una referencia interna. Kelsey dice la primera línea, luego usamos == IMOEN2J para permitirle responder, "Oregano." Luego, podemos usar el = simple para indicar que el interlocutor actual (Imoen) tiene dos líneas consecutivas.

Luego es el turno de hablar de Kelsey, entonces usamos == BJKLSY para decirle a WeiDU que cambien a el otro interlocutor (el cual es Kelsey, desde que le especificamos BJKLSY. Su banter viaja de acá para allá por un rato, y luego cuando es el turno de las líneas de Kelsey, luego de ¿Quieres que te haga esa pizza o no? y Fue TU idea., separamos con un = simple para indicar que el interlocutor actual (Kelsey) tiene dos líneas consecutivas.

Luego del final de Kelsey, el suspiro exasperado, usamos el comando EXIT para terminar el CHAIN, y salir del diálogo.

Y eso es todo lo que necesitas saber para usar CHAIN. Te ahorra tremendas cantidades de tiempo que perderías usando bloques de APPEND individuales o aún bloques de Multi-SAY, para cada NPC.

CHAIN avanzado:

Puedes incluir acciones DO y condiciones dentro del chainText (texto de chain), como en:
CHAIN
  IF ~Global("KelseyImoenPizza","LOCALS",0)
      InParty("Imoen2")
      See("Imoen2")
      !StateCheck("Imoen2",STATE_SLEEPING)~ THEN BJKLSY pizzachain
  ~Imoen, ¿Qué te gusta en tu pizza?~
DO ~SetGlobal("KelseyImoenPizza","LOCALS",1)~
  == IMOEN2J
    ~Oregano.~
    =
    ~Oh, y tal vez con un poco de albahaca mezclada.~

  == BJKLSY
    ~Bueno, si, ¿pero algo más?~

  == IMOEN2J
    ~La salsa es buena.~

    == BJKLSY   IF ~PartyHasItem("pepperoni")~ THEN
      ~Mir, TENEMOS peperoni. ¿Por qué no usar sólo esto? Lo comeré de cualquier modo.
      Si a ti no te gusta, tengo yogurt en su lugar.~

    == IMOEN2J  IF ~!PartyHasItem("pepperoni")~ THEN
      ~Mendrugo. Me gusta el mendrugo en mi pizza. Mendrugo cocido es mejor.~
    == BJKLSY IF ~!PartyHasItem("pepperoni")~ THEN
      ~¿Quieres que te haga esa pizza o no?~
      =
      ~Fue TU idea.~

    == IMOEN2J  IF ~!PartyHasItem("pepperoni")~ THEN
      ~No puedo decidir. No importa, sólo tengo yogurt.~
    == BJKLSY IF ~!PartyHasItem("pepperoni")~ THEN
      ~(suspiro)~
EXIT
En este caso, el diálogo cambia si el grupo tiene el objetor "peperonni". Si es así, Kelsey dice el TENEMOS peperoni, luego (suspiro) y luego el diálogo finaliza. Si no, el diálogo trabaja como antes. Las líneas del chainText con IFs en ellas sólo están comproband si sus condiciones son verdaderas.

7.3 COPY_TRANS

Este tutorial fue amablemente aportado por Jason Compton.

Hay algunos diálogos con ramificaciones complejas en el Engine Infinity que tu, como creador de mods, debes querer agregar. Considera el Baldur's Gate 2 y el diálogo de "La llegada al Infierno". Hay un breve diálogo interno en el que el protagonista acepta que en realidad él/ella está ahora en el Infierno, y entonces todos los compañeros hechos por Bioware tienen oportunidad de hablar. (PLAYER1.DLG situación 25. Ayudará al resto de la explicación su tu usas WeiDU para descompilar PLAYER1.DLG en PLAYER1.D, y/o abrir PLAYER1.DLG en el Near Infinity y mirar la situación 25.)

Luego de que la voz interna del PJ dice Dudas de que estén contentos con su actual situación, cuando tú ni siquiera sabes por qué estás aquí, todos los NPCs de Bioware tienen la oportunidad de hablar. Si estás crando un nuevo NPC y esperas que esté completo, rebosante de la calidad de Bioware, debes querer permitirle a tu personaje hablar aquí igualmente. Para eso, un simple EXTEND_BOTTOM hará el trabajo.

Aquí hay un ejemplo de como Weimer hizo esto con Solaufein:
EXTEND_BOTTOM PLAYER1 25
  IF ~IsValidForPartyDialogue("Sola")
      Global("SolaWelcomeHell","GLOBAL",0)~ THEN
    DO ~SetGlobal("SolaWelcomeHell","GLOBAL",1)~ EXTERN SOLA inHell1
END
Esto coloca una nueva transición al final de PLAYER1 25 que dice al juego que se bifurque a la observación de Soulafein acerca de tu ingreso en el Infierno, si él está presente (IsValid) y si no hemos visto su comentario antes (el chequeo por SolaWelcomeHell=0, luego fijándose a 1. Esto asegura que este curso pueda suceder sólo una vez, lo cual es importante por una razón que explicaré más tarde.) SOLA inHell1, el cual definiremos más tarde, contiene el comentario de Solaufein.

Una vez que Solaufein hace su comentario, sería muy juicioso que permitamos a los otros NPCs de Bioware tener la palabra igualmente, como Bioware proyectó y como los jugadores experimentados de afuera esperan. Podrías simplemente usar el PLAYER1.D descompilado y copiar y pegar la lista de transición. Pero hay algunas buenas razones para no hacer eso. En un grado trivial, eso es un gran derroche de espacio en tu archivo D.

La razón más importante es esta: Si otro mod de NPC viene y deja su propio EXTEND_BOTTOM, no tendrías manera de saber esto. Colocando el paquete de Bioware en la lista de transición, darías por hecho que solo tu mod de NPC tiene su diálogo. El resto serían silenciosos. Entonces si tu fueras el creador de Solaufein, y Solaufein fuera instalado luego de Kelsey y Tashia en un juego, Keslsey y Tashia serían salteados, porque tu solo copiaste la lista de traducción de Bioware. Eso es una gran responsabilidad.

Por eso es que existe COPY_TRANS. COPY_TRANS atrae la lista de trnsición entera de una situación específica y hace la lista de transición para tu nueva situación.

Para ilustrar, mira SOLA inHell1 :
APPEND SOLA
  IF ~~ THEN BEGIN inHell1
    SAY @2 = @3         // usar las cadenas @2 y @3 del archivo de traducción
    COPY_TRANS PLAYER1 25
  END
END 
En vez de copiar y pegar esa gigantesca lista de transiciones IF "" THEN EXTERN del PLAYER1.D, permitimos a WeiDU hacerlo por nosotros. COPY_TRANS PLAYER1 25 dice a WeiDu que agare la lista actual de transiciones de PLAYER1 situación 25, y la usa con la lista de transición de SOLA inHell1. Esto asegura que Solaufein dejará expandir la actividad correctamente a Imoen, Aerie, Minsc, y el resto de la pandilla, Así como también agarra las transiciones que pueden haver sido añadidas por otros NPCs como Kelsey, Valen o Tashia.

COPY_TRANS puede formar toda tu nueva lista de transicion de las situaciones, o sólo una parte de ellas. Esto sería válido, por ejemplo:
IF ~~ THEN BEGIN commentary
  SAY ~Hey, I think I might like to run the transition list from TOLGER
    75... or I might want to do something else, if I'm in chapter six!~
  COPY_TRANS TOLGER 75
  IF ~Global("Chapter","GLOBAL",6)~ THEN GOTO chapter6commentary
END
Esto haría a la transición GOTO commentary2 aparecer al fondo de la memoria de transición (debajo de la lista copiada para TOLGER 75). Recuerda que los gatillos de transición se leen de abajo hacia arriba, asi que esta sería la primera transición evaluada. Si quieres que sea evaluada luego de la lista de transiciones en el COPY_TRANS, colócalo arriba. Nótese, sin embargo, que Bioware usualmente estructura sus listas de transición de modo que el gatillo más alto siempre será verdadero (en realidad, a veces es "True()") asi que es algo improbable que tu nunca quieras colocar un nuevo gatillo de transición encima del COPY_TRANS.

Ahora, esa explicación de por que el chequeo de la variable SolaWelcomeHell es importante: si un usuario instala el mismo mod más de una vez, y éste usa COPY_TRANS, la lista otra vez incluirá nuestro nueva gatillo:
IF ~IsValidForPartyDialogue("Sola")
      Global("SolaWelcomeHell","GLOBAL",0)~ THEN
    DO ~SetGlobal("SolaWelcomeHell","GLOBAL",1)~ EXTERN SOLA inHell1
Si no había memoria siendo fijada para asegurarse de que la transición puede correr sólo una vez, el usuario conseguiría meterse en un círculo. Esto puede y ha pasado ya con algunos mods. El resultado final sería Solaufein o Kelsey o cualquiera que ofrece constantemente su comentario, una y otra vez.

Nota importante: El compilador D de WeiDU ejecuta COPY_TRANS antes que otras acciones que puedes usar para afectar una lista de transiciones dentro del mismo archivo D (como EXTEND_TOP y EXTEND_BOTTOM). Eso es una ventaja.

7.4 INTERJECT
Este tutorial fue amablemente aportado por Jason Compton.

Interjecciones , los pequeños comentarios que hacen los miembros del grupo, una gran manera para darle gusto a un nuevo NPC o una nueva misión que hayas creado. Esto muestra que lo personajes están prestando atención a su mundo de juego, y que tienen una opinión acerca de lo que sucede a su alrededor.

A través de las interjecciones, un NPC puede aconsejar un curso de acción, quejarse acerca de una desición, forzar tu mano... cosas entretenidas.

La forma tradicional para hacer una interjección es encontrar una situación de un diálogo donde otro NPC podría comentar, y usar EXTEND_BOTTOM y APPEND en conunción.

Aquí hay une ejemplo:
EXTEND_BOTTOM SAHPR4 7
     IF ~IsValidForPartyDialog("J#Kelsey")~ THEN EXTERN J#KLSYJ KelseySAHPR4
END

APPEND J#KLSYJ
  IF ~~ THEN BEGIN KelseySAHPR4
    SAY ~Urk. ¿Quién fue el afortunado donador?~
    IF ~~ THEN EXTERN SAHPR2 10
  END
END
Esto funciona, pero es también más trabajo del que se necesita hacer desde la introducción de INTERJECT. (Dicho sea de paso, para los "historiadores" de WeiDU, hay dos motivos principales por los cuales las funciones avanzadas has sido añadidas a WeiDU desde las primeras versiones de Solaufein y el comando CHAIN original: Weimer los necesitaba para sus propios objetivos en la creación de mods, o un proyecto, usualmente Kelsey, lo necesitaba. INTERJECT aconteción cuando Westley finalmente decidió que Solaufein y Valen debían comentar acerca de las gestas. Por otro lado, COPY_TRANS y INTERJECT_COPY_TRANS fueron idea mia.)

INTERJECT simplifica este proceso considerablemente. Para correr un INTERJECT, necesitas saber la situación original (la línea luego de la cual quieres una o más interjecciones de los NPCs), y la situación de destino (donde quieres que el diálogo vaya luego de la interjección.) Generalmente, pero no necesariamente, la situación de destino sería dondequiera que el diálogo originalmente planeara dirigirse, pero si el NPC cambia la conversación en una nueva dirección, esa puede cambiar. Mostraremos los casos más simples para ilustrar.

INTERJECT es una forma especializada de CHAIN. Entonces si estás familiarizado con CHAIN, esto te resultará familiar también.

Considera las driadas en el calabozo de Irenicus. Tal vez Minsc debería decir algo también. IDRYAD1.DLG situación 1 ofrece una buena oportunidad.
IF ~~ THEN BEGIN 1 // from:
  SAY #11080 /* ~Estamos en sus manos.~ */
  IF ~~ THEN EXTERN ~IDRYAD2~ 1
END
Minsc está indignado. Aquí es cuando el puede expresarlo. La idea es que queremos agregar el comentario de Minsc, pero el diálogo deve continuar justo como lo haría si Minsc no hubiera comentado nada.
INTERJECT IDRYAD1 1 MinscDryad
  == MINSCJ IF ~IsValidForPartyDialog("Minsc")~ THEN 
    ~¡Bubú está indignado de que ese mago extraño posea a estas adorables damas!
    ¿Pueden Minsc y Bubú ayudarlas, bellas señoritas?~
END IDRYAD2 1
Aquí está lo que sucede.

Llamar a INTERJECT requiere tres argumentos: el nombre del diálogo y la situación dode vamos a interrumpir, mas un nombre único de variable global. Esta variable será fijada de 0 a 1 luego del INTERJECT, para asegurarse de que esto sólo puede pasar una vez. (Esto es importante en caso de que los jugadores accidentalmente instalen tu mod dos veces, podría crear un problema en círvulos similar al descripto en el tutorial de COPY_TRANS.)

Entonces, INTERJECT IDRYAD1 1 MinscDryad dice a WeiDU "Mete este diálogo luego de la situación 1 de IDRYAD1. Este diálogo se ejecutará si MinscDryad es 0. Luego de ejecutarse, fijaremos MinscDryad a 1."

Luego necesitamos definir quien está hablando. == (que son dos signos de igual consecutivos) es una notación al estilo CHAIN para un nuevo interlocutor, y MINSCJ es el diálogo correcto para usar para el comentario de Minsc "joined-party". Si Minsc está en el grupo y disponible para el diálogo, dirá su línea. Luego de eso, nos transicionamos a la situación 1 de IDRYAD2 (END IDRYAD2 1), lo cual es a donde el diálogo estaba destinado en primer lugar. Podemos hacer esto más complicado y permitir a la driada responder su interrupción antes de proseguir.
INTERJECT IDRYAD1 1 MinscDryad
  == MINSCJ     IF ~IsValidForPartyDialog("Minsc")~ THEN 
    ~¡Bubú está indignado de que ese mago extraño posea a estas adorables damas!
    ¿Pueden Minsc y Bubú ayudarlas, bellas señoritas?~
  == IDRYAD1    IF ~IsValidForPartyDialog("Minsc")~ THEN 
    ~Mortal grande, estamos teniendo una escena dramática. Por favor
    no interrumpas.~
END IDRYAD2 1
Nótese que repetimos el chequeo
IF ~IsValidForPartyDialog("Minsc")~ THEN
en IDRYAD1. Esto es para asegurarse de que ella solo dice esa línea si Minsc está allí, y por añadidura hace este pequeño comentario. Así ahora, Minsc interrumpe, la driada #1 lo regaña, y luego proseguimos con la línea de la segunda driada.

Un consejo: Aunque no es necesario coger una situación que tenga solo una trancisión a otra situación, a menos que estés deseoso de experimentar (o estés intentando intencionalmente quitar las opciones del jugador para la ecuación, haciendo que el NPC diga algo que fuerze a la acción inmediata, por ejemplo), no uses INTERJECT dentro de una situación en la cual haya opciones para el jugador (REPLYs).

7.5 INTERJECT_COPY_TRANS
Este tutorial fue amablemente aportado por Jason Compton.

INTERJECT es bueno para crear interjecciones en donde no existe ya ninguna. Sin embargo, muchas de las oportunidades realmente buenas para las interjecciones en los diálogos del juego ya tienen interjecciones en ellos. Si usas el INTERJECT estándar, las chances son que pases por arriba de ellas.

Considera TOLGER.DLG situación 75. Luego de que Tolgerias dice Éste es un asunto muy delicado, y no puedo contarle todo a cualquier curioso. Necesito que te comprometas a aceptar la tarea. cuatro NPCs (Edwin, Jaheira, Yoshimo, Korgan) dirán lo que ellos piensan de esa distribución corrupta. Lo que es más, Bioware estructuró las transiciones del diálogo para que los cuatro puedan introducir su comentario, si están todos en el grupo.

Sin embargo, usando un INTERJECT estándar para una nueva línea de un NPS se saltearía esos cuatro comentarios, lo cual es más bien desconsiderado. INTERJECT_COPY_TRANS funciona parecido al INTERJECT normal, pero en vez de definir una situación, una transición y luego END, WeiDU usará COPY_TRANS con la lista de transición para la situación en la cual estás usando INTERJECT.

Esto no es tan confuso como suena. Mira como el nuevo NPC hipotético Aqualung responde a los términos de Tolgerias:
INTERJECT_COPY_TRANS TOLGER 75 AquaTolger
  == AQUALUNJ   IF ~IsValidForPartyDialogue("Aqualung")~ THEN 
    ~Hey, ¡Esa es una oferta realmente miserable! ¿A donde fueron esas pequeñas chicas?
    Podría estar sentado en un banco en el parque, ¡no necesito esta molestia! De todos
    modos, ¿Quién eres tu?~
  == TOLGER     IF ~IsValidForPartyDialogue("Aqualung")~ THEN 
    ~No eres más que un viejo cabrón, lo que ves soy solo yo. Ahora ¿Alguien más
    tiene un agudo comentario que le gustaría hacer?~
END
Entonces, si Aqualung está cerca, él oirá el comentario, dirá lo suyo y luego Tolgerias le responderá. Luego de eso, el juego buscará la presencia de Edwin, Jaheira, Yoshimo y Korgan y tendermos sus respuestas a Tolgerias igualmente.

Sugerencia: INTERJECT_COPY_TRANS es bueno para usar aún cuando no hay otras interjecciones en la situación, ejemplo, si hay solo un sumple IF "" THEN GOTO bla. Esto es, tan largo como planees proceder con el destino orignial. Te ahorra el problema de tener que buscar y poner el destino.

7.6 WEIGHTs de las situaciones

stateTriggerStrings, las condiciones que determinan que situación debe ser usada para el comienzo de un diálogo, pueden tener WEIGHTs. Estos WEIGHTs son usados por el Engine Infinity para elegir cuál situación elegir si múltiples gatillos de situación son evaluados como "verdaderos". [ En realidad, los WEIGHTs son solamente los desbalances dentro de la tabla de los gatillos de la situación en el archivo DLG, pero este detalle no es importante a menos que estés escribiendo tu propia herramienta. ] WEIGHTs solo tienen sentido para los stateTriggerStrings que no están vacíos.

Si múltiples stateTriggerStrings son evaluados como verdaderos, el Engine Infinity escogerá la situación con el WEIGHT más bajo. Usualmente el weighting (carga) sigue el orden de la declaración de la situación en el archivo D. Es decir, la primera situación mencionada tiene la carga más liviana (P.Ej, será escogido el primero en caso de un empate) y la última situación mencionada tiene la mayor carga (P.Ej, será escogido a lo último en caso de un empate). Sin embargo, puedes incluir una directiva WEIGHT explícita para cambiar las cosas, por ejemplo, considera este archivo D:
BEGIN foozle
  IF ~True()~ THEN BEGIN a SAY ~Jason~ END
  IF ~True()~ THEN BEGIN b SAY ~yada~ END
  IF ~True()~ THEN BEGIN c SAY ~Compton~ END
  IF ~True()~ THEN BEGIN d SAY ~kelsey~ END
Si tu hablas con foozle, este dirá siempre Jason. Sin embargo, puedes alterar esplícitamente las cargas de manera que la tercer situación es escogida primero, como en:
BEGIN foozle
  IF WEIGHT #10 ~True()~ THEN BEGIN a SAY ~Jason~ END
  IF            ~True()~ THEN BEGIN b SAY ~yada~ END
  IF WEIGHT #2  ~True()~ THEN BEGIN c SAY ~Compton~ END
  IF            ~True()~ THEN BEGIN d SAY ~kelsey~ END
Con este archivo D, foozle dirá siempre Compton. Todas las situaciones con directivas WEIGHT vienen antes que todas las situaciones sin ellas. Las situaciones sin directivas WEIGHT son clasificadas en orden de aparición. Asi que el orden de las situaciones para foozle.DLG es c-a-b-d. Si, esto es complicado.

Consejo Muy Recomendado: No use las directivas WEIGHT en sus archivos D hechos a mano. Solo use el orden implícito.

Las directivas WEIGHT fueron introducidas para facilitar el manejo de los archivos DLG creados por Bioware (P.Ej., BJAHEIR.DLG) que incluyen cargas engañosas. Solo a las situaciones con gatillos no-vacíos le son dadas cargas implícitas. Si creas un archivo D desde un DLG que presenta cargas complicadas, WeiDU emitirá comentarios como este:
IF WEIGHT #8 /* Triggers after states #: 11 12 24 25 26 36 58 even though
                they appear after this state */
  ~True()~ THEN BEGIN 10 // from:
    SAY #52190 /* ~Please do not interrupt our thoughts. We must prepare
      carefully if we are to see a weakness in the illithid web. ~ */
    IF ~~ THEN EXIT
END
para recordarte que el orden no es lo que tu piensas o lo que parece ser.

A todos los gatillos de las situaciones en los archivos DLG le son dadas cargas contando desde 0 hasta el número máximo de gatillos de situación en el archivo DLG. Puedes usar cualquier número que quieras (aún uno negativo): WeiDU simplemente lo clasificará. ADD_STATE_TRIGGER no cambia la carga asociada con ese gatillo. APPEND puede ser usado para dar una carga no-trivial a una situación, como en:
APPEND BJAHEIR
  IF WEIGHT #-999 ~MyCondition()~ THEN BEGIN mystate SAY ~My Stuff~ END 
END
Dado que BJAHEIR tiene implícitos WEIGHTs en el rango de #0 a aproximadamente #50, esto causa que mystate (con un valor de -999) tenga prioridad sobre todas las situaciones que ya existen en BJAHEIR. Sin tal acción drástica, las situaciones APPENDed (anexadas) tendrán que usar el orden implícito, y tendrán de esa manera la prioridad más baja (porque aparecen al final del archivo). Multisay y CHAIN también anexan situaciones, pero como ellos anexan situaciones con stateTriggerStrings vacíos, los WEIGHTs no son relevantes.

Considera el siguiente ejemplo:
BEGIN foozle
  IF WEIGHT #10 ~True()~ THEN BEGIN a SAY ~Jason~ END
  IF            ~~ THEN BEGIN b SAY ~yada~ END
  IF WEIGHT #2  ~True()~ THEN BEGIN c SAY ~Compton~ END
  IF            ~True()~ THEN BEGIN d SAY ~kelsey~ END
  ADD_STATE_TRIGGER foozle 1 /* state b */ ~MyCondition()~
El diálogo foozle resulante aún tendrá el orden de carga c-a-b-d.

Aquí hay otro ejemplo:
BEGIN foozle
  IF            ~True()~ THEN BEGIN a SAY ~Jason~ END
  IF            ~~ THEN BEGIN b SAY ~yada~ END
  IF            ~True()~ THEN BEGIN c SAY ~Compton~ END
  IF            ~True()~ THEN BEGIN d SAY ~kelsey~ END
  ADD_STATE_TRIGGER foozle 1 /* state b */ ~MyCondition()~
El diálogo foozle resultante tendrá el orden a-b-c-d esperado.

Sin embargo, considera este nocivo ejemplo:
  //////
  // foozle.DLG contents, assume it has already been created and is 
  // sitting on your hard drive somewhere
  // IF            ~True()~ THEN BEGIN a SAY ~Jason~ END
  // IF            ~~ THEN BEGIN b SAY ~yada~ END
  // IF            ~True()~ THEN BEGIN c SAY ~Compton~ END
  // IF            ~True()~ THEN BEGIN d SAY ~kelsey~ END
  //////

  // new D file
  ADD_STATE_TRIGGER foozle 1 /* state b */ ~MyCondition()~
Esto actualizará foozle y el oden resultante será a-c-d-b (porque cuando foozle.DLG fue cargado por el disco, a a c y d le fueron dadas cargas, pero a b no (porque tenía un gatillo vacío)). De ese modo, debes evitar usar ADD_STATE_TRIGGER en situaciones con gatillos vacíos a menos que sepas lo que estás haciendo.

7.7 Archivos de traducción TRA

Si estás escribiendo un mod y te gustaría hacerlo más fácil para traducir a otro idioma, puedes usar los "archivos de traducción" (así el BGII mismo usa el DIALOG.TLK) para separar la estructura y el contenido de tu diálogo. Un archivo de traducción basicamente enlista las cadenas de textos en orden. Por ejemplo,

C:\Program Files\Black Isle\BGII - SoA\> WeiDU --trans SCSARLES.DLG


Esto crea scsarles.D y scsarles.tra. scsarles.D ahora contiene:
IF ~NumTimesTalkedTo(0)~ THEN BEGIN 0 // from:
  SAY @1 /* ~¿Quién es? ¿Se puede saber por qué me has interrumpido mientras meditaba?
    A mi musa creativa hay que despertarla dulcemente
    y tu estruendo no es nada apropiado.~ [SARLES02] #28655 */
  IF ~~ THEN REPLY @2 
    /* ~Perdón. Te dejaré con tus pensamientos.~ #28656 */ GOTO 1
  IF ~~ THEN REPLY @3 /* ~Lo siento, pero he venido en busca de tu talento para un encargo artístico.~ #28657 */ 
    DO ~SetGlobal("TalkedToSarles","GLOBAL",1)~ GOTO 2
END 
Nótese que todas las cadenas han sido reemplazadas por un @número y los textos han sido puestos en comentarios.

El archivo de traducción scsarles.tra contiene todas esas cadenas:
// SCSARLES translation file
@1   = ~¿Quién es? ¿Se puede saber por qué me has interrumpido mientras meditaba? 
A mi musa creativa hay que despertarla dulcemente 
y tu estruendo no es nada apropiado.~ [SARLES02]
@2   = ~Perdón. Te dejaré con tus pensamientos.~
@3   = ~Lo siento, pero he venido en busca de tu talento para un encargo artístico.~ 
Luego puedes pedir a alguien que hable en otra lengua que escriba un nuevo archivo de traducción traduciendo todas las líneas en scsarles.tra. Esto impide que el texto de las cadenas se vaya y a la estructura la saca para sincronizar y simplificar la traducción; los jugadores no-técnicos pueden traducir los archivos de texto al crudo fácilmente.

Cuando estés compilando un archivo D que contiene referencias de traducción @number debes proveer (al menos) un archivo de traducción. Por ejemplo, you might say:

C:\Program Files\Black Isle\BGII - SoA\> WeiDU SCSARLES.D italian.tra


Puedes especificar múltiples archivos de traducción. El último que define una cadena gana. Esto es útil si un lenguaje es más moderno que los otros. En este ejemplo:

C:\Program Files\Black Isle\BGII - SoA\> WeiDU SCSARLES.D english.tra italian.tra


Las cadenas serán tomadas de la traducción italiana siempre que sea posible, pero si no están disponibles se volverá a la versión inglesa.

Puedes usar WeiDU para chequear y estar seguro de que las traducciones están actualizadas. WeiDU automáticamente generará un archivo de texto enlistando todas las cadenas que están presentes en una traducción, o archivo TRA (usualmente la original) y que no están presentes en otro. Luego puedes enviar este archivo a tus traductores así ellos saben que hacer. Este comando de ejemplo compara todoslos archivos TRA en los directorios american y french y crea un archivo llamado MISSING.

C:\Program Files\Black Isle\BGII - SoA\> weidu --tcmp-from american --tcmp-to french --textout MISSING


7.8 Convirtiendo un D ``hard-coded´´ en una pareja D/TRA

Este tutorial fue amablemente aportado por Jason Compton.

Los archivos D y TP2 permiten al programador escribir el texto de cualquier forma literalmente:
// Greeting.d
SAY ~Hello.~
o en compañía de un archivo TRA (de traducción) que soporta múltiples lenguajes:
// Greeting.d
SAY @1

// Greeting.tra
@1 = ~Hello.~
La idea es que alguien pueda hacer una versión francesa de Greeting.tra la cual contiene
// French-Greeting.tra
@1 = ~Bonjour.~
Sin embargo, algunos usuarios de WeiDU, por razones de conveniencia o simplemente nunca anticiparon la oportunidad de traducir, pueden haber elegido originalmente el método "hard-coded" pero ahora lamentan esa desición. --traify dejará todo el texto de las entradas de SAY, REPLY, y JOURNAL en formato listo para la traducción. --traify puede también ser usado en los archivos TP2.

Para cambiar el archivo D hard-coded FWKI.d en un nuevo combo D/TRA, usa --traify y --dout para especificar los nombres de archivo de entrada y de salida, respectivamente:

C:\Program Files\Black Isle\BGII - SoA\> weidu --traify fwki.d --dout fwki-new.d


Luego de una pequeña pausa, fwki-new.d y fwki-new.tra serán creados.

El proceso --traify convierte fwki.d
APPEND J#KLSYJ
  IF ~~ THEN BEGIN KelseySAHPR4
    SAY ~Urk. ¿Quién fue el afortunado donador?~
    IF ~~ THEN EXTERN SAHPR2 10
  END
END 
en fwki-new.d
APPEND J#KLSYJ
  IF ~~ THEN BEGIN KelseySAHPR4
    SAY @0
    IF ~~ THEN EXTERN SAHPR2 10
  END
END 
y en el recientemente creado fwki-new.tra, encontrarás
@0    = ~Urk. ¿Quién fue el afortunado donador?~
y este archivo de diálogo está ahora listo para la traducción.

--traify trabaja desde la cima hasta el fondo del archivo D, comenzando desde @0. NO salteará ninguna referencia de traducción @x existente que encuentre, así qus si tu archivo D no contiene cualquier soporte de traducción en lo absoluto, es mejor usar --traify# igualmente.

Porque el --traify estándar comienza por @0 y es ignorante de cualquier entrada @x ya existente en el archivo D, si has comenzado a convertir un D en un par D/TRA a mano, puedes tener entradas @x que choquen con los resultados de --traify.

En otras palabras, si tu ya tienes una situación que dice
IF ~~ THEN BEGIN blah
  SAY @0
  IF ~~ THEN EXIT
END
--traify no salteará @0 automáticamente, tendrás dos lugares donde @0 es usado pero tu intentas usar dos cadenas diferentes, y esto será malo.

Para evitar ese problema, añade el argumento --traify# para especificar el número de comienzo (mayor que 0) para nuevas entradas @x.

C:\Program Files\Black Isle\BGII - SoA\> weidu --traify fwki.d --traify# 1000 --dout fwki-1000.d


creará nuevas referencias @x en fwki-1000.tra que comienzan desde @1000, en vez de @0. --traify# también puede ser usado en los archivos TP2.

7.9 REPLACE_ACTION_TEXT
Este tutorial fue amablemente aportado por Japheth.

REPLACE_ACTION_TEXT puede ser usado con expresiones regulares (regexp). Así, algunas acciones como CreateCreature("blah",[0.0],1) no serán asociadas con WeiDU porque cuando dices [0.0], WeiDU está buscando por un grupo de carácteres.

Aquí hay un diálogo que estoy arreglando y como hacer para corregirlo.

Arghai.dlg tiene este gatillo de acción antes de que REPLACE_ACTION_TEXT lo haga.
CreateCreature("OGREHA",[1351.1078])}
No hay un punto dado, lo cual hace a WeiDU y NI enojar. Para corregir esto usando REPLACE_ACTION_TEXT esto es lo que tienes que hacer:
REPLACE_ACTION_TEXT arghai
~CreateCreature("OGREHA",\[1351.1078\])~
~CreateCreature("OGREHA",[1351.1078],0)~
Así, todo lo que tienes es recordar hacer ese corchete con una barra invertida así WeiDU no lo confunde con una expresión regular.

8 Ensamblaje de módulos: Archivos TP2

En algún momento tu terminarás tu mod (una colección de archivos CRE, ITM, D, etc.) y querrás ensamblarlo a fin de que otros usuarios puedan instalarlo (y luego quizás desinstalarlo más tarde) fácilmente. WeiDU puede hacer esta tarea por ti (y tu puedes distribuir libremente WeiDU.exe con tu módulo).

Un TP2 describe como instalar los componentes de tu módulo. WeiDU leerá el archivo, preguntará al usuario, y luego realizará la instalación. La desinstalación y actualización son también manejadas.

Mira el archivo examples/mymod.tp2 por un ejemplo de como trabaja todo esto.

Aquí están los comandos, el síntaxis y gramática de los archivos TP2:
Archivo TP2   Un archivo TP2 es un archivo de texto que contiene un número de Componentes del mod. Los archivos TP2 le dicen a WeiDU cómo instalar varias partes de tu mod en la computadora del usuario final.
Es BACKUP directoryName AUTHOR emailAddress [ AUTO_TRA path ] Lenguaje lista [ ALLOW_MISSING archivo lista ] [ ASK_EVERY_COMPONENT ] Componente lista Un Archivo TP2 es básicamente un preludio y luego una lista de Componentes. La declaración BACKUP dice a WeiDU donde colocar las versiones respaldadas (backupeadas) de los archivos que serían sobreescritos de tal modo que puedan ser desinstalados más tarde. La directiva AUTHOR da una dirección de correo electrónico para los usuarios para enviar reportes bugs allí si hay algún problema durante la instalación. La directiva opcional AUTO_TRA es usada con el COMPILE Acción TP2. Los Lenguajes son los varios lenguajes en los cuales tu mod está disponible. La directiva ALLOW_MISSING te permite especificar archivos que pueden ser perdidos (cuando intentas copiarlos o referirte a ellos para los archivos D). Versiones vacías de esos archivos serán creados en demanda. ASK_EVERY_COMPONENT significa que el usuario nunca le serán dadas las elecciones para manejar todos los componentes de una vez. Finalmente, los Componentes son la estructura actual de tu mod. Diferentes Componentes pueden ser instalados o desinstalados por separado, pero todas las partes sin un Component son tratadas como una unidad.
 
Lenguaje   Una declaración Lenguaje le dice a WeiDU donde encontrar los archivos TRA.
Es LANGUAGE languageName languageDirectory defaultLanguageTRA list El languageName es el nombre del lenguajetal como es presentado a el usuario. "American English" y "Traducción al Español" son ejemplos. El languageDirectory es el nombre del subdirectorio en el cual has almacenado los archivos TRA para ese lenguaje. Los ejemplo incluyen "american" y "spanish". Finalmente, todos los archivos TRA en la lista de defaultLanguageTRA son cargados tan pronto como el usuario seleccione un lenguaje.
 
Componente   Un Componente es un contiguo grupo de archivos y acciones que un usuario puede instalar, desinstalar o actualizar.
Es BEGIN componentName Acción TP2 lista Básicamente, si el componentName es "Foo", al usuario se le preguntará: "Do you want to install Foo?" ("¿Quieres instalar Foo?"). De ser así, todas las Acciones TP2 asociadas son ejecutadas. Si no, son salteadas.
 
Acción TP2   Una Acción TP2 le dice a WeiDU como instalar un componente. Esto usualmente involucra la copia de archivos y escritura en nuevas referencias de cadenas de texto.
Es COPY fromFile toFile ... patch lista when lista Puedes especificar tantos fromFile-toFile (desde archivo - al archivo) como tu quieras. Cada fromFile es copiado en su toFile asociado. Todos los patches son aplicados. Si hay alguna condición when (cuando) y alguna de ellas es falsa, la copia no se lleva a cabo. Un ejemplo típico es COPY "mymod/sword.itm" "override/sword.itm".
o COPY_EXISTING fromFile toFile ... patch lista when lista Se comporta como COPY excepto que los fromFiles son sacados desde los BIFFs del juego o del directorio override. Esto es útil para hacer cambios a los archivos que otros mods puedan haber cambiado igualmente.
o COPY_EXISTING_REGEXP fromFileRegexp toDir ... patch lista when lista Se comporta como COPY_EXISTING excepto que fromFileRegexp puede contener expresiones regulares regexp. Todos los archivos seleccionados en los BIFFs del juego serán copiados al directorio especificado en toDir.
o COMPILE dFile lista [ USING traFile lista ] Primero, esto carga todos los traFiles (archivos TRA) presentados. Si alguno de sus cursos contienen %s, el %s es reemplazado con el languageDirectory de el Lenguaje que el usuario seleccionó. Si tu especificas AUTO_TRA mymod/%s arriba, WeiDU también intentará cargar mymod/languageDirectory/dFile.tra para cada dFile (Archivo D) en la lista. Una vez que todos los archivos TRA son cargados, los archivos D son compilados. Los DLGs que son creados o modificados son puestos en el directorio override.
o MKDIR dirName lista Instruye a WeiDU para crear todos los directorios en la lista.
o APPEND filename newText when lista Si no hay condiciones when o son todas verdaderas, el texto ASCII newText es agregado al archivo ya existente filename (el cual es leído de los BIFFs del juego o del directorio override).
o APPEND_COL filename newText when lista Si no hay condiciones when o son todas verdaderas, la cadena newText es añadida en columa a el archivo existente filename. Si filename era:
A B C
D E F
X Y Z
P Q R
y newText es "0 1 2 3", el resultado sería:
A B C 0
D E F 1
X Y Z 2
P Q R 3
Debes tener el mismo número de espacios en blanco y palabras en newText como hay en las columnas de filename.
o EXTEND_TOP existingBCS newBCS patch lista Carga los existingBCS (BCS existentes), anexa todos los newBCS (nuevos BCSs) en la cima de este, aplica todos los patches, y luego los copia en el directorio override.
o EXTEND_BOTTOM existingBCS newBCS patch lista Como EXTEND_TOP, pero al archivo newBCS es colocado al fondo del archivo existingBCS.
o EXTEND_TOP_REGEXP existingBCSregexp newBCS patch lista Como EXTEND_TOP, pero el archivo newBCS es colocado al fondo de todos los archivos BCS que correspondan a el regexp existingBCSregexp.
o EXTEND_BOTTOM_REGEXP existingBCSregexp newBCS patch lista Ver EXTEND_TOP_REGEXP.
o ACTION_IF Predicate THEN BEGIN Acción TP2 lista END [ ELSE BEGIN TP2 Actoin lista END ] Si Predicate es evaluado como verdadero, las Acciones TP2 en la bifurcación THEN son ejecutadas. De otro modo, si hay presente una bifurcación ELSE, sus comandos son ejecutados. Si no, no pasa nada.
o AT_EXIT commandToRun Cuando quiera que este componente sea instalado, commandToRun es ejecutado por el sistema operativo fundamental. Si tu quieres hacer algo que WeiDU no puede manejar, como convertir MP3 en WAVs, haz una cantidad de archivos y córrelo desde aquí.
o AT_INTERACTIVE_EXIT commandToRun Como AT_EXIT, pero el comando es solo ejecutado si el usuario es específicamente preguntado por el componente a ser instalado o actualizado. El uso más común es: AT_INTERACTIVE_EXIT ~VIEW mymod\README.txt~ Esto causa que tu archivo README sea mostrado usando un lector apropiado.
o AT_UNINSTALL commandToRun Cuandoquiera que este componente sea removido, commandToRun es ejecutado.
o AT_INTERACTIVE_UNINSTALL commandToRun Cuandoquiera que al usuario se le pregunta específicamente por este componente a ser removido, commandToRun es ejecutado.
o ADD_KIT internalKitName manyComplexArguments Este comando te permite añadir nuevos kits al BGII. Mira el archivo de ejemplo mymod.tp2 por información de como hacer esto.
o ADD_MUSIC internalMusicName newMUSFile ¡No hay documentación aún!
o STRING_SET indexOrString newValue Este comando reemplaza la cadena dada en el archivo TLK del usuario con newValue (nuevo valor). No use este comando.
o REQUIRE_FILE filename warningString Si filename no existe, warningString (texto de peligro) es mostrado y este componente no puede ser instalado.
o FORBID_FILE filename warningString Si filename existe, warningString es mostrado y este componente no puede ser instalado.
o FAIL warningString Si esta Acción TP2 es ejecutada, warningString es mostrado y el componente falla la instalación.
o PRINT displayString El texto DisplayString es repetido al usuario. Útil para las depuraciones o reportes de status.
 
patch   Un patch le dice a WeiDU como modificar un archivo.
Es SAY offset string La referencia de cadena asociada con string es escrita en offset. Esto es usado comúnmente para cambiar la descripción o el nombre de un objeto o conjuro.
o REPLACE regexp texto Todas las apariciones de regexp en el archivo son reemplazados con la imprenta ASCII de la cadena de referencia para texto. Así, si regexp es "FRED" y el texto termina con strref #1234, "FRED" será reemplazado por "1234". Esto es utilizado usualmente para reemplazar referencias de cadena en los archivos BCS (donde estás guardados textualmente). Pon un comando como DisplayString(Myself,99999) en tu archivo BCS y usa algo como REPLACE 99999 "Hola, mundo".
o REPLACE_TEXTUALLY string1 string2 Todas las apariciones de string1 (cadena 1) en el archivo son reemplazados por string2. La variable de sustitución (la cual afecta los nombres de los kit y músicas) trabajará sobre string2.
o WRITE_BYTE offset value El valor de o 8-bit byte es escrito en el offset dado.
o WRITE_SHORT offset value El valor corto de 16-bit es escrito en el offset dado.
o WRITE_LONG offset value El valor corto de 32-bit es escrito en el offset dado.
o WRITE_ASCII offset ascString La cadena ASCII ascString es escrita en el archivo de comienzo en offset. La terminación NULL no es escrita, así que si quieres escribir una, tendrás que meterla tu mismo.
o REPLACE_BCS_BLOCK oldFile newFile Si el archivo actual es un BCS, el segmento de él correspondiente a oldFile es reemplazado con los contenidos de newFile.
o INSERT_BYTES offset cuantos El archivo será expandido en el offset dado con cuantos bytes valor de cero.
o DELETE_BYTES offset cuantos El archivo será comprimido cuantos bytes son eliminados al comienzo del offset dado.
 
when   Una cláusula when te da el control sobre el momento en que un COPY, COPY_EXISTING or APPEND_COL sucederá. Si el COPY o COPY_EXISTING contiene múltiples archivos, cada uno es chequeado según las cláusulas de when por separado.
Es IF_SIZE_IS fileSize Verdadero si el archivo dado tiene el tamaño fileSize.
o IF regexp Verdadero si el arcihvo dado contiene regexp.
o UNLESS regexp Falso si el archivo dado contiene regexp.
 
Predicate   Un Predicate te permite poner condiciones a la ejecución de las Acciones TP2 usando un ACTION_IF.
Es FILE_EXISTS filename Verdadero si el archivo existe y tiene un tamaño distinto a cero.
o FILE_SIZE filename fileSize Verdadero si el tamaño del archivo es exactamente igual.
o FILE_CONTAINS filename regexp Verdadero si el archivo contiene la expresión regular.
o Predicate AND Predicate  
o Predicate OR Predicate  
o NOT Predicate  
o ( Predicate )  
 
offset   Un offset es una localización dentro de un archivo.
Es integer Una localización incuestionable. Puedes poner números en formato decimal, hexadecimal, octal o binario. Use 0x para hexadecimal, 0o para octal y 0b para binario.
o NAME1 Nombre general sin identificar ("Hacha de Batalla")
o NAME2 Nombre general identificado ("K'logarath +4")
o UNIDENTIFIED_DESC ("El hacha de mano o hacha arrojadiza es también conocida como hachuela...")
o IDENTIFIED_DESC ("Muchos clanes fueron a la guerra para poseer K'log...")
o BIO Biografía de un NPC
o ... Casi todo en SNDSLOT.IDS o SOUNDOFF.IDS trabaja igualmente.

9 Tutoriales de TP2 de WeiDU

9.1 COPY_EXISTING_REGEXP
Este tutorial fue amablemente proveído por Japheth.

El propósito de COPY_EXISTING and COPY_EXISTING_REGEXP es remendar un archivo para remiendo. Cogerá el archivo fuera de los BIFF, o si existe una versión en el override, lo cogerá del directorio override.

COPY_EXISTING_REGEXP, EXTEND_BOTTOM_REGEXP y EXTEND_TOP_REGEXP pueden ser acciones potencialmente poderosas si necesitas hacer algunos cambios a un grupo específico de archivos, todos de una vez.

Considera este ejemplo para COPY_EXISTING_REGEXP:

En mi mod quiero hacer que todas las espadas de una mano solo hagan D6 daño, en lugar de la variedad de daños que hacen en SOA. Para hacer esto con el COPY_EXISTING "normal", tendría que copiar todas las espadas de una mano como en:
COPY_EXISTING ~sw1h01.itm~ ~override/sw1h01.itm~
              ~sw1h02.itm~ ~override/sw1h02.itm~
              etc...
Esto tomaría un montón de tiempo. Usando COPY_EXISTING_REGEXP yo puedo minimizar el tiempo de escribir más de 70 líneas de código escribiendo sólo 3. Echa un vistazo a esto:
COPY_EXISTING_REGEXP ~sw1h..[^abc].*itm~ ~override~
  WRITE_LONG 0x88 "6"
  WRITE_LONG 0x8a "1" 
Explicaré como funciona el regexp en el ejemplo de arriba: Quiero evitar copiar sobre los archivos sw1h54a.itm, sw1h54b.itm y sw1h54c.itm porque son los tres componentes que disponen el tanto del empate, y por eso, los offsets de 0x88 y 0x8a no funcionarán porque no existen en esos items.

Para encontrar cual offset para WRITE_LONG abrí el Near Infinity, (se encuentra en http://www.idi.ntnu.no/~joh/ni/) y busqué el offset con él. Afortunadamente para nosotros, el offset es el mismo en todos los items, así podemos hacer todos los cambios de una vez. WRITE_LONG 0x88 "6" está diciendo a WeiDU que escriba el valor de 6 en el offset 88 hexadecimal. En forma similar, WRITE_LONG 0x8a "1" dice a WeiDU que escriba el valor 1 en el offset 8a hexadecimal.

El 6 es el tamaño del dado y el 1 es el número de veces que es lanzado.

9.2 EXTEND_TOP_REGEXP
Este tutorial fue amablemente aportado por Japheth.

Tomemos esta situación en la que estuve:

Estoy haciendo un mod de Mercenarios, y a fin de tomar las transiciones de área a área de los NPCs no pertenecientes al gurpo, necesité hacer una combinación de MakeGlobal(), InMyArea(O:Object*) and MoveGlobalObject(O:Object*,O:Target*).

Originalmente coloqué el script que los mueve de área a área en baldur.bcs (este script está funcionando constantemente en el juego), pero por alguna extraña razón, los *.cre no se moverían a las áreas más pequeñas, sólo a las grandes áreas "principales" del juego. (Como los puertos, el Distrito del Templo, los Barrios Bajos, etc.) Así que me figuré, "Huh, supongo que tendré que colocar el script dentro de todos los scripts de área". (Los scripts de área son scripts que son asignados a las áreas, y funcionan mientras tu te encuentras en ella. ¿Bastante evidente, verdad?)

Ahora, escribir el código de este pequeño script con EXTEND_TOP en todos los scripts de área tomaría mucho tiempo. Mejor que hacer eso, humildemente le pedí a Wes para implementar la característica regexp de EXTEND_TOP y EXTEND_BOTTOM, y él me complajo. (Mi penitencia por tal requerimiento es escribir los documentos que estás leyendo ahora.)

Así que ahora con la ayuda de Wes, pude usar EXTEND_TOP para todas las áreas en una simple línea. Si abrieras el NI (Near Infinity) y expandieras el árbol de BCSs verías un conjunto de scripts que comienzan con el prefijo AR. Estos son los scripts de área que he mencionado antes. Ellos van desde AR0014 hasta AR6400. Así que ahora, usando regexp, así es como colocarías el script hasta la cima de todos los scripts de área:
EXTEND_TOP_REGEXP ~ar[0-6].*bcs~ ~pathtoscript/patch.bcs~
Así que aquí lo tenemos, en vez de más de 100 líneas de código, las minimizé en 1 línea. Ahora, si has entendido regexp, probablemente estés diciéndote ``Hey espera, ¿Por qué no solo usas EXTEND_TOP_REGEXP "ar.*bcs" "pathtoscript/patch.bcs" ?'' Bien, en realidad, hice eso primero, pero olvidé contar que hay otros scripts ``normales'' que comienzan con AR. Entonces, tuve que escribir esto a fin de que regexp tuviera el número luego del AR inicial para que WeiDU solamente usara los archivos de script de área.

10 Distribución del Módulo: Setup-MyMod.exe

Si renombras WeiDU.EXE a algo de forma Setup-MyMod.exe, se comportará como si los siguientes argumentos estuvieran presentes: De modo que, para distribuir tu mod, cambia de nombre WeiDU.EXE a Setup-MyMod.EXE (o lo que sea), coloca el archivo Setup-MyMod.TP2 en el mismo directorio y estás listo! Generalmente los mods son distribuidos en archivos ZIP o archivos auto-extraibles que colocan el EXE, TP2 y los datos del módulo en el directorio principal del BGII.

11 Expresiones Regulares

Una expresión regular o regexp es "algo así" como un wildcard de DOS pero no del todo. La gran diferencia es que si tu dijeras * en DOS, dices .* en regexp. Aquí hay una definición:

El síntaxis para las expresiones regulares es el mismo que en Gnu Emacs. The special los caracteres son:
$^.*+?[]'"
Los siguientes términos son reconocidos:
   .      une cualquier caracter eceptuando la nueva línea
   *      (postfijo) iguala a la previa expresión cero, una o muchas veces
   +      (postfijo) iguala la expresión previa una o varias veces
   ?      (postfijo) iguala la expresión previa una vez o ninguna en lo absoluto
   [..]   Grupo de caracteres; los rangos son denotados con -, como en [a-z];
          en ^ inicial, como en [^0-9], complementa el grupo
   ^      Corresponde al principio de la línea
   $      Corresponde al final de la línea
   \|     (exactamente) alterna entre dos expresiones
   \(..\) Agrupando y nombrando la expresión adjunta
   \1     El texto corresponde a el primer expresión \(...\) 
          (\2 para la segunda expresión, etc)
   \b     Corresponde a los límites de las palabras
   \      Cita caracteres especiales. 
   '      Interpreta literalmente los caracteres dentro de ''
   "      Interpreta literalmente los caracteres dentro de ""
Así que spe.* corresponde a "sper01.itm" y "sper.eff" y "special".

Espero que esto sea entendible para la mayoría de la gente. Si estás todavía rascándote tu cabeza intentando entender como funciona esto, hay un buen tutorial en http://www.devshed.com/Server_Side/Administration/RegExp/page1.html.

12 Formatos de Archivo Comunes

Esta sección explica brevemente algunos de los formatos de archivo comunes. La referencia definitiva es http://www.teambg.com/iesdp/.
13 El Código Fuente
El código fuente de WeiDU está disponible bajo GNU General Public License, como detalla en el archivo COPYING. Si por alguna razón no estás habilitado para obtener una copia de GPL, simplemente anuncia el hecho en algún foro público y tu casilla de correo se llenará de copias de él como para toda la vida. Es una gran manera de conocer nueva gente.

Dado que estes es el mundo de Windows, distribuyo un binario pre-compilado. WeiDU está escrito en OCaml, un efectivo lenguaje de programación que incluye administración automática de memoria, funciones de más alta orden y una generación eficiente de código nativo. Si estos términos no significan nada para ti, probablemente no estés habilitado para modificar el código fuente.

Sin embargo, si quieres modificar el código fuente y luego recompilar WeiDU, es muy fácil. Estate seguro de que tienes OCaml 3.06 (o más nuevo), Perl 5.6, hazlo y en cualquiera gcc o (opcional) cl (el Compilador de C de Microsoft).

Edita Makefile y escoge tu configuración. Si no estás en x86/windows/cygwin o x86/linux, tendrás que hacer algo más. Luego solo teclea make clean y luego make. Presto, lo has recompilado.

14 Agradecimientos Especiales
Me gustaría agradecer a las buenas personas del Proyecto Infinity Engine File Format Hacking Project, si el cual esto no hubiera sido posible: http://www.teambg.com/iesdp/.

Además, hice un gran uso del Near Infinity para mods generales del IE: http://www.idi.ntnu.no/~joh/ni/.

El Infinity Engine Editor Pro es muy bueno cambiando ITMs y SPLs. Gracias a todos en BG-dom: http://www.teambg.com/?page=press/news/index.

Gracias especiales a mis encuentra-bugs principales (carraspeo)... es decir beta-testers: Agradecimientos especiales a Greg Henry por haber sido la primera persona en mencionarme WeiDU en una conversación cara a cara. Me quedó muy marcado. Jason Compton es la primera persona que me mencionó WeiDU en una conversación telefónica.

15 Aspectos no documentados

Acutualmente sin documentar:
16 Índice de términos

Índice
  • 2DA, 12

  • ACTION_IF, 8
  • ADD_KIT, 8
  • ADD_MUSIC, 8
  • ADD_STATE_TRIGGER, 4
  • ADD_TRANS_TRIGGER, 4
  • ALLOW_MISSING, 8
  • AND, 8
  • APPEND, 4
  • APPENDI, 4
  • ASK_EVERY_COMPONENT, 8
  • AT_EXIT, 8
  • AT_INTERACTIVE_EXIT, 8
  • AT_INTERACTIVE_UNINSTALL, 8
  • AT_UNINSTALL, 8
  • AUTHOR, 8
  • AUTO_TRA, 8

  • BACKUP, 8
  • BCS, 12
  • BEGIN, 4
  • BIFF, 12

  • CHAIN, 4
  • CHAIN2, 4
  • COMPILE, 8
  • COPY, 8
  • COPY_EXISTING, 8
  • COPY_EXISTING_REGEXP, 8
  • COPY_TRANS, 4
  • Componente, 8
  • chainEpilogue, 4
  • chainText, 4

  • Acción D, 4
  • Archivo D, 4
  • DELETE_BYTES, 8
  • DLG, 3
  • DO, 4

  • EFF, 12
  • EXIT, 4
  • EXTEND_BOTTOM, 4
  • EXTEND_BOTTOM_REGEXP, 8
  • EXTEND_TOP, 4
  • EXTEND_TOP_REGEXP, 8
  • EXTERN, 4

  • FAIL, 8
  • FILE_CONTAINS, 8
  • FILE_EXISTS, 8
  • FILE_SIZE, 8
  • FLAGS, 4
  • FORBID_FILE, 8

  • GOTO, 4

  • IF_SIZE_IS, 8
  • INSERT_BYTES, 8
  • INTERJECT, 4
  • INTERJECT_COPY_TRANS, 4
  • ITM, 12

  • JOURNAL, 4

  • KEY, 12

  • LANGUAGE, 8
  • Lenguaje, 8

  • MKDIR, 8

  • NOT, 8
  • nonPausing, 4

  • OR, 8
  • offset, 8

  • PRINT, 8
  • Predicate, 8
  • patch, 8

  • REPLACE, 4
  • REPLACE_ACTION_TEXT, 4
  • REPLACE_BCS_BLOCK, 8
  • REPLACE_SAY, 4
  • REPLACE_STATE_TRIGGER, 4
  • REPLACE_TEXTUALLY, 8
  • REPLACE_TRIGGER_TEXT, 4
  • REPLY, 4
  • REQUIRE_FILE, 8
  • regexp, 11
  • replyText, 4

  • SET_WEIGHT, 4
  • SOLVED_JOURNAL, 4
  • SPL, 12
  • STRING_SET, 8
  • sayText, 4
  • situación, 4
  • stateActionString, 4
  • stateLabel, 4
  • stateNumber, 4
  • stateTriggerString, 4

  • TLK, 12
  • TP2, 8
  • TP2 Action, 8
  • TP2 File, 8
  • TRA, 7.7
  • texto, 4
  • transFeature, 4
  • transition, 4
  • transNext, 4
  • transTriggerString, 4

  • UNLESS, 8
  • UNSOLVED_JOURNAL, 4
  • USING, 8

  • WEIGHT, 4
  • WRITE_ASCII, 8
  • WRITE_BYTE, 8
  • WRITE_LONG, 8
  • WRITE_SHORT, 8
  • when, 8

17 Cambios
Version 12:
        * El amanecer de la historia recordada.
        * Arreglado un problema con el algoritmo Un-Ininstall.
        * Arreglado un problema de traducción con múltiples paquetes en un archivo TP.
        * Permitidos muchos archivos TRA para un LANGUAGE en un archivo TP. 
        * Añadido el comando AT_EXIT. 
Version 13:
        * Cambio de TP a TP2 luego de un conflicto reportado en el mod de Sola.
Version 14-20:
        * --biff-get ahora ignora el override/
        * Luego de un error TP recargamos el archivo de traducción, así que no más
          textos extraños durante la instalación
        * SETUP-FOO.EXE implica una búsqueda por FOO.TP2
        * Añadido COPY_TRANS (gracias, JC)
        * Añadido AUTO_TRA (gracias, Quitch)
Version 21:
        * Busca en el Registro por el directorio del juego
        * Maneja archivos sobreescritos de solo-lectura
Version 22:
        * Reempaza [\r\n]+ en el texto-en-bruto (gatillos, acciones) con "\r\n". 
          Esto debría ayudar a la gente que estaba consiguiendo duplicar las nuevas líneas. 
Version 23-24:
        * Incorporadas las sugerencias para el README de Jason. ¡Un millón de gracias!
        * Añadido soporte para IWD. 
        * Convierte múltiples nuevas líneas en el formato correcto cuando se está compilando y
          decompilando. 
Version 25:
        * Ahora retrasa el "successfully installed" (instalación exitosa) hasta que el dialog.tlk ha sido
          grabado. 
Version 26: 
        * Maneja la carga de los gatillos de sutiación. Gracias especiales a Jason Compton
          y Ghreyfain por hacer la investigación. 
        * Memoriza O escribe "[FOO.DLG] created" pero no ambos. 
        * Añadido AT_UNINSTALL
Version 27:
        * Clasifica los gatillos de transición en en el comando trans-trig-table cuando carga.
          (bajo la suposición de que las transiciones trabajan desde el fondo hacia arriba
           en el comando trans-trig-table, así debemos escribir fuera de esa forma
           en orden para preservar la semántica) 
        * COPY_TRANS procesado luego de todas las otras acciones. 
Version 28:
        * Realmente procesa COPY_TRANS. Suspiro. 
Verison 29:
        * Realmente permanece en silencio cuando graba los DLGs.
Version 30:
        * Realmente procesa COPY_TRANS, esta vez seguro. :-)
Version 31:
        * Arreglado un bug donde las situaciones de Multi-SAY olvidarían sus WEIGHTs
Version 32: 
        * Añadida una posición opcional para EXTEND_{TOP,BOTTOM} en los archivos D.
Version 33:
        * Una mejora menor en el perfil y algoritmos hacen que WeiDU
          sea ahora al menos dos veces más rápido que antes mientras conpila los
          archivos D. El aviso "please be patient" es mucho más innecesario.
        * Añadido un mezquino menú de opciones porque estoy cansado de decir
          "No" tres mil veces en el Mod de Sola.
          Desafortunadamente, a DOS no parece gustarle el color. 
        * Añadido ADD_KIT como una opción TP2. Ver mymod.tp2 por detalles. 
Version 34:
        * Arreglado un bug en CHAIN donde el archivo luego de == sería 
          reportado como "not found" (no hallado) aún cuando esté presente. ¡Gracias Michael!
        * Añadido APPEND_COL como una opción TP2. 
        * Añadidos COPY_EXISTING, WRITE_BYTE, WRITE_SHORT, WRITE_LONG. 
        * Los archivos TRA ausentes no dan errores fatales. Teniendo sin embargo
          una referencia indefinida (como, @55). 
        * Archivos ausentes en la desinstalación ya no son erroes fatales. 
        * Incluido el tutorial de Michael Lyashenko. 
Version 35:
        * Añadido ADD_MUSIC
        * Añadido %VARIABLES% que son reemplazadas por el número de kit o música
          desde ADD_KIT o ADD_MUSIC. 
        * Mejor manejo del TLK (Trata un posible error con el DIALOG.TLK
          de la versión polaca del Ascension?).
Version 36-7:
        * Añadido REPLACE_TEXTUALLY
        * Esta vez realmente arregla el manejo del TLK polaco. Cuando la cadena TLK
          tiene una distancia de 0, a veces el offset es un gran número negativo. 
Version 38:
        * Cambiado : por / en los nombres de directorio de los BIFF para compatibilidad con los Mac-VPC.
        * Añadido SET_STRING por Ghrey. 
Version 39:
        * Permite patches luego de EXTEND_TOP, EXTEND_BOTTOM por Michael. 
        * Añadido MKDIR como una acción TP2. 
        * Añadido REQUIRE_FILE como una acción TP2.
        * Añadido REPLACE_SAY como una acción D.
        * Añadido REPLACE_STATE_TRIGGER como una acción D.
        * Añadido SET_WEIGHT como una acción D.
        * ADD_STATE_TRIGGER, ADD_TRANS_TRIGGER and REPLACE_STATE_TRIGGER
          pueden ahora operar en listas de situaciones. Solo coloca las situaciones extra
          luego del gatillo.
        * EXTEND_TOP y EXTEND_BOTTOM pueden operar ahora en listas de situaciones. 
          Colocando las situaciones extra antes de las listas de transiciones. 
        * ¿Quizás algún buen alma podría escribir algún doc sobre estos nuevos 
          rasgos? 
Version 40:
        * WeiDU ahora mantiene una lista de todos los mods instalados en WeiDU mods y hace la
          "desinstalación tetris" automáticamente, luego regresa todos los
          mods temporalmente-desinstalados.
        * Añadido AT_INTERACTIVE_EXIT de modo que puedas evitar "spammear" al usuario
          con tu archivo léeme cuantas veces suceda que tu mod sea fortuitamente
          desinstalado.
Version 41: 
        * Añadido WRITE_ASCII (ver también. WRITE_LONG) para la escritura en nombres de 
           scripts BCS y ITMs.
        * Arreglado MKDIR de modo que ahora hace directorios. 
        * Añadido AT_INTERACTIVE_UNINSTALL. 
        * Arreglado un bug ocn la "desinstalación tetris". 
        * Podemos enlistar todos los efectos en un SPL o ITM. 
Version 42:
        * Convertido / en \ en los comandos del estido de AT_EXIT. 
        * Arreglado un bug en APPEND_COL que causaba que nunca adjuntara
          nada. :-)
Version 43:
        * ADD_KIT ahora toma los parámetros de ToB (Habilidades de alto nivel
          y equipamento de inicio). El equipamento de inicio fue
          muy tramposo para conseguirlo bien, dado que no puedes solo adjuntar una columna,
          tienes que fijar explícitamente la columna X (la cual puede ser o no un
          anexo). 
        * ¡Los tutoriales de Multi-SAY y CHAIN2 de Compton incluidos!
Version 44:
        * Mejor manejo de los cambios de sintaxis en los archivos TP2 (cuando un mod
          intenta desinstalar a otro).
        * Añadido FORBID_FILE. 
Version 45:
        * Arreglado un bug en REPLACE_TEXTUALLY (etc.) que estaba causando que
          no correspondiera un conjunto de cadenas. 
Version 46:
        * Añadidos REPLACE_BCS_BLOCK, INSERT_BYTES y DELETE_BYTES acciones
          patch. 
        * Añadido --cmp-to y --cmp-from. 
        * Arreglado un bug donde copiando FOO.EXT al directorio1 y luego al directorio2
          crearía información del Backup incorrecta: solo directorio1\FOO.EXT
          sería desinstalado. 
Version 47:
        * Añadidos REPLACE_ACTION_TEXT y REPLACE_TRIGGER_TEXT como 
          acciones D. ¡Vamos Jason! 
Version 48:
        * Añadidas las opciones --dcmp-to y --dcmp-from para soltar automáricamente
          los REPLACE-diffs entre los archivos DLG. 
Version 49:
        * Detiene la lista de opciones. 
        * Ahora puedes decir 
            STRING_SET ~Hello~ ~Hola Boy~ ~Hola Girl~ [HOLA]
          para cambiar cara cadena ~Hello~ en DIALOG.TLK por la nueva.El
          viejo STRING_SET 345 sintaxis aún trabaja. Que te diviertas, Compton. 
        * --biff-get puede ahora tomar expresiones regulares regexp
        * Si fallamos en medio de una instalación TP2 entonces desinstalamos
          todos los archivos copiados antes, restaurando las cosas a como estaban
          antes.
Version 50:
        * La lectura desde los BIFF de cualquier tamaño es ahora soportada. Nótese que
          un arcihvo individual dentro de un BIFF, a pesar de eso debe ser <= 16777000 bytes.
        * Más elegantes mensajes de error an uno pocos lados. 
Version 51:
        * Hacer WeiDU unix tratable para un amigo a quien le gustaría volver a
          compilarlo.
        * Añadida una opción --nogame para la gente que le gustaría testearlo
          pero no tiene ninguno de los juegos del Engine Infinity. 
        * Unifica el manego de / y \. 
Version 52:
        * Permite restricciones en COPY. Ahora puedes decir 
                COPY src dst    // multiple src-dst pairs OK
                 patch_list
                 constraint_list // "IF", "UNLESS", "IF_SIZE_IS" 
        * IF_SIZE_IS añadido como una cohibición. 
        * Ver examples/copyif.tp2. 
Version 53:
        * Arregla un bug con "--yes" y las instalaciones fallidas. 
        * Añadida la directiva CHAIN3 para soportar bifurcaciones en diálogos ocn CHAIN. 
          Esto fue usado recientemente en el mod Improved Ilyich mod -- Compare
          la nueva presentación compacta con lo que era antes por los muchachos de Eclipse. 
Version 54:
        * Arreglado un bug con AUTO_TRA. Los archivos D no deberían tomar el correspondiente
          archivo. 
Version 55:
        * Añadida la opción INTERJECT para los banters más sencillos. Ahora estamos verdaderamente
          metidos con fuerzas que no deberíamos conocer! Muajaja!
        * Reemplazado el espacio en blanco manejado en los archivos DLG para evitar dañar 
          CharName("Drizzt Do'Urden",Player1)
          en la situación 57 de c6drizz1.dlg. 
Version 56:
        * Decir AT_EXIT "VIEW esto" en lugar de AT_EXIT "libreta de notas esto". VIEW
          al comienzo de un comando será reemplazado por algo
          apropiado para la arquitectura del usuario (libreta de notas, mac osx lector,
          o similar). 
        * Añadido INTERJECT_COPY_TRANS, el cual hace lo que esperarías
          si ya has entendido las acciones INTERJECT y
          COPY_TRANS. :-) Compton, ¿algunos docs? :-) 
Version 57:
        * Arreglado un bug en el manejo de COMPILE-USING archivos TRA cuando
          no tienes una palabra clave LANGUAGE en tu archivo TP2. Tales archivos Such TRA
          ya no son ignorados. Nunca noté esto conmigo porque todos
          mis mods tienen LANGUAGEs. 
Version 58:
        * Arreglado un bug con el directorio de registro. 
        * Añadido --transref cadena para tener --trans emite referencias de cadena. 
        * Añadidas las nuevas instrucciones de Compton para COPY_TRANS y INTERJECT. 
Version 59:
        * El Registro fuciona realmente esta vez, pero si esto no lo arregla
          no sé que está ocurriendo. 
Version 60:
        * Los directorios posibles ya no son mostrados, puesto que eso estaba confundiendo a los
          usuarios (realmente no).
        * Añadida la opción "--biff-name X" para "--biff-str" y
          "--biff-type" listas. Un uso típico sería algo como
          weidu --biff-name 8 --biff-type CRE --biff-str SW1H
          para imprimir en pantalla los nombres de todas las criaturas que tienen espadas
          de una mano.
Version 61:
        * Añadidos "--tlkcmp-to" y "--tlkcmp-from" por Jason (o algo). 
        * Añadido "ACTION_IF pred THEN BEGIN acciones END" como una acción TP2
        * Añadidos FILE_EXISTS, FILE_SIZE, FILE_CONTAINS, AND, OR, NOT como
          predicates TP2. 
        * Añadidos FAIL y PRINT como acciones TP2. 
Version 62:
        * Añadidos los docs de tlkcmp por JC. 
        * Añadido el predicate "FILE_EXISTS_IN_GAME", el cual es verdadero si el archivo
          está en los BIFF O en el directorio override. 
        * Opción --traify añadida. weidu --traify mi.d --dout nuevo.d 
          Hará nuevo.d el cual es justo como mi.d excepto que todas las cadenas
          ahora usarn las referencias TRA en nuevo.tra. Documentación de
          este aspecto será (esperamos) proveída por nuestro lector de
          mentes trabajador independiente favorito. 
Version 63:
        * CHAIN reemplazado por CHAIN3 (pero puedes continuar usando  CHAIN).
        * --traify ahora emite los TRA en el mismo orden como 
          aparecen en tu archivo D original. Eso hace a --traify más lento.
        * La opción --traify# te permite especificar en offset de comienzo para
          las cadenas de traducción creadas. 
Version 64:
        * Arreglado un bug notado por Quitch donde la situación DLG interna no fue
          borrada luego de una instalación (no)exitosa. Esto dio a entender que
          si tu tienes dos archivos D con "BEGIN foo" ambos en dos componentes
          separados o en el mismo componente que intentaste reinstalar
          fallaría. Esto podría tambien expilcar algunos errores que la gente ha
          ido reportando acercad de los efectos de la "múltiple instalación". 
        * Se queja desde antes si el archivo dialog.tlk dado es de solo lectura
          o un directorio o algo.
Version 65:
        * Otro intento de arreglar el bug que fue reportado por Quitch. :-) 
Version 66:
        * Esta vez estamos realmente seguros acerca del bug de Quitch. :-) Ver
          test\quitch\quitch.tp2 para una manera de reproducir el fallo. 
          Fue usado (como reportó Quitch) pero ahora no se da. 
          Si esto lo arregla, el problema era mucho peor de lo que pensé: la
          lista de acciones de los archivos D podría ser "duplicada" (o al menos
          no borrada) cuando el error sucedió. 
Version 67:
        * Arreglado un bug donde los mods temporalmente desinstalados serían
          manejados de forma deficiente cuando quieras reinstalarlos, bla, aún no
          puedo describir este bug. De todos modos, causaba (por lo menos) un montón
          errores como "Unix.Stat(solarom/uninstall/1/uninstall.1)" pero
          ahora no parece herir nada. Todavía marca un
          desperfecto conceptual en mi entendimiento de que estaba sucediendo. 
        * El comando --tlkcmp ahora produce TP2 STRING_SETs con
          referencias @traducción y un archivo TRA que los llena. 
Version 68:
        * Arreglado un bug donde diciendo --uninstall en un mod que tiene algún
          componente desinstalado te dejaría en un ciclo infinito.
Version 69:
        * En una declaración de situación, IF ~StateTrig()~ THEN BEGIN label, 
          el THEN y BEGIN son opcionales.
        * En una transición, IF ~TransTrig()~ THEN ..., el
          THEN es opcional. 
        * Síntaxis .D abreviado: INTERJECT_COPY_TRANS puede ser I_C_T, etc.
          por las sugerencias de Compton. 
        * INTERJECT_COPY_TRANS ahora hace el copy-trans en todas las
          interjecciones, so sólo en la última. El bit copy_trans bit viene
          sobre tus interjecciones, así que debería aún funcionar como
          antes en todos los casos donde trabajó antes. Suspiro. 
Version 70:
        * Nuevos docs de traify por Compton. Arreglado el ejemplo de la pizza. 
        * Unificados los docs de CHAIN/CHAIN3. 
        * --traify trabaja en archivos TP2. Usa --dout y --traify# como antes.
Version 71-72:
        * Nuevos docs ligeramente cambiados.
        * SET_STRING puede ahora tomas @traducciones.
Version 73:
        * COPY_EXISTING puede ahora usar expresiones regulares.
        * Arreglado un bug donde un archivo D con un error de lingüística sería abierto
          por WeiDU. Este bug fue reportado por Quitch. 
        * WeiDU trabaja con Icewind Dale 2. 
Version 74:
        * Sacado COPY_EXISTING_REGEXP fuera de COPY_EXISTING. Pequeño
          bug de compatibilidad, lo siento.
Version 75:
        * Los archivos TRA con errores ya no son abiertos. 
        * Los archivos TIS pueden ahora ser extraídos correctamente. Gracias especiales a
          Ghreyfain por proveer los archivos de datos para resolver este problema. 
Version 76:
        * También mira en GAME/CDx/Data/ en lugar de solo GAME/Data por BIFFs.
Version 77:
        * Los BIFF comprimidos (a veces llamados BIFCs) son ahora soportados.
Version 78:
        * Corregido un pequeño error tipográfico notado por Jason Compton que causaba que
          todos los archivos no-TIF fueran cargados incorrectamente y todos los archivos TIS excepto el primero
          serían cargados incorrectamente. 
Version 79:
        * El directiorio actual ya no es una localización de búsqueda. Compton
          quiso esto, grito si esto no te sirve.
Version 80:
        * Maneja archivos BCS vacíos en EXTEND_TOP/BOTTOM. 
Version 81:
        * Cambios en CHAIN/CHAIN3:
          + Ahora puedes especificar una condición inicial:
            CHAIN IF ~Global("MyValygarBanter","GLOBAL",0)~ THEN BVALYGA foo
              "Valygar dice hola." 
            END BVALYGA 50
          + Puedes terminar con "EXIT" en vez de "END FILE LABEL". 
          + Puedes terminar con "COPY_TRANS FILE LABEL" en vez de "END FILE
            LABEL". 
        * Cambios en CHAIN/CHAIN3/INTERJECT/I_C_T :
          + Puedes incluir acciones DO luego de un texto hablado:
            CHAIN BVALYGA foo
              "¡Te voy a machacar!" DO ~SetGlobal("ValySmite","GLOBAL",1)~
            == BVICONI
              "Pero no yo. Yo soy resistente a la magia."
            EXIT 
          + Si eres un verdadero masoquista, puedes usar DO e IF al mismo
            tiempo: 
            CHAIN BVALYGA foo
              "¡Te voy a machacar!" DO ~SetGlobal("ValySmite","GLOBAL",1)~
            == BKELDOR
              IF ~IsValidForPartyDialogue("Keldorn")~ THEN 
              "Te voy a prevenir sobre machacar a alguien."
              DO ~SetGlobal("KeldornPreventsSmiting","GLOBAL",1)~
            EXIT 
        * Gracias especiales a "Blue" por hacer el tutorial que sugirió
          estos cambios. Ver examples/chain-banter.d por el tutorial de
          ejemplo. 
Version 82:
        * Setup-Foo.exe ahora termina si Setup-Foo.tp2 y Foo.tp2 no están
          presentes.
        * Añadida la opción --automate. Úsala con el directorio de
          archivos ITM/SPL/CRE (decir, "mymod/itm"), y hará un archivo TP2
          por ti. Uso de ejemplo:
          C:\> weidu --automate foo/itm --textapp Setup-Foo.tp2
        * Gracias especiales a Victoria, quien seguramente será famosa en algún
          momento. Hazme saber cuando hayas actalizado tu tutorial de CHAIN
          y yo daré el link hasta él. 
Version 83-84: 
        * Arreglado un bug en "INTERJECT" que daba números errados
          de parámetros a ser pasados a "Global()" y colocaba gatillos
          (como InParty("Valen")) en el lugar de la acción. ¡Suspiro! ¡Suspiro!
Version 85:
        * Arreglado un bug donde --automate perdía los nombres de los offset en 0xC (el
          nombre identificado de los ITMs, etc). Repite --automate si tu lo usaste para 
          estar seguro de que no perdiste nada. 
        * Añadidos algunos docs de --automate basados en las sugerencias de Rene Heroux. 
Version 86:
        * Mucho mejor manejo de los mods con más de 4 componentes.
        * Añadida la acción TP2 UNINSTALL para permitir a un componente de mod (digamos, 
          el kit de arquero en el nuevo mod tactics) desinstalar otro (digamos,
          la vieja versión del kit de arquero en el mod de Sola). 
Version 87:
        * Yada yada, más deberes para estar listo para el mod tactics. 
Version 88:
        * Añadidas las acciones TP2 EXTEND_TOP_REGEXP y EXTEND_BOTTOM_REGEXP TP2.
          ¿Hará la persona que hizo esta petición algunos docs? 
        * --automate ahora maneja AREs 
        * Puedes ahora decir !NUMBER ~Hello~ (o !NUMBER @44) en un
          archivo D en vez de ~Hello~ para *FORZAR* la cadena ~Hello~ a
          sobreescribir lo que sea que estuviera antes en la referencia NUMBER en el dialog.tlk 
        * Añadida la opción --forceif. Se comporta como  --traify. Entonces puedes
          decir: weidu --forceify my.d --dout new.d 
          El archivo D creado será justo como el anterior, excepto que todas
          las cadenas serán convertidas en cadenas forzadas con su
          actual número de referencia. No, no entiendo por qué querrían 
          esto tampoco. Pero algunas personas lo hacen. 
Version 89:
        * Añadidos los tutoriales de Japeth.
        * --tcmp ya no termina en un archivo inválido. ¡Gracias, Falk!
        * WeiDU ahora describirá aquellos enojosos archivos IDS cuando son
          extraídos de los BIFF. 
        * WeiDU es ahora un BCS -> BAF decompilador. Solo pasa los archivos BCS en
          argumentos. Los archivos BAF serán creados en el directorio actual (o
          puedes usar --out). Considero el NI para ser la "referencia"
          para ver. Déjenme saber si encuentras un script donde WeiDU y el NI
          discrepan en algo que no sea un comentario, un MYAREA o un
          "ar1234". 
        * Ahora puedes dar líneas de comando de WeiDU luego de ver la 
          lista de opciones. 
Version 90:
        * Arreglado un problema donde SETUP-FOO no funcionaba. 
Version 91:
        * WeiDU es ahora un BAF -> BCS compilador. Solo pasa los archivos BAF
          como argumentos. Los archivos BCS serán creados en el directorio actual (o
          puedes usar --out). De nuevo, háganme saber los malos resultados. 
          Trabajo futuro: permitir referencias de cadena al estilo D en los archivos BAF, etc. 
        * WeiDU ahora lee todos los archivos .INI en tu directorio del juego y
          busca por líneas de la forma CD1:=C:\My\Path. 
        * Nuevo tutorial de Uberchain por Jason. 
Version 92:
        * Arreglado un bug al descompilar donde el gatillo errado (Ej.,
          HaveSpellRES en vez de HaveSpell) puede ser impreso. 
        * WeiDU ahora chequea las acciones y gatillos en los archivos D. 
        * La documentación ya no es tan "pesada" una vista más sencilla. Gracias a 
          Tapio Kivikkola por puntualizar esto. 
        * Roland ha ocupado el manto "compilador de WeiDU para usuarios de Mac".
          ¡Gracias!
        * Arreglado un problema con CHAIN olvidando algunas acciones. Gracias,
          Quitch. 
        * CHAIN3 ahora soporta cargas (WEIGHT) para la condición inicial. 
Version 93:
        * Arreglado un problema con los archivos IDS que tienen demasiados espacios en blanco. 
Version 94:
        * Arreglado un problema con I_C_T la reversa de las listas de transiciones. Gracias por
          dejarlo perfectamente claro, Jason.
Version 95:
        * Ahora verificamos las condiciones de transición de los archivos D. Antes eran salteados. 
        * Las acciones y listas de gatillos inválidas en los archivos D son ahora solo
          WARNINGS (peligro), como deben ser.
        * La localización de información para accionesy y listas de gatillos en los archivos D
          es ahora mucho más acelerada. Todavía no es perfecta, pero al menos está
          por buen camino. 
        * BCS->BAF descompilación ya no manda un montón de peligros de
          "this file not found" (archivo no encontrado). 
        * Añadido el tutorial de R_C_T de Japeth. 
        * En los BAF, cosas típicas como "SeE(MySelF)" en vez de
          "See(Myself)" es solamente una advertencia. 
        * Si dices algo como "LastSeenBy()" ahora estás recibiendo una
          advertencia explícita de usar "LastSeenBy(Myself)" en su lugar. Lo primero
          a veces cosigue un trato extraño por parte del engine. 
        * Arreglado un bug en APPENDI. Gracias, Quitch. 
        * Estamos planeando una fiesta sorpresa por el 50avo cumpleaños de mi madre hoy. 
          Deséanos suerte. 
Version 96:
        * Errores de ortografía y advertencias no son guardadas en memoria. 
        * Los archivos 2DA XOR-codificados están ahora decodificados. Anteriormente solo los
          archivos IDS eran decodificados. 
Version 97:
        * Añadido soporte para la lactura en algunos archivos DLG rotos del IWD (vienen
          con gatillos/acciones fuera de contexto). 
        * Añadido soporte para leer en algunos archivos BCS rotos (omiten
          un parámetro de acción no-opcional). 
        * ALLOW_MISSING ya no hace diferencia entre mayúscula y minúscula. Gracias, Carl Grenthe. 
        * Arreglado un error que invorucraba comentarios // indeterminados. Gracias,
          Moonfruit. 
        * Ahora manejamos directorios de CD como "C:\CD2;E:\Other\CD2". 
        * Los archivos de AUTO_TRA son ahora asociados solo con su (simple)
          archivo D asociado y no con otros archivos. Gracias, Dyara
          y Quitch. 
        * Arreglado el problema con "See(LastSeenBy(Nearest([EVILCUTOFF])))" ->
                "See(LastSeenBy(Nearest)([EVILCUTOFF]))"
          Gracias, Dyara. 
Version 98:
        * Arreglado un problema con [ANYONE] en el mundo de BCS->BAF. Gracias, Dyara. 
        * Arreglado un problema reinstalando donde un mod con un error en la
          nueva versión daría el mensaje "yes/no/uninstall" en vez de 
          "yes/no". Gracias, Quitch. 
Version 99:
        * Los IF de CHAIN son ahora chequeados para validar. 
        * Setup-Foo no se copiará sobre el Setup-Bar's más viejo en el
          mismo directorio.
        * Ahora pudes usar COMPILE y EXTEND con los archivos BAF. ver Setup-Solaufein.tp2. 
        * Los archivos BAF pueden ahora tomar ~Referencias de cadena~ y @referencias de traducción.
          Ejemplo:
            DisplayStringHead(Myself,~Flame Arrow~)
            DisplayString("Sola",@144)
Version 100:
        * Arreglado un problema con la llave-separadora-de-directorios. Gracias, Devon. 
        * COMPILE ~foo.baf~ ahora se desinstalaría correctamente. Gracias, Japh. 
Version 101:
        * Las entradas IDS desconocidas (como los conjuros de ToB en el SPELL.IDS de SoA) ahroa
          se atrasan a 0. Esto estaba causando problemas con la instalación de Sola. 
Version 102:
        * Añadido READ_BYTE, etc. WRITE_BYTE y sus compañeros pueden usar ahora expresiones
          compuestas (probablemente involucren variables. Ver IWD2-Ease. 
        * Añadido COPY_RANDOM. 
        * Añadida la opción --biff-get-rest, la cual básicamente aplica
          --biff-get a todo el resto de los argumentos de la línea de comandos. 
Version 103:
        * Añadido ASK_EVERY_COMPONENT TP2 para Jason. Colócalo cerca de
          AUTO_TRA. 
Version 104:
        * Un último chequeo a la auto-actualización 
        * Puedes decir "COMPILE ~mymod/big-folder-of-scripts~" en todos los
          archivos D o BAF en ese directorio que quieres compilar. Esto funciona como
          dándo un directorio para COPY. 
Version 105:
        * Arreglado un problema con WEIGHT. Gracias, GB. 
        * Añadidos --min y --max las cuales trabajan con --tlkcmp y --string.
        * Arreglado un bug menor en --tlkcmp. Gracias, Harden Coonor. 
Version 106:
        * IDENTIFIED_DESC funciona ahora como un offset. 
        * Añadidas SOLVED_JOURNAL y UNSOLVED_JOURNAL. Gracias,
          Avenger. 
Version 107:
        * Arreglado un bug donde el archivo temporal para un gran biff comprimido
          no sería removido si WeiDU se detiene porque el biff era demasiado grande
          (o alguna otra razón). 
        * Acualmente, el manejo entero de los biff comprimidos ha sido cambiado.
          Ahora solo hacemos una descompresión a pedido. Por ejemplo, el tiempo para
          extraer AR0602.WED decae dede 9.6 segundos hasta 0.3 en mi máquina. 
          No más archivos temporarios en lo absoluto. 
        * Ahora es más rápido cuando algo añade un gran número de cadenas nuevas al
          dialog.tlk. 
        * Arreglado nuestro manejo de WEIGHTs (de nuevo!). Gracias, Dyara. A todos,
          háganme saber si encuentran fallas en el nuevo manejo. 
Version 108:
        * Permitidas cadenas como LastSeenBy("foo") en los scripts.   
        * Añadido soporte para la creación de biffs. Usa la opción --make-biff y
          dale un directorio. Todos los archivos en ese directorio serán
          puestos en un biff, CHITIN.KEY será actualizado. 
Version 109:
        * Arreglada la descompilación de BCSs. Gracias, Dyara. 
        * --biff-get y la descompilación de BCSs ya no se detienen luego del primer
          error. 
        * --biff-get puede ahora tomar archivos arbitrariamente largos (ej., AR1000.TIS). 
          A mi oficialmente *no me importa* si hay algún archivo por ahí que WeiDU
          aún no puede estraer. Usen el WinBiff
Version 110:
        * Las acciones y gatillos de los archivos D son ahora reemplazadas con su forma
          convertida. Así puedes decir DO ~EraseJournalEntry(@1000)~ y tienes el
          trabajo en el final. Gracias, Triangle. 
        * El registro de los TP2 es ahora más sensible. 
        * Añadidas las líneas de comando --make-tlk y --traify-tlk. 
        * La extracción de los BIFFs ya no causará problemas a WeiDU si tus archivos
          BIFF y KEY están bien. 
        * Arreglado un problema con la extracción de biffs que estaba causando que
          COPY_EXISTING "esto.cre" fallara. Gracias, Edsel Sabulao. 
Version 111:
        * Añadidos bloques ALWAYS para los archivos TP2. 
Version 112:
        * Permitido el ! en los indicios (pero no como primer caracter).
        * --nocomm saca los comentarios en los archivos BAF. Gracias,
          AvengerTeamBG.
Version 113:
        * Te advertimos sobre añadir cadenas pero no especificar --tlkout. Gracias,
          AvengerTeamBG. 
        * Mejor soporte para el esquema TP2 de los múltiples-directorios. Sin embargo,
          el único método realmente soportado es tener todos tus archivos TP2
          en el directorio principal del juego y correr Setup-Foo.
        * Acuctualizado el epílogo de CHAIN en la gramática documentada.
Version 114:
        * Arreglado un problema con --biff-get y los archivos codificados. 
        * --trans ahroa mira dentro de las acciones DLG (como EraseJournalEntry())
          y da cadenas de traducción para ellas también.  
        * El bug de --biff-name con las referencias de cadena inválidas arreglado. Gracias, Sqweek. 
        * Arreglado un horrible bug en la versión 113 que estaba causando que WeiDU sobreescribiera
          los archivos TP2. 
Version 115:
        * Mejor manejo de errores para los INTERJECT_COPY_TRANS fuera de contexto. 
          Gracias, Sim!
        * Otro arreglo de erroresd en no-Setup-Foo.exe. Esto debe
          permitir la desinstalación. Gracias, GB. 
        * Arreglo de llas condicionales CHAIN3. Gracias, Jason. 
        * Añadido REPLACE_ACTION_TEXT_PROCESS. Buena suerte, Ras.
Version 116:
        * Varios arreglos de portabilidad por Ras. 
        * Arreglado un bug con INTERJECT_COPY_TRANS. Gracias, Elanor. 
        * R, intenté mandarte algún email y fue rebotado. Envíame
          algún email más con la dirección del trabajo. 

This document was translated from LATEX by HEVEA.