[vJass, JESP] Time Stop 1.3.2

This bundle is marked as approved. It works and satisfies the submission rules.

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...

Moderator

M

Moderator

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 duration and range functions should be constant, and don't need the parentheses.
3. Instead of copying the group, and then looping through it twice you should just use a ForGroup(). Your CopyGroup() also leaks.
4. The H2I unit indexing along with the TriggerSleepAction is just awful (not to mention innacurate). You should instead use structs + timers + TimerUtils.
5. You could use the dummy.mdx and attach the special effect to it. It would be a lot better than requiring the use of the object editor.

Originality: 2/5
I've seen the effect before, although it's not extremely unoriginal.

Documentation: 5/5
Documentation was acceptable.

Overall = (Coding * 0.50) + (Originality * 0.30) + (Documentation * 0.20)
Overall: 2.85
Approved with a 3/5 (Useful) rating.
 
Level 10
Joined
Aug 19, 2008
Messages
492
I must say it's unoriginal... I'm checking the script now
(maybe you're updating this post now but I'll answer anyway)
Both yes and no.
Yes, in that sence it's very simple.
No, because I havn't seen it anywhere else.
And come on, wierd spells with a lot of twists are just confusing and often looks wierd. I like to make simple spells because they're a hell-of-alot more user friendly. Not that I mind coding strange and wierd spells, but spells should be simple and understandable (just like blizzard has designed theirs).
 
Level 10
Joined
Aug 19, 2008
Messages
492
I'm not saying spells have to be complex to be nice or original, but the well known DotA already has this spell and lready many people have done it...
Well I don't play dota, so I'm not sure that counts.

And ummm, script seems fine... I'm no Jass pro but I read it and it's well done
Why thank you :grin: I hope I didn't miss any leaks and so.
Oh and I should update the description saying that I focus more on having a good and userfriendly SETUP section rather than optimization.
(If you don't get what I mean, I for example added an extra function so the "Targets()" would take "target" instead of GetFilterUnit())
 
Level 14
Joined
Nov 18, 2007
Messages
815
  • Destroying groups leaks. You leak the initial value of copy, btw.
  • TSA doesnt pause when a player starts lagging.
  • Instead of 90000., you could use 0. for the fly-height-change-rate.
  • Use xefx for the effect.
  • Use Unit Indexing.
  • Maybe, instead of pausing stun the unit for the duration of the spell, and additionally black out the command card if you want/are able to (i think it only works for non-hero units).
  • There can be dead units with more than 0.405 HP
  • This spell doesnt follow the JESP standard (not that that makes any difference nowadays)
  • Wasnt there a module for xe for preloading abilities? Use that one.
 
Level 2
Joined
Jun 11, 2008
Messages
20
its hard to believe you would use the same special effect for the same spell that dota has without knowing it.
 
Level 10
Joined
Aug 19, 2008
Messages
492
Destroying groups leaks. You leak the initial value of copy, btw.
Good idea to change it... I didn't realize until now that my spell isn't instant (in which case it would be better to use 1 global variable)
TSA doesnt pause when a player starts lagging.
What is TSA?
Instead of 90000., you could use 0. for the fly-height-change-rate.
Hm... thank you, that would work as instant, right?
Use xefx for the effect.
No, the effect can't be slowed down when using a special effect
Use Unit Indexing.
What is that?
Maybe, instead of pausing stun the unit for the duration of the spell, and additionally black out the command card if you want/are able to (i think it only works for non-hero units)
So you suggest I spam the map with 20 instant create-dummy-and-cast-stun instead of letting the user add "IsUnitType(target, UNIT_TYPE_HERO) == false" himself?
No, I don't think so...
There can be dead units with more than 0.405 HP
Well, Flame_Phoenix told me that there are no dead units with more than .405 hp, and he's been using that statment for a long time without bugs (he's got a huge-ass rpg and it works fine)
This spell doesnt follow the JESP standard (not that that makes any difference nowadays)
Then tell me how it does not instead of stating that it does not.
Wasnt there a module for xe for preloading abilities? Use that one.
Yes there is, but I wanted it to be as self-sufficient as possible (without libraries). The preload is fine and doesn't lag (or leak), so if the user have this library he can preload it himself.

its hard to believe you would use the same special effect for the same spell that dota has without knowing it.
Look, I'm serious. I don't play Dota. At all.
If I would've known this spell existed I would've either said it in the description when I uploaded it, or wouldn't have made this at all.
I hearby swear on my very soul to God that I did not know there was a similar spell in DotA, or any other map, when I started making this.

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.
Right, I don't. It's on my change list now.
2. Your duration and range functions should be constant, and don't need the parentheses.
No. Constant functions will never change, and I want the area and duration to be dependant on the level of the skill. Oh and the parantheses are just for making it easier to manipulate though they're totally useless.
3. Instead of copying the group, and then looping through it twice you should just use a ForGroup(). Your CopyGroup() also leaks.
To pause all the units in my spell I'm using the "GroupRemoveUnit", and at the end my first group will be empty. If it's empty I cannot unpause them.
Hence the CopyGroup. Oh and I'd be glad if someone told me how to fix the leaks in it.
4. The H2I unit indexing along with the TriggerSleepAction is just awful (not to mention innacurate). You should instead use structs + timers + TimerUtils.
I don't know structs, but I might be able to pull it off with timers...
5. You could use the dummy.mdx and attach the special effect to it. It would be a lot better than requiring the use of the object editor.
I tried that, and it failed. Attaching a special effect to a unit, .mdx or normal dummy unit, still can't be slowed. The effect is still in the same time scale.
I made a topic on this here

I'll start working on it later today, right now I'm off to bed.
 
Level 17
Joined
Jun 17, 2007
Messages
1,433
Good idea to change it... I didn't realize until now that my spell isn't instant (in which case it would be better to use 1 global variable)
What is TSA?
Hm... thank you, that would work as instant, right?
No, the effect can't be slowed down when using a special effect
What is that?
So you suggest I spam the map with 20 instant create-dummy-and-cast-stun instead of letting the user add "IsUnitType(target, UNIT_TYPE_HERO) == false" himself?
No, I don't think so...
Well, Flame_Phoenix told me that there are no dead units with more than .405 hp, and he's been using that statment for a long time without bugs (he's got a huge-ass rpg and it works fine)
Then tell me how it does not instead of stating that it does not.
Yes there is, but I wanted it to be as self-sufficient as possible (without libraries). The preload is fine and doesn't lag (or leak), so if the user have this library he can preload it himself.

Look, I'm serious. I don't play Dota. At all.
If I would've known this spell existed I would've either said it in the description when I uploaded it, or wouldn't have made this at all.
I hearby swear on my very soul to God that I did not know there was a similar spell in DotA, or any other map, when I started making this.

Right, I don't. It's on my change list now.
No. Constant functions will never change, and I want the area and duration to be dependant on the level of the skill. Oh and the parantheses are just for making it easier to manipulate though they're totally useless.
To pause all the units in my spell I'm using the "GroupRemoveUnit", and at the end my first group will be empty. If it's empty I cannot unpause them.
Hence the CopyGroup. Oh and I'd be glad if someone told me how to fix the leaks in it.
I don't know structs, but I might be able to pull it off with timers...
I tried that, and it failed. Attaching a special effect to a unit, .mdx or normal dummy unit, still can't be slowed. The effect is still in the same time scale.
I made a topic on this here

I'll start working on it later today, right now I'm off to bed.
The functions are still constant. While the return value is technically different with each level, it will always be "level * 5 + 10", for example.

Oh, and about the group. With a ForGroup you can avoid removing the units in the first place.
 
Level 14
Joined
Nov 18, 2007
Messages
815
What is TSA?
TriggerSleepAction()

No, the effect can't be slowed down when using a special effect
I suggest you read up on xefx over at wc3c.net. You can slow down effects with xefx.

What is that?
You assign each unit a unique index in the range of 0-8190 without using H2I

So you suggest I spam the map with 20 instant create-dummy-and-cast-stun instead of letting the user add "IsUnitType(target, UNIT_TYPE_HERO) == false" himself?
No, I don't think so...
First of all, one dummy would be enough i imagine. Secondly, i think its a good choice gameplay-wise and blends well with other spells by blizzard.

Well, Flame_Phoenix told me that there are no dead units with more than .405 hp, and he's been using that statment for a long time without bugs (he's got a huge-ass rpg and it works fine)
And where exactly is the part that should convince me that its not a possible bug? Kill a unit and then heal it via triggers. The unit wont revive but instead GetWidgetLife() will now return some value above 0.405, potentially breaking your spell.

Then tell me how it does not instead of stating that it does not.
IIRC, it was something with InitTrig_*spellname* (possibly, there was even more). Like I said, it doesnt matter anyway.
 
Level 10
Joined
Aug 19, 2008
Messages
492
Alright just to be practical here, a stop time spell is easily made with a modified War Stomp ability and some extra effects. I haven't looked at your coding but is it really necessary to do this if you can take care of it much more easily?
Well... yeah.
Just that you'd have to access the Object Editor when you wanna change duration, and then go back to the trigger and make some kind of mathmatical function that fits with it. Not that it would be hard but it would be doing the same thing twice.
And I'd still have to loop through the units cause I really want to freeze them, not just pause them (in which case they still move which isn't very cool if you ask me). If I just loop them once then the special effect wouldn't stack.

The functions are still constant. While the return value is technically different with each level, it will always be "level * 5 + 10", for example.

Oh, and about the group. With a ForGroup you can avoid removing the units in the first place.
Just like when I realized (some posts above) that my spell isn't instant, I now realized that I don't have to count the units in the spell. This teqnique was used in Flame_Phoneix tutorial, because he counted the units in his spell, but I don't.
Now I can remove the CopyGroup() function (which I'm courius about why you said it leaked).
Oh and I'm not so sure about that constant function thingy. I'll have a look on it and update/post about it here later.

TriggerSleepAction()
Oh nuts, then I have to change it into timers.
I suggest you read up on xefx over at wc3c.net. You can slow down effects with xefx.
Alright I will. Would be epic if I finally found a solution to that annoying extra object for the spell.
And where exactly is the part that should convince me that its not a possible bug? Kill a unit and then heal it via triggers. The unit wont revive but instead GetWidgetLife() will now return some value above 0.405, potentially breaking your spell.
Healing a dead unit would not be a good idea. The creator shouldn't do that.
And anyway why does that matter? You pause and unpause a dead unit... not even the decay animation stays, it will just die as normally and the user won't notice any difference. Speaking theoratically, 10 extra dead units in the memmory for 10 more seconds isn't a problem.
IIRC, it was something with InitTrig_*spellname* (possibly, there was even more). Like I said, it doesnt matter anyway.
If you mean that I should use a InitTrig_*spellname* instead of my initializer, you're wrong. In that Hero contest which was previously ended in wc3c.com a dude got minus points for using it instead of an initializer, and I think that means something...
By the way, what is IIRC?



. . . . . . Edit . . . . . .
Use Unit Indexing.
No! It clearly says "Warning: Uses UnitUserData", and I rank MUI (and easy config aswell) above optimization.

. . . . . . Edit . . . . . .
I can't find xefx :sad:
 
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
815
No! It clearly says "Warning: Uses UnitUserData", and I rank MUI (and easy config aswell) above optimization.
Unit Indexing stores the index of that unit in its UserData, so you can always retrieve it. Unit Indexing is MUI, and if used properly really powerful.

I can't find xefx
xefx is part of xe.

what is IIRC?
If I Remember Correctly

If you mean that I should use a InitTrig_*spellname* instead of my initializer, you're wrong.
I didnt say you should. Thats what JESP says. And thats the reason why your spell doesnt comply with the JESP standard.

Healing a dead unit would not be a good idea.
Such things CAN and WILL happen once your map grows sufficiently large.
 
Level 10
Joined
Aug 19, 2008
Messages
492
- The Spell's InitTrig function must be named: InitTrig_<CodeName>
That's from JESP.
And I don't have an InitTrig function, so I don't have to follow that rule. That's only for Jass spells, not for vJass.

Oh and on another topic, please check back soon because I'm gonna update this post with my 1.1 BETA to see if you like it better or if it's worse.


EDIT: Updated to 1.1. Check it out....

Edit 2: I checked out xe0.6, and it seems nice.
Just that it can't slow down effects.
It can twist them, colorize them and move them, but not change the speed. Effects have the same speed no matter what when created with the trigger editor.

Unit Indexing stores the index of that unit in its UserData, so you can always retrieve it. Unit Indexing is MUI, and if used properly really powerful.
Yes but if you already use UnitUserData, the spell will not work, and will thus not be MUI.

Such things CAN and WILL happen once your map grows sufficiently large.
Yes but it does not matter as I said earlier. In this case the units will still die normally and no harm is done.
 
Last edited:
Level 10
Joined
Feb 22, 2008
Messages
619
(maybe you're updating this post now but I'll answer anyway)
Both yes and no.
Yes, in that sence it's very simple.
No, because I havn't seen it anywhere else.
And come on, wierd spells with a lot of twists are just confusing and often looks wierd. I like to make simple spells because they're a hell-of-alot more user friendly. Not that I mind coding strange and wierd spells, but spells should be simple and understandable (just like blizzard has designed theirs).

This has been done plenty of times in plenty of places...
 
Level 10
Joined
Aug 19, 2008
Messages
492
This has been done plenty of times in plenty of places...
Give me a concrete example with a link, and I will begin working on why people should choose mine instead of theirs :wink:

Oh I found 1 here on hive. I've got some good examples why you should use mine
1: Mine only uses 2 trigger windows, his uses 4 trigger windows
2: Mine follows JESP
3: Mine does not target magic immune creeps
4: Mine does not need that "Every .05 seconds of the game" event, just "Unit starts the effect of an ability"
 
Last edited:
Level 10
Joined
Feb 22, 2008
Messages
619
Give me a concrete example with a link, and I will begin working on why people should choose mine instead of theirs :wink:

Oh I found 1 here on hive. I've got some good examples why you should use mine
1: Mine only uses 2 trigger windows, his uses 4 trigger windows
2: Mine follows JESP
3: Mine does not target magic immune creeps
4: Mine does not need that "Every .05 seconds of the game" event, just "Unit starts the effect of an ability"

Oh, I don't have a link I just know alot of games that have time stop alot like this one :grin:
 
Level 2
Joined
Jun 23, 2009
Messages
28
i will ask a noob question but can someone help me importing this spell to a map? (im sure that im the only one who dont knows that)
 
Level 10
Joined
Aug 19, 2008
Messages
492
i will ask a noob question but can someone help me importing this spell to a map? (im sure that im the only one who dont knows that)
Yes I can help you (but first I'd like to point out that double posting is forbidden)
1: Download Jass NewGen Pack
2: Extract the content to a folder and open NewGen WE (I think it's named that way)

What you will see now is kind of familiar. That's right, it's the WE, but a bit modified. It looks the same, but it comes with some features and - most importantly - enables vJass spells. And this spell is vJass.
This is probobly the only way to enable it.
Have fun!

Oh, and don't forget the dots(.) at the end of Duration and Range (I'm not sure if there are more, but when using REAL numbers (i.e 123.456) you have to have a dot at the end)
 
Level 10
Joined
Aug 19, 2008
Messages
492
JESP is totally deprecated... !
Wait... what?
You don't like JESP or am I misunderstanding you?
and use a UnitIndexing System ! ...H2I OMFG °!!!!111
UnitUserData shouldnt be used for anything else than UnitIndexing anyways, so using it for this is totally fine!
Yes, I agree, they should not use UnitUserData for anything else.
But I'm not trying to make this spell optimization freak, but rather user friendly, which includes no bugs what so ever.
If a user wants to have UnitUserData on his map he should not be declined this spell with it.
That's the very soul of this spell, multi user and multi map functionality, 100% self sufficient with no bugs what so ever. I might not have achieved this yet but that is my goal.
At least this applies to this spell, I might make something later which goal isn't functionality but rather optimization, who knows.

Take that in mind while evaluating my work :wink:
 
Level 10
Joined
Aug 19, 2008
Messages
492
Stopping time? I haven't tried this spell so I don't know exactly what it does, but stopping time for units around the caster exactly like stunning them? Sorry if this has been said or something.
Well, it's similar to stunning them, but it really stops them (sets TimeScale to 0, so they don't move at all).
I'd actually wish this stop timed completely, but it doesn't stop for example ability cooldowns.
Just download and test, the effect is neat too :thumbs_up:
 
Level 10
Joined
Aug 19, 2008
Messages
492
HAHAHA SWEET!
one question

how the fuck do u import a spell?!?!! ANYONE HELP ME PLEASE!?!?!

[email protected]
Someone just asked that :hohum:
You need Jass NewGen Pack, because this spell is in vJass.
Just open the NewGen World Editor and copy-paste the two triggers (Time Stop and TimerUtils), the special effect dummy unit and spell your Hero uses to your map (and alternatively the normal dummy unit aswell).
Then you gotta configure some things in the SETUP section in Time Stop (which will be easy if you know how to detect rawcodes, which is CTRL + D in Object Editor), like the Rawcode of the Hero spell, and the special effect unit.

Good luck! :grin:
For further questions just ask me, all I want is reputation
 
Level 2
Joined
Mar 12, 2009
Messages
9
Finally, someone made this spell. I was trying to make this for some time, but there were some problems, but my idea was not only to stop units, but day time, units - entire map.
But this still i cool 5/5 :thumbs_up:
Yeah, The only problem I have is to make all units stop animation - that is all the problem.
 
Level 10
Joined
Aug 19, 2008
Messages
492
I still don't know structs :sad: I wish I did, everyone likes it.
Well, it's been officially declared that Flame_Phoenix will start his work on a tutorial 20th june 2009, and if I remember correctly he's gonna teach me structs. Finally.
I was trying to make this for some time, but there were some problems, but my idea was not only to stop units, but day time, units - entire map.
But this still i cool 5/5 :thumbs_up:
Well, you can always try to change the Range of this to cover entire map (or just the large part you see if that's a possibility?), make Targets return true and add some Slow Down Gametime to 0% function?
 
Level 8
Joined
Apr 7, 2008
Messages
176
Ok, /sigh.
It got my hopes up but then I realized this really was just a Warstomp with an effect, which by the way the special effect doesnt seem to actually reach as far as the spell pause does. If the hero is gonna make a Time Stop bubble and be able to run around, it should continuously stop all incoming enemy units who enter the bubble. Example, You cast the spell and it stops units in range, more units run into range of the bubble and they become paused. And no it wouldnt be overpowered, OP is simply based on the settings someone gives it. IE Duration and range. But as it is right now, it could be made without using any triggers. Warstomp - new Special Effect
 
Level 7
Joined
Dec 19, 2008
Messages
277
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
 
Level 10
Joined
Aug 19, 2008
Messages
492
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
Maybe you should read my other 2 comments? They all say why I didn't use structs.
I can't blame you for thinking my spell's code is bad though, but thanks for the constructive critizism, it really helped me improve my spell.
 
Top