Bienvenue sur JeuxOnLine - MMO, MMORPG et MOBA !
Les sites de JeuxOnLine...
 

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

help [script] Remplir une bouteille

Par Mastokk le 30/11/2002 à 3:29:52 (#2677132)

Voilà mon problème:
J'ai une fontaine et celle-ci est censée avoir des propriétés curatives. je voudrais que mes PJ puissent remplir des bouteilles vides avec le précieux liquide.
Je me suis dis que le meilleur moyen de le faire était de faire un script qui vérifie qu'ils avaient une bouteille vide sur eux, puis, s'ils en ont une, de la virer de l'inventaire et de leur donner une potion de soins mineurs.
Donc j'ai fais un trigger autour de la fontaine qui déclenche une conversation leur proposant de remplir une bouteille, jusque là tout va bien, mais mon script ne fait rien...
Je me doute qu'il doit y avoir des erreurs (j'ai un gros doute sur mon utilisation du GetObjectByTag par exemple...) mais je ne sais pas comment je dois modifier ce script... D'ailleurs je pense aussi que ce script doit poser problème s'il y a plusieurs bouteilles vides dans l'inventaire.

voici ce que j'ai fais (please même si c'est bourré d'erreurs de noob on ne crie pas ;) *A peur de Jedaï* :D):


#include "nw_i0_tool"
void main()
{
//qui utilise la fontaine
object oClicker = GetClickingObject();
//est ce qu il a une bouteille vide ?
if(!CheckPartyForItem(oClicker, "NW_IT_THNMISC001"))
{
//enlever l'item de l'inventaire
object oItemToTake;
object oItemToGive;
oItemToTake = GetItemPossessedBy(oClicker, "NW_IT_THNMISC001");
oItemToGive = GetObjectByTag("NW_IT_MPOTION001");
ActionTakeItem(oItemToTake, oClicker);
ActionGiveItem(oItemToGive, oClicker);
}
else
{
ActionSpeakString("desole mais vous n'avez pas de bouteille a remplir");
}
}

Re: help [script] Remplir une bouteille

Par Tynril le 30/11/2002 à 4:36:06 (#2677268)

void main() {
//Tu parles d'une conversation, est-ce bien le cas ? Si le script est déclanché d'une conversation, c'est cette fonction qu'il faut utiliser.
object oPC = GetPCSpeaker();
if(GetItemPossessedBy(oPC,"NW_IT_THNMISC001")) {
//Le joueur a au moins une bouteille vide.
//On scan alors chaque item de son inventaire pour
// tester s'il en a plus d'une, et a chaque bouteille
// on lui donne une potion.
object oScan = GetFirstObjectInInventory(oPC);
while(GetIsObjectValid(oScan)) {
if(GetTag(oScan) == "NW_IT_THNMISC001") {
DestroyObject(oScan); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPC); //On donne la potion
}
oScan = GetNextItemInInventory(oPC);
}
}
}

interessant

Par Ronce-iris le 30/11/2002 à 13:51:08 (#2679239)

mais j'ai rien compris au script
vous pouvez faire un petit module de démonstration ?

Par Mastokk le 30/11/2002 à 14:58:14 (#2679662)

Merci pour l'aide. J'ai essayé ton script tynril, en le modifiant un peu pour virer les erreurs de compil, mais rien ne se passe non plus. Voici la version modifiée:

#include "nw_i0_tool"
void main() {
//Tu parles d'une conversation, est-ce bien le cas ? Si le script est déclanché d'une conversation, c'est cette fonction qu'il faut utiliser.
object oPC = GetPCSpeaker();
if(!CheckPartyForItem(oPC,"NW_IT_THNMISC001"))
{
//Le joueur a au moins une bouteille vide.
//On scan alors chaque item de son inventaire pour
// tester s'il en a plus d'une, et a chaque bouteille
// on lui donne une potion.
object oScan = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oScan))
{
if(GetTag(oScan) == "NW_IT_THNMISC001")
{
DestroyObject(oScan); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPC); //On donne la potion
}
oScan = GetNextItemInInventory(oPC);
}
}
else
{
ActionSpeakString("desole mais vous n'avez pas de bouteille a remplie");
}
}



Pour ceux qui n'ont pas bien compris, voici ce que je veux faire étape par étape:

+ Il y a un placeable de fontaine normale dans la zone, dont l'eau est censée avoir des propriétés curatives.

+j'ai entouré la fontaine d'un trigger qui appelle une discussion (j'arrivais pas à faire parler la fontaine elle-même, mais ca rend très bien comme ça ;)). Cette discussion demande au joueur s'il désire remplir une bouteille du précieux breuvage. S'il répond oui, on lance le script ci-dessus.

+Le script est censé vérifier que le PC possède au moins une bouteille vide et pour chaque bouteille vide qu'il possède, la supprimer et lui donner une bouteille de soins des blessures mineures à la place.

+S'il n'a pas de bouteille à remplir, il a le message, "désolé pas de bouteille... blablablabla".

voilà

et ça ne marche pas, le script ne se déclenche pas je crois... je vais vérifier mes tags (c'est bien les tags là qu'il faut mettre ? :doute: :confus: ) et l'appelle du script.

Edit\ bhaa j'ai vérifié, les tags et les resrefs de ces objets sont les mêmes donc c'est pas ça qui pose problème :confus:.

Par Mastokk le 30/11/2002 à 15:45:43 (#2679924)

*bump*
alors, personne n'a d'idée ?

Par Jedaï le 30/11/2002 à 16:36:28 (#2680213)

J'ai l'impression qu'il y a un "!" en trop, essaie plutôt ça :


void RempliBouteille(object oPJ, object oVide)
{
DestroyObject(oVide); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPJ); //On donne la potion

oVide = GetItemPossessedBy(oPJ,"NW_IT_THNMISC001");
if (GetIsObjectValid(oVide))
RempliBouteille(oPJ, oVide);

}

void main() {
//Tu parles d'une conversation, est-ce bien le cas ? Si le script est déclanché d'une conversation, c'est cette fonction qu'il faut utiliser.
object oPC = GetPCSpeaker();

object oBout = GetItemPossessedBy(oPC,"NW_IT_THNMISC001");
if (GetIsObjectValid(oBout))
{
RempliBouteille(oPC, oBout);
}
else
{
ActionSpeakString("Désolé, mais vous n'avez pas de bouteille à remplir.");
}
}



Rien n'est sûr...:D

Par Mastokk le 30/11/2002 à 17:01:32 (#2680354)

Merci pour ton aide Jedaï, j'ai eu 126 potions avec une bouteille vide :D. Et encore, c'est parce qu'il y avait plus de place dans l'inventaire ;).
par contre, quand on a pas de bouteille vide, le script ne dit pas la phrase (il ne donne pas de potions, c'est déjà ça :D).

Bon bhaa si quelqu'un a une idée, elle sera la bienvenue, et je vais voir si j'arrive à modifier tout ça.

Par Jedaï le 30/11/2002 à 17:11:42 (#2680400)

Désolé, le récursif ne fait visiblement pas bon ménage avec DestroyObject() (même si on ne spécifie pas de délai, cette fonction met quand même du temps à détruire l'objet...).

J'en reviens à l'antique sagesse de Tyn' qui a joué la prudence...


void main() {
//Tu parles d'une conversation, est-ce bien le cas ? Si le script est déclanché d'une conversation, c'est cette fonction qu'il faut utiliser.
object oPC = GetPCSpeaker();
if(GetIsObjectValid(GetItemPossessedBy(oPC,"NW_IT_THNMISC001")))
{
//Le joueur a au moins une bouteille vide.
//On scan alors chaque item de son inventaire pour
// tester s'il en a plus d'une, et a chaque bouteille
// on lui donne une potion.
object oScan = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oScan))
{
if(GetTag(oScan) == "NW_IT_THNMISC001")
{
DestroyObject(oScan); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPC); //On donne la potion
}
oScan = GetNextItemInInventory(oPC);
}
}
else
{
ActionSpeakString("Désolé, mais vous n'avez pas de bouteille a remplir.");
}
}


Si si, il y a une différence, essaie et tu verra. ;)

Par Mastokk le 30/11/2002 à 17:20:04 (#2680446)

Décidement je ne comprends pas pourquoi ça refuse de dire la phrase quand a pas de bouteille :confus: .
le script fonctionne, le seul problème est qu'il donne toujours une potion de trop par rapport au nombre de bouteilles vides que le PJ possédait.

Par Jedaï le 30/11/2002 à 17:23:52 (#2680471)

Peut-être que c'est dû à ActionSpeakString(), essaie ça :


void main() {
//Tu parles d'une conversation, est-ce bien le cas ? Si le script est déclanché d'une conversation, c'est cette fonction qu'il faut utiliser.
object oPC = GetPCSpeaker();
if(GetIsObjectValid(GetItemPossessedBy(oPC,"NW_IT_THNMISC001")))
{
//Le joueur a au moins une bouteille vide.
//On scan alors chaque item de son inventaire pour
// tester s'il en a plus d'une, et a chaque bouteille
// on lui donne une potion.
object oScan = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oScan))
{
if(GetTag(oScan) == "NW_IT_THNMISC001")
{
DestroyObject(oScan); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPC); //On donne la potion
}
oScan = GetNextItemInInventory(oPC);
}
}
else
{
SpeakString("Désolé, mais vous n'avez pas de bouteille a remplir.");
}
}

Par Mastokk le 30/11/2002 à 17:35:17 (#2680537)

Pas de changement...

bon alors on le prends ce bain

Par Blam le 30/11/2002 à 17:51:15 (#2680634)

c'est ça la cure, non ? se baigner dans une fontaine de soin :)


C'est excellent !

Par coolstar le 30/11/2002 à 18:37:38 (#2680887)

Ben ça alors ! Perso, j'ai essayé aussi et moi j'ai pas de prob avec les Dials, mais par contre je suis surpris car j'ai toujours au moins une bouteille en trop par rapport à ce que je devrais avoir... :confus:

:D

Par eMRaistlin le 30/11/2002 à 18:38:45 (#2680896)

Si j'ai bien compris, ta conversation est declanchée par un trigger, c'est bien ca ?

Donc, le speakstring demande au trigger de parler. c'est impossible.

Au lieu de SpeakString, utilisez plutot FloatingTextStringOnCreature, pour ce genre de message. c'est plus propre, et ca marche tout le temps. (et ca fait moins bizarre qu'un fontaine qui parle ^^)

Pour la bouteille en trop, je vois pas trop, mais je ne vois qu'une explication, mais c'est capillo-tracté (Nylou™) : ^peu etre que le GetItemPossessedBy() qui rammene un objet le stocke qqpart, et que il le considere hors inventaire.

essaye ca :


void main()
{
object oPC = GetPCSpeaker();
object oScan = GetFirstItemInInventory(oPC);
int nPossede;

while(GetIsObjectValid(oScan))
{
if(GetTag(oScan) == "NW_IT_THNMISC001")
{
DestroyObject(oScan); //On vire la bouteille
CreateItemOnObject("nw_it_mpotion001",oPC); //On donne la potion
nPossede = 1;
}
oScan = GetNextItemInInventory(oPC);
}
if (nPossede != 1)
{
FloatingTextStringOnCreature("Désolé, mais vous n'avez pas de bouteille a remplir.",oPC,TRUE);
}
}


C'est un peu plus lourd en temps machine, mais je pense pas que ce soit vraiment redhibitoire, et ca devrait fonctionner sans bouteille en trop

Par Mastokk le 30/11/2002 à 18:40:05 (#2680903)

Ok si t'as pas de problème avec l'ActionSpeakString c'est que j'ai dû faire une bêtise... Pour la bouteille en trop, j'ai le même problème.

PS: Tu as mis le dialogue sur quoi toi?

Par coolstar le 30/11/2002 à 19:12:02 (#2681099)

k eMR! je vais voir ta proposition de mon côté... ;)

Sinon Mastokk, pour éviter les confusions d'interprétation de Script (les miennes), je teste ceux-ci par étape... Aussi, dans ce cas-là, j'ai juste mis le Script dans le Action conséquente d'un Dial... :D

^^


EDIT
---------------
Le Script de eMR marche aussi bien que celui de Jedaï... c-à-dire que tout tourne comme il faut (avec le "message flottant" ;) ), mais toujours aussi avec le prob de "nombre de fioles acquises"... :confus:
---------------

Par Mastokk le 1/12/2002 à 2:45:37 (#2683331)

Merci eMR ça dit bien la phrase maintenant. par contre la création de potion réagit bizarrement... S'il n'y a pas déjà de potion dans l'inventaire du PJ, ça crée 1 potion de trop. Par contre si le PJ possède déjà une potion de soin ça crée le nombre de potions correspondant au nombre de bouteilles vides.
Dingue non ? :D
Et pis en fait je crois que je vais mettre un préposé aux bouteilles... faut leur donner du boulot à ces tas de pixels :D.

Par coolstar le 1/12/2002 à 6:31:40 (#2683683)

Et si tu invitais tes PJs à faire le plein manuellement, non ? Genre par un Dial descriptif interactif... en cliquant sur la fontaine par exemple (Voulez-vous remplir votre fiole ? Voulez-vous en remplir une autre ?)... ou en utilisant tour à tour les Fioles pour les remplir (par l'ouverture d'un Dial en utilisant le "Pouvoir Unique" du-dit objet sur la fontaine) ??? :D

;)

Par Mastokk le 1/12/2002 à 14:48:50 (#2685511)

ouais me suis pas trop intéressé à ces trucs de pouvoir unique parce que la mise en place me semble lourde...
Enfin vais voir quoi faire.

Par coolstar le 1/12/2002 à 15:31:41 (#2685852)

J'ai testé les 'Unique Power' et ça roule nickel! c comme le reste, juste un truc à intégrer... ;)

Par Tynril le 1/12/2002 à 16:03:16 (#2686040)

Désolé pour les erreur de compil et la bouteille de trop, j'étais un peu fatigué, et quand je suis fatigué j'oublie les bugs de NWN :D

void main() {
//Initialisation des variables
object oPC = GetPCSpeaker();
int nCount = 0;
//Scan de l'inventaire
object oScan = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oScan)) {
if(GetTag(oScan) == "NW_IT_THNMISC001") {
//On detruit toutes les bouteilles vides
DestroyObject(oScan);
//Et on compte combien on en a detruit
nCount++;
}
oScan = GetNextItemInInventory(oPC);
}
if(nCount > 0)
//Si on en a detruit plus de zero, on donne au joueur le nombre de bouteilles que l'on a detruit en potions
CreateItemOnObject("nw_it_mpotion001",oPC,nCount);
else
//Sinon, on l'averti
SendMessageToPC(oPC,"Vous n'avez aucune bouteille à remplir !");
}
Effectivement, DestroyObject est pas instantané :)

Par coolstar le 1/12/2002 à 16:15:15 (#2686081)

Question...



Pourrais-tu être plus précis sur le bug de Biowaaiii!! SVP ??? et aussi préciser ce que tu as cherché à faire... aurais-tu tout simplement compté ce qu'il y avait pour en donner ensuite le même nombre, plutôt que de les donner 1 à 1 (ce qui me paraît plus judicieux!) ??? :confus:

:D

Par Tynril le 1/12/2002 à 16:42:08 (#2686272)

Le bug de Bioware n'en est pas vraiment un. En gros, les DestroyObject sont stockés dans le tampon d'exécution jusqu'à la fin du script, sans rien faire. Quand le script est terminé, le tampon est exécuté. Ca pose problème par exemple pour la récursivité, en créant des boucles récursives infinies. Si Bioware l'a vu ainsi, c'est, je pense, pour pouvoir faire ça :

object oTruc = GetFirstPC();
DestroyObject(oTruc);
SendMessageToPC(oTruc,"PAN !");
Si DestroyObject n'était pas stocké en tampon, oTruc ne serait plus valide pour le SendMessageToPC. C'est d'ailleurs grâce à cette mise en tampon qu'ils ont facilement pu intégrer un Delay à la fonction, sans pour autant garder toutes les variables du script en mémoire (coté mémoire, il est donc plus économique de faire DestroyObject(oObject,10.0f); que DelayCommand(10.0f,DestroyObject(oObject));)

Sinon, effectivement, je contourne le bug en comptant le nombre de bouteille (les détruisant par la même occasion), pour lui donner le même nombre de potions à la fin :)

Par coolstar le 1/12/2002 à 16:46:46 (#2686303)

:maboule:


:merci: :merci: :merci:

Par Jaha Effect le 1/12/2002 à 17:03:15 (#2686411)

Ca serait sympa de nous faire un petit fichier .erf et le mettre à dispo dans les postes persistants du forum.
Ca éviterait que ça tombe dans les oubliettes du forum :D

Jaha Effect :D

Par coolstar le 4/12/2002 à 1:50:40 (#2706678)

Provient du message de Mastokk

Salut tout le monde


Je suis toujours face à mon problème de fontaine. Le script pour remplir les bouteilles vides en bouteilles de soins mineur fonctionne bien mais le problème est comment faire parler la fontaine ?

Ce que j'avais fais: mettre un trigger qui lance la conversation. C'est bien mais y a mieux.

Autre chose que l'on m'avait proposé: Utiliser le Unique Power.
Alors là je dis ok: Mais comment je fais sur une fontaine ?! En effet, pour trouver les Unique Power (Unique Power Self et Unique Power) il faut éditer l'objet, aller dans ses propriétés, ouvrir cast spell et choisir entre unique power et unique power self.
Ok, mais ça n'est possible que sur les armes, armures et autres joyeusetés.
Il n'y a pas d'onglet propriétés sur une fontaine, ni sur une pierre d'ailleurs.

Alors comment on fait ? :confus:


Pour ce qui est d'utiliser les Pouvoirs Uniques tu as un Fil par ici où le Sujet a été quelque peu débatu... :D


;)




EDIT
-----------------
Autrement, ma suggestion serait d'opter pour le "Pouvoir Unique" associé aux Bouteilles... Le Script se déclencherait alors (uniquement) en utilisant le "Pouvoir" des Bouteilles sur la Fontaine... Dans les Actes ça donnera tout simplement l'impression que l'on prend la Bouteille pour la remplir... Non ?? :rolleyes:
-----------------

Par Mastokk le 4/12/2002 à 2:02:25 (#2706712)

Je sais utiliser la fonction recherche Coolstar et j'ai lu tous les posts sur le sujet. Le problème c'est que le Unique Power n'est pas accessible sur tous les objets. Et sur une fontaine par exemple, ca n'existe pas...

Par coolstar le 4/12/2002 à 2:07:49 (#2706728)

Le Script se déclencherait alors (uniquement) en utilisant le "Pouvoir" des Bouteilles sur la Fontaine...

Huummm... Effectivement, seuls les Items ont droit aux "Pouvoirs Uniques"! donc, c'est à partir de eux et vers les Placeables qu'il faut agir... (j'ai fait parler des NPCs comme ça... alors le reste, c du pareil au même, non ?) :D



PS : Et désolé si je t'ai présenté un Fil que tu aurais pu trouvé... c'était juste au cas où! je ne voulais pas te remettre en cause... ;)

Par RAT le 4/12/2002 à 2:16:41 (#2706748)

ba tu ne le remets pas en cause, tu lui donnes plusieurs solutions et tu essayes de l'aider , c'est le principal non?:p.

Par RAT le 4/12/2002 à 2:22:01 (#2706763)

Mastokk, on continue la suite ici :). Pour éviter de valser sur deux post en même temps si tu veux bien :).

Par Mastokk le 4/12/2002 à 2:24:54 (#2706775)

oki problème réglé sur ce post là grace à RAT :).

Par RAT le 4/12/2002 à 2:27:19 (#2706780)

De nada mastokk, je suis là pour ça :)

Par coolstar le 4/12/2002 à 2:34:27 (#2706802)

:sanglote:

Par Mastokk le 4/12/2002 à 2:59:01 (#2706847)

Désolé si j'ai été sec coolstar, ce truc m'énervait ;). Merci pour l'aide :). Et arrête de pleurer !

Par coolstar le 4/12/2002 à 3:07:38 (#2706870)

:D

JOL Archives 1.0.1
@ JOL / JeuxOnLine