Spell Lightning Strike

Hatebreeder

So many apples
Reaction score
381
Hey all,
This is one of my first vJass Spell I will be submitting here.
Lightning Strike: Summons lightning from the skies, which crash apon a target Area. The lightning expands, dealing Damage to all enemy Units located in the circle.

Requires: ABC and a Jass Preceptor (New Gen)
Jass/GUI: vJass
MUI: Yes
Leakless: Not of that I am aware of

The Code:
JASS:
scope LightningStrike
//******************************************************************************************************
// How to Implement: Copy and Paste The Spell Lightning Strike                                         *
//                   Copy and Paste this Trigger                                                       *
//                   You Probobly need to change the Rawcode, so go in Object Editor, and Press CTRL+D *
//                   Change "STRIKE_ID" to that Value                                                  *
//                   ABC IS REQUIRED                                                                   *
//******************************************************************************************************
globals
    constant real STRIKE_PERIODIC = 0.05        // This determines the speed of the Timer
    constant integer STRIKE_ID = 'A000'         // This is the Raw Code of the Ability
    constant integer STRIKE_ANGLES = 8          // This is the Number of Angles the Lightning Creates
    constant string STRIKE_LIGHTNING = "CLPB"   // Change this to change the look of the lightning
    constant string STRIKE_SFX_1 = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"              //Special effect 1
    constant string STRIKE_SFX_2 = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"                  //Special effect 2
    constant string STRIKE_SFX_3 = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"//Special effect 3
    constant string STRIKE_SFX_4 = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"                                  //Special effect 4
    constant integer STRIKE_RADIUS = 170        // Determines the Max.Radius of the Lightning
    constant integer STRIKE_RADIUS_ADD = 50     // Determines the increment Max.Radius of the lightning  
    constant integer STRIKE_DAMAGE_INIT = 35    // Determines the Damage dealt on cast
    constant integer STRIKE_DAMAGE = 4          // Determines the Damage taken over Time
endglobals

//========= Don't Edit anything under this line unless you know what you are doing ===========================================

private struct Lightning
unit Caster
real Angle
location Target
real TargetX
real TargetY
real TargetLocationX
real TargetLocationY
real TargetX2
real TargetY2
real Alpha
integer Distance
integer Integer
group Group
lightning array Zap[100]
endstruct

//===============Spell RawCode Func======================================
private function Trig_Lightning_Strike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == STRIKE_ID
endfunction

//===============Group Condition Func====================================
private function Trig_Lightning_Strike_Group takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) == false
endfunction

//================Timer Function=========================================
private function Trig_Lightning_Strike_Timer takes nothing returns nothing
    local timer Timer = GetExpiredTimer()
    local unit PickedUnit
    local real PickedUnitX
    local real PickedUnitY
    local Lightning Data = GetTimerStructA(Timer)
    
    call GroupEnumUnitsInRange(Data.Group,Data.TargetLocationX,Data.TargetLocationY,Data.Distance,Condition(function Trig_Lightning_Strike_Group))
    loop
        set PickedUnit = FirstOfGroup(Data.Group)
        exitwhen PickedUnit == null
        if IsUnitEnemy(PickedUnit,GetOwningPlayer(Data.Caster)) then
            call UnitDamageTarget(Data.Caster,PickedUnit,STRIKE_DAMAGE,false,true,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_LIGHTNING,WEAPON_TYPE_WHOKNOWS)
            set PickedUnitX = GetUnitX(PickedUnit)
            set PickedUnitY = GetUnitY(PickedUnit)
            call DestroyEffect(AddSpecialEffectLoc(STRIKE_SFX_3,Location(PickedUnitX,PickedUnitY)))
        endif
        call GroupRemoveUnit(Data.Group, PickedUnit)
    endloop
    
    set PickedUnit = null
    
    set Data.Angle = 360/STRIKE_ANGLES
    set Data.Distance = Data.Distance + 14
    set Data.Alpha = Data.Alpha - 0.03
    
    loop
        exitwhen Data.Integer >= STRIKE_ANGLES
        set Data.TargetX = GetLocationX(Data.Target) + Data.Distance * Cos(Data.Angle * bj_DEGTORAD * Data.Integer)
        set Data.TargetY = GetLocationY(Data.Target) + Data.Distance * Sin(Data.Angle * bj_DEGTORAD * Data.Integer)
        set Data.TargetX2 = GetLocationX(Data.Target) + Data.Distance * Cos(Data.Angle * bj_DEGTORAD * (1 + Data.Integer))
        set Data.TargetY2 = GetLocationY(Data.Target) + Data.Distance * Sin(Data.Angle * bj_DEGTORAD * (1 + Data.Integer))
        call MoveLightning(Data.Zap[Data.Integer],false,Data.TargetX,Data.TargetY,Data.TargetX2,Data.TargetY2)
        call SetLightningColor(Data.Zap[Data.Integer],1,1,1,Data.Alpha)
        set Data.Integer = Data.Integer + 1
    endloop
    
    set Data.Integer = 0
    
    if Data.Distance >= STRIKE_RADIUS + STRIKE_RADIUS_ADD * GetUnitAbilityLevel(Data.Caster,STRIKE_ID) then
        loop
            exitwhen Data.Integer >= STRIKE_ANGLES
            call DestroyLightning(Data.Zap[Data.Integer])
            set Data.Integer = Data.Integer + 1
        endloop
        call RemoveLocation(Data.Target)
        set Data.Integer = 0
        call ClearTimerStructA(Timer)
        call Data.destroy()
        call PauseTimer(Timer)
        call DestroyTimer(Timer)
    endif
    set Timer = null
endfunction

//================Main Function==========================================
private function Trig_Lightning_Strike_Actions takes nothing returns nothing
    local Lightning Data = Lightning.create()
    local timer Timer = CreateTimer()
    local unit PickedUnit
    
    set Data.Caster = GetTriggerUnit()
    set Data.Angle = 360/STRIKE_ANGLES
    set Data.Distance = 0
    set Data.Alpha = 1
    set Data.Group = CreateGroup()
    set Data.Target = GetSpellTargetLoc()
    set Data.TargetLocationX = GetLocationX(Data.Target)
    set Data.TargetLocationY = GetLocationY(Data.Target)
    
    call DestroyEffect(AddSpecialEffectLoc(STRIKE_SFX_1,Location(Data.TargetLocationX,Data.TargetLocationY)))
    call DestroyEffect(AddSpecialEffectLoc(STRIKE_SFX_2,Location(Data.TargetLocationX,Data.TargetLocationY)))
    
    call GroupEnumUnitsInRange(Data.Group,Data.TargetLocationX,Data.TargetLocationY,STRIKE_RADIUS + STRIKE_RADIUS_ADD,Condition(function Trig_Lightning_Strike_Group))
    loop
        set PickedUnit = FirstOfGroup(Data.Group)
        exitwhen PickedUnit == null
        if IsUnitEnemy(PickedUnit,GetOwningPlayer(Data.Caster)) then
            call UnitDamageTarget(Data.Caster,PickedUnit,STRIKE_DAMAGE_INIT * GetUnitAbilityLevel(Data.Caster,STRIKE_ID),false,true,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_LIGHTNING,WEAPON_TYPE_WHOKNOWS)
            call DestroyEffect(AddSpecialEffectTarget(STRIKE_SFX_4,PickedUnit,"chest"))
        endif
        call GroupRemoveUnit(Data.Group, PickedUnit)
    endloop
    
    set PickedUnit = null
    
    loop
        exitwhen Data.Integer >= STRIKE_ANGLES
        set Data.TargetX = GetLocationX(Data.Target) + Data.Distance * Cos(Data.Angle * bj_DEGTORAD * Data.Integer)
        set Data.TargetY = GetLocationY(Data.Target) + Data.Distance * Sin(Data.Angle * bj_DEGTORAD * Data.Integer)
        set Data.TargetX2 = GetLocationX(Data.Target) + Data.Distance * Cos(Data.Angle * bj_DEGTORAD * (1 + Data.Integer))
        set Data.TargetY2 = GetLocationY(Data.Target) + Data.Distance * Sin(Data.Angle * bj_DEGTORAD * (1 + Data.Integer))
        set Data.Zap[Data.Integer] = AddLightning(STRIKE_LIGHTNING,false,Data.TargetX,Data.TargetY,Data.TargetX2,Data.TargetY2)
        call SetLightningColor(Data.Zap[Data.Integer],1,1,1,Data.Alpha)
        set Data.Integer = Data.Integer + 1
    endloop
    
    set Data.Integer = 0
    
    call SetTimerStructA(Timer, Data)
    
    call TimerStart(Timer,STRIKE_PERIODIC,true,function Trig_Lightning_Strike_Timer)
endfunction
//===========================================================================
function InitTrig_Lightning_Strike takes nothing returns nothing
    local trigger Lightning_Strike = CreateTrigger(  )
    call Preload("Abilities\\Weapons\\Bolt\\BoltImpact.mdl")
    call Preload("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")
    call Preload("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl")
    call Preload("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl")
    call TriggerRegisterAnyUnitEventBJ( Lightning_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( Lightning_Strike, Condition( function Trig_Lightning_Strike_Conditions ) )
    call TriggerAddAction( Lightning_Strike, function Trig_Lightning_Strike_Actions )
endfunction
endscope
And a Pic in Action:
Clipboard02-2.jpg

I hope you like it ! Have fun ! =)
 

Attachments

  • JassSpellMap.w3x
    63.9 KB · Views: 827

Tom Jones

N/A
Reaction score
437
Null the local timer at the end of both functions. Instead of using a new group everytime the timer runs, create a global group and clean (call GroupClear())after use.

It looks like you got the hang of the basics, now it's time to go from locations to points.
 

Sim

Forum Administrator
Staff member
Reaction score
534
Hmm. This spell's explosion should at least deal some base damage.

As it is right now the thunderclap/lightning bolt that falls from the sky deals no damage, and the little charging bolts (And by little I mean very small) deal all the damage.

It shouldn't behave that way. ;)
 

Hatebreeder

So many apples
Reaction score
381
well, I don't only use locations... But I'll try to only use reals (Points).
Also, thank you both (+Rep whore and Tom) for checking though my Code =)
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Other word for Preceptor is teacher (at least that tells me my dictionary..) Nice spell

> local trigger gg_trg_Lightning_Strike = CreateTrigger( )
Loool... Why not local trigger ls = CreateTrigger() ? You can get rid of that ugly gg_trg stuff that annoys me so badly :p You can also put scopes
 

Hatebreeder

So many apples
Reaction score
381
Hmm. This spell's explosion should at least deal some base damage.

As it is right now the thunderclap/lightning bolt that falls from the sky deals no damage, and the little charging bolts (And by little I mean very small) deal all the damage.

It shouldn't behave that way. ;)

EDIT* Added use of scope + privates, made more globals to make it more customizeable, removed Leaks, added "on cast" damage
 

Hatebreeder

So many apples
Reaction score
381
21 Views, and no one realy made any Comments on this Spell...
Please people, tell me about your expiriences =)
 

Astal

New Member
Reaction score
1
i have a few comments. How do you change the damage and such, because in the spell itself it has 0, so I assume its in the trigger but i only see one field in the trigger so how do you increment it? Is it 35 damage per level or?

Code:
    constant integer STRIKE_RADIUS = 170        // Determines the Max.Radius of the Lightning
    constant integer STRIKE_RADIUS_ADD = 50     // Determines the increment Max.Radius of the lightning  
    constant integer STRIKE_DAMAGE_INIT = 35    // Determines the Damage dealt on cast (so it is only 35 no matter the level correct?)
    constant integer STRIKE_DAMAGE = 4          // Determines the Damage taken over Time
 

Blackrage

Ultra Cool Member
Reaction score
25
There are two different types of damage that the spell does.

The STRIKE_DAMAGE_INIT is the damage when you cast the spell.

The STRIKE_DAMAGE is the damage overtime (when the lightning expands). It deals this damage every 0.04 seconds for X seconds I believe.
 
Reaction score
91
Since I'm using this spell in one of my maps I have to add some suggestions.

JASS:

    constant integer STRIKE_RADIUS = 170        // Determines the Max.Radius of the Lightning
    constant integer STRIKE_RADIUS_ADD = 50     // Determines the increment Max.Radius of the lightning  
    constant integer STRIKE_DAMAGE_INIT = 35    // Determines the Damage dealt on cast
    constant integer STRIKE_DAMAGE = 4          // Determines the Damage taken over Time


Make all those functions instead of globals; in your Actions function you're leaking the timer; you're not destroying the group in the struct (btw you should use some group recycling method - GroupUtils); use a scope with an initializer instead of normal JASS initializing. Other than that it seems fine.
 
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