1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. The poll for our 11th Music Contest is up! Help us choose the most awesome cinematic tracks by casting a vote!
    Dismiss Notice
  3. Melee Mapping contest #3 - Poll is up! Vote for the best 4v4 melee maps!
    Dismiss Notice
  4. The 30th edition of the Modeling Contest is finally up! The Portable Buildings need your attention, so come along and have a blast!
    Dismiss Notice
  5. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice

Bloodstone (DotA) GUI v1.4

Submitted by Wietlol
This bundle is marked as approved. It works and satisfies the submission rules.
Description:
I made this spell on request of yrogerg.
This is based on the item Bloodstone from DotA.

Item Description:
- Kills the owner on activation.
- Gains a charge each time an enemy hero dies within 1675 range. Each charge grants 1 mana regeneration per second. If the bearer dies, 500 + 30 health per charge is restored to all allies within a 1675 radius, while the Bloodstone loses a third of its charges. A bloodmark is then placed where the bearer died, granting vision over a 1800 radius and allowing the bearer to gain nearby experience while dead.

How to install:
Copy or create a bloodstone item.
Copy or create all custom abilities from the test map.
Copy or create all global variables used in the test map.
Copy all triggers from the Bloodstone category into your map.
Copy all triggers from the Game Time System (GTS) into your map.
Copy the functions from the header file into your map.
Set the bloodstone variable to the item boodstone.

Triggers:
triggers
  • Bloodstone Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Bloodstone = Bloodstone
      • Set Bloodstone_Dummy_Hero = Dummy Hero
      • Set Bloodstone_Param_Heal_Base = 500.00
      • Set Bloodstone_Param_Heal_Increase = 30.00
      • Set Bloodstone_Param_Heal_Radius = 1675.00
      • Set Bloodstone_Param_Stack_Radius = 1675.00
      • Set Bloodstone_Param_Stack_Lose = 0.67
      • Set Bloodstone_Param_Visual_Radius = 1800.00
      • Set Bloodstone_Param_Mana_Gain = 1.00

  • Bloodstone Death Effect
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • -------- ------------------------------------ --------
      • -------- Local Variables --------
      • -------- ------------------------------------ --------
      • Custom script: local unit udg_TempUnit
      • Custom script: local unit udg_TempUnit2
      • Custom script: local fogmodifier udg_TempVisibilityModifier
      • Custom script: local effect udg_TempSpecialEffect
      • Custom script: local integer udg_TempInteger2
      • -------- ------------------------------------ --------
      • -------- A hero dies in range of an enemy hero with bloodstone --------
      • -------- ------------------------------------ --------
      • Set TempUnit = (Triggering unit)
      • Set TempPlayer = (Owner of TempUnit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (TempUnit is A Hero) Equal to True
        • Then - Actions
          • Set TempLocation = (Position of TempUnit)
          • Set TempUnitGroup = (Units within Bloodstone_Param_Stack_Radius of TempLocation)
          • Custom script: call RemoveLocation(udg_TempLocation)
          • Unit Group - Pick every unit in TempUnitGroup and do (Actions)
            • Loop - Actions
              • Set TempUnit2 = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (TempUnit2 is alive) Equal to True
                  • (TempUnit2 belongs to an enemy of TempPlayer) Equal to True
                  • (TempUnit2 has an item of type Bloodstone) Equal to True
                • Then - Actions
                  • For each (Integer TempInteger) from 1 to 6, do (Actions)
                    • Loop - Actions
                      • Set TempItem = (Item carried by TempUnit2 in slot TempInteger)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Item-type of TempItem) Equal to Bloodstone
                        • Then - Actions
                          • Item - Set charges remaining in TempItem to ((Charges remaining in TempItem) + 1)
                        • Else - Actions
                • Else - Actions
          • Custom script: call DestroyGroup(udg_TempUnitGroup)
          • Custom script: set udg_TempUnit2 = null
        • Else - Actions
      • -------- ------------------------------------ --------
      • -------- Condition for bloodstone effect --------
      • -------- ------------------------------------ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (TempUnit has an item of type Bloodstone) Equal to False
        • Then - Actions
          • Custom script: set udg_TempUnit = null
          • Skip remaining actions
        • Else - Actions
      • -------- ------------------------------------ --------
      • -------- Heal Allies --------
      • -------- ------------------------------------ --------
      • Set TempItem = (Item carried by TempUnit of type Bloodstone)
      • Set TempInteger = (Charges remaining in TempItem)
      • Set TempReal = (Bloodstone_Param_Heal_Base + (Bloodstone_Param_Heal_Increase x (Real(TempInteger))))
      • Set TempLocation = (Position of TempUnit)
      • Special Effect - Create a special effect at TempLocation using Abilities\Spells\NightElf\Tranquility\Tranquility.mdl
      • Set TempSpecialEffect = (Last created special effect)
      • Set TempUnitGroup = (Units within Bloodstone_Param_Heal_Radius of TempLocation)
      • Unit Group - Pick every unit in TempUnitGroup and do (Actions)
        • Loop - Actions
          • Set TempUnit2 = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TempUnit2 is alive) Equal to True
              • (TempUnit2 is A structure) Equal to False
              • (TempUnit2 belongs to an ally of TempPlayer) Equal to True
            • Then - Actions
              • Unit - Set life of TempUnit2 to ((Life of TempUnit2) + TempReal)
            • Else - Actions
      • Custom script: call DestroyGroup(udg_TempUnitGroup)
      • -------- ------------------------------------ --------
      • -------- Remove Charges --------
      • -------- ------------------------------------ --------
      • For each (Integer TempInteger) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set TempItem = (Item carried by TempUnit in slot TempInteger)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Item-type of TempItem) Equal to Bloodstone
            • Then - Actions
              • Set TempReal = ((Real((Charges remaining in TempItem))) x Bloodstone_Param_Stack_Lose)
              • Item - Set charges remaining in TempItem to (Integer(TempReal))
            • Else - Actions
      • -------- ------------------------------------ --------
      • -------- Add Vision --------
      • -------- ------------------------------------ --------
      • Set TempLocation = (Position of TempUnit)
      • Visibility - Create an initially Enabled visibility modifier for TempPlayer emitting Visibility from TempLocation to a radius of Bloodstone_Param_Visual_Radius
      • Set TempVisibilityModifier = (Last created visibility modifier)
      • -------- ------------------------------------ --------
      • -------- Keep Track Of Experience --------
      • -------- ------------------------------------ --------
      • Unit - Create 1 Bloodstone_Dummy_Hero for TempPlayer at TempLocation facing (Facing of TempUnit) degrees
      • Set TempUnit2 = (Last created unit)
      • Hero - Set TempUnit2 experience to (Hero experience of TempUnit), Hide level-up graphics
      • Unit - Make TempUnit2 Invulnerable
      • Custom script: call RemoveLocation(udg_TempLocation)
      • -------- ------------------------------------ --------
      • -------- Remove Heal Special Effect --------
      • -------- ------------------------------------ --------
      • Wait 3.67 game-time seconds
      • Special Effect - Destroy TempSpecialEffect
      • -------- ------------------------------------ --------
      • -------- Wait until hero revives --------
      • -------- ------------------------------------ --------
      • Custom script: loop
      • Custom script: exitwhen GetWidgetLife(udg_TempUnit) > 0
      • Custom script: call TriggerSleepAction(1)
      • Custom script: endloop
      • -------- ------------------------------------ --------
      • -------- Remove Vision --------
      • -------- ------------------------------------ --------
      • Visibility - Disable TempVisibilityModifier
      • Visibility - Destroy TempVisibilityModifier
      • -------- ------------------------------------ --------
      • -------- Add Experience --------
      • -------- ------------------------------------ --------
      • Set TempInteger = (Hero experience of TempUnit2)
      • Hero - Add TempInteger experience to TempUnit, Show level-up graphics
      • Unit - Remove TempUnit2 from the game
      • Custom script: set udg_TempUnit = null
      • Custom script: set udg_TempUnit2 = null
      • Custom script: set udg_TempVisibilityModifier = null
      • Custom script: set udg_TempSpecialEffect = null

  • Bloodstone Activation
    • Events
      • Unit - A unit Uses an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Bloodstone
    • Actions
      • Set TempItem = (Item being manipulated)
      • Item - Set charges remaining in TempItem to ((Charges remaining in TempItem) + 1)
      • Unit - Kill (Triggering unit)

  • Bloodstone Acquire Item
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Bloodstone
    • Actions
      • Set TempUnit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (TempUnit is in BloodstoneUnitGroup) Equal to False
        • Then - Actions
          • Unit Group - Add TempUnit to BloodstoneUnitGroup
          • Trigger - Turn on Bloodstone Mana Regeneration <gen>
        • Else - Actions
      • For each (Integer TempInteger) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set TempItem = (Item carried by TempUnit in slot TempInteger)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TempItem Not equal to (Item being manipulated)
              • (Item-type of TempItem) Equal to Bloodstone
            • Then - Actions
              • Item - Set charges remaining in (Item being manipulated) to (Charges remaining in TempItem)
              • Skip remaining actions
            • Else - Actions

  • Bloodstone Lose Item
    • Events
      • Unit - A unit Loses an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Bloodstone
    • Actions
      • Set TempUnit = (Triggering unit)
      • Set TempItem = (Item being manipulated)
      • For each (Integer TempInteger) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set TempItem2 = (Item carried by TempUnit in slot TempInteger)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TempItem2 Not equal to TempItem
              • (Item-type of TempItem2) Equal to Bloodstone
            • Then - Actions
              • Skip remaining actions
            • Else - Actions
      • Unit Group - Remove TempUnit from BloodstoneUnitGroup
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in BloodstoneUnitGroup) Equal to 0
        • Then - Actions
          • Trigger - Turn off Bloodstone Mana Regeneration <gen>
        • Else - Actions

  • Bloodstone Mana Regeneration
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in BloodstoneUnitGroup and do (Actions)
        • Loop - Actions
          • Set TempUnit = (Picked unit)
          • Set TempInteger = (Charges remaining in (Item carried by TempUnit of type Bloodstone))
          • Set TempReal = ((Real(TempInteger)) x Bloodstone_Param_Mana_Gain)
          • Unit - Set mana of TempUnit to ((Mana of TempUnit) + TempReal)


Images
Tooltip:
[​IMG]

Healing:
[​IMG]

While the unit is dead:
[​IMG]


Changelog:
- 1.4 - 03/03/2015 - Fixed the drop item bug and minor performance improvements.
- 1.3 - 01/03/2015 - Added parameters and reset normal Wait timer.
- 1.2 - 04/02/2015 - Update on review of IcemanBo.
Merged the two "A unit dies" triggers to one.
Fixed a bug where units would not be removed from the mana regeneration group.
Made a variable for the ex-hardcoded dummy hero.
Replaced Wait gametime with a custom wait timer which is more accurate and uses a global timer.
A little code optimization.
- 1.1 - Now sets the dummy unit's experience to the experience of the owner of bloodstone.
This is required for level-dependant experience reduction.
- 1.0 - Uploaded this spell on the Hive.

Keywords:
DotA, Bloodstone.
Contents

Just another Warcraft III map (Map)

Reviews
Moderator
IcemanBo: -date: 3rd March 2015 -submission: Bloodstone (DotA) GUI v1.4 http://www.hiveworkshop.com/forums/spells-569/bloodstone-dota-gui-v1-4-a-261704/index2.html#post2660263 02:26, 3th Feb 2015 IcemanBo:...
  1. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Last edited: Mar 3, 2015
  2. Daffa the Mage

    Daffa the Mage

    Map Moderator

    Joined:
    Jan 30, 2013
    Messages:
    7,311
    Resources:
    22
    Packs:
    1
    Maps:
    8
    Spells:
    12
    Tutorials:
    1
    Resources:
    22
    Pretty great, though the wait kinda annoys me a little, else seems fine, but I don't check the code fully yet.
     
  3. Mythic

    Mythic

    Joined:
    Apr 24, 2012
    Messages:
    7,510
    Resources:
    41
    Models:
    29
    Icons:
    1
    Maps:
    3
    Spells:
    6
    Tutorials:
    2
    Resources:
    41
    Nice locals technique.
    This line though;
    click
    • Set TempUnitGroup = (Units within 1675.00 of TempLocation matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True) and (((Matching unit) has an item of type Bloodstone) Equal to True))))

    please store the picked unit into a variable in the loop, then reference that unit in an ITE with these conditions. That way it's more readable and is more efficient with less calls.
     
  4. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    @Daffa the Mage
    The wait annoys you?
    There are 2 waits in this trigger. One of them being the duration of how long the visual effect is shown.
    The second one is a 1 second check to tell when the hero is revived.
    The first one is visual only and therefor has no reason to be changed into a timer.
    The other one does have a behavior difference but I would rather have a 1 second delay between the revive of the hero and the stuff that it should do than making an array of stuff or hashtable to save the hero and get its id by the handle of the timer.
    There is no way you could do anything in that <1 second.

    @Mythic
    I actually was annoyed by the pick every unit but now that I think of it.
    It has no actual difference between those two :) (Except for the visual and editable stuff.)
     
  5. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    Not trying to be a prick but game-time waits leak a reference:
    Code (vJASS):

    function PolledWait takes real duration returns nothing
       @local timer t@
        local real  timeRemaining

        if (duration > 0) then
            set t = CreateTimer()
            call TimerStart(t, duration, false, null)
            loop
                set timeRemaining = TimerGetRemaining(t)
                exitwhen timeRemaining <= 0

                // If we have a bit of time left, skip past 10% of the remaining
                // duration instead of checking every interval, to minimize the
                // polling on long waits.
                if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                    call TriggerSleepAction(0.1 * timeRemaining)
                else
                    call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
                endif
            endloop
            call DestroyTimer(t)
        endif
    endfunction
     
     
  6. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    In that case I will put a nice function in the header that does exacly the same except for the leak... would you be satisfied then?

    like this
    Code (vJASS):
    function CustomWait takes real duration returns nothing
        local timer t
        local real  timeRemaining

        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.5 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call PauseTimer(t)
        call DestroyTimer(t)
        set t = null
    endfunction
     
  7. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    There is no need to satisfy me, I just pointed it out. Also, only mods can decide if that's acceptable or not.
     
  8. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    In that case I will use the standard wait timer.

    I never said that you had to approve did I?

    But for real, if a non-moderator can give proper/true/helpfull and clear feedback and suggestions, then it is equally appreciated as the feedback from a moderator.

    Ofcourse I want to remove the pending and let my resources be approved but every feedback or suggestion helps to achieve that ain't I right?

    EDIT: As I just took a better look at the wait function, I would not even create a new timer. I would make a timer at the start of the game that runs for one hour and get the (3600 - remaining time + 3600 * number of times that it ran out.) to get the game time instead.
    With that, I reduce the amount of timers used in my custom polledwaits from (one for every polledwait) to ONE!
    Next to that... Who doesn't want to be able to get the current gametime? There could be many stuff that would improve by using that variable.
     
  9. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    Nor did I imply that, I was clarifying that only a mod can answer that question you asked.

    People often use timers and its callback for that since it has better precision than sleeps.
     
  10. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    I am aware of the inaccurate use of timers, it is clearly visible when you see the code of the PolledWait and I assume that TriggerSleepAction works almost the same.

    But as I said before:
    If there is no effect on behavior or data (which only leaves visual effect), like in the first wait timer, the prefect accuracy is not required.
    For the second one there are two options:
    1. Use a TriggerSleepAction and suffer from a <1 second delay.
    2. Create a timer and save the hero and timer in an array (with indexer) or in a hashtable and retrieve them once the timer runs out.

    I chose the first because the stuff that has to be made is too much to achieve such a small thing. I mean who can do something within less than one second to actually make any difference? You get the picture.
     
  11. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    They do since PolledWait also uses sleep calls.
     
  12. Almia

    Almia

    Joined:
    Apr 24, 2012
    Messages:
    4,839
    Resources:
    35
    Spells:
    30
    Tutorials:
    4
    JASS:
    1
    Resources:
    35
    I think both of you should argue with Nestharus, who is an expert in timers
     
  13. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    I wouldn't call this an argument, more like exchanging information.
     
  14. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Update - 1.1:
    Now sets the dummy unit's experience to the experience of the owner of bloodstone.
    This is required for level-dependant experience gain reduction.
     
  15. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    5,853
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Make more configurable. Like effect, range, specific values, etc.

    onDeath -> "remove charges": You make two operations to calculate the correct charge. Just make "Chrages*0.66".

    When you keep track of experience, do not hardcode the unit type.

    We might talk about the wait loop some later.
    Also, you use "Wait 3,62 seconds". Im curious of where this strange value come from.
    By the way, waits are not that accurate. It does not make much sense to make such precice values. (though it's nothing bad to trying be accurate^^)

    Why do you increase charges onAcivation?

    In trigger "Aquire Item" loop from 1-6, not 0-6. Also you do not need the "And - All Conditions" block.
    The only scenario an "And -All Conditions" block is useful may be in combination with an "Or - Any Condition" block.

    Your "lose item" will never remove the unit from ManaRegeneration.
    1) You use the "Add to group" function.
    2) The boolean check will never match. It doesn't work like this. Find an other way.

    The trigger condition in "Add charge":
    Just PickAllUnitsInRange, and make the filter yourself by using If/Then/Else inside the enumeration function.
    Currently the line is very lond and just unreadable. It would be better like mentioned.

    Both death triggers could be combined into one. We try to practice the DRY principle: "Don't repeat yourself."

    I have no idea about this dota related stuff, but for a fan it might be useful.
     
  16. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Yea the second wait timer is made because I don't want to limit the user to the blizzard revive system... Because AoS maps almost never use the regular revive.

    The first wait timer is a little more interesting indeed.
    As soon as I get home, I will place the wait timer test map in my latest post in this thread.
    I will also change the regular wait timer with my Game Time Wait...
    Just a bit optimization of wait timers.

    I activate an item... It removes a charge... I add a charge.
    Good enough?
    I cannot add a charge when the hero dies because if he died on a natural way he would gain a free stack!


    In fact, I never played the original dota :D
    It was on request for a fan.

    Will do.
     
  17. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    5,853
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Hm, PolledWait() does not null the timer after removed, in the implemented function.

    Sounds plausible.
     
  18. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,653
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Sounds more like a feature... but then a glitch.
    When you have 9 stacks for example.
    When you die regulary you have 9 - (9*0.66(=3)) = 6 stacks.
    When you activate the item (you use a stack), you will have 9 - 1 = 8 stacks.
    Then you die and you will have 8 - (8*0.66(=3)) = 5 stacks.
    That is a glitch... I don't like glitches enough.

    That is true...

    Here is my version of PolledWait(). It is more accurate but can be shorter than the requested duration.
    You get (ussually) a maximum difference between -0.075 and +0.075.
    The real difference is mostly 0 or +/-0.025.
    It cannot be used below 1 second though. But I would never tell someone to use wait timers or custom waits for those duration just because of how "TriggerSleepAction()" works.

    It also does not make a timer for each wait. Instead it uses one global timer which is the gametime. It is very easy code:
    Code (vJASS):
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  Header File
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    function GetGameTime takes nothing returns real
        return 3600*udg_GTS_Hours + TimerGetElapsed(udg_GTS_Timer)
    endfunction

    function GameTimeWait takes real duration returns nothing
        local real starttime = GetGameTime()
        local real endtime = GetGameTime() + duration
        local real remainingtime
        local real timerfactor
       
        if (duration > 0) then
            loop
                if GetGameSpeed() == MAP_SPEED_SLOWEST then
                    set remainingtime = endtime - GetGameTime() - 0.045
                elseif GetGameSpeed() == MAP_SPEED_SLOW then
                    set remainingtime = endtime - GetGameTime() - 0.035
                elseif GetGameSpeed() == MAP_SPEED_NORMAL then
                    set remainingtime = endtime - GetGameTime() - 0.075
                elseif GetGameSpeed() == MAP_SPEED_FAST then
                    //Untested yet
                    set remainingtime = endtime - GetGameTime()
                elseif GetGameSpeed() == MAP_SPEED_FASTEST then
                    //Untested yet
                    set remainingtime = endtime - GetGameTime()
                endif
               
                exitwhen remainingtime <= 0
                if remainingtime > 1 then
                    call TriggerSleepAction(0.5 * remainingtime)
                endif
                call TriggerSleepAction(0.05 * remainingtime)
            endloop
        endif
        set udg_TempReal = GetGameTime() - starttime
    endfunction

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  Trig_GTS_System
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    function GTS_Add_Hour takes nothing returns nothing
        set udg_GTS_Hours = udg_GTS_Hours + 1
    endfunction

    function InitTrig_GTS_System takes nothing returns nothing
        set udg_GTS_Timer = CreateTimer()
        call TimerStart(udg_GTS_Timer, 3600, true, function GTS_Add_Hour)
    endfunction


    It is that simple. I am too lazy to do the FAST and FASTEST part because if I want those two I need to make triggers to set the game speed to those values.
    When using + and - you switch between SLOWEST, SLOW and NORMAL.

    EDIT:
    Sorry about the range and stuff but those things are only used once.
    I don't like having a lot of global variables that I never use.
    Because the effects are GUI, I do not have to change them. And many people can read the effect data without a problem.
    So I don't really see the point of having 10 extra variables if everyone already is able to change it. Sorry if you feel offended.

    -----------------------------------------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------------------------------------

    Update 1.2

    I just released version 1.2

    Here are the changes:
    • Merged the two "A unit dies" triggers to one.
    • Fixed a bug where units would not be removed from the mana regeneration group.
    • Made a variable for the ex-hardcoded dummy hero.
    • Replaced Wait gametime with a custom wait timer which is more accurate and uses a global timer.
    • A little code optimization.
     

    Attached Files:

    Last edited: Feb 17, 2015