(Keeps Hive Alive)
Go Back   The Hive Workshop - A Warcraft III Modding Site > Warcraft III Resources > Submissions > "Graveyard"

"Graveyard" Resources which were not approved are moved to this section.

 
 
LinkBack Thread Tools Display Modes
Old 05-24-2008, 03:33 PM   #1 (permalink)

Anozer jasser
 
Join Date: Apr 2008
Posts: 237

Troll-Brain has little to show at this moment (13)Troll-Brain has little to show at this moment (13)


[vJass] Any Type Group System

ChangeLog

v0.2
- method clean added
- method getRandom added
- add the set to 0 the Inc integer variable on top of functions in case of reach a limit op
- remove the uneeded local triggercondition in the forGroup method and remplace it by a global
- warning message to avoid desync with mac users with the method forGroup added
- removed an unused variable integer
- improved the methods copy and addGroup to avoid adding a null thing and return an integer instead of a boolean
- made a cleaner example

v0.1
- Initial release

//==============================================================================
// ATGS -> Any Type Group System -- v0.2
//==============================================================================
//
// PURPOUSE:
// * Use structs and methods for simulate an using of group for any type.
//
//
// HOW TO USE:
// * Check the test trigger and the last lines in this trigger.
//
//
// PROS:
// * Can easily use a "group" for any type (but you need to know vJass).
//
// * You can add the same thing many times in the group, but only if you really
// want it of course, with the method altAdd.
//
// * Not as the natives functions, it return a boolean when you use the methods,
// to know if it was done or not.
//
//
// CONS:
// * It's not very fast, if you really care about it, just use arrays ...
//
// * You need to remove yourself a thing in a group, not as in an unit group when
// an unit is removed of the game.
//
//
// DESCRIPTION OF THE METHODS:
// * create : Just create a new group.
//
// * add : Add the thing to the group, if the thing is already in the group,
// then it doesn't add it. Return true if add it and false if not.
// It will be slower as the group is bigger.
//
// * altAdd : Add the thing to the group but it doesn't check if it is already
// in group or not, so it is fast but not safe. It can be use too if
// you want to add the same thing in the group.
//
// * remove : Remove the thing to the group. Return true if remove it and false if not.
// It doesn't check if the thing is many times in group or not.
// It will be slower as the group is bigger.
//
// * altRemove : Remove the thing of the group as many times as you want.
// Use the argument 0 for remove totally the thing.
// It return the how many times the thing was removed
// It will be slower as the group is bigger.
//
// * clear : Just prepare the group for an other usage. it doesn't clear the memory,
// as the clear natives. It just set an integer variable to 0, so it's fast
//
// * altClear : Prepare the group for an other usage and clean the memory.
// It will be slower as the group is bigger.
//
// * isInGroup : Return true if the thing is in group and false if not.
// It will be slower as the group is bigger.
//
// * forGroup : Just like the native ForGroup, but you need to use a textmacro
// at the top of your function callback. Check the trigger test.
// Like the native ForGroup it doesn't support TriggerSleepAction,
// and so of course neither the PolledWait.
// >>>> USE A FUNCTION WHICH RETURN A BOOLEAN TO AVOID DESYNC WITH MAC USERS <<<<
// It will be slower as the source group is bigger.
//
// * copy : Copy a group. Return true if it was done and false if not.
// It will be slower as the source group is bigger.
//
// * addGroup : Add a group to the source group. Return true if it was done and false if not.
// It will be slower as the source group is bigger.
//
// * clean : Remove all null things on the group. It will be slower as the source group is bigger.
//
// * getRandom : Get a random thing in the group, return the null type if the group is empty
//
//
// SPECIAL THANKS TO:
// * Vexorian for the vJass.
//
//
// HOW TO IMPORT:
// * copy/paste this trigger.
//
//==============================================================================

//! textmacro Groups takes TYPE,NULL_TYPE,STRUCT_ARRAY,GROUP_ARRAY

    struct s_$TYPE$Group[$STRUCT_ARRAY$]

     public integer Index // I don't use private because you may want to read the value, but don't set it ...
     public $TYPE$ Enum // I don't use private to avoid a function call for the method forForce, but don't use it.
     public static s_$TYPE$Group TB$TYPE$Group // I don't use private to avoid a function call for the method forForce, but don't use it
     private integer array Copy[$GROUP_ARRAY$]
     private $TYPE$ array Group[$GROUP_ARRAY$]
     private static trigger T= CreateTrigger()
     private static integer Inc= 0
     private static triggercondition Cond

        static method create takes nothing returns s_$TYPE$Group
         local s_$TYPE$Group s= s_$TYPE$Group.allocate()

            set s.Index=0

         return s
        endmethod

        method add takes $TYPE$ t returns boolean
         local integer i= .Index

            if .Index== $GROUP_ARRAY$ then
                debug call BJDebugMsg(s_$TYPE$Group.add.name+" the group is full, remove before add again")
                return false
            elseif t== $NULL_TYPE$ then
                debug call BJDebugMsg(s_$TYPE$Group.add.name+" $TYPE$ is $NULL_TYPE$")
                return false
            endif

            loop
             exitwhen i==0
             set i=i-1

                if .Group[i]== t then
                    return false
                endif

            endloop

            set .Group[.Index]=t
            set .Index= .Index+1

         return true
        endmethod

        private method altAdd takes $TYPE$ t returns boolean
         local integer i= .Index

            if .Index== $GROUP_ARRAY$ then
                debug call BJDebugMsg(s_$TYPE$Group.altAdd.name+" the group is full, remove before add again")
                return false
            elseif t== $NULL_TYPE$ then
                debug call BJDebugMsg(s_$TYPE$Group.altAdd.name+" $TYPE$ is $NULL_TYPE$")
                return false
            endif

            set .Group[.Index]=t
            set .Index= .Index+1

         return true
        endmethod

        method remove takes $TYPE$ t returns boolean
         local integer i= .Index

         if t== $NULL_TYPE$ then
            debug call BJDebugMsg(s_$TYPE$Group.remove.name+" $TYPE$ is $NULL_TYPE$")
            return false
         endif

            loop
             exitwhen i==0
             set i=i-1

                if .Group[i]== t then
                    set .Index= .Index-1
                    set .Group[i]=.Group[.Index]
                    set .Group[.Index]= $NULL_TYPE$
                    return true
                endif

            endloop
         return false
        endmethod

        method altRemove takes $TYPE$ t, integer nbr returns integer
         local integer i= .Index

            if t== $NULL_TYPE$ then
                debug call BJDebugMsg(s_$TYPE$Group.remove.name+" $TYPE$ is $NULL_TYPE$")
             return 0
            elseif nbr< 0 then

            endif

            if nbr== 0 then
                set nbr= i
            endif

            set .Inc= 0

            loop
             exitwhen i==0 or nbr==0
             set i=i-1

                if .Group[i]== t then
                    set .Copy[.Inc]=i
                    set .Inc= .Inc+1
                    set nbr= nbr-1
                endif

            endloop
            set i=.Inc

            loop
             exitwhen .Inc== 0
             set .Inc= .Inc-1

                set .Index= .Index-1
                set .Group[.Copy[.Inc]]=.Group[.Index]
                set .Group[.Index]= $NULL_TYPE$
                set .Copy[.Inc]= 0

            endloop

         return i
        endmethod

        method clear takes nothing returns nothing
            set .Index= 0
        endmethod

        method altClear takes nothing returns nothing

            loop
             exitwhen .Index== 0
             set .Index= .Index-1

                set .Group[.Index]=$NULL_TYPE$

            endloop

        endmethod

        method isInGroup takes $TYPE$ t returns boolean
        local integer i= .Index

        if t== $NULL_TYPE$ then
            debug call BJDebugMsg(s_$TYPE$Group.isInGroup.name+" $TYPE$ is $NULL_TYPE$")
            return false
        endif

            loop
             exitwhen i== 0
             set i= i-1

                if t== .Group[i] then
                    return true
                endif

            endloop

            return false
        endmethod

        method forGroup takes code c returns nothing
         local integer i= .Index

            set .Cond= TriggerAddCondition(.T,Condition(c))
            loop
             exitwhen i== 0
             set i =i-1

             set .Enum= .Group[i]
             set .TB$TYPE$Group= this
             call TriggerEvaluate(.T)

            endloop

            set .Enum= $NULL_TYPE$
            set .TB$TYPE$Group= 0
            call TriggerRemoveCondition(.T,.Cond)

        endmethod

        method copy takes s_$TYPE$Group s returns integer
         local integer i= .Index

            set .Inc=0
            if s== 0 then
                debug call BJDebugMsg(s_$TYPE$Group.copy.name+ " the destGroup is an invalid struct")
                return 0
            endif

            loop
             exitwhen i==0
             set i= i-1

                if .Group[i]!= $NULL_TYPE$ then
                    set s.Group[i]= .Group[i]
                    set .Inc= .Inc+1
                endif

            endloop
            set s.Index= s.Index+.Inc

         return .Inc
        endmethod

        method addGroup takes s_$TYPE$Group s returns integer
         local integer i= s.Index

            if s== 0 then
                debug call BJDebugMsg(s_$TYPE$Group.addGroup.name+ " the sourceGroup is an invalid struct")
                return 0
            elseif s.Index== 0 then
                debug call BJDebugMsg(s_$TYPE$Group.addGroup.name+ " the sourceGroup is empty")
                return 0
            elseif s.Index+.Index > $GROUP_ARRAY$ then
                debug call BJDebugMsg(s_$TYPE$Group.addGroup.name+ " to many things to add for the destgroup size")
                return 0
            endif
            set .Inc=0

            loop
             exitwhen i == 0
             set i= i-1

                if s.Group[i]!= $NULL_TYPE$ then
                    set .Group[.Index+i]= s.Group[i]
                    set .Inc= .Inc+1
                endif

            endloop
            set .Index= .Index+.Inc

         return .Inc
        endmethod

        method clean takes nothing returns integer
         local integer i= .Index

            set .Inc=0
            loop
             exitwhen i== 0
             set i= i-1

                if .Group[i]== $NULL_TYPE$ then
                    set .Index= .Index-1
                    set .Group[i]= .Group[.Index]
                    set .Group[.Index]= $NULL_TYPE$
                    set .Inc= .Inc+1

                endif

            endloop
         return .Inc
        endmethod

        method getRandom takes nothing returns $TYPE$
            if .Index==0 then
                return $NULL_TYPE$
                debug call BJDebugMsg(s_$TYPE$Group.getRandom.name+ " the group is empty")
            endif

            loop
             exitwhen .Index== 0

                set .Inc= GetRandomInt(0,.Index-1)

                if .Group[.Inc]!= $NULL_TYPE$ then
                    return .Group[.Inc]
                endif

                set .Index= .Index-1

                if .Index!= .Inc then
                    set .Group[.Inc]= .Group[.Index]
                    set .Group[.Index]= $NULL_TYPE$
                endif

            endloop
         return $NULL_TYPE$
        endmethod

    endstruct

//! endtextmacro

//! textmacro InitEnum takes STRUCT_VARIABLE_NAME,TYPE,ENUM_VARIABLE_NAME
    local s_$TYPE$Group $STRUCT_VARIABLE_NAME$= s_$TYPE$Group.TB$TYPE$Group
    local $TYPE$ $ENUM_VARIABLE_NAME$= $STRUCT_VARIABLE_NAME$.Enum
//! endtextmacro

// THIS IS AN EXAMPLE :

//! runtextmacro Groups("destructable","null","8190","100")

Example :

scope Test initializer init

// to avoid a desynch with mac users use a fonction which return a boolean
    private function LoopforGroup takes nothing returns boolean // use a function that takes nothing
     //! runtextmacro InitEnum("s","destructable","d")

        call BJDebugMsg(GetDestructableName(d))
        call s.remove(d)

     return true
    endfunction

    private function Actions takes nothing returns nothing
     local s_destructableGroup s = s_destructableGroup.create()

        call s.add(CreateDestructable('LTlt',0.0,0.0,0.0,0.0,0))
        call s.add(CreateDestructable('LTba',0.0,0.0,0.0,0.0,0))
        call s.add(CreateDestructable('LOcg',0.0,0.0,0.0,0.0,0))
        call s.forGroup(function LoopforGroup)
        call s.destroy()

    endfunction

    private function init takes nothing returns nothing
     local trigger t= CreateTrigger()

        call TriggerRegisterPlayerEventEndCinematic( t, Player(0) ) // press the escape key during the game
        call TriggerAddAction( t, function Actions )

    endfunction

endscope

Last edited by Troll-Brain; 05-25-2008 at 04:32 PM..
Troll-Brain is offline  
Old 05-28-2008, 03:41 PM   #2 (permalink)
 
Earth-Fury's Avatar

Inside You <3
 
Join Date: Feb 2004
Posts: 545

Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)

PayPal Donor: This user has donated to The Hive. 

Why aren't you using a function interface for ForGroup? Add a single integer parameter to make passing structs really, really easy. (pass an arbitrary int to forGroup, and its passed to the interface func on each iteration.)
__________________
Giving reputation is a nice way to say thank you to someone that helps you!
Earth-Fury is offline  
Old 05-28-2008, 04:29 PM   #3 (permalink)

Anozer jasser
 
Join Date: Apr 2008
Posts: 237

Troll-Brain has little to show at this moment (13)Troll-Brain has little to show at this moment (13)


Quote:
Originally Posted by Earth-Fury View Post
Why aren't you using a function interface for ForGroup? Add a single integer parameter to make passing structs really, really easy. (pass an arbitrary int to forGroup, and its passed to the interface func on each iteration.)
because i had never use that.
could you make an example plz ?
Troll-Brain is offline  
Old 05-28-2008, 05:05 PM   #4 (permalink)
 
Earth-Fury's Avatar

Inside You <3
 
Join Date: Feb 2004
Posts: 545

Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)

PayPal Donor: This user has donated to The Hive. 

__________________
Giving reputation is a nice way to say thank you to someone that helps you!
Earth-Fury is offline  
Old 05-28-2008, 08:02 PM   #5 (permalink)

Anozer jasser
 
Join Date: Apr 2008
Posts: 237

Troll-Brain has little to show at this moment (13)Troll-Brain has little to show at this moment (13)


ok thx, i will change it.
i will be absent for one/two or three weeks.
Plz don't put it on graveyard, i will improve it when i will back, or let me post in it :p

Continue to comment it plz
Troll-Brain is offline  
Old 06-04-2008, 05:59 PM   #6 (permalink)
 
Earth-Fury's Avatar

Inside You <3
 
Join Date: Feb 2004
Posts: 545

Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)

PayPal Donor: This user has donated to The Hive. 

This would be much better implemented using linked lists...

20 or so minutes of coding:
Old

library AnyTypeGroup

//! textmacro GroupDeclare takes GNAME, GTYPE, GNULL
scope $GNAME$GroupScope

function interface $GNAME$ForGroup takes $GNAME$ sourceGroup, $GTYPE$ value, integer tag returns nothing

private struct $GNAME$Node
    $GNAME$Node next = 0
    $GNAME$Node prev = 0

    $GTYPE$ value
endstruct

struct $GNAME$
    $GNAME$Node first = 0
    $GNAME$Node last = 0
    integer nodeCount = 0

    method add takes $GTYPE$ value returns nothing
        local $GNAME$Node n = $GNAME$Node.create()

        set n.value = value

        set n.next = this.first
        set this.first.prev = n
        set this.first = n

        set this.nodeCount = this.nodeCount + 1
    endmethod

    method addGroup takes $GNAME$ from returns nothing
        local $GNAME$Node enum = from.first

        loop
            exitwhen enum == 0

            call this.add(enum.value)

            set enum = enum.next
        endloop
    endmethod

    method remove takes $GTYPE$ value returns boolean
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.value == value then
                if this.first == enum then
                    set this.first = enum.next
                endif

                if this.last == enum then
                    set this.last = enum.prev
                endif

                if enum.prev != 0 then
                    set enum.prev.next = enum.next
                endif

                if enum.next != 0 then
                    set enum.next.prev = enum.prev
                endif

                call enum.destroy()

                set this.nodeCount = this.nodeCount - 1

                return true
            endif

            set enum = enum.next
        endloop

        return false
    endmethod

    method clear takes nothing returns nothing
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.next == 0 then
                call enum.destroy()
                exitwhen true
            else
                set enum = enum.next
                call enum.prev.destroy()
            endif
        endloop

        set this.first = 0
        set this.last = 0

        set this.nodeCount = 0
    endmethod

    method containsValue takes $GTYPE$ value returns boolean
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.value == value then
                return true
            endif

            set enum = enum.next
        endloop

        return false
    endmethod

    method getRandom takes nothing returns $GTYPE$
        local $GNAME$Node enum = this.first
        local integer goto = GetRandomInt(0, this.nodeCount - 1)
        local integer i = 0

        loop
            if i == goto then
                return enum.value
            endif

            set i = i + 1
            set enum = enum.next
        endloop

        return $GNULL$
    endmethod

    method forGroup takes $GNAME$ForGroup func, integer tag returns nothing
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            call func.evaluate(this, enum.value, tag)

            set enum = enum.next
        endloop
    endmethod
endstruct

endscope
//! endtextmacro

endlibrary



(Stupid need for $GNULL$ >_>) Possible problem I have yet to remedy: calling .remove(value) from a forgroup callback can possibly fuck up iteration. (I'm just too lazy to solve that problem right now...)
__________________
Giving reputation is a nice way to say thank you to someone that helps you!

Last edited by Earth-Fury; 06-04-2008 at 11:31 PM..
Earth-Fury is offline  
Old 06-04-2008, 06:55 PM   #7 (permalink)

iRawr
 
Join Date: Dec 2005
Posts: 8,349

PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)

Paired Mapping Contest #4 Winner: Fallen Angel - Lucifer's Keep Respected User: This user has been given the respected user award. Map Development Mini-Contest #1 Winner: Stand of the Elements 

EF, a small optimization of .remove:

    method remove takes $GTYPE$ value returns boolean
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.value == value then
                if this.first == enum then
                    set this.first = enum.next
                else
                    set enum.prev.next = enum.next
                endif

                if this.last == enum then
                    set this.last = enum.prev
                else
                    set enum.next.prev = enum.prev
                endif

                call enum.destroy()

                set this.nodeCount = this.nodeCount - 1

                return true
            endif

            set enum = enum.next
        endloop

        return false
    endmethod
PurplePoot is offline  
Old 06-04-2008, 11:36 PM   #8 (permalink)
 
Earth-Fury's Avatar

Inside You <3
 
Join Date: Feb 2004
Posts: 545

Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)Earth-Fury is a glorious beacon of light (532)

PayPal Donor: This user has donated to The Hive. 

New code:
library AnyTypeGroup

//! textmacro GroupDeclare takes GNAME, GTYPE
scope $GNAME$GroupScope

function interface $GNAME$ForGroup takes $GNAME$ sourceGroup, $GTYPE$ value, integer tag returns nothing

private struct $GNAME$Node
    $GNAME$Node next = 0
    $GNAME$Node prev = 0

    $GTYPE$ value
endstruct

struct $GNAME$
    $GNAME$Node first = 0
    $GNAME$Node last = 0
    integer nodeCount = 0

    method add takes $GTYPE$ value returns nothing
        local $GNAME$Node n = $GNAME$Node.create()

        set n.value = value

        // Linked List operations:
        set n.prev = this.last
        set this.last.next = n
        set this.last = n

        if this.first == 0 then
            set this.first = n
        endif

        // Node Counting:
        set this.nodeCount = this.nodeCount + 1
    endmethod

    method addGroup takes $GNAME$ from returns nothing
        local $GNAME$Node enum = from.first

        loop
            exitwhen enum == 0

            call this.add(enum.value)

            set enum = enum.next
        endloop
    endmethod

    method remove takes $GTYPE$ value returns boolean
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.value == value then
                // Iteration:
                if enum == this.now then
                    if this.now.next == 0 then
                        set this.now = 0
                    elseif this.now.prev == 0 then
                        set this.now = -1
                    else
                        set this.now = this.now.prev
                    endif
                endif
                // End Iteration

                if this.first == enum then
                    set this.first = enum.next
                else
                    set enum.prev.next = enum.next
                endif

                if this.last == enum then
                    set this.last = enum.prev
                else
                    set enum.next.prev = enum.prev
                endif

                call enum.destroy()

                set this.nodeCount = this.nodeCount - 1

                return true
            endif

            set enum = enum.next
        endloop

        return false
    endmethod

    method clear takes nothing returns nothing
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.next == 0 then
                call enum.destroy()
                exitwhen true
            else
                set enum = enum.next
                call enum.prev.destroy()
            endif
        endloop

        set this.first = 0
        set this.last = 0

        set this.nodeCount = 0

        // Iteration:
        set this.now = 0
    endmethod

    method containsValue takes $GTYPE$ value returns boolean
        local $GNAME$Node enum = this.first

        loop
            exitwhen enum == 0

            if enum.value == value then
                return true
            endif

            set enum = enum.nex