Inscrit le: 21 Avr 2008 Messages: 1607 Sujets: 81 Spécialité en worldedit: Utiliser le travail des autres Médailles: 3 (En savoir plus...)
Posté le: 19/08/10 16:22 Sujet du message: Questions en vJass et petit problème de lagg avec un sort
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.
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)
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.
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
Merci beaucoup d'avoir tout lu et de vos réponses. _________________
Inscrit le: 13 Oct 2007 Messages: 994 Sujets: 25 Spécialité en worldedit: Codeur
Posté le: 19/08/10 17:08 Sujet du message:
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
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.
Inscrit le: 21 Avr 2008 Messages: 1607 Sujets: 81 Spécialité en worldedit: Utiliser le travail des autres Médailles: 3 (En savoir plus...)
Posté le: 19/08/10 19:14 Sujet du message:
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 ^^ _________________
Inscrit le: 13 Oct 2007 Messages: 994 Sujets: 25 Spécialité en worldedit: Codeur
Posté le: 20/08/10 08:46 Sujet du message:
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.
Inscrit le: 21 Avr 2008 Messages: 1607 Sujets: 81 Spécialité en worldedit: Utiliser le travail des autres Médailles: 3 (En savoir plus...)
Posté le: 20/08/10 11:26 Sujet du message:
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. _________________
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