Oláááá terráqueos.
Nesse últimos dias consegui algum tempo para mexer no meu módulo e agora estou tratando da integração dele com o MySQL.
Meu primeiro passo foi tentar achar algum módulo com alguma funcionalidade já pronta. Acabei pegando o próprio módulo de exemplo que vem no NWNX4. Ele deu um erro ao tentar abrir a única área que ele ja possuía, mas o importante pra mim eram os scripts. Criei então duas áreas, uma com NPCs para testar algumas funcionalidades e outra com uma criatura hostil para testar o sistema de morte.
Com tudo armado, eu abri o script e_mod_load e adicionei os seguinte comandos:
if (!doesTableExist("TEXTOS")) {
SQLExecDirect("CREATE TABLE TEXTOS (" +
"PLAYER VARCHAR(64) NOT NULL DEFAULT '~'," +
"TAG VARCHAR(64) NOT NULL DEFAULT '~'," +
"NAME VARCHAR(64) NOT NULL DEFAULT '~'," +
"TEXTO TEXT," +
"EXPIRE INT(11) DEFAULT NULL," +
"PRIMARY KEY (PLAYER, TAG, NAME)" +
") ENGINE=MyISAM DEFAULT CHARSET=latin1;"
);
if (!doesTableExist("TEXTOS")) {
SetLocalString(oMod, "ERROR", "The MySQL plugin could not set up the table 'pwdata'. Please make sure that the mysql userid in xp_mysql.ini has sufficient permissions to create a new table.");
PrintString("e_mod_load: CREATE pwdata failed.");
return;
}
}
Ou seja, apenas copiei o código anterior que verificava a existencia das tabelas pwdata e pwobjdata e as criavam e as adaptei para verificar e criar a tabela TEXTO, que gravará um texto qualquer.
Rodei o módulo no NWNX4 e funcionou legal.
Meu próximo passo então era gravar um texto qualquer no banco de dados e recuperar. Tentei usar as funções que já vêem no nwnx_sql (GetPersistentString e SetPersistentString), mas não gravava nada. Eu então coloquei algumas mensagens de debug e encontrei o problema:
As funções do nwnx_sql servem apenas para as tabelas ja definidas (pwdata e pwobjdata) e assim criava um comando SQL todo esquisito, como é possível conferir na screenshot acima. A solução então era criar meu próprio script de funcionalidades para a base de dados. Criei então a sh_sql, inicialmente com apenas 2 funções: SetTexto e GetTexto:
//:://////////////////////////////////////////////////
//:: sh_sql
/*
Funções para o uso do NWNX4 de acordo com o esquema de
base de dados criado por mim.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2008 SubHeaven World
//:: Created By: SubHeaven
//:: Created On: 07/10/2008
//:://////////////////////////////////////////////////
#include "nwnx_sql"
/************************************/
/* Function prototypes */
/************************************/
//Gravar texto do jogador.
// oPC: O jogador que está gravando o texto;
// sTexto: O texto a ser gravado na base de dados.
void SetTexto(object oPC, string sTexto);
//Ler texto do jogador.
// oPC: O jogador que gravou o texto anteriormente.
string GetTexto(object oPC);
/************************************/
/* Implementation */
/************************************/
void SetTexto(object oPC, string sTexto)
{
string sPlayer;
string sChar;
if (GetIsPC(oPC))
{
//SendMessageToPC(oPC, "Its a PC");
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
sChar = SQLEncodeSpecialChars(GetName(oPC));
sTexto = SQLEncodeSpecialChars(sTexto);
string sSQL = "SELECT TEXTO " +
"FROM TEXTOS " +
"WHERE PLAYER = '" + sPlayer + "' " +
"AND NAME = '" + sChar + "'";
//SendMessageToPC(oPC, sSQL);
SQLExecDirect(sSQL);
if (SQLFetch() == SQL_SUCCESS)
{
SendMessageToPC(oPC, "Exist TEXTO");
// row exists
sSQL = "UPDATE TEXTOS SET " +
"TEXTO ='" + sTexto + "', " +
"WHERE PLAYER = '" + sPlayer + "' " +
"AND NAME = '" + sChar + "'";
//SendMessageToPC(oPC, sSQL);
SQLExecDirect(sSQL);
}
else
{
SendMessageToPC(oPC, "Doesn't exists TEXTO");
// row doesn't exist
sSQL = "INSERT INTO TEXTOS (" +
"PLAYER, " +
"NAME, " +
"TEXTO" +
") VALUES ('" +
sPlayer + "', '" +
sChar + "', '" +
sTexto + "')";
//SendMessageToPC(oPC, sSQL);
SQLExecDirect(sSQL);
}
}
else
{
SendMessageToPC(oPC, "Its not a PC");
}
}
string GetTexto(object oPC)
{
string sPlayer;
string sChar;
if (GetIsPC(oPC))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
sChar = SQLEncodeSpecialChars(GetName(oPC));
string sSQL = "SELECT TEXTO "+
"FROM TEXTOS " +
"WHERE PLAYER = '" + sPlayer + "' " +
"AND NAME = '" + sChar + "'";
//SendMessageToPC(oPC, sSQL);
SQLExecDirect(sSQL);
if (SQLFetch() == SQL_SUCCESS)
return SQLGetData(1);
else
{
return "Nao existe texto gravado pra voce.";
}
}
else
{
return "";
SendMessageToPC(oPC, "Its not a PC");
}
}
Funcionou legal para verificar se tinha alguma informação:
Ainda tive um pequeno problema na hora de gravar o texto:
Mas foi fácil verificar que eu não fechava o ' do texto.
Para o modulo, ainda criei mais 3 scripts:
sh_escrevertexto, que utiliza a sh_sql para gravar o texto na base de dados.
#include "sh_sql"
void main()
{
object oPC = GetPCSpeaker();
string sMensagem = GetName(oPC) + " esteve aqui.";
//SendMessageToPC(oPC, "sh_escrevertexto");
SetTexto(oPC, sMensagem);
}
sh_lertexto, que utiliza a sh_sql para ler o texto na base de dados.
#include "sh_sql"
void main()
{
object oPC = GetPCSpeaker();
string sMensagem = GetTexto(oPC);
SendMessageToPC(oPC, sMensagem);
}
e um script para ligar no evento OnUse de um objeto para acionar uma conversa que permite as ações acima, a sh_conversar:
//:://////////////////////////////////////////////////
//:: sh_conversar
/*
Função usada para fazer um objeto começar uma conversa com o
jogador.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2008 SubHeaven World
//:: Created By: SubHeaven
//:: Created On: 07/10/2008
//:://////////////////////////////////////////////////
void main()
{
object oPC = GetLastUsedBy();
//SendMessageToPC(oPC, "sh_conversar");
ActionStartConversation(oPC, "", TRUE, FALSE, FALSE, TRUE);
}
Resultado na base de dados:
O módulo de teste está nesse link.
A conversa está aqui.
Próximos passos:
- Criar as funções que gravam a localização do jogador e que o teleportam de volta praquele local;
- Criar as funções de tratamento de Death e Respawn do jogador;
- Criar uma função que calcule o loot das criaturas baseado em dados armazenados no banco de dados;
- Criar a função que impede a criação de mais de um personagem com o mesmo nome.
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário