[Solved] Check if an ability kills an unit and do certain effect

Status
Not open for further replies.
Level 2
Joined
Dec 6, 2022
Messages
3
Hello there! I am creating a new ability to my hero called Plunder. The skill itself is a point-and-click damaging skill that, if kills an unit, gives the player gold.

The problem is: Whenever I try a new solution, two of the scenarios happen: 1) The player gains gold even if it doesnt kill the unit or 2) Nothing happens at all. I have tried using the GUI and the JASS (I will show both of them down bellow).

My logic - Check if the ability Plunder was used and compare if the target of the ability is dead. If true, do effects. I have tried putting a timer on it, because I thought the game wouldnt have time to compare if the unit is dead just after the skill was used. I have tried checking if unit is dead and checking if the HP of the target is less than 1 (Because I have seen somewhere that a unit doesnt actually dies with 0 hp).

Maybe I am missing something? I have seen somewhere that the game cannot see whom killed the unit after it was killed, and right now I am a bit clueless of what to do. Could you give me some hand on what / where to fix? If you read up to here, I already thank your attention :peasant-thumbs-up-cheers:

  • Events
    • Unit - A unit Starts the effect of an ability.
  • Conditions
    • (Ability being cast) Equal to Plunder.
  • Actions
    • Wait 1.00 seconds
    • If (All conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Life of (Target unit of ability being cast)) less than 1.00
    • Then - Actions
      • Special Effect - Create special effect at (Position of (Triggering unit) using UI\Feedback\GoldCredit\GoldCredit.mdl
      • Player - Set (Owner of (Triggering unit)).Current gold to (((Owner of (Triggering unit)) Current gold + 25)
    • Else - Actions
      • Do nothing
JASS:
function checkIfDead takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
endfunction

function Trig_Plunder_Passive_Test_Conditions takes nothing returns boolean

    if ( not ( GetSpellAbilityId() == 'S004' ) and checkIfDead ( GetSpellTargetUnit() ) == false ) then
            return false
    endif
    return true

endfunction

function Trig_Plunder_Passive_Test_Actions takes nothing returns nothing
    
    call AddSpecialEffectLocBJ( GetUnitLoc(GetTriggerUnit()), "UI\\Feedback\\GoldCredit\\GoldCredit.mdl" )

endfunction

//===========================================================================
function InitTrig_Plunder_Passive_Test takes nothing returns nothing
    set gg_trg_Plunder_Passive_Test = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Plunder_Passive_Test, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Plunder_Passive_Test, Condition( function Trig_Plunder_Passive_Test_Conditions ) )
    call TriggerAddAction( gg_trg_Plunder_Passive_Test, function Trig_Plunder_Passive_Test_Actions )
endfunction
 
Level 41
Joined
Feb 27, 2007
Messages
5,229
Your method mostly does work, but it's not precise. Casting it on a target, then immediately attacking to get the killing blow with an attack from a different unit would still reward gold. The problem is that Waits are bad and using them can mess with the value of some event responses. For future reference there's no need to convert a GUI trigger to JASS just to post here; the JASS is actually harder to read and understand because of how convoluted conditions and other nested stuff appears.

There is no easy way to answer the question "what exactly dealt the killing blow?" in wc3 without a Damage Detection System like Damage Engine 5.9.0.0. With such a system it's now possible to know:
  • Which unit got the killing blow
  • How much damage was dealt
  • If the damage was an attack, spell, or code ("have UNIT damage UNIT")
  • If an attack, if it was ranged or melee
It doesn't inherently make it possible to know "which ability in that unit's ability list dealt the killing blow?" You can ultimately answer this question by being a little smart with some dummy units. If you create an invisible dummy caster unit and give it the spell that damages and kills the targeted unit, then you can be sure when the killing blow is dealt by that type of unit then it was killed by that ability since the dummy caster couldn't kill a unit in any other way! If there are multiple such effects you need to keep track of on your map, instead of using a different dummy unit for each one you can just check the level of the appropriate dummy ability for the dummy caster, which would determine which ability it had used.

Do Nothing is worthless and never needs to be added anywhere; it's literally an empty function call. Finally, you are leaking some points and a special effect. I don't have much more to say than this thread and the tutorial it links to will explain. You want to avoid memory leaks in your map, as it will be a performance issue over time the more you leave uncleaned: Things That Leak

Put together your flow is now going to be this:
  1. Make the hero Plunder skill into a basic bitch ability that doesn't actually do anything. No damage, just art. Base it on Channel if you need something with a configurable orderid.
  2. Create a dummy caster unit for your map. No model file, Locust ability, cast backswing and cast point of 0, movement type NONE, maximum mana pool, no attacks. This setting will be a dummy that can instantly cast in any direction instantaneously without facing.
  3. Create the dummy caster version of the Plunder skill which has appropriate damage for each level, max range, 0 mana cost, and appropriate projectile speed (if relevant).
  4. Install DamageEngine (simple, don't overthink)
  5. Triggers to catch cast and death:
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
    • (Ability being cast) equal to Plunder (HERO SKILL)
  • Actions
    • Set TempPoint = (Position of (Triggering Unit)) //might want to make it at the target's location depending on if the ability is a projectile or instant damage or what
    • Unit - Create 1 DUMMY CASTER for (Owner of (Triggering Unit)) at TempPoint facing Default building facing degrees
    • Unit - Add Plunder (DUMMY SKILL) to (Last created unit)
    • Unit - Set level of (Plunder (DUMMY SKILL)) for (Last created unit) to (Level of Plunder (HERO SKILL) for (Triggering Unit))
    • Unit - Add a 1.50 second Generic expiration timer to (Last created unit) //this duration has to be long enough that the dummy is still alive when the ability connects and kills, so if it is a slow projectile or long distance projectile consider increasing this duration
    • Unit - Order (Last created unit) to <whatever order the spell needs> (Target unit of ability being cast)
    • Custom script: call RemoveLocation(udg_TempPoint) //change the name in parenthesis to match your variable name but keep the udg_ prefix
  • Events
    • Game - LethalDamageEvent becomes Greater than 0.00 //read the DE documentation but this is set to run when a unit dies from non-code spell damage
  • Conditions
    • (Level of Plunder (DUMMY SKILL) for DamageEventSource) greater than 0
  • Actions
    • Set TempPoint = (Position of DamageEventSource)
    • Special Effect - Create special effect at TempPoint using UI\Feedback\GoldCredit\GoldCredit.mdl
    • Special Effect - Destroy (Last created special effect)
    • Player - Set (Owner of DamageEventSource) Current gold to (((Owner of DamageEventSource) Current gold + 25)
    • Custom script: call RemoveLocation(udg_TempPoint) //keep the udg_ prefix
 
Last edited:
Level 2
Joined
Dec 6, 2022
Messages
3
Thank you a lot! This surely will not just help in this skill but with future ones too. I was looking forward to install some "mods" to my WarCraft Editor, but some doesn't seem to work on Reforged yet unfortunately. Something to add and remove some abilities data like give regen to something that doesnt have and etc. But this is talk to another post, this one is solved. Thanks a lot :D

(I don't know how reps work but you helped me solve my problem and gave me an espetacular explanation) +REP
 
Status
Not open for further replies.
Top