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

A la recherche d'un créateur de creeps peu gourmand...
Aller à la page 1, 2, 3, 4  Suivante
 
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
 jk2pach
Invité








MessagePosté le: 12/09/09 16:24    Sujet du message: A la recherche d'un créateur de creeps peu gourmand... Citer

Bon. Maintenant que Stars 1.16 est presque fini, en dehors des tests, je me remet doucement à RC601. Et je viens de me rendre compte que mon système de création des creeps est...gourmand, puisqu'il utilise de nombreux timers.

Je voudrais savoir si quelqu'un peut m'aider à l'optimiser.

Les fonctions de ce système sont les suivantes:

-Quand un héro "joueur" entre dans l'une des pièces de RC601 (une région donc), des creeps doivent être générés rapidement.
-Les creeps sont envoyés en patrouille dans cette région (uniquement celle-ci)
-Un compteur d'expiration leur est ajouté pour limiter les leaks.
-Ce compteur est suspendu lorsqu'une unité joueur arrive à une certaine portée du creeps.
-Périodiquement, un déclencheur vérifie qu'il y a des joueurs dans chaque région; sinon tout les creeps sont supprimés de ces régions.

Voilà les déclencheurs (exemples)
Créateur d'unités pour certaines régions
Secret:


Jass:
scope sghoul initializer init
//=================================================
globals
    private constant real TIMEOUTSUMMON = 1.00
    private constant real TIMEOUTPATROL = 10.00
    private constant real LIFESPAN = 60.00
    private constant real AOE = 400.00
    private constant integer OWNERCREEPS = 'A00M'
    private constant integer LIGHT = 'o000'
endglobals
//=================================================
private function filtercreeps takes nothing returns boolean
return  GetUnitAbilityLevel(GetFilterUnit(),OWNERCREEPS)>=1
endfunction
//=================================================
private function filterhero takes nothing returns boolean
return  IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO)==true
endfunction
//=================================================
private function filter takes nothing returns boolean
return  IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD)==false and GetOwningPlayer(GetFilterUnit())!=Player(PLAYER_NEUTRAL_PASSIVE) and GetOwningPlayer(GetFilterUnit())!=Player(8)
endfunction
//=================================================
private struct strpatrol
    unit creeps
    real xmin
    real xmax
    real ymin
    real ymax
    group g
    unit filtered
    player pl
endstruct
//=================================================
private function bouclepatrol takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local strpatrol dat = GetTimerData(t)
    local real x1 = GetUnitX(dat.creeps)
    local real y1 = GetUnitY(dat.creeps)
    local real x2 = GetRandomReal(dat.xmin,dat.xmax)
    local real y2 = GetRandomReal(dat.ymin,dat.ymax)
    local integer n = 0
   
        if  GetUnitState(dat.creeps,UNIT_STATE_LIFE)>0 then
            set dat.g = CreateGroup()
            call GroupEnumUnitsInRange(dat.g,x1,y1,AOE,Condition(function filter))
            loop
                set dat.filtered = FirstOfGroup(dat.g)
                exitwhen dat.filtered == null
                call GroupRemoveUnit(dat.g, dat.filtered)
                if IsUnitEnemy(dat.filtered,dat.pl) == true then
                    set n = n + 1
                endif
            endloop
            call DestroyGroup(dat.g)
            if n > 0 then
                call UnitPauseTimedLife(dat.creeps,true)
            else
                call UnitPauseTimedLife(dat.creeps,false)
                call IssuePointOrder(dat.creeps,"attack",x2,y2)
            endif
        else
            call DestroyGroup(dat.g)
            call ReleaseTimer(t)
            call dat.destroy()
        endif
endfunction
//=================================================
private function inipatrol takes unit creeps, real xmin, real ymin, real xmax, real ymax returns nothing
    local timer t = NewTimer()
    local strpatrol  dat = strpatrol.create()
   
        set dat.creeps = creeps
        set dat.xmin = xmin
        set dat.xmax = xmax
        set dat.ymin = ymin
        set dat.ymax = ymax
        set dat.pl = GetOwningPlayer(dat.creeps)
        set creeps = null
        call SetTimerData(t, dat)
        call TimerStart (t, TIMEOUTPATROL, true, function bouclepatrol )
endfunction
//=================================================
private struct strsummon
    rect zone
    player pl
    integer numero
    group g1
    group g2
    integer i
endstruct
//=================================================
private function bouclesummon takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local strsummon dat = GetTimerData(t)
    local real xmin = GetRectMinX(dat.zone)
    local real ymin = GetRectMinY(dat.zone)
    local real xmax = GetRectMaxX(dat.zone)
    local real ymax = GetRectMaxY(dat.zone)
    local real xGetRandomReal(xmin,xmax)
    local real y = GetRandomReal(ymin,ymax)
    local unit creeps = null
    local integer i = 0
    local integer n = 0
    local integer id = udg_creeps_type_ghoul[GetRandomInt(1,2)]
    set dat.g1 = CreateGroup()
    call GroupEnumUnitsInRect(dat.g1,dat.zone,Condition(function filtercreeps))
    set n = CountUnitsInGroup(dat.g1)
    call DestroyGroup(dat.g1)
        if udg_c_summon[dat.numero]==true and dat.i <= udg_c_max[dat.numero] then
            set dat.i = dat.i +1
            if n<=udg_c_max[dat.numero] then
                set dat.g2 = CreateGroup()
                call GroupEnumUnitsInRange(dat.g2,x,y,AOE,Condition(function filterhero))
                if CountUnitsInGroup(dat.g2)<= 0 and GetTerrainCliffLevel(x,y)<=2 then
                    call DestroyGroup(dat.g2)
                    set creeps = CreateUnit(dat.pl,id,x,y,0.00)
                    call UnitApplyTimedLife(creeps,'BTLF', LIFESPAN)
                    call UnitAddAbility(creeps,OWNERCREEPS)
                    call inipatrol(creeps,xmin,ymin,xmax,ymax)
                    if GetRandomInt(1,100)<=10 then
                        set creeps = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),LIGHT,x,y,0.00)
                        call UnitApplyTimedLife(creeps,'BTLF', LIFESPAN)
                        call UnitAddAbility(creeps,OWNERCREEPS)
                    endif
                endif
            endif
            call DestroyGroup(dat.g2)
        else
            call DestroyGroup(dat.g2)
            set creeps = null
            call ReleaseTimer(t)
            call dat.destroy()
        endif
call DestroyGroup(dat.g1)
call DestroyGroup(dat.g2)
set creeps = null   
endfunction
//=================================================
private function inisummon takes rect zone returns nothing
    local timer t = NewTimer()
    local strsummon  dat = strsummon.create()
    local integer i = 0
        set dat.i = 0
        set dat.zone = zone
        set dat.pl = Player(11)
        loop
            set i = i + 1
            exitwhen i >udg_c_nombre
            if dat.zone == udg_c_rect[i] then
                set dat.numero = i
            endif
        endloop       
        call SetTimerData(t, dat)
        call TimerStart (t, TIMEOUTSUMMON, true, function bouclesummon )
endfunction
//=================================================
private function Conditions takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)==true and GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_USER
endfunction
//=================================================
private function Actions takes nothing returns nothing
local unit entering = GetTriggerUnit()
local integer i = 0
local real x = GetUnitX(entering)
local real y = GetUnitY(entering)
local player pl = GetOwningPlayer(entering)
    loop
        set i = i + 1
        exitwhen i > udg_c_nombre
        if RectContainsUnit(udg_c_rect[i],entering) then
            set udg_c_summon[i]=true
            set entering = null
            set pl = null
            call inisummon(udg_c_rect[i])
            return
        endif
    endloop
set entering = null
set pl = null
endfunction
//=================================================
public function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_1)
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_2)
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_3)
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_4)
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_5)
    call TriggerRegisterEnterRectSimple( t, gg_rct_Logistic_Sector_Material_6)
    call TriggerRegisterEnterRectSimple( t, gg_rct_BCL_Test_Room)
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
endfunction   
endscope



Sécurité: suppression des creeps dans les zones sans joueurs.

Secret:


Jass:
scope TimerSetRectFlagsOff initializer init
//=================================================
globals
    private constant real TIMEOUT = 30.00
    private constant integer OWNERCREEPS = 'A00M'
endglobals
//=================================================
private function filtersummoned takes nothing returns boolean
return  IsUnitType(GetFilterUnit(),UNIT_TYPE_SUMMONED)==true
endfunction
//=================================================
private function filterhero takes nothing returns boolean
return  GetPlayerController(GetOwningPlayer(GetFilterUnit())) == MAP_CONTROL_USER
endfunction
//=================================================
private function boucle takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = 0
    local integer n = 0
    local unit filtered
    local group g1 = CreateGroup()
    local group g2 = CreateGroup()
    loop
        set i = i + 1
        exitwhen i > udg_c_nombre
        set g1 = CreateGroup()
        set n = 0
        call GroupEnumUnitsInRect(g1,udg_c_rect[i],Condition(function filterhero))
        loop
            set filtered = FirstOfGroup(g1)
            exitwhen filtered == null
            call GroupRemoveUnit(g1, filtered)
            set n = n + 1
        endloop
        call DestroyGroup(g1)
        if n <= 0 then
            set udg_c_summon[i]=false
            set g2 = CreateGroup()
            call GroupEnumUnitsInRect(g2,udg_c_rect[i],Condition(function filtersummoned))
            loop
                set filtered = FirstOfGroup(g2)
                exitwhen filtered == null
                call GroupRemoveUnit(g2, filtered)
                if GetUnitAbilityLevel(filtered,OWNERCREEPS)>=1 then
                    call RemoveUnit(filtered)
                endif
            endloop
            call DestroyGroup(g2)
        endif
    endloop 
    call DestroyGroup(g1)
    call DestroyGroup(g2)
    set filtered = null
    set g1 = null
    set g2 = null
endfunction
//=================================================
private function Actions takes nothing returns nothing
    local timer t = NewTimer()
        call TimerStart (t, TIMEOUT, true, function boucle )
endfunction
//=================================================
public function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterTimerEventSingle( t, 1.00 )
    call TriggerAddAction(t, function Actions)
endfunction   
endscope



Parce que je me suis rendu compte que si je créé par exemple une zone où une cinquantaine de creeps sont générés, ça consomme des ressources PC assez monstrueuses :/

Or la carte est prévue pour huit joueurs, donc si chaque héros est dans une pièce différente, ça va faire une grosse saturation.


Je suis preneur de n'importe quel autre système si vous en avez, tant qu'il respecte les conditions données au début du message.

Merci d'avance!


Notes: la variable globale LIGHT sert simplement à éclairer la zone de temps en temps.
La variable OWNERCREEPS fait en fait simplement office de booléen local. En effet, j'utilise pour d'autres systèmes toutes les classifications (Ancien, tauren etc...) et je trouve plus souple d'ajouter une compétence dummy aux unités pour les trier rapidement.
udg_c_rect[] désigne les régions de la carte, donc les pièces.
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 12/09/09 16:29    Sujet du message: Citer

C'est juste une intuition ou alors un fait établi, t'entends quoi par "ressources PC", utilisation de la mémoire vive et/ou du processeur ?
Lag, fps en chute libre ?
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 jk2pach
Invité








MessagePosté le: 12/09/09 16:32    Sujet du message: Citer

Ecran saccadé. Donc pas du leak, mais, sous Vista et le gestionnaire de tâches, UC Utilisé assez élevé, et surtout, Frozen Throne ralenti (images non affichées etc...)
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 12/09/09 16:52    Sujet du message: Citer

Y'a pas mal de choses à faire pour normaliser le code aux standards actuel, mais je crois plutôt que cela vient de la création d'unités.

Y'a un nombre max possible de création de creeps ?
Quand un creep meurt, il laisse un cadavre ?
Si oui de combien est le temps de décomposition ?
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 jk2pach
Invité








MessagePosté le: 12/09/09 17:00    Sujet du message: Citer

Il y a un nombre maximum de creeps, vérifié par la condition:

Jass:
dat.i <= udg_c_max[dat.numero]



(Pour chaque région j'ai affecté plusieurs données: nom, nombre de creeps, etc..)

Les cadavressont présents pendant 30 secondes maximum, après quoi ils sont supprimés, et une unité nouvelle apparaît (résurrection des humains en zombies et des zombies en goules).
Os et Annulation: 30 sec
Chair: 10

Mais le problème ne vient pas de là, pendant mes tests, le problème a eu lieu sans que je ne tue aucun ennemi, mais une fois l'ensemble des creeps générés. Je me suis demandé si ça venait du timer qui fait patrouiller les creeps, (un par creeps), mais je n'ai trouvé nul part de messages indiquant avec 100% de certitudes qu'il fallait mieux un timer pour tout les creeps plutôt qu'un timer par creeps.

J'envisageais de refondre le système en utilisant des Tables, mais en dehors d'une lisibilité et d'une implémentation meilleures, je ne pense pas que ça changerait le problème.
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 12/09/09 17:19    Sujet du message: Citer

Oh Table est le cadet de tes soucis ici, et désormais ce n'est plus aussi nécessaire qu'avant avec l'apparition des hashtables.
Je parlais plutôt de recycler les groups, coder dans l'enum, etc.

Je jetterais un œil plus attentif à ton code plus tard.
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 jk2pach
Invité








MessagePosté le: 12/09/09 17:26    Sujet du message: Citer

Merci mon Maître. (Faudra que je pense à gagner le droit d'avoir comme rang "Padawan de TB " un jour :p)
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 12/09/09 21:18    Sujet du message: Citer

Apocalypse a écrit:
Merci mon Maître. (Faudra que je pense à gagner le droit d'avoir comme rang "Padawan de TB " un jour :p)

N'en fait pas trop quand même ...

Faudrait que tu m'envoies la map, j'aimerais bien comparer avec l'utilisation de mon "système" de timer, même si encore une fois j'ai un gros doute que ca soit cela, au moins j'aurais confirmation avant de poursuivre les investigations.
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Bantas
Anomalie floodiforme


Inscrit le: 21 Aoû 2007
Messages: 1524
Sujets: 37

Médailles: 1 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 12/09/09 21:38    Sujet du message: Citer

Je doute fort que ce soit la raison mais tes timers locaux ne sont pas nullifiés =o

Aussi, la création de groupes pour des actions faites instantanément est superflue; utilises plutôt GroupClear à chaque fois Wink

Sinon, dans le cas de huit joueurs dans huit pièces différentes contenant chacune une cinquantaine de creeps, on arrive à 400 unités. Dans une partie mêlée de Warcraft 3 avec 12 joueurs, à raison de deux de nourriture par unité on arrive à environ 300 unités maximum si je me souviens. Même si je doute que le problème se limite à ça, on touche un peu aux nombres maximums prévus par Blizzou ici, surtout avec une struct par unité. Pourquoi ne pas en faire plutôt une par groupe de creeps ?
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 13/09/09 20:55    Sujet du message: Citer

@Bantas :
Pas besoin de nullifier les variables locales de timer car il utilise TimerUtils, ou autrement dit les timers ne sont pas détruits mais recyclés.
Tu as besoin de nullifier une variable type handle ou tous les sous types tel qu'un timer, uniquement si l'objet ainsi référencé a été détruit.

GroupClear est superflu, on peut utiliser un groupe déjà créé et directement utiliser GroupEnum...
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 jk2pach
Invité








MessagePosté le: 13/09/09 21:01    Sujet du message: Citer

Ok pour envoyer la carte, mais elle est trop grosse pour le filtre de ce site Sad

Le nombre d'unités joue effectivement, mais là ça me pose un gros problème: pour avoir un décor interactif, j'utilise des unités en guise de destructibles . Donc là oui clairement il y en a beaucoup :/
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1) Grand mage créateur de sort (Quantité : 1)

MessagePosté le: 13/09/09 21:03    Sujet du message: Citer

Envoie moi la map par e-mail.

Qu'entends tu par exactement par "interactif" ?
_________________
Le violet, c'est moche.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 Bantas
Anomalie floodiforme


Inscrit le: 21 Aoû 2007
Messages: 1524
Sujets: 37

Médailles: 1 (En savoir plus...)
Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 13/09/09 21:42    Sujet du message: Citer

Troll-Brain a écrit:
GroupClear est superflu, on peut utiliser un groupe déjà créé et directement utiliser GroupEnum...
Ah ? j'ai toujours utilisé GroupClear par précaution =X
_________________
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
 jk2pach
Invité








MessagePosté le: 13/09/09 21:43    Sujet du message: Citer

Interactif: plus facile de faire bouger le décor grâce au gravity gun , grenades et autres avec des unités plutôt que des destructibles. (Genre ne serait-ce que pour SetUnitX et Y).
_________________
Revenir en haut
 Troll-Brain
Ri1kamoua


Inscrit le: 23 Aoû 2007
Messages: 7146
Sujets: 147
Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance
Médailles: 2 (En savoir plus...)
Grand mage créateur de sort (Quantité : 1) Rédacteur de tuto #3 (Quantité : 1)

MessagePosté le: 14/09/09 19:41    Sujet du message: Citer

Avec ta map de test et une armée de paladin imba cheatés j'ai pas le moindre problème de performance.
Dans le trigger globals j'ai édité à chaque fois la variable déployée de set façon.
Gui:
Trigger:
Set c_max[c_nombre] = 2000

Cela dit j'ai un pc de rohxor.
_________________
Le violet, c'est moche.
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
Aller à la page 1, 2, 3, 4  Suivante
Page 1 sur 4
La question posée dans ce topic a été résolue !

 
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