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

Chronosphere

Status
Not open for further replies.
I'm trying to make an Aoe ability that locks every unit in time except the caster and this is what I have so far...

  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • Set ChCaster = (Casting unit)
      • Set ChPoint = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of ChCaster) at ChPoint facing Default building facing degrees
      • Unit Group - Add (Last created unit) to ChGroup[0]
      • Hashtable - Save 60 as 1 of (Key (Last created unit)) in HashLocked
      • Trigger - Turn on Chronosphere loop <gen>
      • Wait 6.00 seconds
      • If ((Number of units in ChGroup[0]) Equal to 0) then do (Trigger - Turn off Chronosphere loop <gen>) else do (Do nothing)
  • Chronosphere loop
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in ChGroup[0] and do (Actions)
        • Loop - Actions
          • Set Remaining = (Load 0 of (Key (Picked unit)) from HashLocked)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Remaining Greater than 0
            • Then - Actions
              • Set Remaining = (Remaining - 1)
              • Hashtable - Save Remaining as 1 of (Key (Picked unit)) in HashLocked
            • Else - Actions
              • Unit Group - Remove (Picked unit) from ChGroup[0]
              • Unit - Kill (Picked unit)
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in HashLocked
          • Unit Group - Pick every unit in (Units within 400.00 of (Position of (Picked unit)) matching ((Owner of (Matching unit)) Not equal to (Owner of (Picked unit)))) and do (Actions)
            • Loop - Actions
              • Unit Group - Add (Picked unit) to ChGroup[1]
      • Unit Group - Pick every unit in ChGroup[1] and do (Actions)
        • Loop - Actions
          • Unit - Pause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between (Position of (Picked unit)) and (Position of (Triggering unit))) Greater than 400.00
            • Then - Actions
              • Unit - Unpause (Picked unit)
              • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
            • Else - Actions
I've propbably spent about a day on this one in total and nothing I wants to happen will hapen! :vw_wtf:

1. The once again the chronosphere Doesn't want to last longer than a second
2. I deactivated the hashtable thing to see if units get paused and they don't.
3.
  • (Distance between (Position of (Picked unit)) and (Position of (Triggering unit))) Greater than 400.00
I know this one is wrong. with triggering unit, I mean 'chronosphere' and I couldn't find it. :(
help PLEASE.
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
For your point #3:
Yes you won't be able to call "Chronosphere" that way. You will need to create a unit variable and save Chronosphere in it after you create it.
Then you will have
"(Distance between (Position of (Picked unit)) and (Position of Chronosphere_var)) Greater than 400.00"
(Chronosphere_var is unit variable)
However that line will leak locations.
You will need to save locations of both picked unit and chronosphere_var and then find out the distance between those points and finally destroy both points.

It should be something like this:
  • Set Temp_Point[1] = (Position of Chronosphere_var)
  • Unit Group - Pick every unit in ChGroup[1] and do (Actions)
    • Loop - Actions
      • Set Temp_Point[2] = (Position of (Picked unit))
      • Unit - Pause (Picked unit)
      • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between Temp_Point[1] and Temp_Point[2]) Greater than 400.00
        • Then - Actions
          • Unit - Unpause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
        • Else - Actions
      • Custom script: call RemoveLocation(udg_Temp_Point[2])
      • Custom script: set udg_Temp_Point[2] = null
  • Custom script: call RemoveLocation(udg_Temp_Point[1])
  • Custom script: set udg_Temp_Point[1] = null
NOTICE
- I set Temp_Point[1] outside/before the group loop, because Chronosphere will be in the same spot during the time you check distance of each unit in ChGroup[1]

- In the group loop you set position of picked unit as Temp_Point[2], check the distance between points and then you destroy Temp_Point[2] location to prevent leak (notice those custom script lines are in the group loop).

- After you have picked all units in ChGrop[1] and check their distance, you destroy Temp_Point[1] location. You do it outside the group loop, else you will destroy Temp_Point[1] after first picked unit has had its distance checked.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
what function are u referring to ? and if ur referring to the custom script then u need to learn these as the custom script he listed are to clean leaks. if u dont clean the leaks ur game will lag horribly after a short time period here is a link to the leak fixing guide http://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/

if u are tlking about the distance comparison. then do condition / real comparison / math - distance between points / then set the values

For your point #3:
Yes you won't be able to call "Chronosphere" that way. You will need to create a unit variable and save Chronosphere in it after you create it.
(Chronosphere_var is unit variable)
 
Sorry for taking so long to reply and thanks for all your help. I gived up on chronosphere. I tried what you guys told me and many other stuff but nothing works. I also gave it a AOE buff that pause units but it takes about half a second for units to recieve and remove the buff.
Thanks for reminding me of leaks

You don't need to add the units to that group. Just enum them on that block.
What do you mean?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
If you use Unit Indexer you could just pause all the units, add them to an array, and when the spell finishes, unpause them. You can do the same with a Unit Group or a Hashtable
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
First you must understand the Spell Concept.
It locks any unit within the AOE of the Chronosphere, this means that any unit enters the Chronosphere will be locked, not upon casting only, but during the runtime of the spell.
That is why you should not add them to Unit Group, just Pick Every Unit group function and lock them every iteration.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I would create a timer and periodically stun any unit inside the cronosphere that's not stunned yet. I would index all those units into a unit array, and when the timer expires, I loop through the array and remove the stun from all units.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
u should do what defskull suggested. i think its the most efficient way.
if u want to check that there out of range / in range do something like this.

  • Set tempPoint1 = (Position of castingUnit)
    • Set tempGroup = (Units within 500.00 of tempPoint1)
    • Unit Group - Pick every unit in tempGroup and do (Actions)
      • Loop - Actions
        • Set tempUnit = (Picked unit)
        • Set tempPoint2 = (Position of tempUnit)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Distance between tempPoint1 and tempPoint2) Greater than or equal to 400.00
          • Then - Actions
            • -------- check if unit is paused / stunned and unpause / unstun it here. --------
          • Else - Actions
            • -------- check if unit is paused / stunned. if it isnt pause / stun it here. --------
        • Custom script: call RemoveLocation( udg_tempPoint2)
        • Custom script: set udg_tempPoint2 = null
    • Custom script: call RemoveLocation( udg_tempPoint1)
    • Custom script: set udg_tempPoint1 = null
    • Custom script: call DestroyGroup( udg_tempGroup)
    • Custom script: set udg_tempGroup = null
 
I would create a timer and periodically stun any unit inside the cronosphere that's not stunned yet. I would index all those units into a unit array, and when the timer expires, I loop through the array and remove the stun from all units.

The reason why I chose to pause units is because it also pause buff timers. It litiraly lock units into time. Anyway I don't know how to loop through arrays.
I tried what you guys said and this is the result:
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • Set pChronosphere[0] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of (Casting unit)) at pChronosphere[0] facing Default building facing degrees
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosphere[0]
  • Actions
    • Unit Group - Pick every unit in gChronosphere[0] and do (Actions)
      • Loop - Actions
        • Set uChronosphere[0] = (Picked unit)
    • Unit Group - Pick every unit in (Units within 400.00 of (Position of uChronosphere[0])) and do (Actions)
      • Loop - Actions
        • Set uChronosphere[1] = (Picked unit)
    • Set Global = (Units in (Playable map area))
    • Unit Group - Pick every unit in Global and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Picked unit) Equal to uChronosphere[1]
          • Then - Actions
            • Unit - Pause (Picked unit)
            • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
          • Else - Actions
            • Unit - Unpause (Picked unit)
            • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
    • Set uChronosphere[0] = No unit
    • Set uChronosphere[1] = No unit
This only pause 1 unit at a time and stays paused until the spell is casted somewhere else
EDIT: it also happens sometimes that if I enter the chronosphere while it has a paused unit then I get paused and the other one is unpaused.
 
Hey dimf I didn't read read your whole tutrail yet but I tried a diffirent strategy and it seems to work:
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • If (iChronosMUI[0] Greater than 23) then do (Set iChronosMUI[0] = 1) else do (Set iChronosMUI[0] = (iChronosMUI[0] + 1))
      • Set uChronosCaster[iChronosMUI[0]] = (Casting unit)
      • Unit - Create 1 Chronosphere for (Owner of (Casting unit)) at (Target point of ability being cast) facing Default building facing degrees
      • Unit - Set the custom value of (Last created unit) to iChronosMUI[0]
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • Trigger - Turn on Chronosphere loop <gen>
      • Wait 6.00 seconds
      • Trigger - Turn off Chronosphere loop <gen>
  • Chronosphere loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in gChronosEffect[0] and do (Actions)
        • Loop - Actions
          • Set iChronosMUI[1] = (Custom value of (Picked unit))
          • Set pChronosphere[iChronosMUI[1]] = (Position of (Picked unit))
      • Set gChronosTarget[iChronosMUI[1]] = (Units within 400.00 of pChronosphere[iChronosMUI[0]] matching ((Matching unit) Not equal to uChronosCaster[iChronosMUI[1]]))
      • Set Global = (Units in (Playable map area))
      • Custom script: call RemoveLocation(udg_pChronosphere[udg_iChronosMUI[1]])
      • Unit Group - Pick every unit in gChronosTarget[iChronosMUI[1]] and do (Actions)
        • Loop - Actions
          • Unit - Pause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
      • Unit Group - Pick every unit in (Units in (Playable map area) matching (((Matching unit) is in gChronosTarget[iChronosMUI[1]]) Equal to False)) and do (Actions)
        • Loop - Actions
          • Unit - Unpause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
      • Custom script: call DestroyGroup(udg_Global)
      • Custom script: call DestroyGroup(udg_gChronosTarget[udg_iChronosMUI[1]])
But why doesn't the units get unpaused?

EDIT: I've just found that this isn't MUI. When I cast a second Chronosphere then the rest of the map is unpaused.
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
The spell isn't MUI, because in your ini trigger you use
turn loop trigger on
wait 6 seconds
turn loop trigger off

If Unit A casts this spell and after 3 seconds Unit B casts this spell, then it will
turn loop trigger on (started by Unit A)
after 3 seconds
attempt to turn loop trigger on (started by Unit B)
after 3 seconds
turn loop trigger off (6 seconds passed since Unit A casted this spell)
after additional 3 seconds
attempt to turn loop trigger off (now 6 seconds passed since Unit B casted this spell)

You have to get rid of that wait; you have to check instead how many instances of that spell are active. It can be find out for example by checking if any "Chronosphere" unit is alive. If at least 1 is alive, then at least 1 instance of the spell is active. If none are alive, then 0 instances are active and you can switch loop trigger off.

---
In your second trigger you have many errors

#1, this line:
  • Set gChronosTarget[iChronosMUI[1]] = (Units within 400.00 of pChronosphere[iChronosMUI[0]] matching ((Matching unit) Not equal to uChronosCaster[iChronosMUI[1]]))
you have "units within 400 of <variable>[0]" - shouldn't the index be 1 instead of 0?

#2
you set global = units in map, but you don't use this global anywhere.

#3
In your second trigger - put all those actions that are not in the 1st "pick every unit in" loop inside that loop. You should do that because you want to cycle through all chronospheres. What you have right now is that you check the last chronosphere only. Putting all actions of your second trigger into the 1st group's loop will also remove location leaks you have there.
 
I must admid I made some stupid mistakes. here is the new trigger:
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • If (iChronosMUI[0] Greater than 23) then do (Set iChronosMUI[0] = 1) else do (Set iChronosMUI[0] = (iChronosMUI[0] + 1))
      • Set uChronosCaster[iChronosMUI[0]] = (Casting unit)
      • Unit - Create 1 Chronosphere for (Owner of (Casting unit)) at (Target point of ability being cast) facing Default building facing degrees
      • Unit - Set the custom value of (Last created unit) to iChronosMUI[0]
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • Trigger - Turn on Chronosphere loop Copy <gen>
      • Wait 6.00 seconds
      • If ((Number of units in gChronosEffect[0]) Equal to 0) then do (Trigger - Turn off Chronosphere loop Copy <gen>) else do (Do nothing)
  • Chronosphere loop Copy
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in gChronosEffect[0] and do (Actions)
        • Loop - Actions
          • Set iChronosMUI[1] = (Custom value of (Picked unit))
          • Set pChronosphere[iChronosMUI[1]] = (Position of (Picked unit))
          • Set gChronosTarget[iChronosMUI[1]] = (Units within 400.00 of pChronosphere[iChronosMUI[1]] matching ((Matching unit) Not equal to uChronosCaster[iChronosMUI[1]]))
          • Custom script: call RemoveLocation(udg_pChronosphere[udg_iChronosMUI[1]])
          • Unit Group - Pick every unit in (Units in (Playable map area) matching (((Matching unit) is in gChronosTarget[iChronosMUI[1]]) Equal to False)) and do (Actions)
            • Loop - Actions
              • Unit - Unpause (Picked unit)
              • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
          • Unit Group - Pick every unit in gChronosTarget[iChronosMUI[1]] and do (Actions)
            • Loop - Actions
              • Unit - Pause (Picked unit)
              • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
      • Custom script: call DestroyGroup(udg_gChronosTarget[udg_iChronosMUI[1]])
Its a little bit better. If I now cast a second cronosphere then the victem of the first one is repeatly paused and unpaused. Otherwise even if the chronosphere dies, the victem remains paused
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
In first trigger, get rid of wait completely, the last line that checks number of chronospheres - put that in ITE at the start of your loop trigger. Like this
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Number of units in AutoTurret_Group) Equal to 0
    • Then - Actions
      • Trigger - Turn off (This trigger)
      • Skip remaining actions
    • Else - Actions
But this won't work that well anyway, because this checks units in group - it counts both dead and alive units in it. So even though the chronosphere is dead, it is still in the unit group. You would need to remove them from that group, but that may cause problems when unpausing units.

Also, that custom script for destroying group should be in the 1st group loop, because inside that loop (for each chronosphere) you create gChronosTarget[iChronosMUI[1]].
Right now it will create gChronosTarget[iChronosMUI[1]] x times (x being the number of chronospheres), but you will destroy only the last one.


Anyway, what is that spell supposed to do? Right now you pick every unit in map and unpause it and then you pick every unit in target group and pause them. Does the chronosphere move or something? Also, unpausing all units that are not affected by this spell may cause problems (for example if another trigger pauses units, this spell would unpause them)
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
I see you used arrays in your tutrail but what if the 'maxindexnova' becomes more than the size of the array? whouldn't the index value be ignored?

if that happens it means ur doing something wrong.
u should never have a spell that hits 8191.
u need to de-index the spell.
if u look in the loop trigger look for the de-index part. u will see the integer getting reduced and the units and other values getting de-indexed
 
Oh ok now I see thanks.
before going to the loop, did I index correctly?
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • Set iChronosMaxIndex = (iChronosMaxIndex + 1)
      • Set uChronosCaster[iChronosMaxIndex] = (Casting unit)
      • Set pChronosphere[iChronosMaxIndex] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of uChronosCaster[iChronosMaxIndex]) at pChronosphere[iChronosMaxIndex] facing Default building facing degrees
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • If (iChronosMaxIndex Equal to 1) then do (Trigger - Turn on Chronosphere loop <gen>) else do (Do nothing)
And for your loop trigger in your tutrial you used 'For each (Integer tempInt) from 1 to maxIndexNova, do (Actions)' but where did you give 'Integer tempInt' a value?
 
Ok I was wondering how that for each integer thing works. Here is the newest trigger. [hidden="trigger']
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • Set iChronosMaxIndex = (iChronosMaxIndex + 1)
      • Set uChronosCaster[iChronosMaxIndex] = (Casting unit)
      • Set pChronos[iChronosMaxIndex] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of uChronosCaster[iChronosMaxIndex]) at pChronos[iChronosMaxIndex] facing Default building facing degrees
      • Set uChronosEffect[iChronosMaxIndex] = (Last created unit)
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • If (iChronosMaxIndex Equal to 1) then do (Trigger - Turn on Chronosphere loop <gen>) else do (Do nothing)
  • Actions
    • For each (Integer TempInt) from 1 to iChronosMaxIndex, do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (uChronosEffect[TempInt] is dead) Equal to True
          • Then - Actions
            • Unit Group - Remove uChronosEffect[TempInt] from gChronosEffect[0]
            • Custom script: call RemoveLocation(udg_pChronos[udg_TempInt])
          • Else - Actions
        • Unit Group - Pick every unit in (Units within 400.00 of pChronos[TempInt] matching ((Matching unit) Not equal to uChronosCaster[TempInt])) and do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • ((Picked unit) is in gChronosEffect[0]) Equal to False
              • Then - Actions
                • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
                • Unit - Pause (Picked unit)
              • Else - Actions
                • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
                • Unit - Unpause (Picked unit)
[/hidden]
I'm not done with the loop yet but I tested it and it doesn't unpause the unit at the end of the ability. In the first loop it's suppose to remove the location where the sphere was and at the end of the loop, the picked units won't be within 400 range of the removed location and will be resumed.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
ok to do what u want u need to the ChronusEffect thing to max index in the top trigger and temp int in the bottom trigger.

then u actually need to pick all units in lets say 600 range then check if the distance from ur unit to the picked unit is under 400. If it isnt under 400 then u remove the unit and unpause the unit. Alsou leak a unit group.
And u never de-index anything.

is this an aoe spell that the units can move away from the aoe ?
if it is u need to index the sphere. then for the loop trigger u do a integer check to deal damage in the then block of the ITE. then u make a tempGroup and pick all units in group then damage picked unit then remove it from the group.
Then u destroy the group.
When ur final counter hits the end number then u de-index the whole thing.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
If you know the Chronosphere duration you can create a timer to end it, and add the time left on that timer to any unit coming within range, so all the timers expire at the same time unpausing the units. Also, i'm not sure, but you can create a trigger with "A unit comes xx distance from X unit/point" and pause the units based on distance, and not by loop.
 
Thanks Spartipilio, there's already a 6 secs expansion timer for the sphere in the casting trigger. Ok guys I know I still have a lot to learn about MUI but in my opinion I don't need a couter to turn of the trigger because when the chronosphere is done, the trigger will remove the chronosphere and it's location location. when there is no spheres left then it will turn off. Also this spell deals no damage. it peroidicly locks any kind of unit in time. however the locked unit can escape the chronosphere when another unit outside use a spell that can change the locked unit's posision. Anyway my spell finaly works! :wink: Only one problem. when there is more than one chronosphere, the victems gets paused and unpaused repeatly. I know the problem but don't know how to fix it. the trigger sees that the unit is in 400 range with point[1] then it pauses but for the next intiger the unit is further than 400 from point[2] so then it unpauses. :(

Here is the file, please help
 

Attachments

  • Chronosphere.w3x
    26.5 KB · Views: 41
Level 20
Joined
Jul 14, 2011
Messages
3,213
Damn... I was making the ability with JASS and timers and stuff, but I forgot the detail about units outside the Chronosphere being able to change locked units position...
 
Damn... I was making the ability with JASS and timers and stuff, but I forgot the detail about units outside the Chronosphere being able to change locked units position...

interisting, where is your ablilty?

Bad news, the chronosphere only works twice :goblin_cry:

  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • Set iChronosMaxIndex = (iChronosMaxIndex + 1)
      • Set uChronosCaster[iChronosMaxIndex] = (Casting unit)
      • Set pChronos[iChronosMaxIndex] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of uChronosCaster[iChronosMaxIndex]) at pChronos[iChronosMaxIndex] facing Default building facing degrees
      • Set uChronosEffect[iChronosMaxIndex] = (Last created unit)
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • If (iChronosMaxIndex Equal to 1) then do (Trigger - Turn on Chronosphere loop <gen>) else do (Do nothing)
  • Chronosphere loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If ((Number of units in gChronosEffect[0]) Equal to 0) then do (Trigger - Turn off (This trigger)) else do (Do nothing)
      • For each (Integer TempInt) from 1 to iChronosMaxIndex, do (Actions)
        • Loop - Actions
          • -------- resume targrts on escape --------
          • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Distance between (Position of (Picked unit)) and pChronos[TempInt]) Greater than 400.00
                • Then - Actions
                  • Unit - Unpause (Picked unit)
                  • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
                • Else - Actions
          • -------- resume targets on ChDeath --------
          • -------- --------------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (uChronosEffect[TempInt] is dead) Equal to True
            • Then - Actions
              • Unit Group - Pick every unit in (Units within 400.00 of pChronos[TempInt]) and do (Actions)
                • Loop - Actions
                  • Unit - Unpause (Picked unit)
                  • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
              • Unit Group - Remove uChronosEffect[TempInt] from gChronosEffect[0]
              • Custom script: call RemoveLocation(udg_pChronos[udg_TempInt])
            • Else - Actions
          • -------- Pause units --------
          • Unit Group - Pick every unit in (Units within 400.00 of pChronos[TempInt] matching ((Matching unit) Not equal to uChronosCaster[TempInt])) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is in gChronosEffect[0]) Equal to False
                • Then - Actions
                  • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
                  • Unit - Pause (Picked unit)
                • Else - Actions
                  • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
                  • Unit - Unpause (Picked unit)
  • Chronosphere loop 2
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer TempInt) from 1 to iChronosMaxIndex, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Distance between (Position of (Picked unit)) and pChronos[TempInt]) Greater than 400.00
                • Then - Actions
                  • Unit - Unpause (Picked unit)
                  • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
                • Else - Actions
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I have it already with timers. Each unit in the range when the ability is cast has it's own timer, paused and stuff. When timer expires they're al unpaused, and the chrono is removed, and all that. When other units comes near they also become paused. The problem's that i'm not checking if they're still inside the Chronosphere... So, I actually think that doing the group loop is better than using the timers and stuff :p
 
Level 8
Joined
Feb 3, 2013
Messages
277
erm.. honestly I did not think such a simple question would take so long to answer uhh

i made a sample map for you, is this what you are looking for?

chronosphere like dota, faceless void, chornosphere*

MUI: yes
vJASS: yes
requires Cohadar's TT system

I assume you can do it in GUI too, you'll need to use an integer variable array to index each spell cast. You'll also need multiple triggers - for the looping effect. I'd rather make it on vjass tho lol. Would be pretty dam annoying if you ask me, use vJASS - it's the same thing as GUI, but provides more flexibility.

JASS:
scope Chronosphere initializer init 
    
    private struct data
        unit caster
        unit dummy
        location point
        integer count 
        player play
        group g = CreateGroup()
        
        static method create takes unit cast, location p returns thistype
            local thistype this = thistype.allocate()
            set this.caster = cast
            set this.point = p
            set this.play = GetOwningPlayer(this.caster)
            set this.count = (GetUnitAbilityLevel(this.caster, 'A000') * 2) + 4
            set this.dummy = CreateUnitAtLoc(this.play, 'h000', this.point, 0)
            return this
        endmethod
        
        method destroy takes nothing returns nothing
            call RemoveUnit(this.dummy)
            call RemoveLocation(this.point)
            call DestroyGroup(this.g)
            set this.g = null
            set this.caster = null
            set this.point = null
            set this.play = null
            set this.dummy = null
            call this.deallocate()
        endmethod
    endstruct
    
    private function T_Freeze takes nothing returns boolean
            local data d = TT_GetData()
            local unit fog
            if d.count == 0 then
                call GroupEnumUnitsInRangeOfLoc(d.g, d.point, 300, null)
                loop
                    set fog = FirstOfGroup(d.g)
                    exitwhen fog == null
                    call PauseUnit(fog, false)
                    call SetUnitTimeScale(fog, 1)
                    call GroupRemoveUnit(d.g, fog)
                endloop 
                call d.destroy()
                return true
            else
                call GroupEnumUnitsInRangeOfLoc(d.g, d.point, 300, null)
                loop
                    set fog = FirstOfGroup(d.g)
                    exitwhen fog == null
                    if GetUnitTypeId(fog) == 'E000' then
                    else
                        call PauseUnit(fog, true)
                        call SetUnitTimeScale(fog, 0)
                    endif
                    call GroupRemoveUnit(d.g, fog)
                endloop
            endif
            set d.count = d.count - 1
            return false
    endfunction
            
    private function T_Cond takes nothing returns boolean   
        local unit lv_caster = GetTriggerUnit()
        local location lv_point = GetSpellTargetLoc()
        local data d
        local unit fog
        
        if GetSpellAbilityId() == 'A000' then
            set d = data.create(lv_caster, lv_point)
            call TT_StartEx(function T_Freeze, d, .5)
            call GroupEnumUnitsInRangeOfLoc(d.g, d.point, 300, null)
            loop
                set fog = FirstOfGroup(d.g)
                exitwhen fog == null
                if GetUnitTypeId(fog) == 'E000' then
                else
                    call PauseUnit(fog, true)
                    call SetUnitTimeScale(fog, 0)
                endif
                call GroupRemoveUnit(d.g, fog)
            endloop
        endif
        
        set lv_caster = null
        set lv_point = null
        return false
    endfunction
    
    private function init takes nothing returns nothing 
        local trigger t = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, function T_Cond)
        
        set t = null
    endfunction
    
endscope
 

Attachments

  • Chronosphere.w3x
    26.5 KB · Views: 45
Last edited:
Erm, does the spell affects the building?
If not, add
((Picked Unit) is a Building/Structure *i forget which one*) Equal to False

condition at the picking-unit conditions
Actually the more things it pauses, how better. It should pause magic immune, that thing that blocks spells, invaurnable, expansion timers, HP regen, buildings - everything except the caster. For now I'm just trying to make the spell work properly. By the way thanks for asking :)

I have a chronosphere spell in my map but sadly I can't post it here.
Why not??

erm.. honestly I did not think such a simple question would take so long to answer uhh

i made a sample map for you, is this what you are looking for?

chronosphere like dota, faceless void, chornosphere*

MUI: yes
vJASS: yes
requires Cohadar's TT system

I assume you can do it in GUI too, you'll need to use an integer variable array to index each spell cast. You'll also need multiple triggers - for the looping effect. I'd rather make it on vjass tho lol. Would be pretty dam annoying if you ask me, use vJASS - it's the same thing as GUI, but provides more flexibility.
Nice thanks :D. however if I add another caster then the trigger crash. it says 'TESH.alwaysfold=0' could not by read. Sorry, I know less than 0 about jass but thanks for sharing :).

About my previous question:
  • A horrible condition problem
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • ((Picked unit) is in gChronos[1]) Equal to True
              • ((Picked unit) is in gChronos[2]) Equal to True
              • ((Picked unit) is in gChronos[3]) Equal to True
              • ((Picked unit) is in gChronos[4]) Equal to True
              • ((Picked unit) is in gChronos[5]) Equal to True
              • ((Picked unit) is in gChronos[6]) Equal to True
              • ((Picked unit) is in gChronos[7]) Equal to True
              • ((Picked unit) is in gChronos[8]) Equal to True
              • ((Picked unit) is in gChronos[9]) Equal to True
              • ((Picked unit) is in gChronos[10]) Equal to True
              • ((Picked unit) is in gChronos[11]) Equal to True
              • ((Picked unit) is in gChronos[12]) Equal to True
              • ((Picked unit) is in gChronos[13]) Equal to True
              • ((Picked unit) is in gChronos[14]) Equal to True
              • ((Picked unit) is in gChronos[15]) Equal to True
              • ((Picked unit) is in gChronos[16]) Equal to True
              • ((Picked unit) is in gChronos[17]) Equal to True
              • ((Picked unit) is in gChronos[Blah blah...]) Equal to True
        • Then - Actions
          • Unit - Pause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
          • Unit - Pause the expiration timer for (Picked unit)
        • Else - Actions
          • Unit - Unpause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
          • Unit - Unpause the expiration timer for (Picked unit)
Please tell me a better way to state this condition

EDIT: just a second I just got a new idea. I will see if it will work when I set TempInt to each Int from 1 to 24 (the size of my arrays) and use it in 'if any conditions are true'

EDIT: Finaly it's done! but >.<
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • If (iChronosMaxIndex Greater than 23) then do (Set iChronosMaxIndex = 1) else do (Set iChronosMaxIndex = (iChronosMaxIndex + 1))
      • Set uChronosCaster[iChronosMaxIndex] = (Casting unit)
      • Set pChronos[iChronosMaxIndex] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of uChronosCaster[iChronosMaxIndex]) at pChronos[iChronosMaxIndex] facing Default building facing degrees
      • Set uChronosEffect[iChronosMaxIndex] = (Last created unit)
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosEffect[0]
      • Trigger - Turn on Chronosphere loop <gen>
      • -------- Caster, point and dummy is saved --------
  • Chronosphere loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If ((Number of units in gChronosEffect[0]) Equal to 0) then do (Trigger - Turn off (This trigger)) else do (Do nothing)
      • For each (Integer TempInt) from 1 to iChronosMaxIndex, do (Actions)
        • Loop - Actions
          • -------- Cleans up finished ability --------
          • -------- ------------------------------------ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (uChronosEffect[TempInt] is dead) Equal to True
            • Then - Actions
              • Unit Group - Remove uChronosEffect[TempInt] from gChronosEffect[0]
              • Set uChronosEffect[TempInt] = No unit
              • Custom script: call RemoveLocation(udg_pChronos[udg_TempInt])
              • Unit Group - Pick every unit in gChronosTarget[TempInt] and do (Actions)
                • Loop - Actions
                  • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
                  • Unit - Unpause (Picked unit)
            • Else - Actions
          • -------- Do actions on remaing chronospheres --------
          • Set Global = (Units in (Playable map area))
          • Set gChronosTarget[TempInt] = (Units within 400.00 of pChronos[TempInt] matching ((Matching unit) Not equal to uChronosCaster[TempInt]))
          • Unit Group - Pick every unit in gChronosTarget[TempInt] and do (Actions)
            • Loop - Actions
              • If (((Picked unit) is in gChronosEffect[0]) Equal to False) then do (Unit Group - Remove (Picked unit) from gChronosTarget[TempInt]) else do (Do nothing)
          • Unit Group - Pick every unit in gChronosTarget[TempInt] and do (Actions)
            • Loop - Actions
              • Unit - Pause (Picked unit)
              • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
1. - Chronospheres pauses each other :/
so I was smart and said:
  • If (((Picked unit) is in gChronosEffect[0]) Equal to False) then do (Unit Group - Remove (Picked unit) from gChronosTarget[TempInt]) else do (Do nothing)
But then it doesn't pause anything. please help

2. - some leaks I think
 
Last edited:
Level 8
Joined
Feb 3, 2013
Messages
277
kay, meng I've been messing around with the triggers in your map for at least like 2 hours and I just can't get a GUI version to be MUI;;

Like the LEAST i can do to make a GUI version MUI, is pass a lot of data using custom scripts and if you're gonna do that - you might as well as use the vJASS version instead (which is a lot cleaner). And the vJASS one I posted up there is flawless compared to this one we have in your map.

i'll show you how to set it up too
 
kay, meng I've been messing around with the triggers in your map for at least like 2 hours and I just can't get a GUI version to be MUI;;

Like the LEAST i can do to make a GUI version MUI, is pass a lot of data using custom scripts and if you're gonna do that - you might as well as use the vJASS version instead (which is a lot cleaner). And the vJASS one I posted up there is flawless compared to this one we have in your map.

Allright then thanks :). I will use your version but in the mean time I will try to make the GUI version MUI because I like a challenge ;)

+rep

I want to give rep to deathismyfriend too but I need to spread some rep to others before I can give him again...
 
My virus defender has balcked a virus when I tried to download JNGP 1.5 :(. About the GUI chronosphere: [hidden="trigger]
  • Chronosphere spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chronosphere
    • Actions
      • If (iChronosMaxIndex Greater than 23) then do (Set iChronosMaxIndex = 1) else do (Set iChronosMaxIndex = (iChronosMaxIndex + 1))
      • Set uChronosCaster[iChronosMaxIndex] = (Casting unit)
      • Set pChronos[iChronosMaxIndex] = (Target point of ability being cast)
      • Unit - Create 1 Chronosphere for (Owner of uChronosCaster[iChronosMaxIndex]) at pChronos[iChronosMaxIndex] facing Default building facing degrees
      • Set uChronosEffect[iChronosMaxIndex] = (Last created unit)
      • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
      • Unit Group - Add (Last created unit) to gChronosTarget[0]
      • Trigger - Turn on Chronosphere loop <gen>
      • -------- Caster, point and dummy is saved --------
  • Chronosphere loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If ((Number of units in gChronosEffect[0]) Equal to 0) then do (Trigger - Turn off (This trigger)) else do (Do nothing)
      • For each (Integer TempInt) from 1 to iChronosMaxIndex, do (Actions)
        • Loop - Actions
          • -------- ------------------------------------------------------ --------
          • -------- Cleans up finished ability --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (uChronosEffect[TempInt] is dead) Equal to True
            • Then - Actions
              • Unit Group - Remove uChronosEffect[TempInt] from gChronosEffect[0]
              • Set uChronosEffect[TempInt] = No unit
              • Custom script: call RemoveLocation(udg_pChronos[udg_TempInt])
            • Else - Actions
          • Set gChronosTarget[1] = (Units within 400.00 of pChronos[TempInt] matching ((Matching unit) Not equal to uChronosCaster[TempInt]))
          • Unit Group - Pick every unit in gChronosTarget[1] and do (Actions)
            • Loop - Actions
              • Unit Group - Remove (Picked unit) from gChronosTarget[0]
      • -------- ------------------------------------------------------ --------
      • -------- Pause/Unpause units --------
      • Unit Group - Pick every unit in gChronosTarget[0] and do (Actions)
        • Loop - Actions
          • Animation - Change (Picked unit)'s vertex coloring to (0.00%, 0.00%, 0.00%) with 0.00% transparency
          • Unit - Unpause (Picked unit)
          • Animation - Change (Picked unit)'s animation speed to 100.00% of its original speed
          • Unit Group - Remove (Picked unit) from gChronosTarget[0]
      • Unit Group - Pick every unit in gChronosTarget[1] and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is in gChronosEffect[0]) Equal to False
            • Then - Actions
              • Unit - Pause (Picked unit)
              • Animation - Change (Picked unit)'s animation speed to 0.00% of its original speed
              • Unit Group - Remove (Picked unit) from gChronosPaused[1]
              • Unit Group - Add (Picked unit) to gChronosPaused[0]
            • Else - Actions
      • Custom script: call DestroyGroup(udg_gChronosTarget[1])
[/hidden]

The purpose of this trigger strategy is to add every unit in the chronosphere in the same group 'gChronosTarget[1]' and remove them from [0]. At the end of the trigger, all units in Target[1] will be paused and transfered to Target[0] and the units in Target[0] will be unpaused.

Problems:
I made the tunderclap effect at every chronos point and found something funny
-The location doesn't remove unless the next chronosphere is casted
-If there is 2 chronospheres at once on the map, the thunderclap effect appears at bouth

  • Animation - Change (Picked unit)'s vertex coloring to (0.00%, 0.00%, 0.00%) with 0.00% transparency
I used this function to see if the victems are transfered to [0]. It appears they does but doesn't unpause! ^ that function and the 'unpause' function is under the same loop after all.

Here is the file if you want to play around with the triggers
 

Attachments

  • Chronosphere.w3x
    26.8 KB · Views: 47
Status
Not open for further replies.
Top