Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 06/03/12 11:55 Sujet du message: [vJass] Régénération/Dégénération
Nom de la fonction : Regeneration & Degeneration Créateur : Sapeur-Goblin
Fonctions requises : Aucune
Code :
Secret:
Jass:
library Regeneration /*
***********************
*
* Fonctions
* ---------
*
* - Regeneration.add takes unit caster, unit target, real amount, real duration, integer id, boolean cumul, boolean on returns Regeneration
* - Regeneration.remove takes unit target, integer id returns nothing
* - Regeneration.has takes unit target, integer id returns boolean
*
* - Degeneration.add takes unit caster, unit target, real amount, real duration, integer id, boolean cumul, boolean on returns Regeneration
* - Degeneration.remove takes unit target, integer id returns nothing
* - Degeneration.has takes unit target, integer id returns boolean
*
***********************/
globals
private real Intervalle = 0.1 // Interval de temps pour les dégénération
private constant integer DummyNumber = 12 // Nombre max de joueurs pour lesquels un dummy sera créé
// (il faut en rajouter pour neutre hostile etc)
private constant integer DummyId = 'dumm' // Indentifiant de l'unité dummy qui infligera les dégâts si le lanceur meurt
private unit array Dummy[DummyNumber]
endglobals
private thistype prev
private thistype next = 0
private unit caster
private unit target
private integer targetId
private real r
private real t = 0
private real dur
private integer id
private boolean cumul
private boolean on
private static method Timer takes nothing returns nothing
local thistype this
local real r = 0
local integer i = 0
loop
exitwhen i >= Total
set this = enumInst[i]
loop
exitwhen this == 0
set this.t = this.t + Intervalle
if GetUnitTypeId(this.caster) == 0 or IsUnitType(this.caster, UNIT_TYPE_DEAD) then
if this.on then
set this.caster = Dummy[0]
else
set this.caster = null
endif
endif
if this.t > this.dur or GetUnitTypeId(this.target) == 0 or IsUnitType(this.target, UNIT_TYPE_DEAD) or this.caster == null then
if this.next == 0 then
call SaveInteger(table, this.targetId, this.id, this.prev)
endif
if this.prev == 0 then
set enumInst[i] = this.next
endif
if this.prev == 0 and this.next == 0 then
set enumInst[i] = enumInst[Total-1]
set Total = Total - 1
set i = i - 1
call RemoveSavedInteger(table, this.targetId, this.id)
endif
set this.prev.next = this.next
set this.next.prev = this.prev
set this.caster = null
set this.target = null
call this.deallocate()
else
if this.cumul then
call SetUnitState(this.target, UNIT_STATE_LIFE, GetUnitState(this.target, UNIT_STATE_LIFE) + this.r)
elseif this.r > r then
set r = this.r
endif
endif
set this = this.next
endloop
set this = enumInst[i]
call SetUnitState(this.target, UNIT_STATE_LIFE, GetUnitState(this.target, UNIT_STATE_LIFE) + r)
set r = 0
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
static method has takes unit target, integer id returns boolean
return HaveSavedInteger(table, GetHandleId(target), id)
endmethod
static method remove takes unit target, integer id returns nothing
local thistype this = LoadInteger(table, GetHandleId(target), id)
call RemoveSavedInteger(table, GetHandleId(target), id)
loop
exitwhen this == 0
set this.t = this.dur
set this = this.prev
endloop
endmethod
static method add takes unit caster, unit target, real r, real dur, integer id, boolean cumul, boolean on returns thistype
local thistype this
local thistype prev
local integer i = GetHandleId(target)
local integer j
if GetUnitTypeId(target) != 0 and r > 0 and dur > 0 then
if GetUnitTypeId(caster) != 0 or on then
set this = thistype.allocate()
set this.caster = caster
set this.target = target
set this.targetId = i
set this.r = r * Intervalle
set this.dur = dur
set this.id = id
set this.cumul = cumul
set this.on = on
set prev = LoadInteger(table, i, id)
if prev == 0 then
set enumInst[Total] = this
set Total = Total + 1
else
set prev.next = this
set this.prev = prev
endif
call SaveInteger(table, i, id, this)
if Total == 1 then
call TimerStart(Tim, Intervalle, true, function Regeneration.Timer)
endif
return this
endif
endif
return 0
endmethod
private thistype prev
private thistype next = 0
private unit caster
private unit target
private integer targetId
private real r
private real t = 0
private real dur
private integer id
private boolean cumul
private boolean on
private integer playerId
private static method Timer takes nothing returns nothing
local thistype this
local real r = 0
local integer i = 0
loop
exitwhen i >= Total
set this = enumInst[i]
loop
exitwhen this == 0
set this.t = this.t + Intervalle
if GetUnitTypeId(this.caster) == 0 or IsUnitType(this.caster, UNIT_TYPE_DEAD) then
if this.on then
set this.caster = Dummy[this.playerId]
else
set this.caster = null
endif
endif
if this.t > this.dur or GetUnitTypeId(this.target) == 0 or IsUnitType(this.target, UNIT_TYPE_DEAD) or this.caster == null then
if this.next == 0 then
call SaveInteger(table, this.targetId, this.id, this.prev)
endif
if this.prev == 0 then
set enumInst[i] = this.next
endif
if this.prev == 0 and this.next == 0 then
set enumInst[i] = enumInst[Total-1]
set Total = Total - 1
set i = i - 1
call RemoveSavedInteger(table, this.targetId, this.id)
endif
set this.prev.next = this.next
set this.next.prev = this.prev
set this.caster = null
set this.target = null
call this.deallocate()
else
if this.cumul then
call UnitDamageTarget(this.caster, this.target, this.r, FALSE, TRUE, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
elseif this.r > r then
set r = this.r
endif
endif
set this = this.next
endloop
set this = enumInst[i]
call UnitDamageTarget(this.caster, this.target, r, FALSE, TRUE, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
set r = 0
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
static method has takes unit target, integer id returns boolean
return HaveSavedInteger(table, GetHandleId(target), id)
endmethod
static method remove takes unit target, integer id returns nothing
local thistype this = LoadInteger(table, GetHandleId(target), id)
call RemoveSavedInteger(table, GetHandleId(target), id)
loop
exitwhen this == 0
set this.t = this.dur
set this = this.prev
endloop
endmethod
static method add takes unit caster, unit target, real r, real dur, integer id, boolean cumul, boolean on returns thistype
local thistype this
local thistype prev
local integer i = GetHandleId40;target)
local integer j
if GetUnitTypeId40;target) != 0 and r > 0 and dur > 0 then
if GetUnitTypeId40;caster) != 0 or on then
set this = thistype.allocate40;)
set this.caster = caster
set this.target = target
set this.targetId = i
set this.r = r * Intervalle
set this.dur = dur
set this.id = id
set this.cumul = cumul
set this.on = on
if GetUnitTypeId40;caster) == 0 then
set this.playerId = GetPlayerId40;GetOwningPlayer40;target))
else
set this.playerId = GetPlayerId40;GetOwningPlayer40;caster))
endif
set prev = LoadInteger40;table, i, id)
if prev == 0 then
set enumInst[Total] = this
set Total = Total + 1
else
set prev.next = this
set this.prev = prev
endif
call SaveInteger40;table, i, id, this)
if Total == 1 then
call TimerStart40;Tim, Intervalle, true, function Degeneration.Timer)
endif
return this
endif
endif
return 0
endmethod
private function Init takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= DummyNumber
set Dummy91;i] = CreateUnit40;Player40;i), DummyId, 0, 0, 0)
set i = i + 1
endloop
endfunction
endlibrary
Utilisation : Tout d'abord, il faut savoir (vous le savez déjà, je pense), que la plupart des buffs de warcraft ne sont pas cumulables, et quand on veut faire des sorts, ça devient vite une galère. Ces fonctions permettent de gérer ces histoires de cumulable/non cumulable.
Je vais détailler l'utilisation de la dégénération car c'est plus marrant , mais sachez que pour la régénération, c'est pareil.
u : L'unité qui lance la dégénération
c : La cible
10 : Taux de dégénération par seconde
20 : Durée de la dégénération
'XXXX' : Catégorie de dégénération
false : Si vous mettez false, cette dégénération ne sera pas cumulable avec toutes les autres de la même catégorie, sachant que c'est la plus puissante qui se fait ressentir. Avec true, elle sera cumulable avec les autres de la même catégorie, donc avec toutes les dégénérations existante sur l'unité
false : La dégénération ne continuera pas si le lanceur meurt. Avec true, elle continuera.
Enlever une dégénération :
Jass:
call Degeneration.remove(u, 'XXXX')
Enlève toutes les dégénérations de type 'XXXX'.
HasUnitDegeneration :
Jass:
call Degeneration.has(u, 'XXXX')
Renvoie true si l'unité a la dégénération de type 'XXXX'
Copyright : Libre
Remarques : Si vous avez modifié le type d'attaque Chaos dans les constantes, les dégénérations tiendront compte de l'armure.
J'ai empêché de mettre des dégénérations/régénérations négatives parce que, si vous faîtes une régénération négative par exemple, ce sera la moins puissante qui sera ressentie par l'unité.
N'oubliez pas de bien préciser l'unité dummy, qui inflige les dégâts quand le réel lanceur meurt.
Si vous voulez ajouter un effet pour que la régénération/dégénération ne sorte pas de nulle par, je vous invite à utiliser cette fonction. _________________
Dernière édition par Sapeur-Goblin le 26/04/12 09:21; édité 14 fois
Une régénération négative est pas semblable a une degeneration ( sauf peut être pour savoir qui a kill l'unit cible ? ). Mais en ajoutant une partie cible dans régénération devrait régler la chose.
Essaie d'ajouter une API, serait plus simple a utiliser. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 07/03/12 11:13 Sujet du message:
Citation:
Une régénération négative est pas semblable a une degeneration ( sauf peut être pour savoir qui a kill l'unit cible ? ). Mais en ajoutant une partie cible dans régénération devrait régler la chose.
Pas tout à fait, à moins que je ne fasse la régénération par des dégâts négatifs mais bon...
Sinon, il y a déjà une partie cible dans la régénération , sinon ça servirait à rien. C'est l'argument lanceur qui n'existe pas, bien que je vais bientôt en rajouter un pour pouvoir ajouter une fonctionalité : faut-il continuer la régénération si le lanceur est mort?
Je n'ai pas trop "lu" ton système mais une regen' négative est semblable a une degenration. Enfin si tu ajoute des points de vie a l'unit. En ajoutant des points de vie négatifs cela aura le même effet ?
J'avais vu que ta regen' avais qu'un argument unit donc j'ai pense que tu avais seulement l'unit lanceur ( donne des noms plus compréhensible ).
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 09/03/12 21:36 Sujet du message:
Ce qu'il veut dire c'est que tu n'as pas de documentation pour l'API.
Même remarque qu'ailleurs, tes noms de variables ne sont pas explicites.
- On peut très bien se retrouver avec une unité morte ayant plus de 0.405 de vie, il vaut mieux utiliser IsUnitType(u,UNIT_TYPE_DEAD).
- Tu ne fais aucune vérification de "sécurité", à savoir si les paramètres de tes fonctions sont valides.
- Pour HasUnitRegeneration il doit y avoir moyen de rendre la complexité algorithmique O(1) plutôt que O(N).
- Tu ne gères pas les cas où une unité meurt/est supprimée de la partie.
D'ailleurs je suppose qu'il faudrait prévoir l'utilisation d'une unité dummy pour infliger les dégâts, ainsi si "u" est supprimée de la partie, le joueur possesseur de "u" continue à infliger des dégâts et recevoir les récompenses pour sa mort éventuelle.
- l'utilisation de string est à éviter quand ce n'est pas nécessaire, ici il vaudrait mieux utiliser un paramètre entier (vive les constant integer).
D'une part parce qu'une erreur de frappe ne sera pas détectée à la compilation du script, d'autre part pour les custom spell une constant integer utilisant le rawcode 'XXXX' du spell devrait déjà définie.
Enfin, la gestion des string en jass est "horrible" (non je ne développerais pas ce dernier point) _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 31/03/12 15:33 Sujet du message:
Je suis en train d'essayer de l'améliorer mais j'ai quelques questions à propos de ce que tu disais :
•
Troll-Brain a écrit:
- Tu ne gères pas les cas où une unité meurt/est supprimée de la partie.
D'ailleurs je suppose qu'il faudrait prévoir l'utilisation d'une unité dummy pour infliger les dégâts, ainsi si "u" est supprimée de la partie, le joueur possesseur de "u" continue à infliger des dégâts et recevoir les récompenses pour sa mort éventuelle.
Je suis d'accord mais il faut que "u" prenne le relais que lorsque le réel lanceur meurt, non? Sinon les gains d'xp (qui dépendent de la distance) ne correspondent pas.
•
Troll-Brain a écrit:
- l'utilisation de string est à éviter quand ce n'est pas nécessaire, ici il vaudrait mieux utiliser un paramètre entier (vive les constant integer).
D'une part parce qu'une erreur de frappe ne sera pas détectée à la compilation du script, d'autre part pour les custom spell une constant integer utilisant le rawcode 'XXXX' du spell devrait déjà définie.
Enfin, la gestion des string en jass est "horrible" (non je ne développerais pas ce dernier point)
Ca ralentit tellement les calculs? Pour gérer les dégénérations cumulables, faudrait utiliser un booléan alors?
•
Troll-Brain a écrit:
- Pour HasUnitRegeneration il doit y avoir moyen de rendre la complexité algorithmique O(1) plutôt que O(N).
Faut passer par une "indexiation"? _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 31/03/12 19:31 Sujet du message:
1) Oui bien entendu (même si je n'avais pas pensé à cela huhu)
2) les strings ca suck c'est tout, au delà d'un souci d'efficacité du code, il y a l'aspect pratique.
3) Pas obligé, mais ca serait le must bien entendu, pour tes autres fonctions y'a aussi surement moyen de diminuer la complexité, mais franchement j'ai plus la motivation pour quoi que ce soit. _________________
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 31/03/12 20:04 Sujet du message:
Tu peux utiliser "UnitAddAbility" et "GetUnitAbilityLevel() > 0", par exemple, si tu ne veux pas utiliser de système d'indexage (avec des compétences invisibles qui ne servent à rien ^^).
Faut juste pas utiliser les groupes d'unités parce que la complexité de "IsUnitInGroup" est sans doute O(n). _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 31/03/12 20:11 Sujet du message:
Tirlititi a écrit:
Tu peux utiliser "UnitAddAbility" et "GetUnitAbilityLevel() > 0", par exemple, si tu ne veux pas utiliser de système d'indexage (avec des compétences invisibles qui ne servent à rien ^^).
April fool ?
Citation:
Faut juste pas utiliser les groupes d'unités parce que la complexité de "IsUnitInGroup" est sans doute O(n).
Même si c'est le cas, ce qui n'est clairement pas certain, (c'est peut être un tas binaire ou quelque chose du style).
Ça doit rester suffisamment efficace, car il ne faut pas oublier que le jass est un langage interprété, qui est interprété d'une façon très lente, dans ce genre de fonction le temps d'éxécution du code est probablement insignifiant par rapport au temps de "parsage" du code. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 01/04/12 15:12 Sujet du message:
Je ne crois pas que ce soit possible avec des compétences cachées : il en faudrait une pour chaque catégorie. Pareil avec un système d'indexiation, à moins qu'il soit possible d'attacher plusieurs entiers à une même unité, je m'y connais pas trop.
Pour l'instant, pour alléger un peu la fonction, j'ai mis set i = Total quand elle trouve l'unité avec la régénération, ça permet de directement sortir de la boucle.
Edit: Euh une unité qui est remove de la map n'est pas sensée être considérée comme nulle? Parce que après quelques tests, je me suis rendu compte que non. Donc si on utilise RemoveUnit(u), je ne pourrais pas savoir qu'elle a été retirée, donc la régénération pourra pas être retirée/ajoutée.
Edit #2: Une unité qui est retirée de la map est en fait cachée, donc pour détecter ça, c'est un peu la galère puisque si j'utilise IsUnitHidden(u) et que quelque part dans la map on se sert de ShowUnit(u , false), la régénération sera stoppée (ou continuera, mais ce ne sera plus u qui la lancera). Ca peut poser quelques problèmes. Troll-Brain, j'espère que t'as une solution de roxxor .
Edit #3: Enfait non, IsUnitHidden(u) ne marche qu'une fois sur deux... Je vois pas trop où est le problème.
Je poste le code au cas où, mais il me semble que l'erreur vient juste de la manière utilisée pour détecter si une unité est retirée de la map (quand elle meurt, ça marche très bien).
Secret:
Jass:
library AddUnitRegeneration initializer Init
globals
private constant real Interval = 0.1 //Interval de temps pour les dégénération
private constant integer ID = 'dumm' //Indentifiant de l'unité dummy qui infligera les dégâts si le lanceur meurt
private constant integer I = 12
endglobals
private struct degeneration
unit u
unit c
real d
real t = 0
real tm
integer id
boolean cumul
boolean on
integer p
endstruct
private struct regeneration
unit u
unit c
real d
real t = 0
real tm
integer id
boolean cumul
boolean on
integer p
endstruct
globals
private timer TimDegeneration = CreateTimer()
private integer DTotal = 0
private degeneration array DAr
private unit array Dummy[I]
function RemoveDegeneration takes unit u, integer id returns nothing
local degeneration rg
local integer i = 0
loop
exitwhen i >= DTotal
set rg = DAr[i]
if u == rg.c and id == rg.id then
set rg.u = null
set DAr[i] = DAr[DTotal - 1]
set DTotal = DTotal - 1
call rg.destroy()
set i = i - 1
endif
set i = i + 1
endloop
endfunction
function RemoveRegeneration takes unit u, integer id returns nothing
local regeneration rg
local integer i = 0
loop
exitwhen i >= RTotal
set rg = RAr[i]
if u == rg.c and id == rg.id then
set rg.u = null
set RAr[i] = RAr[RTotal - 1]
set RTotal = RTotal - 1
call rg.destroy()
set i = i - 1
endif
set i = i + 1
endloop
endfunction
function HasUnitDegeneration takes unit u, integer id returns boolean
local degeneration rg
local boolean b = false
local integer i = 0
loop
exitwhen i >= DTotal
set rg = DAr[i]
if u == rg.c and rg.id == id then
set b = true
set i = DTotal
endif
set i = i + 1
endloop
return b
endfunction
function HasUnitRegeneration takes unit u, integer id returns boolean
local regeneration rg
local boolean b = false
local integer i = 0
loop
exitwhen i >= RTotal
set rg = RAr[i]
if u == rg.c and rg.id == id then
set b = true
set i = RTotal
endif
set i = i + 1
endloop
return b
endfunction
private function DegenerationTimer takes nothing returns nothing
local degeneration rg
local degeneration rt
local real d = 0
local integer i = 0
local integer c = 0
local boolean b = true
loop
exitwhen i >= DTotal
set rg = DAr[i]
set rg.t = rg.t + Interval
if rg.u == null or IsUnitHidden(rg.u) or IsUnitType(rg.u, UNIT_TYPE_DEAD) then
if rg.on then
set rg.u = Dummy[rg.p]
else
set rg.u = null
endif
endif
if rg.t <= rg.tm and rg.c != null and not IsUnitHidden(rg.c) and not IsUnitType(rg.c, UNIT_TYPE_DEAD) and rg.u != null then
set d = rg.d
if not rg.cumul then
loop
exitwhen c >= DTotal
set rt = DAr[c]
if rg.c == rt.c and rg.id == rt.id and not rt.cumul then
if rg.d > rt.d then
set d = rg.d
elseif rg.d < rt.d then
set d = rt.d
set b = false
elseif rg.d == rt.d then
if i > c then
set b = false
endif
endif
endif
set c = c + 1
endloop
endif
if b then
call UnitDamageTarget(rg.u, rg.c, d, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
endif
else
set rg.u = null
set rg.c = null
set DAr[i] = DAr[DTotal - 1]
set DTotal = DTotal - 1
call rg.destroy()
set i = i - 1
endif
set b = true
set c = 0
set i = i + 1
endloop
if DTotal == 0 then
call PauseTimer(TimDegeneration)
endif
endfunction
private function RegenerationTimer takes nothing returns nothing
local regeneration rg
local regeneration rt
local real d = 0
local integer i = 0
local integer c = 0
local boolean b = true
loop
exitwhen i >= RTotal
set rg = RAr[i]
set rg.t = rg.t + Interval
if rg.u == null or IsUnitHidden(rg.u) or IsUnitType(rg.u, UNIT_TYPE_DEAD) then
if rg.on then
set rg.u = Dummy[rg.p]
else
set rg.u = null
endif
endif
if rg.t <= rg.tm and rg.c != null and not IsUnitHidden(rg.c) and not IsUnitType(rg.c, UNIT_TYPE_DEAD) and rg.u != null then
set d = rg.d
if not rg.cumul then
loop
exitwhen c >= RTotal
set rt = RAr[c]
if rg.c == rt.c and rg.id == rt.id and not rt.cumul then
if rg.d > rt.d then
set d = rg.d
elseif rg.d < rt.d then
set d = rt.d
set b = false
elseif rg.d == rt.d then
if i > c then
set b = false
endif
endif
endif
set c = c + 1
endloop
endif
if b then
call SetUnitState(rg.c, UNIT_STATE_LIFE, GetUnitState(rg.c, UNIT_STATE_LIFE) + d)
endif
else
set rg.u = null
set rg.c = null
set RAr[i] = RAr[RTotal - 1]
set RTotal = RTotal - 1
call rg.destroy()
set i = i - 1
endif
set b = true
set c = 0
set i = i + 1
endloop
if RTotal == 0 then
call PauseTimer(TimRegeneration)
endif
endfunction
function AddUnitDegeneration takes unit u, unit c, real d, real t, integer id, boolean cumul, boolean on returns nothing
local degeneration rg
local boolean b = true
local integer i = 0
if c != null and d > 0 and t > 0 then
if u != null or on then
set rg = degeneration.create()
set rg.u = u
set rg.c = c
set rg.d = d*Interval
set rg.tm = t
set rg.id = id
set rg.cumul = cumul
set rg.on = on
set rg.p = GetPlayerId(GetOwningPlayer(u))
if DTotal == 0 then
call TimerStart(TimDegeneration, Interval, true, function DegenerationTimer)
endif
set DAr[DTotal] = rg
set DTotal = DTotal + 1
endif
endif
endfunction
function AddUnitRegeneration takes unit u, unit c, real d, real t, integer id, boolean cumul, boolean on returns nothing
local regeneration rg = regeneration.create()
local boolean b = true
local integer i = 0
if c != null and d > 0 and t > 0 then
if u != null or on then
set rg.u = u
set rg.c = c
set rg.d = d*Interval
set rg.tm = t
set rg.id = id
set rg.cumul = cumul
set rg.on = on
set rg.p = GetPlayerId(GetOwningPlayer(u))
if RTotal == 0 then
call TimerStart(TimRegeneration, Interval, true, function RegenerationTimer)
endif
set RAr[RTotal] = rg
set RTotal = RTotal + 1
endif
endif
endfunction
private function Init takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= I
set Dummy[i] = CreateUnit(Player(i), ID, 0, 0, 0)
set i = i + 1
endloop
endfunction
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 01/04/12 18:03 Sujet du message:
Tirlititi faisait référence aux indexeurs d'unités "modernes" tel que UnitIndexer et AutoIndex qui utilisent la compétence "défendre" des footman, pour détecter quand une unité est remove du jeu (bug exploit), est créée, ainsi que divers event non natifs.
On ne peut en effet pas directement lier plusieurs entiers à une unité mais utiliser un unit indexer suffit, en effet chaque unité se voit attribuer un entier unique (via la "custom value"), et avec celle ci on peut utiliser pléthore de structures de données, comme une hashtable, une struct ou même une simple array, ou d'autres abominations mélangeant tout cela.
Mais bon là comme je l'ai dit j'ai la flemme d'aller plus loin, surtout que je devrais probablement réécrire ton code de A à Z. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 02/04/12 17:08 Sujet du message:
Voilà, j'ai mis à jour, ça marche. Peut-être qu'un jour, si l'envie me prend, je ferais en sorte qu'on puisse choisir l'intervalle de régénération. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 02/04/12 17:29 Sujet du message:
Je vois que tu as gardé ces affreux noms de variables, crois moi ce genre de pratique ne te rendra pas service.
Il est primordial d'avoir un code compréhensible pour éviter des erreurs de logique et en règle générale pouvoir lire/comprendre le code facilement.
Comme il est aussi intéressant d'ajouter des commentaires, notamment si l'on reprend le code des mois ou des années plus tard.
Tu n'as pas besoin de vérifier qu'une unité est == null, étant donné que GetUnitTypeId(null) == 0 _________________
Dernière édition par Troll-Brain le 28/07/12 18:39; édité 1 fois
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 03/04/12 15:56 Sujet du message:
Ok, j'ai corrigé et enlevé quelques calculs qui servaient à rien.
J'ai aussi fait en sorte que ça fonctionne si un met un lanceur null dès le début en mettant que le joueur qui inflige la dégénération est le joueur qui la subit, comme ça pas de problème d'xp. _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2Suivante
Page 1 sur 2
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