Journal de quete vidé

Répondre
Partager Rechercher
J'ai fait une suite de quêtes, cependant, dès que le serveur redémarre, le journal de quêtes des joueurs se vide. J'imagine qu'il faut entrer les quêtes quelque part ailleurs pour que le serveur les reload une fois qu'un personnage entre sur le module, mais j'avoue n'avoir aucune idée du "comment faire. "

Si quelqu'un pouvait m'aider,

Merci beaucoup,
Persistance quand tu nous tiens

Il existe trois choix possible pour conserver tes données.
-> Variable sur Objet du PJ (SetLocal/GetLocal)
-> Utilisation de la bd de bioware
-> Utilisation d'une bd externe.

La mise à jour du journal de quête devra utilisé une de ces méthodes de sauvegarde de données. Donc dès ajout ou modification d'une quête, faudra pensé à enregistrer sa position et état dans un sac à données (une des trois méthodes si dessus).
A la connexion du PJ, il faudra lire les données qui lui sont liées pour remplir le journal de quête comme il faut.

Cela te va comme réponse?
Plus précisément....

-> Variables sur objets du PJ

Il s'agit de donner au PJ un objet unique, indroppable et un vendable. Il peut s'agire d'une baguette d'émote, d'un anneau de reconnaissance de faction, come de tout autre objet "indispensable" au PJ.
Toutes les variables placées sur cet objet seront sauvegardées directemetn dans le fichier .bic représentant le personnage. Ainsi, même si ton module plante, ces variables resteront.
Tu les poses avec un SetLocal<type>(object item, string nom, <type> valeure)
Et tu les récupperre avec un GetLocal<type>(object item, string nom)

Type est le type de ta variable (object, string, int ou float).
object est l'objet en question passé en argument.
nom est le nom de la variable.

exemple d'utilisation : scripte a poser sur un PNJ.
Code PHP:

    main()
    {
      
object oPC GetPcSpeacker();
      
object oItem GetObjectByTag("mesSaves");
      if( 
getLcocalInt(oItem"quete1") == )
      {
          
SetLocalIntoItem"quete1"2)
      }
    } 
Ainsi, si le PJ qui parle au pnj qui a déclenché ce scripte est dans la phase 1 de la quete, alors je le passe a la phase 2.

Sur le OnEnter du module tu pourra mettre un petit bout de code vérifiant l'état des variables et recréant le journal en fonction...

-> Utilisation de la BD bioware
je la déconseille a cet usage.
Il est possible de sauvegarder en persistant via la fonction SetCampaign<type> et de reccupperer la variable lpus tard.
La variable est sauvegardé dans un fichier externe que Bioware a appelé base de donnée. Cela peut être utile a de petits scriptes, mais vu que tu n'auras pas besoin d'acceder aux variables une fois le joueur déconnecté, inutile de s'appesantir sur ce systeme.

-> Utilisation d'une BD externe (mySQL, ou autres.)
Il est possible via des outils comme nwnx2 de stoquer tes variables sur une base de donnée exterrieur a nwn. L'interet principal est que tu peux ainsi y acceder ou les modifier a la main sans meme te donner la peine de monter sur le module. Cela permet de faire beaucoup de choses diverses et variées, notemment d'interfacer avec un site écrit en PHP....
cross post ^^

Je disais donc....

Variable locales....
Lorsque le PNJ donne la quete, tu poses ta variable. Lorsque le PJ termine sa quete tu fais un DeleteLocalInt...

Sur le onEnter de ton module, tu vérifie l'état de chacune des variables. Tu ajustes le journal en conséquent....



nb: un getLocalInt sur une variable inéxistante renvoie 0...
AddJournalQuestEntry comporte des variables, et bien ce sont celle là que tu sauvegardes
Et à la connexion du fait appel à cette fonction avec les variables récupérées.

Les 3 plus importantes étant les 3 premières variables :
-> Tag du journal
-> Numéro d'avancement
-> L'objet PJ

Donc au minimum, tu auras :
Code PHP:

AddJournalQuestEntry(GetLocalString(oItemPJ"TagQuete"), GetLocalInt(oItemPJ"IDQuete"), oPJ); 

Un truc du genre, attention celui là ne fonctionnera que pour une quête. Si tu souhaites gérer plusieurs quêtes faudra utilisé un petit système du genre :
Code PHP:

GetLocalString(oItemPJ"TagQuete" IntToString(iCompteur)) 

Avec une boucle.

J'espère avoir été assez clair...

PS : pas assez rapide pour ce post
Merci pour vos réponses

pour le moment j'utilise ca :

Code:
void main()
{
object oPC=GetPCSpeaker();

// Activer la quete dans la BDD
SetCampaignInt("tarabasfiole", "statut_quete", 1, oPC);

//on ajoute la quete
AddJournalQuestEntry("tarabasfiole", 1, oPC, FALSE, FALSE, FALSE);
//0 Quete non active
//1 Quete active
//5 Quete finie et non repetable
}
donc en fait, tout ce que j'aurai à faire sur le onenter du module, et je fais un truc du genre

si getcampagnint = 1
alors
AddJournalQuestEntry("tarabasfiole", 1, oPC);
si getcampagnint = 5
alors
AddJournalQuestEntry("tarabasfiole", 2, oPC);
sinon rien

C'est ca ? Si j'ai beaucoup de quêtes c'est pas lourd pour le serveur de devoir remettre à chaque fois les quetes ?

Merci encore ^_^
effectivement ca risque d'etre lourd.... surtout que lorsque tu détruit une valeur dans la DB bioware, celle ci est simplement "oubliée" et n'est pas réellement détruite. Ainsi tu risque de tres rapidement surcharger tes "tables"

Passes donc par un objet dans l'inventaire des tes PJs.
Code PHP:

   {
   
object oPC=GetPCSpeaker();
   
object oItem=GetItemPossessedBy(oPC"tag_objet");
   
   
SetLocalInt(oItem"statut_quete_tarastafiole"1);
   
   
AddJournalQuestEntry("tarabasfiole"1oPCFALSEFALSEFALSE);
   } 
Ok, et pour rajouter les quetes a la connexion après redémarrage du serveur, sur le onenterclient

Code PHP:

main()
    {
      
object oPC GetEnteringObject();
      
object oItem GetObjectByTag("baton_emote");
      if( 
getLocalInt(oItem"tarabasfiole1") == )
      {
          
AddJournalQuestEntry("tarabasfiole"1oPCFALSEFALSEFALSE);
      }
    } 
J'ai tout compris ^_^ C'est très rare ^^ ;-) Merci beaucoup pour votre aide
et pis je parie que ton scripte de donnes du nimportequoi ;-)

bin oui...
GetObjectByTag("baton_emote");
Ca prends un baton d'émote, mais pas forcément celui que tu veux.... d'ou le GetItemPossessedBy(oPC, "baton_emote")
La tu pourra avoir un probleme si le PJ a deux batons d'émotes par contre....
Effectivement, Heziva a bien noté un truc fondamental que j'avais pas vu non plus.
Pour l'objet, afin d'eviter les double, le mieux c'est de donner aux PJ un item spécialement conçu pour ça, qui soit indropable aussi, invendable indestructible, in modifiable, etc.
Si tu mets ça sur un vêtement pas exemple, ou un objet modifiable avec les skill, c'est pas sur qu'il garde les variables que tu aura mis dessus.

Pour la lourdeur dont tu parlais plus haut, la difficulté vient du fait que tu as plusieurs étapes dans chacune de tes quetes et surtout que tes PJ peuvent je suppose les faire dans le désordre. Donc on peux pas faire un truc du genre :
[php]
if(GetLocalInt(oPC,"Mes_Quetes") == 3)
{
AddJournal... 1
AddJournal... 2
AddJournal... 3
}
Si tu te sent de faire un tableau, avec toutes les possibilités de combinaisons de quetes ce sera moins lourd pour l'ordi, mais pour toi je doute
En plus a mon avis c'est pas ça qui prendra le plus de mémoire ou de temps à executer.
Citation :
Publié par Heziva

Passes donc par un objet dans l'inventaire des tes PJs.
Code PHP:

   {
   
object oPC=GetPCSpeaker();
   
object oItem=GetItemPossessedBy(oPC"tag_objet");
 
   
SetLocalInt(oItem"statut_quete_tarastafiole"1);
 
   
AddJournalQuestEntry("tarabasfiole"1oPCFALSEFALSEFALSE);
   } 

Bonjour ^^

Je poste ici bien que la poussière et les toiles d'araignée géante ont eut main basse sur ce sujet mais au cas ou une âme charitable passerait par là pourrait-elle me dire ou mettre ce script :P Oo

En effet je commence à moderniser mon module (lol) mais g besoin d'aide pour certains script

Comme celui du save des quêtes (oui c'est fun je trouve). Toutes mes quêtes se font par dialogue et j'aimerai utiliser cet outil qu'est le journal et comme certaine de mes quêtes sont de longue haleine...

Voila voila si quelqu'un pouvait m'aider ça serait top!

D'avance merci
Bonjour,

Ce script peut se mettre où l'on veut, il suffit d'ajuster la première ligne qui récupère le personnage.
Je me permets de rappeler quelques bricoles sur ce procédé.
Le problème de départ, c'est qu'en server vault, on ne peut pas sauvegarder le journal du PJ. On recourt donc à une astuce. On sauvegarde l'état du journal (et des quêtes) puisqu'on n'a pas accès direct au fichier journal.

Ici, tu as deux exemples d'options pour les sauvegardes: la base Bioware, pas souple du tout pour ça et la sauvegarde par objet d'inventaire (qui est très souple et qui ne prend quasiment pas de place puisque stockée dans le .bic du personnage, par contre, elle n'est disponible que si le personnage est connecté et présent sur le serveur. Indisponible lors du OnClientExit par exemple).

Evidemment, pour gérer ces données, il faut en permanence tenir à jour l'état de chaque quête. A chaque fois qu'une modification intervient, il faut remettre la (ou les) variable(s) de la quête en question à jour, par exemple:
  • mort de la cible d'une quête (OnDeath de la créature = GetLastHostileActor() )
  • dialogue avec le PNJ correspondant à l'objectif (Action conséquente de dialogue = GetPCSpeaker() )
  • activation d'un objet quelque part (OnUsed d'un objet = GetLastUsedBy() )
etc

En fonction du moment où tu voudras changer une variable, il faudra appeler ce genre de script. Donc, il faudra l'adapter en permanence étape de la quête concernée (une quête, ce n'est pas forcément limité à deux étapes: "en cours" et "finie", il peut y avoir plusieurs étapes intermédiaires. C'est pour ça qu'il n'y a pas de réponse universelle.
La seule complication, c'est que la façon de récupérer le PJ va changer selon l'évènement utilisé pour rafraîchir l'état de la quête dans le journal.
Et pour réactiver les entrées, il suffit de le faire à la connexion du client ou à l'entrée sur le module. S'il y a beaucoup de quêtes, ça risque de faire un gros script listant toutes les variables à remettre en l'état. Mais ça n'a rien d'impossible si tu restes rigoureux et organisé.

J'espère que ça t'a quand même aidé.
Bon bon bon je vais regarder tout çà! Si j'ai bien compris le script que j'ai cité est là est à mettre dans l'Action Concéquence du dialogue avec le pnj car on a un GetPCSpeaker()

Merci de ta réponse Azmathiel ça m'a éclairé sur ce que j'avais demandé - bon je vais voir dans la pratique lol ^^

Je risque peut-être de revenir si je vois encore de la lumière
Re-moi j'ai vu de la lumière lol

Bon pas encore eut le temps de tester (je tire dans tous les sens là lol ^^) mais une question me vient à l'esprit, c'est concernant la date du module. En effet il me semble que les quete s'incrémente dans le journal avec la date actuelle du serveur. Or en sauvegardant les quetes encours et apres reboot la date va revenir à celle préréglée dans l'éditeur. Donc peut-on save la date quelque part histoire de donner une origine à mon module (voir d'introduire un facteur temps dans mon module genre: "mon humain je le joue depuis 129 ans RP ah bah ton perso est mort de vieillesse lui dit le MD" - ce n'est qu'une idée )
Oui, bien sûr qu'on peut sauvegarder le temps. Et là, il vaut mieux utiliser la base Bioware. Elle est parfaitement adaptée.

L'évènement le plus adapté pour ce faire reste OnHeartBeat du module.
Après, à chacun de voir quelle précision est nécessaire. Personnellement, je me limite à sauvegarder à l'heure près (avant, je sauvegardais toutes les 6 secondes, soit un OHB, mais mon disque dur a rendu l'âme après 2 ans). Ça me sert en même temps à recaler l'horloge qui se détraque parfois et se bloque au passage jour/nuit. Cela arrive en général quand le serveur a besoin de plus de temps de calcul que ne peut lui fournir le PC support (nombreux spawns à gérer, pile énorme, etc).
Je ne sauvegarde que s'il y a un joueur en ligne, sinon, je laisse faire.

Voilà le script que j'ai écrit et que j'utilise:
Code PHP:

void main()
{
    
// on initialise le calendrier du serveur
    // S'il y a quelqu'un en ligne, sinon, on ne fait rien
    // Utilisé pour pallier au blocage des transitions Jour/Nuit dû à la surcharge CPU
    
int nCompteur GetLocalInt(GetModule(), "Compteur_OHB");
    
// 600x6 = 3600 secondes soit une heure.

    
if (GetFirstPC() != OBJECT_INVALID)
    {
        if (
nCompteur >= 600)
        
// restriction rajoutee le 16/07/2007 pour economiser le disque dur du serveur
        // une sauvegarde par heure du groupe Date/Heure suffit au lieu d'une toutes les 6 secondes.
        
{
            
SetCampaignInt("calendrierjdo""annee"GetCalendarYear());
            
SetCampaignInt("calendrierjdo""mois"GetCalendarMonth());
            
SetCampaignInt("calendrierjdo""jour"GetCalendarDay());
            
SetCalendar(GetCalendarYear(),GetCalendarMonth(),GetCalendarDay());
            
// on initialise l'heure
            
SetCampaignInt("calendrierjdo""heure"GetTimeHour());
            
SetTime(GetTimeHour(),GetTimeMinute(),GetTimeSecond(),GetTimeMillisecond());
            
SetLocalInt(GetModule(), "Compteur_OHB"0);
        }
        else
        {
            
// si l'heure n'est pas passee, on compte et c'est tout. Pas de sauvegarde.
            
nCompteur++;
            
SetLocalInt(GetModule(), "Compteur_OHB"nCompteur);
        }
    }

Avec ça, il faut aussi rajouter des choses dans le OnModuleLoad pour recaler l'horloge. voici cette partie de script à rajouter au OnModuleLoad.
Code PHP:

// Sequence de reinitialisation calendrier et horloge
   // Les donnees sont dans la base "calendrierjdo"
   // Voir OHB module
   
int AnneeMoisJourHeure;

   
Annee GetCampaignInt("calendrierjdo""annee");
   
Mois GetCampaignInt("calendrierjdo""mois");
   
Jour GetCampaignInt("calendrierjdo""jour");
   
Heure GetCampaignInt("calendrierjdo""heure");

   
SetCalendar(AnneeMoisJour);
   
SetTime(Heure000); 
Bien sûr, il faudra adapter le nom de la table à ton module
Merci de ta réponse super rapide Azmathiel
Tes scripts me conviennent parfaitement ^^
J'avance plus vite là d'un coup avec l'aide de personne qui s'y connaissent
Citation :
Publié par Erigion / Titam
Ok, et pour rajouter les quetes a la connexion après redémarrage du serveur, sur le onenterclient

Code PHP:

main()
    {
      
object oPC GetEnteringObject();
      
object oItem GetObjectByTag("baton_emote");
      if( 
getLocalInt(oItem"tarabasfiole1") == )
      {
          
AddJournalQuestEntry("tarabasfiole"1oPCFALSEFALSEFALSE);
      }
    } 
Bonjour! C'est à nouveau moi^^

Apres mise à jour de mes quetes, map... etc... je m'attaque à la persistance du journal et... oui je bute sur un script (^^), celui ci-dessus -> apparement il fonctionne (il sert à récupérer l'état de chaque quete lancée par le personnage par rapport à un objet qu'il possede en permanence) et en compilant j'ai une erreur de position de paranthèse à ce que j'ai compris à la ligne:

if( getLocalInt(oItem, "tarabasfiole1") == 1 )

1- Peut-on m'expliquer le problème???

2- La fonction main () toute seule semble poser aussi un problème à la compilation -> merci de m'expliquer cela aussi ^^

3- Je me suis aperçue que les xp de quetes ne sont pas donnés automatiquement. Apparement il faut rajouter un script (dans le action/conséquence ??)
J'ai déjà lu des articles à ce sujet mais je ne parvient pas à les retrouver.

Ma question ^^ : peut-on me donner un script pour attribuer les xp d'une quete?
(genre GetxptoCreature (journalquestentry... == 2...) -> pas l'éditeur sous les yeux donc j'ai les termes exactes

Voilaaaa encore besoin d'...

Davance merci
Je ne vois pas d'erreur de parenthèses dans ton script, par contre il y en a deux autres:

main ne s'utilise jamais seul mais avec void et ça donne void main(). Il n'y a pas grand chose à expliquer, c'est comme ça qu'on dit bonjour à un compilateur C.

La seconde erreur est dans la fonction getLocalInt(oItem, "tarabasfiole1").
le "g" doit être majuscule. La fonction a été définie comme ça par Bioware, il faut respecter son orthographe exacte:
Code PHP:

// Get oObject's local integer variable sVarName
// * Return value on error: 0
int GetLocalInt(object oObjectstring sVarName
Pour donner des XP à un personnage, c'est assez simple si c'est dans un dialogue:

- Bonjour, avez-vous terminé la quête ?
-> oui (ici on teste la variable dans le script conditionnel pour afficher ou non la branche) et si c'est le cas, on donne des XP dans l'action conséquente de la branche
-> non (branche par défaut, on ne fait rien et on part sur la suite du dialogue)

Comment donner des XP à un PJ ?
Code PHP:

// Gives nXpAmount to oCreature.
void GiveXPToCreature(object oCreatureint nXpAmount
nXpAmount = nombre de XP à donner. (attention, ce nombre ne peut pas être négatif, on ne peut pas donner -100 XP en espérant que ça diminue les XP du personnage)

Ton script Action Conséquente devient donc:
Code PHP:

void main()
{
    
object oPerso GetPCSpeaker(); // celui qui parle au PNJ en ce moment même
    
GiveXPToCreature(oPerso50000); // oui, je sais, ce n'est pas assez pour cette énorme quête :p

A toi de jouer.
J'ai testé et ça marche pas donc j'ai dut faire des erreur dans les réferencements:
Pour être sure de mon coup merci de préciser ma demande -> j'ai remis les 2 script concerné en indiquant ce que je pensais qu'il faille indiquer à la place des termes en rouge


{
object oPC=GetPCSpeaker();
object oItem=GetItemPossessedBy(oPC, "tag_objet");
SetLocalInt(oItem, "statut_quete_tarastafiole", 1);

AddJournalQuestEntry("tarabasfiole", 1, oPC, FALSE, FALSE, FALSE);
}

"tag_objet" = TAG de l'objet sur lequel on sauvegarde
"statut_quete_tarastafiole" = ???? une variable pour la sauvegarde??
"tarabasfiole" TAG de la quete dans le journal

ENSUITE

void main()
{
object oPC = GetEnteringObject();
object oItem = GetObjectByTag("baton_emote");
if( GetLocalInt(oItem, "tarabasfiole1") == 1 )
{
AddJournalQuestEntry("tarabasfiole", 1, oPC, FALSE, FALSE, FALSE);
}
}


"baton_emote" = TAG de l'objet sur lequel a lieu la sauvegarde
"tarabiosfiole1" = ???? variable pour récupérer la sauvegarde??? si on se réfère au 1er script de serait "statut_quete_tarastafiole" ????
"tarabasfiole" = TAG de la quete dans le journal

Voila désolé de paraître long à la détente (lol) mais je lacherai pas le morceau ^^ avant que ça marche - pas de raison que j'y arrive pas

D'avance encore, encore et euh... encore merci
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés