Neverwinter Nights
Menú
Gamersmafia es ahora un archivo de solo lectura.

tesoros para el grupo

Me gustaría hacer que un cofre diera tesoro para cada uno de los jugadores de un grupo, osea que no solo el primero en abrir se lleve to el pastel sino que haya mas o menos lo mismo para cada uno y si llega mas tarde otro jugador en un grupo diferente que tambien encuentre algo. No sé si alguien tuviera una idea d como hacerlo y pudiera alumbrar mi camino le estaria muy agradecido

Mira, para la generacion del tesoro puedes usar los scripts de bioware.. que tienen los cofres por defecto… y modificarlos a tu antojo.

Para que el tesoro sea para todos.. puedes hacer con variables locales.. cuando un jugador abra un cofre se generara el tesoro (aleatoriamente o no) y se le asignara una variable, si lo vuelve a abrir como tiene la variable pues no se genera nada… pero si lo abre otro si… no es muy complicado de hacerlo y hasta quiza haya una forma más optima pero ami se m ocurre esto

Si ves que las variables es algo aun complicado, lo que también puedes hacer que, en el evento OnClose del cofre, se regenere el tesoro.

Eso si, da tesoros pequeños, ya que si no el PJ podrá estar “eternamente” abriendo y sacando cosas… y eso no es lo que queremos, ¿verdad?

Si Imrishale me lo permite… te remitire a un articulo de la web que estoy creando… aunque aun no esta “abierta” pues aun la estoy acabando… hay un articulo donde habla de como funcionan las variables…

[Aqui” href=”https://www.joanmadrid.net/universonwn/docs/Estableciendo_Variables.pdf]Aqui”>www.joanmadrid.net/universonwn/do…</a> el articulo ]

Sino entiendes algo puedes comentarlo

PD: por si hay algun mal pensado… es un tutorial oficial de bioware sobre iniciacion al NWNscript.. que traduci para la web. No me atribuyo el merito de este tutorial… solo de haberlo traducido..

Gracias a los dos, oye muy bueno el tuto de variables, avisa cuando tengas la web ! Bueno me ha salido algo así:
//onOpen del cofre

void main()
{

object oPC = GetLastOpenedBy();

if (!GetIsPC(oPC)) return;

int nInt;
nInt=GetLocalInt(oPC, “nCofreAbierto”);

if (nInt == 0)
{
CreateItemOnObject(“nw_wdbmax009”, OBJECT_SELF);
SetLocalInt(oPC, “nCofreAbierto”, 1);
ActionWait(300.0f);
DeleteLocalInt (oPC, “nCofreAbierto”);
}
}

Me compila bien pero no lo he podio probar pq lo he hecho en el curro, de todas maneras le puse que genere un item concreto, como sería para un tesoro alto pero aleatorio? Luego guardo en el PJ la variable con valor 1 y me interesa q en un tiempo determinado (le puse 300 pero lo suyo es mas) ese PJ pueda volver a encontrar tesoro, osea q borro la variable, como lo veis?
El problema que veo es que tendria q hacer un script diferente por cada cofre que kiero similar, pq si no el PJ al abrir el 1er cofre la variable pasa a tener valor 1 con lo cual al abrir el 2o cofre no encontraría nada.
Podría añadirle esto:

else
{
SendMessageToPC(oPC, “No seas avaricioso ya cogiste lo que había”);

}

Mas que nada porque me entró la duda de si debo cerrar el if con un else o puedo dejarlo sin el.
Otra opcion sería guardar la variable en el cofre, no sé a ver si mañana pruebo en casa q toi cansao.

Hombre, trescientos segundos está más que bien, pero bueno, jejeje. Lo que puedes hacer es, asociar la variable al cofre, y no al PJ. Es decir, que sea el cofre el que recuerde la variable del PJ, y no el PJ quien vea su variable. Así evitas que en distintos cofres, sea la misma variable la que organice.

Para el tesoro alto aleatorio, fíjate en el script de items altos aleatorios del NwN, que allí viene muy bien explicado.

“Lo que puedes hacer es, asociar la variable al cofre, y no al PJ

Así lo que tendría que hacer sería guardar quién abre el cofre y cuando lo abre para entonces generar tesoro si han pasado 300 segundos no?
Ya que la idea es que si otro PJ lo abre inmediatamente después, haya tesoro. Pff esto ya es mas complicao para mi, no se que comandos son mejores para identificar al PJ, GetPCPlayerName, GetTimeHour…

Por cierto Lagarto, un apunte del PDF: cuando pone “el jugador completa la misión…El PJ vuelve cuando ha hecho lo que el PJ quería…” debería ser “…lo que el PNJ quería” no?

bueno supongo… , por cierto la web, aunque no esta 100% acabada, ya esta operativa… [url]www.universoNWN.com[/url]

Bueno, tras varios intentos sin éxito me puse a empezar de 0, planificar bien el script, lo que pasa es que no se si la idea se puede hacer en un script:
1- En el onOpen del cofre iría un script que primero comprueba si el que lo abre es un PC y si es asi hacer que el PC ejecute un script que explico en el paso 3.
2- En el onClose del cofre va otro script que identifica al PC (su nombre) y guarda este dato durante por ej. 300 segundos, luego se borraría. (lo que no se si es posible guardar esos datos y cuantos podria almacenar, ya que la idea es que si mas de 1 abre el cofre se puedan guardar esos datos tambien).
3- El PC al abrir el cofre comprobaría si su nombre está almacenado en el cofre y si no está se generaría el tesoro.

A ver si alguien me puede decir si es posible y darme alguna pista
Gracias !!

Si, la idea es esa. Lo de guardar info puedes guardar una variable en el cofre con el nombre de PJ.

El planteamiento está bien, pero ahora te falta decidir cómo vas a hacerlo. Si nos basamos en la persistencia (que yuyu), pues podemos almacenar dicha variable de un modo algo más “sencillo” (si se sabe de persistencia).

Pero suponiendo que no queremos nada de persistencia, pues bueno, podemos basarnos en el archiconocido sistema de “almacén de datos en modo ubicado”.

La traducción a cristiano sería algo así como un ubicado, colocado en un área especial para cositas del módulo, en el que se almacenarían todos los datos.

¿Cómo funcionaría? Pues sería el que almacenase todos los datos de los cofres, y no cada cofre. Por ejemplo, el PJ abre el cofre y se lleva lo del interior. Pues en el ubicado de registro, se grabaría el dato del TAG del cofre, el nombre del PJ por cuenta y la variable, que a los 300 segundos, se borraría.

Así tenemos todo unificadito, y siempre podemos recurrir a un sólo lugar para el control de las variables.

Eso si, cada cofre con un TAG distinto, por favor

yo nunca habia oido hablar del ubicado base de datos , aunque no es mala idea no

Lo bueno es que así sólo tienes que ir asignando los datos al mismo objeto, por lo que si hay algún error, ya sabes a donde acudir : D

Pues el tema es que eso ha sido utilizado desde los albores del NwN, así ke… Sin ir más lejos, Nordock lo usaba, en el área llamado TEST AREA, y muchos otros módulos también

Esto no os va a gustar nada.

Lo primero: De verdad que la persistencia no no requiere nada más que un poco de cuidado, amigos. Se maneja casi igual que las variables locales y sólo hay que decirle antes al módulo qué BD vamos a usar (script del evento OnModuleLoad) poniendo la línea
[code:1:1c2b9cccdb]
SetLocalString(GetModule(), "X0_CAMPAIGN_DB", "");[/code:1:1c2b9cccdb]

Luego, todo son llamadas a SetCampaignInt(), GetCampaignInt(), DeleteCampaignInt() y las funciones de los restantes tipos de datos. Lo prometo.

—***—

No obstante, para generar tesoros para cada miembro del grupo tengo una solución funcionando… que no requiere persistencia ninguna. Como está “prohibido” (con muy buen criterio, quizá) pegar aqui scripts con soluciones, os cuento como va:

1) En el OnOpen del cofre, preguntamos por una variable local asociada al PJ. Si vale “1”, simplemente no hacvemos nada (o sea, que no hay tesoro). Si vale “0”, llamamos a la generación de tesoro Y ponemos esa variable local a “1” [i:1c2b9cccdb]para ese personaje[/i:1c2b9cccdb].

2) En el script del evento OnHeartBeat del módulo, preguntamos si la variable local de cada PJ es [i:1c2b9cccdb]mayor que[/i:1c2b9cccdb] 0. Si es así, arreglamos que se aumente en 1 la variable local, hasta que alcance un cierto valor. Por ejemplo, si la variable vale 10 cuando decidimos borrarla, habrán pasado 6x10 segundos. En ese punto, al hacer que valga “0” (pues está borrada), el PJ podrá volver a abrir el cofre y tener tesoro al cabo de 1 minuto.

Evidentemente, se necesitan tantas variables locales de cofre como cofres queramos controlar. Personalmente, con 20 variables para tesoros bajos y otras 20 para tesoros medios, os aseguro que el módulo no se ralentiza casi nada. Basta con hacer que cofres en extremos separados del módulo compartan la misma variable local, ya que es complicado que el mismo PJ esté en esos lugares a la vez.

—***—

Para tesoros altos y especiales, hay un sistema mejor (introducido con SoU), aunque mucho más complicado. Se basa en usar un “contenedor de referencia” en el que meteremos, digamos 10 objetos. Ha de estar en un área a la que los jugadores no tengan acceso, por supuesto. Sin más que controlar etiquetas de los contenedores, en el cofre del tesoro aparecerán hasta 3 de los objetos que estén en el contenedor de referencia.

La ventaja más alucinante de este sistema es que los DM’s pueden cambiar los tesoros posibles para los PJ’s, sin más que quitar o poner objetos en el contenedor de referencia.

Y, como fin de fiesta, se puede mezclar el sistema de “tesoro para todos” con el de “contenedor de referencia”. Eso es justo lo que hicimos nosotros en nuestro PW.

Ya os digo, es complicado. Requiere estudiarse muy bien el script “x0_i0_treasure”. Pero trae cuenta, la verdad.

Un saludo.

cito :

SetLocalString(GetModule(), “X0_CAMPAIGN_DB”, “");

Luego, todo son llamadas a SetCampaignInt(), GetCampaignInt(), DeleteCampaignInt() y las funciones de los restantes tipos de datos. Lo prometo.


Vale, pero luego cuando reinicio el server, como hago para cargar una variable guardada en un pj, volversela a cargar al mismo pj cuando reinicio el server? …..es que no tengo nada claro, no se ni donde guarda la informacion, supongo quue en el log,pero yo estao mirando y no he visto mas que entradas y salidas de jugadores y bichos muertos

El truco es pensar en eventos, Ender_Spain.

Cuando tu reinicias el servidor, es produce el evento OnModuleLoad. Pero, en ese punto sólo tiene sentido cargar variables persistentes [b:127917366e]del módulo[/b:127917366e] (como pueden ser la fecha y la hora). No hay personajes, quiero decir.

Imagina que entra un jugador/personaje. Ahora se produce el evento OnClientEnter. Y es justo ahí (en su script asociado, claro) cuando has de cargar tantas variables persistentes como sean convenientes.

Pero mejor aún: Las variables persistentes no tienes porqué preocuparte de ellas hasta que no las necesitas. Imagina una variable persistente entera que sea “estado de la quest número 14 para un personaje”. ¿Para qué preocuparse de cuánto vale si el jugador entra a matar bichos y no hace nada relacionado con quests?.

Sólo en el caso de que un personaje hiciera algo (una conversación, matar a un monstruo determinado… un evento conocido, a fin de cuentas) relacionado con la quest número 14, entonces podriamos preguntar por esa variable o cambiar su valor. ¿No estás de acuerdo?.

—***—

No. Los datos persistentes no se guardan en el log. Eso se hacía antes de NWN 1.32 (yo recuerdo algo llamado “SAM’s Persistant World”). Desde esa versión de NWN, ya se guardan en una base de datos con estructura dBase, que estará en la carpeta “database” del servidor.

Hay sistemas de base de datos mucho más potentes que guardan los datos persistentes en bases de datos Access (que acaban explotando) y MySQL (las mejores, en mi opinión). Pero, el NWN estándar usa el formato dBase que he comentado antes.

Y, de verdad, de esto no hace falta preocuparse. Uno le dice al módulo cómo quiere que se llame la BD, y si no existe, la crea por su cuenta.

El problema, una vez todo montado, es mantener los datos de la BD. Cambiarlos a mano, vaya. Ahí es donde empiezan los auténticos problemas del sistema de Bioware/dBase. Pero como eso es gestión de un mundo persistente más que programación de un módulo, no digo más.

Un saludo.

No es por molestar pero… creo que esto se va ya desviando un poco a la sección de scripting, ¿no creéis?

Si preferís seguir por estos derroteros, podemos hacer un movimiento de post, y todo tan ordenadito como siempre

Aparte, a ver si le damos ya una buena respuesta al chaval, que debe de estar flipándolo

Gracias, voy a probar a ver, y si ….creo que esta misma cuestion la llevamos tambien en scripting, donde me ha respondido Surdo, y a ver si me aclaro un poco, creo que para crear la base solo hay que declararla como string…..creo……hay una funcion que servia pa eso creo…..o esto ya lo he escrito antes……en scripting……..donde vuelvo a preguntarl lo del log…………

Los más activos en Aurora Toolset