Ninfablanca

30/12/2005 03:10:12

Bueno, a ver como lo explico, he logrado (para mi ha sido duro XD) que al usar una forja te habra una conversación y te pregunte que quieres fundir, alli seleccionas el metal que quieres usar y si lo tienes(y tienes además el molde) inicias la fundición, cambiandotelo por un lingote.
Ahora, dado mi bajo nivel de programación, me gustaría saber como hacer un par de cosillas.

-Lo primero es que el pj por ejemplo, desde esa acción emprendida haga una tirada de constitución+nv de herrería (que vendría a ser una variable) cd20 por ejemplo, y si la supera ya que le dé el lingote.

-Lo segundo es referente a esa variable (que supongo que será una variable) Me gustaría que aumentara cada ciertas fundiciones o algo así, pero la pregunta es si ese valor desaparece al reiniciar el servidor, y si es así, que puedo hacer para que se mantenga.

Asias por todo chicos, os estoy haciendo trabajar ultimamente jeje, espero que podais contestarme.

30/12/2005 10:59:40

Para la primera pregunta hay una funcion que se llama GetAbilityModifier que pilla el bono de la caracteristica que desees, para habilidades esta GetSkillRank, una vez guardas eso en una variable le sumas 1d20 con la funcion d20() y ya lo tienes.

Para guardar cosas permanentemente lo mas rapido y sencillo es usar la base de datos de neverwinter con el conjunto de funciones GetCampaign y SetCampaing, funcionan como el GetLocal y el SetLocal, pero para una base de datos.
por ejemplo

SetCampaignInt("NOMBRE_BASEDATOS", "XP_Forja", 100, oPJ);

esto graba en la base de datos llamada NOMBRE_BASEDATOS una variable llamada XP_Forja con un valor de 100 y ademas esta variable con este valor es para el jugador oPJ

mviper

30/12/2005 13:46:20

Un pequeño apunte.... la base de datos donde guardas esos datos... no existe, se crea la primera vez que guardas el modulo con un script de base de datos (¿o era al guardar el script?.. beuno eso es igual).

Me explico, alli donde Althor a escrito

[quote:12e70f086a]
SetCampaignInt("NOMBRE_BASEDATOS", "XP_Forja", 100, oPJ);
[/quote:12e70f086a]

La palabra "NOMBRE_BASEDATOS", es la que a ti te venga mejor para llevar un control sobre esa base de datos... pero recuerda siempre respetar las comillas.

Por ejemplo, en mi modulo io uso una base de datos llamada "bdbanco" para que los pjs guarden el dinero en un banco y tras el reinicio no lo pierdan, ademas tengo otra base de datos llamada "bdIsnar" donde guardo variables de miscelanea, como por ejemplo el control de entrada y salida para los hechizos y demas, tengo otra llamada "bdInqui" donde agrupo a los pjs que se hacen de la inquisicion....

Otra para los pjs del ejercito... etc... y una ultima que utilizo para que los pjs puedan escribir mensajes en un tablon de anuncios que hay en la ciudad.

Es decir... puedes usar tantas bases de datos como desees, y ponerles el nombre que mas se te antoje, es util darles un trabajo especifico a cada base de datos para despues tener un mejor control sobre ellas (sobre todo si quieres entrar dentro y borrar o escribir algo usando un programa externo al nwn). Por ejemplo, en mi caso la base de datos que uso para los mensages en el tablon, la borro cada semana, y no interfiere en absoluto sobre los datos en el resto de bases de datos del servidor.

Un ultimo detalle... no uses los comandos Campaing en script que vallas a poner en OnHeartBeat, sobrecarga de sobremanera el servidor

P.D. El valor 100 indicado en la linea dada por Althor es un int es decir, no tienes porque poner un numero, puedes poner un valor de int, asi pues puedes recoger el valor guardado del pj en la base de datos con un
int iHer=GetCampaingInt(oPC);
Sumarle los nuevos puntos que adquiere:
iHer=iHer+100;
Y despues guardarlo de nuevo en el mismo sitio, borrando el valor antiguo:
SetCampaignInt("NOMBRE_BASEDATOS", "XP_Forja", iHer, oPJ);

Lo de "XP_Forja" tambien puedes ponerle el nombre que desees (entre comillas), y dado que es un string, puedes usar ... eso un string para ello (por ejemplo string sNom=GetName(oPC);
SetCampaignInt("NOMBRE_BASEDATOS", sNom, 100, oPJ);
Con eso te aseguras que el valor es guardado con el nombre del pj, por sdi las moscas.. o incluso puedes decir que sNom=sNom+GetPlayerName(oPC); y de esa forma sNom, guarda el valor con el nombre del pj y del jugador, evitando que otro pj con el mismo nombre robe o modifique el valor.)

Bueno... solo era una pequeña aclaracion, ... (¿porque siempre me salen estas parrafadas?)

Ninfablanca

30/12/2005 14:39:30

jeje gracias a los dos, a ver que tal se me da ;), ya os iré diciendo.

Ninfablanca

30/12/2005 18:54:31

Puff que lio, soy demasiado torpe aun para esto jajaja... no en serio lo he mirado y cuando no me da un error me da otro, mira, os pongo aqui el script y me decis vosotros porfavor. En si la función es detectar si tienes el oro crudo y trabajarlo hasta convertirlo en un lingote, a la tirada que hace le falta sumarle el valor del nv de herreria del pj, que han de grabarse en la base de datos. Luego cada vez que realice un lingote (donde te comunica que la fundición ha sido exitosa) ha de sumarle 1 a una variable que actuaría como la experiencia del oficio, y que llegada a cierta cantidad añadiría 1 al nv(Esto se más o menos como hacerlo, pero no como guardarlo porque eso de la base de datos me ha dejado de hielo)

void main()
{

object oPC= GetPCSpeaker();
int nDado=d20();
int nRangos=GetAbilityModifier (ABILITY_CONSTITUTION, oPC);
int nTotal=nDado+nRangos;
string sDado=IntToString(nDado);
string sRangos=IntToString(nRangos);
string sTotal=IntToString(nTotal);
string sCaracteristica="Constitucion";
string sOro=GetName(GetPCSpeaker())+"Oro crudo";
object oOb=GetFirstItemInInventory(GetPCSpeaker());
while (GetIsObjectValid(oOb))
{
if (GetTag(oOb)=="met_oro")
{
DestroyObject(oOb); oOb=OBJECT_INVALID;
AssignCommand( oPC, SpeakString("Prueba de "+sCaracteristica+", resultado: "+sDado+" Modificador: "+sRangos+" = "+sTotal+" CD:25"));
if (nTotal>=25)
{
CreateItemOnObject("ling_oro", GetPCSpeaker());
SendMessageToPC(oPC,"La fundicion ha resultado existosa");

}
if (nTotal<=25)
{
SendMessageToPC(oPC,"La fundicion ha sido un fracaso");
}
}
else oOb=GetNextItemInInventory(GetPCSpeaker());
}

}

mviper

30/12/2005 20:00:54

Primero el script con las variables y demas lineas para incluir en una base de datos... lo notaras un poco cambiado.... con este escript chequeas todos los objetos y haces una tiarda por cada lingote que encuentra, asi si el pj lleva 10, hace una tirada por cada uno.

Tambien esta incluido que aumente la experiencia de herrero en cada lingote que fabrica.

[code:1:9bc5c8ba43]
void main()
{

object oPC= GetPCSpeaker();//Identificamos al pj.
object oOb=GetFirstItemInInventory(oPC);//Marcamos el primer objeto del inventario del pj

string sDado, sNivel, sTotal;//Maracmos unos string que usaremos mas tarde
string sNom=GetName(oPC)+GetPCPlayerName(oPC);//Cogemos el nombre del pj, y de su controlador.

int nDado, nTotal, iNivel;//Marcacmos unas int que usaremos despues
int nRangos=GetAbilityModifier (ABILITY_CONSTITUTION, oPC);//Cogemos la habilidad del pj
int iPx=GetCampaignInt("bdninfa",sNom,oPC);//Recogemosla canmtidad de PX de herreria acumulados.

string sRangos=IntToString(nRangos);

while (oOb!=OBJECT_INVALID)//Comenzamos un bucle que recorrera todos los objetos del pj
{
if (GetTag(oOb)=="met_oro")
{
DestroyObject(oOb);
nDado=d20();
sDado=IntToString(nDado);
iNivel=iPx/10;//Suponiendo que cada 10px de herrero suba un nivel, aqui maracmos el nivel.
if(iPx<=9)iNivel=0;//Si aun no tinene ni 10px, redondeamos su nivel a 0.
sNivel=IntToString(iNivel);
nTotal=nDado+nRangos+iNivel;//Sumamos el nivel al chequeo.
sTotal=IntToString(nTotal);
AssignCommand( oPC, SpeakString("Prueba de constitucion, resultado: "+sDado+" Modificador: "+sRangos+" Nivel: "+sNivel+" = "+sTotal+" CD:25"));
if (nTotal>=25)
{
CreateItemOnObject("ling_oro", oPC);
SendMessageToPC(oPC,"La fundicion ha resultado existosa");
iPx++;//Si tubo exito gana 1px extra.
}
else
{
SendMessageToPC(oPC,"La fundicion ha sido un fracaso");
}
}
oOb=GetNextItemInInventory(oPC);//Pasamos al siguiente objeto para comprobar si e sun lingote.
}

SetCampaignInt("bdninfa",sNom,iPx,oPC);//Guardamos en la base de datos la cantidad de PX ganados en herreria
}
[/code:1:9bc5c8ba43]

Vale.... ahora te pongo como lo haria io... ya que tal como tu lo haces, el oro debe estar en el inventario del pj, y los lingotes se fabrican dentro de su inventario.

Este otro script, es para que el oro este dentro de una mesa de trabajo (yunque o loq ue se te ocurra), y los lingotes aparezcan dentro de esa mesa de trabajo.

[code:1:9bc5c8ba43]
void main()
{

object oPC= GetPCSpeaker();//Identificamos al pj.
object oTarget=OBJECT_SELF;//Marcamos el ubicado contenedor que vamos a usar de mesa de trabajo
object oOb=GetFirstItemInInventory(oTarget);//Marcamos el primer objeto del inventario del objeto contenedor.

string sDado, sNivel, sTotal;//Maracmos unos string que usaremos mas tarde
string sNom=GetName(oPC)+GetPCPlayerName(oPC);//Cogemos el nombre del pj, y de su controlador.

int nDado, nTotal, iNivel;//Marcacmos unas int que usaremos despues
int nRangos=GetAbilityModifier (ABILITY_CONSTITUTION, oPC);//Cogemos la habilidad del pj
int iPx=GetCampaignInt("bdninfa",sNom,oPC);//Recogemosla canmtidad de PX de herreria acumulados.

string sRangos=IntToString(nRangos);

while (oOb!=OBJECT_INVALID)//Comenzamos un bucle que recorrera todos los objetos dela mesa de trabajo
{
if (GetTag(oOb)=="met_oro")
{
DestroyObject(oOb);
nDado=d20();
sDado=IntToString(nDado);
iNivel=iPx/10;//Suponiendo que cada 10px de herrero suba un nivel, aqui maracmos el nivel.
if(iPx<=9)iNivel=0;//Si aun no tinene ni 10px, redondeamos su nivel a 0.
sNivel=IntToString(iNivel);
nTotal=nDado+nRangos+iNivel;//Sumamos el nivel al chequeo.
sTotal=IntToString(nTotal);
SendMessageToPC(oPC,"Prueba de constitucion, resultado: "+sDado+" Modificador: "+sRangos+" Nivel: "+sNivel+" = "+sTotal+" CD:25");//mandamos un mensage por el canal de datos al pj
if (nTotal>=25)
{
CreateItemOnObject("ling_oro", oTarget);//Creamos el lingote dentro del objeto contenedor (mesa de trabajo)
SendMessageToPC(oPC,"La fundicion ha resultado existosa");
iPx++;//Si tubo exito gana 1px extra.
}
else
{
SendMessageToPC(oPC,"La fundicion ha sido un fracaso");
}
}
oOb=GetNextItemInInventory(oTarget);//Pasamos al siguiente objeto para comprobar si e sun lingote.
}

SetCampaignInt("bdninfa",sNom,iPx,oPC);//Guardamos en la base de datos la cantidad de PX ganados en herreria
}
[/code:1:9bc5c8ba43]

Bueno.. en ambos scripts e calculado que el pj sube un nivel de herreria por cada 10px de herrero, si por el contrario fuera cada por ejemplo 27px solo cambia en la linea:
iNivel=iPx/10; ------> por iNivel=iPx/27;
y esta otra:
if(iPx<=9)iNivel=0;---> por if(iPx<=26)iNivel=0;//

Y listo.

Una cosa mas... a la base de datos la he llamado "bdninfa" pero mientras respetas las comillas llamala como te salga en gana. Por otro lado el niveld e herreria se guarda en esa base de datos con el string sNom, que es el nombre del pj y de su jugador.

Pos eso.

Ninfablanca

30/12/2005 21:03:40

Juas, muchisimas gracias, me quedo con el del recipiente entonces que creo que es mejor, solo una cosilla más (debo ser más que agobiante XD)

Ahora el script esta ideado de modo que salga de una conversación igual, pero que las cosas se reflejen en el ubicado, lo cual necesito que al cerrar el inventario del ubicado por ejemplo, desencadene una conversación, pero no se como hacerlo bien, se que con desencadenantes es así:

[code:1:25addcfcc8]void main()
{

object oPC = GetEnteringObject();
object oTarget = OBJECT_SELF;

AssignCommand(oTarget, ActionStartConversation(oPC, "so_fundicion"));

}[/code:1:25addcfcc8]

oPC no se muy bien como definirla

mviper

31/12/2005 12:04:57

[code:1:191a6b76e8]
void main()
{

object oPC = GetLastClosedBy();

if (!GetIsPC(oPC)) return;

ActionStartConversation(oPC, "so_fundicion");

}
[/code:1:191a6b76e8]

Este script se pone en OnClosed de la mesa de trabajo, y la conversacion se habre al cerrar la mesa.

Ninfablanca

31/12/2005 14:52:14

Gracias nene, he usado este otro porque ese no me funcionaba

[code:1:41e33ecb23]void main()
{

object oPC = GetLastClosedBy();
object oTarget = OBJECT_SELF;

AssignCommand(oTarget, ActionStartConversation(oPC, "so_fundicion"));

}[/code:1:41e33ecb23]

Ninfablanca

31/12/2005 14:59:24

O.o juaps, poniendo el script tal como me lo expusiste allá arriba; al iniciar la conversación me hace 80 veces la tirada (literalmente) y sube 3 nv de herrería, creando a partir de una misma pieza de metal 25 paginas de lingotes.

Ninfablanca

08/01/2006 17:05:59

ya he encontrado lo que me daba problemas gracias ^^