Archives des forums MMO/MMORPG > Neverwinter Nights > NWN - Maskado > help [script] Remplir une bouteille
help [script] Remplir une bouteille
Par Mastokk le 30/11/2002 à 3:29:52 (#2677132)
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)
vous pouvez faire un petit module de démonstration ?
Par Mastokk le 30/11/2002 à 14:58:14 (#2679662)
#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)
alors, personne n'a d'idée ?
Par Jedaï le 30/11/2002 à 16:36:28 (#2680213)
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)
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)
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)
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)
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)
bon alors on le prends ce bain
Par Blam le 30/11/2002 à 17:51:15 (#2680634)
C'est excellent !
Par coolstar le 30/11/2002 à 18:37:38 (#2680887)
:D
Par eMRaistlin le 30/11/2002 à 18:38:45 (#2680896)
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)
PS: Tu as mis le dialogue sur quoi toi?
Par coolstar le 30/11/2002 à 19:12:02 (#2681099)
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)
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)
;)
Par Mastokk le 1/12/2002 à 14:48:50 (#2685511)
Enfin vais voir quoi faire.
Par coolstar le 1/12/2002 à 15:31:41 (#2685852)
Par Tynril le 1/12/2002 à 16:03:16 (#2686040)
void main() {
Effectivement, DestroyObject est pas instantané :)
//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 !");
}
Par coolstar le 1/12/2002 à 16:15:15 (#2686081)
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)
object oTruc = GetFirstPC();
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));)
DestroyObject(oTruc);
SendMessageToPC(oTruc,"PAN !");
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)
:merci: :merci: :merci:
Par Jaha Effect le 1/12/2002 à 17:03:15 (#2686411)
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)
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)
Par RAT le 4/12/2002 à 2:22:01 (#2706763)
Par Mastokk le 4/12/2002 à 2:24:54 (#2706775)
Par RAT le 4/12/2002 à 2:27:19 (#2706780)
Par coolstar le 4/12/2002 à 2:34:27 (#2706802)
Par Mastokk le 4/12/2002 à 2:59:01 (#2706847)
Par coolstar le 4/12/2002 à 3:07:38 (#2706870)
JOL Archives 1.0.1
@ JOL / JeuxOnLine