Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 11:24 Sujet du message: Le Marché aux Bugs - Déclencheurs
RETURN BUG
Ancien bugs corrigé par Blizzard avec le Patch 1.24.
Il permettait de faire n'importe quelle conversion de type. C'était possible car tous les types utilisés par Warcraft 3 sont codés sur le même nombre de bits et que le compilateur ne vérifiait que le dernier Return d'une fonction.
Exemple :
Jass:
function Handle2Int takes handle H returns integer
return H
return 0
endfunction
Cette fonction n'étant plus correcte depuis la 1.24, la fonction native GetHandleId la remplace. Mais beaucoup d'autres conversions de type ne sont plus utilisables.
Blizzard a corrigé ce bug car il permettait d'accéder à d'autre ressources que celles utilisées par Warcraft. _________________
Dernière édition par Tirlititi le 03/06/10 11:59; édité 2 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 11:35 Sujet du message:
BUGS DE SAUVEGARDE
Attribuer une valeur à l'index 8191, l'index maximum d'une variable déployée, empêchera de charger une partie sauvegardée ultérieurement et ce y compris si la valeur en question est null. Le jeu plante lors de l'écran de chargement.
Il n'y a, à part ça, apparemment aucun autre bug et la variable marchera normalement.
Dans le script, la limite de taille d'une chaîne affichée à l'écran en une fois est de 1023 caractères (au-delà, la chaîne est tronquée). Si une chaîne de taille 1024 ou plus est utilisée, cela empêchera de charger une partie sauvegardée. À noter que les fonctions SubString et String Length fonctionneront normalement quel que soit la taille d'une chaîne (la longueur maximum d'une chaîne étant de 4099 caractères).
Cependant, si la chaîne est externalisée (si elle est dans le fichier war3map.wts - en GUI, les chaînes sont externalisée si elles sont écrites dans les gros blocs qui peuvent contenir plusieurs lignes), la chaîne ne sera pas tronquée à l'affichage et ne provoquera pas de bug de sauvegarde. À l'affichage, il peut se produire un autre bug : le texte sera mal positionné et débordera sur la minimap et le portrait unité.
Exemple (chaîne externalisée) :
Après avoir sauvegardé puis rechargé une partie, les fonctions natives OrderId2String et UnitId2String renverront null à chaque utilisation. On peut se baser sur la librairie de Troll-Brain pour résoudre ce problème en partie. _________________
Dernière édition par Tirlititi le 12/01/12 16:42; édité 14 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 11:39 Sujet du message:
BUGS DE REPLAY
Lors d'un replay, la fonction GetLocalPlayer renvoie systématiquement le 1er utilisateur présent au moment du chargement de la partie.
Par exemple, si le joueur 1 est un ordinateur et le joueur 2 un utilisateur, GetLocalPlayer renverra le joueur 2 tout au long du replay. _________________
Dernière édition par Tirlititi le 01/04/11 22:58; édité 2 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 12:01 Sujet du message:
INITIALISATION DES GLOBALES
Initialiser une globale avec les fonctions suivantes (et leurs dérivées) lors de leur déclaration ne marchera pas :
Jass:
CreateRegion // L'handle est créé mais inutilisable
GetLocalPlayer // Fait crasher le jeu pendant le chargement
CreateUnit // Pour les suivantes, l'objet n'est pas créé et la variable reste null
CreateDestructable
CreateItem
On peut toujours utiliser les fonctions Remove (le leak disparaîtra) mais ce sont les seules. _________________
Dernière édition par Tirlititi le 08/03/14 23:04; édité 7 fois
Inscrit le: 05 Avr 2010 Messages: 114 Sujets: 8 Spécialité en worldedit: Faire des maps originales; déclencheurs; solutions.
Posté le: 01/06/10 12:35 Sujet du message: Re: Le Marché aux Bugs - Déclencheurs
UNITÉS DANS UNE ZONE
Warcraft 3 utilise plusieurs façons différentes pour savoir si une unité se trouve dans une zone ou non.
POUR LES RÉGIONS
Il y a 2 types de régions : les régions GUI et les régions jass.
Les régions GUI sont celles que l'on définit sur la map avec la palette et servent pour la condition suivante :
Gui:
Trigger:
(REGION contains (UNIT)) Egal à TRUE
Si la position de l'unité se trouve dans la région GUI, la condition est remplie, c'est aussi simple que ça.
Les régions jass sont souvent associées aux régions GUI et servent pour l'évènement
Gui:
Trigger:
Unité - A unit enters (REGION)
Cependant, il y a une petite différence entre une région GUI et sa région jass associée : la région jass est plus grande sur les côtés droit et haut de 32 (échelle Warcraft). Une unité qui déclenche l'évènement ne sera donc pas toujours considéré dans la région GUI associée.
Exemples :
Gui:
Trigger:
Déclencheur
Evénements
Unité - A unit enters REGION
Conditions
Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Si - Conditions
(REGION contains (Triggering unit)) Egal à TRUE
Alors - Actions
-------- cas où l'unité vient d'en bas ou de gauche --------
Sinon - Actions
-------- cas où l'unité vient d'en haut ou de droite --------
POUR LES CERCLES
En GUI, les unités sont considérée dans le cercle de rayon R lorsque leur position est à une distance du centre inférieure à R. Cependant, les sorts prennent également en compte la taille collision des unités. Dans le cas où l'on fait un sort de zone par déclencheur, il y aura donc une petite différence entre les unités qui seraient touchées normalement par le sort et les unités qui sont considérées par le déclencheur (notamment avec l'action "Pick every units in range...").
En jass, il existe 3 fonctions natives qui permettent de prendre en compte la collision :
Jass:
constant native IsUnitInRange takes unit whichUnit, unit otherUnit, real distance returns boolean
constant native IsUnitInRangeXY takes unit whichUnit, real x, real y, real distance returns boolean
constant native IsUnitInRangeLoc takes unit whichUnit, location whichLocation, real distance returns boolean
On pourra donc les utiliser dans les filtres pour toucher les même unités que si le sort n'était pas fait par déclencheur. _________________
Dernière édition par Dj0z le 01/06/10 13:57; édité 2 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 12:38 Sujet du message:
CAMERA BOUNDS
À chaque utilisation de l'action
Gui:
Trigger:
Caméra - Set the camera bounds for Joueur to Region
et de sa fonction native, la minimap est réinitialisée de façon assez buguée :
• Les positions des unités et le brouillard de guerre sont modifiées pour correspondre à la camera bound mais pas le terrain ni les destructibles ce qui désorganise un peu.
• La minimap est compressée (dans le sens vertical) en fonction de la rotation de la caméra actuelle. Avec une rotation de 90, il n'y a pas de compression ; avec une rotation de 227.4, la minimap est totalement compressée et entre 227.5 et 312.5, le jeu plante.
De plus, la camera bounds sera également ajustée en fonction de la rotation de la caméra actuelle : la caméra bound sera un rectangle passant par les 4 points donnés (en GUI, les 4 points sont les 4 coins de la région) dont les côtés sont parallèles avec la caméra.
Exemple : _________________
Dernière édition par Tirlititi le 06/08/10 15:32; édité 2 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 14:33 Sujet du message:
AJOUT/RETRAIT D'OBJETS À VENDRE
La compétence Sell Items permet de vendre des objets et de contrôler quels items sont vendus par déclencheur. Mais il y a quelques bugs dûs à la limite d'objets qu'un magasin peut avoir en stock (qui ne peut excéder 11, la valeur par défaut) :
• Lorsqu'on ajoute plus d'objets que la limite, les objets les plus anciens seront enlevés mais si on diminue la limite via l'action
Gui:
Trigger:
Bâtiment neutre - Limit marketplace to X item slots
, ce sont les objets les plus récents qui seront retirés du magasin.
• l'action
Gui:
Trigger:
Bâtiment neutre - Retirer des objets du magasin
n'a aucune influence sur la limite d'objet et les objets les plus vieux seront retirés quand même après avoir ajouté/retiré suffisament d'objets (même si le bâtiment a moins d'objets à vendre après toutes ces manip' que sa limite normale).
Exemple :
Gui:
Trigger:
Actions
Bâtiment neutre - Limit MARKETPLACE to 2 item slots Bâtiment neutre - Add OBJET_1 to MARKETPLACE with 1 in stock and a max stock of 1 Bâtiment neutre - Add OBJET_2 to MARKETPLACE with 1 in stock and a max stock of 1 Bâtiment neutre - Remove OBJET_2 from MARKETPLACE Bâtiment neutre - Add OBJET_3 to MARKETPLACE with 1 in stock and a max stock of 1
Lors de la dernière action, l'OBJET_1 est retiré du magasin. _________________
Dernière édition par Tirlititi le 12/01/12 16:40; édité 3 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 14:43 Sujet du message:
FONCTIONS DYSFONCTIONNANTES
GUI
- Avec l'évènement suivant,
Gui:
Trigger:
Unité - A unit Fait apparaître une unité invoquée
la réponse "Triggering unit" renvoie l'invocation et non pas l'invocateur, comme on pourrait le penser.
- L'action suivante,
Gui:
Trigger:
Animation - Change UNIT's size to (X%, Y%, Z%) of its original size
ne prend en compte que la valeur de X et modifie la taille de l'unité selon tous les axes avec cette valeur.
Jass
Les fonctions ci-dessous ne marchent pas ou marchent très mal :
Jass:
AbilityId // renvoie 0
AbilityId2String // renvoie null, GetObjectName marche
GroupEnumUnitsOfTypeCounted // Pour toutes ces fonctions, le dernier argument ne sert à rien
GroupEnumUnitsInRectCounted
GroupEnumUnitsInRangeCounted
GroupEnumUnitsInRangeOfLocCounted
SetCineFilterTexMapFlags // L'option WRAP_V ne fonctionne pas
Les fonctions "GroupEnum..." produisaient du leak si le filtre était null. Heureusement, ce bug a été corrigé par Blizzard. _________________
Dernière édition par Tirlititi le 22/09/12 15:48; édité 12 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 01/06/10 15:07 Sujet du message:
ORDRE REÇUS ANORMALEMENT
Une unité qui possède certaines compétences activables/désactivables reçoit l'ordre de les désactiver :
-1 fois lorsqu'elle est mise dans un transport,
-1 fois lorsqu'elle est pausée/dépausée (par déclencheur - seulement si l'action a un effet),
-1 fois lorsqu'elle meurt,
-2 fois lorsqu'elle est retirée de la partie (1 seule fois si elle était déjà morte),
-2 fois lorsqu'on lui retire la compétence (1 seule fois si elle était morte),
-2 fois si on lui lance le sort Sarment (1 seule fois si la compétence n'est pas activée - les ordres reçus de cette façon ne désactivent pas la compétence).
Et ce même si la compétence est désactivée pour le joueur et qu'il ne possède pas les mise à jour nécessaires pour l'utiliser.
D'après quelques tests, les compétences concernées sont Défensif, Défense Magique et Immolation.
Lorsqu'une unité reçoit un ordre avec un objet/point pour cible, lui donner un ordre sans cible en réponse évènement sera sans effet mais déclenchera l'évènement
Gui:
Trigger:
Unité - A unit Reçoit un ordre sans cible
Pour que l'ordre ait un effet, on peut utiliser la mise en pause :
Gui:
Trigger:
Unité - Pause (Triggering unit) Unité - Order (Triggering unit) to Arrêter Unité - Reprendre (Triggering unit) Unité - Order (Triggering unit) to ORDRE
(l'ordre est celui de la mise en pause, il annule l'ordre ciblé et l'unité reprend son dernier ordre sans cible.)
Lorsque l'unité utilise une compétence "Livre de Sort", il est encore plus compliqué de lui donner des ordres sans cible. On pourra lui ordonner d'avancer juste devant elle à la place ; voici un code qui fait ça sans les problèmes de leak du GUI :
Inscrit le: 05 Avr 2010 Messages: 114 Sujets: 8 Spécialité en worldedit: Faire des maps originales; déclencheurs; solutions.
Posté le: 02/06/10 23:17 Sujet du message:
REMOVE DESTRUCTIBLE
Un déclencheur avec pour événement "Destructible dies" sera executé quand on utilise l'action "Remove Destructible" sur ce même destructible,
y compris dans le cas où le destructible est déjà mort.
En d'autres termes, retirer un destructible (comme un arbre) de la partie, compte comme si on le "tue" également, et lance tout déclencheur qui a pour ordre de démarrer si un arbre meurt. Et ceci se produit même si l'arbre en question est déjà mort (on "tue l'arbre mort" en le retirant de la partie...). _________________
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 15/06/10 20:30 Sujet du message:
HÉROS : BAISSE DE NIVEAU
Gui:
Trigger:
Héros - Set UNIT Hero-level to LEVEL
Cette action utilise 2 fonctions jass : SetHeroLevel (lorsque le nouveau niveau est plus grand que l'ancien) et UnitStripHeroLevel (pour baisser le niveau du héros). Cette dernière fonctionne mal car elle retire certaines stats au héros.
Les stats concernées sont :
• Points de compétences : retirer 1 niveau -> retirer 1 point de compétence (utilisé ou non). Ça ne correspond pas lorsqu'il y a plus de niveaux que de compétences, par exemple.
• Régen de vie/mana : Chaque baisse de niveau entraine une baisse de régénération (dépendamment de la force/intel par niveaux mais indépendamment de la constante de jeu qui fixe cette régénération).
• Points de vie/mana : Idem que pour la régénération (semble différent dans le fonctionnement par contre ; sans changer les constantes, les régéns buggent mais pas les points de vie/mana)
Les caractéristiques (force/agi/intel), par contre, sont gardées (y compris les modifications par trigger) et je n'ai jamais remarqué de modification d'autre stat. _________________
Dernière édition par Tirlititi le 10/10/10 14:28; édité 1 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 10/10/10 14:21 Sujet du message:
DESTRUCTION DE TRIGGER
Utiliser l'action "TriggerSleepAction" dans une action de trigger après avoir détruit ce trigger fait dysfonctionner la création d'handle en perturbant l'attribution des IDs.
Il faut donc éviter de détruire un déclencheur au début de son exécution ou bien ne pas utiliser "TriggerSleepAction".
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 13/11/10 14:17 Sujet du message:
BUGS APRÈS CERTAINS ÉVÈNEMENTS
La plupart du temps, les déclencheurs sont exécutés juste avant leurs évènements. Par exemple, un déclencheur avec l'event
Gui:
Trigger:
Unité - UNIT subit des dégâts
se déclenchera avant que les dégâts n'aient effectivement lieu (on pourra donc la soigner avant de façon à la garder en vie). De ce fait, utiliser certaines actions avec ces events peut perturber plus ou moins dramatiquement le bon déroulement de la chose.
LES ORDRES
Comme indiqué dans la partie "Ordres reçus anormalement", un ordre sans cible donné après les évènements "reçoit un ordre avec point/objet pour cible" sera ignoré par l'unité. Pour bien comprendre le fonctionnement de ce bug, il faut avoir la chronologie de ce qui se passe en tête :
1) Le joueur (ou n'importe quoi d'autre) lance un message d'ordre à l'unité,
2) Warcraft appelle les déclencheurs ayant l'évènement "reçoit un ordre avec point/objet pour cible",
3) L'un de ces déclencheurs lance un message d'ordre sans cible à l'unité,
4) Warcraft appelle les déclencheurs ayant l'évènement "reçoit un ordre sans cible" (on suppose içi qu'il n'y en a pas),
5) L'ordre sans cible est exécuté,
6) L'ordre avec cible est exécuté.
Étant donné que c'est l'ordre avec cible qui est donné en premier, c'est lui qui sera exécuté en dernier (c'est une logique d'empilement).
LES COMPÉTENCES
La chronologie des évènements se déroule ainsi pour la compétence Canaliser :
1) L'unité commence à canaliser *
2) Attente [Durée de lancer de sort]
3) L'unité commence le lancement *
4) L'unité joue [Noms d'animation] en boucle
5) Attente [Point de lancer]
6) Utilisation du mana
7) L'unité initie l'effet *
8) Les effets spéciaux sont montrés
9) Le cooldown commence
10) Attente [Suivre dans la durée]
11) L'unité achève le lancement *
12) L'unité arrête de jouer [Noms d'animation]
13) Les effets spéciaux qui étaient joués en boucle s'arrêtent
Les attentes en rouge signifient que le joueur doit donner l'ordre "Stop" ou "Tenir position" pour annuler la compétence (mais pas les déclencheurs).
Les * indiquent les positions des events.
A partir du moment où l'unité commence à canaliser, l'interruption (ou l'achèvement) de la compétence déclenche l'évènement "Arrête le lancement".
Enfin, il faut savoir que cette chronologie n'est pas exactement la même pour tous les sorts et que c'est vraiment au cas par cas (mais Canaliser est le plus utile pour les sorts avec déclencheurs). D'ailleurs, le temps de "lancer retour" n'est pas pris en compte avec canaliser.
Une fois que vous connaissez la chronologie de la compétence, vous devez savoir que donner un autre ordre à (ou déplacer) l'unité pendant qu'elle utilise une compétence entraîne l'arrêt immédiat de la compétence et le reste ne sera pas exécuté.
Exemple :
Secret:
Dans cet exemple, le texte affiché est "1 2 3". L'évènement "initie" n'est jamais atteint.
Gui:
Trigger:
Lancement
Evénements
Unité - A unit Commence le lancement d'une compétence
Conditions
Actions
Partie - Display to (All players) the text: 1 Unité - Order (Triggering unit) to Arrêter Partie - Display to (All players) the text: 3
Arret
Evénements
Unité - A unit Arrête le lancement d'une compétence
Conditions
Actions
Partie - Display to (All players) the text: 2
Initie
Evénements
Unité - A unit Initie l'effet d'une compétence
Conditions
Actions
Partie - Display to (All players) the text: 4
Vous devez aussi savoir que Pauser l'unité déclenche également l'évènement "Arrête le lancement" et détruit la plupart des données (à part celle qui indique qui a lancé la compétence) mais n'arrête pas véritablement l'exécution de la compétence. On se retrouve donc avec un bug : la compétence n'a plus de cible ("null" si c'est une unité, le point (0,0) si c'est un point) mais continue son effet.
Exemple : Pause/Reprendre avec quelques compétences
EDIT : Comme le fait justement remarquer Troll-Brain, les détails techniques de la théorie ont quelques défauts. Malgré cela, je la laisse jusqu'à ce que quelqu'un comprenne mieux comment ça se passe réellement dans le ventre de la machine. _________________
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 12/01/12 16:19 Sujet du message:
LA SÉLECTION
La sélection et la désélection des unités sont assez bizarrement gérées par Warcraft III au niveau du moment précis où la sélection est effective. Il faut surtout garder à l'esprit que les actions de sélection comme
Gui:
Trigger:
Unité - Select Unit For Player
ne sont pas forcément instantanées pour la condition "Unit Selected By Player" et ne sont jamais instantanées pour l'évènement "Selection Event".
Selection Event :
"Selection Event" n'est pas immédiat et peut provoquer une boucle infinie si on selectionne une unité dans un déclencheur qui l'utilise évènement.
Exemple :
Le déclencheur suivant bug en provoquant une boucle infinie. Comme l'event n'est pas immédiat, le jeu ne plante quand même pas directement.
Gui:
Trigger:
Evénements
Joueur - JOUEUR Sélectionne a unit
Conditions
Actions
Déclencheur - Turn off (This trigger) Sélection - Add UNIT to selection for JOUEUR Déclencheur - Turn on (This trigger)
Unit Selected by Player :
Cette condition booléenne est à moitié synchrone : elle prend immédiatement en compte les sélections d'unités mais pas toujours les dé-sélection. Elle ne les prend en compte que pour annuler l'effet d'une sélection précédemment appelée dans un trigger. "Clear Selection" a le même effet qu'une dé-sélection sur toutes les unités sélectionnées.
Exemple :
Gui:
Trigger:
Set BOOLEAN = UNIT is selected by PLAYER Sélection - Remove UNIT from selection for PLAYER If ((UNIT is selected by PLAYER) then do (Partie - Display to (All players) the text: true) else do (Partie - Display to (All players) the text: false) -------- Affiche la même valeur que BOOLEAN -------- Sélection - Add UNIT to selection for PLAYER If ((UNIT is selected by PLAYER) then do (Partie - Display to (All players) the text: true) else do (Partie - Display to (All players) the text: false) -------- Affiche toujours true -------- Sélection - Remove UNIT from selection for PLAYER If ((UNIT is selected by PLAYER) then do (Partie - Display to (All players) the text: true) else do (Partie - Display to (All players) the text: false) -------- Affiche la même valeur que BOOLEAN --------
À noter qu'il existe une fonction jass, "SyncSelections", qui agit à la manière d'un Wait pour attendre que la sélection soit synchronisée sur tous les ordinateurs. _________________
Dernière édition par Tirlititi le 13/09/14 20:29; édité 1 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 21/01/12 13:46 Sujet du message:
LES IMAGES
Les Ids des images sont traités d'une façon similaire à celles des textes flottants : avec des nombres très petits. Alors que les textes flottants ont une Id allant de 99 à 0 (0 est donc l'Id du 100ème et dernier texte flottant que l'on peut créer), les images ont une Id commençant à 0 et montant jusqu'à plus de 10000 (il n'y a donc pas de limite significative). La 1ère image créée a une Id de 0.
A venir : un autre bug sur les images ! _________________
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