Variable permanente
Hola gente ya se que me quereis mucho y que no creeis que sea pesado… siiii ok ok preguntare menos, lo intentaré palabra… El caso es que he aprendido +/- a poner variables he hecho alguna misión y to (que ilusión…) pero… siempre hay peros, las misiones son para un mundo en internet y por tanto han de ser permanentes o lo que es lo mismo quiero guardar la misión para que el jugador no la vuelva a hacer nunca mas. Voy a poner una variable sencilla el caso seria que uno insulta a una mujer y evidentemente ella recordará que le ha insultado (que memoria que tienen
no se les olvida ni una mala). Bueno aquí va a ver si mi Idolo
me explica como tendría que cambiar la variable para que sea permanente. *Tras insultar en las acciones emprendidas guardo la variable: void main() { object oTarget = GetObjectByTag(“Tia”); SetLocalInt(oTarget,” insulto”,1); } *Si el jugador vuelve a hablar con ella mira si este tiene la variable, que va en el texto aparece cuando: int StartingConditional() { if(GetLocalInt(OBJECT_SELF,”insulto”) == 1) { return TRUE; } else return FALSE; } Creo sinceramente que el hecho de poner aquí explicaciones tan básicas como esas puede ayudar a otras personas que aún no saben por eso digo donde tienen que ir. Espero que no este haciendo nada malo. Gracias por ayudar.
Neverwinter Nights
Aqui creo que ya tienes que manejar bases de datos, para guardar en ellas las variables.
Si no recuerdo mal se utiliza SetCampaignInt, en os parametros hay que especificar el nombre la campaña, el de la variable, su valor y el nombre del pj. Puede ser Int, String, Float… dependiendo del tipo de valor.
Mi vida en el escrip se basa en ejemplos graficos contantes y sonantes
. Las palabrojas esas sueltas no me dicen nada lo siento.
bien, yo te oriento un poco con mi scriptingitaner, a lo de champain, usar las bases de datos hcr y esas cosas, eso dejalo pa los señoriiiiiitus (mas que nada por que no tengo ni papa
)
esta todo bien, pero no especificas si va dentro de un void main, o si utilizas el sombrerito de payo de conversaciones, si utilizaras el main seria algo asi como
if (Getlocalint tatata=1)
{
pasa esto
}
pero si usas el editor de conversaciones es mas facil, por que solo tienes que poner el nombre de la variable, el wizar lo hace todo, por eso no te va con el else, si usas startinconditional mmm
startingconditional
if (!Getlocalint lelelerele)= 1
return true
return false
no utilices este codigo que no va, es que no tengo instalao el nwn pero te haras una idea el condicional solo deja paso al gion de la conversacion de accion si devuelve true, el otro lo puedes usar el el gion de “ocurre esto”, y expandirlo mucho mas, con si vale 1 pasa esto, si vale 2 pasa esto , etc.
pero serte de ayuda, auque sea un poco gitano esta respuesta
Oye me has respondido a mi me parece que no…
Ya se que esas varables permanentes son cosa de niños mayores, pero no me queda mas cojones que conseguirlas, lo que estoy haciendo es un mundo permanente y nesesito variables permannetes.
si lo que quieres que la tia recuerde que en una conversacion el pj la insulto, es como dices, comprueba variable. pero tu lo has puesto que la almacene en el pnj, cuando lo que tienes que hacer es guardarla en el pj. si quieres que recuerde, es decir que esa variable no desaparezca……a ver , si me equivoco que alguien me corrija
una variable almacenada con setlocalint tipo
object oTarget = GetObjectByTag(“Tia”);
SetLocalInt(oTarget,” insulto”,1);
l
uego comprueba
if(GetLocalInt(OBJECT_SELF,”insulto”) == 1) {
//esta mirando si la variable de la tia vale 1, no la del jugador
insulto se guardaria en el pnj, en la tia vamos, pero si le ponesGetspeakerpc, donde dices otarget, la guardaria en el jugador.
si la guardas en la tia, cada vez que hable CUALQUIER pj con ella, comprobaria getlocalint “insulto”, otarget vale 1? pues claro, por que llego pepe y la insulto, al llegar manolo y decirla -bailas? la tia lee que insulto vale 1 y le manda a la mierda, y el pobre manolo no sabe ni de que va el rollo (te lo digo por que este finde me ha pasao eso, seguro que fuiste tu quien le puso la variable insulto a la rubia a 1, llege yo y me lleve la ostia)
pero si pones
SetLocalInt(Getpcspeaker(),” insulto”,1);
la guardaria en pepe, y la tia solo reconoceria a pepe como el que le insulto
al comprobar
if(GetLocalInt(getpcspeaker,”insulto”) == 1) {
si habla pepe, la tia ve que la variable de pepe vale 1, y sabe que la insulto, pero si habla manolo(este es el galan) vale 0 y sabe que no la insulto.
Y POR FIN FOLLO!!!!!!
mmm sigo el rollo, a ver si era esto lo que preguntabas
las variables se almacenan en objetos, en el pc, o en la tia, tambien puedes hacer generalizadas del modulo, getmodule, estas variables NO SE BORRAN, aunque el tio salga del server, insulto sigue valiendo 1, y las tias tienen mucha memoria pa estas cosas, si vuelve a entrar, y tu no pones nada de limpiar variables, sigue valiendo 1. Hasta claro, que CIERRES EL SERVER Y REINICIES. en ese caso se borran todas las variables, y el tio queda blanco e inmaculado para volver a insultar, a no ser que antes de cerrar el server guardes partida, luego en vez de reiniciar cargas partida, y las variables estan todas declaradas en su sitio
pero para eso estan el rollo de las hcr y el rollo del log, que es pa señoritus con buena nota, en el cual al cerrar el server, especifica que pepe tiene insulto que vale 1 y aunque reinicies el server desde 0, gracias al log o las hcr y esas cosas de los academicos y gente de buen entender, le mete insulto vale 1 a pepe, por mucho que se afeite, o se cambie de armadura, es decir, la insulto una vez, y aunque reinicies, la tia no lo olvida, pero de hcr no se muy bien como va
bueno, no se si era esto lo que pregunteabas….a lo mejor todo este rollo de las variables ya lo sabias
….saluditooooooss
Pues si me has entendido perfectamente, según iba leyendo mi cara iba cambiando de entender un poco a perderme
así mas o menos :

pero en fin auqnuesea si me aguanta hasta que se reinicie esta bien, si te he entendido bien lo que tengo que hacer es:
La frase culminante pepe, por mucho que se afeite, o se cambie de armadura, es decir, la insulto una vez, y aunque reinicies, la tia no lo olvida efectivamente no quiero que le olvide nunca, el motivo es que lo que hago es ajustar al jugador a una facción determinada (ajusto la reacción de las facciones a el mejor dicho) y para evitar que esto se pueda cambiar pensaba en hacer el ajuste permanente. Pero bueno un hombre puede soñar
+Tras insultar en las acciones emprendidas guardo la variable:
void main()
{
object oTarget = GetObjectByTag(“Tia”);
SetLocalInt(oTarget,” insulto”,1);
}
+Si el jugador vuelve a hablar con ella mira si este tiene la variable, que va en el texto aparece cuando:
int StartingConditional()
{
if(GetLocalInt(getpcspeaker,”insulto”) == 1){
return TRUE;
}
else return FALSE;
}
Sería asin?, por cierto no te desanimes con la variable de la pava esa quizás este finde hayan reiniciado el garito y puedas ligártela.
Define la variable al PNJ, y así siempre lo recordará. Si es para inet, necesitarás lanzar un acceso de registro a la BD para ke lo recuerde si el servidor hace ploff.
Acceso ? emmmm? comoooo?.
Per sis ten cia
El único tema que no controlo
U
Iris, no se la lies mas, que nosotros vamos a mas bajo lvl
Az-fox, si, vas encaminado, pero en lo qe has puesto, estaba mal
“tras insultaar guardo en acciones emprendidas”
void main()
{
object oTarget = GetObjectByTag(“Tia”); //aqui estas diciendo que buske
//al pnj por su tag
SetLocalInt(oTarget,” insulto”,1); //le has dicho que GUARDE LA
//VARIABLE EN EL PNJ, NO EN EL PJ, POR QUE no has declarado que
//objeto es el pj, otarget es la tia, noel pj.
}
aqui la variable estaria guardada entonces en la tia, y queremos que la guarde en el pj, si es en un archivo de conversacion y creo que es asi, en acciones seria
void main()
{
object oTarget = GetPcSpeaker();//declaras al pj como el que habla con
//la tia
SetLocalInt(oTarget,” insulto”,1); //le metes la variable al pj
}
para que compruebe en “el texto aparece si ocurre”
int StartingConditional()
{
if(GetLocalInt(getpcspeaker,”insulto”) == 1){ //mira si la variable del que
//habla vale 1, si fue pepe quien la insulto, pues como vale 1 devuelve
//true
return TRUE;
}
else return FALSE;
}
//pero si es manolo, devuelve false por que VALE 0, aqui los que hablan serian el getpcspeaker, para que entiendas que de la otra forma guardarias la variable en el objeto de la tia, y no en el objeto del que habla,(el jugador), mmm es decir varias variables pueden llamarse igual, mientras no esten almacenadas en el mismo objeto, no es la misma insulto para la tia, que para el jugador pepe, que para el jugador manolo
, insisto, si la tia tiene que comprobar quien tiene el moraton de la ostia del insulto….guardarias el moraton en la tia? claro que no, por que simpre tendria moraton, valdria 1, tienes que guardar el moraton en el tio que la insulto, para cuando vuelva a habar, le vea el moraton a EL , no a ella…juer, si es que ocntra mas me explico, creo que te estoy liando mas.xD
por eso….n se si te estoy liando
y el caso, si te vale para los reinicios, estas variables, se guardan hasta que reinicies o la pongas tu a cero, si guardas partida tambien se guarda la variable, si al grabar insulto valia 1, al cargar sigue valiendo 1, y el tema del log…..bueno, si esto te parece dificil, mejor lo dejamos, como las hcr, ya vienen todo explicao alli, pero eso es otro cantar.
creo que tu fallo es que no sabes diferenciar entre objetos, mira a los pnj y los pj como objetos, getpcspeaker, es el jugador que esta hablando con el pnj, bytag, ya le estas indicando un pnc, placeable, item, etc, pero no un jugador. bueno, analiza esto a ver si te aclaras
Gracias a los que me han contestado, mi fallo no es que no diferencie entre objetos, mi fallo es que no tengo ni la mas putisima idea de lo que hago, me limito a copy paste y a ver si cuela
. Ese es mi escrip ale ya sabeis el secreto de los no campeones niños no hagais esto en casa
.
Gracias por la ayuda gente.
setlocalint (Getpcspeaker,”insulto”)1,
ves, guarda la variable en el pj que habla.–
————–
luego para que la tia compruebe cada vez que hable con un jugador si este le insulto, en “el texto aparece cuando” eliges variable local, en entero pones insulto, que sea igual …y en entero constante pones 1. esto creara un startinconditional, para ver si es false o true
pero sera con
getlocalint (getpcspeaker”insuto”)=1,
si es uno, pasara a acciones, por que devuelve true, si ese jugador es el que la insulto, si ufera otro, como su varialbe vale 0 pues el sigiente texto no saldra, uffff, que mal escribo de rapido.
Venga. Me voy a arriesgar a que me consideréis todos un pedante de mierda. Pero ya veréis como a alguien le viene bien:
1) Lo primero: Llamemos a las cosas por su nombre. Lo que quiere hacer AZ_FOX se llama “persistencia”. Una variable persistente en NWN es aquella que conserva su valor, con independencia de si el servidor está levantado o no. Y eso se consigue guardando la variable (y su valor) en una Base de Datos.
Por otra parte, las variables locales (“SetLocalInt()”) sólo mantienen sus valores mientras el servidor está levantado. Asi que nos podemos olvidar de ellas si queremos que algo dure “para siempre”.
2) Las Bases de Datos se organizan en forma de tablas. Esas tablas tienen una serie de [i:7cdb72142b]columnas /i:7cdb72142b y una serie de [i:7cdb72142b]filas[/i:7cdb72142b] (llamadas “registros”). En el caso del NWN “normal”, los campos son “Objeto al que se le asocia la variable”, “nombre de la variable”, “valor de la variable” y otros que no nos interesan. Y digo “NWN normal” porque hay otros sistemas de persistencia (yo me he pegado ya con 3 - SAM’s persistant, NWN-DBase y NWNX-MySql).
3) Bien. Ya sabemos que hay funciones del estilo “SetCampaignInt()” y “GetCampaignInt()” [con sus parámetros correspondientes] que guardan o leen el valor de una variable persistente. Pero, como cada registro de la tabla de la BD exige que completemos todos sus campos, hay que asignar la variable a un objeto. Normalmente, a un personaje jugador. Asi, el mismo “nombre-de-variable-persistente” sirve para diferentes personajes… porque son registros [i:7cdb72142b]distintos[/i:7cdb72142b] en la Base de Datos.
4) No sé vosotros, pero yo paso de aprenderme de memoria todas y cada unas de las funciones del NWN. Para eso está la ayuda del editor de scripts y, mucho más claro, el Lexicon que tenemos [url=www.nwnlexicon.com/]aqui[/url]. La pega, claro, es que todo eso está en el más puro inglés.
Os aseguro que casi todo lo necesario para manejarse con la persistencia está en este mensaje… y en el Lexicon
. Pero recordemos que los scripts, en el fondo, no son mas que programas. Uno debería conocer sobre qué piezas está trabajando o las cosas no funcionan casi nunca.
Y, si, la culpa es de Bioware por darnos un juego tan alucinante y dejarnos huérfanos de documentación.
Un saludo.
PD: Imrishale, te juro que habría acabado antes poniendo el script resuelto.
Pero luego no me pasas ni una… 
Muy bien explicado, pero el asunto esta en que nadie sabe como manejar las bases de datos esas ni como hacer la persistencia en el log.
Y aunque no venga a cuento, y como estoy desesperao, una pregunta.
intento hacer una pocion que recupere los usos de feats y spells de un pj sin necesidad de descansar, he logrado que se recuperen los feats como familiar, etc, gracias a la función incrementremaingusesfeat, pero no logro hacerlo con los spells, por que solo hay una funcion para decrement, intente hacerlo con forcerest, y se recupera todo, pero el rollo esta en que si el pj se ha echado un piel robliza, al ser como un rest normal, pierde todos los efectos que se haya echado encima, como el piel robliza y demas, y lo que intento es que recupere sus usos de hechizos como un rest se tratara, pero sin perder los efectos que tenga el pj encima, no se me ocurre ya nada, se te ocurre algo para ayudarme?¿
[quote:af6933d093]Me voy a arriesgar a que me consideréis todos un pedante de mierda.[/quote:af6933d093]
En NwNSpain nadie tacha a nadie de nada (excepto a mi de lioso, pero hago la vista gorda, o no…
).
Aquí estamos todos para aprender (si, incluso yo), por lo que no tengáis miedo de comentar lo que creáis oportuno, que aquí se os respetará. y se os dirá si lo que habéis dicho es coherente o “de lo otro”, jejeje.
Venga, un saludo
[quote:6a7497d33d=”Ender_spain”]Muy bien explicado, pero el asunto esta en que nadie sabe como manejar las bases de datos esas ni como hacer la persistencia en el log. [/quote:6a7497d33d]
Vale. Lo primero es [i:6a7497d33d]saber[/i:6a7497d33d] que hay una Base de Datos [b:6a7497d33d]externa[/b:6a7497d33d] al juego, que se queda ahí aunque el servidor se caiga.
Lo segundo es, como ya he dicho, tener una idea de cómo se organizan las cosas en la BD.
Lo tercero es decirle a nuestro módulo cómo se llama la BD que vamos a usar (porque podemos tener varias BD de nombres distintas). Esto se hace en el script asociado al evento OnModuleLoad (ver el Lexicon).
Y lo último es usar las funciones del tipo “campaign” para leer, escribir y borrar datos en la BD. Estas funciones están documentadas en el Lexicon.
Esas son todas las piezas de la persistencia (de Bioware, claro - otras son MUCHO más complicadas). No hay más.
[quote:6a7497d33d=”Ender_spain”]Intento hacer una pocion que recupere los usos de feats y spells de un pj sin necesidad de descansar, he logrado que se recuperen los feats como familiar, etc, gracias a la función incrementremaingusesfeat, pero no logro hacerlo con los spells, por que solo hay una funcion para decrement, intente hacerlo con forcerest, y se recupera todo, pero el rollo esta en que si el pj se ha echado un piel robliza, al ser como un rest normal, pierde todos los efectos que se haya echado encima, como el piel robliza y demas, y lo que intento es que recupere sus usos de hechizos como un rest se tratara, pero sin perder los efectos que tenga el pj encima, no se me ocurre ya nada, se te ocurre algo para ayudarme?[/quote:6a7497d33d]
Si lo entiendo bien, querrías hacer un descanso sin descanso. ¿No?. Vas bien, pero si fuerzas el descanso, éste hace que se pierdan todos los [i:6a7497d33d]efectos[/i:6a7497d33d] que tenga el PJ. Asi que los tienes que haber [b:6a7497d33d]guardado antes[/b:6a7497d33d] de forzar el descanso. Mira una posible secuencia para el script asociado a la poción (o el script de OnActivateItem, si quieres):
a) Antes de nada, miras qué efectos tiene el PJ. Cómo no sabes a priori cuántos van a ser y en NWN no hay listas dinámicas, yo contaría primero los efectos válidos.
b) Ya sabes cuántos efectos tiene. Puedes usar tantas variables temporales de tipo string como efectos tenga el PJ para guardar qué efecto es cada uno.
c) Fuerzas el descanso.
d) Le aplicas cada uno de los efectos al PJ hasta que los tenga todos de nuevo.
e) Borras las variables temporales de tipo string asociadas al PJ.
Si. Esto es bastante ineficiente y posiblemente haya formas más directas de hacerlo, pero asi, de pronto, es lo que se me ocurre.
Un saludo.
Gracias deor, no escrito antes por que estaba liao con lo del descanso sin descanso. Tambien se me ocurrio el rollo de poner todos los efectos como extraordinary para que no los borrara, pero era mucho lio y al final no me sale.
Por cierto, es que de las bases de datos no tengo ni idea, si uso las funciones de persisten y champain, ¿No se graban en el lo? la bd no es el log del nwn? es qeu no tengo ni idea, a ver si va a ser un programa que hay que meter.
Te agradeceria mucho qeu me pusieras un ejemplo como guardar una variable en un pj, que se la de al salir, y luego al entrar se la reconozca.
bueno se que si se la das antes de salir, si no reinicias la guarda, pero si la pones en el clientleave, no la mete al pj.
Como seria un ejemplo para eso? una variable que guarde al salir..por que yo alponerlo en el leave no me la guarda,
y como seria un ejemplo para la bd, para los reinicios carge la variable otra vez en el pj? Si es con el log, mejor, por que no se ni como, donde estan, como se meten, las bd en el nwn. Siempre crei que se referian al log del nwn
Venga un sludo y gracias.
A vé, en el nwn se pueden guardar numeros enteros ( int ), fraccionarios ( float ), letras ( strings ) , objetos ( object ) y localizaciones de mapa (location).
Existen dos formas de guardar estas variables, una forma local ( es una forma rapida de guardar datos, pero si se cierra/peta el nwn se borran y otra forma persistente ( campaign ) que se guardan los datos aunque se pete el nwn pero es lento.
Bien, la forma de usar las variables locales es relativamente sencillo, hay dos tipos de funciones, el primer tipo es el de preguntar datos locales y el segundo es el de modificar datos o crear datos locales, en el caso de enteros son las siguientes funciones :
int GetLocalInt(object oPC, string sNombre)
void SetLocalInt( object oPC, string sNombre, int iValor);
Bien que hacen estas funciones, pues asociar a un objeto, bien puede ser una espada, un jugador, una puerta, el modulo, una area….lo que sea pero que sea objeto, pos eso asocia al objeto un valor de tipo entero. Así pues si ponemos el siguiente script, en el evento OnUsed de un ubicado.
void main()
{
object oJugador = GetLastUsedBy();
objecto oUbicado = OBJECT_SELF;
if ( GetLocalInt(oUbicado, “PALANCA”) == 1 )
{
SendMessageToPC(oJugador, “Has movido la palanca hacia arriba”);
SetLocalInt(oUbicado, “PALANCA”, 1);
}
else
{
(estoy escribiendo este post desde la universidad, no tengo ni flowers de si chutará esto)
El funcionamiento es sencillo, de este script y deberías entenderlo, al menos intentar traducirlo a castellano y vereis que hace, si está bien el script se dedica a suponer una posible palanca de un ubicado que si estaba arriba la pone abajo y si estaba abajo la pone arriba, y pa eso se usan variables de tipo local. Que ocurre si se chapa el servidor, pues que esa variable palanca se vuelve a 0 en cuanto el servidor se ponga de nuevo. De hecho cualquier variable que se crea, imaginemos que hacemos un GetLocalInt a una variable que no se ha creado, pues por defecto valdrá 0.
Bien y si queremos hacer que esa variable sea persistente, pues en vez de usar las funciones GetLocal y SetLocal usaremos las funciones GetCampaignInt y SetCampaignInt
int GetCampaignInt(
string sCampaignName,
string sVarName,
object oPlayer = OBJECT_INVALID
);
y
void SetCampaignInt(
string sCampaignName,
string sVarName,
int nInt,
object oPlayer = OBJECT_INVALID
);
Diferencias a la hora de usar estas funciones con las Locals, pues que tenemos que decirle a la función un valor nuevo de tipo String que es ni más ni menos que el nombre de la base de datos^^ no os compliqueis la vida, se pueden crear tantas BBDD como se quieran.
Bueno espero haber sido de gran ayuda^^
===»> Estooooo alguno me dirá algo como APS/NWNX,……no he dicho nada por no complicar la vida aún más
Os pongo varias páginas
www.nwnlexicon.com pa buscar esa funcion que no encuentro del nwn o enterarme que hace tal función
sourceforge.net/projects/apsnwnx/ por si alguien se quiere enterar de que es eso del aps/nwnx
Enga chau
Por cierto Un saludo, mucho tiempo sin verte surdo.
Mas o menos las variables persistentes se como se declaran, y creo que incluso me hago a la idea de que se cargan desde el onmoduleload.
Ahora ya se que se declara la base de datos como variable tipo string, pero no se donde, y que se puede poner con el nombre que tu quieres, ok
Pero lo que no se
¿esa base de datos como se guarda, y que tipo?¿Es un txt? ¿O hay que usar acces?¿Como cargo la base de datos luego al poner el server? Desde el onmoduleload supongo, pero ¿Como se salva? ¿La base de datos no es el log, o puedo usarla como base de datos?
Bueno, un saludo y gracias, no te veia desde el hispania
Bueno, espero que se me entienda porque tuti esto lo digo de cabeza pero si lo llego a explicar bien, es una de las formas de montar una base de datos de forma muy sencillita^^
==> Existen dos formas de montar una base de datos, una es usando las funciones Campaign del propio Neverwinter y otra usar las funciones llamadas APS junto con la aplicación nwn2x.exe^^
Para la primera, te recomendaría usar el sistema ASG aquí te pongo su página y trasteas con esos scripts, simplemente es una serie de funciones que pasan variables persistentes a variables locales y viceversa.
nwvault.ign.com/Files/scripts/dat…
no he visto su pagina principal por ningun lao^^ diria que existe para hotu pero total solo es actualizar esos scripts y au^^
Para la última, y personalmente, el mejor sistema de base de datos que hay^^ la única pega es que hay que saber un pokitin de lenguaje sql^^
Hay que hacer lo siguiente^^
sourceforge.net/project/showfiles… />
Mirar lo que hay ahi^^ y para la proxima vez que venga paka^^ os cuento un par de cosas para hacer que no chupe na de ram^^
Lo estoy mirando por encima y creo que era esto lo que buscaba, voy a pasar el .mod al otro ordenador y a sacar los ejemplos, me quedo con la primera forma, que la otra por ahora del sql me parece mas complicada, gracias y te debo un beso