aide pour quête : cumul d'objets de tags similaires

Répondre
Partager Rechercher
Bonjour à tous,

Nous sommes deux fans de NWN et avons décidé de faire un petit module pour un ami (alors que l'on est pas des bons programmeurs... ^^). Les conseils trouvés sur ce forum nous ont d'ailleurs grandement aidés (merci à tous! ^^) et permis de passer du stade novice à un niveau correct pour la création d'un module standard (créations de quêtes, marchands, objets, récompenses, apparitions de persos etc...).


Problème : Un PNJ doit offrir une armure si on lui rapporte 20 "pièces rouges". Ces pièces rouges sont des gems ayant tous le même tag. Ainsi nous n'arrivons pas à scripter la demande du PNJ pour qu'il reçoive ses 20 pièces rouges en une seule fois. Bien sûr on a pensé à faire un tag par pièce, néanmoins on veut placer plus de pièces dans le jeu que demandé par le personnage (environ 30..). Ces pièces sont cumulables dans l'inventaire, c'est à dire que l'on peut avoir les pièces par paquet de 10.

Bien sûr l'idée est que le joueur puisse proposer ses pièces au PNJ seulement lorsqu'il en a 20 ou plus.

On a essayé de faire une boucle, d'utiliser la fonction GetNumItem mais on arrive toujours sur un bug.


Pouvez vous nous aider s'il vous plait?

Merci d'avance.
Ça fait longtemps que je n'ai plus joué aux campagnes d'origine du jeu et ses expansions mais ça m'étonnerait qu'elles ne comprennent aucune quête du type "ramener XX machins", vous avez pensé à regarder de ce côté là ?
Pour les extensions je ne sais pas mais je me rappel d'un "marchand" avec des gems je crois... Enfin je ne suis plus sûr. Et comment avoir ces scripts la sinon? (Je ne savais pas qu'ils étaient disponibles)
La meilleure technique pour récupérer un scripte qui t'intéresse, est de passer par Aurora Toolset, pour cela tu dois récupérer le module de la campagne solo et le renommer en ".mod" pour pouvoir l'ouvrir avec le toolset.

Après tu fais ce que tu veux, récupérer les scriptes, les dialogues voir des quêtes entières.

Pour ton scripte du marchand, le plus simple sera d'ouvrir son dialogue, dans sa fiche en bas à gauche de mémoire et de trouver le scripte qui fait référence.

J'espère que ça t'aideras.
Bonjour,

il serait intéressant pour t'aider de savoir ce que tu appelles "on arrive toujours sur un bug".

Un extrait de tes codes pourrait nous permettre de t'aider franchement.

En ce qui concerne la fonction GetNumItems elle semble bien prendre en compte les objets empilables.

Si vraiment tu veux passer par une boucle, avec les fonctions GetNumStackedItems, GetFirstItemInInventory, GetNextItemInInventory tu fais :
Code:
- Une variable pour le premier objet
- Tant que mon objet est différent de OBJECT_INVALID.
  |- Si le Tag est égal à celui attendu.
     |-> Je compte le nombre d'objet empilé, j'incremente une variable compteur.
  |- J'initialise la variable objet avec l'objet suivant.
- Je test si ma variable compteur est supérieure ou égale à 20.
Bon courage.
Je te colle ici pour aide un script que j'ai sur mon module qui permet de prendre X quantité d'un objet à un joueur. Les valeurs en bleu sont celles à modifier en fonction de tes besoins.

Si tu es amené à utiliser bcp de fois ce script je te conseille aussi d'envisager l'utilisation de variables locales. En gros tu stockes les valeurs chiffrées sous forme de variable sur le PNJ du dialogue et tu les récupères avec la fonction "GetLocalInt("PNJ,"NOM_VARIABLE"); (ou GetLocalString pour un tag) Comme ça tu peux utiliser même 100 fois le script sans devoir en créer 100 itérations différentes, c'est une optimisation du poids du module


Code:
int TakeItem(object oTarget, object oItem, int nQuantity)
{
	int nCount = 0;
	int nStack = GetItemStackSize(oItem);
	    
	if (nQuantity < 0 || nStack == 1 || nStack <= nQuantity)
	{
		DestroyObject(oItem);
		nCount += nStack;
	}
	else
	{
		SetItemStackSize(oItem, nStack - nQuantity);
		nCount += nQuantity;
	}
	
	return nCount;
}


int TakeItems(object oTarget, string sItemTag, int nQuantity)
{
	int nCount = 0;
	int nTaken = 0;
	object oItem = GetFirstItemInInventory(oTarget);
	
	while(GetIsObjectValid(oItem) && nQuantity != 0)
	{
		if(GetTag(oItem) == sItemTag)
		{		
			nTaken = TakeItem(oTarget, oItem, nQuantity);
			
			nQuantity -= nTaken;
			nCount += nTaken;
		}		
		oItem = GetNextItemInInventory(oTarget);
	}	
	return nCount;
}


//--------------------------------------------------------------------------------------------------
//  PRINCIPAL
//--------------------------------------------------------------------------------------------------

void main()
{
	object oPC = GetPCSpeaker();
	if(GetIsObjectValid(GetItemPossessedBy(oPC, "TONTAG")))
	{
		TakeItems(oPC, "TONTAG", "Quantité à prendre");
	}
}
Bonjour,

Tout d'abord merci à tous/toutes.
Moukoutoute
J'avoue que comme j'ai mixé pas mal de fonctions et tenté beaucoup de choses sans une bonne connaissance du script, il ne ressemble plus à rien . Je pense mettre des nouveaux problèmes à chaque fois que je réessaye.

Delolia
Merci pour ton script. J'avoue ne pas très bien comprendre tout le fonctionnement mais je vais voir si ça colle.

Hyperion1
Je ne savais pas qu'on pouvait faire ça ainsi. Ca nous sera bien utile pour la suite je pense!
Alors merci pour le script il marche très bien pour récupérer les objets. Maintenant j'essaye de trouver le moyen de scripter le "text appear when"! J'avoue avoir du mal à cerner le problème... Voici ce que j'ai mis :

Code:
#include "nw_i0_tool"

int StartingConditional()
{

    // Ma variable de quête
    if(!(GetLocalInt(GetPCSpeaker(), "q_alphonse") == 100))
        return FALSE;

    // Être sûr qu'il ait les 20 pièces rouges
    if(!(HasItem(GetPCSpeaker(), "piecerouge")== 20 ))
        return FALSE;


    return TRUE;
}
Le texte n’apparaît pas malgré tout... j'ai essayé de modifier la ligne mais soit elle ne sert à rien soit elle empêche à la proposition d’apparaître.

PS: Je ne sais pas si ça change quelque chose, mais ce script apparaît sur un choix de dialogue du joueur.
Hyperion1
J'ai ouvert le module via le Toolset, j'ai retrouvé mon vendeur : c'est les "Smugglers' Coin" que l'actionnaire échange contre les objets magiques dans la taverne des docks "Seedy tavern". Par contre, son script ne fait en rien référence à un échange!
Je trouve ça

Code:
int StartingConditional()
{
    return GetLocalInt(OBJECT_SELF,"NW_L_ItemCSold") == FALSE;
}
C'est à dire que tant que l'objet de plus petite valeur n'est pas vendu il nous propose pas le suivant..... Rien de très utile.. Avez vous d'autres pistes pour chercher ses scripts s'il vous plait?
C'est bon!!
Après maintes recherches, nous y voila rendu
Pour ceux que ça intéresse je laisse ça là!!!
Code:
int StartingConditional()
{

    // Ma variable de quête
    if(!(GetLocalInt(GetPCSpeaker(), "q_alphonse") == 100))
        return FALSE;

    int nCost = 20;
    int nCount;
    object oCoin = GetFirstItemInInventory(GetPCSpeaker());
    while( GetIsObjectValid(oCoin) )
     {
        if(GetTag(oCoin) == "piecerouge")
        {
            nCount = nCount + GetNumStackedItems(oCoin) ;
        }
        oCoin = GetNextItemInInventory(GetPCSpeaker());
    }
    int bCondition = nCount >= nCost;
    return bCondition;


    return TRUE;
}
En tout cas encore merci pour les différentes aides par vos réponses tout d'abord mais aussi tous le forum!! J’essaierais de vous communiquer le module si on le termine un jour !
Du coup c'est bien ça a fait travailler les boucles, mais avec la fonction GetNumItems dont on parlait plus haut tu te serais moins embêté.

Code:
#include "nw_i0_plot"

int StartingConditional()
{
    object oPC = GetPCSpeaker();

    // On test si le total de pièces rouges est supérieur ou égal à 20 + l'état de la variable de quête
    if((GetNumItems(oPC, "piecerouge") >= 20) && (GetLocalInt(oPC, "q_alphonse") == 100))
        return TRUE;

    return FALSE;
}
Bonne soirée.
Répondre

Connectés sur ce fil

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