Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 02/06/12 17:58 Sujet du message: [vJass] Buff
Nom de la fonction : Buff Créateur : Sapeur-Goblin
Fonctions requises : UnitIndexer et TimerUtils et optionnellement DamageEvent Code :
Secret:
Jass:
library Buff /*
*************************************************************************************
*
* Permet un développement rapide et efficace de buffs.
*
*************************************************************************************
*
* */ uses /*
*
* - */ UnitIndexer /*
* - */ TimerUtils /*
* - */ optional DamageEvent /*
*
*************************************************************************************
*
* La création de buff commence par la définition d'un type de buff, ce faisant
* dans une structure à laquelle il faut implémenter le module BuffStruct, extendant
* array de préférence pour éviter une surcharge de code inutile :
*
* struct BuffTypeA extends array
*
* implement BuffStruct
*
* endstruct
*
* Ensuite, il est possible de défnir les différentes configurations pour le type de
* buff en incluant des membres statiques. Tous sont optionnels (la valeur indiquée
* ci-dessous est la valeur par défaut) :
* - static boolean stackable = false
* • Lorsqu'un buff non stackable est appliqué à une unité bénéficiant
* déjà de ce type de buff, l'ancien buff est rafraîchi.
* • Voir la réponse d'événement onRefresh pour plus d'informations.
* - static boolean permanent = false
* • Les buffs permanents ne peuvent pas être dissipés.
* • Voir la section Dispel pour plus d'informations.
* - static integer dispellPriority = -1
* • Voir la section Dispel pour plus d'informations
* - static integer auraId = 0
* • Permet d'afficher le buff dans la barre d'état de l'unité.
* • Pour cela, créer un sort basé sur aura de lenteur, et réfler les
* cibles sur personnel.
* • Ajouter ensuite le buff conrrespondant.
* - static integer buffId = 0
* • Il s'agit du buff ajouté par l'aura de lenteur.
* - static integer alignment = BUFF_ALIGNMENT_NEUTRAL
* • Alignement du buff. Il en existe trois types :
* • BUFF_ALIGNMENT_POSITIVE
* • BUFF_ALIGNMENT_NEGATIVE
* • BUFF_ALIGNMENT_NEUTRAL
* - static boolean positiveBuffImmune = false
* • Immunise l'unité contre les buffs positifs.
* - static boolean negativeBuffImmune = false
* • Immunise l'unité contre les buffs négatifs.
* - static boolean neutralBuffImmune = false
* • Immunise l'unité contre les buffs neutres.
* - static boolean positiveDispelImmune = false
* • Immunise l'unité contre les dissipations de buffs positifs.
* - static boolean negativeDispelImmune = false
* • Immunise l'unité contre les dissipations de buffs négatifs.
* - static boolean neutralDispelImmune = false
* • Immunise l'unité contre les dissipations de buffs neutres.
* - static boolean keepAtDeath = false
* • L'unité garde le buff lorsquelle meurt.
* - static real period
* • Période pour les réponses d'événement périodiques.
* - static integer damagePriority = 0
* • Priorité de l'appel de la méthode onDamage.
* - static integer category = 0
* • A utiliser comme vous le souhaitez.
*
* Une fois ces paramètres définis, il est possible d'ajouter des réponses d'événement.
* Il existe huit réponses, toutes optionnelles :
* - static method onApply takes Buff this returns nothing
* • Appelée lors de l'application du buff.
* - static method onPeriodic takes Buff this returns nothing
* • Méthode appelée périodiquement.
* • Il est nécessaire d'ajouter un paramètre period.
*
* - static method onRefresh takes Buff this returns nothing
* • Appelée lorsque le buff est rafraîchi.
* • Pour accéder aux paramètres de l'ancien buff, utiliser :
* • previousDuration
* • previousCaster
* • previousLevel
*
* - static method onDispel takes Buff this, unit dispeler, boolean b returns nothing
* • Appelée lorsqu'une tentative de dissipation du buff a lieu.
* • L'argument unité correspond à l'unité essayant de dissiper le buff.
* • L'argument boolean vaut true si la disspation a réussie (le buff sera alors
* détruit), false sinon.
* • Voir la sections Dispel pour plus d'informations.
*
* - static method onExpire takes Buff this returns nothing
* • Appelée lorsque le buff expire (la durée est nulle).
* • Il est possible de redéfinir la durée pour que le buff ne soit pas détruit.
*
* - static method onDeath takes Buff this returns nothing
* • Appelée lorsque le trajet du buff meurt.
*
* - static method onRemove takes Buff this returns nothing
* • Appelée lorsque le buff est détruit.
* • Redéfinir la durée ou le rafraîchir n'empêchera pas sa déstruction.
*
* - static method onDamage takes Buff this returns nothing
* • Appelée lorsque le trajet du buff subit des dégâts.
* • Ne peut être utilisé qu'avec la bibliothèque DamageEvent.
*
* La structure possède aussi une méthode apply permettant d'appliquer le type de buff et
* type, renvoyant le type de buff.
*
*************************************************************************************
*
* struct Buff extends array
*
* - readonly unit caster (utiliser refresh pour modifier ce paramètre)
* - readonly unit target
* - readonly integer targetId
* - readonly real level (utiliser refresh pour modifier ce paramètre)
* - public real duration (method operator)
* - public real initialDuration (method operator)
* - static method apply takes BuffType buffType, unit caster, unit target, real level,
* real duration returns thistype
* • Si la durée est nulle, le buff n'expirera jamais.
* - method destroy takes nothing returns nothing
* • Préferer utiliser les dissipations de buff que cette méthode.
* - method refresh takes unit caster, real level, real duration returns thistype
* • Rafraîchit le buff avec les nouveaux paramètres.
* • Un buff peut être rafraîchit même si l'unité est immunisée contre
* l'application du type de buff correspondant.
* - static method has takes unit target, BuffType buffType returns boolean
* - static method count takes unit target returns integer
* - static method countType takes unit target, BuffType buffType returns integer
* - static method countAlignment takes unit target, integer alignment returns integer
* - static method immune takes unit target, integer alignment returns boolean
* - Renvoie true si l'unité est immunisée aux buffs de l'alignement spécifié.
* - static method dispelImmune takes unit target, integer alignment returns boolean
* - Renvoie true si l'unité est immunisée aux dispels de l'alignement spécifié.
*
*
*************************************************************************************
*
* Dispel
* ------
*
* - method dispel takes unit dispeler, integer priority returns boolean
* • Le buff en question sera dissipé si la priorité du dispel est supérieure
* strictement à la priorité de dissipation du buff.
*
* - static method dispelAlignment takes unit dispeler, unit target, integer priority, integer alignment returns integer
* • Applique une dissipation sur tous les buffs de l'alignement spécifié sur la cible.
*
* - static method dispelAll takes unit dispeler, unit target, integer priority returns integer
* • Applique une dissipation sur tous les buffs de la cible.
*
* Les buffs permanents ne peuvent pas être dissipés, mais peuvent être détruits par l'intermédiaire de
* la méthode destroy().
*
* Manipuler les buffs d'une unité
* -------------------------------
*
* Les buffs d'une unité sont classés pour permettre des énumérations efficaces.
* Chaque buff possède les membres next et prev, permettant d'accéder aux buffs
* suivants et précédents :
* A1 A2 A3 C1 C2 B1 B2 B3 D1 D2 E1 E2 E3 E4 E5
* -------------- -> -------------- -> --------------
* Buffs positifs Buffs négatifs Buffs neutres
*
* Il existe trois manières d'accéder aux buffs d'une unité :
* - local Buff this = Buff[unit]
* • Renvoie le premier buff d'une unité.
* • loop
* exitwhen this == 0
* set this = this.next
* endloop
* - local Buff this = Buff[unit][type]
* • Renvoie le premier buff d'une unité du type spécifié.
* • loop
* exitwhen this.type != monType
* set this = this.next
* endloop
* - local Buff this = Buff91;unit]91;alignment]
* • Renvoie le premier buff d'une unité de l'alignement spécifié.
* • loop
* exitwhen this.type.alignment != monAlignement
* set this = this.next
* endloop
*
*************************************************************************************/
method operator target takes nothing returns unit
return GetUnitById(targetId)
endmethod
method operator initialDuration takes nothing returns real
return TimerGetTimeout(tim)
endmethod
method operator duration takes nothing returns real
return TimerGetRemaining(tim)
endmethod
method operator duration= takes real dur returns nothing
if (dur > 0) then
if (tim == null) then
set tim = NewTimerEx(this)
endif
call TimerStart(tim, dur, false, function thistype.expire)
else
if (tim != null) then
call ReleaseTimer(tim)
set tim = null
endif
endif
endmethod
static method has takes unit targ, integer id returns boolean
return HaveSavedInteger(table, GetUnitUserData(targ), id)
endmethod
if (buffType.positiveBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralBuffImmune) then
call decreaseImmuneCount(targetId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (buffType.positiveDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralDispelImmune) then
call decreaseDispelImmuneCount(targetId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (this == previous) then
if (buffType != next.buffType) then
call removeFirst(targetId, buffType)
call removeCount(targetId, buffType)
call UnitRemoveAbility(target, buffType.auraId)
call UnitRemoveAbility(target, buffType.buffId)
else
call setFirst(targetId, buffType, next)
endif
set previous = first(targetId, buffType.alignment)
if (this == previous) then
if (buffType.alignment != next.buffType.alignment) then
call removeFirst(targetId, buffType.alignment)
call removeCount(targetId, buffType.alignment)
else
call setFirst(targetId, buffType.alignment, next)
endif
endif
endif
if (prev == 0) then
set firstBuff91;targetId] = next
else
set prev.next = next
endif
set next.prev = prev
set caster = null
call ReleaseTimer(tim)
set tim = null
call ReleaseTimer(periodicTim91;this])
set periodicTim91;this] = null
set recycle = thistype(0).recycle
set thistype(0).recycle = this
endmethod
method dispel takes unit cast, integer priority returns boolean
set eventBool = priority > buffType.dispelPriority and not buffType.permanent and not dispelImmuneById(targetId, buffType.alignment)
if (buffType.hasDispelEvent) then
set thistype(0).caster = cast
call fireEvent(dispelEvent)
endif
if (eventBool) then
call destroy()
endif
return eventBool
endmethod
static method dispelAlignment takes unit cast, unit targ, integer priority, integer align returns integer
local thistype this = thistype91;targ]91;align]
local integer c = 0
loop
exitwhen (buffType.alignment != align)
set eventBool = priority > buffType.dispelPriority and not buffType.permanent and not dispelImmuneById(targetId, align)
if (buffType.hasDispelEvent) then
set thistype(0).caster = cast
call fireEvent(dispelEvent)
endif
if (eventBool) then
set c = c + 1
call destroy()
endif
set this = next
endloop
return c
endmethod
private static method expire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if (buffType.hasExpireEvent) then
call fireEvent(expireEvent)
endif
if (tim != null and duration == 0) then
call destroy()
endif
endmethod
method refresh takes unit cast, real lev, real dur returns thistype
local real plev = previousLevel
local real pdur = previousDuration
local unit pcas = previousCaster
set previousLevel = level
set previousDuration = duration
set previousCaster = caster
set caster = cast
set level = lev
set duration = dur
if (buffType.hasRefreshEvent) then
call fireEvent(refreshEvent)
endif
set previousLevel = plev
set previousDuration = pdur
set previousCaster = pcas
return this
endmethod
static method apply takes BuffType buffType, unit cast, unit targ, real lev, real duration returns thistype
local thistype this
local thistype previous
local thistype align
local integer targId = GetUnitUserData(targ)
if (targId == 0 or immuneById(targId, buffType.alignment)) then
return 0
endif
set previous = LoadInteger(table, targId, buffType)
if (not buffType.stackable and previous != 0) then
return previous.refresh(cast, lev, duration)
else
if (thistype(0).recycle != 0) then
set this = thistype(0).recycle
set thistype(0).recycle = recycle
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
set align = first(targId, buffType.alignment)
if (previous == 0) then
if (align == 0) then
set previous = firstBuff91;targId]
else
set previous = align
endif
call UnitAddAbility(targ, buffType.auraId)
call SetUnitAbilityLevel(targ, buffType.auraId, R2I(lev))
call UnitMakeAbilityPermanent(targ, true, buffType.auraId)
endif
if (previous == firstBuff91;targId]) then
set firstBuff91;targId] = this
call setFirst(targId, buffType.alignment, this)
elseif (previous == align) then
call setFirst(targId, buffType.alignment, this)
endif
call setFirst(targId, buffType, this)
set prev = previous.prev
set next = previous
set prev.next = this
set next.prev = this
if (buffType.positiveBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralBuffImmune) then
call increaseImmuneCount(targId, BUFF_ALIGNMENT_NEUTRAL)
endif
if (buffType.positiveDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_POSITIVE)
endif
if (buffType.negativeDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_NEGATIVE)
endif
if (buffType.neutralDispelImmune) then
call increaseDispelImmuneCount(targId, BUFF_ALIGNMENT_NEUTRAL)
endif
set caster = cast
set targetId = targId
set level = lev
set buffType = buffType
if (duration > 0) then
set tim = NewTimerEx(this)
call TimerStart(tim, duration, false, function thistype.expire)
endif
if (buffType.hasApplyEvent) then
call fireEvent(applyEvent)
endif
endif
return this
endmethod
private static method onDeath takes nothing returns boolean
local thistype this = firstBuff91;GetUnitUserData(GetDyingUnit())]
loop
exitwhen (this == 0)
if (buffType.hasDeathEvent) then
call fireEvent(deathEvent)
endif
if (not buffType.keepAtDeath) then
call destroy()
endif
set this = next
endloop
return false
endmethod
private static method onDeindex takes nothing returns boolean
local integer unitId = GetIndexedUnitId()
local thistype this = firstBuff91;unitId93;
loop
exitwhen (this == 0)
if (buffType.hasRemoveEvent) then
call fireEvent(removeEvent)
endif
if (next == 0) then
set recycle = thistype(0).recycle
else
set recycle = next
endif
set caster = null
call ReleaseTimer(tim)
set tim = null
call ReleaseTimer(periodicTim91;this93;)
set periodicTim91;this93; = null
set this = next
endloop
set this = firstBuff91;unitId93;
set firstBuff91;unitId93; = 0
set buffCount91;unitId93; = 0
call FlushChildHashtable(table, unitId)
call FlushChildHashtable(table, -unitId)
set thistype(0).recycle = this
return false
endmethod
static if (LIBRARY_DamageEvent) then
static integer damagePriority = 0
endif
endstruct
module BuffStruct
private static delegate DefaultValues default
static if (LIBRARY_DamageEvent and thistype.onDamage.exists) then
private static method damageCall takes nothing returns boolean
static if (thistype.damageFilter.exists) then
local Buff this
if 40;damageFilter40;)) then
set this = Buff91;DamageEvent.target93;91;typeid93;
loop
exitwhen 40;this == 0)
call onDamage40;this)
set this = this.next
endloop
endif
else
local Buff this = Buff91;DamageEvent.target93;91;typeid93;
loop
exitwhen 40;this == 0)
call onDamage40;this)
set this = this.next
endloop
endif
return false
endmethod
endif
static if 40;thistype.onPeriodic.exists) then
private static method periodicCall takes nothing returns nothing
call onPeriodic40;GetTimerData40;GetExpiredTimer40;)))
endmethod
endif
private static method onEvent takes nothing returns boolean
if 40;eventType == applyEvent) then
static if thistype.onPeriodic.exists then
set periodicTim91;triggerBuff93; = NewTimerEx40;triggerBuff)
call TimerStart40;periodicTim91;triggerBuff93;, buffType.period, true, function thistype.periodicCall)
endif
static if thistype.onApply.exists then
call onApply40;triggerBuff)
endif
static if 40;thistype.onDispel.exists) then
//! novjass
elseif 40;eventType == dispelEvent) then
//! endnovjass
call onDispel40;triggerBuff, Buff40;0).caster, eventBool)
endif
static if 40;thistype.onRefresh.exists) then
//! novjass
elseif 40;eventType == refreshEvent) then
//! endnovjass
call onRefresh40;triggerBuff)
endif
static if 40;thistype.onRemove.exists) then
//! novjass
elseif 40;eventType == removeEvent) then
//! endnovjass
call onRemove40;triggerBuff)
endif
static if thistype.onExpire.exists then
//! novjass
elseif 40;eventType == expireEvent) then
//! endnovjass
call onExpire40;triggerBuff)
endif
static if 40;thistype.onDeath.exists) then
//! novjass
elseif 40;eventType == deathEvent) then
//! endnovjass
call onDeath40;triggerBuff)
endif
endif
return false
endmethod
private static method onInit takes nothing returns nothing
set buffEvent91;typeid93; = Filter40;function thistype.onEvent)
set buffTypeStackable91;typeid93; = stackable
static if thistype.onPeriodic.exists then
set buffTypePeriod91;typeid93; = period
endif
set buffTypeAuraId91;typeid93; = auraId
set buffTypeBuffId91;typeid93; = buffId
set buffTypeAlignment91;typeid93; = alignment
set buffTypeDispelPriority91;typeid93; = dispelPriority
set buffTypePermanent91;typeid93; = permanent
set buffTypePositiveBuffImmune91;typeid93; = positiveBuffImmune
set buffTypeNegativeBuffImmune91;typeid93; = negativeBuffImmune
set buffTypeNeutralBuffImmune91;typeid93; = neutralBuffImmune
set buffTypePositiveDispelImmune91;typeid93; = positiveDispelImmune
set buffTypeNegativeDispelImmune91;typeid93; = negativeDispelImmune
set buffTypeNeutralDispelImmune91;typeid93; = neutralDispelImmune
set buffTypeKeepAtDeath91;typeid93; = keepAtDeath
set buffTypeCategory91;typeid93; = category
static if 40;LIBRARY_DamageEvent and thistype.onDamage.exists) then
call DamageEvent.ANY.register40;Filter40;function thistype.damageCall), damagePriority)
endif
static if 40;thistype.onApply.exists) then
set buffTypeHasApplyEvent91;typeid93; = true
elseif 40;thistype.onPeriodic.exists) then
set buffTypeHasApplyEvent91;typeid93; = true
endif
static if 40;thistype.onRefresh.exists) then
set buffTypeHasRefreshEvent91;typeid93; = true
endif
static if 40;thistype.onRemove.exists) then
set buffTypeHasRemoveEvent91;typeid93; = true
endif
static if 40;thistype.onExpire.exists) then
set buffTypeHasExpireEvent91;typeid93; = true
endif
static if 40;thistype.onDeath.exists) then
set buffTypeHasDeathEvent91;typeid93; = true
endif
static if 40;thistype.onDispel.exists) then
set buffTypeHasDispelEvent91;typeid93; = true
endif
endmethod
static method apply takes unit caster, unit target, real level, real duration returns Buff
return Buff.apply40;typeid, caster, target, level, duration)
endmethod
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 09/08/14 22:00 Sujet du message:
Tu utilises le UnitIndexer de Nestharus?
Sinon je ne peux pas garantir que cette lib' n'a aucun bug et qu'elle fonctionne totalement correctement.
(Je sais que l'affichage des icônes dans la barre d'état des unités ne se fait pas...) _________________
Inscrit le: 12 Nov 2009 Messages: 711 Sujets: 50 Spécialité en worldedit: Vétéran
Posté le: 06/11/14 20:57 Sujet du message:
Ton lien d'UnitIndexer ne donne plus la lib.
Juste comme ça, comment ça fonctionne pour faire afficher un buff? Les buffs ajoutés par trigger, on doit faire nous même les effets je suppose nan? _________________
C'est en forgeant que l'on devient forgeron
"Le feu ne peut tuer le dragon"
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 15/11/14 19:45 Sujet du message:
Hmm oui Nestharus a rage quit et détruit toutes ses ressources.
Mais tu peux quand même le trouver là.
Sinon, oui cette lib' est faite pour des buffs 100% par déclencheurs (il y a un certain nombre d'events qui sont inclus dans la lib pour tout simplifier. Du tout tu construits juste ton buff et pas toute l’indexation et les trucs chiants qu'il y a derrière). L'éditeur d'objets est juste utilisé pour les animations/icônes dans la barre d'état.
Et pour faire afficher un buff tu as un problème? Il me semble qu'il y avait un problème avec cette fonctionnalité, je me souviens plus exactement.
Edit: Je viens de me rendre compte que Nes a changé ses libs depuis le temps. Il a ajouté des fonctionnalités et de la documentation, mais il y a beaucoup plus de dépendances (7 requirements pour UnitIndexer --'). Du coup je vais peut-être poster une map exemple avec les anciens systèmes. _________________
Inscrit le: 12 Nov 2009 Messages: 711 Sujets: 50 Spécialité en worldedit: Vétéran
Posté le: 16/11/14 23:15 Sujet du message:
Pas forcèment le fonctionnement de ta lib, je voudrais juste savoir pour comprendre comment c'est réalisé, la manière pour faire afficher un buff par trigger. _________________
C'est en forgeant que l'on devient forgeron
"Le feu ne peut tuer le dragon"
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