Posté le: 22/02/10 01:17 Sujet du message: Me servir d'Autoindex correctement
Je vais prendre un exemple simple, pour que tu puisses me dire si j'utilise correctement Autoindex.
Ici, une unité attaquée va utiliser le sort 'Adef' et après X secondes revenir au mode par défaut (undefend donc).
Si elle est attaquée, je regarde si elle utilise déjà defend avec le booléen isdefending de la struct pour empêcher l'unité d'utiliser defend à chaque fois qu'elle est attaquée.
Jass:
scope phsw initializer init
globals
private constant integer ID = 'o007'
private constant real DURATION = 10.
endglobals
private struct str
unit caster
boolean isdefending = false
static method operator [] takes unit u returns thistype
return thistype(GetUnitId(u))
endmethod
private function Action takes nothing returns nothing
local timer t = GetExpiredTimer()
local str this = GetTimerData(t)
call IssueImmediateOrder(this.caster,"undefend")
call ReleaseTimer(t)
call this.destroy()
endfunction
private function IniWait takes unit whichUnit returns nothing
local timer t = NewTimer()
local str this = str[whichUnit]
set this.isdefending = true
set this.caster = whichUnit
call IssueImmediateOrder(this.caster,"defend")
call SetTimerData(t, this)
call TimerStart (t,DURATION, false, function Action )
endfunction
private function CheckStatus takes unit whichUnit returns nothing
local str this = str[whichUnit]
if this.isdefending == false then
call IniWait(whichUnit)
endif
endfunction
private function Conditions takes nothing returns boolean
local unit victim = GetTriggerUnit()
if GetUnitTypeId(victim)==ID then
call CheckStatus(victim)
endif
set victim = null
return false
endfunction
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t,Player(10), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerAddCondition(t, Condition(function Conditions))
endfunction
endscope
Par ailleurs, en admettant que je me sers correctement de Autoindex ici, peux-tu m'aider à comprendre en quoi la nouvelle version est utile? Les modules AutoCreate et compagnie, ça me dépasse malgré la lecture et la relecture des commentaires de grim001.
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: 08/03/10 18:31 Sujet du message:
Tu en es toujours au même point ou as tu assimilé certaines utilisations ?
Parce que dans ton ex une unité peut se retrouver avec un isdefending à true si une unité ayant ce booléen est remove de la map et son index recyclé car une unité est attaquée. _________________
private struct str
unit caster
boolean isdefending = false
private method onCreate takes nothing returns nothing
set .isdefending = false
set .caster = me
endmethod
implement AutoCreate
private method onDestroy takes nothing returns nothing
set .isdefending = false
set .caster = null
endmethod
implement AutoDestroy
endstruct
private function Action takes nothing returns nothing
local timer t = GetExpiredTimer()
local str this = GetTimerData(t)
call IssueImmediateOrder(this.caster,"undefend")
call ReleaseTimer(t)
set this.isdefending = false
endfunction
private function IniWait takes unit whichUnit returns nothing
local timer t = NewTimer()
local str this = str[whichUnit]
set this.isdefending = true
set this.caster = whichUnit
call IssueImmediateOrder(this.caster,"defend")
call SetTimerData(t, this)
call TimerStart (t,DURATION, false, function Action )
endfunction
private function CheckStatus takes unit whichUnit returns nothing
local str this = str[whichUnit]
if this.isdefending == false then
call IniWait(whichUnit)
endif
endfunction
private function Conditions takes nothing returns boolean
local unit victim = GetTriggerUnit()
if GetUnitAbilityLevel(victim,SPELL)>=1 and victim!= null and GetUnitState(victim,UNIT_STATE_LIFE)>0 then
if GetPlayerController(GetOwningPlayer(victim)) == MAP_CONTROL_USER then
call CheckStatus(victim)
elseif GetUnitAbilityLevel(victim,AI_ENABLED)>=1 then
call CheckStatus(victim)
endif
endif
set victim = null
return false
endfunction
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t,Player(11), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerAddCondition(t, Condition(function Conditions))
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: 08/03/10 21:41 Sujet du message:
AutoCreate est inutile ici, il n'y aucun intérêt à allouer une instance quand une unité est créée.
Et tu peux overlaod create à la place de déclarer une method onCreate.
Tu peux recycler le timer dans la method onDestroy, ainsi quand une unité sera remove du jeu avant la fin du compteur celui ci sera recyclé et on essayera pas un IssueImmediateOrder sur une unité non existante.
(Ca ne doit pas crasher mais c'est toujours plus sain et permet de recycler les timers plus vite). _________________
private struct str
unit caster
boolean isdefending = false
timer ti = null
private static method createFilter takes unit u returns boolean
return (GetUnitAbilityLevel(u,SPELL1)>=1 or GetUnitAbilityLevel(u,SPELL1)>=2) and IsUnitType(u,UNIT_TYPE_HERO)==false
endmethod
private method onCreate takes nothing returns nothing
set .isdefending = false
set .caster = me
set .ti = null
endmethod
implement AutoCreate
private method onDestroy takes nothing returns nothing
call ReleaseTimer(.ti)
set .ti = null
set .isdefending = false
set .caster = null
endmethod
implement AutoDestroy
endstruct
private function Update takes nothing returns nothing
local str this = GetTimerData(GetExpiredTimer() )
call IssueImmediateOrder(this.caster,"undefend")
set this.isdefending = false
endfunction
private function IniWait takes unit whichUnit returns nothing
local str this = str[whichUnit]
set this.isdefending = true
set this.caster = whichUnit
call IssueImmediateOrder(this.caster,"defend")
set this.ti = NewTimer()
call SetTimerData(this.ti, this)
call TimerStart (this.ti,DURATION, false, function Update)
endfunction
private function CheckStatus takes unit whichUnit returns nothing
local str this = str[whichUnit]
if this.isdefending == false then
call IniWait(whichUnit)
endif
endfunction
private function Conditions takes nothing returns boolean
local unit victim = GetTriggerUnit()
if (GetUnitAbilityLevel(victim,SPELL1)>=1 or GetUnitAbilityLevel(victim,SPELL2)>=1) and victim!= null and GetUnitState(victim,UNIT_STATE_LIFE)>0 then
if GetPlayerController(GetOwningPlayer(victim)) == MAP_CONTROL_USER or GetUnitAbilityLevel(victim,AI_ENABLED)>=1 then
call CheckStatus(victim)
endif
endif
set victim = null
return false
endfunction
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition(t, Condition(function Conditions))
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: 09/03/10 20:57 Sujet du message:
Apocalypse a écrit:
Ma patronne :p
Masculin > Féminin, même si IRL ce n'est pas toujours le cas, n'est ce pas ?
Citation:
Je préfère garder l'AutoCreate en ajoutant le filtre, c'est plus sexy non?
Non.
Préférerais tu employer une personne à temps plein surveillant toutes les naissances, en les répertoriant, pour qu'au final une infirme partie soit traitée, ou une personne qui ne traite que les dossiers concernés au moment voulu ? (je n'arrive pas à trouver une meilleure métaphore)
Citation:
En plus pour recycler le timer, il faudrait qu'il soit dans la struct non?
Et, c'est quoi le problème ?
Par contre le truc reloud des modules Auto... c'est l'emploi obligatoire des method on... , appelées automatiquement quand .(de)allocate est appelé.
Et que l'on ne puisse pas overload create et destroy.
Il n'a pas eu le choix à cause des limitations actuelles du vJass, mais dans certain cas c'est vraiment chiant.
On est obligé d'utiliser l'allocation naturelle des structs du vJass (.allocate qui est appelé par .create, et .deallocate par .destroy), bien que cela ne soit pas le plus chiant.
En effet les benchmarks que j'ai fait sur UnitList m'ont appris pas mal de chose.
La différence de vitesse entre .allocate et un set de variable est de l'ordre de quelques % (moins de 10), c'est donc vraiment négligeable. _________________
Avec ce que j'utilise: à chaque entrée d'unité dans la carte, le filtre vérifie si l'unité peut rentrer dans la struct. Si non, pas de création.
Avec ta méthode (devoir créer la struct quand nécessaire): je dois donc détecter à chaque fois qu'une unité entre sur la carte pour lui associer une struct si elle est bien parmi celles qui peuvent utiliser Phalanx. Donc ca revient bien au même.
Ou alors pourquoi aurai-t-il créé ce onFilter? _________________
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/10 22:07 Sujet du message:
Apocalypse a écrit:
D'accord.
Mais pour le filtre, regarde ma fonction:
logiquement c'est aussi rapide non?
Actuellement non, car tu effectues tout de même les vérifications dans "conditions".
D'ailleurs j'espère que tu n'utilise pas les compétences comme un moyen de lier une donnée à une unité ?
Math powa :
Jass:
GetUnitAbilityLevel(u,SPELL1)>=1 or GetUnitAbilityLevel(u,SPELL1)>=2
->
Jass:
GetUnitAbilityLevel(u,SPELL1)>=1
Ou encore vérifier si le niveau est "!=" ou encore ">" à 0
Citation:
Avec ce que j'utilise: à chaque entrée d'unité dans la carte, le filtre vérifie si l'unité peut rentrer dans la struct. Si non, pas de création.
Avec ta méthode (devoir créer la struct quand nécessaire): je dois donc détecter à chaque fois qu'une unité entre sur la carte pour lui associer une struct si elle est bien parmi celles qui peuvent utiliser Phalanx. Donc ca revient bien au même.
Ou alors pourquoi aurai-t-il créé ce onFilter?
Tu pourrais créer la struct simplement quand une unité se fait attaquer, le booléen serait égal à false par défaut.
Mais mettons tu as une map où une unité se fait attaquer toutes les 0.01s, alors oui ta méthode serait la plus judicieuse.
Le problème en faisant cela c'est que tu diminues le nombre d'instances simultanées possible, même si dans 99 % des cas ce n'est pas un problème _________________
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: 10/03/10 17:34 Sujet du message:
Apocalypse a écrit:
En dehors de ma faute débile,
pourquoi pas:
GetUnitAbilityLevel(u,SPELL1)>=1 comme filtre?
Pourquoi vérifies tu de nouveau que l'unité à la compétence quand elle se fait attaquer ?
Si tu as vraiment besoin de le faire alors AutoCreate est vraiment inutile. _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2, 3Suivante
Page 1 sur 3 La question posée dans ce topic a été résolue !
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