• 🏆 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!

Electrifying Smash

This is my Spell Electrifying Smash requested by Aelita

Electrifying Smash
The Mage lifts his enemy high into the sky to burn him with heavy lightnings.
Then he smashes him to the ground, damaging all enemies in AOE.
The Spell is of course MUI, leakless and that stuff.
It's in vJass so you need JNGP to make it work well

I tried a new coding style so if you find bugs or think that this style is better than my old one please tell me

A how to import is included!!

gl & hf

v.2.0: Fixed the things TriggerHappy wanted me to


JASS:
scope ElectrifyingSmash initializer Init

// Electrifying Smash by The_Witcher

//The Mage lifts his enemy high into the sky to burn him with heavy lightnings.
//Then he smashes him to the ground, damaging all enemies in AOE.

// Setup Part
globals
    // The Rawcode of the ability (Press Ctrl + D in object editor to show/hide rawcodes)
    private constant integer ABILITY_ID = 'A000'
    
    // The timer Interval (increase if laggs ingame)
    private constant real INTERVAL = 0.01
    
    // The amount the speed changes each interval (a amount nearer to 0 will make the unit raise higher before falling)
    private constant real GRAVITY = -9.81 * INTERVAL  
    
    // The attacktype with which the units in the AOE are damaged
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
    
    // The damagetype with which the units in the AOE are damaged
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
    
    // The weapontype with which the units in the AOE are damaged
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
    
    // The effect created when the target crushes down on the ground
    private constant string CRUSH_EFFECT = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
    
    // The effect created when the target reached the sky
    private constant string LIGHTNING_EFFECT = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
    
    // The Effect created when a lightning effect hits
    private constant string DAMAGE_EFFECT = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
    
    // The Effect created when the AOE damage is dealt
    private constant string AOE_DAMAGE_EFFECT = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"  
    
    // The attachement point for all the effects
    private constant string EFFECT_ATTACH = "chest"
endglobals

// Returns the damage each unit in AOE takes
private function GetDamage takes integer level returns real
    return I2R(level) * 100
endfunction

// Returns the radius of the AOE
private function GetDamageRange takes integer level returns real
    return I2R(level) * 50 + 150
endfunction

// Returns the maximal distance the unit gets shaked relative to the units original position 
private function GetShakeRange takes integer level returns real
    return I2R(level) * 7
endfunction

//-----------Don't modify anything below this line---------

private struct data
    unit u
    unit d
    real z = 0
    real x
    real y
    real Vz     
    integer t = 0
    integer t2 = 0
    integer phase = 1
    timer tim = CreateTimer()
    integer lvl
endstruct

globals
    private hashtable h = InitHashtable()
    private group g = CreateGroup()
    private data temp
endglobals

private function FriendsOnly takes nothing returns boolean
    return IsUnitAlly(GetFilterUnit(),GetOwningPlayer(temp.u)) and not (IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) or GetUnitTypeId(GetFilterUnit()) == 0 )
endfunction

private function DamageGroup takes nothing returns nothing
    call UnitDamageTarget(temp.d, GetEnumUnit(), GetDamage(temp.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
    call DestroyEffect(AddSpecialEffectTarget(AOE_DAMAGE_EFFECT, GetEnumUnit(), EFFECT_ATTACH))
endfunction

private function execute takes nothing returns nothing
    local data dat = LoadInteger(h,GetHandleId(GetExpiredTimer()),0)
    local real zz = dat.Vz
    if dat.phase == 1 then
        set dat.Vz = dat.Vz + GRAVITY                                                                          
        if dat.Vz <= 0 and zz > 0 then
            set dat.phase = 2
            set dat.t = R2I(0.1/INTERVAL) - 1
        endif
        set dat.z = dat.z + dat.Vz
        call SetUnitFlyHeight(dat.u,dat.z,0)
    elseif dat.phase == 2 then
        set dat.t = dat.t + 1
        if ModuloInteger(dat.t,2) == 0 then
            call SetUnitX(dat.u,GetRandomReal(dat.x-GetShakeRange(dat.lvl), dat.x+GetShakeRange(dat.lvl)))
            call SetUnitY(dat.u,GetRandomReal(dat.y-GetShakeRange(dat.lvl), dat.y+GetShakeRange(dat.lvl)))
        endif
        if dat.t == R2I(0.2/INTERVAL) then
            if dat.t2 == 6 then
                set dat.phase = 3
                call SetUnitPosition(dat.u,dat.x,dat.y)
                set dat.Vz = -20
            endif
            call DestroyEffect(AddSpecialEffectTarget(LIGHTNING_EFFECT, dat.u, EFFECT_ATTACH))
            call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, dat.u, EFFECT_ATTACH))
            set dat.t = 0
            set dat.t2 = dat.t2 + 1
        endif
    elseif dat.phase == 3 then
        set dat.Vz = dat.Vz + GRAVITY
        if dat.z <= 0 then
            set dat.phase = 4
            call DestroyEffect(AddSpecialEffect(CRUSH_EFFECT, dat.x, dat.y))
            call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, dat.u, EFFECT_ATTACH))
            set temp = dat
            call GroupEnumUnitsInRange(g,dat.x,dat.y,GetDamageRange(dat.lvl),Condition(function FriendsOnly))
            call UnitRemoveAbility(dat.u,'Avul')
            call ForGroup(g,function DamageGroup)
            call GroupClear(g)
        endif
        set dat.z = dat.z + dat.Vz
        call SetUnitFlyHeight(dat.u,dat.z,0)
    else
        call PauseUnit(dat.u,false)
        call PauseTimer(dat.tim)
        call DestroyTimer(dat.tim)
        call FlushChildHashtable(h,GetHandleId(dat.tim))
        call dat.destroy()
    endif
endfunction

private function cast takes nothing returns boolean
    local data dat
    if GetSpellAbilityId() == ABILITY_ID then
        set dat = data.create()
        set dat.u = GetSpellTargetUnit()
        set dat.d = GetTriggerUnit()
        call UnitAddAbility(dat.u,'Amrf')
        call UnitRemoveAbility(dat.u,'Amrf')
        call PauseUnit(dat.u, true)
        call UnitAddAbility(dat.u,'Avul')
        set dat.Vz = 8
        set dat.x = GetUnitX(dat.u)
        set dat.y = GetUnitY(dat.u)
        set dat.lvl = GetUnitAbilityLevel(dat.d, ABILITY_ID)
        call SaveInteger(h,GetHandleId(dat.tim),0,dat)
        call TimerStart(dat.tim,INTERVAL,true,function execute)
    endif
    return false
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t,Condition(function cast))
    call Preload(CRUSH_EFFECT)
    call Preload(LIGHTNING_EFFECT)
    call Preload(DAMAGE_EFFECT)
    call Preload(AOE_DAMAGE_EFFECT)
endfunction

endscope

Keywords:
spell, electricity, lightning, crush, aoe, vjass, group, damage, air, lift, unit
Contents

Noch eine WARCRAFT-III-Karte (Map)

Reviews
13:52, 4th Jan 2010 TriggerHappy: You never use the Location variable and the Attack/Weapon types should be configurable. But I think it's good enough to be approved but please do those suggestions.

Moderator

M

Moderator

13:52, 4th Jan 2010
TriggerHappy:

You never use the Location variable and the Attack/Weapon types should be configurable. But I think it's good enough to be approved but please do those suggestions.
 
Top