variable sur module

Répondre
Partager Rechercher
Je souhaiterais pouvoir faire contrôler une variable pouvant être placée sur plusieurs modules, mais je ne trouve pas comment je peux faire pour "nommer" les modules à vérifier.

J'utilise cette ligne pour placer ma variable:

Code PHP:

SetLocalInt(GetModule(), "temple"1); 

Et pour l'instant je la fais vérifier via ce script:

Code PHP:

int StartingConditional()
{
int nShow GetLocalInt(GetModule(), "temple") == 1;
return 
nShow;

Seulement, ce n'est valable que pour le module en cours me semble-t-il. Je souhaiterais le modifier pour qu'il puisse vérifier la présence d'une variable portant le même nom sur "module1", "module2" et "module3" par exemple.

Quelqu'un peut éclairer ma lanterne ?
Je vais utiliser le script de vérification pour faire apparaître des points sur la carte du monde et j'aurais, en moyenne, 4 modules à vérifier pour chaque point et en tout plus d'une vingtaine de points donc j'ai peur que ce soit un peu complexe pour moi à faire
Tu peux éventuellement utiliser la base de données du jeu grâce aux fonctions Get/SetCampaign*.

Par exemple :
Code PHP:

SetCampaignInt("carte_monde","temple",1); 

et
Code PHP:

int StartingConditional()
{
    
int nShow GetCampaignInt("carte_monde","temple")==1;
    return 
nShow;

Si le deuxième module reconnaît ces variable, les deux autres la reconnaîtront forcément.
Intéressant comme système, y-a-t-il un maximum de variables que l'on peut placer comme cela ?

Edit: j'avais oublié, peut-on faire faire les vérifications de plusieures zones par ce moyen via un seul script ? Et si oui, comment ?
Concernant le nombre de variables, je n'ai pas vraiment réfléchi, mais il y a largement de quoi faire.

Question place, je dirais que tu peux en avoir autant que ce que ton disque dur te permet. Je suggérerais juste de ne pas aller dans l'excès au niveau du nombre de variable par base de données. En effet c'est un système très accessible, mais loin d'être aussi performant que NWNX4, qui fait très mal au cerveau, mais qui est beaucoup plus rapide et complet. En tous cas, si un système simple et accessible te convient, je te conseille vivement d'utiliser la base de données du jeu (celui dont nous parlons, donc ^^).

Ce système utilise ton répertoire "database" de "mes documents", et y crée trois fichiers. Ceux-ci porteront le nom précisé dans le premier paramètre des fonctions "SetCampaign*". Dans mon cas, ces trois fichiers auront tous le nom "carte_monde". S'ils existent déjà, ils ne seront pas remplacés, mais simplement utilisés. Pour faire simple, j'appellerai "Base de données" cet ensemble de trois fichiers.

Une fois la base de donnée créée (si elle n'existe pas), la variable s'y inscrit. Elle obéit aux même règles que les variables locales, sauf que l'on peut y accéder après un redémarrage du module. Je crois aussi me souvenir qu'il existe un programme permettant d'y accéder en dehors du jeu, mais c'est moins sûr. Le nom d'une variable ne peut pas excéder 32 ou 64 caractères (là aussi ça fait longtemps, il faudra que je revérifie).

Les fonctions en rapport sont celles-ci :
- (Get)SetCampaignFloat
- (Get)SetCampaignInt
- (Get)SetCampaignLocation
- (Get)SetCampaignString
- (Get)SetCampaignVector
- (Retrieve)StoreCampaignObject

Les variables stockées sont traitées indépendamment tant qu'elles ne sont pas liée par leur type de valeur ET par le joueur associé (le dernier paramètre de la fonction). Il est donc possible d'inscrire :
- Deux variables dont le nom est le même, mais dont le type est différent.
- Deux variables dont le nom et le type sont les mêmes, mais dont le joueur associé est différent.
Il est également possible de ne pas définir le joueur associé à la variable (donc laisser le paramètre par défaut). Les règles restant inchangées, il est possible d'écrire :
- Deux variables dont le nom et le type sont les mêmes, mais dont l'une doit être associée à un joueur.


Ceci étant, ton cas ne nécessiterait que l'utilisation d'une seule base de données, composé uniquement de variables de type "int". Vu que tu veux un seul script pour toutes tes vérifications (un script générique), il faut d'abord voir comment organiser l'ensemble (tes zones, les paramètres de la carte du monde, etc.). Je te conseille donc te revoir les points d'arrivée et de départ de chaque zone reliée à la carte du monde, notamment le tag des points de passage d'arrivée (ou des portes).

Pour l'affichage des zones sur la carte du monde, c'est le même principe qu'avec le script suivant, où une quête permettait de conditionner l'apparition d'un lieu :
Code PHP:

// check if area visible in the world map

int StartingConditional(string sQuestint nState)
{
    return((
GetJournalEntry(sQuestGetFirstPC()) >= nState)); 

Il nous suffit juste de remanier le script en fonction de nos besoins, soit vérifier une variable dans la base de données :
Code PHP:

// check if area visible in the world map

int StartingConditional(string sVariable)
{
    return(
GetCampaignInt("carte_monde",sVariable)==1);

On peut parfaitement conditionner selon un ensemble de paramètres. Admettons que je veuille faire apparaître un point de la carte si notre variable le permet, mais également si le joueur :
- a accompli une quête (cf. le script de base)
- a 20 en force
- possède un familier au nom de "Broutablourbe"
- possède un item "générateur de bave" en main gauche
- a son nombre de points de vie au maximum
Code PHP:

// check if area visible in the world map

int StartingConditional(string sVariablestring sQuestint nState)
{
    
object oPC GetFirstPC();
    
int bReturn TRUE;

    
bReturn *= (GetCampaignInt("carte_monde",sVariable) > 0);
    
bReturn *= (GetJournalEntry(sQuest,oPC) >= nState);
    
bReturn *= (GetAbilityScore(oPC,ABILITY_STRENGTH) > 19);
    
bReturn *= (GetFamiliarName(oPC) == " Broutablourbe");
    
bReturn *= (GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC)) == "gen_bave_beurk");
    
bReturn *= (GetCurrentHitPoints(oPC) == GetMaxHitPoints(oPC));

    return 
bReturn;

Bon, j'ai testé ton système et je suis confronté à deux "gros" problèmes.

- Le premier, indépendant de ce que tu m'as indiqué, mais que je découvre vu que je commence juste à m'occuper de la carte du monde, lorsque je charge une nouvelle zone (via la carte du monde) l'ancienne n'est pas sauvegardée. Lorsque j'utilisais des points de transitions entre modules la sauvegarde se faisait. Est-ce que ça peut venir du fait que j'ai repris mon ancien script pour charger les zones depuis la carte du monde ?

Code PHP:

//******************************************************************
// This <span class="highlight">script</span> transitions a player from one  
// <span class="highlight">module</span> to another using an area transition or a door.
// ** Put this in the OnClicked event of a door or Area Transition
//******************************************************************
void main()
{
    
LoadNewModule("A02_BG1""cote_haute_haie4");

- Le second problème est directement lié au répertoire Database, en effet, après test je me suis aperçu qu'une fois que la variable est stockée dedans, elle ressort tout le temps (elle n'est pas effacée d'une partie sur l'autre, même lors d'un simple test de la zone via l'éditeur).
Citation :
Publié par Lyendhal
lorsque je charge une nouvelle zone (via la carte du monde) l'ancienne n'est pas sauvegardée. Lorsque j'utilisais des points de transitions entre modules la sauvegarde se faisait. Est-ce que ça peut venir du fait que j'ai repris mon ancien script pour charger les zones depuis la carte du monde ?
J'avoue que ça n'est pas très très clair pour moi... pourrais-tu préciser un peu plus ? ^^

Ton script actuel charge un nouveau module, et non une simple zone.

Citation :
après test je me suis aperçu qu'une fois que la variable est stockée dedans, elle ressort tout le temps (elle n'est pas effacée d'une partie sur l'autre, même lors d'un simple test de la zone via l'éditeur).
C'est le principe : rendre une variable persistante. On peut toutefois désactiver une variable de la base de données en utilisant la fonction "DeleteCampaignVariable(...)", et effacer toutes les variable désactivées d'une base de données en utilisant "PackCampaignDatabase(...)".
Je m'aperçois que je me suis très mal exprimé, je parlais de la sauvegarde des modifications apportées par le joueur à la zone. Un exemple valant mieux qu'un long discours, dans ma zone de démarrage, j'ai 3 compagnons recrutables, lorsque je change de module via un waypoint et le script que j'ai donné plus haut (et que j'ai recruté les compagnons bien entendu), la zone de départ est sauvegardée et ne contient plus les compagnons en questions. Maintenant, si j'utilise la carte du monde (toujours en recrutant les compagnons) pour partir de la zone de départ, lorsque j'y reviens les compagnons ont réapparu (ainsi que tous les pnjs devant avoir disparu).

J'espère avoir été un peu plus clair

Maintenant, pour la variable, comment faire pour la désactiver lorsque on arrête de jouer ou comment revenir à une valeur antérieure lorsque l'on recharge une partie ? Pour faire plus simple j'ai voulu rechercher les scripts des campagnes originales mais j'ai été incapable de les modifier pou les faire fonctionner ...
Concernant la transition avec des compagnons, je sais qu'Obsidian utilise les fonctions comme suit :
Code PHP:

DespawnAllRosterMembers(TRUE);
LoadNewModule("A02_BG1","cote_haute_haie4"); 
Pour le reste je vais essayer de me renseigner, mais ça ne sera pas immédiat.
J'ai "trouvé" ce qui initie le bug, c'est lorsque l'on rentre dans une zone pour la première fois et que l'on choisi via la carte du monde la zone dans laquelle on se trouve pour voyager. Si l'on choisit tout autre zone, tout se passe normalement.

Donc, question simple (pas dit que la réponse le soit), peut-on désactiver le voyage vers la zone dans laquelle on se trouve sur la carte du monde ?

Je te remercie d'essayer de te renseigner pour le reste, ceci dit si c'est trop compliqué autant que je reste sur des variables par modules .
Tu peux toujours rajouter un test dans ton script. Je n'ai pas testé, mais logiquement ça devrait fonctionner.

Admettons que le tag du point de passage de destination soit "wp_destination", et qu'il n'y ait d'erreur dans aucun tag de points de passage en jeu, quelque soit le module :
Code PHP:

void main()
{
    
object oPC GetFirstPC();
    
object oDestination GetObjectByTag("wp_destination");

    
// le point de passage n'existe pas,
    // il s'agit donc d'un autre module.
    
if(oDestination == OBJECT_INVALID)
    {
        
DespawnAllRosterMembers(TRUE);
        
LoadNewModule("module","wp_destination");
    }
    
// La zone du point de passage est différente,
    // on envoie donc le joueur et son groupe.
    
else if(GetArea(oPC) != GetArea(oDestination))
        
JumpPartyToArea(oPC,oDestination);

Citation :
Maintenant, pour la variable, comment faire pour la désactiver lorsque on arrête de jouer ou comment revenir à une valeur antérieure lorsque l'on recharge une partie ? Pour faire plus simple j'ai voulu rechercher les scripts des campagnes originales mais j'ai été incapable de les modifier pou les faire fonctionner ...
Tu veux faire quoi exactement, par rapport au jeu et au joueur ?
Je veux reprendre la majeure partie du système original, mais en y ajoutant une fonction de la seconde extension.
En clair, je veux que la carte puisse envoyer les joueurs au Nord, Sud, Est ou Ouest en fonction de leur point de sortie sur la zone précédente (sortie au Nord, entrée au Sud en gros) mais aussi qu'elle indique le temps approximatif de trajet entre le point ou se trouve le groupe et les zones disponibles (et évidement, que le temps passe lorsqu'il s'y rend).

Je sais que les scripts des deux campagnes permettent de le faire mais je n'arrive pas à comprendre comme ils le font fonctionner

Pour les variables, je me demandais si ce ne serait pas plus simple en les mettant sur le joueur (vu que c'est une campagne non persistante) ?
Pour ça, il faudrait définir tous les lieux possible dans le script, et calculer au cas par cas.


Une autre solution consisterait à définir la position des lieux et les utiliser dans le script, pour pouvoir ainsi calculer le point d'arrivée. Je pensais à quelque chose comme ça :


Par exemple (en prenant des valeurs au hasard) :
- lieu d'origine situé en haut à gauche de la carte : coordonnées (5; 6)
- lieu de destination situé en bas à droite : coordonnées (22; 19)

On fait la différence entre les coordonnées du lieu d'origine et du lieu de destination et on agit en fonction :
- Si la première valeur est négative, le joueur apparaît à l'ouest, et à l'est si elle est positive.
- Si la seconde valeur est négative, le joueur apparaît au nord, et au sud si elle est positive.

Si tu détermines tes points d'arrivée comme étant nord, est, sud ou ouest, on peut déterminer le point d'arrivée final selon ce calcul :
- Si la valeur absolue de la première valeur est supérieure à la valeur absolue de la seconde valeur, le joueur apparaît dans l'axe est-ouest. Sinon il apparaît dans l'axe nord-sud.

Si tes points d'arrivée concernent également les axes intermédiaires, comme nord-est, nord-ouest, sud-ouest et sud-est, tu peux utiliser le principe suivant :
- Si la valeur absolue de la plus grande valeur est supérieure à environ la valeur absolue de la valeur la plus petite multipliée par 2.414 (il y a un calcul plus précis, mais là c'est pour te donner une idée), le joueur apparaît dans un axe principal. Sinon il apparaît dans l'un des axes intermédiaires.

Ca peut sembler compliqué comme ça, mais c'est possible à faire grâce aux paramètres que l'on prédéfinit pour les scripts de la carte du monde.
Alors ce que je crois savoir : La variable locale sur un joueur est sauvegardée lorsqu'on sauvegarde une partie.

Ce que je ne sais pas (et n'ai pas encore cherché) : La variable locale sur un joueur est-elle conservée lors de la transition d'un module à un autre via "LoadNewModule(...)".


Sinon pour le concept de la vérification des zones, il faudrait (selon la manière dont je vois les choses) :

- inscrire en variable locale sur le déclencheur la position X et Y de la zone dans la carte, et la copier sur le joueur :
Code PHP:

object oPC GetFirstPC();
object oSelf OBJECT_SELF;
SetLocalInt(oPC,"POSITION_X_CARTE_MONDE",GetLocalInt(oSelf,"POSITION_X_CARTE_MONDE"));
SetLocalInt(oPC,"POSITION_Y_CARTE_MONDE",GetLocalInt(oSelf,"POSITION_Y_CARTE_MONDE")); 
On considérera les points cardinaux par 0 (nord), 2 (est), 4 (sud) et 6 (ouest). Définir les points d'arrivée sur chaque zone, en leur donnant un Tag précis, par rapport au Tag de la zone et à sa position dans la zone, par exemple "0_cote_haute_haie4" pour le nord ta zone, ou encore "2_cote_haute_haie4" pour l'est de la zone.

Dans le script d'action du lieu de destination de la carte, faire le calcul du sens qu'à emprunté le joueur pour y aller. Il faut donc mettre en paramètre la position de la zone de destination dans des variable du style "nPositionX" et "nPositionY", ainsi que le tag de base du point d'arrivée, pour faire en sorte que le script les prenne en compte.

Je vais considérer ici qu'on n'exploitera que les deux axes principaux (nord-sud et est-ouest) :
Code PHP:

void main(float nPositionXfloat nPositionYstring sDestination)
{
    
object oPC GetFirstPC();
    
int nOrigineX GetLocalInt(oPC,"POSITION_X_CARTE_MONDE");
    
int nOrigineY GetLocalInt(oPC,"POSITION_Y_CARTE_MONDE");

    
int nDiffX nPositionX-nOrigineX;
    
int nDiffY nPositionY-nOrigineY;

    if(
abs(nDiffX)>=abs(nDiffY))
    {
        
int nDirection 2;
        if(
nDiffX<0)
            
nDirection 6;
    }
    else
    {
        
int nDirection 0;
        if(
nDiffY>0)
            
nDirection 4;
    }

    
string sWaypoint IntToString(nDirection)+"_"+sDestination.
    
object oWaypoint GetObjectByTag(sWaypoint);

    
// le point de passage n'existe pas,
    // il s'agit donc d'un autre module.
    
if(oDestination == OBJECT_INVALID)
    {
        
DespawnAllRosterMembers(TRUE);
        
LoadNewModule("module","wp_destination");
    }
    
// La zone du point de passage est différente,
    // on envoie donc le joueur et son groupe.
    
else if(GetArea(oPC) != GetArea(oDestination))
        
JumpPartyToArea(oPC,oDestination);

C'est juste un truc fait de tête, donc pas forcément la meilleure méthode de calcul.

De plus, avec ce système, il faudrait également prendre en compte les points d'arrivée inexistants. Admettons que le joueur est sensé arriver par le nord de la zone, mais que c'est physiquement impossible (grosse montagne, ou étendue d'eau, etc.). Il faudra absolument mettre un point de passage correspondant au nord, quelque part dans la zone de destination, pour que le joueur puisse s'y faire transférer.

J'ai un peu survolé le système d'Obsidian, et il me semble qu'il répertorie chaque zone dans une constante qui lui est propre, et qui doit leur gérer les calculs de manière plus simplifiée. Ca fait faire des scripts plus lourds, mais moins casse-tête.
Navré d'avoir mis autant de temps avant de répondre, j'ai été pas mal occupé.


Lorsque j'essaie de compiler le script il m'indique une erreur de type :

Parsing Variable List

à la ligne "object oWaypoint = GetObjectByTag(sWaypoint);"

J'ai essayé en remplaçant le point qui clôt la ligne du dessus par un ";" mais j'obtient une nouvelle erreur plus bas au niveau du "DespawnAllRosterMembers(TRUE);"

Que dois-je faire ?
Si le script ne compile pas, c'est le script qui est en cause et pas les tag de waypoint.

Tu as défini quelque part l'objet oDestination comme l'a dit krighaur ? Le script tente d'utiliser une variable et de vérifier sa validité
Code PHP:

if(oDestination == OBJECT_INVALID
Mais oDestination n'est pas défini. Il faut quelque part que tu définisses cet objet. Là par exemple, le script ne sait pas de quel type oDestination est : entier ? chaîne de caractères ? objet ? Parce qu'il n'a pas été défini.

Au final j'ai l'impression que dans le script, ce oDestination devrait en réalité être le oWaypoint - qui lui, est défini plus haut.
Code PHP:

object oWaypoint GetObjectByTag(sWaypoint); 



Il ne te reste qu'à mettre le même nom de variable partout : soit oWaypoint, soit oDestination.
Il me semblait que c'était un script "générique" que l'on rempli lors de son utilisation sur la carte du monde pour le chargement des zones ... je vais essayer en faisant ces modifications.

Mais je viens de m'apercevoir d'un problème potentiel, si je sors par l'ouest d'une zone et que je veux me rendre dans une zone à l'ouest de celle dont je sors (c'est là qu'il faut suivre ), je risque de rentrer dans la nouvelle zone par l'est alors que je viens de l'ouest, non ?
Et bien, j'ai réussi à me tromper en voulant expliquer !!

Si on sort de la zone en question par l'est et que l'on se dirige vers une zone à l'ouest, on va y entrer par l'ouest au lieu de l'est non ?
Répondre

Connectés sur ce fil

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