Posté le: 03/02/13 08:43 Sujet du message: au rythme des marées
J'ai un peu hésité à poster ça ici ou dans la catégorie déclencheur. Mais comme je compte faire ici une compil de toutes les difficultés que je rencontre, y compris dans l'éditeur d'objet, je me suis dit que ça avait plutôt sa place ici.
Donc je vais vous détailler mon gros problème du moment.
A un moment donné dans ma carte, j'ai besoin de créer une déformation progressive permanente de terrain (une bosse). Pour ça, j'utilise l'action environnement --> Create Terrain Deformation : Crater et j'entre une valeur négative pour l'amplitude pour obtenir une bosse et je fais durer la défo sur plusieurs minutes
Jusque là, aucun problème.
Sauf que la zone considérée est boisée, j'y ai mis des arbres. Et le problème, c'est que les destructibles ne sont pas affectés par la déformation de terrain, ce qui fait qu'ils se retrouvent en dessous du niveau du sol.
J'ai rencontré exactement le même problème avec les unités de type bâtiment, sauf que là, j'ai réussi à résoudre le problème : il suffit de déplacer périodiquement le bâtiment sur sa propre position (Unité --> move unit (instantly) --> move unit at position of picked unit) et il se replace à la bonne altitude, suivant la déformation de terrain en temps réel.
Sauf qu'il est impossible de faire pareil avec les destructibles. Il n'existe pas de fonction move destructible j'ai essayé de les faire disparaitre, puis de les recréer ensuite avec la fonction remove et create destructible, et en fait, ça marche plutôt bien, sauf pour les arbres :
j'utilise une table de hachage pour sauvegarder toutes les caractéristiques des arbres histoire que l'éditeur ne me recrée pas des arbres différents à chaque itérations, ce qui serait visuellement assez moche. Le seul souci, c'est que je ne peux sauvegarder que des valeurs numériques. Lorsque j'utilise groupe destructible --> pick every destructible in region puis table de hachage --> save destructable handle / save position handle, qu'ensuite je fais remove picked destructible et qu'ensuite, je fais une deuxième boucle en dehors de la première pour lire les destructible avec destructible --> create destructible --> create destructible of type (load values from hashtable) at position (load values from hashtable)..., ça ne marche pas. Les destructibles disparaissent, mais ne réapparaissent pas. Du coup, je suis obligé de contourner le problème en faisant toute une batterie de tests conditionnels en sauvegardant les données sous forme de variables numériques (réels, entiers et booléens). Et là, ça marche, mais c'est vraiment boiteux et le script de la procédure est juste surchargé.
Comme les arbres disparaissent périodiquement, lorsqu'un péon les récolte, il est interrompu toutes les trois secondes et lorsqu'il revient à l'hôtel de ville pour déposer le bois, il ne repart pas ensuite car l'arbre qu'il était en train de couper a disparu entretemps. (même s'il a été recréé). Et voilà : dans une partie, c'est pas jouable !
Mon idée du moment, c'est de ne pas toucher aux arbres qui vont dont "s'enfoncer dans le sol" et de superposer dessus un destructible personnalisé ayant l'apparence d'un arbre qui lui suivra la déformation de terrain. Techniquement, c'est réalisable je pense. Sauf que c'est un peu moche visuellement parlant. Sans compter qu'il faut que le destructible fantôme meure en même temps que l'arbre qu'il remplace lorsqu'il est abattu.
J'ai eu aussi l'idée de faire en sorte que l'action "récolter" devienne un sort automatique grâce à l'éditeur de compétence, mais... chépa, je trouve que cette solution n'est pas très élégante.
Enfin voilà. Si vous avez des suggestions, enjoy ! _________________
Dernière édition par Helheim le 03/02/13 09:09; édité 1 fois
Inscrit le: 19 Oct 2011 Messages: 382 Sujets: 32 Spécialité en worldedit: Il faut vraiment que je réponde ?
Posté le: 03/02/13 09:07 Sujet du message:
T'as essayé en tuant l'arbre et en le réincarnant ? Normalement c'est
toujours le même destructible donc sa devrait rien changer.
Sinon, en mettant peut être des modifications autre que le "Cratère" sa
marcherait peut être ? _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 03/02/13 10:50 Sujet du message:
Citation:
j'utilise une table de hachage pour sauvegarder toutes les caractéristiques des arbres histoire que l'éditeur ne me recrée pas des arbres différents à chaque itérations, ce qui serait visuellement assez moche. Le seul souci, c'est que je ne peux sauvegarder que des valeurs numériques. Lorsque j'utilise groupe destructible --> pick every destructible in region puis table de hachage --> save destructable handle / save position handle, qu'ensuite je fais remove picked destructible et qu'ensuite, je fais une deuxième boucle en dehors de la première pour lire les destructible avec destructible --> create destructible --> create destructible of type (load values from hashtable) at position (load values from hashtable)..., ça ne marche pas. Les destructibles disparaissent, mais ne réapparaissent pas. Du coup, je suis obligé de contourner le problème en faisant toute une batterie de tests conditionnels en sauvegardant les données sous forme de variables numériques (réels, entiers et booléens). Et là, ça marche, mais c'est vraiment boiteux et le script de la procédure est juste surchargé.
Pourquoi une table de hachage? Une simple liste suffirait (voire deux si tu utilises des coordonnées).
Tu fais une variable location array (ou deux réels array, ce qui est plus optimisé), plus une variable count, pour connaître le nombre de locations sauvegardées, et c'est bon.
Par contre avant de faire ça, test la solution de Zaaap.
Sinon je n'ai pas compris comment ta deuxième boucle pour recréer les destructibles fonctionne. Tu les as remove, donc ils n'existent plus, la boucle n'énumère aucun destructible. _________________
Zaaap : Oui, j'ai essayé de tuer l'arbre et de le ressusciter. Ca ne fonctionne pas car l'arbre reste toujours en dessous du niveau du sol. Quant au cratère, ce n'est pas non plus possible de changer cette déformation de terrain parce que c'est cette déformation qu'il me faut.
SG : Il me faut une table de hachage parce qu'il n'y a pas que les coordonnées que je veux sauvegarder : il y a aussi le type de destructible, sa variation, sa taille, son orientation et sa quantité de point de vie. Ca fait déjà pas mal de données donc je me suis dit que j'allais les sauver dans un tableau, c'est ce qui me paraissait le plus simple (car d'après ce que j'ai compris, une table de hachage, c'est un tableau).
En fait, dans un monde parfait, je ferais (et j'ai fait) :
dans un premier déclencheur (j'ai mis en couleur ce qui va ensemble pour faciliter la compréhension) :
évènement :
map initialization
action :
compteur = 0 ! (C'est un entier)
boucle : pick every destructible in playable map area and do (action)
____if destructible type of (picked destructible) Egal à arbre then
________set compteur = (compteur + 1)
________Table de hachage - Save Handle of (position of (Picked destructible) as compteur of 1 in Table de Hachage
________Table de hachage - Save Handle of (Picked destructible) as compteur of 2 in Table de Hachage
________Destructible - Remove picked destructible
____else
________do nothing
____(end if)
(end boucle)
set fin = compteur ! fin est aussi une variable de type entier et sert à sauvegarder la valeur finale de la variable compteur
compteur = 1
Boucle : For each (integer compteur) from 1 to fin
____Destructible : create (destructible-type of (load compteur of 2 from table de hachage) at (load compteur of 1 in Table de hachage)
(end for)
Ensuite, dans un deuxième déclencheur
évènement :
Periodic event : every 3.00 seconds of game time
action :
boucle : pick every destructible in playable map area and do (action)
____if destructible type of (picked destructible) Egal à arbre then
________remove picked destructible
____(end if)
(end boucle)
Boucle : For each (integer compteur) from 1 to fin
____Destructible : create (destructible-type of (load compteur of 2 from table de hachage) at (load compteur of 1 in Table de hachage)
(end for)
Bon... je vous ai simplifié le script pour ne pas surcharger. Je sais que c'est assez pénible de déchiffrer un code qui n'est pas le sien, donc je vous ai mis que l'essentiel (mais si vous voulez que je vous l'explicite totalement, je peux le faire)
Sauf que ça ne marche pas. Et je ne sais pas où est ce que ça buggue. du coup, je contourne le problème avec
évènement :
map initialization
action :
compteur = 0 ! (C'est un entier)
boucle : pick every destructible in playable map area and do (action)
____if destructible type of (picked destructible) Egal à arbre then
________set compteur = (compteur + 1)
________Table de hachage - Save Handle of (position of (Picked destructible) as compteur of 1 in Table de Hachage
________Table de hachage - Save 1 as compteur of 2 in Table de Hachage ! en fait, c'est pour différencier les arbres simples des cimes d'arbre à l'aide d'un test conditionnel que je n'ai pas explicité ici)
________Set variation = random integer beetween1 and 9 ! Car il y a 9 variations d'arbres
________Table de hachage - Save variation as compteur of 3 in Table de Hachage
________Destructible - Remove picked destructible
____else
________do nothing
____(end if)
(end boucle)
set fin = compteur compteur = 1
Boucle : For each (integer compteur) from 1 to fin
____Destructible : create arbre at (load compteur of 1 in Table de hachage) [...] and variation (load compteur of 3 in Table de hachage)
(end for)
et dans un deuxième déclencheur :
évènement :
Periodic event : every 3.00 seconds of game time
action :
boucle : pick every destructible in playable map area and do (action)
____if destructible type of (picked destructible) Egal à arbre then
________remove picked destructible
____(end if)
(end boucle)
Boucle : For each (integer compteur) from 1 to fin
____Destructible : create arbre at (load compteur of 1 in Table de hachage) [...] and variation (load compteur of 3 in Table de hachage)
(end for)
Et là, ça fonctionne !!! Donc ça signifie que c'est le fait de mettre des destructibles dans une table de hachage qui crée un bug. Le problème, c'est que je ne sais absolument pas si le bug a lieu lors de l'écriture des destructibles dans la table ou si il a lieu lors de la lecture quand il s'agit de les restituer. Et j'aimerais bien pouvoir utiliser directement les destructibles parce que je pense que ça résoudrait le bug des péons qui ne retrouvent plus leurs arbres.
Voilà, désolé pour ce pavé indigeste, j'espère qu'il ne vous rebutera pas lol ! _________________
Tu peux copier en version texte tes déclencheurs avec un clique droit sur la feuille blanche ( si je m'en rappelle bien ).
Avec l'utilisation des balises Gui fournies par le forum il te sera beaucoup plus simple de nous faire voir tes déclencheurs.
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 03/02/13 22:02 Sujet du message:
En fait, dans ta 1ère version, tu sauvegardes ton destructible dans la hashtable puis tu détruis ton destructible, ce qui détruit également toutes les données qui lui sont associées (dont son "type-destructible"). C'est pour ça que tu te retrouves avec un "type-destructible" incorrect lorsque tu récupères la valeur.
Tu peux sauvegarder une donnée de type "type-destructible" dans une hashtable, mais pas en GUI. Tu dois passer par un custom script de ce genre :
Gui:
Trigger:
Set VariableTypeDestructible = Destructible-type of (Picked destructible) Custom script: call SaveIntegerBJ( udg_VariableTypeDestructible, udg_compteur, 2, udg_Table_de_Hachage )
Pour récupérer le type ensuite, tu fais :
Gui:
Trigger:
Custom script: set udg_VariableTypeDestructible = LoadIntegerBJ( udg_compteur, 2, udg_Table_de_Hachage )
En fait, les "type-destructible" (tout comme les "type-unités", etc...) sont juste des entiers.
Tu auras remarqué que, dans un custom script, les noms des variables sont précédées d'un "udg_" et que les espaces sont changés en underscores.
Puisque tu as fait du Matlab, tu ne seras sans doute pas effrayé d'apprendre qu'on peut utiliser l'éditeur de déclencheur avec uniquement des custom scripts (c-à-d avec du texte, comme un langage de programmation).
Tu pourras trouver une liste des fonctions utilisables dans ce langage ici :
common.j Blizzard.j
Ce sont des fichiers textes, tu peux les ouvrir avec le notepad, par exemple.
Secret:
Manœuvre machiavélique pour convertir le petit nouveau au jass entamée
Bon, ça fait presque deux heures que je suis dessus et ça marche pas ! En fait, le truc, c'est que j'ai jamais utilisé de custom script, c'est la première fois que j'en utilise. Donc...
Je vous passe le code complet (je ne sais pas pourquoi ici, le forum me met les déclencheurs avec la table de hachage en rouge comme si il les reconnaissait pas. Sur mon éditeur, il les reconnaît parfaitement) :
Secret:
Gui:
Trigger:
Table de hachage - Create a hashtable Set definition_nord = (Last created hashtable) -------- On crée une table de hachage qui n'est en fait qu'un nom barbare pour désigner un tableau défini avec des lignes et des colonnes dans laquelle on va pouvoir stocker toutes les caractéristiques numériques et autres des destructibles -------- -------- suivant le protocole de rangement défini dans la partie "commentaire" pour pouvoir ensuite aller les récupérer quand on en aura besoin. -------- -------- (Ligne suivante) On initie une boucle qui va considérer chaque destructible un par un. -------- Destructible - Pick every destructible in (Playable map area) and do (Actions)
Boucle - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Si - Conditions
(Destructible-type of (Picked destructible)) Egal à Mur d'arbres en ruines
Alors - Actions
Set Compteur_Nord = (Compteur_Nord + 1) -------- A chaque itération de la boucle, la variable entière "Compteur_Nord" préalablement créée sera augmentée de 1 -------- Table de hachage - Save Handle Of(Position of (Picked destructible)) as Compteur_Nord of 1 in definition_nord -------- On sauve ici la localisation du destructible considéré suivant le protocole de rangement défini dans la partie "commentaire" du déclencheur. -------- -------- On remarque d'ailleurs au passage l'utilité d'avoir un compteur : à chaque itération de la boucle, il prend la valeur supérieure et on passe donc à la ligne suivante du tableau de sauvegarde. -------- Set type_destructible_2 = (Destructible-type of (Picked destructible)) Custom script: call SaveIntegerBJ( udg_type_destructible_2, udg_Compteur_Nord, 2, udg_definition_nord ) -------- Comme on va virer le destructible, on ne peut pas le stocker dans une table de hachage. Il Paraît qu'il faut utiliser un custom script, sauf que j'ai pas très bien pigé comment fonctionne ce truc. -------- Destructible - Remove (Picked destructible) Set Taille_Destructible = (Random real number between 0.65 and 1.05) Set Variation_Destructible = (Random integer number between 0 and 9) Set Angle_Destructible = (Random angle) -------- On crée un triplet de valeurs (orientation, taille, variation) qui vont achever de définir le destructible qu'on va créer (car ces valeurs ne peuvent pas être sauvegardées à ma connaissance à partir d'un destructible déjà placé). -------- Table de hachage - Save Angle_Destructible as Compteur_Nord of 3 in definition_nord Table de hachage - Save Taille_Destructible as Compteur_Nord of 4 in definition_nord Table de hachage - Save Variation_Destructible as Compteur_Nord of 5 in definition_nord -------- Et on sauve ces valeurs dans la table de hachage, toujours suivant le protocole de rangement préalablement établi. -------- Custom script: set udg_type_destructible_2 = LoadIntegerBJ( udg_Compteur_Nord, 2, udg_definition_nord ) Destructible - Create a (Destructible-type of (Load Compteur_Nord of 2 in definition_nord)) at (Load Compteur_Nord of 1 in definition_nord) facing Angle_Destructible with scale Taille_Destructible and variation Variation_Destructible -------- On recrée maintenant le destructible à partir des données contenues dans la table de hachage et dans le custom script, sauf que je pige toujours pas comment fonctionne un CS --------
Sinon - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Si - Conditions
(Destructible-type of (Picked destructible)) Egal à Cime d'arbre des ruines
Alors - Actions
Set Compteur_Nord = (Compteur_Nord + 1) Table de hachage - Save Handle Of(Position of (Picked destructible)) as Compteur_Nord of 1 in definition_nord Set type_destructible_2 = (Destructible-type of (Picked destructible)) Custom script: call SaveIntegerBJ( udg_type_destructible_2, udg_Compteur_Nord, 2, udg_definition_nord ) Destructible - Remove (Picked destructible) Set Taille_Destructible = (Random real number between 0.80 and 1.20) Set Variation_Destructible = (Random integer number between 0 and 2) Set Angle_Destructible = (Random angle) -------- On crée un triplet de valeurs (orientation, taille, variation) qui vont achever de définir le destructible qu'on va créer (car ces valeurs ne peuvent pas être sauvegardées à ma connaissance à partir d'un destructible déjà placé). -------- Table de hachage - Save Angle_Destructible as Compteur_Nord of 3 in definition_nord Table de hachage - Save Taille_Destructible as Compteur_Nord of 4 in definition_nord Table de hachage - Save Variation_Destructible as Compteur_Nord of 5 in definition_nord -------- Et on sauve ces valeurs dans la table de hachage, toujours suivant le protocole de rangement préalablement établi. -------- Custom script: set udg_type_destructible_2 = LoadIntegerBJ( udg_Compteur_Nord, 2, udg_definition_nord ) Destructible - Create a (Destructible-type of (Load Compteur_Nord of 2 in definition_nord)) at (Load Compteur_Nord of 1 in definition_nord) facing Angle_Destructible with scale Taille_Destructible and variation Variation_Destructible
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 04/02/13 20:20 Sujet du message:
Je vois pas non plus, désolé...
À part la solution que tu proposes avec une unité/objet pour le modèle et un destructible invisible qui fait l'arbre. Tu peux utiliser ce modèle pour le destructible invisible, mais sélectionnable, d'ailleurs :
http://communots.free.fr/upload/SelectionBox13600055.mdx
Mais y'a peut-être un autre moyen... Essaie de faire "Kill Destructble" à la place du "Remove", et vois si ça ne permet pas aux péons d'adapter leur collecte (après tout, ils s'adaptent lorsqu'on détruit les arbres avec choc de flamme, non?).
Si ça marche pas, réessaie en mettant un "Wait 1.00 seconds" entre la destruction et la création des arbres. _________________
Désolé si je ne viens pas souvent. Avec les cours, toussa, je peux pas m'investir très souvent dans ma map.
Je suis à nouveau en train d'y retravailler. J'ai considéré ton conseil, mais le souci, c'est que si je fait "kill destructible", le jeu va me montrer l'animation de mort et il n'est pas possible de masquer cette animation. Et visuellement, je trouve ça un peu bofant. 'fin, faut pas oublier que à terme, c'est une map prévue pour qu'on joue dessus. So, il faut qu'elle soit un minimum esthétique quoi. _________________
Non, ça n'est pas possible. Enfin si, c'est possible, mais ça ne sera pas beau.
Je vais vous expliquer en détail ma map.
En fait, ma map est de type "ruines englouties" et j'essaie de programmer des marées.
Pour ça, j'ai un niveau de terrain de base avec de l'eau, toussa, qui correspond à la marée haute. Ensuite, ce que j'ai fait, c'est que j'ai programmé une élévation de terrain avec un rayon suffisamment grand pour que ça concerne toute la carte.
Concrètement, le niveau d'eau reste où il est et c'est le terrain qui monte. C'est comme ça que je simule la marée basse.
Le problème, c'est que les arbres ne suivent pas cette déformation de terrain. Ils "s'enfoncent" dans le sol au fur et à mesure qu'il s'élève. Et visuellement, c'est juste archimoche.
Ma première solution avait consisté à faire disparaître (remove) puis à recréer les arbres périodiquement pour qu'ils suivent cette déformation de terrain.
Dans l'absolu, cette solution marche sauf qu'elle a un bug : les péons chargés de récolter le bois sont complètement paumés parce que les arbres qu'ils récoltent disparaissent. Au final, ils finissent par ne plus travailler du tout. Et dans une partie, c'est pas viable d'être constamment en train d'ordonner à tes péon de récolter du bois.
Et il n'est pas possible de killer les arbre pour les ressusciter ensuite. En ce qui concerne les péons, ça pourrait marcher je pense. Mais après, ça suppose que toutes les 3 secondes, il y a l'intégralité des arbres de la carte qui meurent, avec l'animation de mort. Et... bof quoi !
Actuellement, je suis en train de travailler sur ceci : j'ai rendu les arbres minuscules grâce à l'éditeur d'objet, et je leur ai superposé des arbres factices grandeur nature (créés avec l'éditeur d'objet toujours) qui eux sont recréés périodiquements. Comme ça, je ne touche pas aux arbres réels et les péons s'y retrouvent, et les arbres factices suivent la déformation de terrain. Mais franchement, c'est super bancal comme solution je trouve. Et il y a des bugs que j'arrive pas à résoudre... Je vais essayer de vous en faire un résumé plus tard. _________________
Inscrit le: 05 Nov 2010 Messages: 696 Sujets: 56 Spécialité en worldedit: Cartes Melee
Posté le: 21/02/13 09:31 Sujet du message:
Si tu veux faire repousser tes arbres,il faut te baser sur la compétence Volcan du Seigneur du feu(j'ai vu ça sur un tuto je sais plus lequel malheureusement )
Autre question : utilises-tu des falaises réalistes(voir tuto falaises réalistes) ou celles de Blizzard pour ton terrain ?Si c'est le cas c'est mieux de refaire toute la carte en utilisant seulement des collines faites avec l'outil "Elever" dans l'onglet terrain .Tu remplis ta carte d'eau au départ comme ça tu t'en sortira mieux pour tes déclencheurs pour modifier les altitudes avec ton système de marée haute/Marée basse .
Pour la compétence Volcan,il faudra demander à quelqu'un d'autre parce que je vois pas comment faire bien que je sache comme fonctionne ce pouvoir,c'est une augmentation d'altitude,là tu peux le faire, et tu règles le pop des arbres,ça peut paraître énervant je sais mais je pense que c'est ce que tu veux pour ta carte . _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2, 3, 4Suivante
Page 1 sur 4
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum