Worldedit
  Worldedit
Le site sur l'éditeur de warcraft 3 !
 
  FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres    Groupes d'utilisateursGroupes d'utilisateurs   medals.phpMé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

Questions en vJass et petit problème de lagg avec un sort

 
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
 Crowolf
Animateur


Inscrit le: 21 Avr 2008
Messages: 1607
Sujets: 81
Spécialité en worldedit: Utiliser le travail des autres
Médailles: 3 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand décorateur (Quantité : 2)

MessagePosté le: 19/08/10 16:22    Sujet du message: Questions en vJass et petit problème de lagg avec un sort Citer

Salut, alors en fait j'ai "perdu" mon dossier avec mes cartes de RAoC non protégées (mode gros boulet). Mais je me suis dis que c'était une excellente occasion pour faire ce que j'avais dis et repasser les sorts en vJass.

Sur un sort "Dévotion", j'ai un petit problème. Lors du premier lancement du sort par le héros, il y a un léger freeze. Pourtant, j'ai suivi le tuto de Flame_Phoenix sur TheHiveWorkshop et j'ai ajouté ces lignes qui sont censées éviter ce problème.
Secret:

Jass:
        //preloading effects
        call Preload(AOE_EFFECT)
        call Preload(ALLY_EFFECT)
        call Preload(ENEMY_EFFECT)
       
        set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, 0, 0, 0)
        call UnitAddAbility(bj_lastCreatedUnit, SPELL_ID)
        call KillUnit(bj_lastCreatedUnit)



La description du sort pour vous aidez à bien comprendre le résultat que je voulais. Les gemmes sont en fait des compétences. En fonction des items possédé, on récupère un certain nombre d'un certain type de gemme.
Secret:

Danil invoque la puissance de la Lumière pour protéger ses alliés et affaiblir ses ennemis. Augmente la défense des alliés et diminue celle des adversaires de 1 toutes les secondes. Les unités retrouvent leur défense original en fonction du temps.

Effets :
-Bonus en défense

-Voies de Magie :Lumière, Hermétisme.

Niveau 1 - Zone d'effet<A00F,Area1>
Dure <A00F,HeroDur1> secondes.
Niveau 2 - Zone d'effet <A00F,Area2>
Dure <A00F,HeroDur2> secondes.
Niveau 3 - Zone d'effet <A00F,Area3>
Dure <A00F,HeroDur3> secondes.

Bonus en défense : Chaque Gemmes de Lumière, ou d'Hermétisme augmente ou diminue la défense de 1 dès le début de l'incantation.Coldown : <A00F,Cool1>/<A00F,Cool2>/<A00F,Cool3> secondes




Le code du sort.
Secret:

Jass:
scope Devotion initializer Init
//=============================================================================
//=============================================================================
//=============================================================================
   globals
        private constant integer SPELL_ID = 'A00F'// ID du sort basé sur channeling
        private constant integer LightGem = 'A001'
        private constant integer HermetismGem = 'A00A'
        private constant integer BONUS_A = 'A00B'//Le bonus donné par la compétence
        private constant integer MALUS_A = 'A009'//le malus donné par la compétence
        private constant integer BONUS_G = 'A00C'//le bonus donné par les gemmes
        private constant integer MALUS_G = 'A00D'
        private constant integer AllyBuff = 'A00E'//La compétence qui ajoute un buff aux alliés
        private constant integer EnemyBuff = 'A00G'//Buff aux enemy
        private constant integer ABUFF_ID = 'B005'//Buff des alliés
        private constant integer EBUFF_ID = 'B007'//Buff des enemy
        private constant integer DUMMY_ID = 'h001'//Dummy
        private constant string AOE_EFFECT = "Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl"
        private constant string ALLY_EFFECT = "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
        private constant string ENEMY_EFFECT = "Abilities\\Spells\\Orc\\Voodoo\\VoodooAuraTarget.mdl"
        private constant real tDEF = 1.
       
    endglobals
   
    private function Duration takes real duration, integer level returns nothing
        set duration = level * 8.
    endfunction
   
    private function Range takes integer level returns real
        return level * 100. + 400.
    endfunction
   
    private function Targets takes unit target returns boolean
        return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
    endfunction
//=============================================================================
//=============================================================================
//=============================================================================
    globals
        private group all
        private boolexpr b
        private group copy
        private group ally
        private group enemy
    endglobals
//=============================================================================
//Function made by Blade.dk
    private function CopyGroup takes group g returns group
        set bj_groupAddGroupDest = CreateGroup()
        call ForGroup(g, function GroupAddGroupEnum)
        return bj_groupAddGroupDest
    endfunction
//=============================================================================
    private function Pick takes nothing returns boolean
        return Targets(GetFilterUnit())
    endfunction
//=============================================================================
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID 
    endfunction

//==============================================================================
    struct Devotion
        unit caster
        unit u
        group copy
        group ally
        group enemy
        integer level
        integer i
    endstruct
//==============================================================================
//Fonction qui augmente le niveau de la compétence de défense des alliés
    private function IncreaseDef takes nothing returns nothing
        if GetUnitAbilityLevel(GetEnumUnit(), ABUFF_ID) > 0 then
            call IncUnitAbilityLevel(GetEnumUnit(), BONUS_A)
            call DestroyEffect(AddSpecialEffectTarget(ALLY_EFFECT, GetEnumUnit(), "overhead"))
        else
            call GroupRemoveUnit(ally, GetEnumUnit())
            call UnitRemoveAbility( GetEnumUnit(), BONUS_A)
            call UnitRemoveAbility( GetEnumUnit(), BONUS_G)
        endif
   
    endfunction
//==============================================================================
//Fonction qui diminue la défense des ennemies
    private function DecreaseDef takes nothing returns nothing
        if GetUnitAbilityLevel(GetEnumUnit(), EBUFF_ID) > 0 then
            call IncUnitAbilityLevel(GetEnumUnit(), MALUS_A)
            call DestroyEffect(AddSpecialEffectTarget(ENEMY_EFFECT, GetEnumUnit(), "overhead"))
        else
            call GroupRemoveUnit(enemy, GetEnumUnit())
            call UnitRemoveAbility( GetEnumUnit(), MALUS_A)
            call UnitRemoveAbility( GetEnumUnit(), MALUS_G)
        endif
   
    endfunction
//==============================================================================
//==============================================================================
//fonction qui diminue le niveau de la compétence de défense des alliés
    private function IncreaseDefEnd takes nothing returns nothing
        if GetUnitAbilityLevel(GetEnumUnit(), ABUFF_ID) > 0 then
            call DecUnitAbilityLevel(GetEnumUnit(), BONUS_A)
            call DestroyEffect(AddSpecialEffectTarget(ALLY_EFFECT, GetEnumUnit(), "overhead"))
        else
            call GroupRemoveUnit(ally, GetEnumUnit())
            call UnitRemoveAbility( GetEnumUnit(), BONUS_A)
            call UnitRemoveAbility( GetEnumUnit(), BONUS_G)
        endif
   
    endfunction
//==============================================================================
//Rend la défense originale des ennemies
    private function DecreaseDefEnd takes nothing returns nothing
        if GetUnitAbilityLevel(GetEnumUnit(), EBUFF_ID) > 0 then
            call DecUnitAbilityLevel(GetEnumUnit(), MALUS_A)
            call DestroyEffect(AddSpecialEffectTarget(ENEMY_EFFECT, GetEnumUnit(), "overhead"))
        else
            call GroupRemoveUnit(enemy, GetEnumUnit())
            call UnitRemoveAbility( GetEnumUnit(), MALUS_A)
            call UnitRemoveAbility( GetEnumUnit(), MALUS_G)
        endif
   
    endfunction
//==============================================================================
    private function Periodic takes nothing returns nothing// La fonction periodique qui va modifier la défense (Merci Apocalypse/jk2pach)
        local timer chrono = GetExpiredTimer()
        local Devotion data = GetTimerData(chrono)// on attache les données de la struct au timer
       
        if data.i < data.level * 8 then
// si le sort est à la moitié de sa durée, on augmente le niveau des compétences de défense
            call ForGroup(data.ally, function IncreaseDef)
            call ForGroup(data.enemy, function DecreaseDef)
            set data.i = data.i + 1
        else
            call ForGroup(data.ally, function IncreaseDefEnd)
            call ForGroup(data.enemy, function DecreaseDefEnd)
            set data.i = data.i + 1
        endif
//si la durée du sort est finie, on enlève toutes les compétences bonus
        if data.level * 8 * 2 == data.i then           
            loop
                set data.u = FirstOfGroup(data.ally)
                exitwhen(data.u == null)
                call GroupRemoveUnit(data.ally, data.u)
                call UnitRemoveAbility( data.u, BONUS_G)
                call UnitRemoveAbility( data.u, BONUS_A)
            endloop       
            loop
                set data.u = FirstOfGroup(data.enemy)
                exitwhen(data.u == null)
                call GroupRemoveUnit(data.enemy, data.u)
                call UnitRemoveAbility( data.u, MALUS_G)
                call UnitRemoveAbility( data.u, MALUS_A)
            endloop
           
            set data.i = 0
            set data.u = null
            set data.ally = null
            set data.enemy = null
            call ReleaseTimer(chrono)//on libère le timer
            call data.destroy()//on détruit la struct
        endif

    endfunction
//=============================================================================
    private function Actions takes nothing returns nothing
        local timer chrono = NewTimer()
        local Devotion data = Devotion.create()
        local location spellLoc = GetSpellTargetLoc()
        local real spellX = GetLocationX(spellLoc)
        local real spellY = GetLocationY(spellLoc)
        local unit caster = GetTriggerUnit()
        local unit u = null
        local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
        local integer lvl_lgem = GetUnitAbilityLevel(caster, LightGem)
        local integer lvl_hgem = GetUnitAbilityLevel(caster, HermetismGem)
        local integer nbr_gem = lvl_lgem + lvl_hgem
        local integer owner = GetPlayerId(GetOwningPlayer(caster))
        local integer i = 0
        local unit dummy = null
       
        set data.caster = caster
        set data.u = u
        set data.copy = copy
        set data.ally = ally
        set data.enemy = enemy
        set data.level = level
        set data.i = i
           
        call GroupEnumUnitsInRange(all, spellX, spellY, Range(level), b)
        set copy = CopyGroup(all)
        call DestroyEffect(AddSpecialEffect(AOE_EFFECT, spellX, spellY))
//on lance le sort qui donne le buff sur chaques unités dans la zone d'effet.
//ce buff permet de dissiper le sort
        loop
            set u = FirstOfGroup(copy)
            exitwhen(u == null)
            call GroupRemoveUnit(copy, u)
            if IsUnitAlly(u, GetOwningPlayer(caster)) then
                call GroupAddUnit( ally, u)
                call CreateNUnitsAtLoc(1, DUMMY_ID, Player(owner), spellLoc, bj_UNIT_FACING)
                set dummy = GetLastCreatedUnit()
                call UnitApplyTimedLife( dummy, 'BTLF', 1)
                call UnitAddAbility(dummy, AllyBuff)
                call SetUnitAbilityLevel(dummy, AllyBuff, level)
                call IssueTargetOrder(dummy, "innerfire", u)
                call UnitAddAbility(u, BONUS_A)
                set dummy = null
                if nbr_gem != 0 then
                    call UnitAddAbility(u, BONUS_G)
                    call SetUnitAbilityLevel(u, BONUS_G, nbr_gem)
                endif
            else
                call GroupAddUnit(enemy, u)
                call CreateNUnitsAtLoc(1, DUMMY_ID, Player(owner), spellLoc, bj_UNIT_FACING)
                set dummy = GetLastCreatedUnit()
                call UnitApplyTimedLife( dummy, 'BTLF', 1)
                call UnitAddAbility(dummy, EnemyBuff)
                call SetUnitAbilityLevel(dummy, EnemyBuff, level)
                call IssueTargetOrder(dummy, "slow", u)
                call UnitAddAbility(u, MALUS_A)
                set dummy = null
                if nbr_gem != 0 then
                    call UnitAddAbility(u, MALUS_G)
                    call SetUnitAbilityLevel(u, MALUS_G, nbr_gem)
                endif
            endif
        endloop
        set dummy = null

        call SetTimerData(chrono, data)
        call TimerStart(chrono, tDEF, true, function Periodic)
               
        call RemoveLocation(spellLoc)
        set spellLoc = null
        set caster = null
    endfunction
//=============================================================================
    private function Init takes nothing returns nothing
        local trigger DevotionTrg = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(DevotionTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(DevotionTrg, Condition( function Conditions ) )
        call TriggerAddAction( DevotionTrg, function Actions )
       
        //setting globals
        set all = CreateGroup()
        set copy = CreateGroup()
        set ally = CreateGroup()
        set enemy = CreateGroup()
        set b = Condition(function Pick)
        //preloading effects
        call Preload(AOE_EFFECT)
        call Preload(ALLY_EFFECT)
        call Preload(ENEMY_EFFECT)
       
        set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, 0, 0, 0)
        call UnitAddAbility(bj_lastCreatedUnit, SPELL_ID)
        call KillUnit(bj_lastCreatedUnit)
    endfunction   
endscope



Voici la map, si vous voulez tester le sort et regarder les 2 autres. Nécessite le JassNewGenPack.
Télécharger la map

Voilà, si vous pouviez me dire tout ce qu'il ne va pas ou ce que je pourrais améliorer, ce serait cool. Il y a certaines fonctions dont je ne suis pas sûr qu'elles soient les meilleures du monde.Par exemple CreateNUnitAtLoc(), mais CreateUnit() ne marchait pas chez moi. Pas de message d'erreur mais les unités ne recevait pas le buff. Confused

J'en viens maintenant à mes question, elles concernent les method et static method.
J'ai compris que les method sont comme des fonction mais à l'intérieur des structs. En gros les structs permettent d'utiliser des variables dans plusieurs fonctions sans les déclarer. (Je crois que j'ai bon jusque là ^^)
Les methods utilise 'this.' avant les variables déclarées dans la struct.
Les static methods n'utilise pas 'this.' mais peuvent utiliser les private members (On entend bien par private members, les fonction, variables etc. ayant le "préfixe" 'private'?)

Et donc, pourquoi utilise-t-on des method plutôt que des fonctions avec struct.variable?

En fait, on va commencer par ça, je poserais mes questions sur les private struct et static variable après.

Est-ce que ce serait trop demander une petite séance de TP pour créer un damage over time de zone par exemple. Tout ceux que j'ai vu utilisaient les method.
[edit] je viens juste de trouver un tuto pour ça sur W3C Rolling Eyes

Merci beaucoup d'avoir tout lu et de vos réponses.
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Magus
Membre a fort taux de post


Inscrit le: 13 Oct 2007
Messages: 994
Sujets: 25
Spécialité en worldedit: Codeur


MessagePosté le: 19/08/10 17:08    Sujet du message: Citer

Je ne sais pas à quoi set Preload, mais si mes souvenirs sont bons, pour éviter ce freeze il faut donner les sorts à une unité présente sur la carte au départ. Puis dés le début de la partie tu peux la supprimer.

A moins que je confonde avec le bug du livre de sort. Je suis plus sur Very Happy

Pour tes autres questions, laisse les méthodes et les membres static de côté pour l'instant tant que tu n'as pas compris le reste.
La meilleur façon d'avancer est de se fixer un but et de l'atteindre, puis de recommencer. (je ne sais plus qui à dit ça, Leonard de Vinci je crois, ou peut être Voltaire).

Une struct (ou une classe dans les autres langages), sert à représenter un objet de la réalité.
Un exemple con, tu veux représenter une personne. Tu vas faire une struct Personne avec en membre (ou attribut, on peut les appeler des 2 façons) le nom, le prénom, l'age, la couleur de cheveux, etc ...

Ensuite il y a une autre principe qu'on appelle l'encapsulation. Un instance d'une classe (un objet donc), doit assurer sa propre intégrité et ne jamais se retrouver dans un état instable.
Donc tu vois, si tu rends un membre public (accessible à tous le monde), c'est dangereux. Car tu ne peux pas empêcher les autres de mettre n'importe quoi dans ton membre.
Donc on préfère passer par des méthodes, comme ça on peut maitriser ce qu'on fait et empêcher d'arriver dans un état dangereux.
_________________
- La théorie c'est quand rien ne fonctionne mais tout le monde sait pourquoi.
- La pratique c'est quand tout fonctionne mais personne ne sait pourquoi.
- Chez moi la théorie et la pratique sont réunies, rien ne fonctionne et personne ne sait pourquoi.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger
 Crowolf
Animateur


Inscrit le: 21 Avr 2008
Messages: 1607
Sujets: 81
Spécialité en worldedit: Utiliser le travail des autres
Médailles: 3 (En savoir plus...)
Grand décorateur (Quantité : 2) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 19/08/10 19:14    Sujet du message: Citer

Ok, je commence à mettre de l'ordre dans toutes ces notions. Le tuto que j'ai trouvé sur W3C explique bien aussi, je pense que quand je l'aurais fini et refais des spells j'aurais bien assimilé.
En tout cas, c'est trop cool de plus utiliser la molette de la souris pour choisir les actions ^^
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Magus
Membre a fort taux de post


Inscrit le: 13 Oct 2007
Messages: 994
Sujets: 25
Spécialité en worldedit: Codeur


MessagePosté le: 20/08/10 08:46    Sujet du message: Citer

Ce ne sont pas des questions qui se limitent au vJass. Ce sont des questions générales sur la programmation. Tu trouveras beaucoup de tutos ailleurs que sur W3C.
_________________
- La théorie c'est quand rien ne fonctionne mais tout le monde sait pourquoi.
- La pratique c'est quand tout fonctionne mais personne ne sait pourquoi.
- Chez moi la théorie et la pratique sont réunies, rien ne fonctionne et personne ne sait pourquoi.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger
 Crowolf
Animateur


Inscrit le: 21 Avr 2008
Messages: 1607
Sujets: 81
Spécialité en worldedit: Utiliser le travail des autres
Médailles: 3 (En savoir plus...)
Grand décorateur (Quantité : 2) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 20/08/10 11:26    Sujet du message: Citer

J'ai regardé des tutos sur le C++ parce que c'est ce que j'utilise le plus à la fac (de géol, pas d'info ^^), mais comme je n'ai jamais fais d'OOP et que je suis un peu une buse dès qu'on rentre dans l'abstrait, ça met du temps à rentrer.
Je me suis servi du tuto de W3C
http://www.wc3c.net/showthread.php?t=100953
pour rendre le sort Dévotion stakable 2 fois. Ca marche, mais je cherche s'il n'y aurait pas des leaks.
Par contre, pour le freeze du départ, j'ai toujours pas trouvé. La compétence est basée sur canaliser parce que je ne veut pas avoir d'autres buff et les autres sorts de zones en ajoutent tous un, ou ministun, ou dispell etc.
_________________
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
Page 1 sur 1

 
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