yo veo estas cosas y a mi se me para , por dios!!! que manera de trabajar, y todo es por los usuarios, son todos modelos hechos por usuarios que quieren ver mas grande y mejor a 2238 T.T
ACB, el Mutie 11 Mar : 03:58
Ostras, valla curro tio!!
Slaughter 11 Mar : 02:40
Aviso que el avance sobre New Vegas es extenso, leer con tiempo y calma
Feral Dog 10 Mar : 20:23
uu che q hagan wipe de 1 ves q me aburro esperando y no me da ganas de entrar sabiendo de wipe futuro
X_Treme 10 Mar : 17:33
jaja acb estubo muy bueno ajja!!!
aplastando clanes menores ajja
Khorne 10 Mar : 17:24
La idea es que la web se vea tanto en Firefox como en IE , pero Firefox muestra el diseño mejor ... Se intentara qe no haya errores en IE siempre que se pueda .
X_Treme 10 Mar : 16:42
mala suerte, estaban diciendo que ni siquiera ganando la liga el ingeniero pelegrini se queda
Bienvenido al estupido cuaderno sobre scripts por Khorne Una serie de tutoriales que trata de explicar este "misterioso" mundo que es el Scripting sobre el Fallout 2 ... Una nota : El indice no es asi de soso si no que se ira ampliando este "mini faq" con nuevas preguntas y todo eso ... pero en un futuro logicamente . Nota : Se aceptan nuevos contenidos . Si conoces alguna manera mejor , o mas facil de hacer algo citado en este manual y te gustaria contribuir , puedes dejar un mensaje en el Taller de Vic . La segunda nota : El apartado de scripting esta centrado en como crear contenidos , no en cubrir ciertas funciones .
Un script se encarga de mandar al juego a hacer determinada accion ,ya sea destruir un escenario y crear otro (romper algo) , recargar un arma o una simple conversacion . La mayoria de acciones son controladas mediante script , asi que si queremos agregar nuevas acciones a una mod tendremos que aprender algo de este lenguaje . Mucha gente se piensa que esto es algo complicado , y no lo voy a negar . Pero no todo es complicado , crear conversaciones , agregar nuevos objetos y demas no es muy complicado incluso para el que no dispone de mucha idea de lo que esta haciendo . Ademas hace realmente poco que este sector (el de los scripts) empieza a ser conocido , ya que antes habia que complicarse mucho la tarea y solo estaba al alcance de algunos gurus . Actualmente hay manuales (como este ) , programas , scripts predefinidos y un monton de utilidades que nos facilitaran la tarea . Al final del documento en la seccion "recursos" incluyo una lista de los mas utiles .
Ahora explico alguna terminologia :
Local Var (variable local) Una variable local se almacena en ese mismo momento , los cambios echos al mapa por una Local var no se guardaran al cambiar la zona , al abandonar , se reseteara cualquier valor que tengan. Suelen empezar por LVAR_ Se tienen que definir al principio del script .
Map Var (variable de mapa) Estas variables se guardan en los cambios de mapa , al guardar la partida , etc... Y sin usadas para establecer quests exclusivas de una ciudad , un encuentro , etc... Suelen agregarse a los Headers de los mapas , para luego hacer un Include al mapa donde va el script , y tener asi todas las variables organizadas . Empiezan por MVAR_
Global Var (variable global) Estas ultimas son similares a las MVAR , la diferencia , es que estas se guardan y permanecen en ese estado DURANTE todo el tiempo , mientras vas por el mapa , hablando , etc... Estas vienen definidas en el archivo GLOBAL.H y empiezan por GVAR_
II - Puesta a punto La puesta a punto trata sobre como tener todo listo y preparado para no encontrarnos con ningun problema a al hora de modear , tener los scripts a mano . Recomendamos su lectura a todos los usuarios ya que la mayoria de problemas suelen ser por una mala organizacion .
A - Herramientas necesarias Hay dos herramientas que son indispensables para compilar scripts y/o trabajar con ellos .
BIS Compiler (descargar aqui) Este es el compilador oficial que lanzo interplay para compilar los scripts del Fallout 2 ... Necesita de un Prepocessor como el Watcom (descargar aqui) o el Visual Basic 6 . Bastante efectivo .
FSE (Fallout Script Editor) (descargar aqui) IDE desarrollado por Jargo , que permite hacer un monton de funciones casi automaticas (registrar un script , añadir conversaciones , llevar un orden de los nodos , etc..) . A la hora de compilar tiene todo lo necesario para compilarlo sin preocuparse (basicamente es el BIS Compiler con el Watcom ya preparado)
Tambien hay una especie de "grupo" que yo utilizo actualmente para compilar , uso el FSE para componerlos y el BIS para compilarlos ... ¿Razon? Hace poco tube problemas con el FSE porque no te indica en algunos aspectos si tu script esta mal compuesto , mientras que el BIS te indica el error . Asi que para usuarios noveles recomiendo la siguiente utilidad que se compone de el BIS Compiler , Watcom , y todo lo necesario para compilar los Scripts de una manera sencilla . Para mas informacion de como utilizarlo revisar el apartado "Compilar con el BIS Compiler" .
B - Organizacion del "entorno" Antes de empezar ni tan siquiera a replantearse el trabajar con scripts , tendremos que tener una organizacion sobre lo que hacemos , donde lo hacemos y demas informacion . El Fallout 2 se compone de mas de 1200 scripts , como para tener que buscar cual hemos modificado o creado . Asi que recomiendo la siguiente organizacion .
Ya que trabajaremos en algunos momentos con Ms-Dos , es recomendable crear una carpeta en la unidad principal con un nombre corto (menos de 5 caracteres) ... Todos los ejemplos citados en el manual se han creado teniendo en cuenta que la carpeta donde estan los programas es : "c:\usr\kpiler\" , ya que tambien necesitamos incluir los Headers de una manera facil , tengo la siguiente rama de carpetas :
c:\usr\kpiler
Compilador y scripts sin compilar
c:\usr\scomp
Scripts compilados (.int)
c:\usr\HEADERS
Headers que utilizamos
De este modo mantendremos un orden sobre lo que editamos , asi que al crear un script solo tendremos que utilizar para incluir un header "..\headers\define.h" (como esta establecido en los scripts oficiales) y los scripts son guardados en "scomp" , ya que personalmente , prefiero guardar los scripts en una carpeta diferente (para saber que se han compilado , no tener que buscar en toda la lista , etc..) para luego agregarlos con mas tranquilidad ...
C - Preparar los headers actualizados Ya empezamos a tener todo organizado , la carpeta con los programas y las ideas claras ... Pero , hay un dato que se les pasa a la mayoria . Los scripts que vienen con el mapper son de la version 1.0 , por lo que si usamos esos scripts , a la hora de hacer una mod , estaremos incluyendo los fallos que tenia la misma version , cosa que no es nada buena . Logicamente tambien querremos incluir la 1.02 para que todo vaya como la seda verdad ? Pues para eso tendremos que usar los scripts descompilados de la version 1.02 . Tranquilos , Haen ya se ha tomado la molestia de descompilarlos y subirlos a NMA para que los tengamos para descargar , el pack se puede descargar en este enlace . Una vez descargados solo tendremos que descomprimirlos en "c:\usr\HEADERS" (o donde los hayais incluido) sobrescribiendo los archivos ya existentes . De esta manera nos aseguramos de que nuestra mod ni incluya algun bug o fallo sin corregir previo
A - Compilar con el BIS Compiler Mas sencillo que el FSE y rapido , por eso tiene una parte aqui . Para esta parte doy por sentado que todos teneis el set de aplicaciones que he citado arriba . Se trata del Watcom ,el BIS Compiler ,los HEADERS puestos en una ruta accesible etc... El batch que viene con el BIS Compiler era demasiado extraño para mi asi que me hice una variacion de uno que encontre por aqui ... Abrir el archivo P.BAT que se encuentra en la carpeta "KPILER" con el blog de notas y pegar esto :
Archivo BAT :
@echo off copy %1.ssl temp.c WCC386 temp.c /p /fo=temp.i copy temp.i temp.ssl dos4gw compile temp.ssl rem INCLUIR EN LA SIGUIENTE LINEA LA RUTA DONDE QUIERES QUE VAYA EL SCRIPT : copy temp.int "c:\usr\scomp\%1.int" del temp.c del temp.i del temp.ssl del temp.int echo Script compilado con exito !
Una vez hecho , guarda el bat y abre una nueva ventana de Ms-Dos (ejecutar > cmd) y dirigete al directorio donde tienes el compilador (" cd c:\usr\kpiler ") . Y para compilar un script , deberas llamar al BAT seguido del nombre del script que quieres compilar . Asi que yo tengo un script llamado "0kmgu.ssl" lo copio a la carpeta KPILER , y tecleo lo siguiente :
p 0kmgu
Si todo ha funcionado correctamente , en la carpeta SCOMP tendras el archivo que pusiste. De haber un error el script no se compilara y se creara un archivo con log de porque ha ocurrido ese error ... Ese error es el que te dice que hay mal escrito en tu script , asi que si encuentras uno no estaria mal que le prestaras atencion , de tener todo correcto saldra una ventana similar a esta :
Ya solo quedaria incluirlo en el Scripts.lst y copiarlo a la carpeta "fallout2\data\scripts" para que este disponible en el mapper . Revisa la parte : "Agregar scripts al Define" que explica bastante la tarea . DATO EXTRA : Hay una version mas completa del BAT que he puesto arriba , que te dice algunos datos mas y crear un archivo de error llamado "err.log" que incluye el error del porque no se ha compilado citado script , os lo pongo a continuacion
Archivo BAT mas completo :
@echo off if not exist %1.ssl goto EXISTE copy %1.ssl temp.c wcc386 temp.c /pc /fo=temp.i /w4 copy temp.i temp.ssl ..\dos4gw ..\compile temp.ssl if %errorlevel% neq 0 goto ERROR
rem La ruta en las dos siguientes lineas es donde ira el script compilado md data\scripts copy temp.int data\scripts\%1.int
del temp.c del temp.i del temp.ssl del temp.int goto EXITO
:ERROR echo Ha ocurrido un error al compilar , revisar el archivo echo err.log para mas informacion . . . echo ERROR: %_CWDS%%1.ssl >> ..\err.log pause goto DONE
:EXISTE echo El script especificado no existe goto DONE
:EXITO echo Script compilado con exito
:DONE
Este en concreto hace algunas comprobaciones y/o muestra mas mensajes de error , por ejemplo , si el archivo no existe te lo dice , si ha habido un error tambien . Tambien puedes tener los dos bat , el uso es el mismo ("nombrebat nombrescript")
B - Compilar con el FSE Parte en construccion ... Pero basicamente es darle al boton F9 ...
A - Añadir nuevos PID (itempid.h) Si deseamos agregar objetos mediante script , y esos objetos son nuevos (creados por nosotros mismos). A no ser que los agreguemos al archivo "itempid.h" correctamente no los podremos usar mediante script (que si por metodo normal de mapper) . Asi que manos a la obra . Entonces , supongamos que queremos agregar una nueva municion que se trata de una variacion de los cartuchos de escopeta . Tenemos ya el archivo proto (.PRO) y el archivo de imagen (.FRM) y agregado al archivo "items.lst" . Abrimos entonces el archivo "itempid.h" (recomiendo abrirlo con el FSE ya que colorea el codigo y es mas facil de editar) en la carpeta de headers y nos vamos a la parte comentada (el texto entre /* */) que ponga "Ammo" y nos vamos al final de esas lineas , podremos ver algo similar :
Archivo > ITEMPID.H
define
Descipcion PID
Numero
#define
PID_7_62MM_AMMO
(363)
#define
PID_FLAMETHROWER_FUEL_MK_II
(364)
En este caso pertenecen los dos ultimos campos a la municion 7.62 y al Napalm MKII . Asi que si queremos agregar nuestro objeto solo tendriamos que agregar seguido de la municion :
Agregar al archivo > ITEMPID.H
#define
PID_12_GAUGE_NUEVO
(538) *!
*! = Ese numero es muy importante , no es un numero QUE NO ESTE REPETIDO , es el numero referente al archivo proto (.pro) , los archivos proto se guardan en "fallout2\data\proto\inven" . Asi que si el proto que teniamos con la municion nueva era el archivo "00000538.pro" tendremos que ponerle de numero "538" para que todo vaya perfecto . Pues con esto tan simple acaba este apartado , ahora si quieres usarlo mediante script puedes usando "PID_12_GAUGE_NUEVO" .... Ejemplo :
Parte de script :
if (obj_is_carrying_obj_pid(dude_obj,PID_12_GAUGE_NUEVO)) then begin call Node999; dend
(Nota : Parte de codigo , si lo agregas asi a un script no funcionara) En este caso el script comprueba mediante funcion IF (para que sea entendible por todos ... IF pregunta si se ha complido una accion , es como decir "Y SI" ) si el objeto (en este caso PID_12_GAUGE_NUEVO que es nuestro proto)("dude_obj" significa el mismo jugador) tiene en el inventario ("obj_is_carrying_obj_pid" funcion que comprueba si X objeto esta cargando X PID (proto))
B - Añadir nuevos Critters (critrfid.h - artfid.h) Parte en construccion
C - Añadir nuevos elementos (scenepid.h) Parte en construccion
E - Añadir scripts al define (scripts.h - scripts.lst) Antes de pensar ni tan siquiera el probar o usar un script nuevo , tenemos que agregarlo y decirle al sistema que ese script existe . Por lo tanto , ANTES de compilarlo necesitas agregarlo a una lista (para compilarlos solo es necesario agregarlo al scripts.h , pero ya que estamos nos ahorramos hacer dos viajes)
No tengo entendido con exactitud el significado de esos archivos , pero si como funcionan , el scripts.h es el que contiene todos los nombres de los scripts (intuyo que para tenerlos a mano , cargarlos facil , y demas cosas) . Abriendo el archivo scripts.h con el bloc de notas ,y nos vamos a las ultimas lineas que seran algo asi :
Archivo > SCRIPTS.H
Nombre Script
Numero
Archivo INT
Descripcion
#define SCRIPT_NIBISHDR
(1302)
// niBisHDr.int
; New Reno Bishop Hard Locked Door
#define SCRIPT_NTRICROM
(1303)
// ntRicRom.int
; New Reno Richard Wright Room Spacial
Cada linea representa un script ,y viene identificado por el Nombre (1) que es el que se utiliza a la hora de definir el nombre del script . El numero es un numero identificativo y unico , ningun script deberia de tener un numero ya repetido , el archivo INT , logicamente hace referencia al archivo que se encuentre dentro de la carpeta scripts y la descripcion es lo que nos aparece en el mapper al seleccionar un script de la lista . Un dato importante , es que tienen que ser EXACTAMENTE iguales a los que usemos en el archivo scripts.lst ... por la siguiente razon : Si nos vamos ahora a la carpeta de scripts y abrimos el archivo scripts.lst con el bloc de notas y nos vamos a la ultima linea podemos ver algo asi :
Archivo > SCRIPTS.LST
Nombre Script
Descripcion
Variables
niBisHDr.int ;
New Reno Bishop Hard Locked Door
# local_vars=6
ntRicRom.int ;
New Reno Richard Wright Room Spacial
# local_vars=1
Aqui vemos que es mas simple , llevando solo la referencia de el nombre , archivo int y otro dato importante , las variables en uso . Esta parte esta aun en investigacion , pero se de buena tinta que la descripcion y el nombre del archivo tienen que ser EXACTOS al archivo scripts.h ya que si no encontraremos muchos errores a la hora de usar el script (por experiencia propia). Usease que si queremos agregar un script para compilarlo y tenerlo listo , habria que agregar algo asi :
Agregar al archivo > SCRIPTS.H
#define SCRIPT_NOMBRE
(1304)
// kscr01.int
; Script de prueba
Agregar al archivo > SCRIPTS.LST
kscr01.int ; Script de prueba # local_vars=4
Explicacion de local_var : Ese numero determina las variables locales que utiliza el documento . No se a ciencia cierta si esto influye a la hora de leer y/o ejecutar un script , pero para sacar el numero exacto solo hay que mirar en el script y contar las variables locales del tipo " " que tenemos . El FSE puede detectar y contar las variables automaticamente .
Sub-categoria : Agregar scripts usando el FSE Con el FSE la tarea de registrar scripts se hizo aun mas facil y automatizada . Simplemente tienes que seguir un sencillo paso , dirigete a " Script > Register Script " o dale a F7 para abrir la siguiente ventana :
Ahora solo tenemos que incluir los datos del registro . "Object name" significa el nombre que se agregara al archivo "scrname.msg" , "Short script description" es la descripcion de la que hablabamos arriba . Y el numero de variables locales es lo que de que hablaba arriba . De normal no es necesario tocarlo ya que a la hora de registrarlo el propio FSE calcula las variables usadas en el script . Paso seguido le damos a OK y si tenemos todo configurado correctamente nos saldra esto :
Con esto ya tenemos nuestro script agregado y podemos usarlo y/o compilarlo . Que decir que esto es necesario , ya que si no definimos un nombre de script y no lo registramos con exito sera imposible usarlo en el juego .
A - Creacion de quests Que es de una mod sin que incluya alguna mision nueva o similar (ojo que este ejemplo puede usarse para hacer mas cosas que quests) , pues de esto se basa este ejemplo , vamos a crear una quest simple del tipo "traeme X objeto" , para ello tendremos que tener lo siguiente :
El proto del objeto (puede ser creado por nosotros o del juego ya)
El proto de quien te va a dar la mision (para menos lios utilizaremos uno en blanco) mas su script (el que dara la quest)
El archivo MSG con los contenidos de la quest
Lo siguiente es crear un script nuevo con el FSE , le damos a nuevo y escogemos "Script from Critter template" (nota , yo he eliminado los comentarios para guardar espacio) con lo que tendremos algo asi (Nota , he coloreado un poco el codigo , hiba a utilizar GeSHi pero eso me complicaba bastante la tarea y lo dejaba demasiado coloreado para mi gusto , y tambien podria liar a los usuarios , el codigo viene en gris y los comentarios en verde oscuro ) ; Antes de seguir , os comento por si mas adeltante comento de que va la quest sin haberla explicado : Vamos a crear una quest simple , que te la da un Critter llamado Torki , tienes que traerle un stimpak para poder curarse de su horrible lesion de pierna . Asi que necesitaremos crear un proto para Torki (agregandolo tal y como se explica en el siguiente manual) , luego un script para Torki (que vamos a explicar ahora) y luego finalmente el lugar donde colocaremos a nuestor gran amigo Torki Yo he elegido un mapa en blanco , pero podeis ponerlo donde os plazca !
Ahora continuemos con lo de crear un script nuevo :
Script from critter template :
/* Script de ejemplo */
#include "..\headers\define.h" /* Aqui hay que especificarle un nombre para el script para que no nos de error a la hora de compilarlo , revisar este manual */ #define NAME SCRIPT_TORKIQ
procedure look_at_p_proc begin script_overrides; if (local_var(LVAR_Herebefore) == 0) then display_msg(mstr(100)); else display_msg(mstr(101)); end
procedure description_p_proc begin script_overrides; display_msg(mstr(102)); end
procedure use_skill_on_p_proc begin end
procedure use_obj_on_p_proc begin end
procedure damage_p_proc begin end
procedure map_enter_p_proc begin end
procedure map_update_p_proc begin end /* Esta es la funcion que es llamada cuando intentas hablar con el proto que lleve este script y en donde basaremos la mayor parte de este script */ procedure talk_p_proc begin end
Para decirle al juego si determinada accion se ha cumplido o no , utilizaremos las GVAR_ , que son denominadas 'Variables Globales' . Todas ellas se encuentran en el archivo vault13.gam , lo abrimos y nos vamos a la ultima parte , veremos algo asi :
Y procedemos a agregar una variable nueva que sera la que utilizaremos para describir los distintos estados de la quest (completada , conocida , fallida , etc..) al final mas o menos para que quede asi :
De momento ya tenemos la variable para establecer la quest , y el template del critter que la dara , asi que vamos a trabajar en ella . Ya que queremos que la quest la de al hablar con el jugador . Presentamos aqui el esquema del archivo MSG :
TORKIQ.MSG >
{100}{}{Un hombre herido} // si no lo habias visto nunca {101}{}{Torki} // al hablar con el {102}{}{Ves un aldeano que parece estar herido} // texto al usar los prismaticos // Texto incial {103}{}{Ayudame por favor , estaba plantando unas mazorcas cuando se me ha ido la mano con la hazada y me cortado! No para de sangrar ¿tienes un stimpak por hay ?} // respuestas a 103 {104}{}{Claro ! Tengo uno aqui mismo!} {105}{}{Si que tengo , pero te costara 100 chapas!} {106}{}{Olvidame plebeyo}
// respuesta a 104 {107}{}{Muchas gracias por la ayuda ! Sufria un dolor terrible ! No tengo mucho pues soy un campesino , pero ruego te lleves esto que encontre el otro dia (Te da una revista que tenia en la parte de atras)}
// respuesta a 105 {108}{}{Malos tiempos corren cuando prestar ayuda a un humilde granjero se ha convertido en una cuestion de dinero. Antes que la muerte prefiero quedarme sin dinero . Toma , pero piensa en la canallada que has hecho...} // respuesta a 106 {109}{}{(el granjero te mira con un mal gesto y continua revisando su herida)}
// respuesta a 108 {110}{}{Suelo pensar mejor con el dinero! Adios !} // respuestas genericas {111}{}{Adios} {112}{}{(Fin)}
// texto para cuando la quest este completada {113}{}{Muchas gracias por ayudarme con mi herida , ya me siento mucho mejor!} // texto si el jugador no tiene stimpaks {114}{}{No tienes stimpaks ! Por favor , vuelve cuando tengas uno !}
Bien bien ! la cosa empieza a tomar forma ! Tenemos el template del script , el archivo MSG , la variable creada , y ahora que queda ? lo mas divertido ! (por que tu lo digas ) ahora procedemos a crear una conversacion siguiendo las ramas que podemos ver en el archivo MSG tal y como se describe en la siguiente parte de este manual (si , lo se , es un poco raro poner que leas una parte avanzada del manual para aprender a hacer una cosa .. pero no me acorde de esta parte cuando ya estaba la mayoria escrito ) Por lo que obtendremos el siguiente codigo y guardamos el archivo como EKCSQ.SSL :
EKCSQ.SSL >
/* Script de ejemplo */
#include "..\headers\define.h" /* Aqui hay que especificarle un nombre para el script para que no nos de error a la hora de compilarlo , revisar este manual */ #define NAME SCRIPT_TORKIQ
procedure look_at_p_proc begin script_overrides; if (local_var(LVAR_Herebefore) == 0) then display_msg(mstr(100)); else display_msg(mstr(101)); end
procedure description_p_proc begin script_overrides; display_msg(mstr(102)); end
procedure use_skill_on_p_proc begin end
procedure use_obj_on_p_proc begin end
procedure damage_p_proc begin end
procedure map_enter_p_proc begin end
procedure map_update_p_proc begin end /* Esta es la funcion que es llamada cuando intentas hablar con el proto que lleve este script y en donde basaremos la mayor parte de este script */ procedure talk_p_proc begin start_gdialog(NAME, self_obj, 4, -1, -1); gsay_start; if (get_critter_stat(Dude_obj, STAT_iq)>3) then call node001; else call node001; gsay_end; end_dialogue; end
//Dialog created by Fallout Script Editor //Look at Enlace //~~~~~~~~~~~~~~~~ FSE STARTS HERE
// comienza el dialogo procedure node001 begin Reply(103); gSay_Option(NAME,104,node002,50); gSay_Option(NAME,105,node003,50); gSay_Option(NAME,106,node004,50); end
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin Reply(107); gSay_Option(NAME,111,node999,50); end
// Answer to: Si que tengo , pero te costara 100 chapas! procedure node003 begin Reply(108); gSay_Option(NAME,110,node999,50); end
// Answer to: Olvidame plebeyo procedure node004 begin Reply(109); gSay_Option(NAME,112,node999,50); end
// texto a mostrar si la quest esta completada ya procedure node005 begin Reply(113); gSay_Option(NAME,111,node999,50); end
// END DIALOGUE. procedure node999 begin end
// START COMBAT. procedure node998 begin end
Vereis que se ha agregado codigo creado por el editor de conversacion del FSE , y tambien algunas procedures arriba (no puede incluir un "procedure" en tu codigo sin antes definirlo al principio) . Antes de proseguir , agregaremos justo despues del siguiente comentario que tiene nuestro script (arriba no aparece , pero en el de FSE si) : "/* Local variables which do not need to be saved between map changes. */ "
Entonces agregamos : "variable item; "
Cuando lleguemos mas adelante explicare porque hemos hecho esto , ahora continuemos :
Ahora separemos partes del dialogo para incluir hay dentro nuestro codigo para las quest . asi que ahora nos fijamos en (Si estais al loro de lo que estamos haciendo , veras que no hemos utilizado la linea 114 del MSG, esa la crearemos mas adelante):
EKCSQ.SSL >
// comienza el dialogo procedure node001 begin Reply(103); gSay_Option(NAME,104,node002,50); gSay_Option(NAME,105,node003,50); gSay_Option(NAME,106,node004,50); end
Te acuerdas que a nuestra variable goblar (GVAR_) le pusimos un 0 de numero inicial ? pues esa es el estado inicial de nuestra quest . Asi que establecemos una serie de numeros que nos dira en que estado esta nuestra quest .
En este caso lo he organizado de la siguiente manera (no hay que incluirlo en ningun lado , esto es simple organizacion) : - 0 = Sin hablar con torki - 1 = Quest solucionada
Para comprobar si la variable esta por defecto (osease , 0 , incompleta) utilizaremos la funcion "IF" y le preguntaremos que si la quest esta completada , muestre un mensaje diferente (aqui ya no entra el editor de conversaciones , si no vuestra propia maña al idenfiticar el codigo ) . Asi que lo comprobaremos con : "if (global_var(GVAR_TORKIQ_QUEST) == 0)"
No os alarmeis , quitando parentesis ... es como si le preguntaramos al juego : "SI (el global var (GVAR_TORKIQ_QUEST) es igual a == 0 )" Despues de esto , suele acompañarse de un "then begin" ... : "if (global_var(GVAR_TORKIQ_QUEST) == 0) then begin " Que traduciendolo a mi modo (siento decirlo asi pero es para que TODO el mundo lo entienda) : "SI (el global var (GVAR_TORKIQ_QUEST) es igual a == 0 ) entonces comenzamos "
Entonces nos vamos a nuestro cacho de codigo inicial donde comienza la conversacion y le añadimos el codigo que hemos comentado arriba :
EKCSQ.SSL >
// comienza el dialogo procedure node001 begin /* aqui le pedimos al script que compruebe si el estado de la quest es 1 , de ser asi es que esta completada , asi que llamamos al nodo 05 que es el que tiene el texto para cuando completemos la quest */ if (global_var(GVAR_TORKIQ_QUEST) == 1) then begin call Node005; // llamamos al nodo 5 * end // finalizar begin * else // funcion else * Reply(103); gSay_Option(NAME,104,node002,50); gSay_Option(NAME,105,node003,50); gSay_Option(NAME,106,node004,50); end
* 1 = Este codigo hara que como dice el comentario , si intentamos hablar con Torki , y la GVAR que tenemos asignada es 1 , significa que ya hemos ayudado a Torki en el pasado , asi que salta al Nodo de conversacion 5 que es el que contiene el texto al haber completado la quest . * 2 = Si hubieramos echo solo then despues del if , no habria hecho falta poner el END al final del comando , pero cuando se usa begin (comenzar) tiene que ir despues del codigo que queramos incluirle a ese begin , un END que indique ya no hay mas codigo que procesar * 3 = la funcion ELSE tiene que usarse cuando haces una llamada a la funcion IF ... Para que lo entienda todo el mundo es algo asi :
"SI (el global var (GVAR_TORKIQ_QUEST) es igual a == 1 ) entonces comenzamos // llamamos al nodo 5 FIN del entonces // end" si no se ha cumplido entonces // funcion else // comienza la conversacion normal FIN del entonces // end para el else"
VALE ! Ya tenemos solucionado un problema , y es que cuando acabemos la mision la volvamos a poder repetir ... Cosa que no gustaria nada verdad ? Ahora saltemos a la parte de comprobar si tienes un stimpak y que eliges hacer con el ! Ahora queda decirle lo contrario , que si la GVAR de Torki es igual a 0 , muestre el dialogo para poder suministrarle un stimpak ... Asi que usaremos una copia del codigo de arriba pero que se igual a 0 : "if (global_var(GVAR_TORKIQ_QUEST) == 0) then begin " Y se lo agregamos despues de ELSE , entonces como ya sabemos al utilizar un begin tambien tendremos que ponerle el end , por lo que el nuevo codigo quedara asi :
EKCSQ.SSL >
// comienza el dialogo procedure node001 begin /* aqui le pedimos al script que compruebe si el estado de la quest es 1 , de ser asi es que esta completada , asi que llamamos al nodo 05 que es el que tiene el texto para cuando completemos la quest */ if (global_var(GVAR_TORKIQ_QUEST) == 1) then begin call Node005; // llamamos al nodo 5 * end // finalizar begin * else // funcion else * if (global_var(GVAR_TORKIQ_QUEST) == 0) then begin Reply(103); gSay_Option(NAME,104,node002,50); gSay_Option(NAME,105,node003,50); gSay_Option(NAME,106,node004,50); end // finalizamos el segundo begin end
Nos fijamos ahora en esta parte del codigo :
EKCSQ.SSL >
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin Reply(107); gSay_Option(NAME,111,node999,50); end
Esta es la respuesta en la que le dices a torki que tienes uno y como buen ciudadano se lo das sin coste alguno para el . Asi que lo queremos es que compruebe si el jugador tiene Stimpaks , y en caso de que tenga , quitarle el objeto del inventario y darle una revista de Guns & Bullets como recompensa (y de paso algo de XP no ?) . asi que utilizaremos la funcion IF de nuevo acompañado de "(obj_is_carrying_obj_pid(OBJETO,PID_OBJETO))" que traduciendolo a mi charnego particular seria algo mas o menos asi : "SI (el objeto lleva un pid(OBJETO,PID_OBJETO)) entonces comenzamos " Para consultar el PID (prototype ID) de el stimpak puedes consultarlo abriendo el header (archivo .H en la carpeta HEADERS) "ITEMPID.H" . La linea que buscamos es la siguiente :
ITEMPID.H >
#define PID_STIMPAK (40)
Asi que cambiamos el codigo a lo siguiente : "if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin "
Traduciendolo a mi manera de programacion favorita que no existe : "SI (el objeto lleva un pid(YO MISMO,PID_STIMPAK)) entonces comenzamos " Podreis observar que el dude_obj ha sido cambiado por YO MISMO y es que dude_obj significa el jugador en si y no ningun otro NPC (si lo que quereis es darle el objeto a otra persona , por ejemplo a un miembro de tu equipo hay tendrias que poner su PID)
Comprendiendo ya como funciona el codigo de cargar el stimpak . Entonces lo aplicamos a nuestro codigo :
EKCSQ.SSL >
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin // codigo comentado arriba if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin Reply(107); gSay_Option(NAME,111,node999,50); end else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Nota : como necesito que el NPC diga tambien algo si no tenia stimpaks he copiado las dos lineas que tenian : Reply(107); gSay_Option(NAME,111,node999,50); Una vez pegado despues de ELSE . Y le he cambiado el numero a "reply(107);" por "reply(114);" que es la linea {114} en el archivo TORKIQ.MSG
Con esto conseguimos que el NPC compruebe si tenemos algun stimpak en el inventario , de ser asi , te dice una frase u otra . Pero , seguimos aun con este codigo ,ya que queda cambiar la GVAR a quest completada , restar un stimpak y sumar una revista en el caso de que la quest haya sido completada con exito . Para el primer proceso , cambiar la GVAR a 1 , para decirle al juego la siguiente vez que hablemos con Torki , nos diga un mensaje diferente ... (en el primer codigo hecho checkeamos que la GVAR sea 0 no la cambiamos ni nada) Para esto vamos a utilizar la funcion "set_global_var(QUE_GVAR,NUEVO_NUMERO); " Esperando que hayais cogido las bases , añadimos a nuestro ultimo codigo :
EKCSQ.SSL >
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin // codigo comentado arriba if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 Reply(107); gSay_Option(NAME,111,node999,50); end else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Bien ! Ahora ya tenemos que Torki , cuando acepte el Stimpak , cambiara el GVAR de la mision a 1 , cambiando asi la posibilidad de volver a repetir la mision , cuando comienze el dialogo y nuestro primero codigo checke si la GVAR es 1 , entonces saltara la otra conversacion ... Util eh ? Ahora pasemos al lado de restar un stimpak . Para esto usaremos la funcion : "destroy_object(obj_carrying_pid_obj(QUE_OBJETO, QUE_PID));" Esta es una combinacion de "obj_is_carrying_obj_pid" pero llamando primero a "destroy_object" que es la que se encargara de borrar determinado objeto . Asi que hay que modificarlo para que quede asi : "destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK));" asi que nuestro nuevo codigo quedara asi :
EKCSQ.SSL >
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin // codigo comentado arriba if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); //destruimos stimpak Reply(107); gSay_Option(NAME,111,node999,50); end else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Eh! Esto toma forma ! Ahora nos comprueba que tengamos stimpaks , y de ser asi , cambia el GVAR a 1 y encima borra el stimpak ! Ahora solo queda que nos de nuestra preciada recompensa , una revista Guns & Bullets ! Asi que nos vamos a ITEMPID.H y localizamos la citada revista :
ITEMPID.H >
#define PID_GUNS_AND_BULLETS (102)
Para crear objetos usamos la funcion "add_obj_to_inven(A_QUIEN,QUE_OBJETO);"
NOTA : Esta parte del manual ha sido rediseñada ya que pensaba que al agregar un objeto era tan sencillo como usar esa sentencia . Pero resulta que por alguna extraña razon , un script no puede crear un objeto de la nada , asi que necesitas "precargarlo" antes , en caso de no hacerlo , al usar por ejemplo : "add_obj_to_inven(dude_obj,PID_GUNS_AND_BULLETS);"
Hara que te salte un error y te tire a Windows (me he rebanado y he cambiado codigo del manual unas 7 veces ) Entonces , usaremos en conjunto de la funcion "add_obj_to_inven" la siguiente : "create_object(QUE_OBJETO,QUE_TILE,QUE_ELEVACION);"
En donde "QUE_OBJETO" es el pid (itempid.h) del objeto que queremos crear , "QUE_TILE" la baldosa que queremos donde se cree el objeto , tiene que ser en formato numerico (click a un tile del mapa para que te diga que numero es) y "QUE_ELEVACION" consiste en una de las 3 elevaciones que tiene cada mapa (nota ! se empieza a contar desde el 0 , asi que 0 sera 1 , 1 sera 2 y 2 sera 3). Como queremos que el objeto lo cree en un lugar temporal , para luego darselo al jugador , haremos este codigo :
"create_object(PID_GUNS_AND_BULLETS,0,0);"
Esto pondra el objeto en el la tile 0 y la elevacion 1 del mapper , que es el borde de arriba del todo , dudo que podamos ver ese objeto en el juego Pero hay una pequeña "complicacion" , y es que no podemos darle ese determinado objeto que hemos creado al jugador , sin decirle al juego que ese objeto es "uno en concreto" que vamos a usar ... ¿Os acordais de la variable que pusimos al principo? : "variable item;"
Pues es como una GVAR , la unica diferencia , es que estas se quedan en el mapa y no se guardan en ningun otro lado , pero en vez de definirlas en GLOBAL.H o similar , las tenemos que definir al principio del script , muy utiles ... Pues hay que "asignar" esa variable a la funcion de crear el objeto que mencionamos arriba ... y eso se hace asi : "item:=create_object(PID_GUNS_AND_BULLETS,0,0);"
Cada vez que asigemos una variable a una funcion tiene que ir seguido de := . Asi hemos hecho una especia de "macro" donde la variable "item" significa crear una revista Guns & Bullets en ese sitio ...
Ahora , mezclamos los dos codigos , pero le decimos a la funcion "add_obj_to_inven" que en vez de darle un PID , le daremos el macro "item" asi que tendremos este codigo :
Cachico de codigo >
item:=create_object(PID_GUNS_AND_BULLETS,0,0); add_obj_to_inven(dude_obj,item); // en este caso , en vez de pid , ponemos item
Aclarado como crear objetos sin error alguno , pasamos a agregarlo a nuestro codigo :
EKCSQ.SSL >
// Answer to: Claro ! Tengo uno aqui mismo! procedure node002 begin // codigo comentado arriba if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); //destruimos stimpak item:=create_object(PID_GUNS_AND_BULLETS,0,0); // Dar recompensa 1 add_obj_to_inven(dude_obj,item); // Dar recompensa 2 Reply(107); gSay_Option(NAME,111,node999,50); end else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Esto continua cogiendo forma ! y por fin tenemos esta parte completada , que es finalizar la quest , quitamos un stimpak , cambiamos el GVAR y a su vez añadimos una recompensa ! Ahora que queda ? Finalizar la quest de modo avaro ! (y asi de paso enseño como sumar dinero al jugador ) Asi que ahora nos fijamos en esta parte del codigo :
EKCSQ.SSL >
// Answer to: Si que tengo , pero te costara 100 chapas! procedure node003 begin Reply(108); gSay_Option(NAME,110,node999,50);
end
Esta es la parte que es llamada cuando elegimos la conversacion de que le costara 100 chapas el Stim ... Asi que utilizaremos una modificacion del codigo anterior agregando el cambio de GVAR y la destruccion del stimpak :
EKCSQ.SSL >
// Answer to: Si que tengo , pero te costara 100 chapas! procedure node003 begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); //destruimos stimpak Reply(108); gSay_Option(NAME,110,node999,50);
end
Espera juancho ! Estas a punto de cometer tu primer bug ! que ocurre en ese codigo ? Que das por sentado que el jugador tiene stimpaks en posesion , cuando ese valor solo lo hemos definido para la primera conversacion ! Por lo que intentar destruir un objeto que no existe podria probocar un comportamiento extraño en el juego . Asi que modificamos nuestro codigo agregando el "if (obj_is_carrying_obj_pid)" al principio :
EKCSQ.SSL >
// Answer to: Si que tengo , pero te costara 100 chapas! procedure node003 begin if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); //destruimos stimpak Reply(108); gSay_Option(NAME,110,node999,50); end /* ahora copiamos la parte que va despues del ELSE del anterior codigo ya que es una respuesta generica para decirle a Torki que no tenemos stimpaks */ else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Asi nos queda un codigo , que otra vez comprueba si el jugador tiene Stimpaks , pero como veis no da la revista , por que ? Porque no es el mismo ! Ahora toca agregar las chapas ,y para eso usamos la funcion "item_caps_adjust(A_QUIEN,CUANTO);" y asi cambiamos el codigo a : "item_caps_adjust(dude_obj,100); " Dato util : En caso de que queramos restarle dinero , solo hay que poner -cantidad ... Ejemplo : -3215 Asi que cambiamos el codigo por el nuevo quedando asi :
EKCSQ.SSL >
// Answer to: Si que tengo , pero te costara 100 chapas! procedure node003 begin if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); // cambiamos el GVAR a 1 destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); //destruimos stimpak item_caps_adjust(dude_obj,100); // damos 100 chapas de recompensa Reply(108); gSay_Option(NAME,110,node999,50); end /* ahora copiamos la parte que va despues del ELSE del anterior codigo ya que es una respuesta generica para decirle a Torki que no tenemos stimpaks */ else // si no tengo stimpaks entonces * Reply(114); gSay_Option(NAME,111,node999,50); end
Con esto conseguimos una segunda manera de acabar la quest ! Cambia la GVAR a completada , pero en vez de dar una revista , por ser avaro consigues solo 100 chapas . Tambien puedes agregar otras bonificaciones como las siguientes :
"give_xp(CUANTO);"
"critter_mod_skill(A_QUIEN,QUE_SKILL,CUANTO);" (los nombres de los skills los encuentras en DEFINE.H , linea 77) "critter_heal(A_QUIEN,CUANTO);"
Que dan diferentes bonificadores :
Ejemplo de bonificadores >
// Da al jugador 1000 de XP give_xp(1000);
// da un +20% a las small guns del jugador critter_mod_skill(dude_obj,SKILL_SMALL_GUNS,20);
// cura 46 pts de vida del jugador critter_heal(dude_obj,46);
Como veis agregar quests , una vez se coge el truquillo es bastante sencillo . Por lo que llenar una ciudad de gente con algo interesante que decir es bastante facil ! PERO ESPERA ! La cosa no ha acabado ! Vamos a probar este script ! Y asi de paso aprobechamos para demostrarte que Khorne no os esta haciendo perder el tiempo ! Haciendo un resumen (adaptando algunos comentarios , quitando espacios , etc..) de todo nuestro codigo , tendremos algo asi (no es necesario quitarle comentarios , pero tube algunos errores con comentarios mal puestos , y tambien lo hago adrede para salvar espacio en la pagina):
procedure look_at_p_proc begin script_overrides; if (local_var(LVAR_Herebefore) == 0) then display_msg(mstr(100)); else display_msg(mstr(101)); end
procedure description_p_proc begin script_overrides; display_msg(mstr(102)); end
procedure use_skill_on_p_proc begin end
procedure use_obj_on_p_proc begin end
procedure damage_p_proc begin end
procedure map_enter_p_proc begin end
procedure map_update_p_proc begin end
procedure talk_p_proc begin start_gdialog(NAME, self_obj, 4, -1, -1); gsay_start; if (get_critter_stat(Dude_obj, STAT_iq)>3) then call node001; else call node001; gsay_end; end_dialogue; end
procedure node001 begin if (global_var(GVAR_TORKIQ_QUEST) == 1) then begin call Node005; end else if (global_var(GVAR_TORKIQ_QUEST) == 0) then begin Reply(103); gSay_Option(NAME,104,node002,50); gSay_Option(NAME,105,node003,50); gSay_Option(NAME,106,node004,50); end end
procedure node002 begin
if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); item:=create_object(PID_GUNS_AND_BULLETS,0,0); add_obj_to_inven(dude_obj,item); Reply(107); gSay_Option(NAME,111,node999,50); end else Reply(114); gSay_Option(NAME,111,node999,50); end
procedure node003 begin if (obj_is_carrying_obj_pid(dude_obj,PID_STIMPAK)) then begin set_global_var(GVAR_TORKIQ_QUEST,1); destroy_object(obj_carrying_pid_obj(dude_obj, PID_STIMPAK)); item_caps_adjust(dude_obj,100); Reply(108); gSay_Option(NAME,110,node999,50); end else Reply(114); gSay_Option(NAME,111,node999,50); end
procedure node004 begin Reply(109); gSay_Option(NAME,112,node998,50);
end
procedure node005 begin Reply(113); gSay_Option(NAME,111,node999,50); end
procedure node999 begin
end
procedure node998 begin
end
Asi que ahora vamos a compilarlo ! agregarlo al juego y ver como funciona citada cosa ! Como he comentado arriba que tengas el archivo MSG llamado "TORKIQ.MSG" , ahora llamalo conforme vayas a compilar tu script , para agregarlo posteriormente al los defines y los headers necesarios (si no sabes de que estoy hablando , repasa esta parte del manual , para saber como agregarlos) Una vez este todo listo , compila el script , revisa esta parte si usas el BIS Compiler o esta otra si manejas FSE
Nota : Si tu script no se compila correctamente , revisa cualquier codigo que hayas escrito o copiado de la web , el script de arriba completo es una copia que he hecho del script del FSE antes de compilarlo , y no , no daba NINGUN error . Asi que si quieres puedes copiarlo de arriba y comprarlo con el otro haber que has escrito mal o que se te ha pasado por alto .
Una vez compilado el script , y agregado correctamente , nos vamos y le creamos una pequeño pero apacible sitio para nuestro amigo Torki (no hace falta que os compliqueis tanto era para darle calidad al manual PERO ASEGURAROS de agregar un stimpak cerca...) :
Ahora con la opcion de colocar Critters , selecionamos a nuestro colega Torki , y le damos al boton EDIT , seguidamente le damos al boton "script" de la ficha del critter , y seleccionamos el script "ekcsg " de la lista (darle a la tecla E del teclado para empezar a mirar desde esa letra , bastante util - si no aparece el script es que no esta registrado y definido correctamente) :
Le damos a DONE y yasta ! Ahora llega el momento de la magia beibe !! Dale a F8 para entrar en el modo de prueba ! Coges el stimpak y habla con Torki :
'>
Con esto acaba esta leccion de como crear quests....
Logicamente , este codigo es muy basico , pero te da los procedimientos necesarios para crear quests mas complejas . Ejemplos , estableciendo mas GVAR puedes hacer que la quest tenga varias partes , tambien que se enlacen otras GVAR , que al hablar con un NPC sobre algo, active una GVAR y al activarla , otro NPC activa otro dialogo para crear quests "diplomaticas". Tambien podeis pedir otro objeto , como algo "necesario" para reparar un objeto , etc... Ademas las funciones de agregar objetos , sustraerlos , cambiar las GVAR , crear variables , pueden usarse en todo el script , no solo durante la conversacion ... Como por ejemplo puedes hacer que cuando se ejecute la accion de pegarle a alguien te reste dinero (por decir algo! )
A - Crear conversacion con el FSE Que es de una mod sin que incluya alguna mision nueva o similar (ojo que este ejemplo puede usarse para hacer mas cosas que quests) , pues de esto se basa est