Voir le sujet précédent ¤
Voir le sujet suivant
|
Auteur |
Message |
Djezebel
Héros
Inscrit le: 29 Sep 2005
Messages: 252
|
Posté le : 27/02/2006 11:09:39 Sujet du message : [Résolu !] Spawn à base d'un placeable
Bonjour, je tente de réaliser un script, mais ça fait bien planter le jeu (freeze et obligé de tuer le process).
L'idée : Dans une grande salle il y a plusieurs trous (dans l'exemple deux). Au moment où les joueurs entrent dans cette salle, des insectes sortent de ces trous pour les attaquer.
Le but : "reboucher" les trous (en attaquant les placeables et en les détruisant).
Pour faire cela, j'ai utilisé :
- Un placeable "grand trou" avec pour tag "Trou1"
- Un placeable "grand trou" avec pour tag "Trou2"
- Un waypoint intitulé "Spwn1"
- Un waypoint intitulé "Spwn2"
- Un grand trigger dans toute la salle
Voici le script qui est sur le trigger dans le OnEnter (et qui fait planter)
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Edit : Vous trouverez la solution apportée par Enki avec les conseils de lylver dans ce spoiler :
Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.Spoiler :
Script à mettre sur le onEnter du trigger :
NWScript :void TestPersistantPC () { object oPo = GetFirstInPersistentObject( OBJECT_SELF); while( GetIsObjectValid( oPo)) { if ( GetIsPC( oPo)) { SetLocalInt( OBJECT_SELF, "insect", 1); } oPo = GetNextInPersistentObject( OBJECT_SELF); } } void SpawnInsect( object oTrou, location lLoc, float fDelay) { if ( GetLocalInt( OBJECT_SELF, "insect")== 1) { if ( GetIsObjectValid( oTrou) == TRUE) { CreateObject( OBJECT_TYPE_CREATURE, "nw_btlbomb", lLoc, FALSE); } DelayCommand( fDelay, SpawnInsect( oTrou, lLoc, fDelay )); } } void main() { object oPC= GetEnteringObject(); if ( GetLocalInt( OBJECT_SELF, "insect")== 1) return; if ( GetIsPC( oPC)) { object oT1 = GetNearestObjectByTag( "Trou1"); object oT2 = GetNearestObjectByTag( "Trou2"); location lSpwn1 = GetLocation( GetWaypointByTag( "Spwn1")); location lSpwn2 = GetLocation( GetWaypointByTag( "Spwn2")); TestPersistantPC (); SpawnInsect( oT1, lSpwn1, 10.0 ); SpawnInsect( oT2, lSpwn2, 13.0 ); } } Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Script à mettre dans le OnExit du trigger
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Merci encore !
Dernière édition par Djezebel le 03/03/2006 07:50:18; édité 4 fois
|
|
Revenir en haut |
|
|
Sith Vicious
Grand Sage du Conseil
Inscrit le: 19 Oct 2005
Messages: 693
|
Posté le : 27/02/2006 11:44:24 Sujet du message :
Les actions ne marchent que pour des créatures, tu ne peux pas créer une pause dans un script par cette commande (ni avec aucune autre d'ailleurs) donc du coup ça fait planter car le script s'affole (tu crées environ 1000 insectes avant qu'il décroche avec un too many instructions donc il sait plus ooù les mettre et ta carte graphique aussi balaise soit-elle doit avoir du mal à les dessiner)
Il y avait eu une demande un peu pareil il y a quelques temps, pour qu'un placeable spawn des monstres, ça m'avait plu j'avais fait un cript pour. Ca spawn un certain nombre de monstres au début puis ça en recrée un à chaque fois qu'un est tué. Le script donne ça, sur le OnUserDefinedEvent du plaçable :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Donc ça se lance à partir du OnEnter du trigger en lançant un EventUserDefined(73212) et tu rajoutes une ligne sur le OnDeath des insectes tu mets :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Je pense qu'en l'arrangeant tu peux faire ce que tu cherches ou t'en inspirer du moins.
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 27/02/2006 12:03:47 Sujet du message :
EDIT : Je vois que Sith Vicius dégaine plus vite que moi ! je laisse quand même mon script, il peut toujours servir.
Salut Djezebel, ça va bien ?
En fait, tu ne peux pas mettre de boucle de ce genre sur le onEnter, le trigger va créer un trés grand nombre de monstres en même temps. De plus le ActionWait ne marche que sur des créatures il me semble.
Avec ce script, cela devrait marcher ! (je l'ai testé, ça a l'air d'aller.)
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Au fait, est-ce que tu as testé le hak d'animation que nous avons réalisé avec Argyl ?
Je suis sûr qu'il t'amusera beaucoup !
A bientôt !
|
|
Revenir en haut |
|
|
Djezebel
Héros
Inscrit le: 29 Sep 2005
Messages: 252
|
Posté le : 27/02/2006 13:32:55 Sujet du message :
Salutations Sith Vicious et Enki !
Merci encore pour votre précieuse aide.
Sith Vicous > J'avais effectivement trouvé ton script en recherche, mais le repop se faisait automatiquement à la mort d'une des créatures et ce n'était pas vraiment mon intention. Il fallait de plus prendre en compte qu'un placeable soit valide.
En tout cas, merci pour ta réponse si rapide et ton explication
Enki > Ca va bien, merci et toi ? Le script fonctionne très bien, j'y ai apporté une petite modification pour qu'en fonction des "trous" il y ait des temps de réapparition différents. Ca permet justement aux joueurs d'établir des stratégies pour savoir quel trou reboucher en premier.
Ca donne ceci :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Je n'ai malheureusement pas testé le hak d'animations, où puis-je le trouver ? ^^
|
|
Revenir en haut |
|
|
Sith Vicious
Grand Sage du Conseil
Inscrit le: 19 Oct 2005
Messages: 693
|
Posté le : 27/02/2006 13:43:27 Sujet du message :
Yup c'est vrai que mon script donne pas tout à fait ce que tu voulais (enfin il prends aussi en compte que le placeable est valide, puisque s'il ne l'est plus, l'event ne peut pas se déclancher). Mais je te conseille quand même de rajouter un compteur de monstres spawnés et tués pour ne pas en faire trop (ie un joueur rentre dans le trigger, se fait pourrir la tête et se barre) sinon tu risques un gros gros lag.
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 27/02/2006 14:17:38 Sujet du message :
NWScript :void SpawnInsect( object oTrou, location lSpwn, float fDelay) { if( GetIsObjectValid( oTrou) ) { CreateObject( OBJECT_TYPE_CREATURE, "nw_btlbomb", lSpwn, FALSE); } if( GetLocalInt( oTrou, "PCHERE") ) DelayCommand( fDelay, SpawnInsect()); } void main() { object oPC = GetEnteringObject(); object oT1 = GetNearestObjectByTag( "Trou1"); object oT2 = GetNearestObjectByTag( "Trou2"); location lSpwn1 = GetLocation( GetWaypointByTag( "Spwn1")); location lSpwn2 = GetLocation( GetWaypointByTag( "Spwn2")); if ( GetIsPC( oPC)) { SpawnInsect( oT1, lSpwn1, 10.0); SetLocalInt( oT1, "PCHERE", TRUE); SpawnInsect( oT2, lSpwn2, 13.0); SetLocalInt( oT2, "PCHERE", TRUE); } } Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème. _________________ TSLODOSS
TN Bouchon 2
NWN-FF
The DMFI
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 27/02/2006 17:08:14 Sujet du message :
Oui, Lylver a raison, il faut un script sur le onExit au cas où le PJ se fait tuer ou s'enfuit.
|
|
Revenir en haut |
|
|
Djezebel
Héros
Inscrit le: 29 Sep 2005
Messages: 252
|
Posté le : 28/02/2006 11:36:44 Sujet du message :
Rebonjour !
Je n'avais effectivement pas finalé pour la sortie mais se pose deux autres problèmes ^^
Le premier, dans le script de Lylver, ça met une erreur de compilation à cette ligne :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Visiblement, il n'aprécie pas le "SpawnInsect" quand ce n'est pas définit.
Le second problème (et non des moindre) : le script de spawn va se lancer à chaque fois que quelqu'un entre sur le trigger...
Donc dans mon teste, je passe une fois, je repars. Je reviens 30 secondes plus tard et alors qu'il n'y avait que 2 cafards, il y en a 8 et le nombre va doublant vu que je suis repassée sur le onEnter...
Donc comment réajuster cette partie de script ?
Merci encore !
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 28/02/2006 12:01:02 Sujet du message :
Salut !
Pour le script de Lylver, il suffit de mettre ceci à mon avis :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Si le script onExit de Lylver fonctionne, alors, tout devrait bien se passer normalement ? Je ne comprends pas où est le problème, je vais tester ces scripts, pour voir ce que ça fait chez moi ^^
A bientôt !
|
|
Revenir en haut |
|
|
Djezebel
Héros
Inscrit le: 29 Sep 2005
Messages: 252
|
Posté le : 28/02/2006 12:07:16 Sujet du message :
En ajoutant cette ligne ça résoud à moitié le problème (ou le bloque à moitié ^^ )
Quand le joueur entre sur le trigger, ça spawn une fois mais c'est tout.
Et s'il repasse, ça respawn.
Le but est quand même que tant que le joueur est sur le trigger ça spawn en boucle ^^.
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 01/03/2006 15:25:34 Sujet du message :
ah oui, oups, j'ai oublié le passage des paramètres.
Sinon modifie la partie suivante :
Code :
if (GetIsPC(oPC))
{
SpawnInsect(oT1,lSpwn1,10.0);
SetLocalInt(oT1,"PCHERE",TRUE);
SpawnInsect(oT2,lSpwn2,13.0);
SetLocalInt(oT2,"PCHERE",TRUE);
}
en
NWScript :if ( GetIsPC( oPC)) { if( ! GetLocalInt( oT1, "PCHERE") ){ SpawnInsect( oT1, lSpwn1, 10.0); SetLocalInt( oT1, "PCHERE", TRUE); } if( ! GetLocalInt( oT1, "PCHERE") ){ SpawnInsect( oT2, lSpwn2, 13.0); SetLocalInt( oT2, "PCHERE", TRUE); } } Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Ca évitera le lancement de multiples itérations
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 01/03/2006 17:08:26 Sujet du message :
Si la solution de Lylver n'est pas efficace, voici ce que je te propose et qui marche assez bien. (du moins en solo ).
tu reprends mon script, ou ceux que tu as fait à partir du mien, (désolé, je me fais de la pub ! ).
et tu rajoutes une condition avec une variable dans la fonction.
ex :
NWScript :void SpawnInsect() { object oT1 = GetObjectByTag( "Trou1"); object oT2 = GetObjectByTag( "Trou2"); location lSpwn1 = GetLocation( GetWaypointByTag( "Spwn1")); location lSpwn2 = GetLocation( GetWaypointByTag( "Spwn2")); if ( GetLocalInt( OBJECT_SELF, "insect")== 1) { if ( GetIsObjectValid( oT1) == TRUE) { CreateObject( OBJECT_TYPE_CREATURE, "nw_btlbomb", lSpwn1, FALSE); } if ( GetIsObjectValid( oT2) == TRUE) { CreateObject( OBJECT_TYPE_CREATURE, "nw_btlbomb", lSpwn2, FALSE); } DelayCommand( 10.0, SpawnInsect()); } } void main() { object oPC= GetEnteringObject(); if ( GetIsPC( oPC)) { SetLocalInt( OBJECT_SELF, "insect", 1); SpawnInsect(); } } Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
et tu mets ceci sur le onExit du trigger :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Le seul problème que j'envisage, c'est si deux ou plusieurs joueurs entrent dans le trigger mais seulement l'un d'eux en sort. Il se peut que le spawn de cafard s'arrête bien qu'il y ait encore quelqu'un sur le déclencheur.
Mais c'est déja une piste.
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 01/03/2006 17:58:11 Sujet du message :
Bon, ne tiens pas compte de mon post précédent, je le laisse pour qu'il y ait le raisonnement en entier.
EDIT :
Mets ce (nouveau) script dans le OnEnter et je pense que cela marchera correctement !
(avec le précédent pour le onExit)
NWScript :void TestPersistantPC () { object oPo = GetFirstInPersistentObject( OBJECT_SELF); while( GetIsObjectValid( oPo)) { if ( GetIsPC( oPo)) { SetLocalInt( OBJECT_SELF, "insect", 1); } oPo = GetNextInPersistentObject( OBJECT_SELF); } } void SpawnInsect( object oTrou, location lLoc, float fDelay) { if ( GetLocalInt( OBJECT_SELF, "insect")== 1) { if ( GetIsObjectValid( oTrou) == TRUE) { CreateObject( OBJECT_TYPE_CREATURE, "nw_btlbomb", lLoc, FALSE); } DelayCommand( fDelay, SpawnInsect( oTrou, lLoc, fDelay )); } } void main() { object oPC= GetEnteringObject(); if ( GetLocalInt( OBJECT_SELF, "insect")== 1) return; if ( GetIsPC( oPC)) { object oT1 = GetNearestObjectByTag( "Trou1"); object oT2 = GetNearestObjectByTag( "Trou2"); location lSpwn1 = GetLocation( GetWaypointByTag( "Spwn1")); location lSpwn2 = GetLocation( GetWaypointByTag( "Spwn2")); TestPersistantPC (); SpawnInsect( oT1, lSpwn1, 10.0 ); SpawnInsect( oT2, lSpwn2, 13.0 ); } } Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.
Voilà, j'ai pas fait le test en Multi ^^, mais d'après moi, cela devrait aller.
Si quelqu'un voit une erreur de ma part, qu'il n'hésite pas à la souligner, j'en aurai bien besoin !
Autre chose, si le joueur s'amuse à entrer-sortir du trigger, il y aura plein de monstres, mais s'il fuit de manière logique lorsqu'il revient le spawn des monstres sera normal.
Voilà, à bientôt !
Dernière édition par Enki le 02/03/2006 10:16:45; édité 1 fois
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 01/03/2006 18:23:47 Sujet du message :
Bon grosso-modo on fait tous la même chose.
Cependant, Enki, j'ai modifié ton script SpawnInsect pour des raisons d'optimisation, je m'explique... dedans tu fais des appels à des fonctions de recherche :
object oT1 = GetObjectByTag("Trou1");
object oT2 = GetObjectByTag("Trou2");
location lSpwn1 = GetLocation(GetWaypointByTag("Spwn1"));
location lSpwn2 = GetLocation(GetWaypointByTag("Spwn2"));
C'est consommateur de temps et c'est la raison pour laquelle je les fait calculer une seule fois dans la fonction main(), c'est mieux d'une manière générale quand tu utilises la récursivité. La propagation par variable est peu consommatrice en mémoire dans notre cas mais surtout carrément plus économe côté calcul.
Egalement il faut utiliser plutot GetNearestXXX qui restreint la recherche dans la zone quand tu n'as pas besoin de fouiller ailleurs.
Dernière remarque : attention à OBJECT_SELF pour TestPersistentPC, c'est une fonction qui retourne un objet et pas une constante, quand tu la sors de son "scope" originel, tu n'est pas sûr de sa valeur.
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 01/03/2006 18:35:20 Sujet du message :
Merci de toutes ces précisions Lylver, n'étant pas du tout dans l'informatique et nwn depuis longtemps, je ne suis pas familiers des notions d'optimisation.
Pour le GetNearest je le savais, d'autant que s'il y a dans le module un autre objet avec le même tag, cela peut poser problème.
Merci encore pour ces réflexions !
Je pense que Djezebel pourra faire les corrections et rajouts éventuels toute seule.
A bientôt !
|
|
Revenir en haut |
|
|
Enki
Légende vivante
Inscrit le: 06 Déc 2005
Messages: 432
|
Posté le : 02/03/2006 10:20:34 Sujet du message :
Salut !
J'ai édité mon script précédent en tenant compte des remarques de Lylver, et du test que l'on a effectué hier.
Normalement, les monstrent apparaissent à des moments différents, et si un deuxième joueur vient marcher sur le trigger alors qu'un joueur y est déjà, les spawns ne recommencent pas !
( Normalement ! )
A bientôt, et j'espère que le sujet sera enfin résolu !
|
|
Revenir en haut |
|
|
Djezebel
Héros
Inscrit le: 29 Sep 2005
Messages: 252
|
Posté le : 03/03/2006 07:44:10 Sujet du message :
Après un teste en solo, tout semble bien fonctionner. Et d'après ce que je lis, en multi aussi ça devrait aller.
Merci encore Enki !
|
|
Revenir en haut |
|
|
|