//============================================================================
//== ==
//== Space Trap v1.3 ==
//== Created by Cheezeman @ hiveworkshop.com ==
//== ==
//== Stops the time for all units in a certain area around the caster. ==
//== ==
//== This spell isn't fully developed, it has some bugs and so. ==
//== That's why I don't spend more time on a header ==
//== ==
//============================================================================
scope SpaceTrap initializer Init
//===========================================================================
//=============================== SETUP =====================================
//===========================================================================
globals
private constant integer SPELL_ID = 'A000'
//The rawcode of the blank active Hero spell.
//To detect a Rawcode you must go to object editor, select the object - in this case
//the ability - and hit Ctrl + D.
//Only the four first letters are required.
private constant integer DUMMY_ID = 'h000'
//The rawcode of the normal dummy unit, used for preload.
private constant integer SPECIAL_DUMMY_ID = 'h003'
//The rawcode of the special effect dummy unit.
private constant real EFFECT_SCALE = 2.
//Sets the scale of the special effect, were 1. is normal.
//Don't forget the . in the end!
endglobals
private function Duration takes integer level returns real
return 3. + ( 2. * level )
//The duration of the spell. Remember the . at the end
endfunction
private function Range takes integer level returns real
return 150. + ( 150. * level )
//The range of the spell. Remember the . at the end!
endfunction
private function Targets takes unit caster, unit target returns boolean
return ( IsUnitType( target, UNIT_TYPE_HERO ) == false ) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false) and IsUnitEnemy( target, GetOwningPlayer( caster ) ) and ( GetWidgetLife( target ) > 0.405 ) and ( IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false)
//These are the targets the spell will affect. For example, it won't affect dead or magic immune targets.
//Because many people might wish to change Mechanical and Hero, I've added them first.
endfunction
//===========================================================================
//============================= END SETUP ===================================
//===========================================================================
globals
private boolexpr b
private group all
private unit tempCaster
endglobals
//===========================================================================
private function Pick takes nothing returns boolean
return Targets( tempCaster, GetFilterUnit() )
endfunction
//===========================================================================
//This function was made by Blade_dk. Visit [url]www.wc3c.com[/url] for more info.
private function CopyGroup takes group g returns group
set bj_groupAddGroupDest = CreateGroup()
call ForGroup( g, function GroupAddGroupEnum )
return bj_groupAddGroupDest
endfunction
//===========================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
//===========================================================================
private function Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local player p = GetOwningPlayer( caster )
local unit f
local unit dummyEffect
local integer level = GetUnitAbilityLevel( caster, SPELL_ID )
local group copy = CreateGroup()
local real casterX = GetUnitX( caster )
local real casterY = GetUnitY( caster )
local integer unitData
local real duration = Duration( level )
set tempCaster = caster
//Adding the special effect.
set dummyEffect = CreateUnit( p, SPECIAL_DUMMY_ID, casterX, casterY, 0.00 )
call SetUnitScale( dummyEffect, EFFECT_SCALE, EFFECT_SCALE, EFFECT_SCALE )
call SetUnitFlyHeight( dummyEffect, 60., 90000. )
call UnitApplyTimedLife( dummyEffect, 'BTLF', duration )
call SetUnitTimeScale( dummyEffect, 1. / duration )
//Set the group. There are two groups, because I'm using 2 loops and GroupRemoveUnit()
call GroupEnumUnitsInRange( all, casterX, casterY, Range( level ), b )
set copy = CopyGroup( all )
//First loop. This one pauses all units, increases their custom value by 1
//and sets their animation speed to 0%
loop
set f = FirstOfGroup( all )
exitwhen f == null
set unitData = GetUnitUserData( f )
call GroupRemoveUnit( all, f )
call SetUnitUserData( f, unitData + 1 )
call PauseUnit( f, true )
call SetUnitTimeScale( f, 0. )
endloop
//The duration of the spell
call TriggerSleepAction( duration )
//Second loop. This reduces their custom values by 1, and if the
//value is = 0 it will unpause it and turn the animation speed back to 100%
//However, if it isn't 0 it means that it's in effect by another user, thus it will not unpause.
//This method is used so the spell can stack.
loop
set f = FirstOfGroup( copy )
exitwhen f == null
set unitData = GetUnitUserData( f ) - 1
call GroupRemoveUnit( copy, f )
call SetUnitUserData( f, unitData )
if unitData == 0 then
call PauseUnit( f, false )
call SetUnitTimeScale( f, 1. )
endif
endloop
//Cleanup
call SetUnitTimeScale( dummyEffect, 5. )
call DestroyGroup( copy )
set copy = null
set caster = null
set dummyEffect = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
//setting globals
set b = Condition( function Pick )
set all = CreateGroup()
//preloading ability
set bj_lastCreatedUnit = CreateUnit(Player( PLAYER_NEUTRAL_PASSIVE ), DUMMY_ID, 0, 0, 0)
call UnitAddAbility( bj_lastCreatedUnit, SPELL_ID )
call KillUnit( bj_lastCreatedUnit )
endfunction
endscope