• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

First target hit by spell gets stunned

Status
Not open for further replies.
Level 3
Joined
Jul 12, 2011
Messages
32
Hello, again :eek:.

Well, I searched Hive and found nothing to help me with this.

A simple spell, like Starfall or Shockwave, will stun its first target (like when you cast Shockwave into a army, then first target who gets damaged by the shockwave gets stunned). I was wondering how to trigger this, and you'd give me photos, cause i am working on a map myself.

Thanks in advance, and +rep for who helps me.

P.S no need to remove the shockwave (and its art) after someone gets stunned by it.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1) You could use a Damage Detection System to detect when the unit is hit by the Shockwave.

- A unit cast Shockwave
-> Set "Shockwave Boolean" = true

- A unit takes damage (GDD_Event becomes equal to 0.00)
-> If "Shockwave Boolean = True" then -> Stun the Unit (Create the dummy, order the unit to stun, etc.), and set "Shockwave Boolean = false".

Something like that.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
if you use GDD, you must filter the orderId==852125, if not then other damage from the
unit like attacked will stun the target...

do a triggered shockwave, create a dummy unit of a shockwave model, then move it using
a looping timer/trigger towards the spell target location, checking everytime in the dummy's
AOE if an enemy unit is not null, then stun it...
 
Level 3
Joined
Jul 12, 2011
Messages
32
GDD? I use World editor.

And if its not too hard, you could give me photos, since I am not any pro Triggerer, and hardly understand (or hell, can i event find these stuff from the trigger list).
 
Level 3
Joined
Jul 12, 2011
Messages
32
Well, this system sounds pretty complicated.
Is there something simplier?
Like something this spartipilo said?
It sounds pretty simple, but i have no idea
that what should be condition or action.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
vampkitty... Almost every system will seem "too complicated" for you, since you're just starting.

As Pharaoh_ said, a DSS is a Damage Detection System. GDD is really easy to use, just has three isntructions. Don't be scared... one line after another, and you'll achieve any code/system you want.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
@vampkitty
wait until tonight coz Im out of town most of the day...I'm working on a missile system
that can trigger your first target stun and damage/heal targets option...not only stun
but triggers most of the TargetUnit able spells...

EDIT:

JASS:
//===Simple Missile System
//Created by: Mckill2009

//Requires:
//- Jass New Gen Pack By Vexorian
//- Timer32 By Jesus4Lyf ([url]http://www.thehelper.net/forums/showthread.php/132538-Timer32[/url])

//How to Install:
//- Create 2 triggers named MS and T32x, convert it to custom text >>> EDIT >>> CONVERT TO CUSTOM TEXT
//- Create 1 dummy unit as the caster of the stun
//- Create 1 unit modeled as shochwave
//- Copy the Timer32 library from [url]http://www.thehelper.net/forums/showthread.php/132538-Timer32[/url] and paste it to your T32x trigger
//- Copy the code I made and paste it to the MS trigger
//- Take note that you MUST overwrite all text from MS and T32x when pasting
//- Change the raw code of DUMMY_ID if needed, raw codes can be viewed by pressing CTRL + D from object editor

library SimpleMissileSystem uses T32x

globals
    private constant integer               DUMMY_ID = 'h001' //raw code of the UNIT dummy, change this if needed, but it MUST have mana
    private constant integer          MISSILE_SPEED = 30 //speed in which the missile travels
    private constant attacktype                 ATK = ATTACK_TYPE_NORMAL
    private constant damagetype                 DMG = DAMAGE_TYPE_NORMAL
    private constant boolean    ENABLE_FIRST_TARGET = false //set to true if you want to enable first target spell
endglobals

private struct MS
    unit missile
    real angle
    real distance
    real xdist = 0
    real aoe
    real damage
    integer abilId
    integer orderId
    integer level
    boolean check = true
        
    private static thistype DATA
    
    private static method filterfirst takes nothing returns boolean
        local thistype this = DATA
        return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.missile)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)
    endmethod
    
    private static method damageall takes nothing returns boolean
        local thistype this = DATA
        local unit u = GetFilterUnit()
        if IsUnitEnemy(u, GetOwningPlayer(.missile)) and not IsUnitType(u, UNIT_TYPE_DEAD) then
            call UnitDamageTarget(.missile, u, .damage, false, false, ATK, DMG, null)
        endif
        set u = null  
        return false
    endmethod
    
    method periodic takes nothing returns nothing
        local unit first
        local unit dummy
        local real x
        local real y
        if .distance > .xdist then
            set x = GetUnitX(.missile)
            set y = GetUnitY(.missile)
            set .xdist = .xdist + MISSILE_SPEED
            call SetUnitX(.missile, x + MISSILE_SPEED * Cos(.angle))
            call SetUnitY(.missile, y + MISSILE_SPEED * Sin(.angle))
            set DATA = this
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, .aoe, function thistype.damageall)
            if ENABLE_FIRST_TARGET then
                call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, .aoe, function thistype.filterfirst)
                set first = FirstOfGroup(bj_lastCreatedGroup) 
                if .check and first != null then
                    set .check = false
                    set dummy = CreateUnit(GetOwningPlayer(.missile), DUMMY_ID, x, y, 0)
                    call UnitAddAbility(dummy, .abilId)
                    call SetUnitAbilityLevel(dummy, .abilId, .level)
                    call IssueTargetOrderById(dummy, .orderId, first)               
                endif
            endif
        else
            call KillUnit(.missile)
            call .stopPeriodic()
            call .destroy()            
        endif   
        set first = null
        set dummy = null
    endmethod
    
    implement T32x
    
    static method create takes unit m, real a, real d, real ao, real dam, integer ab, integer o, integer l returns thistype
        local thistype this = thistype.allocate()
        set .missile = m
        set .angle = a
        set .distance = d
        set .aoe = ao
        set .abilId = ab
        set .orderId = o
        set .level = l   
        set .damage = dam * T32x_PERIOD
        call .startPeriodic()
        return this
    endmethod
endstruct

//this is the only function you will call
//Sample >>> call SetMissile(missile, GetSpellTargetX(), GetSpellTargetY(), 200, 100, 'AHtb', 852095, 1)
function SetMissile takes unit missile, real xDist, real yDist, real aoe, real damage, integer abilId, integer orderId, integer level returns nothing
    local real x = GetUnitX(missile)
    local real y = GetUnitY(missile)
    local real angle = Atan2(yDist-y, xDist-x)
    local real distance = SquareRoot((xDist-x)*(xDist-x) + (yDist-y)*(yDist-y)) 
    call MS.create(missile, angle, distance, aoe, damage, abilId, orderId, level)    
endfunction

endlibrary
 
Last edited:
Level 3
Joined
Jul 12, 2011
Messages
32
Thank you Mckill, but why is this jass? I use World editor, and hardly understand this.

Well, little off-topic question:

Wc3 trigger.png

This spell doesn't work(no frost nova at all). And if it helps, 'The grip of the Lich king' is entalging roots.
 
Level 10
Joined
Oct 5, 2008
Messages
355
To the off topicquestion: I think [targeted unit] just applies to the "aquires a target event", so you need [Target unit of ability being cast] to order the dummi to cast the ability. And at best create first the dummi, add the ability and then set the level of the added ability to the level you need.

To the topic, i have unfortunately nothing to add to this. It would be the best to trigger the spell completely, since then you can fully customize it, but this alternative would be much for the beginning.
 
Level 3
Joined
Jul 12, 2011
Messages
32
Thank You, it works now.
But, 1 more question about this; If i change the Grip of the lich king into something else, like Death Coil or Mana Burn, then will this trigger still work?
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
you dont need to understand this coz its a preset system and can work with GUI, but a little explanation will do...

How to install?...
- See the code, I've edited that

How it works?...
  • Demo
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Flame Strike
    • Actions
      • Set TempLoc = (Position of (Triggering unit))
      • Unit - Create 1 missile for (Triggering player) at TempLoc facing Default building facing degrees
      • Set Dummy = (Last created unit)
      • Custom script: call RemoveLocation(udg_TempLoc)
      • -------- This line sets the missile --------
      • Custom script: call SetMissile(udg_Dummy, GetSpellTargetX(), GetSpellTargetY(), 200, 100, 'AHtb', 852095, 1)
as you can see the key is...

Custom script: call SetMissile(udg_Dummy, GetSpellTargetX(), GetSpellTargetY(), 200, 100, 'AHtb', 852095, 1)

udg_Dummy = is the shockwave dummy model
GetSpellTargetX() & GetSpellTargetY() = is a Location coordinate, so no need to change this
200 = is the area of effect, the missile will damage targets
100 = is the damage
'AHtb' = raw code of the Storm Bolt
852095 = orderId of the Storm Bolt
1 = is the level of Storm Bolt spell

About the offtopic:
Lord is right, its the order (if the dummy is right, meaning, if has mana, can move etc...and the right ability and order is OK)...

here's the order:
- Create dummy
- add timer
- add spell to dummy
- set level for dummy spell
- cast the spell
 
Level 3
Joined
Jul 12, 2011
Messages
32
(Sorry for the offtopic questions, I just didn't want to
create another thread for small question)

And, here is another question;

wc_r1.png

Does not work. The penance is healing wave
, and dummy holy light is healing wave aswell
(and the target i casted it on doesn't have full hp).

@mckill

Oh, so i just make the trigger look like this, then it will work?
I will try it tomorrow when i have more time then.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Use
  • tags to paste triggers, instead of images.
  • 1- Maybe the Dummy doesn't have enough mana, or enough time to cast it.
 
Level 3
Joined
Jul 12, 2011
Messages
32
No, before i looped this spell, it did work.
Now, it does not work.

EDIT; Spartipilo, i checked those and the spell still does not work. Any other advice?
 
Last edited:
Level 3
Joined
Jul 12, 2011
Messages
32
Ooo, I leak? Which one? My friend said that this doesn't
leak and he said it doesn't work cause there may be
something wrong with the objects.

Also, another offtopic question; How do i make a buff remove units collision?
 
Level 10
Joined
Oct 5, 2008
Messages
355
The value (Position of (Target Unit of ability being cast)) when creating your dummi does leak. This creates the location, which determinate the point on which the target does stand, and because you does not declare this as a variable and remove it afterwards, you leak.

For beginners, when you reffer to custom buffs, you could make a simple system for this, at most when the buff is not area-affecting.

I assume now that you make the buff single target only (like curse or something like this), if not, it will follow the same circumstances, just you will need to change the targeting trigger:

At first, you need at least 1 variable:
-A Unit Group (I named it Buffgroup)

I will use 2 variables to optimize it a bit:
-The group
- A Unit variable (I named it Tempunit)

(Ok, i know that for such small trigger, it is not really needed, but it will increase the performance when you have big triggers which repeats fast):

You need two triggers:

This one will get all targets of the spell and add them to the unit group, which controls the buff, and it will also turn off the collision.

  • Collision turnoff
    • Events
      • Unit - A unit starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal [Insert Spell here]
      • ((Target unit of ability being cast) is in Buffgroup) Equal False
    • Actions
      • Set Tempunit = (Target unit of ability being cast)
      • Unit - Turn collision for Tempunit Off
      • Unitgroup - Add Tempunit to Buffgroup
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Conditions
          • (Collision turnoff <gen> is on) Equal False
        • 'THEN'-Actions
          • Trigger - Turn on Buff Collision check <gen>
        • 'ELSE'-Actions
The second trigger is turned off, since it fires every 0,5 seconds and without any unit in the group it would be just useless, so the trigger above turns it on:

  • Buff Collision check
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Bedingungen
          • (Number of units in Buffgroup) Greater than 0
        • 'THEN'-Aktionen
          • Unitgroup - Pick every unit in Buffgroup and do (Actions)
            • Loop - Actions
              • Set Tempunit = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Conditions
                  • (Tempunit has buff [Insert Buff here]) Equal True
                • 'THEN'-Actions
                • 'ELSE'-Actions
                  • Unit - Turn collision for Tempunit On
                  • Unitgroup - Remove Tempunit from Buffgroup
        • 'ELSE'-Actions
          • Trigger - Turn off (This trigger)
This trigger picks all units in the buffgroup (when there are any)(there are only some affected by the first trigger and with this by the casted ability), check if they have still the buff, and when not, the collision will be turned on and the units will be removed from the group. If there are nio units in the group, the trigger turns itself off.

(I didn't tested the trigger now, if there are any flaws or bugs, tell me please)

I think this could be usefull for you, there are better (and some more complicated) alternatives, but this one is quite simple and enough for the beginning to understand.
 
Level 3
Joined
Jul 12, 2011
Messages
32
So, when I create location for dummy to cast his spell,
I must "ALWAYS" declare it as variable and remove it then?
So, i just make variable named 'penance' and set it as position of last created unit?

And, about this buffgroup thing,.,
Yes, this does seem very simple, and this will definitely
help me making cool triggered spells.
So! +rep for you.
But, I was also thinking doing this same kind of thing that (another trigger activates another trigger) but instead.,.

Hero starts channeling spell
Activate X trigger
---------------------
every 2 seconds of game
create unit at...

Or should it even be done like this? Do i need to make variables?
What should be the variable type? How do I set variables as=target unit of ability being cast?
 
Level 10
Joined
Oct 5, 2008
Messages
355
You should declare it always as a variable and then destroy it via the custom script "call RemoveLocation(udg_[Insert Variablename here])"
(The udg_ declares that the variable is a global one, locals just exists in jass)
Overriding them don't remove them.

How do I set variables as=target unit of ability being cast?
If i understand you right, you are referring to the "Set Variable" action, it is a generic one, the 8th from the top. Just choose your global variable on the left side and then the value you want to set the variable on the right side. Its clear that you need to create a global variable first.

Hero starts channeling spell
Activate X trigger
---------------------
every 2 seconds of game
create unit at...

There will occur three problems when triggering a channeling ability like this.

The first one will be that when you end the channeling of the ability by stopping/stunning etc., the effect will still take place. So you can begin to channel, walk away then and the effect will still take place. So i would create a third trigger which will be active when the caster ends his channeling. Of course you cannot use the "ability being cast" condition (I think at least so, some time ago since i created my last channeling ability), since you stopped the spell already, so you should just check if the caster was the one which channeled this ability (with a unit group or unit variable for example which will be set in your first trigger).

Your second problem will be that your second trigger (the periodic one) has no information about the caster. Since in this trigger you cannot refer to (triggering unit) or (target of ability being cast), since they were preset just for the trigger before, you have to store the informations. So you have to set the variables in the first trigger to use them in your periodical trigger, since these are the only references to which unit began to cast the spells.

The last problem will be that your variables will be overriden, when another unit begins to channel the same ability. This is the difference between the so called GUI and MUI (I believe they stand for Global and Multi Unit Instances, i'm quite new to the hive so i don't know the expressions really).
An example for this:
You are triggering a cluster rockets-spell. You have stored the caster and the targeted point into two variables. You have one unit with this spell and use it. It will work. But when you cast the spell one time and another unit casts the spell, the first cast will stop and the second will work. Why this? Because the two variables are overwriten!
So you need to cope with this somehow. At best is the use of a hashtable or an indexer, there are some tutorials for them, describing them here would take a few pages. These are very usefull for better spellmaking and the developement of your mapping skills.
If you use an ability like starfall, you could just do it with a Unitgroup, since all you need to store is the caster, which can be done in a unitgroup. Add the unit when it begins the channeling of the ability, remove it from the geroup when it stops the channeling, and run a periodical trigger which picks every unit in this group (Refer with (picked Unit) to the picked unit and with this to the caster).

Ah, and to answer the question which variables should be used: it is depending on the spell. Like said, theoretically, a starfall just needs a unit variable (the caster), drain life will need 2 unit variables (the caster and the target), Cluster rockets needs a location and a unit variable (the caster and the targeted point of the ability being cast). It is all dependent on what spell you want to do.



At first to variables overall (I don't know really your expreience with them, but here you get to know about them and about arrays, which are essential for triggering, at least of systems):
http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/variables-5896/

Then for memory leaks, memory leaks are always bad and mappers (at most the experienced ones) like to hang themselves on them when they find some. But removing them is really necessary, because they will slow down the game alot because they are just datas which are not used anymore, but still exists in the game, so you have garbage which cannot be removed properly (except by removing them after the use completly or with special leak collectors which are written in jass):
http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/basic-memory-leaks-5889/

Now to trigger enhanced spells. This tutorial really helps and will solve some questions which will occur for you while you create some spells by describing how to create them properly (You will know much of it but there will be some things like channeling abilitys which you will need):

http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/basics-trigger-enhancing-spells-7334/

Here comes two tutorials, one for hashtables and one which shows the difference between MUI and GUI (ok it was shown in the one before but this is more accurate) and how to create MUI via an Indexer. Both ways can be used for creating MUI spells, but the way i know, Indexer are faster:

http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/multi-instancible-gui-spell-making-34393/

http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/complete-beginners-guide-hashtables-197381/

I think these ones could help, if you have any questions, feel free to ask.

Edit: Of course i don't want to leave you alone with this tutorials, they should be only a help when you need a reference or want to learn the backgrounds and the triggers step by step, a forum can be quite unhandy for this sometimes
 
Level 3
Joined
Jul 12, 2011
Messages
32
@lord earthfire

I don't quite understand the variables...

What type variable?
What variable value?
What is this 'the group' variable, i don't see it being used in the triggers.
 
Level 10
Joined
Oct 5, 2008
Messages
355
I think you are reffering to the tutorial, aren't you:

There is not "type"-variable, but every variable inhibits a type and can be set to a value. In fact, a variable is a path which leads to a specific value, which is set and changed ingame or in the editor. The tutorial referrs to the image Window, which will opened when you click in the trigger editor on the small X at the top. This will open a window in which you create the variables. You have to create them first to use them in your trigger. By clicking the green X with the plus you will open a window like it is shown in the tutorial. there you can set now the name of the variable, the type of the variable (you need to seek for "unitgroup" to create a unitgroup-variable), its starting value (leave it to the standart, since you override it anyway) and you can choose if it should have arrays or not (leave it turned off until you need them).

type a name inthere, choose the type in the list (like unitgroup), and then clicking Ok will create your first variable in the list. You can now set the variable to a value you want via the "set variable function", where the left parameter is the variable and the right parameter is the value you want your variable to save.

And here is an example for Unit groups:

  • Example
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Unitgroup = (Units in (Playable map area))
      • Unitgroup - Pick every unit in Unitgroup and do (Actions)
        • Loop - Actions
          • -------- Insert your Actions here --------
      • Custom script: call DestroyGroup(udg_Unitgroup)
This example shows how to set the unitgroup variable and how to destroy it

(i think there is a special in-script variable for unitgroups, which will destroy them directly after the pick unitgroup action if set to true, but i forgot which it was)
 
Status
Not open for further replies.
Top