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

Timed Special Effect v2.1 & v1.8.1

TIMED SPECIAL EFFECT
IMPORT GUIDE :
[Patch 1.31+ is needed to access the test map for both versions]
[v2.x]
1. Install TimedEventLinkedList to your map if you do not use it yet
2. Copy the TimedSpecialEffect folder in the test map
3. Configure the TSELLConfig trigger
4. To utilize the system, refer to the TSELLSampleRegisterUnit and TSELLSampleRegisterPoint triggers
[v1.x]
1. Copy the TimedSpecialEffect folder in the test map
2. Configure the TSEConfig trigger
3. To utilize the system, refer to the TSESampleRegisterUnit and TSESampleRegisterPoint triggers
SYSTEM INFORMATION :
A system designed to ease the pain of working with timed special effects in GUI. Whenever someone wants to create a timed special effect in GUI, they have to do the hassle of handling everything from the start to finish.
For example, creating a simple cloud effect in GUI when Silence is cast is going to look something like one of the following:

  • CloudVar1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Silence
    • Actions
      • Special Effect - Create a special effect at (Target point of ability being cast) using Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • Wait 3.00 seconds
      • Special Effect - Destroy (Last created special effect)
  • CloudVar2
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Silence
    • Actions
      • Custom script: local effect u
      • Special Effect - Create a special effect at (Target point of ability being cast) using Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • Custom script: set u = GetLastCreatedEffectBJ()
      • Wait 3.00 seconds
      • Custom script: call DestroyEffectBJ(u)

CloudVar1 is prone to bug when there are multiple silence casted at once.
CloudVar2 uses locals which requires some knowledge of custom script.
Both of these also has issues since they uses Wait action. Unless they use PreciseWait for LUA, precision will be an issue. All these doesn't include the fact that it is hard to do anything to these effects after they are created aside of destroying them. Don't forget that leaks also existed if not handled carefully.

v2.x

v1.x

With TimedSpecialEffect, the issues above can be resolved quite easily. TimedSpecialEffect provided an easy way of creating timed effects. Creating cloud similar to CloudVar1 and CloudVar2 with TSE looks like the following:
  • TestEffect 2
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Silence
    • Actions
      • Set TSELL_Duration = 3.00
      • Set TSELL_EffectName = Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • Set TSELL_Point = (Target point of ability being cast)
      • Trigger - Run TSELL_RegisterTrigger (checking conditions)
Just set 3 variables, run the TSELL_RegisterTrigger and let the system handles the rest. TimedSpecialEffect uses Countdown Timer internally, thus it has better precision than waits. In addition, any effect created with TSE is MUI and leakless. TSELL stands for TimedSpecialEffect LinkedList, for those who are curious. The renaming is due to some internal issues during development of v2.0 that finalizes with a decision to alter the entire variable structure for better readability.

TimedSpecialEffect also provided support for extensive modifications while an effect is running. It is possible to create complex spells by attaching triggers to an effect. The following variables are exposed:
- TSELL__RemainingDuration: Get/Set the remaining time of the effect (yes, set, which means changing this value changes the remaining duration)
- TSELL__LoopTimer: Get/Set the period for each loop execution (yes, set, which means changing this value changes the period of the loop trigger)
- TSELL__Integer: Get/Set a free to use integer variable for your need (yes, set, which means changing this value changes it for the rest of the effect duration)
- TSELL__SpecialEffect: Get control of your effect, so any modification that you want to do to it can easily be done during any of the events
- TSELL__ActiveIndex: Get the index of the instance easily without knowing the detailed intricacies of TimedSpecialEffect
- TSELL__TargetUnit: Get the unit affected by TimedSpecialEffect, returns no unit if TargetUnit is not specified when registering
- TSELL__SourceUnit: Get the registered source unit of this TimedSpecialEffect, returns no unit if SourceUnit is not specified
- TSELL__Point: Get the point of the effect, returns position of TargetUnit when TargetUnit is used
NOTE: Use TSELL__Alloc** when accessing during the Allocation (START) phase

This is the entire register for Unit and Point variation:
  • TSELLSampleRegisterUnit
    • Events
    • Conditions
    • Actions
      • -------- CORE --------
      • -------- TSELL_Duration is the duration of the effect --------
      • Set TSELL_Duration = 10.00
      • -------- TSELL_TargetUnit determine which unit has this effect attached --------
      • Set TSELL_TargetUnit = (Triggering unit)
      • -------- TSELL_AttachPoint is only used in conjunction with TargetUnit to determine in which part of unit it is placed --------
      • Set TSELL_AttachPoint = left hand
      • -------- TSELL_EffectName is the string to the effect file --------
      • Set TSELL_EffectName = war3mapImported/Soul Bow Enchantment Necro.mdx
      • -------- EXTENSION --------
      • -------- TSELL_TargetUnitAliveCheck refers to whether the attached effect account whether the unit is alive or not --------
      • Set TSELL_TargetUnitAliveCheck = False
      • -------- TSELL_SourceUnit refers to the source of the buff, useful if the TargetUnit and SourceUnit are two different units --------
      • Set TSELL_SourceUnit = (Triggering unit)
      • -------- TSELL_SourceUnitAliveCheck whether the SourceUnit must be alive or not --------
      • Set TSELL_SourceUnitAliveCheck = False
      • -------- TSELL_ChanneledOrderID is used for buff tied with channeling spells --------
      • -------- The buff immediately ceased if the channeling spell ends --------
      • Set TSELL_ChanneledOrderID = blizzard
      • -------- TSELL_ChanneledOrderID is used for buff tied with channeling spells --------
      • -------- TSELL_OnEventAllocate is an event that runs when the effect is created (directly at moment of effect creation). Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventAllocate = TSELL_OnEventAllocate
      • -------- TSELL_OnEventLoop is an event that runs every TSELL_TimerOnLoop seconds. Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventLoop = TSELL_OnEventLoop
      • -------- TSELL_TimerOnLoop is the duration between each tick of the loop --------
      • -------- Setting this allows better control over the OnLoopEvent instead of dealing with TELL_TimerTIMEOUT global --------
      • -------- This variable cannot be lower than TELL_TimerTIMEOUT --------
      • Set TSELL_TimerForLoop = 1.00
      • -------- TSELL_OnEventDeallocate is an event that runs when the effect is about to be destroyed. Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventDeallocate = TSELL_OnEventDeallocate
      • -------- END --------
      • -------- After all core variables are set, run TSELL_RegisterTrigger --------
      • Trigger - Run TSELL_TriggerRegister (checking conditions)
  • TSELLSampleRegisterPoint
    • Events
    • Conditions
    • Actions
      • -------- CORE --------
      • -------- TSELL_Duration is the duration of the effect --------
      • Set TSELL_Duration = 16.00
      • -------- TSELL_EffectName is the string to the effect file --------
      • Set TSELL_EffectName = Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • -------- TSELL_Point is the position of the effect created --------
      • Set TSELL_Point = (Target point of ability being cast)
      • -------- TSELL_Scale for scaling the effect (point-based only) --------
      • Set TSELL_Scale = 1.00
      • -------- EXTENSION --------
      • -------- TSELL_SourceUnit refers to the source of the buff, useful if the TargetUnit and SourceUnit are two different units --------
      • Set TSELL_SourceUnit = (Triggering unit)
      • -------- TSELL_SourceUnitAliveCheck whether the SourceUnit must be alive or not --------
      • Set TSELL_SourceUnitAliveCheck = False
      • -------- TSELL_ChanneledOrderID is used for buff tied with channeling spells --------
      • -------- The buff immediately ceased if the channeling spell ends --------
      • Set TSELL_ChanneledOrderID = blizzard
      • -------- TSELL_ChanneledOrderID is used for buff tied with channeling spells --------
      • -------- TSELL_OnEventAllocate is an event that runs when the effect is created (directly at moment of effect creation). Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventAllocate = TSELL_OnEventAllocate
      • -------- TSELL_OnEventLoop is an event that runs every TSELL_TimerOnLoop seconds. Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventLoop = TSELL_OnEventLoop
      • -------- TSELL_TimerOnLoop is the duration between each tick of the loop --------
      • -------- Setting this allows better control over the OnLoopEvent instead of dealing with TELL_TimerTIMEOUT global --------
      • -------- This variable cannot be lower than TELL_TimerTIMEOUT --------
      • Set TSELL_TimerForLoop = 1.00
      • -------- TSELL_OnEventDeallocate is an event that runs when the effect is about to be destroyed. Refer to data with TSELL__ActiveIndex. --------
      • Set TSELL_OnEventDeallocate = TSELL_OnEventDeallocate
      • -------- END --------
      • -------- After all core variables are set, run TSE_RegisterTrigger --------
      • Trigger - Run TSELL_TriggerRegister (checking conditions)
TSE v2.x also comes with support for Timed Effect by Almia. TSE v2.x uses RemoveEffect by Pyrogasm. Due to multiple reasons, TSE v2.x and TSE v1.x are mutually exclusive, and both can be installed on the same map. Feature-wise, TSE v2.x is superior, but TSE v1.x by itself is sufficiently rich in feature to allow for complex creations.
With TimedSpecialEffect, the issues above can be resolved quite easily. TimedSpecialEffect provided an easy way of creating timed effects. Creating cloud similar to CloudVar1 and CloudVar2 with TSE looks like the following:
  • TestEffect 2
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Silence
    • Actions
      • Set TSEDuration = 3.00
      • Set TSEEffectName = Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • Set TSEPoint = (Target point of ability being cast)
      • Trigger - Run TSE_RegisterTrigger (checking conditions)
Just set 3 variables, run the TSE_RegisterTrigger and let the system handles the rest. TimedSpecialEffect uses Countdown Timer internally, thus it has better precision than waits. In addition, any effect created with TSE is MUI and leakless.

TimedSpecialEffect also provided support for extensive modifications while an effect is running. It is possible to create complex spells by attaching triggers to an effect. The following resources showcase examples how it is done in old versions of TimedSpecialEffect:
Seal of Blessed Light
Lightning Seal: Zeal
Lightning Seal: Strike Array
And now with v1.6, TimedSpecialEffect exposes some of the useful variables in a comfortable way that you can easily use them on your OnEvent:
- TSE__SpecialEffect: Get control of your effect, so any modification that you want to do to it can easily be done during any of the events
- TSE__RemainingDuration: Get the remaining time of the effect
- TSE__ActiveIndex: Get the index of the instance easily without knowing the detailed intricacies of TimedSpecialEffect
- TSE__TargetUnit: Get the unit affected by TimedSpecialEffect, returns no unit if TargetUnit is not specified when registering
- TSE__SourceUnit: Get the registered source unit of this TimedSpecialEffect, returns no unit if SourceUnit is not specified
- TSE__Point: Get the point of the effect, returns Center of Playable Map Area when TSE__TargetUnit is used

An example from the test map utilizing TimedSpecialEffect OnEvent:
  • TestEffect with Event
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Thunder Clap
    • Actions
      • Set TSEDuration = 5.00
      • Set TSEAttachPoint = overhead
      • Set TSEEffectName = Abilities\Spells\Human\MagicSentry\MagicSentryCaster.mdl
      • Set TSETargetUnit = (Triggering unit)
      • Set TSEUnitAliveCheck = True
      • Set TSEOnLoopEvent = TestEffect CheckDur <gen>
      • Set TSEOnLoopTimer = 1.00
      • Set TSEOnEndEvent = TestEffect HealAfterDelay <gen>
      • Trigger - Run TSE_RegisterTrigger (checking conditions)
  • TestEffect HealAfterDelay
    • Events
    • Conditions
    • Actions
      • Unit - Set life of TSE__TargetUnit to 100.00%
  • TestEffect CheckDur
    • Events
    • Conditions
    • Actions
      • Game - Display to (All players) the text: (Current Index: + (String(TSE__ActiveIndex)))
      • Game - Display to (All players) the text: (Remaining Time: + (String(TSE__RemainingDuration)))
This spell uses the OnLoopEvent and OnEndEvent. The idea is that after Thunder Clap is casted, create a magic sentry effect on the hero, where the hero will be healed after 5 seconds. Every 1 second, the game informs the player how many seconds left before healing.


For more detail, refer to the TSESampleRegisterUnit and TSESampleRegisterPoint triggers.
  • TSESampleRegisterUnit
    • Events
    • Conditions
    • Actions
      • -------- CORE --------
      • -------- TSEDuration is the duration of the effect --------
      • Set TSEDuration = 10.00
      • -------- TSETargetUnit determine which unit has this effect attached --------
      • Set TSETargetUnit = (Triggering unit)
      • -------- TSEAttachPoint is only used in conjunction with TargetUnit to determine in which part of unit it is placed --------
      • Set TSEAttachPoint = left hand
      • -------- EffectName is the string to the effect file --------
      • Set TSEEffectName = war3mapImported/Soul Bow Enchantment Necro.mdx
      • -------- EXTENSION --------
      • -------- TSETargetUnitAliveCheck refers to whether the attached effect account whether the unit is alive or not --------
      • Set TSETargetUnitAliveCheck = False
      • -------- TSESourceUnit refers to the source of the buff, useful if the TargetUnit and SourceUnit are two different units --------
      • -------- KNOWN ISSUE TILL V1.5: If SourceUnit is set to a unit and the SourceUnit is killed, the buff will immediately ceased --------
      • -------- KNOWN ISSUE TILL V1.5: (cont) so if the buff is not tied to the state of the source, it is preferred to not be set --------
      • Set TSESourceUnit = (Triggering unit)
      • -------- TSESourceUnitAliveCheck is to troubleshoot the KNOWN ISSUE for v1.5 --------
      • -------- Since it is considered an issue, the default state is now to ignore SourceUnit state (False) --------
      • Set TSESourceUnitAliveCheck = False
      • -------- TSEChanneledOrderID is used for buff tied with channeling spells --------
      • -------- The buff immediately ceased if the channeling spell ends --------
      • Set TSEChanneledOrderID = blizzard
      • -------- TSEChanneledOrderID is used for buff tied with channeling spells --------
      • -------- TSEOnIndexEvent is an event that runs when the effect is created (directly at moment of effect creation). Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnIndexEvent = TSEOnIndexEvent
      • -------- TSEOnLoopEvent is an event that runs every TSEOnLoopTimer seconds. Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnLoopEvent = TSEOnLoopEvent
      • -------- TSEOnLoopTimer is the duration between each tick of the loop --------
      • -------- Setting this allows better control over the OnLoopEvent instead of dealing with TSE_TIMEOUT global --------
      • -------- This variable cannot be lower than TSE_TIMEOUT --------
      • Set TSEOnLoopTimer = 1.00
      • -------- TSEOnEndEvent is an event that runs when the effect is about to be destroyed. Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnEndEvent = TSEOnEndEvent
      • -------- If you utilize external array variables tied to TSE__ActiveIndex (v1.6+) OR TSE_Index /TSE_MaxIndex (v1.5-) in any of the event, YOU MUST SET LOCK INSTANCE TO TRUE --------
      • -------- Else, it is recommended to set this to false so the system performs better --------
      • Set TSELockInstance = False
      • -------- END --------
      • -------- After all core variables are set, run TSE_RegisterTrigger --------
      • Trigger - Run TSE_RegisterTrigger (checking conditions)
  • TSESampleRegisterPoint
    • Events
    • Conditions
    • Actions
      • -------- CORE --------
      • -------- TSEDuration is the duration of the effect --------
      • Set TSEDuration = 16.00
      • -------- TSEEffectName is the string to the effect file --------
      • Set TSEEffectName = Abilities\Spells\Human\CloudOfFog\CloudOfFog.mdl
      • -------- TSEPoint is the position of the effect created --------
      • Set TSEPoint = (Target point of ability being cast)
      • -------- EXTENSION --------
      • -------- TSESourceUnit refers to the source of the buff, useful if the TargetUnit and SourceUnit are two different units --------
      • -------- KNOWN ISSUE TILL V1.5: If SourceUnit is set to a unit and the SourceUnit is killed, the buff will immediately ceased --------
      • -------- KNOWN ISSUE TILL V1.5: (cont) so if the buff is not tied to the state of the source, it is preferred to not be set --------
      • Set TSESourceUnit = (Triggering unit)
      • -------- TSESourceUnitAliveCheck is to troubleshoot the KNOWN ISSUE for v1.5 --------
      • -------- Since it is considered an issue, the default state is now to ignore SourceUnit state (False) --------
      • Set TSESourceUnitAliveCheck = False
      • -------- TSEChanneledOrderID is used for buff tied with channeling spells --------
      • -------- The buff immediately ceased if the channeling spell ends --------
      • Set TSEChanneledOrderID = blizzard
      • -------- TSEChanneledOrderID is used for buff tied with channeling spells --------
      • -------- TSEOnIndexEvent is an event that runs when the effect is created (directly at moment of effect creation). Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnIndexEvent = TSEOnIndexEvent
      • -------- TSEOnLoopEvent is an event that runs every TSEOnLoopTimer seconds. Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnLoopEvent = TSEOnLoopEvent
      • -------- TSEOnLoopTimer is the duration between each tick of the loop --------
      • -------- Setting this allows better control over the OnLoopEvent instead of dealing with TSE_TIMEOUT global --------
      • -------- This variable cannot be lower than TSE_TIMEOUT --------
      • Set TSEOnLoopTimer = 1.00
      • -------- TSEOnEndEvent is an event that runs when the effect is about to be destroyed. Refer to data with TSE__ActiveIndex. --------
      • -------- Read TSELockInstance notes if external array variables uses TSE__ActiveIndex. --------
      • Set TSEOnEndEvent = TSEOnEndEvent
      • -------- If you utilize external array variables tied to TSE__ActiveIndex (v1.6+) OR TSE_Index /TSE_MaxIndex (v1.5-) in any of the event, YOU MUST SET LOCK INSTANCE TO TRUE --------
      • -------- Else, it is recommended to set this to false so the system performs better --------
      • Set TSELockInstance = False
      • -------- END --------
      • -------- After all core variables are set, run TSE_RegisterTrigger --------
      • Trigger - Run TSE_RegisterTrigger (checking conditions)




MEDIA SHOWCASE :

CHANGELOG :
v2.1:
- Removed support for backward compatibility with TimedSpecialEffect v1.x
>> refer to https://www.hiveworkshop.com/threads/timed-special-effect-v2-0-6.332579/#post-3614576 for more information
v2.0.6:
MANDATORY UPDATE FOR THOSE WHO USE VERSION 2.X WITH TSECompat TRIGGERS!
- Fixed a major issue with TSECompat
v2.0.5:
- Fixes TSECompat triggers
v2.0.4:
- Fix overlooked variables that not pointing to the right data in the allocation
v2.0.3:
- Final fix on bug from TimedEventLinkedList
- For checking data during allocation (START) phase, use TSELL__Alloc** instead of TSELL__**
v2.0.2:
- Further fix on the critical bug
- Reduces trigger by removing TSELLEmptyEvent and bind it to TELLEmptyEvent
v2.0.1:
- Fixed a critical bug from TimedEventLinkedList
v2.0:
[This changelog is compared to v1.7 since v2.0 development began around v1.7 release]
- New Requirement: TimedEventLinkedList (TELL)
- Deprecated LockInstance and variables related to this feature
- Rewrite the entire API of TimedSpecialEffect for better readability
- Point variable is now always usable, and point toward TargetUnit when TargetUnit is defined
- Fixed an issue with TimedSpecialEffect loop that existed within v1.7 version (technically, it is auto fixed due to TELL requirement)
- Additional variable for storing information: TSE_Integer
> It has come to my attention that spells using TSE has a hidden minor issue regarding level handling where the level stored might not be equal to the original level at time of cast if the registration is done long after spell has been cast
> TSE_Integer is added to allow storing a single integer data to resolve this, it can be for level or other uses (specifically data that needs to be passed between effects created at separate times)
> This issue is not present when the data is stored immediately OnIndexEvent (v1.7) during the casting phase of the spell (all past resources with TSE uses this method)
> To be clear, this issue arise when the following scenario happened:
[1] Hero cast ability
[2] Ability only create effect for visual
[3] After a delay, the effect create ANOTHER effect
[4] The ANOTHER effect deals damage based on level after another delay
> It is impossible to get the level at time of cast to attach for effect at [3] since the ability might have been levelled during the delay between [2] and [3]
- Improve effect removal with Pyrogasm RemoveEffect snippet
- Added TSECompat for backward compatibility support (please report if any resources that use TSE v1.x still breaks when you update to TSE v2.x)
> Be aware that TSELL-TSECompat is slower than TSE at the moment
- Added TimedEffectAlmiaCompat

KNOWN ISSUES:
- TSELL is slower due to more overhead compared to TSE v1.x, especially with TELL requirement underneath
> I plan to switch to vJass and remove TELL dependency if possible, but for the moment the overhead can be reduced by removing TSECompat aspect of this resources


v1.8.1:
- Improved TSESampleRegisterPoint by adding TSEScale into the sample
> It has been available for multiple versions, but I missed it on 1.6 update for the samples
v1.8:
- Fixed an issue with TimedSpecialEffect loop
v1.7:
- TSE__RemainingDuration can now be altered to modify the duration of the effect for OnIndex and OnLoop
v1.6:
- Fixed a bug that if the first effect created by TSE is a point effect, it will be affected by the new scale native and rendered it invisible
- Added a disabled theory trigger to showcase that Set Scale does not affect unit-attached effects
- Added an example of register event for both unit and point
- Added SourceUnitAliveCheck --> Solution for an issue discovered in v1.5
- Added OnEvent variables that allowed better readability of OnEvent triggers --> all are READ-ONLY
- MAJOR FIX: Resolve a hidden issue where indexes of TSE are not properly deallocated at times, especially after dealing with instances that has LockInstance = True
- Changed the timer scheme from using the add event to a Countdown Timer based approach due to 1.32+ patches having a limit of 100 Hz
- Fixes an inconsistency in naming between TimedSpecialEffect and TimedSpellEffect

Old Information:
This system is meant to ease the pain of working with special effects that are time tied because they are annoying to code in GUI. Sorry, super annoying to code.
With this system, users only have to provide the parameters and let the system handle the effects without any further issues down the line.

I'll be honest, I might not do my homework properly but as far as I am aware, no system in GUI or GUI-Friendly line that has handled Special Effect when we need it the most. I also tried a new time native, but it does not seem to function properly from my tests. This system can be easily replicated in any Warcraft 3 patch since it is written without the new natives.

Dynamic Indexing is used to allow multiple effects under one user. I have considered Unit Indexer and Hashtables approach, the first is difficult when working with the same unit with multiple effects, while the latter is less to my taste and I feel the need to work with multiple data types, and casting them around is not a fun way to code. This comes with one disadvantage: it is difficult to retrieve the index of units affected by the spell effect easily, which is relevant for complex spells or spells that are not unit-bound but position bound.
v1.5:
- Point is now preserved into the TSE data if declared and can be accessed via TSE_I_Point
v1.4:
- Added LockInstance capability
- Provided some Recursion safety for the Lock Instance feature, although it is more of additional safety layers
v1.3.1:
- Fixed a critical bug with the newly added event feature
v1.3:
- Added ability to register triggers on events: OnIndexEvent, OnLoopEvent, OnEndEvent
> OnIndexEvent runs once the system finish indexing (register) all relevant data
> OnLoopEvent runs every TSE_TIMEOUT while the effect is active
> OnEndEvent runs when the system is about to deindex the instance
v1.2 Beta:
- Changed TSEUnit to TSETargetUnit
- Added backward compatibility to v1.1 and earlier (TSE_Unit should not be used for those using v1.2 forward)
- Changed TSEMaxIndex to TSE_MaxIndex
- Changed TSEUnitAliveChecks to TSE_I_UnitAliveCheck
- Changed TSEIsChannelings to TSE_I_IsChanneling
- Changed TSESourceUnits to TSE_I_SourceUnit
- Changed TSEChanneledOrderIDs to TSE_I_ChanneledOrderID
- Changed TSEEffects to TSE_I_Effect
- Changed TSERemainingDurs to TSE_I_RemainingDuration
- Changed TSETimeout to TSE_TIMEOUT
- Changed TSERegister to TSE_RegisterTrigger
- Changed TSETargetUnits to TSE_I_TargetUnit
- Changed TSEIndexLoop to TSE_Index
v1.1: Changed the patching convention and changed the timeout from 0.03 to 0.03125.
Patch 20: Added support for channeled spell effects by capturing the ability's orderID. More examples are provided in the test map.
Patch 11: Added scaling ability, removed the Jass variant since it's just bloat the code like crazy (and making it hard to maintain)
Patch 10: Added an extension to support location (I find this needed for an ability idea)
Patch 2: Switched to 1.31 to increase accessibility
Patch 1: Released


CREDIT :
Bow Enhancement - @Mythic
RemoveEffect - @Pyrogasm
Contents

TimedSpecialEffect v1.8 (Map)

TimedSpecialEffect v2.1 (Map)

Reviews
MyPad
A simple yet classic system that should make effect creation, timing, and destruction a breeze for users.
I don't have a very good reading comprehension but... basically this spell allows stacking of same ability codes?
No, this system allows spell effect to be used with timers.

Usually, when making complex spells, we need an effect for the target for a duration. This system allows for that with very little effort.

EDIT:

Updated to add accessibility for 1.31.
 
Last edited:
Level 22
Joined
Nov 4, 2010
Messages
6,232
This looks great!

I like how the casters can be made to show indicator effects whenever their spells are still ongoing, while they need not to stand there in one place channeling.

As far as I see, this does not need dummy unit sheningans too, which is very good.

Updated to add accessibility for 1.31.

Based!

Hopefully, one day somebody can make an edition for use between 1.29.2 and 1.30.4
 
The purpose of the TSEPatch appears to be "questionable" to say the least. What does it do?
Ah, must be a left-over idea. I was thinking of using that to ensure backward compatibility with older versions but I think it might be a bit of a stretch on my end. I'll just remove it, I think.
 
Removed the unnecessary TSEPatch (implicit in the changelog) and timeout changed to 0.03125 (1/32).

Timed Alpha Modifier v1.1 has the ability to insert arguments, thus making it possible to be used akin to a spell given one can understand how the data is processed by that resource. I did consider the same capability for TSE, but I think the variables need renaming before I can go that route, and if I decided as such, I need to ensure compatibilities to ensure any map that is and intend to use TSE not breaking.
 
Released 1.2 Beta:
  • Changed TSEUnit to TSETargetUnit
  • Added backward compatibility to v1.1 and earlier (TSE_Unit should not be used for those using v1.2 forward)
  • Changed TSEMaxIndex to TSE_MaxIndex
  • Changed TSEUnitAliveChecks to TSE_I_UnitAliveCheck
  • Changed TSEIsChannelings to TSE_I_IsChanneling
  • Changed TSESourceUnits to TSE_I_SourceUnit
  • Changed TSEChanneledOrderIDs to TSE_I_ChanneledOrderID
  • Changed TSEEffects to TSE_I_Effect
  • Changed TSERemainingDurs to TSE_I_RemainingDuration
  • Changed TSETimeout to TSE_TIMEOUT
  • Changed TSERegister to TSE_RegisterTrigger
  • Changed TSETargetUnits to TSE_I_TargetUnit
  • Changed TSEIndexLoop to TSE_Index

This is released alongside 1.1 since 1.2 Beta is not tested yet despite the renaming and potential failure from such modification. I release this since one of my soon-to-be-released resources utilizes the 1.2 Beta version.
 
Released 1.3:
  • Added ability to register triggers on events: OnIndexEvent, OnLoopEvent, OnEndEvent
    OnIndexEvent runs once the system finish indexing (register) all relevant data
    OnLoopEvent runs every TSE_TIMEOUT while the effect is active
    OnEndEvent runs when the system is about to deindex the instance

I am still holding on the "arguments" feature since I am not sure on the utility. Level seems to be a stretch and something that will be a first priority into the argument based on my experience handling Timed Vertex Modifier and Timed Alpha Modifier, which might be better added as optional arguments given this particular resources had quite the capability of being more dynamic in comparison to the other two.
 
Last edited:
URGENT!

All users of the v1.3 must immediately update to v1.3.1 since there is a critical bug that renders the event feature not properly indexed in the system.

EDIT:
v1.4 RELEASED!
  • Added LockInstance capability
  • Provided some Recursion safety for the Lock Instance feature, although it is more of additional safety layers
 
Last edited:
v1.6:
  • Fixed a bug that if the first effect created by TSE is a point effect, it will be affected by the new scale native and rendered it invisible
  • Added a disabled theory trigger to showcase that Set Scale does not affect unit-attached effects
  • Added an example of register event for both unit and point
  • Added SourceUnitAliveCheck --> Solution for an issue discovered in v1.5
  • Added OnEvent variables that allowed better readability of OnEvent triggers --> all are READ-ONLY
  • MAJOR FIX: Resolve a hidden issue where indexes of TSE are not properly deallocated at times, especially after dealing with instances that has LockInstance = True
  • Changed the timer scheme from using the add event to a Countdown Timer based approach due to 1.32+ patches having a limit of 100 Hz
  • Fixes an inconsistency in naming between TimedSpecialEffect and TimedSpellEffect

Okay, the last change is actually due to a fault back when Patch 1 is released. Back then, I accidentally named the description as TimedSpellEffect shortly before release while the entire internal trigger folder uses TimedSpecialEffect as the naming. I am sure this has created some confusion on the resources' purpose which let to some of the design choices between v1.1 and v1.6.

I decided that the TimedSpecialEffect should be the name of this resource since it primarily focused on handling special effects over a specified time. Yes, it is possible to use this for spell making, but it is not the only use of this resource. The main idea, after all, is creating a more GUI-friendly version of Timed Effect v1.1

As of v1.6 release, I have updated description of multiple spells of mine that uses TimedSpecialEffect where I named it as TimedSpellEffect. Hopefully this clear up any lingering confusion for this resource and I'll stick to this name going forward.
 
v2.0:
[This changelog is compared to v1.7 since v2.0 development began around v1.7 release]
  • New Requirement: TimedEventLinkedList (TELL)
  • Deprecated LockInstance and variables related to this feature
  • Rewrite the entire API of TimedSpecialEffect for better readability
  • Point variable is now always usable, and point toward TargetUnit when TargetUnit is defined
  • Fixed an issue with TimedSpecialEffect loop that existed within v1.7 version (technically, it is auto fixed due to TELL requirement)
  • Additional variable for storing information: TSE_Integer
It has come to my attention that spells using TSE has a hidden minor issue regarding level handling where the level stored might not be equal to the original level at time of cast if the registration is done long after spell has been cast
TSE_Integer is added to allow storing a single integer data to resolve this, it can be for level or other uses (specifically data that needs to be passed between effects created at separate times)
This issue is not present when the data is stored immediately OnIndexEvent (v1.7) during the casting phase of the spell (all past resources with TSE uses this method)
To be clear, this issue arise when the following scenario happened:
[1] Hero cast ability
[2] Ability only create effect for visual
[3] After a delay, the effect create ANOTHER effect
[4] The ANOTHER effect deals damage based on level after another delay
It is impossible to get the level at time of cast to attach for effect at [3] since the ability might have been levelled during the delay between [2] and [3]
  • Improve effect removal with Pyrogasm RemoveEffect snippet
  • Added TSECompat for backward compatibility support (please report if any resources that use TSE v1.x still breaks when you update to TSE v2.x)
Be aware that TSELL-TSECompat is slower than TSE at the moment
- Added TimedEffectAlmiaCompat

KNOWN ISSUES:
- TSELL is slower due to more overhead compared to TSE v1.x, especially with TELL requirement underneath
I plan to switch to vJass and remove TELL dependency if possible, but for the moment the overhead can be reduced by removing TSECompat aspect of this resources

=====

I provided both v1.8.1 and v2.0 since the latter has more features but the speed is quite reduced due to large overhead (thanks GUI and your annoying global variables!) while the former has less feature but operates in faster manner. The v2.0 has been on wait for some time due to TimedEventLinkedList v1.0.1 needs approval before I can bring it out. Happy holidays!
 
Last edited:
URGENT! DO NOT CREATE TIMED EFFECT INSTANCE INSIDE ANOTHER TIMED EFFECT INSTANCE FOR V2.0!

I am resolving an issue I just found after releasing v2.0 and working on a spell that specifically requires it at the moment. The issue is related to TimedEventLinkedList. I will bring update a solution is found.
 
Last edited:
URGENT! DO NOT CREATE TIMED EFFECT INSTANCE INSIDE ANOTHER TIMED EFFECT INSTANCE FOR V2.0!

I am resolving an issue I just found after releasing v2.0 and working on a spell that specifically requires it at the moment. The issue is related to TimedEventLinkedList. I will bring update a solution is found.
This issue has been patched by updating TimedEventLinkedList to version 1.1
 
I recently found two major issues with v2.0.6 of Timed Special Effect.
  • It breaks compatibility with Stun Snippet v1.2 which uses v1.x, something which doesn't exist back in glitchy v2.0. I think it has something to do with the compatibility support and the issue patched between v2.0 and v2.0.6.
  • One cannot create an instance in deallocation
After some more thought, I am thinking that having to maintain a compatibility between both v1.x and v2.x in my opinion is not worth the trouble. Both can coexist on a map if I drop the entire 'compatibility' BS and they won't interfere with each other due to variable differences (TSE for v1.x and TSELL for v2.x). With this consideration, I decided that this system will no longer support different major versions and let them stay separate instead.

EDIT:

TSE v1 and v2 has different design reasons. TSE v1 aims to keep the whole 'create timed based effect' simple, while TSE v2 aims to be flexible and probably a base idea of 'object-based spell making' paradigm I am trying to get a hold of.

EDIT 2:
If there's enough demand, I think v1.x, feature-wise, can be developed enough to be on the same level as v2.x (since I just now noticed that the first spell with v2.x, which is Licht Regen v1.1, seems to be possible in v1.x at a glance). The biggest advantage v2.x has over v1.x lies in the Linked List nature of v2.x (this was a disadvantage since it keeps raising issues due to my flawed TELL coding) which avoids 'empty instances' that is used by v1.x to allow external variables to be used. To illustrate:

v1.x: 1 [2] 3 4 [5] 6 7 8 9 10
v2.x: 1 2 3 4 5 6 7 8 9 10

Due to the 'Lock Instance' feature, which is meant to cheat the dynamic indexing nature of v1.x, whenever an instance is deleted prior to locked instance, the instance is only skipped, but not fully removed. Say, instance 3 and 4 ended:

v1.x: 1 [2] (3) (4) [5] 6 7 8 9 10
v2.x: 1 2 5 6 7 8 9 10

[] = Locked
() = Not Removed Due to Neighboring Locks

When there's a lot of spells working with TSE, this issue can get out of hand with lots of instance not deallocated due to locks. This is the main advantage of TSE v2.x. The disadvantage, which comes from Timed Event Linked List limitations, is the need of Alloc variables, which I personally is a fair trade-off.
 
Last edited:
Level 5
Joined
Nov 3, 2018
Messages
73
what is the variable that we need to change in order to change the special effects height? in vanilla gui you can do with this funciton
or this does not have it?
1710350991978.png
 
what is the variable that we need to change in order to change the special effects height? in vanilla gui you can do with this funciton
or this does not have it?
View attachment 465744
This one does not have it yet, but you can use that action with TSELL__SpecialEffect variable. I can consider this for future update since I didn't have any use for it in the past and nobody asked before.

What do you want to do with height specifically?
 
Level 5
Joined
Nov 3, 2018
Messages
73
This one does not have it yet, but you can use that action with TSELL__SpecialEffect variable. I can consider this for future update since I didn't have any use for it in the past and nobody asked before.

What do you want to do with height specifically?
Specifically i wanted to attach an effect to a dying unit (that unit dies underground) and an effect appears in his model
before using your system what i would do is create an effect variable and modify the height variable so that the effect appears on the ground and not on the model (underground)
currently as a workaround until this gets an update i went back to using that old method
also i tend to use modified models which have a screwed up origin point and i use the height to adjust the effect properly to where its supossed to go

For example a buff that applies a small cloud on his head would make it appear on his feet (since a lot of custom models lack node references)
so my workaround was also use the trigger height system to workaround it.

another use was that one of my characters has an ability that makes him look like he is flying while a lightning follows him ( the lightning its supossed to go into the ground instead of attached to the ground so again my work around was use classic gui variables for this ability) i just found out recently today that this system did not have that feature and i have been using it for about 2 months
i thank you for the system it has been great!
 
Specifically i wanted to attach an effect to a dying unit (that unit dies underground) and an effect appears in his model
before using your system what i would do is create an effect variable and modify the height variable so that the effect appears on the ground and not on the model (underground)
currently as a workaround until this gets an update i went back to using that old method
also i tend to use modified models which have a screwed up origin point and i use the height to adjust the effect properly to where its supossed to go

For example a buff that applies a small cloud on his head would make it appear on his feet (since a lot of custom models lack node references)
so my workaround was also use the trigger height system to workaround it.

another use was that one of my characters has an ability that makes him look like he is flying while a lightning follows him ( the lightning its supossed to go into the ground instead of attached to the ground so again my work around was use classic gui variables for this ability) i just found out recently today that this system did not have that feature and i have been using it for about 2 months
i thank you for the system it has been great!
I get the general idea for the first one, though I am having a hard time understanding the last one (the flying hero with a lightning). I take it the orb starts from the air then get dropped into the ground or did I misunderstood something?
 
Level 5
Joined
Nov 3, 2018
Messages
73
I get the general idea for the first one, though I am having a hard time understanding the last one (the flying hero with a lightning). I take it the orb starts from the air then get dropped into the ground or did I misunderstood something?
Sorry english its not my first lenguage made an example
flying hero casts ability a lightning appears on the hero and lightning appears under him
my method to achieve this is was a dummy plus a timer that moves the dummy under him
1710421595963.png
 
Top