Template [cJass] Chain Spell

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
I wanted to experiment with cJass by making a useful spell. This chain spell template is currently setup to work much like chain lightning, where it bounces amongst the closest enemies. The bouncing mechanism isn't very modular except for the filter, but I can change this if requested. The cool part about this spell, is that you can easily specify what you want it to do in the jumpTo method. The jumpTo method can do any action to the next target and the previous one, such as creating a lightning effect between them (this part is commented out in the code, but it is there in a sample). This also stores the caster in this.caster, so you can have the caster deal damage, steal mana, or heal them. Do whatever, it is a template :D, making it a Good Idea™

JASS:
/*

This is a chain spell template by Frozenhelfire
Requires cJass: <a href="http://www.thehelper.net/forums/showthread.php?t=137979" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=137979</a>
Requires KT by Jesus4Lyf, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=78392" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=78392</a>
Requires Recycle by Nestharus, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=136087" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=136087</a>
Sample code has a commented line that uses TL by Flare, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=92877" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=92877</a>


This spell is made to be casted on a unit, then it will bounce to the next closest unit.
Each bounce performs the actions in the .jumpTo method

private bool Filt() decides what units it can bounce to. At default settings, it will only bounce to
    enemies of the casting unit that are alive and not a structure.

*/


include &quot;cj_types.j&quot;
include &quot;cj_typesEx.j&quot;
include &quot;cj_types_priv.j&quot;
include &quot;cj_typesEx_priv.j&quot;
library ChainTemplate initializer init uses KT /*, TL , TT*/{

    define{
        private NUMBER_OF_BOUNCES = 10 //this bounces 10 times, not 11, changeable in the create method
        private SPELL_ID = &#039;AHbn&#039; //Change this to the rawcode of your dummy spell
        private BOUNCE_RANGE = 500
        private PERIOD = 0.10 //Time between bounces
    }
    private player FILTER_PLAYER //This is used in the filter, if you only want the spell to hit enemies or allies of the casting player
    private real x1, y1, x2, y2, DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE
    private boolexpr filterFunction
    private bool Filt(){ //Sample Filter, checks if unit is enemy of caster and not a structure and not dead
                         //This impersonates a standard chain lightning, but the filter can be changed to do other things
        return IsUnitEnemy(GetFilterUnit(),FILTER_PLAYER) &amp;&amp; !IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) &amp;&amp; GetWidgetLife(GetFilterUnit()) &gt; .405
    }   

    struct ChainTemplate{
        void jumpTo(unit target /*unit the spell is jumping to*/){
            /*this.u is the unit the spell is jumping from
            this.caster is the caster of the spell
            Any actions in here happen every jump*/
            //TL_Unit(&quot;CLPB&quot;, this.u, target, 1, false, 1, 1) // If you have FLARE&#039;s Timed Lightning system...
            //you can uncomment the line above to see the actual jumps.
            //TL can be gotten from: 
            this.bounces += 1 //jumping to a new unit, so add 1 to bounces.
            this.u = target //stores the target for the next bounce (comparing unit distances)
            GroupAddUnit(this.immune,target)
        }
        
        int bounces, maxBounces
        group immune
        unit caster, u
        player castingPlayer
        
        static thistype create(unit caster, unit target){
            thistype D = thistype.allocate()
            D.bounces = 0
            D.maxBounces = NUMBER_OF_BOUNCES
            D.caster = caster
            D.u = caster
            D.immune = CreateGroup()
            D.jumpTo(target)
            D.castingPlayer = GetOwningPlayer(caster)
            return D
        }
        
        /*private static thistype create(unit caster, unit target, int abilLevel){
            thistype D = thistype.allocate()
            D.bounces = 0
            D.maxBounces = abilLevel * 2//By default, bounces 2x the ability level
            D.caster = caster
            D.u = caster
            D.immune = Group.get()
            D.jumpTo(target)
            D.castingPlayer = GetOwningPlayer(caster)
            return D
        }*/

        void onDestroy(){
            DestroyGroup(this.immune)
            this.immune = null
            this.caster = null
            this.u = null
        }
    }

    private bool Cond(){
        return GetSpellAbilityId() == SPELL_ID
    }
    
    group g = CreateGroup()

    private bool TimerCallback(){
    ChainTemplate D = KT_GetData()
    unit u = null
    unit t = null
        DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE 
        FILTER_PLAYER = D.castingPlayer
        x1 = GetUnitX(D.u)
        y1 = GetUnitY(D.u)
        GroupEnumUnitsInRange(g,x1,y1,BOUNCE_RANGE,filterFunction)
        loop{
            u = FirstOfGroup(g)
            exitwhen u == null
            if (IsUnitInGroup(u,D.immune) == false) {
                x2 = GetUnitX(u) - x1
                y2 = GetUnitY(u) - y1
                if (x2*x2 + y2*y2 &lt; DISTANCE) { 
                    DISTANCE = x2*x2 + y2*y2
                    t = u
                }
            }
            GroupRemoveUnit(g,u)
        }
        if (t == null) { //if there is no unit to jump to, end the spell
            u = null
            t = null
            D.destroy()
            return true
        }
        D.jumpTo(t)
        u = null
        t = null
        if (D.bounces &gt;= D.maxBounces) { //max bounces reached, end the spell.
            D.destroy()
            return true
        }
        return false
    }

    private void Act(){
        ChainTemplate D = ChainTemplate.create(GetTriggerUnit(),GetSpellTargetUnit())
        //ChainTemplate D = ChainTemplate.create(GetTriggerUnit(),GetSpellTargetUnit(), GetUnitAbilityLevel(GetTriggerUnit(),SPELL_ID))
        //uncomment the line above if using the ability level
        KT_Add(function TimerCallback,D, PERIOD)
    }

    private void init(){
    trigger t = CreateTrigger()
    int i = 0
        
        filterFunction = Condition(function Filt)

        loop {
            TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            exitwhen i &gt;= 11
            i += 1
        }
        TriggerAddCondition(t,Condition(function Cond))
        TriggerAddAction(t,function Act)
    }
}


Updated the code a bit, here's a test map for anyone who wants to see it in action. Learn banish, 0 mana, 0 cd, 0 casting time, 0 casting animation on the bloodmage. Spam it as much as you'd like. The other skills do nothing.
 

Attachments

  • test.w3x
    37 KB · Views: 251

Nestharus

o-o
Reaction score
84
cJASS isn't an approved resource on TH yet. Romek vowed to instantly graveyard any resource written in cJASS.

Many of the moderators on this forum are totally opposed to cJASS.

Chances are this is going to be graveyarded as soon as it is seen ^_^.

I'm still waiting for them to give the word that it is ok to submit cJASS resources myself =P


This isn't the only forum opposed to cJASS.

The Hive Workshop-
You can only submit vJASS resources, but you may submit the resource in both vJASS and cJASS on the same submission (2 versions)

wc3c.net-
No cJASS resources whatsoever.

TH-
No cJASS resources whatsoever

Pretty Much Every Clan-
No cJASS resources whatsoever

So yea, it'll be a bit before cJASS is accepted ^_^.

Actually, I once asked what would happen if I converted Recycle into cJASS. Jesus4Lyf responded that he'd instantly graveyard it =P.



Oh well, I suppose when the thread containing cJASS is put into resources on TH, everyone will be allowed to use it. While it remains in submission, that's the moderators telling us it's still not ok to use ^_^. If it's graveyarded, that's the moderators telling us that it's never going to be ok to use =o.
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Oh, that's kind of lame :( cJass is completely usable with vJass so it doesn't mean each system will need two versions :( I don't see the big deal with "NO CJASS!1!", but I'll submit my vJass version then.
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
We should hide behind that bush over there, and then staple Romek and J4L to a train (one that goes very far away) when they come to graveyard this thread.
 

Nestharus

o-o
Reaction score
84
You're the one who submitted the cJASS resource =P. I was just letting you know the current stance of TH =).

JASS:

    define private NUMBER_OF_BOUNCES = 10 //this bounces 10 times, not 11, changeable in the create method
    define private SPELL_ID = &#039;AHbn&#039; //Change this to the rawcode of your dummy spell
    define private BOUNCE_RANGE = 500 //How far should the spell be able to bounce?
    define private PERIOD = 0.10 //Time between bounces


should be

JASS:

define {
    private NUMBER_OF_BOUNCES = 10 //this bounces 10 times, not 11, changeable in the create method
    private SPELL_ID = &#039;AHbn&#039; //Change this to the rawcode of your dummy spell
    private BOUNCE_RANGE = 500 //How far should the spell be able to bounce?
    private PERIOD = 0.10 //Time between bounces}
}


JASS:

    private player FILTER_PLAYER //This is used in the filter, if you only want the spell to hit enemies or allies of the casting player
    private real x1 //These reals are for distance calculations
    private real y1
    private real x2
    private real y2
    private real DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE


Should be
JASS:

    private player FILTER_PLAYER //This is used in the filter, if you only want the spell to hit enemies or allies of the casting player
    private real x1, y1, x2, y2, DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE //These reals are for distance calculations


JASS:

        int bounces
        int maxBounces
        group immune
        unit caster
        unit u
        player castingPlayer


should be

JASS:

        int bounces, maxBounces
        group immune
        unit caster, u
        player castingPlayer


Use Recycle for your groups... : \

And that's just the start. After all of that, you have a bundle of things that can be made better : |...
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Thanks for the feedback. Ironic that I wanted to use cJass but forgot to take advantage of that. :D

[del]Incorporating recycle now.[/del]

Ok, done implementing recycle. Is it correct to null the struct group after using Group.release()?
 

Nestharus

o-o
Reaction score
84
You mean group right?

No need to null it. You asked the same question in the Recycle Thread and I answered there too and I said why =P.

[ljass]GroupEnumUnitsInRange(g,x1,y1,BOUNCE_RANGE,Filter(function Filt))[/ljass]

Leak and slow. You are creating a filter each time... just make a global, initialize it, and use it : |.

Like I said, there are quite a few more : \.

And why???
JASS:
loop{
            u = FirstOfGroup(g)
            exitwhen u == null
            if (IsUnitInGroup(u,D.immune) == false) {
                //calculates distance between the picked unit and the last unit hit by the spell
                x2 = GetUnitX(u) - x1
                y2 = GetUnitY(u) - y1
                if (x2*x2 + y2*y2 &lt; DISTANCE) { //is this unit the closest one in the group?
                    //sets DISTANCE to the distance to the closest unit
                    DISTANCE = x2*x2 + y2*y2
                    t = u
                }
            }
            GroupRemoveUnit(g,u)
        }


Put everything in your filter and return false in it.... no need for all of this extra stuff, it's just slowing you down unnecessarily.

JASS:
        loop {
            TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            exitwhen i &gt;= 11
            i += 1
        }
        TriggerAddCondition(t,Condition(function Cond))
        TriggerAddAction(t,function Act)


Not good : |... you shouldn't be registering every single player from 0 to 11 every time... leaks and a total waste ...

And why are your condition and action separate? Again just slowing things down and creating more unnecessary handles.

If Player Tracking wasn't graveyarded (and it shouldn't be), you could use that.

Furthermore, until Vexorian gets a clue and listens to what so many people have been telling him to do with struct allocation, using default struct create and destroy methods is a very bad practice.

JASS:
struct extends array {}


Inline allocation, create a definition... you only ever use it once, so inlining it will actually save you code and make your stuff faster and save you 2 method calls (allocate and create)

Inlining destroy will save you 1 method call and 1 trigger evaluation : \.

And yes, there is so much more, but I'll leave you with all of these fixes for now ^_^.
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Well you said it doesn't take care of handles, so I assume I have to null the locals. I was just wondering about globals because J4L found that weird leak with them, and wasn't sure if it applied to recycle. :D.

Put everything in your filter and return false in it.... no need for all of this extra stuff, it's just slowing you down unnecessarily.

No way to access D.immune in a filter, unless I made a global group :eek:, which I could do. I also decided to use the FirstOfGroup loop as to not cloud the filter function. It can't be that slow (I notice no speed drop in my map), but given the speed issue I still like this format better. Would making the filter global would be doing something like:

[lJASS]boolexpr b = Filter(function filt)[/ljass]
[ljass]GroupEnumUnitsInRange(g,x1,y1,BOUNCE_RANGE,Filter(function Filt))[/lJASS]?
 

Nestharus

o-o
Reaction score
84
You can't initialize a global variable to a function..

Also, you'd be using the variable. Every time you use Filter() you are creating a new handle ... thus causing a memory leak.

And considering there is absolutely 25% of the code in your loop, yes, it would be a lot faster...

And read my other comments, I was editing my post a lot : P

Oh, and the only memory leak would be the pointer value itself, but I'm really unsure if that actually leaks ;o. Values should be cleared when they go out of scope, but I don't know if handles in JASS follow this general programming rule o-o. I know integers do as they converted into pure C++, so no worries there. Strings do as well (just use regular literal string table in C++). But handles... that part was programmed by Blizzard ;o.

Oh yes, and you are over-commenting your code. Self-explanatory variables like NUMBER_OF_BOUNCES don't need a comment that says that it holds the number of bounces. When you comment to that extent, comments become hurtful.

[ljass]private bool TimerCallback()[/ljass]

not a good function name. What is it really doing? I read that and think, a timer callback, but for what?

Where are your generalized comments at the ends of the lines?

JASS:
void Hi() {
}//simple note on what Hi does


JASS:
exitwhen i &gt;= 11
            i += 1


should be

JASS:
exitwhen --i &lt; 0


always iterate backwards when you can : \. Also, considering you are using a do whilenot loop-

JASS:
do {
} whilenot --i &lt; 0


And now I am going to sleep ^^
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Also, you'd be using the variable. Every time you use Filter() you are creating a new handle ... thus causing a memory leak.

? So I would use a local? I haven't seen any tutorials about this. Perhaps I could initialize the global variable in my init function? Or is that still a no-go?

Not good : |... you shouldn't be registering every single player from 0 to 11 every time... leaks and a total waste ...

? That registers it to each player once, exactly as the BJ does. I'll change it to use [ljass]bj_MAX_PLAYER_SLOTS[/ljass] though.

As far as inlining the creation and destruction goes, I have no clue how to do that. I haven't seen any tutorials about it either. What would making the struct into an array do for the spell? Or is that how you inline the create/destroy? O_O

And considering there is absolutely 25% of the code in your loop, yes, it would be a lot faster...

I will do that. I'll just put a bunch of empty lines before it or something like that.

edit: Tried moving things into the filter function, but now it fatals on loading screen:
edit2: now it doesn't fatal, but it isn't considering the immune group, will look into that.
edit3: [del]fixed that[/del], took out some of the variable comments, but the one on NUM_OF_BOUNCES is kind of important, many might assume that it would be 11 instead of 10.

JASS:
/*

This is a chain spell template by Frozenhelfire
Requires cJass: <a href="http://www.thehelper.net/forums/showthread.php?t=137979" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=137979</a>
Requires KT by Jesus4Lyf, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=78392" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=78392</a>
Requires Recycle by Nestharus, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=136087" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=136087</a>
Sample code has a commented line that uses TL by Flare, download from: <a href="http://www.thehelper.net/forums/showthread.php?t=92877" class="link link--internal">http://www.thehelper.net/forums/showthread.php?t=92877</a>


This spell is made to be casted on a unit, then it will bounce to the next closest unit.
Each bounce performs the actions in the .jumpTo method

private bool Filt() decides what units it can bounce to. At default settings, it will only bounce to
    enemies of the casting unit that are alive and not a structure.

*/


include &quot;cj_types.j&quot;
include &quot;cj_typesEx.j&quot;
include &quot;cj_types_priv.j&quot;
include &quot;cj_typesEx_priv.j&quot;
library ChainTemplate initializer init uses KT, Recycle /*, TL, TT*/{

    define{
        private NUMBER_OF_BOUNCES = 10 //this bounces 10 times, not 11, changeable in the create method
        private SPELL_ID = &#039;AHbn&#039; 
        private BOUNCE_RANGE = 500 
        private PERIOD = 0.10 //Time between bounces
    }
    private player FILTER_PLAYER //This is used in the filter, if you only want the spell to hit enemies or allies of the casting player
    private real x1, y1, x2, y2, DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE //These reals are for distance calculations

    //These two variables are used to transfer data to/from the filter function
    private group immune
    private unit t
    
    private bool Filt(){ //Sample Filter, checks if unit is enemy of caster and not a structure and not dead
                         //This impersonates a standard chain lightning, but the filter can be changed to do other things
        unit u = GetFilterUnit()
       
        if(/*Put the filter conditions on the next line! Next line has sample conditions that can be replated
        */ IsUnitEnemy(GetFilterUnit(),FILTER_PLAYER) == true and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(GetFilterUnit()) &gt; .405) {

            if (IsUnitInGroup(u,immune) == false) {
                //calculates distance between the picked unit and the last unit hit by the spell
                x2 = GetUnitX(u) - x1
                y2 = GetUnitY(u) - y1
                if (x2*x2 + y2*y2 &lt; DISTANCE) { //is this unit the closest one in the group?
                    //sets DISTANCE to the distance to the closest unit
                    DISTANCE = x2*x2 + y2*y2
                    t = u
                }
            }
        }
        u = null
        return false
    }   

    struct ChainTemplate{
        void jumpTo(unit target /*unit the spell is jumping to*/){
            /*this.u is the unit the spell is jumping from
            this.caster is the caster of the spell
            Any actions in here happen every jump*/
            //TL_Unit(&quot;CLPB&quot;, this.u, target, 0.5, false, 1, 1) // If you have FLARE&#039;s Timed Lightning system...
            //you can uncomment the line above to see the actual jumps.
            //TL can be gotten from: 
            UnitDamageTarget(this.caster,target,2000,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_FIRE,null)
            this.bounces += 1 //jumping to a new unit, so add 1 to bounces.
            this.u = target //stores the target for the next bounce (comparing unit distances)
            GroupAddUnit(this.immune,target)
        }
        
        int bounces, maxBounces
        group immune
        unit caster, u
        player castingPlayer
        
        static thistype create(unit caster, unit target){
            thistype D = thistype.allocate()
            D.bounces = 1 //Change to 0 if desired
            D.maxBounces = NUMBER_OF_BOUNCES
            D.caster = caster
            D.u = caster
            D.immune = Group.get()
            D.jumpTo(target)
            D.castingPlayer = GetOwningPlayer(caster)
            return D
        }
        
        /*private static thistype create(unit caster, unit target, int abilLevel){
            thistype D = thistype.allocate()
            D.bounces = 1
            D.maxBounces = abilLevel * 2//By default, bounces 2x the ability level
            D.caster = caster
            D.u = caster
            D.immune = Group.get()
            D.jumpTo(target)
            D.castingPlayer = GetOwningPlayer(caster)
            return D
        }*/

        void onDestroy(){
            Group.release(this.immune)
            this.immune = null
            this.caster = null
            this.u = null
        }
    }

    private bool Cond(){
        return GetSpellAbilityId() == SPELL_ID
    }

    private bool TimerCallback(){
    ChainTemplate D = KT_GetData()
    group g = Group.get()
        //Sets distance to square of bounce_range (efficiency)
        DISTANCE = BOUNCE_RANGE * BOUNCE_RANGE 
        FILTER_PLAYER = D.castingPlayer
        x1 = GetUnitX(D.u)
        y1 = GetUnitY(D.u)
        immune = Group.get()
        immune = D.immune
        GroupEnumUnitsInRange(g,x1,y1,BOUNCE_RANGE,Filter(function Filt))
        GroupAddUnit(D.immune,t)
        Group.release(g)
        Group.release(immune)
        g = null
        if (t == null) { //if there is no unit to jump to, end the spell
            t = null //just in case, heard that this was still needed anyway
            D.destroy()
            return true
        }
        D.jumpTo(t)
        if (D.bounces &gt;= D.maxBounces) { //max bounces reached, end the spell.
            D.destroy()
            return true
        }
        return false
    }

    private void Act(){
        ChainTemplate D = ChainTemplate.create(GetTriggerUnit(),GetSpellTargetUnit())
        //ChainTemplate D = ChainTemplate.create(GetTriggerUnit(),GetSpellTargetUnit(), GetUnitAbilityLevel(GetTriggerUnit(),SPELL_ID))
        //uncomment the line above if using the ability level
        KT_Add(function TimerCallback,D, PERIOD)
    }

    private void init(){
    trigger t = CreateTrigger()
    int i = 0

        loop {
            TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
            exitwhen i &gt;= 11
            i += 1
        }
        TriggerAddCondition(t,Condition(function Cond))
        TriggerAddAction(t,function Act)
    }
}
 

Nestharus

o-o
Reaction score
84
Your code is starting to look better, but it still needs a load of work ^_^

Also, you'd be using the variable. Every time you use Filter() you are creating a new handle ... thus causing a memory leak.
? So I would use a local? I haven't seen any tutorials about this. Perhaps I could initialize the global variable in my init function? Or is that still a no-go?

JASS:
boolexpr myFunction

void Initialization() {
        myFunction = Condition(function MyFunction)
}


An example of how to initialize a global boolean expression variable to a function on initialization : \.

? That registers it to each player once, exactly as the BJ does. I'll change it to use bj_MAX_PLAYER_SLOTS though.

That's even worse o-o. You might not get certain players then : o. I really need to get J4L to ungraveyard and approve Player Tracking.. you could literally do this-

JASS:
int i = GetPlayerCount()-1
do {
        TriggerRegisterPlayerUnitEvent(t,GetIndexedPlayer(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
} whilenot --i == 0


But again, this utility is in the graveyard for no apparent reason. The couple of complaints about it were fixed a long time ago : |.

As far as inlining the creation and destruction goes, I have no clue how to do that. I haven't seen any tutorials about it either. What would making the struct into an array do for the spell? Or is that how you inline the create/destroy? O_O

You'd be implementing a Collection... or a very simple stack with no maintained order. It requires a good understanding of how vJASS works.

I will do that. I'll just put a bunch of empty lines before it or something like that.

What I meant was 25% of the code in your loop is extra code that wouldn't be there if you did it right : \. If you put it all in the filter, you won't be removing from the group and getting the first of the group and so on.... you'd save quite a few lines and a you'd make it a way more efficient.

As for grouping on bounce, I believe that is the right move, but naming the group immune or whatever? Terrible name =P.

[ljass]GroupEnumUnitsInRange(g,x1,y1,BOUNCE_RANGE,Filter(function Filt))[/ljass]

Get rid of that leak o-o

Also
JASS:
if(/*Put the filter conditions on the next line! Next line has sample conditions that can be replated
        */ IsUnitEnemy(GetFilterUnit(),FILTER_PLAYER) == true and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(GetFilterUnit()) &gt; .405)


...

JASS:
if IsUnitEnemy(u, FILTE_PLAYER) &amp;&amp; !IsUnitType(u, UNIT_TYPE_STRUCTURE) &amp;&amp; (IsUnitType(u, UNIT_TYPE_DEAD) || GetUnitTypeId(u) == 0) &amp;&amp; !IsUnitInGroup(u, immune) {
}


[ljass]Group.release(g)[/ljass]

You these groups are released right after they are used, so I would suggest 2 global groups that are equal to CreateGroup(). Group 1 (the enum group) never has to be cleared because nothing is ever added to it. Group 2 needs to be cleared after the enumeration.

JASS:
if (t == null) { //if there is no unit to jump to, end the spell
            t = null //just in case, heard that this was still needed anyway
            D.destroy()
            return true
        }


wth? Shouldn't this be in the Filter func?

Why do you even have a t????
[ljass]t = u[/ljass]
 

Azlier

Old World Ghost
Reaction score
461
>Get rid of that leak o-o

What leak?
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Why do you even have a t????
t = u

How else do I get the closest unit using it in the filter? All I need is a simple example because I still don't see anything that will explain it.
 

Romek

Super Moderator
Reaction score
963
> You can only submit vJASS resources, but you may submit the resource in both vJASS and cJASS on the same submission (2 versions)
Feel free to do that.
As this forum, and the majority of the Wc3 community use vJass, I think it's fair that every resource remains in either regular JASS or vJASS. If you want to add cJASS too, feel free.

Also, I said that no cJASS until it's out of the beta, which is now the case. :)
 

Romek

Super Moderator
Reaction score
963
So as well as Systems, Spells, Demos, etc; you want cJass Spells, cJass Systems, cJass Demos, etc?

I'll pass. :p
 

Nestharus

o-o
Reaction score
84
Still a little off topic, but this will be last one here ^_^

http://www.hiveworkshop.com/forums/...jass-vjass-cjass-sections-146170/#post1335534

Then stop requiring people to write a cJASS and vJASS version-

Suggest JASS, vJASS, and cJASS sections
I suggest you split them up into 3 sections so that we don't have to keep saying this requires this and that. It'll also make cJASS people happier as they won't have to keep writing in vJASS. I'm a cJASS person that hates writing vJASS ^_^.

Either that, or let people submit plain old cJASS resources in the current JASS section without requiring a vJASS version. Do you require plain JASS versions for the vJASS? No. So why are you requiring vJASS on the cJASS stuff??

This will make everyone happy ^_^.

=P
 

Executor

I see you
Reaction score
57
I don't think that this will make everyone happy. Well maybe some cJass coder are forced to code in vJass if they want to submit sth., but imagine half of the "better" JASS coders start to code cJass and no vJass anymore. People using several systems will have to use cJass AND vJass in their maps which would just overcomplicate the whole thing particulary for the mapping beginners.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top