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

[Trigger] Target Destructuble of Ability being cast

Status
Not open for further replies.
Level 7
Joined
Jun 19, 2017
Messages
141
Greetings friends i have a little issue here. I have made a custom ability based on the Sentinel that stays on trees and provides vision of the area. The problem is that it stays permanently and i wanted to set a duration to it, so i tried a trigger like this
  • Shadow Spy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Shadow Spy (Assassin)
    • Actions
      • Set Destructible[(Player number of (Owner of (Triggering unit)))] = (Target destructible of ability being cast)
      • Wait 120.00 seconds
      • Destructible - Kill Destructible[(Player number of (Owner of (Triggering unit)))]
The problem is that every time the unit casts the spell the old destructible get's overwritten with the new, no matter what Interger i put in the array. So my question is what do i have to put in the array so the destructibles get saved in a sequence rather than get overwritten ?
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
If you want an array, you can use: Visualize: Dynamic Indexing
Another option is using a local destructible variable together with the wait.

If you want to get rid of the inaccurate wait you can either use the dynamic indexing method from above with a counter variable or use a timer and attach the destructible to the timer. This method however is better done in JASS.
 
Level 7
Joined
Jun 19, 2017
Messages
141
Yes i saw from other threads that using local variables require jass, but i was wondering if there is a way of doing it in GUI so do you mind explaining a bit about how to attach the destructible to a timer :vw_wtf:
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Dynamic indexing is the only pure GUI method from the ones I mentioned. It requires a lot of additional variables and is quite complicated for how simple the problem is.
I will explain the wait + local variable first.
You need a destructible variable ( does not need to be an array), I will call it Tree. If you have been clearing leaks, you will know, that you need the prefix udg_ to refer to global variables in JASS.
  • Shadow Spy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sentinel
    • Actions
      • Custom script: local targetTree
      • Set Tree = (Target destructible of ability being cast)
      • Custom script: set targetTree = udg_Tree
      • Wait 120.00 seconds
      • Custom script: set udg_Tree = targetTree
      • Destructible - Kill Tree
      • Custom script: set targetTree = null
The local variable needs to be declared at the top, I named it targetTree.
The global variable is used to make it easier for you, because it can be used with GUI. We store the destructible in Tree.
Then the local variable is used to store the variable as well. The local variable cannot be overwritten from other triggers or if this trigger is executed again. A local variable is unique for every instant the trigger runs.
Now we can safely wait, because we know, that the local variable targetTree cannot be overwritten.
After the wait, we use Tree again and set it's value to targetTree. Again this is because we can use Tree together with GUI functions.
Now you can access the destructible with Tree and kill it.
At the end we set the local variable targetTree to null to prevent a leak.

This method is the shortest and easiest, even though it needs a little bit of JASS.


Attaching the destructible to a timer:
Now this is usually done in JASS, because of how bad timers are supported in GUI. You will need to write functions in JASS, so unless you are planning to use JASS, I don't think it makes much sense to explain it here.
 
Additional to what Jampion said, there is this technique called Shadowing Global Variables: using a local with the same name as a global. That way you can use the local in most actions in the trigger with the default GUI actions.
In his example it would mean you use "local destructable udg_Tree" then you skip this conversion lines.

Be aware that locals do not work in conditions/enumerations, cause of the way GUI creates conditions/enumerations in Subfunctions outside of the main-action function.

The name is a little bit pushy, but tells you much about warcraft triggering.
Things You Should Know When Using Triggers / GUI
 
Last edited:
Level 7
Joined
Jun 19, 2017
Messages
141
Jampion i copy pasted the trigger you gave me, but when i clicked test map this error popped out any idea why it might have happened ?
 

Attachments

  • error.png
    error.png
    14.5 KB · Views: 68

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Yes my bad, do what KILLCIDE said. I forgot the destructible type in the declaration.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
Oh ye, and do destructibles leak afterall ?

No destructibles cannot leak, similar to units. They take memory as long as they are not removed. However you don't have to worry about it. If you kill a unit or destructible it will automatically be removed by the game after it decayed.

As you can always access units or destructibles with unit or destructible groups, you can never lose reference, so they can't leak by the definition of a memory leak.
An invisible dummy unit or an invisible destructible without collision, that is no longer needed, but not removed would have a similar effect as a leak though.

Correct me if I'm wrong, but is it necessary to null destructibles? I don't recall them being handle types.

From the common.j file:
JASS:
type agent               extends     handle
...
type widget             extends     agent
...
type destructable       extends     widget

I guess this means, that destructibles are also handles. After all you can use GetHandleId() with destructibles.

I don't think much about whether a type needs to be nulled though. I null everything, if possible.
 
Status
Not open for further replies.
Top