[résolu] Détecter Si Une Cellule Intérieure A Un Niveau D'eau
#1
Posté 17 juillet 2009 - 11:45
Afin d'empêcher que le joueur puisse se servir de bombes sous l'eau, j'ai utilisé les fonctions GetPos Z, GetInterior ainsi que GetWaterLevel.
C'est d'une simplicité enfantine:
- si le joueur est en extérieur, il suffit de détecter si la bombe renvoie un Z négatif... dans ce cas elle est sous l'eau et pfuit!
- si le joueur est en intérieur, il suffit de détecter si la valeur du niveau d'eau de la cellule est supérieur à la coordonnée de la bombe sur l'axe des Z... dans ce cas, elle est sous l'eau et pfuit!
Mais...
si la cellule n'a pas d'eau, c'est la dernière valeur du GetLevelWater qui est tenue en compte, ce qui fausse tous les calculs: si par hasard la bombe se trouve au-dessous du niveau d'eau de la cellule précédente, ça fait forcément pfuit! alors que la bombe est au sec.
D'où ma question: est-il possible de détecter par script si la cellule intérieure dans laquelle on se trouve n'a pas d'eau?
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#2
Posté 17 juillet 2009 - 11:49
La solution qui me semble la plus simple est simplement de mettre de l'eau dans toutes tes cellules, et si tu veux une cell "sans eau", tu places son niveau bien en-dessous de tout le reste (pas juste en dessous sinon tu vas avoir le sound).
Ainsi, tes niveaux d'eau sont respectés pour chaque cell, tu as un "WaterLevel" défini dans chacune, et tu n'as rien à modifier de ton script bien pensé.
#3
Posté 17 juillet 2009 - 11:57
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#4
Posté 17 juillet 2009 - 12:10
Je pense que tu devrais essayer de passer par une des "caractéristiques" de la présence de l'eau. A réfléchir, je vois bien le GetSoundPlaying "Water Layer" et GetSoundPlaying "drown" (le premier étant la surface de l'eau, le second le son de la respiration sous l'eau). Si aucun des deux n'est joué, tu n'as pas d'eau à proximité. Si l'un des deux joue, tu peux alors faire le GetWaterLevel.
Du genre :
Begin BombScript If ( GetSoundPlaying "Water Layer" == 1 ) If ( GetPos Z < GetWaterLevel ) ; Pfuit Endif Endif If ( GetSoundPlaying "drown" == 1 ) If ( GetPos Z < GetWaterLevel ) ; Pfuit Endif Endif End
A priori, dans un autre cell sans eau, tu vas avoir le GetWaterLevel qui va renvoyer n'importe quoi, mais comme tu n'auras pas les sons qui jouent, tu n'auras pas le Pfuit. Et dans une Cell avec de l'eau tu as forcément l'un de ces deux sons qui jouent (puisque c'est soit celui de surface, soit celui en dessous), donc le test est comme avant.
Maintenant faut tester voir si ça marche, je ne l'ai pas fait, et je ne suis pas sûr à 100% que les GetSoundPlaying marchent si le joueur a coupé le volume de tous les sons, bien qu'à mon avis, ça passe.
Je ne garantis rien, donc, mais ça peut être une idée.
#5
Posté 17 juillet 2009 - 12:12
Plutôt que chercher si la cellule contient de l'eau, ne serait-il pas plus facile de savoir si le joueur est dans l'eau?...
Il devrait suffire de faire un test sur "GetSoundPlaying", avec les sons "Swim left", "Swim right", "Underwater" et "Drowning damage", qui sont, à ma connaissance, les seuls sons associés au milieu aquatique...
Mais c'est juste une théorie, je n'ai pas testé le résultat...
***Edit***
J'ai été prise de vitesse par une Souris Cornue... C'est sûrement la preuve que je ne suis pas trop loin de la solution....
(Wiwi d'or de la plus serviable et de la plus cool... Merci à vous tous...)
#6
Posté 17 juillet 2009 - 12:15
#7
Posté 17 juillet 2009 - 12:17
Je m'en vais essayer tout ça et je vous redis.
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#8
Posté 17 juillet 2009 - 16:12
Souris Cornue, le 17.07.2009 à 13:09, dit :
J'avais eu du mal à le comprendre à cause de cette phrase imprécise du MSfD : ""GetSoundPlaying" Renvoie 1 lorsque le son spécifié est actuellement joué."
#9
Posté 17 juillet 2009 - 17:18
En tout cas, j'ai essayé en testant swim left et swim right avec comme appelant le PJ... et ça ne semble pas fonctionner... Par ailleurs, il y a fort à parier que si le joueur restait immobile, ces sons ne seraient pas joués...
Pour le drown, il n'est joué qu'en cas de noyade... et je me demande ce qui joue le son waterlayer... mais probablement pas un objet unique...
Il me semble donc difficile de passer par des sons.
J'ai pensé essayer de faire quelque chose avec la jauge d'air, mais c'est en fait un mauvais critère, puisque le joueur peut très bien barboter.
J'avais songé placer faire à chaque changement de cellule un setup de la variable récupérant le niveau de l'eau qui la mettait à -900'000, en espérant que dans une cellule sans niveau d'eau ça ne bougerait plus et que les bombes sauteraient alors que dans une cellule avec niveau d'eau, le niveau réel prendrait le relais... mais manifestement ça ne fonctionne pas non plus. Tout porte à croire que s'il n'y a pas de niveau d'eau, le tescs considère que la valeur est 0, ce qui est fort embêtant.
Dernière idée: il me semble que le sommeil détectait si le joueur avait les pieds dans l'eau. "You can only rest on solid ground." Quelqu'un sait comment ça marche?
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#10
Posté 17 juillet 2009 - 19:16
Not Quite Dead, le 17.07.2009 à 18:17, dit :
Not Quite Dead, le 17.07.2009 à 18:17, dit :
begin testeau if ( "player"->GetSoundPlaying "DefaultLandWater" == 1 ) MessageBox "Plouf, sacré plongeon !" elseif ( "player"->GetSoundPlaying "FootWaterLeft" == 1 ) MessageBox "Nage ou marche sur l'eau (G)." elseif ( "player"->GetSoundPlaying "FootWaterRight" == 1 ) MessageBox "Nage ou marche sur l'eau (D)." elseif ( "player"->GetSoundPlaying "drowning damage" == 1 ) MessageBox "Tu vas bientôt nourrir les poissons." endif end
Note que marcher sur l'eau et nager utilise les mêmes sons ! (Ces sons ont d'ailleurs les mêmes "wav" que les "Swim").
Not Quite Dead, le 17.07.2009 à 18:17, dit :
Not Quite Dead, le 17.07.2009 à 18:17, dit :
Not Quite Dead, le 17.07.2009 à 18:17, dit :
#11
Posté 17 juillet 2009 - 19:26
Citation
Il y a peut être une parade...
Si le script détecte un waterlevel à 0 en entrant dans la cellule:
mettre le waterlevel à 1
si après cela, getwaterlevel renvoit à 1 -> il y a de l'eau puisque setwaterlevel en a changé le niveau
puis remettre le waterlevel à 0 , pour éviter d'éventuels problèmes de scripts venant d'autres modules.
Si le waterlevel ne change pas -> pas d'eau, pas de pfuit
Qu'en pensez-vous?
Modifié par Von Zeeple, 17 juillet 2009 - 19:27.
#12
Posté 17 juillet 2009 - 19:31
elendell, le 17.07.2009 à 20:15, dit :
Not Quite Dead, le 17.07.2009 à 18:17, dit :
Je testerai ça dans le détail dans une dizaine de jours: là il me faut me mettre au préparatifs de voyage: je pars en vacances demain.
Il faudra que je jette également un coup d'oeil à la suggestion de Von Zeeple.
Merci à tous pour votre aide sur cet épineux problème.
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#13
Posté 17 juillet 2009 - 19:34
A tester, donc.
EDIT :
Citation
#14
Posté 17 juillet 2009 - 19:36
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
#15
Posté 17 juillet 2009 - 21:42
Citation
Sans vouloir parler à la place de NQD, il me semble qu'il s'agissait plutôt d'un:
set Var_niveau to -900 set Var_niveau to getwaterlevel;en espérant que getwaterlevel laisserait Var_niveau à -900 dans le cas d'une cellule sans eau
Ce que je proposais était:
setwaterlevel to 1 if ( getwaterlevel != 1 ); si le niveau n'a pas changé, par exemple, valeur dans la cell précédente set humide to 0 elseif ( getwaterlevel == 1 ) set humide to 1 endif remettre au niveau d'origine
j'ai enlevé le "if (getwaterlevel == 0)" car j'avais oublié que getwaterlevel renvoyait la valeur de la cell précédente.
Il est possible que le niveau d'eau de la cell précédente soit 1, il faut donc prévoir un système d'incrémentation pour être sur de détecter la variation de la valeur renvoyée par getwaterlevel.
Modifié par Von Zeeple, 17 juillet 2009 - 21:44.
#16
Posté 18 juillet 2009 - 01:15
Von Zeeple, le 17.07.2009 à 22:41, dit :
setwaterlevel to 1 if ( getwaterlevel != 1 ); si le niveau n'a pas changé, par exemple, valeur dans la cell précédente set humide to 0 elseif ( getwaterlevel == 1 ) set humide to 1 endif
J'ai fait différents essais de scripts, en une ou plusieurs frames et avec les cellules suivantes : "Abanabi" (eau à -1200), "Todd" (pas d'eau), "Vivec, canal des Mystères, centre" (eau à 0).
Contrairement à ce qu'indique NQD, "GetWaterLevel" fonctionne dans tous les cas. Si la nouvelle cellule n'a pas d'eau, elle retourne 0 et pas la valeur du dernier test où il y avait de l'eau. On ne peut bien sûr pas en déduire qu'il n'y a pas d'eau puisque l'eau peut être à 0.
Le problème pour ta proposition est que "SetWaterLevel" fonctionne également, même si la case "Has Water" de la cellule n'est pas cochée. Donc, en faisant "SetWaterLevel 1" (sans le "to" pour la fonction), tu n'auras jamais "GetWaterLevel != 1".
Note : "ModWaterLevel" fonctionne également.
EDIT pour NQD :
En attendant de voir le script à ton retour, je note une réflexion pour ne pas l'oublier :
elendell, le 17.07.2009 à 20:15, dit :
Not Quite Dead, le 17.07.2009 à 18:17, dit :
Et de toute façon, si c'est un local, il ne tournera plus.
#17
Posté 18 juillet 2009 - 10:19
Not Quite Dead, le 22.06.2006 à 19:42, dit :
Fervent Partisan de l'Immuabilité Avatarienne.
#18
Posté 20 juillet 2009 - 20:11
Finraïl, le 18.07.2009 à 11:18, dit :
(Au passage, il est très bien ce module ! )
Note : En me relisant, je m'aperçois que je n'ai pas vérifié quel son est joué quand le PJ marche sur l'eau. Si c'est le même son (les FootWater), en tenez-vous compte dans Mr_Armor pour ne pas appliquer les malus dans ce cas ?
Mais je reviens au présent sujet :
J'ai trouvé le moyen de détecter si un objet est dans l'eau à un moment précis. Ça correspond donc, je pense, au besoin de NQD pour sa bombe. On ne se préoccupe plus de savoir s'il y a de l'eau ou non dans la cellule, ni même si le PJ lui-même est sous l'eau.
De plus, on peut faire ce test à n'importe quel moment. Quand le PJ dépose la bombe, quand il l'active ou encore, quand elle devrait exploser si c'est un objet à lancer (cas où la bombe serait lancée dans un endroit sec mais avec le PJ qui serait dans l'eau ou l'inverse, comme évoqué par Finraïl).
Le principe : En cherchant à détecter le lancement d'Undewater qui se produit quand le PJ entre sous l'eau, je me suis aperçu de particularités des sons d'environnements. Je ferai un sujet sur ça car se servir des mêmes ID de sons dans un "mod" peut avoir des répercussions étranges et non souhaitables.
Je n'ai pas réussi à détecter le lancement automatique d'Underwater mais on peut détecter l'arrêt de ce son qui se produit quand le PJ n'est plus sous l'eau. Contrairement à un "StopSound" qui ne stoppe habituellement un son ciblé que s'il cible lui aussi cet objet, le "StopSound" de sons d'environnement stoppe tous les sons correspondants, même s'ils sont ciblés.
Donc, pour savoir si un objet est sous l'eau, je place le PJ au même endroit que l'objet (plus bas pour tenir compte de la différence de hauteur des centres), je fais jouer Underwater par le PJ (avec un volume à 0), je place le PJ à une hauteur à coup sûr hors de l'eau et je teste si le PJ a toujours Underwater actif.
Si l'objet est sous l'eau, le fait de placer le PJ au même endroit déclenche le Underwater environnemental. Comme ce dernier est actif, si à la frame suivante le PJ est hors de l'eau, ça déclenche automatiquement le "StopSound" qui va également stopper le Underwater ciblé sur le PJ. Ensuite, il suffit de replacer le PJ à sa position d'origine et de faire un "StopSound" ciblé sur lui.
Ce StopSound ciblé est nécessaire pour 2 raisons : 1) Si l'objet n'était pas dans l'eau, il n'y a pas de "StopSound" environnemental et 2) S'il était sous l'eau il faut quand même le stopper parce que sinon, si le PJ va sous l'eau par la suite dans la même cellule, le Underwater environnemental qui serait lancé aurait les réglages qu'on avait donné à l'Underwater ciblé.
Bref, voici le script en question :
begin Bombe_Scr ; Script local pour tester si un objet est sous l'eau à un moment précis. short etape short son short sousleau float posx float posy float posz float posxPJ float posyPJ float poszPJ if ( OnActivate == 1 ); OnActivate ne sert que pour ce script d'essai, pour dire de lancer le test. set posxPJ to ( Player->GetPos x ) set posyPJ to ( Player->GetPos y ) set poszPJ to ( Player->GetPos z ) set posx to GetPos x set posy to GetPos y set posz to GetPos z set posz to ( posz - 120 ); à régler en fonction de son centre dans le NIF et si l'on veut que le script relève seulement l'immersion totale ou même partielle de l'objet. TCL Player->SetPos x posx Player->SetPos y posy Player->SetPos z posz set etape to 1 endif if ( etape == 1 ) Player->PlayLoopSound3DVP Underwater 0.0 0.0 set etape to 2 elseif ( etape == 2 ) Player->SetPos z 10000 set etape to 3 elseif ( etape == 3 ) ; on attend une frame car dès fois, une seule ne suffit pas pour valider ; le "StopSound" automatique, quand le PJ n'est plus dans l'eau. set etape to 4 elseif ( etape == 4 ) set son to ( Player->GetSoundPlaying, Underwater ) Player->StopSound, Underwater if ( son == 1 ) MessageBox "La mèche est hors de l'eau." set sousleau to 0; pour le reste du script si besoin else MessageBox "La mèche est sous l'eau !" set sousleau to 1; pour le reste du script si besoin endif Player->SetPos x posxPJ Player->SetPos y posyPJ Player->SetPos z poszPJ TCL set etape to 0 activate; Ne sert que pour l'essai endif end
Voila. Cette version finale a fonctionné dans tous mes essais. Les seuls petits inconvénients que j'ai trouvés sont qu'il se produit un petit éclair très rapide (le PJ est placé en plein ciel pendant 2 frames) et une micro coupure du son Underwater si le PJ est sous l'eau. Mais je pense que ce n'est pas très gênant pour ce que ça permet de faire.
#19
Posté 22 juillet 2009 - 20:29
elendell, le 20.07.2009 à 21:10, dit :
elendell, le 20.07.2009 à 21:10, dit :
elendell, le 20.07.2009 à 21:10, dit :
Not Quite Dead, le 22.06.2006 à 19:42, dit :
Fervent Partisan de l'Immuabilité Avatarienne.
#20
Posté 23 octobre 2009 - 13:52
J'ai utiliser la variable OnPCDrop comme déclencheur et j'ai dû un peu déplacer certaines sections du script pour éviter des court-circuits avec la partie pillée à Fandorn, mais c'est à présent opérationnel.
Je pense probablement donner accès aux bombes via une autre quête dans le module, afin de les rendre accessibles à un plus large public. Le travail que vous avez effectué vaut bien cela!
Encore merci à tous pour votre aide.
- You were a doctor!
- I had bad days! »
John Watson, en train d'étrangler Sherlock Holmes, Sherlock - A Scandal in Belgravia (2012)
---------------
Vous aussi rejoignez les Fervents Partisans de l'Immuabilité Avatarienne!
---------------
VGM impénitent (était-il besoin de le préciser?)
---------------
Paterfamilias niv.IV
0 utilisateur(s) li(sen)t ce sujet
0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)