System Extended Effects

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
This is an easy, simple to use system, which gives you more freedom when it comes to special effects.

The system allows you to create special effects for a single player, add an expiration timer or custom value to it or even retrieve the model name or coordinates of the effect.

This system is still in beta, so, any feedback whatsoever is appreciated, especially ideas concerning adding new functions and extras!

version: BETA

Extended Effects functions list:

Code:
_______________________________________________________________________________________________________________________________________
[B] function[/B] AddSpecialEffectEx [B]takes [COLOR="RoyalBlue"]string[/COLOR][/B] modelName, [B][COLOR="RoyalBlue"]real[/COLOR][/B] x, [COLOR="RoyalBlue"][B]real[/B][/COLOR] y [B]returns [COLOR="RoyalBlue"]effect[/COLOR][/B]
 [B]function [/B]AddSpecialEffectTargetEx [B]takes [COLOR="RoyalBlue"]string[/COLOR][/B] modelName, [COLOR="RoyalBlue"][B]widget[/B][/COLOR] targetWidget, string attachPointName [B]returns [COLOR="RoyalBlue"]effect[/COLOR][/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
 * These two functions do exactly the same as Blizzard's two effect functions, however, they also save the passed variables, 
   to a struct, so you can later use the "Get" functions to retrieve data associated with the specified effect.
   
_______________________________________________________________________________________________________________________________________  
[B] function[/B] AddSpecialEffectForPlayer [B]takes [COLOR="RoyalBlue"]player[/COLOR][/B] id, [COLOR="RoyalBlue"][B]string[/B][/COLOR] modelName, [COLOR="RoyalBlue"][B]real[/B][/COLOR] x, [COLOR="RoyalBlue"][B]real[/B][/COLOR] y [B]returns [COLOR="RoyalBlue"]effect[/COLOR][/B]
[B] function [/B]AddSpecialEffectTargetForPlayer [B]takes [COLOR="RoyalBlue"]player[/COLOR][/B] id, [COLOR="RoyalBlue"][B]string[/B][/COLOR] modelName, [COLOR="RoyalBlue"][B]widget[/B][/COLOR] targetWidget, [B][COLOR="RoyalBlue"]string [/COLOR][/B]attachPointName [B]returns [COLOR="RoyalBlue"]effect[/COLOR][/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * Similar to the above functions, though, with a difference to create a special effect only for a single player.
 
 * Use function "GetEffectOwner" to get the "owner" of the effect - the local player you created the effect.
 
_______________________________________________________________________________________________________________________________________ 
[B] function[/B] RemoveEffect [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns nothing[/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * Destroys the specified effect plus the struct attached to it.
 
_______________________________________________________________________________________________________________________________________ 
[B] function[/B] EffectApplyTimedLife [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect, [B][COLOR="RoyalBlue"]real[/COLOR][/B] duration [B]returns nothing[/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * This functions applies a timed life to a given special effect.
 
_______________________________________________________________________________________________________________________________________ 
 [B]function[/B] SetEffectUserData [B]takes[COLOR="RoyalBlue"] effect[/COLOR][/B] whichEffect, [B][COLOR="RoyalBlue"]integer[/COLOR][/B] data [B]returns nothing[/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * Gives the effect a custom value, which you can later retrieve.
 
_______________________________________________________________________________________________________________________________________ 
 [B]function[/B] GetEffectX [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]real[/COLOR][/B]
 [B]function[/B] GetEffectY [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]real[/COLOR][/B]
 [B]function[/B] GetEffectUserData [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]integer[/COLOR][/B]
 [B]function[/B] GetEffectOwner [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]player[/COLOR][/B]
 [B]function[/B] GetEffectModelName [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]string[/COLOR][/B]
 [B]function[/B] GetEffectAttachPointName [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]string[/COLOR][/B]
 [B]function[/B] GetEffectTargetWidget [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]widget[/COLOR][/B]
 [B]function[/B] GetEffectUserData [B]takes [COLOR="RoyalBlue"]effect[/COLOR][/B] whichEffect [B]returns [COLOR="RoyalBlue"]integer[/COLOR][/B]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * Retrieving functions, which obtain values from a given effect.

Extended Effects code:

JASS:
//version BETA launch
library EXTENDEDEFFECTS requires CACHE, TIMERLIB
    struct effectdata    
        integer effectData = 0
        string modelName = ""
        string attachPointName = ""
        widget targetWidget = null
        player owner = null
        effect storedEffect = null
        real x
        real y
               
        static method CreateEffect takes string modelName, real x, real y returns effectdata
            local effectdata data = effectdata.allocate()
            set data.modelName = modelName
            set data.x = x
            set data.y = y
            set bj_lastCreatedEffect = AddSpecialEffect(modelName, x, y)
            set data.storedEffect = bj_lastCreatedEffect
            call SetHandleStruct(bj_lastCreatedEffect, data)
            return data
        endmethod
        static method CreateEffectTarget takes string modelName, widget targetWidget, string attachPointName returns effectdata
            local effectdata data = effectdata.allocate()
            set data.modelName = modelName
            set data.targetWidget = targetWidget
            set data.attachPointName = attachPointName
            set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
            set data.storedEffect = bj_lastCreatedEffect
            call SetHandleStruct(bj_lastCreatedEffect, data)
            return data
        endmethod
    endstruct

    function AddSpecialEffectEx takes string modelName, real x, real y returns effect
        local effectdata data = effectdata.CreateEffect(modelName, x, y)   
        return bj_lastCreatedEffect
    endfunction        
    function AddSpecialEffectTargetEx takes string modelName, widget targetWidget, string attachPointName returns effect
        local effectdata data = effectdata.CreateEffectTarget(modelName, targetWidget, attachPointName)       
        return bj_lastCreatedEffect
    endfunction
    
    function AddSpecialEffectForPlayer takes player id, string modelName, real x, real y returns effect
        local effectdata data
        local string path = ""
        
        if (GetLocalPlayer() == id) then
            set path = modelName
        endif
        set data = effectdata.CreateEffect(path, x, y)
        set data.owner = id
        return bj_lastCreatedEffect                
    endfunction    
    function AddSpecialEffectTargetForPlayer takes player id, string modelName, widget targetWidget, string attachPointName returns effect
        local effectdata data
        local string path = ""
        
        if (GetLocalPlayer() == id) then
            set path = modelName
        endif
        set data = effectdata.CreateEffectTarget(path, targetWidget, attachPointName)
        set data.owner = id
        return bj_lastCreatedEffect     
    endfunction 
    
    function SetEffectUserData takes effect whichEffect, integer data returns nothing
        local effectdata eyeCandy = GetHandleStruct(whichEffect)
        set eyeCandy.effectData = data
    endfunction

    function RemoveEffect takes effect whichEffect returns nothing
        local effectdata data = GetHandleStruct(whichEffect)
        call DestroyEffect(whichEffect)
        call data.destroy()
    endfunction    
    
    function EffectApplyTimedLifeRun takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local effectdata data = GetHandleStruct(t)
        call RemoveEffect(data.storedEffect)
        call TimerDestroy(t)
    endfunction
    function EffectApplyTimedLife takes effect whichEffect, real duration returns nothing
        local timer t = TimerCreate()
        call SetHandleStruct(t, GetHandleStruct(whichEffect))
        call TimerStart(t, duration, false, function EffectApplyTimedLifeRun)
    endfunction 

    //! textmacro GetEffectTYPE takes NAME, DATA, RETURN
    function GetEffect$NAME$ takes effect whichEffect returns $RETURN$
        local effectdata eyeCandy = GetHandleStruct(whichEffect)
        return eyeCandy.$DATA$
    endfunction
    //! endtextmacro
    
    //! runtextmacro GetEffectTYPE("X", "x", "real")
    //! runtextmacro GetEffectTYPE("Y", "y", "real")
    //! runtextmacro GetEffectTYPE("Owner", "owner", "player")
    //! runtextmacro GetEffectTYPE("ModelName", "modelName", "string")
    //! runtextmacro GetEffectTYPE("AttachPointName", "attachPointName", "string")
    //! runtextmacro GetEffectTYPE("TargetWidget", "targetWidget", "widget")
    //! runtextmacro GetEffectTYPE("UserData", "effectData", "integer")
endlibrary


Andrewgosu
 

Attachments

  • Extended Effects BETA.w3x
    16.7 KB · Views: 236

R@i_no_Wyrm

New Member
Reaction score
43
Really good but I hope I can do it in GUI... Can I?:confused:
(can't find add expiration timer for Special effects in GUI...)
 

Hatebreeder

So many apples
Reaction score
381
I am wondering, why do effects need custom Values?
I mean, thru Structs, they all have uniquw IDs anyway, and by farmost, even when only using locals, it should be MUI...

Please elaborate what you mean with Custom Value on effect...

I like the Idea with the Timed Special Effects ^^ Although you only need these timed stuff for effects that are not too flashy (For example Flame Strike, the floor thingy)
 
Reaction score
456
Make the whole code like.. how to say.. well, an example:
JASS:
    //! textmacro GetEffectTYPE takes NAME, DATA, RETURN
    function GetEffect$NAME$ takes effect whichEffect returns $RETURN$
        local effectdata eyeCandy = GetHandleStruct(whichEffect)
        return eyeCandy.$DATA$
    endfunction
    //! endtextmacro
    
    //! runtextmacro GetEffectTYPE("X", "x", "real")
    //! runtextmacro GetEffectTYPE("Y", "y", "real")
    //! runtextmacro GetEffectTYPE("Owner", "owner", "player")
    //! runtextmacro GetEffectTYPE("ModelName", "modelName", "string")
    //! runtextmacro GetEffectTYPE("AttachPointName", "attachPointName", "string")
    //! runtextmacro GetEffectTYPE("TargetWidget", "targetWidget", "widget")
    //! runtextmacro GetEffectTYPE("UserData", "effectData", "integer")
endlibrary

To:
JASS:
//! textmacro GetEffectTYPE takes NAME, DATA, RETURN
function GetEffect$NAME$ takes effect whichEffect returns $RETURN$
    local effectdata eyeCandy = GetHandleStruct(whichEffect)
    return eyeCandy.$DATA$
endfunction
//! endtextmacro
    
//! runtextmacro GetEffectTYPE("X", "x", "real")
//! runtextmacro GetEffectTYPE("Y", "y", "real")
//! runtextmacro GetEffectTYPE("Owner", "owner", "player")
//! runtextmacro GetEffectTYPE("ModelName", "modelName", "string")
//! runtextmacro GetEffectTYPE("AttachPointName", "attachPointName", "string")
//! runtextmacro GetEffectTYPE("TargetWidget", "targetWidget", "widget")
//! runtextmacro GetEffectTYPE("UserData", "effectData", "integer")
endlibrary


To save space =)!
 

gref

New Member
Reaction score
33
The effect system... I get the feeling that pretty much everyone that uses Jass at an advanced level probably made this for themselves at some point.
I mean...I had the timedlife, the create effect for player and the struct attachment already. While it will be useful for people starting out or maybe as a system that can be used as a standard in sharing maps, I'm sorry that I won't just start and drool...

An idea for another function to extend this... how about an inbuilt delay argument/function. Being able to call functions to: add an attachment to a unit that lasts X seconds, and have an effect occur on that unit after X seconds, in one function without having to use your own timer would make eyecandy easier to make...

Also another function that I ended up having to make with effects was a AddSpecialEffectScaled function, which involved making a dummy unit, scaling the units animation to X and then attaching the effect so that you can have the right size effect. Add that with the RemoveEffect cleaning the dummy unit and custom values would be quite powerful.
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
Make the whole code like.. how to say.. well, an example:
JASS:
    //! textmacro GetEffectTYPE takes NAME, DATA, RETURN
    function GetEffect$NAME$ takes effect whichEffect returns $RETURN$
        local effectdata eyeCandy = GetHandleStruct(whichEffect)
        return eyeCandy.$DATA$
    endfunction
    //! endtextmacro
    
    //! runtextmacro GetEffectTYPE("X", "x", "real")
    //! runtextmacro GetEffectTYPE("Y", "y", "real")
    //! runtextmacro GetEffectTYPE("Owner", "owner", "player")
    //! runtextmacro GetEffectTYPE("ModelName", "modelName", "string")
    //! runtextmacro GetEffectTYPE("AttachPointName", "attachPointName", "string")
    //! runtextmacro GetEffectTYPE("TargetWidget", "targetWidget", "widget")
    //! runtextmacro GetEffectTYPE("UserData", "effectData", "integer")
endlibrary

To:
JASS:
//! textmacro GetEffectTYPE takes NAME, DATA, RETURN
function GetEffect$NAME$ takes effect whichEffect returns $RETURN$
    local effectdata eyeCandy = GetHandleStruct(whichEffect)
    return eyeCandy.$DATA$
endfunction
//! endtextmacro
    
//! runtextmacro GetEffectTYPE("X", "x", "real")
//! runtextmacro GetEffectTYPE("Y", "y", "real")
//! runtextmacro GetEffectTYPE("Owner", "owner", "player")
//! runtextmacro GetEffectTYPE("ModelName", "modelName", "string")
//! runtextmacro GetEffectTYPE("AttachPointName", "attachPointName", "string")
//! runtextmacro GetEffectTYPE("TargetWidget", "targetWidget", "widget")
//! runtextmacro GetEffectTYPE("UserData", "effectData", "integer")
endlibrary


To save space =)!

Uberplayer, that's called indentation and it's used to make code more clear to understand...

Saving space doesn't speed up your code afaik.
 
Reaction score
456
Well.. I just told what Cohadar told me. And I believe him, because he is more experienced than I am.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Really good but I hope I can do it in GUI... Can I?:confused:
(can't find add expiration timer for Special effects in GUI...)

Because there is not such an action.

I had GUI in mind when I triggered this system, we have a nice GUI modifying tutorials in our Repository. Hint, hint.

I

Please elaborate what you mean with Custom Value on effect...

It's pretty much the same as the action, which attaches a custom value to a unit.

In GUI it's called set unit custom value.

Lets say, for a unidentified reason, you need to store a unit's kills to a special effect. Then you would use the "SetEffectUserData" function to do that.

To save space =)!

Whitespace does not matter.

An idea for another function to extend this... how about an inbuilt delay argument/function. Being able to call functions to: add an attachment to a unit that lasts X seconds, and have an effect occur on that unit after X seconds, in one function without having to use your own timer would make eyecandy easier to make...

Also another function that I ended up having to make with effects was a AddSpecialEffectScaled function, which involved making a dummy unit, scaling the units animation to X and then attaching the effect so that you can have the right size effect. Add that with the RemoveEffect cleaning the dummy unit and custom values would be quite powerful.

Nice ideas, though the "AddSpecialEffectScaled" is a little bit utopian.

I mean, one has to make unit with all the special effect models in order to pull this thing off.
 

Tom Jones

N/A
Reaction score
437
JASS:
    function AddSpecialEffectForPlayer takes player id, string modelName, real x, real y returns effect
        local effectdata data
        local string path = ""
        
        if (GetLocalPlayer() == id) then
            set path = modelName
        endif
        set data = effectdata.CreateEffect(path, x, y)
        set data.owner = id
        return bj_lastCreatedEffect                
    endfunction    
    function AddSpecialEffectTargetForPlayer takes player id, string modelName, widget targetWidget, string attachPointName returns effect
        local effectdata data
        local string path = ""
        
        if (GetLocalPlayer() == id) then
            set path = modelName
        endif
        set data = effectdata.CreateEffectTarget(path, targetWidget, attachPointName)
        set data.owner = id
        return bj_lastCreatedEffect     
    endfunction
Does these two worK?
 

gref

New Member
Reaction score
33
They should. (without looking at the structs themselves)

As for the Scaled bit, from memory Andrew, the adding an effect to a target automatically scales the effect to the target, so it's not so utopian really. The main problem I remember having with it, is that I had to specify a Z offset because scaling the size of the dummy obviously meant that potentially the point the effect is attached to is too high.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
uses CACHE, TIMERLIB :eek:

Is that a very bad thing?

As for the Scaled bit, from memory Andrew, the adding an effect to a target automatically scales the effect to the target, so it's not so utopian really. The main problem I remember having with it, is that I had to specify a Z offset because scaling the size of the dummy obviously meant that potentially the point the effect is attached to is too high.

Yes, I suppose.

I will implement your ideas, thanks!


(This is beta)
 

Cohadar

master of fugue
Reaction score
209
Is that a very bad thing?
very bad is a huge understatement.

It is an Unbelievable, Unbearable crime against humanity.

CACHE is nothing else than a renamed CSData
and TIMERLIB is nothing else than renamed CSSafety.

The last thing mapping community needs is every Award-winning and skillful coder, renaming standard libraries and renaming functions inside them.

When I first time saw Vexorians CSSafety I cursed him for bad naming.
I mean NewTimer and ReleaseTimer is totally absurd.
NewTimer and FreeTimer would be more C/C++
even AllocateTimer and ReleaseTimer would be more logical.

But I did not play smart and tried to change his names.
I always used CSSafety and will always use it because it is a standard
It helps people share their spells.
That is why I tell people: You don't like ABC for some reason?
Than please use CSData, do not use some random 0x10000 Impressive System that everyone should Use(!) that is an excuse for attachment system.

For those reasons I am officially boycotting this system.


Extended Effects - Is a Very Nice and Neat System but Unfortunately I don't like It because of the reasons listed above.

--------------------------------------------

Quit the swearing
~ Daxtreme​
 

hell_knight

Playing WoW
Reaction score
126
Flame much?
I think what he is trying to say this system takes 1 milli-second longer than ABC it sucks.
Seriously cohadar calm down.....

On topic I think its useful , cause I've always hated arraying special effects then destroying them later its a pain.
I can use this like in GUI using custom script correct?
 

Cohadar

master of fugue
Reaction score
209
Flame much?
I think what he is trying to say this system takes 1 milli-second longer than ABC it sucks.

Please don't try to think what I try to say ok.

@Andrewgosu
you are working against community by publishing something that uses random named systems.
Please recode that to use CSSafety and CSData.

TIP: If you do not like how CSData is coded inside than change it inside,
replace CSData function implementation for your pleasure only.
But keep the function names same so others can easily use it.
 

Sim

Forum Administrator
Staff member
Reaction score
534
Cohadar, quit the swearing. If you can't explain what you want to say in proper words, then do not post. Else...

Consider this as a warning.
 

Cohadar

master of fugue
Reaction score
209
My reasons are valid and well argumented.
Swearing was there just to ephesize my strong emotions about this subject.
 

Sim

Forum Administrator
Staff member
Reaction score
534
My reasons are valid and well argumented.
Swearing was there just to ephesize my strong emotions about this subject.

Do you seriously think it matters? Because it does not. We are strict about this and no matter your reasons, you do not swear.

Anyways, back on topic.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Sure, no problem to recode it to use CSData.:)

It's still BETA, so the main stress is still on developing the special effect functions.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top