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

How to do trigger damage after ability projectile lands?

Status
Not open for further replies.
Level 2
Joined
Dec 29, 2019
Messages
8
As title says, I want my ability Hurl Boulder to trigger some extra damage but after it hits the target not when its casted. After its casted it has to travel to target and unfortunately if u trigger it with after ability is casted that is immediately after projectile is launched.

Cant find a solution to this one. One idea was to apply debuff to target and immediately damage it but I cant get this to work.
 
Level 20
Joined
May 16, 2012
Messages
635
Actually what you want is only possible using a Missile System in conjuction with a Damage Detection System. When detecting damage you can only distinguish the damage dealer, the target, the amount, and the type of damage, but you cannot get which ability dealt the damage, so as i say, you would need to create a spell like Hurl Bolder using a Missile System and them using such system OnHit events to apply the type and amount of damage you want. It sounds really hard to do, but its actually quite easy if you know a little bit of JASS/vJASS. For a Missile System, i recommend either [vJASS] - Missile by BPower or xe0.9 - Wc3C.net by Verxorian. To your case speccifically you should use xemissile since it can create homming missiles like Hurl Bolder.

Here's an example of code that creates a homing missile and apply some damage when it hits its target using zemissile system:

JASS:
scope HurlBolderTriggered initializer Init

globals
    trigger Example
endglobals

private struct Missile extends xehomingmissile
    private unit caster
    private unit target
    private real damage

    static method create takes unit caster, unit target, real damage, string fxpath, real x, real y, real z returns Missile
        // Creates a missile from the caster position with an offset of +60 in the z axis that will seek the target
        local Missile this = Missile.allocate(x, y, z, target, BlzGetUnitZ(target) + 60.0)
       
        set this.caster = caster
        set this.target = target
        set this.damage = damage
        set this.fxpath = fxpath //xefx library required
        set this.scale  = 1.0 // the scale
       
        call this.launch(1000.0, 0.1) // Launches the missile with 1000 as Missile Speed and 0.1 Arc

        return this
    endmethod
   
    method onHit takes nothing returns nothing
        //When the Missile reaches its target, it will deal the amount of passed as parameter to the create method
        //Note: ATTACK_TYPE_NORMAL means Spell Damage
        call UnitDamageTarget(this.caster, this.target, this.damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)

        //To prevent local handle leaks
        set this.target = null
        set this.caster = null
    endmethod
endstruct

private function Conditions takes nothing returns nothing
    local unit caster = GetTriggerUnit() // the caster
    local unit target = GetSpellTargetUnit() // the target
    local real x = GetUnitX(caster) // x of the caster
    local real y = GetUnitY(caster) // y of the caster
    local real z = BlzGetUnitZ(caster) // z of the caster
    local boolean HurlBolder = GetSpellAbilityId() == 'A000' //Your custom ability code
    local real damage = 1000 //The desired amount of damage to be applied OnHit
    local Missile m // the missile instance

    // if ability being cast is your custom ability then create the missile
    if HurlBolder then
        //creates the missile instance
        set m = Missile.create(caster, target, damage, "Abilities\\Weapons\\RockBoltMissile\\RockBoltMissile.mdl", x, y, z)
        //Uses the original Hurl Bolde Missile, but you can use any model you want
    endif

    set target = null
    set caster = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
    set Example = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(Example, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(Example, Condition(function Conditions))
endfunction

endscope

for your use case you dont really need a Damage Detection System but its always usefull to have one for future use. As @Aeryn metioned, Bribe DDS is pretty much all you need if if only use GUI, but if you know a little bit of JASS than you dont need nothing at all, since 1.31 patch introduced Detetcing damage natively with EVENT_PLAYER_UNIT_DAMAGED or EVENT_PLAYER_UNIT_DAMAGING
 
Level 2
Joined
Dec 29, 2019
Messages
8
Oh comeone, is there no simplier way to do this but codeing?
How hard would it be to simply add dmg trigger but delay it for 0.5 sec so it alteast damages slightly after?

Also how hard to use is this damage engine? Can it increase spell damage based on your attributes easly? Im beginner so Im not familiar with these systems.
I just want hurl boulder damage to stack with agility
 
Level 39
Joined
Feb 27, 2007
Messages
5,010
If you base the spell on Acid Bomb you can easily detect when it impacts a target with just a DDS because Acid Bomb applies a buff to the hit target (and other targets nearby depending on how you set the spell options). Check for whatever buff you give to the spell and then remove it right away. You can query the damaging unit for the level of the spell or use different buffs for each level.

  • Events
    • -------- whatever event your DDS says to use --------
  • Conditions
    • (<unit damaged in event> has buff YOUR_BUFF) equal to True
  • Actions
    • Unit - Remove YOUR_BUFF from <unit damaged in event>
    • Unit - Cause <unit doing the damaging> to damage <unit damaged in event> for ...
 
Last edited:
Level 24
Joined
Feb 9, 2009
Messages
1,787
I was quite peeved with this problem, but now I use the new ability native to directly modify the damage of the ability on cast, haven't had issues yet.
Not near a computer right now so I can't post it... maybe another helpful person can post it.

*cough* @Pyrogasm *cough*
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
5,010
  • Ability - Set Ability: (Unit: (THE_UNIT)'s Ability with Ability Code: THE_ABILITY)'s Real Level Field: Damage ('Hbz2') of Level: 0 to 10.00
Note that these level fields are 0-indexed, so level 0 is actually level 1. Some things are real/int/string level fields (if they can change with level, ex: damage) and some are just real/int/string fields (ex: projectile art). Also I just picked Hbz2 as an example field, but it will likely be different for different spells. In the OE, look down the list of spell data for the spell you want to modify until you find the field you need to change, then press ctrl+d to switch the display to raw mode and look at the name of the field. Finally, find this same field name in the action (where Hbz2 is in my example).
 
Level 2
Joined
Dec 29, 2019
Messages
8
in unreal tournament voice: HOLY SHIT!!!!

This: "Ability - Set Ability" trigger worked! Its crazy that now we can make our spells stack with attributes! In a way that works also with projectiles.

Pyrogasm - I have tried at first with acid bomb but couldn't get it to work. Because same problem as with rock throw, when acid bomb is casted its only launched, it didn't hit target yet so condition if enemy has your debuff doesn't work. And I couldnt find any "Event" that can start when enemy gets a debuff.

Thanks a lot guys! This will help me a lot with future spells, as well with some custom spells now that I have this wonderful Set Ability Action and all its possibilitys.
In case this might help others, I will paste my code here, also btw I had to set many things to "Casting unit" instead of "Matching unit" to get it work.

Ability - Set Ability: (Unit: (Casting unit)'s Ability with Ability Code: Throw Rock )'s Real Level Field: Damage ('Ctb1') of Level: 0 to (10.00 + ((Real((Agility of (Casting unit) (Include bonuses)))) x 5.00))
 
Level 24
Joined
Feb 9, 2009
Messages
1,787
Pleased to hear @Rotgut, for the acid bomb problem, the event for damage engine can be found by using "Game Value of Real Variable" to which you select one depending on the situation:

"DamageEvent" =Hit
"DamageEventModifer" = Before hit
"AfterDamageEvent" = Self explanitory
"LethalDamageEvent" = Damage that lands a killing blow

The numbers are a little more advanced but generally just stick to "1.00"

I highly recommend going through Bribe's if you wish to delve deeper, Bribe has a wonderful section in the description that breaks down what everything does, grab a hot drink and get that knowledge in your noggin.

Edit: also the Damage Engine test map has a lovely set of examples, I'd recommend playing with it for a good half hour.

Also pic of event:
upload_2020-1-9_14-34-48.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,537
This isn't necessary in this case but here's a neat method I used before. Use a Dummy unit to cast your Hurl Boulder ability and give it a unique property to set it apart from the other Dummy units. For instance, set it's name to "Hurl Boulder Dummy", or give it a unique custom value, point value, hit points, any unique value that the Dummys for your other abilities don't have. You can even create a Dummy unit specific for this ability in the Object Editor.

Finally, in the Damage Event trigger check for this unique value. So if: DamageEventSource = Unit of Type "Hurl Boulder Dummy" or DamageEventSource's Name = "Hurl Boulder Dummy", etc... then we know that the damage came from the Hurl Boulder ability. You can even store the level of Hurl Boulder as the Dummy's custom value if you wanted to track that. Like I said not necessary for most advanced users but something nice and GUI friendly.
 
Last edited:
Status
Not open for further replies.
Top