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

Manipulating Damage factors and such...

Status
Not open for further replies.
Level 2
Joined
Jan 30, 2006
Messages
12
I do have a particular spell in mind here, but I have (a) much more general question(s). How, through triggers or JASS, can effects that detect or manipulate the amount of damage a unit takes be made? For example: The DOTA hero Lord of Avernus' Aphotic Shield and Borrowed Time abilities.

Aphotic Shield is a castable buff that places a shield on a unit that absorbs a set amount of damage. (Once that damage is exceeded, it explodes, dealing that amount to enemies in an AOE.)

Borrowed Time is a passive ability, that activates whenever Lord of Avernus' hit points drop below 400. It puts on him the Unsummon Building effect, and nullifies any and all damage, for 5 seconds or so. The effect, once activated, will not activate for another minute or so, giving it a cooldown of sorts.

If Lord of Avernus has Aphotic Shield on himself while Borrowed Time is in effect, then any damage he would take instead heals him (as if he were taking negative damage).

How is this accomplished? How is damage dealt with - I have no idea how the "a unit takes damage" events and "damage taken" event variables are to be used. The specific spell I had in mind is a castable Mana Shield buff. I could just make a spell that adds Mana Shield to the target unit and activates it via triggers, but that would be in my opinion less than authentic, and potentially messy.

What I want to do is place a visible buff on a unit. Whenever a unit with this buff takes damage from any source (aside from itself, presumably) that damage is reduced by a percentage, say 20%, and that damage is instead done to the unit's mana pool, possibly multiplied by some factor. If the unit takes damage and has no mana, or less than 20 mana or so, the buff is instantly removed. So basically the effect of mana shield, coming from triggers activated by a unit with the buff taking damage.

Sorry if this question is obnoxious or difficult. Thanks in advance for any help or advice!
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
When they cast the ability, it creates a temporary trigger that waits till Avernus is damaged. When he is, it adds

(Damage Taken)

life to him, and subtracts (Damage Taken) life from the shield. I would assume that the shield has a max duration; if so, they remove the buff when the shield's life hits 0, and they remove the life from the shield when the buff expires

If you know JASS, I can show you how to do this fairly easily. If you only know GUI, that's alot more questionable
 
Level 2
Joined
Jan 30, 2006
Messages
12
I have a tenuous grasp of JASS. I think I could follow whatever directions you gave me. By the way, where can I get WEU?
 
Level 2
Joined
Jan 30, 2006
Messages
12
Cool, thanks in advance. I look at 'unit takes damage,' and it's only available for specific units. It won't take unit variable either, so I've not idea how to use it. If it were available as a generic unit event, I probably wouldn't even have a problem.

Sorry to double post, but I did have another question, and I'm told it's better to post additional questions to a thread you've already started than to start a new one. My original query stills stands, of course. But also: how do you detect when a unit uses an auto-cast "arrow" ability? It doesn't seem to count as a spell. I read in some other thread that you could set a boolean on and off when a unit is issued an order to turn the arrow ability on and off autocast, but how would that detect it if it were off autocast, and you decided to simply use it once, by clicking it?
 
Last edited by a moderator:
Level 2
Joined
Jan 30, 2006
Messages
12
Could you elaborate a bit? The spells I'm trying to do are Concussive Arrows and Vampiric Arrows. The first simply has a chance to apply a stun each time the arrow spell is used. The second restores the user's health every time the arrow spell is used. I want the trigger to detect the arrow spell whenever it's used, whether it's set to autocast or not.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Tested and working (for the first question). One flaw, that I'm almost sure is unfixable; a blow that does the unit's Max life or more will still kill them.

JASS:
constant function Shield_ID takes nothing returns integer
    return 'A000'//Rawcode of your shield spell
endfunction

function Shield_BuffId takes nothing returns integer
    return 'B000'//Buff for your shield spell
endfunction

constant function Shield_DamageAbsorbed takes real level returns real
    return 100 * level //Damage the shield absorbs
endfunction

constant function Shield_AbsorbPercent takes real level returns real
    return 1 + 0*level//% of all damage the shield absorbs (0% = .00, 1% = .01, 10% = .1, etc, up to 100% = 1).
    //Eg. If the shield can absorb 50% damage, and the unit takes 50 damage,
    // it will stop 25 damage, and the unit will take the other 25.
    //A value greater than 1 will heal the shielded unit, and a value less than 0 will damage them.
endfunction

function IsShield takes nothing returns boolean
    return GetSpellAbilityId() == Shield_ID()
endfunction

function Shield_Child_BlockDamage takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = GetAttachedUnit( t, "u" )
    call SetWidgetLife( u, GetWidgetLife( u ) + GetAttachedReal( t, "hl" ) )
    set u = null
    call CleanAttachedVars( t )
    call DestroyTimer( t )
    set t = null
endfunction

function Shield_Child takes nothing returns nothing
    local trigger t = GetTriggeringTrigger()
    local unit u = GetTriggerUnit()
    local real r = GetEventDamage() - ( 1 - GetAttachedReal( t, "absorb" ) )
    local real l = GetAttachedReal( t, "life" )
    local real a = GetAttachedReal( t, "absorb" )
    local real tm
    local timer tt
    if not ( GetUnitAbilityLevel( u, Shield_BuffId() ) > 0 ) then
        set u = null
        call TriggerRemoveAction( t, GetAttachedTriggerAction( t, "ta" ) )
        call CleanAttachedVars( t )
        call DestroyTrigger( t )
        set t = null
        return
    endif
    set r = r * a
    set tm = GetUnitState( u, UNIT_STATE_MAX_LIFE ) - ( GetWidgetLife( u ) + r )
    set l = l - r
    if l <= 0 then
        call UnitRemoveAbility( u, Shield_BuffId() )
    else
        call AttachReal( t, "life", l )
    endif
    if tm >= 0. then
        call SetWidgetLife( u, GetWidgetLife( u ) + r )
    else
        call SetWidgetLife( u, GetWidgetLife( u ) + r + tm )
        set r = r - ( r + tm )
        set tt = CreateTimer()
        call AttachReal( tt, "hl", r )
        call AttachObject( tt, "u", u )
        call TimerStart( tt, .01, false, function Shield_Child_BlockDamage )
        set tt = null
    endif
    set u = null
    set t = null
endfunction

function Shield takes nothing returns nothing
    local trigger t = CreateTrigger()
    local unit u = GetTriggerUnit()
    local unit u2 = GetSpellTargetUnit()
    if u2 == null then
        set u2 = u
    endif
    call TriggerRegisterUnitEvent( t, u2, EVENT_UNIT_DAMAGED )
    call AttachObject( t, "ta", TriggerAddAction( t, function Shield_Child ) )
    call AttachReal( t, "life", Shield_DamageAbsorbed( GetUnitAbilityLevel( u, Shield_ID() ) ) )
    call AttachReal( t, "absorb", Shield_AbsorbPercent( GetUnitAbilityLevel( u, Shield_ID() ) ) )
    set t = null
    set u = null
    set u2 = null
endfunction

function InitTrig_Shield takes nothing returns nothing
    set gg_trg_Shield = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Shield, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Shield, Condition( function IsShield ) )
    call TriggerAddAction( gg_trg_Shield, function Shield )
endfunction

Please give me credit if you use it in a map in the end X_x
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
you can set life using triggers.
Because the event is triggered using a unit is damaged, you know the damage delt. If the units life is less than or equal to 0 (DEAD) it quickly stops the death by adding the HP bonous (full life) then does one of the below.

  1. Sets the HP% to that of the damage - the reduction/old total HP then removes the ability
  2. Sets the HP to that of the damage - the reduction then removes the ability
  3. Removes the ability then sets the HP to damage - reduction.

Try the above, my next spell will experiment with this to find the best method.
 
Status
Not open for further replies.
Top