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

[vJass, JESP] Time Stop 1.3.2

Time Stop


Completely stops the time for all enemy units within
an area around the caster
100% Multi-User instancable and stacks properly
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯


This is my very first spell.
It follows the JESP standard and is written in vJass. In this spell I've focused more on a userfriendly and easy Setup section rather than optimization. For example, I added the function Pick() so that Targets() would take 'target' instead of GetFilterUnit() as an argument.
I didn't know that such a spell already existed in DotA when I started my work, so don't judge my creativity (which sucks, but I'm not a stealer).
And please, when reviewing my script don't tell me "use structs man, you suck". I don't know them yet, or at least when I'm writing this.

Ignore hvo-busterkomo's review. It was for 1.0 and alot has been changed in scripting since then.

Constructive feedback and critisism is most welcome :thumbs_up:
No credits is required when used in your map, though a shiny sphere would be nice.

This resource is frequently updated, whenever bugs are discovered or code improvement is found.
When you see that a new version is released, please tell me what you think about it. If you feel uncomfortable with reviving a spell (you can't really 'revive' a spell which has been updated...), you can PM me with opinions (actually, I want you to PM me with them).



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

Requirements
¯¯¯¯¯¯¯¯¯¯¯
- A vJass compiler (I recommend JassHelper by Vexorian, get it with Jass NewGen Pack)
- CSSafety
--- TimerUtils by Vexorian
--- GroupUtils by Rising_Dusk
- PauseUtils (Included in map. If possible replace with UnitToggling)

Credits
¯¯¯¯¯¯
* Flame_Phoenix; Teaching me vJass and helping me optimizing this spell
* Vexorian; Creating the TimerUtils system
* Rising_Dusk; Creating the GroupUtils system
* tomtefar1988 (not a Hive member); Showing me the neat special effect

Awards
- 103 Downloads the first 48 hours
- More than 1000 total downloads
- Was Newest Spell on hive for a long period (19 days counted so far)
- Record-fast import time of 2:56 (everything ready to use) on a moderatly sized map

__________________
Version 1.3.2
Made by Cheezeman
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

JASS:
//===========================================================================
//     
//                            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       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
1.3.2
- Added Jass version

1.3.1
- Removed an old debug call

1.3 - The new age
- Changed the AllowedTargets() so it would be easier to manipulate
- Remade the system so it now uses a public stack module instead of a private one
- Moved AllowedTargets() out of Advanced Functions section
- Renamed StackingCounter to ReferanceCounter
- Renamed setup function Range() to AreaOfEffect()

1.2 - The next generation
- Replaced the H2I and resized arrays with Hashtables
- Added a Advanced Setup section, which includes
--- AdditionalSpecialEffects() [removed the EFFECT_SCALE and EFFECT_FLY_HEIGHT global constants for this]
--- RevertTimeScale() [For special cases of maps]
--- AllowedTargets() [Units that can be affected]
--- PreloadAbility() [Anti first-time-lag]
- Added a trigger which resets a 'stopped' units animation speed if it's killed (trigger is automatically disabled when not used)
- Enhanced the spell with GroupUtils
- Added comments to the code
- Renamed SPECIAL_DUMMY_ID to EFFECT_DUMMY_ID
- Tweaked the header
- Changed import guide, aswell as added comment windows with additional information

1.1 - The timer era
- Replaced TriggerSleepAction() with timers (using TimerUtils)
- Replaced the FirstOfGroup() looping with ForGroup()
- Properly destroyed and cleaned the all[] group
- Changed the special effect's fly height speed to 0. instead or 90000.
- Made the Range() and Duration() functions constant
- Removed the two unnecessary GUI globals from the map
- Moved the first 5 test creeps slightly closer to the bridge

1.0 - Initial release
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

Now you're set. Enjoy.

* The 'triggers' refered to here are the trigger window objects in the map, but they are indeed not triggers.
This is the JESP standard document, if a map contains this document it means that there are
spells that follow this standard.

Spells of this map that follow the standard:
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- Time Stop

Advantages of the Standard
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- Implementing spells that follow the standard is relatively easier than implementing JASS
spells that don't follow the standard.

- Configuring/Balancing spells that follow the standard is relatively easier than
implementing JASS spells that don't follow the standard.

- Users may do the following procedure to make a new ability that uses the spell's script :

* Create a new Trigger with a name (case sensitive)
* Convert that trigger to custom text.
* Copy the spell's script to a text editor like Notepad or your OS equivalent.
* Replace the spell's Code name with the name you used on the trigger.
* Copy the new text to the new trigger
* Duplicate the Spell's original objects to have new ones for the new spell script.

You are now able to use that new version of the spell.

- In case two guys give the same name to 2 different spells, there are no conflict problems
because you can easily change the name of one of them

What is the JESP Standard?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
The JESP standard was designed to make spell sharing much better. And to make sure JASS
enhanced spells follow a rule, to prevent chaos.

What does JESP Standard stands for?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
JASS
Enhanced
Spell
Pseudotemplate

Requirements for a spell to follow the JESP Standard
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- The spell is written in JASS
- The spell is 100% multi instanceable.
- The spell script is ready to support spells of any number of levels.
(default config header is not required to support all of them)

- The Spell has a specific code name.

- The Spell's trigger must have the spell's codename as name

- The Spell's InitTrig function must be named: InitTrig_<CodeName>

- The spell has a configuration header.

- It is mandatory that rawcodes of objects are configurable in the header.

- All the spell's specific code is inside the spell's "Trigger" (Trigger== that custom text
slot that world editor calls Trigger, the spell may use as many 'trigger' OBJECTS as needed)

- Every spell-specific single identifier or key works in such a way that reproducing the
spell's trigger but after performing a text-replace of codename with another name (and thus
renaming the cloned trigger to the new code name) it won't cause compile errors / conflicts
when playing the map.

- There is no code inside the spell's "Trigger" that is not specific to the spell.

- There are no requirements for GUI variables that are specific to the spell. If a system
used by the spell requires GUI variables the code for the system must be outside the "Trigger"

- Eyecandy and spell's balance have to be easy to configure

- The name of the author should be included in the spell's script.

- The reason to exist of this standard is spell sharing. This document should be included
within the map. And it should specify which spell follows the standard, in the top list.
JASS:
//===========================================================================
//     
//                            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
Hidden text: #332c29 Hidden quote: #222222

Keywords:
Cheezeman, JESP, Time, Stop, Time Stop, Chronosphere, DotA
Contents

Time Stop 1.3 (Map)

Reviews
19:00, 28th Jun 2009 hvo-busterkomo: Coding: 2/5 Decent coding, although I still have my complaints. 1. You don't need to use a ridiculously large integer to create a instant height change. 0 will set to the specified height instantly. 2. Your...
Level 6
Joined
Jun 15, 2008
Messages
175
Pathetic use of another systems for spell

IF you use JGNP, you can easy write same spell with STRUCTS and it will not require all these tons of systems.

It's all about code...

OMG, i looked trough code, that's very bad.... 0/5 for code

[Off-Topic] I really must say, you most certainly managed to aggro me ><. You're being way to negative, with no real critisicm, just that it sucks... what can Cheezeman use it for? I haven't seen you make any spell at all, all I could find in your resources was a map, that was not very well rated.

I woulden't know about the coding, but it seems like a nice spell, and so what if it's a warstomp with other effects, if you have this you could easily improve it as someone suggested, by making units stop when entering the bubble, plus warstomp stuns the units and giving the stun animation, this keeps the animation they had while being stunned - I like it :)
 
Level 10
Joined
Aug 19, 2008
Messages
491
Hey, good point... But the balance wouldn't match Blizzard's design.
Then again, no one really cares about that anymore, so it'll be equal.

For 1.3
3: Gonna make it optional to target ground or no target (pretty easy but it's gonna have to wait for 1.3)
4: Make some mathmatical function that changes the bubble's size according to Area (only works for current effect)

And I'm glad you still read this Deuterium :grin:
 
Level 1
Joined
Feb 8, 2009
Messages
7
It's a beauty, sadly I don't know enough to criticize the spell. I can only say that I love it.
 
Level 2
Joined
Jan 26, 2009
Messages
13
I have some problem with this line
call PauseUnit( gg_unit_h002_0022, false )
what do this line?
 
Level 10
Joined
Aug 19, 2008
Messages
491
If you really want me to, I can make a Jass version (it's not that hard) but it'd be alot better if you got vJass instead.
Did you try running the program even if it said some DLL files were viruses? It worked for me, probably because I don't use UMSWE or ReinventingTheCraft
 
Level 10
Joined
Aug 19, 2008
Messages
491
All you need to know and change is in the header, in which you can set all your values and balance the spell.
Only hard thing I can think of is SPELL_ID, DUMMY_ID etc. Just copy the dummy unit as I said, and hit Ctrl+D in the object editor to see the rawcode (id) of the unit and then put it in the field (SPELL_ID = 'A000').

I'll update this thread (and this post too) when I've added a jass version

Edit: Yep, updated.
 
Last edited:
Top