Worldedit
  Worldedit
Le site sur l'éditeur de warcraft 3 !
 
  FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres    Groupes d'utilisateursGroupes d'utilisateurs   medals.php?sid=1508f7d5246ac917557d2228aeda2276Médailles   S'enregistrerS'enregistrer 
 ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 
  FAQFAQ World Editor   UploadUploader une map ou une image    UploadAjouter sa map à l'annuaire   UploadConsulter l'annuaire

Fatal Error T.T (le retour)
Aller à la page 1, 2  Suivante
 
Poster un nouveau sujet   Répondre au sujet    Worldedit Index du Forum -> Aide sur les déclencheurs
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 14/11/07 18:41    Sujet du message: Fatal Error T.T (le retour) Citer

Bon ben voilà comme son nom l'indique, je rencontre une fatal erroe à cause de ce trigger.
Cependant ce n'est pas direct dès l'utilisation du sort. Après quelques essais, à partir du moment où le nombre de cibles dans la zone d'effet descend en dessous de 3, j'ai droit de temps en temps à un affichage de limit op (dans la fonction TraitsDeFoudrePassiveTrigger_Actions), jusqu'à ce que ça plante et me ponde une FE... (quand il n'y a qu'une cible possible, c'est la FE direct)
Ce qui est étrange c'est que tout se passe bien tant que 3 cibles ou plus se truovent dans la zone oO

voilà donc le trigger, j'espère que vous pourrez m'aider à trouver une solution, j'y tient à ce sort u_u

Jass:
function RotationTimeTraitsDeFoudre takes unit whichunit, location whichloc returns real
    local real angle = (RAbsBJ(( AngleBetweenPoints(GetUnitLoc(whichunit), whichloc)) - GetUnitFacing(whichunit)))
    if angle > 180 then
        set angle = 360 - angle
    endif
    return (angle/(360 * GetUnitTurnSpeed(whichunit)))
endfunction

function AttackTimeTraitsDeFoudre takes unit attacker, unit attacked, real missilespeed returns real
    local real distance = DistanceBetweenPoints(GetUnitLoc(attacker), GetUnitLoc(attacked))
    local real time = (distance)/(missilespeed)
    return time
endfunction

function TraitsDeFoudrePassiveTrigger_Conditions takes nothing returns boolean
    return (GetEventDamageSource() == udg_Archer) and (udg_DoT[GetPlayerId(GetOwningPlayer(GetEventDamageSource()))] == false)
endfunction

function TraitsDeFoudrePassive_Conditions takes nothing returns boolean
    return ((udg_ATraitsDeFoudreOn == true) and (GetAttacker() == udg_Archer) and (GetUnitState(GetAttacker(), UNIT_STATE_MANA) >= 49))
endfunction

function TraitsDeFoudrePassive_Matching takes nothing returns boolean
    return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Archer)))
endfunction

function TraitsDeFoudrePassiveTrigger_Actions takes nothing returns nothing
    local integer Damage = R2I(70.00 + I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, udg_Archer, true)) )
    local unit TargetSecondary = null
    local integer chances = 3 * GetHeroAgi(udg_Archer, true)
    local integer zone = 200 + 5 * GetHeroInt(udg_Archer, true)
    local integer boucle = 1
    local unit Target = GetAttackedUnitBJ()
    local group TargetGroup = GetUnitsInRangeOfLocMatching(zone, GetUnitLoc(GetTriggerUnit()), Condition(function TraitsDeFoudrePassive_Matching))
    call DestroyTrigger(GetTriggeringTrigger())
    call UnitDamageTargetBJ( udg_Archer, Target, Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_LIGHTNING )
    call CreateTextTagLocBJ( "-" + I2S(R2I(Damage)), GetUnitLoc(Target), 10.00, 10, 100.00, 0.00, 0.00, 0.00 )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96, 90 )
    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
        loop
        exitwhen boucle > 2
        if GetRandomInt(1, 100) <= chances then
            set Damage = (R2I(Damage - (Damage * 0.10 )))
            set TargetSecondary = GroupPickRandomUnit(TargetGroup)
            if (TargetSecondary != Target) and (GetUnitStateSwap(UNIT_STATE_LIFE, TargetSecondary) > 0.00) and (IsUnitEnemy(TargetSecondary, GetOwningPlayer(udg_Archer)))then
                call TriggerSleepAction( 0.00 )
                call CreateNUnitsAtLoc( 1, 'u601', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetUnitLoc(Target), 0.00)
                call IssueTargetOrderBJ( GetLastCreatedUnit(), "chainlightning", TargetSecondary )
                call UnitApplyTimedLifeBJ( 0.50, 'BTLF', GetLastCreatedUnit() )
                call UnitDamageTargetBJ( udg_Archer, TargetSecondary, Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_LIGHTNING )
                call CreateTextTagLocBJ( "-" + I2S(R2I(Damage)), GetUnitLoc(TargetSecondary), 10.00, 10, 100.00, 0.00, 0.00, 0.00 )
                call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
                call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96.00, 90 )
                call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
                call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
                set Target = TargetSecondary
                set TargetSecondary = null
                set chances = R2I((chances - 20))
                set boucle = 1
            else
                call GroupRemoveUnit(TargetGroup, TargetSecondary)
                set Target = TargetSecondary
                set TargetSecondary = null
                set boucle = 1
            endif
        else
            set boucle = 2
        endif
        set boucle = boucle + 1
    endloop
endfunction
   
function TraitsDeFoudrePassive_Actions takes nothing returns nothing
    local trigger Trigger = null
    set Trigger = CreateTrigger()
    call TriggerRegisterUnitEvent( Trigger, GetAttackedUnitBJ(), EVENT_UNIT_DAMAGED )
    call TriggerAddCondition( Trigger, Condition(function TraitsDeFoudrePassiveTrigger_Conditions) )
    call TriggerAddAction( Trigger, function TraitsDeFoudrePassiveTrigger_Actions )
    call TriggerSleepAction(RotationTimeTraitsDeFoudre(GetAttacker(), GetUnitLoc(GetTriggerUnit())) + AttackTimeTraitsDeFoudre(GetAttacker(), GetTriggerUnit(), 1200) + 0.10)
    call DestroyTrigger(Trigger)
endfunction

//===========================================================================
function InitTrig_TraitsDeFoudrePassive takes nothing returns nothing
    set gg_trg_TraitsDeFoudrePassive = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_TraitsDeFoudrePassive, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_TraitsDeFoudrePassive, Condition(function TraitsDeFoudrePassive_Conditions) )
    call TriggerAddAction( gg_trg_TraitsDeFoudrePassive, function TraitsDeFoudrePassive_Actions )
endfunction

_________________


Dernière édition par Serial Bigouden le 16/11/07 20:06; édité 1 fois
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 14/11/07 18:59    Sujet du message: Citer

J'ai pas regardé plus loin pour l'instant mais tu détruits 2 fois ton trigger créé.

Conseils :
Jass:
local trigger Trigger = null
set Trigger = CreateTrigger()
équivaut à
Jass:
local trigger Trigger = CreateTrigger()

Fait comme tu le sens mais pour différencier les fonctions des variables ne commence jamais une variable par une majuscules
Sauf pour les globales déclarées en Vjass (full majuscules)

sinon y'a un léger leak
Tu dois nullifier ta variable Trigger
Jass:
set Trigger = null


un leak plus grave, il faut destroy l'action avant de detruire un trigger.
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Ayane
Bot administrateur


Inscrit le: 17 Sep 2007
Messages: 2012
Sujets: 49

Médailles: 2 (En savoir plus...)
Ayane (Quantité : 1) Rédacteur de tuto #1 (Quantité : 1)

MessagePosté le: 14/11/07 19:35    Sujet du message: Citer

Imaginons que tu as 100 en chances, que les unités qui sont dans TargetGroup ne répondent pas aux conditions suivantes:
Jass:
(TargetSecondary != Target) and (GetUnitStateSwap(UNIT_STATE_LIFE, TargetSecondary) > 0.00) and (IsUnitEnemy(TargetSecondary, GetOwningPlayer(udg_Archer)))

C'est à dire que l'unité est morte, est la même que la cible, ou n'est pas ennemie.
Alors ton code se résume à
Jass:
loop
        exitwhen boucle > 2
        set TargetSecondary = GroupPickRandomUnit(TargetGroup)
        call GroupRemoveUnit(TargetGroup, TargetSecondary)
        set Target = TargetSecondary
        set TargetSecondary = null
        set boucle = 1
        set boucle = boucle + 1
    endloop


Autrement dit une boucle infinie.
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 14/11/07 19:55    Sujet du message: Citer

Han merci beaucoup c'est le genre de truc que j'aurai jamais vu Rolling Eyes

Euh par contre j'ai beau chercher (chuis ptet un peu fatigué aussi ><) mais je vois pas comment empêcher cette boucle infinie =/

EDIT: si je filtre à l'entrée du groupe ça devrai le faire non ?
J'ai juste un problème pour ça : j'arrive pas à trouver comment exprimer la condition sans utiliser de fonction, je serais donc obligé d'utiliser une variable globale (pour désigner la position de la cible initiale)
_________________


Dernière édition par Serial Bigouden le 14/11/07 20:29; édité 1 fois
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 14/11/07 20:28    Sujet du message: Citer

edit ton code avec ce qu'à dit Ayane dèjà, il est ch.... à lire là ^^
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 14/11/07 22:27    Sujet du message: Citer

Bon beh voilà après discussion avec troll-brain, j'ai fini par réussir à construire un trigger qui marche, et qui marche bien ^^

Je vous le montre néanmoins pour régler les éventuels problèmes de leak ^^"

Jass:
function RotationTimeTraitsDeFoudre takes unit whichunit, location whichloc returns real
    local real angle = (RAbsBJ(( AngleBetweenPoints(GetUnitLoc(whichunit), whichloc)) - GetUnitFacing(whichunit)))
    if angle > 180 then
        set angle = 360 - angle
    endif
    return (angle/(360 * GetUnitTurnSpeed(whichunit)))
endfunction

function AttackTimeTraitsDeFoudre takes unit attacker, unit attacked, real missilespeed returns real
    local real distance = DistanceBetweenPoints(GetUnitLoc(attacker), GetUnitLoc(attacked))
    local real time = (distance)/(missilespeed)
    return time
endfunction

function TraitsDeFoudrePassiveTrigger_Conditions takes nothing returns boolean
    return (GetEventDamageSource() == udg_Archer) and (udg_DoT[GetPlayerId(GetOwningPlayer(GetEventDamageSource()))] == false)
endfunction

function TraitsDeFoudrePassive_Conditions takes nothing returns boolean
    return ((udg_ATraitsDeFoudreOn == true) and (GetAttacker() == udg_Archer) and (GetUnitState(GetAttacker(), UNIT_STATE_MANA) >= 49))
endfunction

function TraitsDeFoudrePassiveTrigger_Actions takes nothing returns nothing
    local integer d = R2I(70.00 + I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, udg_Archer, true)) )
    local unit ts = null
    local integer c = 3 * GetHeroAgi(udg_Archer, true)
    local integer z = 200 + 5 * GetHeroInt(udg_Archer, true)
    local boolean b = false
    local unit t = GetTriggerUnit()
    local unit u = null
    local group gt = CreateGroup()
    local group g = GetUnitsInRangeOfLocAll(z, GetUnitLoc(GetTriggerUnit()))
    call DestroyTrigger(GetTriggeringTrigger())
    call UnitDamageTargetBJ( udg_Archer, t, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_LIGHTNING )
    call CreateTextTagLocBJ( "-" + I2S(R2I(d)), GetUnitLoc(t), 10.00, 10, 100.00, 0.00, 0.00, 0.00 )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96, 90 )
    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
        loop
            set u = FirstOfGroup(g)
        exitwhen u == null
            if (GetUnitStateSwap(UNIT_STATE_LIFE, u) &gt; 0.00) and (IsUnitEnemy(u, GetOwningPlayer(udg_Archer))) then
                call GroupRemoveUnit(g, u)
                call GroupAddUnit(gt, u)
            endif
            call GroupRemoveUnit(g, u)
        endloop   
            set u = null
        loop
            call GroupRemoveUnit(gt, t)
            call GroupAddUnit(gt, t)
            set ts = FirstOfGroup(gt)
            if ts == t then
                set b = true
            elseif GetRandomInt(1, 100) <= c then
                call TriggerSleepAction( 0.00 )
                set c = R2I(c * 0.80)
                set d = R2I(d * 0.80)
                call CreateNUnitsAtLoc( 1, 'u601', Player(PLAYER_NEUTRAL_AGGRESSIVE), GetUnitLoc(t), 0.00)
                call IssueTargetOrderBJ( GetLastCreatedUnit(), "chainlightning", ts )
                call UnitApplyTimedLifeBJ( 0.50, 'BTLF', GetLastCreatedUnit() )
                call UnitDamageTargetBJ( udg_Archer, ts, d, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_LIGHTNING )
                call CreateTextTagLocBJ( "-" + I2S(R2I(d)), GetUnitLoc(ts), 10.00, 10, 100.00, 0.00, 0.00, 0.00 )
                call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
                call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96.00, 90 )
                call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
                call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
                set t = ts
                set ts = null
            else
                set b = true
            endif
            exitwhen b == true
        endloop
endfunction
   
function TraitsDeFoudrePassive_Actions takes nothing returns nothing
    local trigger Trigger = null
    set Trigger = CreateTrigger()
    call TriggerRegisterUnitEvent( Trigger, GetAttackedUnitBJ(), EVENT_UNIT_DAMAGED )
    call TriggerAddCondition( Trigger, Condition(function TraitsDeFoudrePassiveTrigger_Conditions) )
    call TriggerAddAction( Trigger, function TraitsDeFoudrePassiveTrigger_Actions )
    call TriggerSleepAction(RotationTimeTraitsDeFoudre(GetAttacker(), GetUnitLoc(GetTriggerUnit())) + AttackTimeTraitsDeFoudre(GetAttacker(), GetTriggerUnit(), 1200) + 0.10)
    call DestroyTrigger(Trigger)
endfunction

//===========================================================================
function InitTrig_TraitsDeFoudrePassive takes nothing returns nothing
    set gg_trg_TraitsDeFoudrePassive = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_TraitsDeFoudrePassive, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_TraitsDeFoudrePassive, Condition(function TraitsDeFoudrePassive_Conditions) )
    call TriggerAddAction( gg_trg_TraitsDeFoudrePassive, function TraitsDeFoudrePassive_Actions )
endfunction



C'est cependant un cas particulier, car dans ma map, il n'est pas possible d'avoir deux unités du même type, ce qui fait que l'astuce du remove/add unit d'un groupe pour la remettre derrière la "file d'attente" fonctionne parfaitement.
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Bantas
Anomalie floodiforme


Inscrit le: 21 Aoû 2007
Messages: 1524
Sujets: 37

Médailles: 1 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 14/11/07 23:37    Sujet du message: Citer

Ce n'est peut-être qu'un bug de la balise jass mais regardez cette ligne :
Jass:
if (GetUnitStateSwap(UNIT_STATE_LIFE, u) &gt; 0.00) and (IsUnitEnemy(u, GetOwningPlayer(udg_Archer)))

Ensuite j'aimerais bien savoir pourquoi tu fais I2S(R2I(d)) au lieu de simplement R2S(d) ^^

Citation:
un leak plus grave, il faut destroy l'action avant de detruire un trigger.
On en apprend tous les jours. Faudrait une liste des leaks à supprimer (la réponse "tu sais ce qu'il te reste à faire" ne sera pas acceptée Razz).
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Ayane
Bot administrateur


Inscrit le: 17 Sep 2007
Messages: 2012
Sujets: 49

Médailles: 2 (En savoir plus...)
Rédacteur de tuto #1 (Quantité : 1) Ayane (Quantité : 1)

MessagePosté le: 15/11/07 00:16    Sujet du message: Citer

Jass:
if (GetUnitStateSwap(UNIT_STATE_LIFE, u) < 0.00) and (IsUnitEnemy(u, GetOwningPlayer(udg_Archer))) then

A priori cela fonctionne correctement

Pour les fuites de mémoires sur les déclencheurs d'après des testes que j'avais effectué ce qu'il faudrait supprimer principalement ce sont les conditions, par exemple Condition(function TraitsDeFoudrePassive_Conditions) créer une condition qu'il faut supprimer, ce qui est logique car l'on peut très bien utiliser cette condition pour un autre déclencheur en même temps.
Un déclencheur ne fait que la liaison avec des conditions et actions, la destruction du déclencheur n'entraîne que la suppression de la liaison.
Pour la destruction des actions je ne suis pas sûr étant donné qu'on ne lui donne qu'un code, soit un entier, il devrait logiquement le stocker dans un tableau propre au déclencheur.
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 15/11/07 00:31    Sujet du message: Citer

Bantas a écrit:
Ensuite j'aimerais bien savoir pourquoi tu fais I2S(R2I(d)) au lieu de simplement R2S(d)


Pour que le texte flottant affiche -96 au lieu de -96.65325 ^^"
(c'est du vécu xD)

Sinon c'est bien une erreur de la balise jass, en réalité c'est

Jass:
if (GetUnitStateSwap(UNIT_STATE_LIFE, u) > 0.00) and (IsUnitEnemy(u, GetOwningPlayer(udg_Archer))) then


Sinon pour virer la condition il suffit de mettre un ptit TriggerClearConditions(GetTriggeringTrigger) ?
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 15/11/07 17:06    Sujet du message: Citer

@ Bantas : Tu sais parfaitement ce qu'il te reste à faire
Je sais c'est nul, mais j'ai mon topic à bug à nourrir Razz
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Bantas
Anomalie floodiforme


Inscrit le: 21 Aoû 2007
Messages: 1524
Sujets: 37

Médailles: 1 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 15/11/07 18:01    Sujet du message: Citer

Serial Bigouden a écrit:
Sinon pour virer la condition il suffit de mettre un ptit TriggerClearConditions(GetTriggeringTrigger) ?
Oui Smile
Sauf si tu veux supprimer une condition en particulier, dans ce cas il faudra utiliser :
Jass:
native TriggerRemoveCondition takes trigger whichTrigger, triggercondition whichCondition returns nothing


@Troll : Mr. Green
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 16/11/07 20:06    Sujet du message: Citer

Bon beh voilà jretombe sur une fatal error sur un autre trigger, sans vraiment comprendre pourquoi oO enfin voilà l'histoire :

Je ne sais pas si vous l'avez remarqué mais en ce moment je travaille sur les sorts que l'on peut mettre en autocast (flèches de flammes, de glace, ...), et c'est pas du gateau x)
J'ai remarqué, en essayant toutes les combinaisons possibles et imaginables de clic sur les quelques sorts en autocast attribués à mon héros (une archère...), jme suis rendu compte que se contenter de mettre une variable boléenne à vrai/faux quand l'unité reçoit l'ordre un/flamingarrows (par exemple) ne suffisait pas. En effet, il suffit d'activer l'autocast juste après que la flèche soit tirée pour ne pas dépenser de mana tout en obtenant les effets du sort (par trigger 'videmment), et, à l'inverse, si on désctive l'autocast alors que la flèche n'a pas encore atteint sa cible, beh pas d'effet kisscool et on dépense du mana pour rien.

J'ai donc eu une idée qui m'a paru viable (vous pourrez au passage me dire si elle l'est vraiment, en tout cas ça marche presque, à une FE près xD) :

A chaque fois que le héros reçoit un ordre d'activation d'autocast, un trigger est créé puis stocké dans une variable globale :

Jass:
function FlamingArrows_Conditions takes nothing returns boolean
    return ((GetTriggerUnit() == udg_ElvenArcher) and (GetIssuedOrderId() == String2OrderIdBJ("flamingarrows")) and (udg_FlamingArrows == false))
endfunction

function FlamingArrowsTrigger_Conditions takes nothing returns boolean
    return (GetAttacker() == udg_ElvenArcher)
endfunction

function FlamingArrowsTrigger_Actions takes nothing returns nothing
    call TriggerClearConditions(GetTriggeringTrigger())
    call TriggerClearActions(GetTriggeringTrigger())
    call DestroyTrigger(GetTriggeringTrigger())
    set udg_FlamingArrows = true
    set udg_ColdArrows = false
    set udg_VoidArrows = false
    set udg_LightningArrowOn = false
    set udg_ElvenArcherTriggerAutoCast = null
endfunction

function FlamingArrows_Actions takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerClearConditions(udg_ElvenArcherTriggerAutoCast)
    call TriggerClearActions(udg_ElvenArcherTriggerAutoCast)
    call DestroyTrigger(udg_ElvenArcherTriggerAutoCast)
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function FlamingArrowsTrigger_Conditions))
    call TriggerAddAction(t, function FlamingArrowsTrigger_Actions)
    set udg_ElvenArcherTriggerAutoCast = t
    set t = null
endfunction

//===========================================================================
function InitTrig_FlamingArrows takes nothing returns nothing
    set gg_trg_FlamingArrows = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_FlamingArrows, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(gg_trg_FlamingArrows, Condition(function FlamingArrows_Conditions))
    call TriggerAddAction(gg_trg_FlamingArrows, function FlamingArrows_Actions)
endfunction


Comme vous pouvez le constater, au moment où le héros attaquera, le trigger ainsi stocké passera le boléen déterminant si l'autocast est activé ou non à true puis détruit.

Si l'autocast est désactivé par la suite, ce trigger se met en route :

Jass:
function UnFlamingArrows_Conditions takes nothing returns boolean
    return ((GetTriggerUnit() == udg_ElvenArcher) and (GetIssuedOrderId() == String2OrderIdBJ("unflamingarrows")))
endfunction

function UnFlamingArrowsTrigger_Conditions takes nothing returns boolean
    return (GetAttacker() == udg_ElvenArcher)
endfunction

function UnFlamingArrowsTrigger_Actions takes nothing returns nothing
    call TriggerClearConditions(GetTriggeringTrigger())
    call TriggerClearActions(GetTriggeringTrigger())
    call DestroyTrigger(GetTriggeringTrigger())
    set udg_FlamingArrows = false
    set udg_ElvenArcherTriggerAutoCast = null
endfunction

function UnFlamingArrows_Actions takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerClearConditions(udg_ElvenArcherTriggerAutoCast)
    call TriggerClearActions(udg_ElvenArcherTriggerAutoCast)
    call DestroyTrigger(udg_ElvenArcherTriggerAutoCast)
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function UnFlamingArrowsTrigger_Conditions))
    call TriggerAddAction(t, function UnFlamingArrowsTrigger_Actions)
    set udg_ElvenArcherTriggerAutoCast = t
    set t = null
endfunction

//===========================================================================
function InitTrig_UnFlamingArrows takes nothing returns nothing
    set gg_trg_UnFlamingArrows = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_UnFlamingArrows, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(gg_trg_UnFlamingArrows, Condition(function UnFlamingArrows_Conditions))
    call TriggerAddAction(gg_trg_UnFlamingArrows, function UnFlamingArrows_Actions)
endfunction


Qui détruit donc le trigger précédement stocké

Et si le joueur met en route directement un autocast ? Pas de problème (je crois), la globale est reset et on stocke le trigger correspondant à l'autre sort, qui passera une autre variable à true...

Pour finir, le trigger déclenchant les effts du sort (des fois que la FE viendrait de là, même si j'en doute ^^")

Jass:
function FlamingArrowsSpellTrigger_Conditions takes nothing returns boolean
    return (udg_FlamingArrows == true) and (GetEventDamageSource() == udg_ElvenArcher) and (udg_DoT[GetPlayerId(GetOwningPlayer(GetEventDamageSource()))] == false)
endfunction

function FlamingArrowsSpell_Conditions takes nothing returns boolean
    return (GetAttacker() == udg_ElvenArcher) and (GetUnitState(GetAttacker(), UNIT_STATE_MANA) >= 19)
endfunction

function FlamingArrowsSpellTrigger_Actions takes nothing returns nothing
    local unit t = null
    local integer dmg = (GetHeroInt(udg_ElvenArcher, true) + R2I(GetEventDamage()))
    local group gt = CreateGroup()
    local player p = GetOwningPlayer(udg_ElvenArcher)
    local location tl = null
    local real z = 10 * I2R(GetHeroInt(udg_ElvenArcher, true))
    local real d = 0
    local unit dummy = null
    local real zdmg = 0
    call TriggerClearConditions(GetTriggeringTrigger())
    call DestroyTrigger(GetTriggeringTrigger())
    if (GetRandomInt(1, 100) <= (GetHeroAgi(udg_ElvenArcher, true))) then
        set dummy = CreateUnitAtLoc(Player(PLAYER_NEUTRAL_PASSIVE), 'u00F', GetUnitLoc(GetTriggerUnit()), 0)
        call IssueTargetOrder(dummy, "thunderbolt", GetTriggerUnit())
        call UnitApplyTimedLifeBJ(1.00, 'BTLF', dummy)
        call GroupEnumUnitsInRangeOfLoc(gt, GetUnitLoc(GetTriggerUnit()), z, null )
        loop
            set t = FirstOfGroup(gt)
        exitwhen t == null
            if (IsUnitEnemy(t, p)) and (GetUnitState(t, UNIT_STATE_LIFE) &gt; 0) then
                if (t == GetTriggerUnit()) then
                    call UnitDamageTargetBJ(udg_ElvenArcher, t, dmg * 1.20 + GetHeroInt(udg_ElvenArcher, true), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
                    call CreateTextTagLocBJ( "-" + I2S(R2I(dmg * 1.20) + GetHeroInt(udg_ElvenArcher, true)), GetUnitLoc(t), 0.00, 10, 100.00, 0.00, 0.00, 0.00 )
                    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
                    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96.00, 90 )
                    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
                    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
                    call GroupRemoveUnit(gt, t)
                else
                    set d = DistanceBetweenPoints(GetUnitLoc(t), GetUnitLoc(GetTriggerUnit()))
                    set zdmg = dmg*(((z - d)/z) + 0.20)
                    if zdmg &gt;= 10 then
                        call UnitDamageTargetBJ(udg_ElvenArcher, t, zdmg, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
                        call CreateTextTagLocBJ( "-" + I2S(R2I(zdmg)), GetUnitLoc(t), 0.00, 10, 100.00, 0.00, 0.00, 0.00 )
                        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
                        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96.00, 90 )
                        call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
                        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
                        call GroupRemoveUnit(gt, t)
                    else
                        call GroupRemoveUnit(gt, t)
                    endif
                endif
            else
                call GroupRemoveUnit(gt, t)
            endif
        endloop
    else
        call UnitDamageTargetBJ(udg_ElvenArcher, GetTriggerUnit(), I2R(GetHeroInt(udg_ElvenArcher, true)), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
        call CreateTextTagLocBJ("-" + I2S(GetHeroInt(udg_ElvenArcher, true)), GetUnitLoc(GetTriggerUnit()), 0.00, 10, 100.00, 0.00, 0.00, 0.00 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 96.00, 90 )
        call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 2.00 )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4.00 )
    endif
endfunction

function FlamingArrowsSpell_Actions takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent(t, GetAttackedUnitBJ(), EVENT_UNIT_DAMAGED)
    call TriggerAddCondition(t, Condition(function FlamingArrowsSpellTrigger_Conditions))
    call TriggerAddAction(t, function FlamingArrowsSpellTrigger_Actions)
    call TriggerSleepAction(RotationTime(GetAttacker(), GetUnitLoc(GetTriggerUnit())) + AttackTime(GetAttacker(), GetTriggerUnit(), 1200) + 0.20)
    call TriggerClearConditions(t)
    call DestroyTrigger(t)
    set t = null
endfunction

//===========================================================================
function InitTrig_FlamingArrowsSpell takes nothing returns nothing
    set gg_trg_FlamingArrowsSpell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_FlamingArrowsSpell, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_FlamingArrowsSpell, Condition(function FlamingArrowsSpell_Conditions) )
    call TriggerAddAction( gg_trg_FlamingArrowsSpell, function FlamingArrowsSpell_Actions )
endfunction


Voilà merci d'avoir tout lu (même si vous avez zappé le code xD), j'espère que c'est pas du à une pauvre faute de noob ^^"
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 16/11/07 20:37    Sujet du message: Citer

J'ai zappé le code mais sache que lorsqu'une unité reçoit l'ordre d'attaquer, à moins de lagger comme un porc on a toujours le temps de stopper l'ordre d'attaque mais l'event sera déclenché Sad

donc la solution la plus simple mais pas garantie comme je l'ai déjà dit, c'est de mettre un wait et de repérer quand l'unité subit des dégâts et de vérifier que l'attaquant est toujours le même.
Si aprés le wait l'unité n'a pas subit de degât du même attaquant on supprime le trigger

Pourquoi ce n'est pas garanti ?

car on peut pas différencier les dégâts d'un spell, d'une attaque Crying or Very sad

sur wc3campaigns.net ils utilisent une compétence orbe avec un buff de 0.01 s et il vérifient périodiquement quand l'unité est touchée (toutes les 0.01s), j'ignore si il y a des problèmes avec cette technique.

enfin j'en vois au moins une et toujours la même, si l'unité est sous l'emprise d'un buff de l'attaquant.
Cela a simplement moins de chances de se produire
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Serial Bigouden
Membre actif


Inscrit le: 31 Oct 2007
Messages: 142
Sujets: 23
Spécialité en worldedit: Boarf


MessagePosté le: 16/11/07 21:18    Sujet du message: Citer

Mouarf j'ai du encore mal m'exprimer ou alors tu n'as pas compris mon problème ^^"

Le sort en lui même marche très bien, les dégats s'affichent correctement quand la cible est effectivement touchée, il ya bien un efft de zone quand on a un poil de chance, et si la cible esquive, et si la cible subit des dégats sur le temps entre le moment où le trigger secondaire est créé et où il est détruit, cela ne déclenche pas le sort.

Mon seul problème est de faire qu'il ne soit pas possible de déclencher le sort lors d'une attaque normale, en activant l'autocast l'attaque et l'impact (et inversement de perdre du mana sans lancer le sort en désactivant l'autocast au même moment)

J'ai trouvé la solution au problème, mais ça me pond une FE dans un cas précis...
J'active l'autocast, je fonce à l'attaque et tire quelques flèches, tout ce passe bien, pas de FE en cas de proc du sort (qui produit des dégats de zone), bref ça roule. Pis après je désactive, ça marche toujours, si la flèche était déjà partie, le sort fait quand même effet, pis ensuite je réactive, première attaque impecc, et là deuxième attaque, juste après les dégats (juste au moment de la deuxième attaque en fait), FE --"

EDIT : non ça se déclenche pas si l'unité est sous l'emprise d'un buff de l'attaquant, car avant chaque "UnitDamageTarget" de ce genre de buffs (que je fais aussi par déclo), la variable DoT[numéros du joueur] passe true, pis false après, et cette variable est dans la condition du sort ^^"

EDIT²: en fait la FE survient aléatoirement, mais jamais à la première attaque...
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 16/11/07 21:56    Sujet du message: Citer

Je me suis mal exprimé je n'ai plus le temps là, je verrais ca demain.
Mais encore une fois comment peux tu savoir avec exactitude si c'est une attaque qui s'est finie et non pas qui a simplement commencée
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Worldedit Index du Forum -> Aide sur les déclencheurs Toutes les heures sont au format GMT + 1 Heure
Aller à la page 1, 2  Suivante
Page 1 sur 2

 
Sauter vers:  
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


Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com