• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Chaoslaser v2 GUI and JASS (v1.10)

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: Arman
Chaoslaserv2
BTNBanish.gif

Charges energy to unleash a huge laserbeam which explodes and spreads out shards on it's impact.
Damage: 40/45/60 on hit + 30/60/90 on impact
Range: 700
Type: Active
Cooldown: 10s
--
*Spell is mui/gui/epic
*Spell is made all by myself and therefore all credits go to me
*Spell needs jngp (I think) and TimerUtils
--
2oo9 by Squiggy

GUI:
*v1.01: I fixed the channel-issue using a 4s stun

JASS: *v1.10: Remade a bit


JASS:
//==Chaoslaser v2==
//~Uses TimerUtils (blue flavor)
//~Needs jngp
//Credits go to HINDYhat for teaching me jass and correcting my spell a couple of times ^^
//2oo9 by Squiggy

scope CLv2 initializer SpellInit
    globals
        private constant integer SPELLID = 'A000'                   //First, I set the constants to the two abilites
        private constant integer SPELLID2 = 'A001' 
        private constant integer DmgFactor = 30                     //Here you can preset the amount of damage which is going to be dealt (level*DmgFactor)
        private constant real distance = 100                        //Here, you can change the distance in which the beamdummies are created
        private constant string effpath = "Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl"  //And here, you can change the cast effect
    endglobals
    
    globals
        private player p
    endglobals
        
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELLID                      //The usual condition
    endfunction
    
    private struct growth                                          //The struct 'growth' holds every needed data for the growth of the dummy and the 
        unit dummy                                                 //stuff that goes after
        real size
        real grow
        real posX
        real posY
        real facing
        real distance
        integer abilv
        real distaddX
        real distaddY
    endstruct

    private function Grp takes nothing returns boolean             //Group filter to your left
        return IsUnitEnemy(GetFilterUnit(), p)
    endfunction    
    
                                                                   //Everything after the dummy is created goes here
    
    private function grow takes nothing returns nothing
        local integer INDEX                                        //First, we define and set the needed locals
        local unit u
        local unit gru
        local group g
        local growth gt = growth(GetTimerData(GetExpiredTimer()))  //Now we get the data from the expired timer
        set gt.size = gt.size + .1                                 //We increase the dummysize by 10%
        call BJDebugMsg(R2S(gt.size))
        call SetUnitScale(gt.dummy, gt.size, gt.size, gt.size) 
        if gt.size > 10 then                                       //Now if the dummysize reaches 10, it's time to create the 'laserbeam'
            set g = CreateGroup()
            call ReleaseTimer(GetExpiredTimer())                   //and to remove the timer
            set INDEX = 0
            call RemoveUnit(gt.dummy)
            set gt.posX = GetUnitX(gt.dummy)
            set gt.posY = GetUnitY(gt.dummy)
            loop 
            exitwhen INDEX >= (gt.distance/distance)                    //Now we create one dummy per 100 warcraft units until the distance it reached
                set u = CreateUnit(p, 'n001', gt.posX, gt.posY, gt.facing)
                call SetUnitAbilityLevel(u, SPELLID2, gt.abilv)
                call UnitApplyTimedLife(u, 'BLTF' , .2)
                set INDEX = INDEX+1
                set gt.posX = gt.posX + gt.distaddX                //And here we move the position of the next created dummy 'forward'
                set gt.posY = gt.posY + gt.distaddY
            endloop
            set INDEX = 0
            loop 
                exitwhen INDEX == 8                                // Now we spawn the eight dummies which move outwards from the current position
                set u = CreateUnit(p, 'n001', gt.posX, gt.posY, INDEX*45)
                call SetUnitAbilityLevel(u, SPELLID2, gt.abilv)
                call IssuePointOrder(u, "move", gt.posX+1000.00*Cos((INDEX*45)*bj_DEGTORAD), gt.posY+1000.00*Sin((INDEX*45)*bj_DEGTORAD))  //We order it to move
                call SetUnitScale(u, 0.3, 0.3, 0.3)                //And now we decrease it's scaling to 0.33
                call UnitApplyTimedLife(u, 'BLTF' , 1.2)
                set INDEX = INDEX+1
            endloop
            set u = CreateUnit(p, 'n002', gt.posX, gt.posY, 90)    //Last, we need the effect and to deal damage
            call SetUnitAbilityLevel(u, SPELLID2, gt.abilv)
            call UnitApplyTimedLife(u, 'BLTF' , 1.0)
            call GroupEnumUnitsInRange(g, gt.posX, gt.posY, 500, Filter(function Grp))
            loop                                                   //As we just picked every unit in 200 range from the point where the dummy is spawned
                set gru = FirstOfGroup(g)                          //we deal the damage equal to lvl*30
                exitwhen gru == null
                call UnitDamageTarget(u, gru, gt.abilv*DmgFactor, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                call GroupRemoveUnit(g, gru)
            endloop
            set u = null                                           //And now we null the necessary variables and clean up leaks
            set gt.dummy = null
            call DestroyGroup(g)
            set g = null
        call gt.destroy()
        endif
        endfunction
    
    private function Actions takes nothing returns nothing         //This part of the spell creates the dummy and starts the timer which makes the dummy 'grow'
        local unit caster = GetTriggerUnit()
        local real dx
        local real dy
        local location targetpoint = GetSpellTargetLoc()
        local timer t = NewTimer()                                 //Here, we create the timer
        local growth gt = growth.create()
        set p = GetOwningPlayer(caster)
        call SetTimerData(t, integer(gt))                          
        set gt.abilv = GetUnitAbilityLevel(caster, SPELLID)
        set gt.size = 0.00
        set gt.facing = GetUnitFacing(caster)
        set gt.dummy = CreateUnit(p, 'n000', GetUnitX(caster)+distance*Cos(gt.facing*bj_DEGTORAD), GetUnitY(caster)+100.00*Sin(gt.facing*bj_DEGTORAD), gt.facing)
        call TimerStart(t, 0.04, true, function grow)              //Now we start it
        set gt.posX = GetUnitX(gt.dummy)
        set gt.posY = GetUnitY(gt.dummy)
        set dx = GetLocationX(targetpoint)-gt.posX                 //And now it's time to get the diatance between the caster and the targeted point
        set dy = GetLocationY(targetpoint)-gt.posY
        set gt.distance = SquareRoot(dx * dx + dy * dy)
        set gt.distaddX = distance*Cos(gt.facing*bj_DEGTORAD)
        set gt.distaddY = distance*Sin(gt.facing*bj_DEGTORAD)
        call SetUnitScale(gt.dummy, gt.size, gt.size, gt.size)
        call IssueTargetOrder(gt.dummy, "thunderbolt", caster)     //This is done to stun the caster (looks crappy if he can move while casting
        call DestroyEffect(AddSpecialEffect(effpath, gt.posX, gt.posY))
        call RemoveLocation(targetpoint)                           //And here we get rid of leaks
        set caster = null
    endfunction    
    
    private function SpellInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
    endfunction
endscope

Keywords:
spell, laser, shoop da whoop, squiggy, epic, lulz, aoe, gui, mui, green, nature, damage
Contents

Chaoslaser v2 (Map)

Reviews
19:59, 22nd Sep 2009 The_Reborn_Devil: It's not compatible with 1.24 :/

Moderator

M

Moderator

19:59, 22nd Sep 2009
The_Reborn_Devil:

It's not compatible with 1.24 :/
 
Level 10
Joined
Jun 1, 2008
Messages
485
ok, Squiggy, nice spell
but here's few bugs:
1. when i start channel it, then order unit to stops, then the ability still channeling and get started, without unit channeling it and the ability didn't go into cool down, and i can repeat it many times. maybe you can add trigger that check when unit is stops channeling.
2. when the beam 'throwed' (not the beam that released on impact, but when ability is started), the beam didn't deal any damage. maybe you ca adding it.
3. when 'beam' impact, it damages unit in square, make it on circle.

that's all. and you should tells that this spell need custom value on the dummy.
otherways, great spell.
 
Level 10
Joined
Jun 1, 2008
Messages
485
hmm, sorry then. for second issue, i didn't see the dummy have the 'damage' ability.
for third issue, i miss-seeing the trigger, sorry, it damage unit in circle.

and for custom value, it's just for information, but i think it still can cause bug in some map that give every unit custom value for example. (well, it's very-very rare to see map like that)

just suggestion, but you can make damage more adjustable by adding it with trigger. because in trigger you can make damage more complex, like (level of ability x strength).
well, it just suggestion.

sorry for wrong issue.
 
Level 28
Joined
Mar 25, 2008
Messages
2,955
Hmm.. maybe I'll edit it - but then I'd have to rewrite a huge part of the spell since I can't refer to (Triggering Unit) in the second trigger :eek:

//edit:
I just updated that one, fixed the challenge-issue by using a stun being applied to the casting unit - that way it gets a nice buff (This unit is charging his laser) *lulz*
lazer-chare.jpg


And for the rectangular damaging, since there'd be a leak if I used a dynamically generated region, i'll leave it as it is..
 
Last edited:
Level 2
Joined
Mar 5, 2009
Messages
5
Pretty good spell haven't seen many Laser-type spells around.
One pointer looks too green to me looks like the laser is going to turn into the Hulk or something haha :angry:. oh and perhaps you could up the damage as well

final rating 3.1/5
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Couldn't check the Jass version in-game... most probably 'cause I still use WC3 v1.21.

Umm, I didn't fully read the script but it looks well-done and well-structured.

Yet, you forgot to null the trigger local variable in the Init function.

And here's a better version of that:

JASS:
    private function AntiLeaker takes nothing returns boolean
        return true
    endfunction
    
    private function SpellInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        local filterfunc f = Filter(function AntiLeaker)
        local integer i = 0
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, f)
            set i = i + 1
            exitwhen i == 16
        endloop
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
        set f = null
        set t = null
    endfunction
You'd be getting rid of 16 leaks using that filter, and having your whole script BJ free ;)
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
Several suggestions/questions:
1.Why do you use a double block for globals? I mean u have 3 global variables and 2 global blocks :p
2.nvm
3.You could have just used local reals x,y for GetUnitX(),GetUnitY() and avoid calling the GetUnitX(),GetUnitY() functions.
4.Add the constant integer variable for the unit you are creating, else the spell might not work after importing it.
JASS:
    globals
        //...other globals  before this one...
        private constant integer Dummy1ID = 'n001'
        private constant integer Dummy2ID = 'n002'
    endglobals

All in all nice to see you are working in jass.
Much easier than GUI if you ask me, structs are too good :D
 
Level 17
Joined
Mar 2, 2009
Messages
332
off-topic
can you tell me where did you learned Jass....i want it too :p
i just want local variable functions....if oyu can give em some tutorial pls....tnx
....btw didn't check spells yet..
i will give you rep tomorrow... @You have given out too much Reputation in the last 24 hours, try again later!@
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
@Everyone
Guys this is Squiggy's spell, if you got offtop stuff to tell me do it via VM.(visitor mesages for thos who don't know)

Btw Squiggy i tested this and it didn't work :p
The spell isn't MUI even with the structs and stuff...
I suggest you to try to find the source of this problem and consult with Hindyhat(cause you said he is your teacher) or someone else.
 
Level 28
Joined
Mar 25, 2008
Messages
2,955
1.Why do you use a double block for globals? I mean u have 3 global variables and 2 global blocks :p
Now I've added more than two other constants.
Also, it's easier to modify if you don't have to bother about some globals and just change the constants
3.You could have just used local reals x,y for GetUnitX(),GetUnitY() and avoid calling the GetUnitX(),GetUnitY() functions.
Why should I use even more variables for just ONE use?
4.Add the constant integer variable for the unit you are creating, else the spell might not work after importing it.
Why should it?

can you tell me where did you learned Jass....i want it too :p
I'm given lessons from HINDYchat

And on a sidenote, the spell's mui again
 
Level 6
Joined
Jul 27, 2008
Messages
132
Post the link for JNGP !

off-topic
can you tell me where did you learned Jass....i want it too :p
i just want local variable functions....if oyu can give em some tutorial pls....tnx
....btw didn't check spells yet..
i will give you rep tomorrow... @You have given out too much Reputation in the last 24 hours, try again later!@
off top

i learn with Thanthos :)
or you can test by your self download JNGP
and practice it's best tool for helping newbie.
you should ask pros if you have question :X
hmmm you shall begin(to make vJass) as simple spell, convert to text
remove bj declare global use variable remove leaks etc..
or you can PM me or thanthos
thx!
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
I see you don't understand.
While improting your spell the ID of the DUMMY CHANGES therefore it should be in a constant value so users don't have to replace the ID's manualy inside the code.
There are SLIM chances that the ID of the dummy you are using will be same upon import.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Nooo Squiggy you're not getting it :p

Umm, you created a new map, set the trigger and dummy, the dummy ID is 'h000'

I have a map which I've been working on for a year, I copy your triggers and your dummy, the dummy Id wouldn't be 'h000' but something more like 'h203'

Then the guy search your globals and he doesn't know where yo change it...
that's why you need to set a private constant integer in the globals for the dummy id ;)

Got it now? =D
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
ukhh Squiggy you can be stuborn sometimes :p
Well I won't argue anymore, but so that you get the idea:

JASS:
globals
     private constant integer Dummy = 'n000'
endglobals

//in some function
call CreateUnit(bla bla, Dummy, bla bla...)

it's not a matter of how many times you use it, it's just a matter of the person not to have to search for the dummy in the script and just adjust it in the globals...

well it's your decision after all... :p
 
Top