Spell Pillar of Lightning

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> Why?

Deleted the globals. Didn't want to rename all the variables in the code. :p
 

U are a noob

Mega Super Ultra Cool Member
Reaction score
152
Code:
Pillar of Lightning
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
        (Ability being cast) Equal to Pillar of Lightning 
    Actions
        Set TempPoint = ((Target point of ability being cast) offset by (0.00, 0.00))
        Special Effect - Create a special effect at TempPoint using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
        Special Effect - Destroy (Last created special effect)
        For each (Integer A) from 1 to 10, do (Actions)
            Loop - Actions
                Unit - Create 1 Effect Unit for (Owner of (Triggering unit)) at TempPoint facing Default building facing degrees
                Unit - Order (Last created unit) to Stop
                Animation - Play (Last created unit)'s stand animation
                Set Wisps[(Integer A)] = (Last created unit)
                Animation - Change Wisps[(Integer A)] flying height to (50.00 x ((Real((Integer A))) - 1.00)) at 500.00
        Wait 0.10 seconds
        For each (Integer A) from 1 to LightningIntervals, do (Actions)
            Loop - Actions
                For each (Integer B) from 1 to NumberofTargets, do (Actions)
                    Loop - Actions
                        Custom script:   if (bj_forLoopBIndex == 1 or GetRandomInt(1,100) <= udg_ChanceforBolt) then
                        Unit - Create 1 Effect Unit for (Owner of (Triggering unit)) at TempPoint facing Default building facing degrees
                        Set Caster = (Last created unit)
                        Unit - Hide Caster
                        Unit - Add a 3.00 second Generic expiration timer to Caster
                        Animation - Change Caster flying height to (Random real number between 100.00 and 450.00) at 4000.00
                        Set TempGroup = (Units within BoltRange of TempPoint matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True))
                        Set Target = (Random unit from TempGroup)
                        Unit - Order Caster to Orc Far Seer - Chain Lightning Target
                        Custom script:   call DestroyGroup(udg_TempGroup)
                        Custom script:   endif
                Wait (Random real number between 1.00 and 3.00) seconds
        For each (Integer A) from 1 to 10, do (Actions)
            Loop - Actions
                Animation - Change Wisps[(Integer A)] flying height to 0.00 at 300.00
        Wait 2.50 seconds
        For each (Integer A) from 1 to 10, do (Actions)
            Loop - Actions
                Unit - Remove Wisps[(Integer A)] from the game
        Custom script:   call RemoveLocation(udg_TempPoint)
If this is all that is in your spell you can upgrade it to MUI easy.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> If this is all that is in your spell you can upgrade it to MUI easy.

Array-less? Doubt it. Already tried.

The JASS version is MUI. Just use that. :p
 
C

Crapling

Guest
This looks awesome, I'll have to try it out once I get home.
 

Exide

I am amazingly focused right now!
Reaction score
448
JASS:

exitwhen looping &gt; end


Could be:

JASS:

exitwhen looping &gt; 10



Anyway, nice spell. :)
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> Could be:
JASS:
exitwhen looping &gt; 10



Yes. In some cases. Not all. But, I was just going for the MUI, and merely replaced the GUI functions with more efficient ones, but didn't alter the structure a whole lot.
 

Exide

I am amazingly focused right now!
Reaction score
448
>Yes. In some cases. Not all. But, I was just going for the MUI, and merely replaced the GUI functions with more efficient ones, but didn't alter the structure a whole lot.
Also, I noticed that later in the trigger;

JASS:

set end = LightningIntervals


So I guess it will only work properly on the first loop, and since you're using a variable, 'end', later anyway so what the heck... :p
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Well, at least you're critiquing my code.

That's a good thing.
I thought there'd be more problems with it. (I don't do JASS well - yet.)

I'm surprised so far. :p
 

Sim

Forum Administrator
Staff member
Reaction score
534
> I thought there'd be more problems with it. (I don't do JASS well - yet.)
> I'm surprised so far. :p

If you insist :p

> set TempGroup = GetUnitsInRangeOfLocMatching(BoltRange, TempPoint, Condition(function Trig_Pillar_of_Lightning_Func008Func001Func007002003))

You could use the native directly by first setting TempGroup to "CreateGroup()" and then calling the function "GroupEnumUnitsInRangeOfLocMatching" (NOT setting the variable to the function. Call it and give it the created group).

You might want to name your functions better.

> set TempPoint = OffsetLocation(GetSpellTargetLoc(), 0, 0)

Technically, you should set first another location variable to "GetSpellTargetLoc()" because it leaks and then set TempPoint to this location offset by 0...

But, why not just set TempPoint directly to GetSpellTargetLoc()? :p

> call AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", TempPoint )
> call DestroyEffect( GetLastCreatedEffectBJ() )

Sorry, AddSpecialEffectLoc doesn't work with GetLastCreatedEffectBJ() :p

You should do this instead:

call DestroyEffect(AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", TempPoint ))

JASS:
    call CreateNUnitsAtLoc( 1, &#039;e000&#039;, GetOwningPlayer(GetTriggerUnit()), TempPoint, bj_UNIT_FACING )
    call IssueImmediateOrder( GetLastCreatedUnit(), &quot;stop&quot; )
    call SetUnitAnimation( GetLastCreatedUnit(), &quot;stand&quot; )
    set Wisps[looping] = GetLastCreatedUnit()


If you're going to use "GetLastCreatedUnit()" many times, you're better off setting it to a variable to prevent useless function calls.

While doing so, using the native "CreateUnit()" would also be better :p

Don't know why, but you did set the last created unit to a variable in the second loop!

So... that's about it!
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> You could use the native directly by first setting TempGroup to "CreateGroup()" and then calling the function "GroupEnumUnitsInRangeOfLocMatching" (NOT setting the variable to the function. Call it and give it the created group).


No idea what you mean there. :p
Why would I want to create the group when I just set the variable?

> You might want to name your functions better.

Bah! Who cares about that? Useless, that's what it is. :p

> Technically, you should set first another location variable to "GetSpellTargetLoc()" because it leaks and then set TempPoint to this location offset by 0...
But, why not just set TempPoint directly to GetSpellTargetLoc()?

Yes, I think I already mentioned this, but I thought that was causing a problem earlier. Didn't change it back. Fixed.

> Sorry, AddSpecialEffectLoc doesn't work with GetLastCreatedEffectBJ()

You should do this instead:

call DestroyEffect(AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderCl ap\\ThunderClapCaster.mdl", TempPoint ))



Interesting. What does it do? How can it destroy an effect that has not been created?

> If you're going to use "GetLastCreatedUnit()" many times, you're better off setting it to a variable to prevent useless function calls.

Oh, now you're just being silly.
Don't expect consistency from me. Expect it to work. :p


> While doing so, using the native "CreateUnit()" would also be better

Boo! Hiss! I refuse to define X's and Y's. :p

> Don't know why, but you did set the last created unit to a variable in the second loop!

Consistency....
 

Sim

Forum Administrator
Staff member
Reaction score
534
> Why would I want to create the group when I just set the variable?

To use the native directly. Saves function calls :p

> Interesting. What does it do? How can it destroy an effect that has not been created?

I'll go in deep explanations of "what" and "why".

what?

Quite simple :p

Here is the function "AddSpecialEffectLocBJ" (which you didn't use)

JASS:
function AddSpecialEffectLocBJ takes location where, string modelName returns effect
    set bj_lastCreatedEffect = AddSpecialEffectLoc(modelName, where)
    return bj_lastCreatedEffect
endfunction


It sets bj_lastCreatedEffect to the newly created effect. (bj_lastCreatedEffect is returned by the function GetLastCreatedEffect)

Then, the function you used:

JASS:
native AddSpecialEffectLoc          takes string modelName, location where returns effect


Oops, no bj_lastCreatedEffect!

So it won't work.

why?

Why use the DestroyEffect before and how can you create and destroy an effect right away?

Well, to destroy an effect you need an already existing effect. Which is why we create an effect... to destroy it!

Point is, the editor will never destroy an effect (Few exceptions may apply...) until it reaches a full "cycle" of action.

Which means, it has to "play" his whole animation before dying.

SO, it saves a function call and it works anyway. Use it!

The thing you did previously didn't clean the leak.

> Don't expect consistency from me. Expect it to work. :p

I'm criticizing your code!

> Boo! Hiss! I refuse to define X's and Y's. :p

CreateUnitAtLoc anyone?

It's a native too, you can use it!

> Consistency....

:confused: Gha...! (n_04)
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> I'll go in deep explanations of "what" and "why".

Cool. All I really needed to see was the two code comparisons and the Destroy part. :p

> I'm criticizing your code!

Yes! It's just that bad! :p

> CreateUnitAtLoc anyone?

Hmm... I could do that.

> Gha...! (n_04)

What? Don't look at me like that. It works. :p
 

Sim

Forum Administrator
Staff member
Reaction score
534
> It works. :p

It is my philosophy too.

BUT, I had to criticize your work. (I was forced by... *insert unknown reason here*)

As for the GUI...

It works good without leaks? Fine.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> It works good without leaks? Fine.

Works good? Debatable. Not MUI. The pillar animation can get bugged a bit. Doesn't affect the spell's execution, but may cause eye torture. :p

Without leaks? Yes.
 

Sim

Forum Administrator
Staff member
Reaction score
534
MUI is not a requirement ;)

> The pillar animation can get bugged a bit.

:confused: Didn't notice that.
 

0zaru

Learning vJASS ;)
Reaction score
60
> You could use the native directly by first setting TempGroup to "CreateGroup()" and then calling the function "GroupEnumUnitsInRangeOfLocMatching" (NOT setting the variable to the function. Call it and give it the created group).


No idea what you mean there.
Why would I want to create the group when I just set the variable?


He means something like this
JASS:
local grup g=CreateGroup()
call GroupEnumUnitsInRangeOfLocMatching(all arguments here...)


>Interesting. What does it do? How can it destroy an effect that has not been created?


it creates the effect and destroy it playing the effect death animation (With some effects it doesn't work)

It's like this
JASS:
call RemoveUnit(CreateUnit(bla bla))

It creates the unit and then removes it

> If you're going to use "GetLastCreatedUnit()" many times, you're better off setting it to a variable to prevent useless function calls.

Oh, now you're just being silly.
Don't expect consistency from me. Expect it to work.


You can even do this directly
set bj_lastCreatedUnit=CreateUnit(arguments bla bla...) X's and Y's are easy to set :p

The "GetLastCreatedUnit()" function just returns bj_lastCreatedUnit
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
@ Daxtreme:

Yes. Completely random. Difficult to prevent. I've tried. See the latest version.

@ 0zaru:

Already got it, but thanks anyway. :D
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Yup, the master Purge has come to Purge your code, and renew it in an optimized way! Muahahahaa!

Here it is, optimized:

Just update your map and remove the globals. I really optimized your code, it was a big hassle, but I optimized it anyways!! :D

JASS:
//Constant functions, you may edit these//
constant function POL_rawcode takes nothing returns integer
    return &#039;A000&#039; //The rawcode of the spell//
    //POL means Pillar_Of_Lightning//
endfunction

constant function POL_ThunderClap takes nothing returns string
    return &quot;Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl&quot;
endfunction

constant function LightningIntervals takes nothing returns integer
    return 50
endfunction
constant function NumberofTargets takes nothing returns integer
    return 3
endfunction
constant function ChanceforBolt takes nothing returns integer
    return 20
endfunction
constant function BoltRange takes nothing returns real
    return 600.
endfunction
//Do NOT edit past this point unless you know what you are doing//

function Pillar_Of_Lightning_UnitEnemy takes nothing returns boolean
    return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )
endfunction

function Trig_Pillar_of_Lightning_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == POL_rawcode()
endfunction

function Trig_Pillar_of_Lightning_Actions takes nothing returns nothing
    local unit array Wisps
    local location TempPoint
    local unit Caster
    local unit Target
    local group TempGroup
    local integer i                      = 0   
    local integer i2                     = 0 
    set TempPoint = GetSpellTargetLoc()
    call DestroyEffect(AddSpecialEffectLoc(POL_ThunderClap(), TempPoint  ))
    set i = 1
    loop
        exitwhen i &gt; 10
        set Wisps<i> = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()) , &#039;e000&#039;, TempPoint, bj_UNIT_FACING )
        call IssueImmediateOrder( Wisps<i>, &quot;stop&quot; )
        call SetUnitAnimation( Wisps<i>, &quot;stand&quot; )
        call ResetUnitAnimation( Wisps<i> )
        call SetUnitFlyHeight( Wisps<i>, ( 50.00 * ( I2R(i) - 1 ) ), 500.00 )
        set i = i + 1
    endloop
    call TriggerSleepAction( 0.10 )
    set i = 1
    loop
        exitwhen i &gt; LightningIntervals()
        set i2 = 1
        loop
            exitwhen i2 &gt; NumberofTargets()
            if (i2 == 1 or GetRandomInt(1,100) &lt;= ChanceforBolt()) then
                set Caster = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()) , &#039;e000&#039;, TempPoint, bj_UNIT_FACING )
                call ShowUnitHide( Caster )
                call UnitApplyTimedLife(Caster, &#039;BTLF&#039;, 3.00 )
                call SetUnitFlyHeight( Caster, GetRandomReal(100.00, 450.00), 4000.00 )
                set TempGroup = CreateGroup()
                call GroupEnumUnitsInRangeOfLoc(TempGroup, TempPoint, BoltRange(), Condition(function Pillar_Of_Lightning_UnitEnemy))
                set Target = GroupPickRandomUnit(TempGroup)
                call IssueTargetOrder( Caster, &quot;chainlightning&quot;, Target )
                call DestroyGroup(TempGroup)
                set TempGroup            = null
                set Caster               = null
                set Target               = null
            endif
            set i2 = i2 + 1
        endloop
        call TriggerSleepAction( GetRandomReal(1.00, 3.00) )
        set i = i + 1
    endloop
    set i = 1
    loop
        exitwhen i &gt; 10
        call SetUnitFlyHeight( Wisps<i>, 0.00, 300.00 )
        set i = i + 1
    endloop
    call TriggerSleepAction( 2.50 )
    set i = 1
    loop
        exitwhen i &gt; 10
        call RemoveUnit( Wisps<i> )
        set Wisps<i>                     = null
        set i = i + 1
    endloop
    call RemoveLocation(TempPoint)
    set TempPoint                        = null
endfunction

//===========================================================================
function InitTrig_Pillar_of_Lightning takes nothing returns nothing
    set gg_trg_Pillar_of_Lightning = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Pillar_of_Lightning, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(gg_trg_Pillar_of_Lightning,Condition(function Trig_Pillar_of_Lightning_Conditions))
    call TriggerAddAction( gg_trg_Pillar_of_Lightning, function Trig_Pillar_of_Lightning_Actions )
endfunction</i></i></i></i></i></i></i></i>
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Constant Functions? We don't need constant functions. :p

No, seriously. How are people supposed to be able to set the globals? You don't even include them. I left them for a reason.

I guess it's just as easy to edit them in the code with them not being globals, but it would be easier if they could set them with GUI for the newer mappers.

Either way works.

Thanks for the optimization. :D
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Well, I think I understand you correctly. See, the global variables should only be for the GUI version. Instead of using locals that are set to globals, you can just make constant functions. It is much more easier to edit. You just need to type. Not click the value and go through all those selection junk.

Since you are setting locals to globals, why not just use the globals? Since you don't have two triggers or functions in which those globals are needed, why use the globals? It just adds more implementation difficulty.

Besides, constant functions are so easy to edit. In fact, I should make a tutorial about it.

~Reserved tutorial idea until further notice~ :D

Your welcome! Thanks for making the spell! :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • 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 The Helper:
    Here is another comfort food favorite - Million Dollar Casserole - https://www.thehelper.net/threads/recipe-million-dollar-casserole.193614/

      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