Name | Type | is_array | initial_value |
TimeStop__Bugfix | trigger | No | |
TimeStop__DUMMY_ID | integer | No | |
TimeStop__EFFECT_DUMMY_ID | integer | No | |
TimeStop__Hash | hashtable | No | |
TimeStop__RefCount | integer | No | |
TimeStop__SPELL_ID | integer | No | |
TimeStop__TempCast | unit | No |
//TESH.scrollpos=54
//TESH.alwaysfold=0
//===========================================================================
//
// Time Stop
//
// Stops the time for all enemy units within
// an area around the caster
// Does not target magic immune or mechanical units
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
// Import
// ¯¯¯¯¯¯
// Copy and paste these triggers* to your map:
// - Time Stop
// - TimerUtils
// - GroupUtils
// - PauseUtils
// Copy and paste these objects to your map:
// - Abilities\\SPELL_ID
// - Units\\EFFECT_DUMMY_ID
// - Units\\DUMMY_ID
// Make sure the Setup section contains all the correct rawcodes:
// - SPELL_ID
// - DUMMY_ID
// - EFFECT_DUMMY_ID
//
// * Trigger window objects
//
//
// Pros and Cons
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// [+] Follows the JESP standard (document included in this map)
// [+] Fully customizable in a clear Setup section
// [+] 100% Multi User Instancable
// [+] Easy to import with no configuration problems
// [+] Neat special effect with lots of customization
// [+] Should be leakless, though one can never be sure
// [-] Requires an additional unit
// [-] Special effect settings outside the Setup section
// [-] If you use other spells with the PauseUnit() native,
// you have to replace it with PauseUnitEx() or Time Stop
// will cause bugs
//
//
// For more information please check out this map's documentation folder,
// or - if you found it in a public map - the official upload page:
// hiveworkshop.com/forums/spells-569/vjass-jesp-time-stop-1-2-a-133719/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
//
// ____________________
// I Version 1.3.2 I
// I Made by Cheezeman I
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
//===========================================================================
scope TimeStop initializer Initialize
//===========================================================================
//=============================== SETUP =====================================
//===========================================================================
globals
private constant integer SPELL_ID = 'A000' //The rawcode of the spell the Hero uses
private constant integer DUMMY_ID = 'h000' //The rawcode of the normal dummy unit (used for preload)
private constant integer EFFECT_DUMMY_ID = 'h003' //The rawcode of the special effect dummy unit
//NOTE: To change the special effect, open the EFFECT_DUMMY_ID inside the Object Editor and change "Art - Model File"
endglobals
private constant function Duration takes integer level returns real
return 3. + ( 2. * level ) //The duration of the spell
endfunction
private constant function AreaOfEffect takes integer level returns real
return 150. + ( 150. * level ) //The area the spell affects
endfunction
private function AllowedTargets takes unit caster, unit target returns boolean
//These are the conditions the target must meet.
//If you want to add more, simply copy a line, paste it inside the block
//and modify it to a statement.
return /*
//==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== //The target...
*/ IsUnitEnemy( target, GetOwningPlayer( caster ) ) and /* //- must be an enemy
*/ GetWidgetLife( target ) > 0.405 and /* //- must be alive
*/ IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false and /* //- mustn't be magic immune
*/ IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false and /* //- mustn't be a structure
*/ IsUnitType( target, UNIT_TYPE_MECHANICAL ) == false and /* //- mustn't be mechanical
//==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
*/ true
endfunction
//========================== Advanced Setup =========================
//======= These functions are for 'advanced' Jass/vJass users =======
private function AdditionalSpecialEffects takes unit Effect, real casters_current_height returns nothing
call SetUnitScale( Effect, 2., 2., 2. )
call SetUnitFlyHeight( Effect, casters_current_height + 100., 0. )
//Here you can tweak the special effect even more.
//You can colorize it, make it move, spin and lots of other things
//(the 'effect' is a unit, so it has all the options a normal unit has)
endfunction
private function RevertTimeScale takes unit target returns nothing
call SetUnitTimeScale( target, 1. )
//If your map already utilize the TimeScale for other purposes,
//you can add an If/Then/Else statement to revert its TimeScale
//to the one it had before ('original' TimeScale)
endfunction
private function PreloadTimeStop takes nothing returns nothing
set bj_lastCreatedUnit = CreateUnit( Player( 15 ), DUMMY_ID, 0, 0, 0 )
call UnitAddAbility( bj_lastCreatedUnit, SPELL_ID )
call KillUnit( bj_lastCreatedUnit )
//This is the preload the ability is using.
//If you're using xe in your map, just replace this with XE_PreloadAbility(SPELL_ID)
//(or whatever the function is named)
//Before I get any stupid comments on these lines, note that bj_ variables are not
//evil. Only BJ >>Functions<< are evil.
endfunction
//===========================================================================
//============================= END SETUP ===================================
//================ Don't mess with the code below this line =================
//===========================================================================
globals
private hashtable Hash
private unit TemporareCaster
private boolexpr Target_Checker
private boolexpr DummyFilter
private trigger BugfixTrigger
private integer ReferanceCounter = 0
endglobals
//===========================================================================
private function Pick takes nothing returns boolean
return AllowedTargets( TemporareCaster, GetFilterUnit() )
endfunction
private constant function AntiLeakFilter takes nothing returns boolean
return true
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Bugfix_Conditions takes nothing returns boolean
return LoadInteger( Hash, 1, GetHandleId( GetTriggerUnit() ) ) > 0
endfunction
//============================ Main script ==================================
private function PauseTargets takes nothing returns nothing
local unit enum = GetEnumUnit()
call SaveInteger( Hash, 1, GetHandleId( enum ), LoadInteger( Hash, 1, GetHandleId( enum ) ) + 1 )
call PauseUnitEx( enum, true )
call SetUnitTimeScale( enum, 0. )
set enum = null
endfunction
private function UnpauseTargets takes nothing returns nothing
local unit enum = GetEnumUnit()
local integer enum_id = GetHandleId( enum )
//Although it uses PauseUtils, it still requires to check if it should reset time scale
call PauseUnitEx( enum, false )
call SaveInteger( Hash, 1, enum_id, LoadInteger( Hash, 1, enum_id ) - 1 )
if LoadInteger( Hash, 1, enum_id ) <= 0 then
call RemoveSavedInteger( Hash, 1, enum_id )
call RevertTimeScale( enum )
endif
set enum = null
endfunction
private function ActionsContinued takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer t_dat = GetHandleId( t )
call ForGroup( LoadGroupHandle( Hash, 2, t_dat ), function UnpauseTargets )
call SetUnitTimeScale( LoadUnitHandle( Hash, 3, t_dat ), 5. )
set ReferanceCounter = ReferanceCounter - 1
if ReferanceCounter <= 0. then
set ReferanceCounter = 0
call DisableTrigger( BugfixTrigger )
endif
call ReleaseGroup( LoadGroupHandle( Hash, 2, t_dat ) )
call ReleaseTimer( t )
call RemoveSavedHandle( Hash, 2, t_dat )
call RemoveSavedHandle( Hash, 3, t_dat )
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local integer caster_id = GetHandleId( caster )
local real casterX = GetUnitX( caster )
local real casterY = GetUnitY( caster )
local integer level = GetUnitAbilityLevel( caster, SPELL_ID )
local real duration = Duration( level )
local real caster_fly = GetUnitFlyHeight( caster )
local timer t = NewTimer()
local unit dummy = CreateUnit( GetOwningPlayer( caster ), EFFECT_DUMMY_ID, casterX, casterY, 0.00 )
local group g = NewGroup()
set TemporareCaster = caster
set ReferanceCounter = ReferanceCounter + 1
call EnableTrigger( BugfixTrigger )
call SaveUnitHandle( Hash, 3, caster_id, dummy )
call AdditionalSpecialEffects( dummy, caster_fly )
call UnitApplyTimedLife( dummy, 'BTLF', duration )
call SetUnitTimeScale( dummy, 1. / duration )
call GroupEnumUnitsInRange( g, casterX, casterY, AreaOfEffect( level ), Target_Checker )
call SaveGroupHandle( Hash, 2, GetHandleId( t ), g )
call ForGroup( g, function PauseTargets )
call TimerStart( t, duration, false, function ActionsContinued )
set caster = null
set dummy = null
set t = null
set g = null
endfunction
private function Bugfix_Actions takes nothing returns nothing
call RevertTimeScale( GetTriggerUnit() )
endfunction
//============================= Initialze ===================================
private function Initialize takes nothing returns nothing
local integer ForLoop = 0
local trigger spell = CreateTrigger()
set BugfixTrigger = CreateTrigger()
set Target_Checker = Condition( function Pick )
set DummyFilter = Condition( function AntiLeakFilter )
set Hash = InitHashtable()
call DisableTrigger( BugfixTrigger )
call PreloadTimeStop()
loop
exitwhen ForLoop > 15
call TriggerRegisterPlayerUnitEvent( spell, Player(ForLoop), EVENT_PLAYER_UNIT_SPELL_EFFECT, DummyFilter )
call TriggerRegisterPlayerUnitEvent( BugfixTrigger, Player( ForLoop ), EVENT_PLAYER_UNIT_DEATH, DummyFilter )
set ForLoop = ForLoop + 1
endloop
call TriggerAddCondition( spell, Condition( function Conditions ) )
call TriggerAddAction( spell, function Actions )
call TriggerAddCondition( BugfixTrigger, Condition( function Bugfix_Conditions ) )
call TriggerAddAction( BugfixTrigger, function Bugfix_Actions )
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library_once TimerUtils initializer init
//*********************************************************************
//* TimerUtils (Blue flavor for 1.23b or later)
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Blue Flavor: Slower than the red flavor, it got a 408000 handle id
//* limit, which means that if more than 408000 handle ids
//* are used in your map, TimerUtils might fail, this
//* value is quite big and it is much bigger than the
//* timer limit in Red flavor.
//*
//********************************************************************
//==================================================================================================
globals
private hashtable hasht //I <3 blizz
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
call SaveInteger(hasht,0, GetHandleId(t), value)
endfunction
function GetTimerData takes timer t returns integer
return LoadInteger(hasht, 0, GetHandleId(t))
endfunction
//==========================================================================================
globals
private timer array tT
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
set tT[0]=CreateTimer()
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
set hasht = InitHashtable()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GroupUtils
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This library is a simple implementation of a stack for groups that need to
//* be in the user's control for greater than an instant of time. Additionally,
//* this library provides a single, global group variable for use with user-end
//* enumerations. It is important to note that users should not be calling
//* DestroyGroup() on the global group, since then it may not exist for when it
//* it is next needed.
//*
//* The group stack removes the need for destroying groups and replaces it with
//* a recycling method.
//* function NewGroup takes nothing returns group
//* function ReleaseGroup takes group g returns boolean
//* function GroupRefresh takes group g returns nothing
//*
//* NewGroup grabs a currently unused group from the stack or creates one if the
//* stack is empty. You can use this group however you'd like, but always
//* remember to call ReleaseGroup on it when you are done with it. If you don't
//* release it, it will 'leak' and your stack may eventually overflow if you
//* keep doing that.
//*
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hash table. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it.
//*
globals
//* Group for use with all instant enumerations
group ENUM_GROUP = CreateGroup()
//* Temporary references for GroupRefresh
private boolean Flag = false
private group Refr = null
//* Assorted constants
private constant integer MAX_HANDLE_COUNT = 408000
private constant integer MIN_HANDLE_ID = 0x100000
//* Arrays and counter for the group stack
private group array Groups
private integer array Status[MAX_HANDLE_COUNT]
private integer Count = 0
endglobals
private function AddEx takes nothing returns nothing
if Flag then
call GroupClear(Refr)
set Flag = false
endif
call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
set Flag = true
set Refr = g
call ForGroup(Refr, function AddEx)
if Flag then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if Count == 0 then
set Groups[0] = CreateGroup()
else
set Count = Count - 1
endif
set Status[GetHandleId(Groups[Count])-MIN_HANDLE_ID] = 1
return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
local integer stat = Status[GetHandleId(g)-MIN_HANDLE_ID]
local boolean b = true
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Null groups cannot be released")
set b = false
elseif stat == 0 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Group not part of stack")
set b = false
elseif stat == 2 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Groups cannot be multiply released")
set b = false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Max groups achieved, destroying group")
call DestroyGroup(g)
set b = false
else
call GroupClear(g)
set Groups[Count] = g
set Count = Count + 1
set Status[GetHandleId(g)-MIN_HANDLE_ID] = 2
endif
return b
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
//==
//== PauseUtils
//== ¯¯¯¯¯¯¯¯¯¯¯
//== Written by Cheezeman
//==
//== This module is an off-spring of StackingUtils, I just made it smaller
//== for TimeStop.
//== It lets you pause and unpause a unit just like normally,
//== but without having to worry about the stacking issues
//== with normal PauseUnit() (where you can pause a unit a million times
//== but only one unpause is sufficient)
//==
//== call PauseUnitEx( unit whichUnit, boolean flag )
//== True pauses the unit like normally, while false atempts to
//== unpause the unit, which isn't possible if the unit is affected
//== by other pauses (a.k.a. its pause-referance is not 0)
//==
//== ____________________
//== I Version 1.0 I
//== I Made by Cheezeman I
//== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//===========================================================================
library PauseUtils initializer Init
globals
private hashtable Hash
endglobals
function PauseUnitEx takes unit u, boolean flag returns nothing
local integer i = LoadInteger( Hash, 0, GetHandleId( u ) )
if flag then
if i == 0 then
call PauseUnit( u, true )
endif
call SaveInteger( Hash, 0, GetHandleId( u ), i + 1 )
else
call SaveInteger( Hash, 0, GetHandleId( u ), i - 1 )
if i - 1 <= 0 then
call RemoveSavedInteger( Hash, 0, GetHandleId( u ) )
call PauseUnit( u, false )
endif
endif
endfunction
private function Init takes nothing returns nothing
set Hash = InitHashtable()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
//
// Time Stop
// [Jass version]
//
// Stops the time for all enemy units within
// an area around the caster
// Does not target magic immune or mechanical units
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
// Import
// ¯¯¯¯¯¯
// - Copy this trigger* (only this trigger) to your map
// - Copy and paste these objects to your map:
// Abilities\\udg_TimeStop__SPELL_ID
// Units\\udg_TimeStop__EFFECT_DUMMY_ID
// Units\\udg_TimeStop__DUMMY_ID
// - Create these variables in your map:
// [Name] [Type]
// TimeStop__Bugfix trigger
// TimeStop__DUMMY_ID integer
// TimeStop__EFFECT_DUMMY_ID integer
// TimeStop__Hash hashtable
// TimeStop__RefCount integer
// TimeStop__SPELL_ID integer
// TimeStop__TempCast unit
// //You may rename these later, as long as the first time you
// //create them they have these names.
// - Make sure the Setup section contains all the correct rawcodes:
// udg_TimeStop__SPELL_ID
// udg_TimeStop__DUMMY_ID
// udg_TimeStop__EFFECT_DUMMY_ID
// - If you get a compile error, make sure the name of this trigger is "TimeStop Jass"
// You can rename it after you've saved.
//
// * Trigger window object
//
//
// Pros and Cons
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// [+] Follows the JESP standard (document included in this map)
// [+] Fully customizable in a clear Setup section
// [+] 100% Multi User Instancable
// [+] Easy to import with no configuration problems
// [+] Neat special effect with lots of customization
// [+] Should be leakless, though one can never be sure
// [-] Requires an additional unit
// [-] Special effect settings outside the Setup section
// [-] If you use other spells with the PauseUnit() native,
// this spell will cause bugs.
//
//
// For more information please check out this map's documentation folder,
// or - if you found it in a public map - the official upload page:
// hiveworkshop.com/forums/spells-569/vjass-jesp-time-stop-1-2-a-133719/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
//
// ____________________
// I Version 1.3.2 I
// I Made by Cheezeman I
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
//===========================================================================
//===========================================================================
//=============================== SETUP =====================================
//===========================================================================
function TimeStop__Setup takes nothing returns nothing
set udg_TimeStop__SPELL_ID = 'A000' //The rawcode of the spell the Hero uses
set udg_TimeStop__DUMMY_ID = 'h000' //The rawcode of the normal dummy unit (used for preload)
set udg_TimeStop__EFFECT_DUMMY_ID = 'h003' //The rawcode of the special effect dummy unit
endfunction
constant function TimeStop__Duration takes integer level returns real
return 3. + ( 2. * level ) //The duration of the spell
endfunction
constant function TimeStop__AreaOfEffect takes integer level returns real
return 150. + ( 150. * level ) //The area the spell affects
endfunction
function TimeStop__AllowedTargets takes unit caster,unit target returns boolean
local boolean b = true
//These are the conditions the target must meet.
//If you want to add more, simply copy a line, paste it inside the block
//and modify it to a statement.
set b = b and IsUnitEnemy(target , GetOwningPlayer(caster))
set b = b and GetWidgetLife(target) > 0.405
set b = b and IsUnitType(target , UNIT_TYPE_MAGIC_IMMUNE) == false
set b = b and IsUnitType(target , UNIT_TYPE_STRUCTURE) == false
set b = b and IsUnitType(target , UNIT_TYPE_MECHANICAL) == false
return b
endfunction
//========================== Advanced Setup =========================
//======= These functions are for 'advanced' Jass/vJass users =======
function TimeStop__AdditionalSpecialEffects takes unit Effect,real casters_current_height returns nothing
call SetUnitScale(Effect , 2. , 2. , 2.)
call SetUnitFlyHeight(Effect , casters_current_height + 100. , 0.)
//Here you can tweak the special effect even more.
//You can colorize it, make it move, spin and lots of other things
//(the 'effect' is a unit, so it has all the options a normal unit has)
endfunction
function TimeStop__RevertTimeScale takes unit target returns nothing
call SetUnitTimeScale(target , 1.)
//If your map already utilize the TimeScale for other purposes,
//you can add an If/Then/Else statement to revert its TimeScale
//to the one it had before ('original' TimeScale)
endfunction
function TimeStop__PreloadTimeStop takes nothing returns nothing
set bj_lastCreatedUnit = CreateUnit(Player(15) , udg_TimeStop__DUMMY_ID , 0 , 0 , 0)
call UnitAddAbility(bj_lastCreatedUnit , udg_TimeStop__SPELL_ID)
call KillUnit(bj_lastCreatedUnit)
//This is the preload the ability is using.
//If you're using xe in your map, just replace this with XE_PreloadAbility(SPELL_ID)
//(or whatever the function is named)
//Before I get any stupid comments on these lines, note that bj_ variables are not
//evil. Only BJ >>Functions<< are evil.
endfunction
//===========================================================================
//============================= END SETUP ===================================
//================ Don't mess with the code below this line =================
//===========================================================================
function TimeStop__Pick takes nothing returns boolean
return TimeStop__AllowedTargets(udg_TimeStop__TempCast , GetFilterUnit())
endfunction
function TimeStop__Conditions takes nothing returns boolean
return GetSpellAbilityId() == udg_TimeStop__SPELL_ID
endfunction
function TimeStop__Bugfix_Conditions takes nothing returns boolean
return LoadInteger(udg_TimeStop__Hash , 1 , GetHandleId(GetTriggerUnit())) > 0
endfunction
//============================ Main script ==================================
function TimeStop__PauseTargets takes nothing returns nothing
local unit enum= GetEnumUnit()
call SaveInteger(udg_TimeStop__Hash , 1 , GetHandleId(enum) , LoadInteger(udg_TimeStop__Hash , 1 , GetHandleId(enum)) + 1)
call PauseUnit(enum , true)
call SetUnitTimeScale(enum , 0.)
set enum = null
endfunction
function TimeStop__UnpauseTargets takes nothing returns nothing
local unit enum= GetEnumUnit()
local integer enum_id= GetHandleId(enum)
call SaveInteger(udg_TimeStop__Hash , 1 , enum_id , LoadInteger(udg_TimeStop__Hash , 1 , enum_id) - 1)
if LoadInteger(udg_TimeStop__Hash , 1 , enum_id) <= 0 then
call RemoveSavedInteger(udg_TimeStop__Hash , 1 , enum_id)
call TimeStop__RevertTimeScale(enum)
call PauseUnit(enum , false)
endif
set enum = null
endfunction
function TimeStop__ActionsContinued takes nothing returns nothing
local timer t= GetExpiredTimer()
local integer t_dat= GetHandleId(t)
call ForGroup(LoadGroupHandle(udg_TimeStop__Hash , 2 , t_dat) , function TimeStop__UnpauseTargets)
call SetUnitTimeScale(LoadUnitHandle(udg_TimeStop__Hash , 3 , t_dat) , 5.)
set udg_TimeStop__RefCount = udg_TimeStop__RefCount - 1
if udg_TimeStop__RefCount <= 0. then
set udg_TimeStop__RefCount = 0
call DisableTrigger(udg_TimeStop__Bugfix)
endif
call DestroyGroup(LoadGroupHandle(udg_TimeStop__Hash , 2 , t_dat))
call DestroyTimer(t)
call RemoveSavedHandle(udg_TimeStop__Hash , 2 , t_dat)
call RemoveSavedHandle(udg_TimeStop__Hash , 3 , t_dat)
set t = null
endfunction
function TimeStop__Actions takes nothing returns nothing
local unit caster= GetTriggerUnit()
local integer caster_id= GetHandleId(caster)
local real casterX= GetUnitX(caster)
local real casterY= GetUnitY(caster)
local integer level= GetUnitAbilityLevel(caster , udg_TimeStop__SPELL_ID)
local real duration= TimeStop__Duration(level)
local real caster_fly= GetUnitFlyHeight(caster)
local timer t= CreateTimer()
local unit dummy= CreateUnit(GetOwningPlayer(caster) , udg_TimeStop__EFFECT_DUMMY_ID , casterX , casterY , 0.00)
local group g= CreateGroup()
local boolexpr b= Condition(function TimeStop__Pick)
set udg_TimeStop__TempCast = caster
set udg_TimeStop__RefCount = udg_TimeStop__RefCount + 1
call EnableTrigger(udg_TimeStop__Bugfix)
call SaveUnitHandle(udg_TimeStop__Hash , 3 , caster_id , dummy)
call TimeStop__AdditionalSpecialEffects(dummy , caster_fly)
call UnitApplyTimedLife(dummy , 'BTLF' , duration)
call SetUnitTimeScale(dummy , 1. / duration)
call GroupEnumUnitsInRange(g , casterX , casterY , TimeStop__AreaOfEffect(level) , b)
call SaveGroupHandle(udg_TimeStop__Hash , 2 , GetHandleId(t) , g)
call ForGroup(g , function TimeStop__PauseTargets)
call TimerStart(t , duration , false , function TimeStop__ActionsContinued)
set caster = null
set dummy = null
set t = null
set g = null
endfunction
function TimeStop__Bugfix_Actions takes nothing returns nothing
call TimeStop__RevertTimeScale(GetTriggerUnit())
endfunction
//============================= Initialze ===================================
function InitTrig_TimeStop_Jass takes nothing returns nothing
local integer ForLoop= 0
local trigger spell= CreateTrigger()
call TimeStop__Setup()
set udg_TimeStop__Bugfix = CreateTrigger()
set udg_TimeStop__Hash = InitHashtable()
call DisableTrigger(udg_TimeStop__Bugfix)
call TimeStop__PreloadTimeStop()
loop
exitwhen ForLoop > 15
call TriggerRegisterPlayerUnitEvent(spell , Player(ForLoop) , EVENT_PLAYER_UNIT_SPELL_EFFECT , null )
call TriggerRegisterPlayerUnitEvent(udg_TimeStop__Bugfix , Player(ForLoop) , EVENT_PLAYER_UNIT_DEATH , null)
set ForLoop = ForLoop + 1
endloop
call TriggerAddCondition(spell , Condition(function TimeStop__Conditions))
call TriggerAddAction(spell , function TimeStop__Actions)
call TriggerAddCondition(udg_TimeStop__Bugfix , Condition(function TimeStop__Bugfix_Conditions))
call TriggerAddAction(udg_TimeStop__Bugfix , function TimeStop__Bugfix_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Revive initializer Init
private function Conditions takes nothing returns boolean
return IsUnitType( GetTriggerUnit(), UNIT_TYPE_HERO )
endfunction
private function Actions takes nothing returns nothing
local unit rev = GetTriggerUnit()
local player p = GetOwningPlayer( rev )
local real locX
local real locY
call ReviveHeroLoc( rev, GetPlayerStartLocationLoc( p ), true )
set locX = GetUnitX( rev )
set locY = GetUnitY( rev )
call PanCameraToForPlayer( p, locX, locY )
set rev = null
set p = null
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Initialize initializer Init
//===========================================================================
globals
private constant integer HERO_ID = 'H001'
endglobals
//===========================================================================
private function Actions takes nothing returns nothing
local integer p = 0
local location loc
local real locX
local real locY
local unit hero
local unit dummy
loop
exitwhen ( p == 12 )
set loc = GetPlayerStartLocationLoc( Player( p ) )
set locX = GetLocationX( loc )
set locY = GetLocationY( loc )
if ( GetPlayerController( Player( p ) ) == MAP_CONTROL_USER ) and ( GetPlayerSlotState( Player( p ) ) == PLAYER_SLOT_STATE_PLAYING ) then
set hero = CreateUnit( Player(p), HERO_ID, locX, locY, 0.00 )
call SetHeroLevel( hero, 10, false )
endif
set p = p + 1
endloop
call SetTimeOfDay( 12 )
call TriggerSleepAction( 5. )
call RemoveLocation( loc )
set loc = null
set p = 0
set locX = 0.
set locY = 0.
set hero = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterTimerEventSingle( trg, 0.05 )
call TriggerAddAction( trg, function Actions )
set trg = null
endfunction
endscope