• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Dummy Stack

Status
Not open for further replies.
Level 7
Joined
Apr 27, 2011
Messages
272
I'll just leave this here to get some constructive criticisms.
JASS:
library DummyStack
//===========================================================================
// Dummy Stack by Alain.Mark
//
// -How to Use-
//   *GetDummyId(u) - retrieves the assigned id of the dummy.
//   *GetNewDummy(pl,x,y,f) - returns a new dummy to be used.
//   *RecycleDummy(u)
//
//===========================================================================
    globals
        private integer       I =-1
        private integer       Id=-1
        private unit    array StackedDummies
    endglobals
    
//===========================================================================
    private function Pop takes nothing returns unit
        local integer i=I
        local unit    u
        set u=StackedDummies[0]
        set StackedDummies[0]=StackedDummies[i]
        set I=i-1
        return u
    endfunction

//===========================================================================
    private function Push takes unit u returns nothing
        local integer i=I+1
        set StackedDummies[i]=u
        set I=i
    endfunction
    
//===========================================================================
    private function StackEmpty takes nothing returns boolean
        return StackedDummies[0]==null
    endfunction
    
//===========================================================================
    private function IndexDummy takes unit u returns nothing
        local integer i=Id+1
        call SetUnitUserData(u,i)
        set Id=i
    endfunction
    
//===========================================================================
    function GetDummyId takes unit u returns integer
        return GetUnitUserData(u)
    endfunction
    
//===========================================================================
    function GetNewDummy takes player pl, real x, real y, real f returns unit
        local unit u
        if(StackEmpty())then
            set u=CreateUnit(pl,SPELLCRAFT_DUMMY,x,y,f)
            call IndexDummy(u)
        else
            set u=Pop()
            call SetUnitOwner(u,pl,false)
            call SetUnitX(u,x)
            call SetUnitY(u,y)
            call SetUnitFacing(u,f)
            call PauseUnit(u,false)
        endif
        return u
    endfunction
    
//===========================================================================
    function RecycleDummy takes unit u returns nothing
        call Push(u)
        call SetUnitOwner(u,Player(15),false)
        call PauseUnit(u,true)
    endfunction
    
//===========================================================================
endlibrary
 
Last edited:
- SPELLCRAFT_DUMMY should be a global
- local integer i=I+1 >>> set I = I+1
- GetUnitUserData will interrupt other systems like UnitIndexer
- There's no need to get the Id coz you will set it in the process
- StackEmpty() >>> StackedDummies[0]==null
- idk whats the use of Dummy array for
- return u >>> return StackedDummies
- Better to put recycled units in a group then get one of it when used
- Better to categorize the dummies and order it to cast spells (target/not target/point/target)

Others I didnt read & did not tests this...but I see no great efficiency of recycling dummies...
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Why are you pausing, set facing, changing owner of a spellcraft dummy to neutral?Also you can't be sure that user will need to set x and y coordinates of dummy.

Personally I prefer this.(Actually I prefer not to use a dummy system :grin:)

JASS:
library Dummy

globals
    private constant integer DUMMY_ID = 'hfoo'

    private group AvailableDummies = CreateGroup()
endglobals

function GetNewDummy takes player p returns unit
    local unit u = FirstOfGroup(AvailableDummies)
    if u == null then
        return CreateUnit(p, DUMMY_ID, 0, 0, 0)
    else
        call SetUnitOwner(u, p, false)
        call GroupRemoveUnit(AvailableDummies, u)
        return u
    endif
endfunction

function GetNewDummyEx takes player p, real x, real y returns unit
    local unit u = GetNewDummy(p)
    call SetUnitX(u, x)
    call SetUnitY(u, y)
    return u
endfunction

function RecycleDummy takes unit u returns nothing
    call GroupAddUnit(AvailableDummies, u)
endfunction

endlibrary
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
It's better to have only one dummy, and you change the owner before the cast.
Because if you use the neutral player it's not the same, basically if you make a custom spell with trigger but want to consider it as a native one (gold, xp earned, ...) you will have to make it with trigger.

And yes it's possible to make a spell truly instant, so only one unit is enough, but you have to make a valid dummy unit.

http://www.thehelper.net/forums/showthread.php/133873-DummyCaster
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Of course it is possible to make dummy unit cast spells instantly, but dummies have different uses too.Effects, channeling spells, vision dummy etc.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Of course it is possible to make dummy unit cast spells instantly, but dummies have different uses too.Effects, channeling spells, vision dummy etc.

You realize that in his code he doesn't handle unit types (i mean different rawcodes, models), right ?
Well i suppose he could still use passive morph abilities though.
The vision dummy seems kinda useless since we have natives functions for vision handling, unless i'm missing something ?
 
You realize that in his code he doesn't handle unit types (i mean different rawcodes, models), right ?
Well i suppose he could still use passive morph abilities though.
The vision dummy seems kinda useless since we have natives functions for vision handling, unless i'm missing something ?

call AddSpecialEffectTarget(...)

You can attach effects to the dummy model. (which I assume he is using)

@Alain.Mark: Some of the locals in your code can be inlined if you think about it. For example:
JASS:
    private function Push takes unit u returns nothing
        local integer i=I+1
        set StackedDummies[i]=u
        set I=i
    endfunction
Can be:
JASS:
    private function Push takes unit u returns nothing
        set I=I+1
        set StackedDummies[I]=u
    endfunction
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
-Effect
You know Vexorian's dummy model right?
Edit: PurgeandFire faster

-Vision Dummy
I was thinking a dota spell when I said that :grin:
Zeus - Lightning Bolt
Summons a bolt of lightning from the heavens to strike a target enemy.
Gives true sight within 900 range at target area for 3 seconds.

Still I have channeling spells :grin:
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
AddSpecialEffectTarget -> but you can't play all animations provided with the model, or can you ?
But it's enough in many cases for sure.

Dota spell -> you can do that with natives function, or even with an ability

Channeling spells -> you mean spells which have a channeling cast time ?
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Spells like blizzard, aerial shackles, rain of fire, big bad voodoo.

Also you can use that dummy model for projectiles.

How can you do that with natives, can you show an example?
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Ok for channeling spells, considering you don't use triggers to apply the effects (visual or not)
And yes projectiles need several dummy units.

vision with natives :

JASS:
/============================================================================
// Fog of War API
native  SetFogStateRect      takes player forWhichPlayer, fogstate whichState, rect where, boolean useSharedVision returns nothing
native  SetFogStateRadius    takes player forWhichPlayer, fogstate whichState, real centerx, real centerY, real radius, boolean useSharedVision returns nothing
native  SetFogStateRadiusLoc takes player forWhichPlayer, fogstate whichState, location center, real radius, boolean useSharedVision returns nothing
native  FogMaskEnable        takes boolean enable returns nothing
native  IsFogMaskEnabled     takes nothing returns boolean
native  FogEnable            takes boolean enable returns nothing
native  IsFogEnabled         takes nothing returns boolean

native CreateFogModifierRect        takes player forWhichPlayer, fogstate whichState, rect where, boolean useSharedVision, boolean afterUnits returns fogmodifier
native CreateFogModifierRadius      takes player forWhichPlayer, fogstate whichState, real centerx, real centerY, real radius, boolean useSharedVision, boolean afterUnits returns fogmodifier
native CreateFogModifierRadiusLoc   takes player forWhichPlayer, fogstate whichState, location center, real radius, boolean useSharedVision, boolean afterUnits returns fogmodifier
native DestroyFogModifier           takes fogmodifier whichFogModifier returns nothing
native FogModifierStart             takes fogmodifier whichFogModifier returns nothing
native FogModifierStop              takes fogmodifier whichFogModifier returns nothing

So CreateFogModifierRadius together with DestroyFogModifier and maybe FogModifierStart seems fine here.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
I still don't get how can native functions make a player see invisible units.
 
@PurgeandFire111
-I used a local integer because i thought locals are faster than globals.

That is correct however you are only increasing the operations.

You create a local variable (takes processor), increase it by the global plus
one, then set the global to that local variable.

The way Purge suggests is to just increase the global by 1.

Your way is like taking the bus to get across the street.
 
Status
Not open for further replies.
Top