Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Scripts (http://www.wc3c.net/forumdisplay.php?f=737)
-   -   DamageEvent & DamageModifiers (http://www.wc3c.net/showthread.php?t=108009)

grim001 11-04-2009 01:07 AM

It registers damage detection triggers, of course it can detect the amount of damage dealt. But it doesn't differentiate between spells and attacks.

Mr.Malte 11-07-2009 01:04 PM

edit: Can I also prevent the damage differently than creating structs for each unit?
edit 2: Can't you make somtehing like this:

Collapse JASS:
// Gets data from events like GetEventDamage and adds the survival ability e.g
// if necessary
function ModifyDamage takes unit who, real byValue returns nothing

which can be only used in damage events?

But coded by you (used some map-specific funcs. Also I didn't all the research and don't know what to check)

Anitarf 11-07-2009 02:01 PM

No.

grim001 11-07-2009 02:42 PM

Quote:

Originally Posted by Mr.Malte
Can't you make somtehing like this:


Making it work that way is actually really difficult and hasn't been done flawlessly before. Maybe sometime in the future.

Mr.Malte 11-07-2009 05:40 PM

But this:

Collapse JASS:
library ModifyDamage requires TimerUtils
    //! external ObjectMerger w3a AIl1 DMsa anam "LifeBonus" ansf "(DamageModifiers)" Ilif 1 100000 aite 0
    private struct DamageTaken
        real healAfterwards = 0.
        unit who
    endstruct
    private function AfterDamage takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local DamageTaken a = GetTimerData(t)
        call ReleaseTimer(t)
        if GetUnitAbilityLevel(a.who,'DMsa') > 0 then
            call UnitRemoveAbility(a.who,'DMsa')
        endif
        call SetUnitState(a.who,UNIT_STATE_LIFE,GetUnitState(a.who,UNIT_STATE_LIFE)+a.healAfterwards)
    endfunction
    function ModifyDamage takes real mod returns nothing
        local unit damaged = GetTriggerUnit()
        local real damage = GetEventDamage()
        local real life = GetUnitState(damaged,UNIT_STATE_LIFE)
        local real maxLife = GetUnitState(damaged,UNIT_STATE_MAX_LIFE)
        local timer t
        local DamageTaken a
        
        if life < damage and life - damage + mod > 0.405 then
            call BJDebugMsg("Prevent Death")
            set a = DamageTaken.create()
            set a.who = damaged
            set a.healAfterwards = damage - mod
            call UnitAddAbility(damaged,'DMsa')
            set t = NewTimer()
            call SetTimerData(t,a)
            call TimerStart(t,0.00,false,function AfterDamage)
        endif
        
        if life + mod > maxLife then
            set a = DamageTaken.create()
            set a.who = damaged
            set a.healAfterwards = life + mod - maxLife
            set t = NewTimer()
            call SetTimerData(t,a)
            call TimerStart(t,0.00,false,function AfterDamage)
        else
            call SetUnitState(damaged,UNIT_STATE_LIFE,life+mod)
        endif

    endfunction
endlibrary

works perfectly well (ive tested it) and replaced my damage-reduction by hand easily.
What makes the thing complicated?
Did I forget anything?

grim001 11-07-2009 07:01 PM

I don't feel like getting into the details of how damage modification systems can fail, but there are about a dozen different ways. It gets more complicated if you allow it to increase damage dealt, keep bounties and kill triggers working correctly, avoid life bar flicker, and be called an unlimited number of times on the same unit.

Fire-Dragon-DoL 11-08-2009 04:52 PM

I'm having a problem with the external call (that should come in compile time right?)

It doesn't include any ability (and I haven't even created a single one, or even edited!)...

Can you post a map with the ability (also even the ability, just to allow me copy/paste) because i think it'easier than come up on why the merger doesn't work for me :P

Another little thing
Are there any possibilities for damage types implementation?Or at least something like this in your to-do list?Because damage types are very interesting

Anitarf 11-09-2009 12:41 PM

If the object merger call isn't working for you, you can create the ability in the object editor yourself instead, I think that's the fastest way. Just pick one of the "Item Life Bonus" abilities, make a custom ability based on it, change the life bonus value to some high number and copy the new ability's rawcode to the calibration section of DamageModifiers.

Sinnergy 01-18-2010 09:48 AM

ok I have this simple spell that just modifies the received damage of the targeted unit to deal more damage, but I'm just confused if I still need to this function function RunDamageModifiers takes nothing returns real
If I need to call that function, then where should I call it?
The spell code:

//! zinc
library BOY requires AutoIndex, SpellEvent, DamageModifiers, TimerUtils{
    constant integer spell = 'A01I';
    constant string sfx = "Abilities\\Spells\\NightElf\\Barkskin\\BarkSkinTarget.mdl";
   
    struct boyDamage extends DamageModifier{
        integer l;
        method onDamageTaken(unit c, real dmg)->real{
            return dmg*(0.13*l);
        }
    }
   
    struct data{
        unit u;
        effect fx;
        real ctr;
        boyDamage dm;
        method onDestroy(){
            DestroyEffect(fx);
            ctr = 0.0;
        }
    }
   
    function act(){
        unit c = SpellEvent.CastingUnit;
        unit u = SpellEvent.TargetUnit;
        timer t = NewTimer();
        data d = data.create();
        d.u = u;
        d.fx= AddSpecialEffectTarget(sfx,u,"origin");
        d.ctr = 0.0;
        d.dm= boyDamage.create(u,0);
        d.dm.l = GetUnitAbilityLevel(c,spell);
        SetTimerData(t,d);
        TimerStart(t,0.035,true,function(){
            timer t = GetExpiredTimer();
            data d = GetTimerData(t);
            if(d.ctr >= 8.0 || GetWidgetLife(d.u) <= 0.405){
                d.dm.destroy();
                ReleaseTimer(t);
                d.destroy();
            }
            d.ctr += 0.035;
            t = null;
        });
        t = null;
        u = null;
        c = null;
    }
   
    function onInit(){
        RegisterSpellEffectResponse(spell,act);
    }
}
//! endzinc


Anitarf 01-18-2010 02:16 PM

If you have the DamageEvent library in your map, you do not need to call RunDamageModifiers yourself because DamageEvent already does it.

Sinnergy 01-27-2010 01:32 AM

ok I have this skill that increases the damage on whatever damage she dealt to enemy units (10/20/30% amplify damage), base spell is from berserk, and the timer inside the trigger checks if the unit still has the berserk buff, else destroy damage modifiers.

I doubt that this trigger doesn't work, why? because I have another spell that deals 300 damage (attack type normal, damage type normal) that when tested to a 330 life unit with 0 armor, the spell left the target with 23 life without the damage modifiers applied, again tested the spell now with damage modifiers applied, now the spell left the target with 19 life, while 300 * 30% = 90 = 390 damage in total, which must kill the target instantly.

So here's the code.
Collapse Zinc:
//! zinc
library ArcaneBless requires TimerUtils, DamageModifiers, SpellEvent{
    constant integer spell = 'A01Y';
    constant integer bap = 'B00K';
    
    struct abDamage extends DamageModifier{
        integer l;
        method onDamageDealt(unit t, real dmg)->real{
            return dmg*(l*0.1);
        }
    }
    
    struct data{
        unit c;
        abDamage dm;
    }
    
    function act(){
        unit c = SpellEvent.CastingUnit;
        timer t = NewTimer();
        data d = data.create();
        d.c = c;
        d.dm = abDamage.create(c,0);
        SetTimerData(t,d);
        TimerStart(t,0.035,true,function(){
            timer t = GetExpiredTimer();
            data d = GetTimerData(t);
            if(GetUnitAbilityLevel(d.c,bap) <= 0 || GetWidgetLife(d.c) <= 0.405){
                d.dm.destroy();
                ReleaseTimer(t);
                d.destroy();
            }
            t = null;
        });
        t = null;
        c = null;
    }
    
    function onInit(){
        RegisterSpellEffectResponse(spell,act);
    }
}
//! endzinc

Deaod 01-27-2010 10:38 AM

Correct me if im wrong, but i think you forgot to change d.dm.l when creating a new instance.

Sinnergy 01-28-2010 02:43 AM

Quote:

Originally Posted by Deaod
Correct me if im wrong, but i think you forgot to change d.dm.l when creating a new instance.

owned

Kueken 01-28-2010 01:27 PM

Any possibility to use the variables for the damage types provided by IDDS together with damagemodifiers? I tried to access the GetDamageType function directly in the DamageModifiers onDamageTaken method, but they return 1 for every damage type. I would like to make the modifier behave differently with different damage types.

Anitarf 01-28-2010 05:26 PM

Quote:

Originally Posted by Kueken
Any possibility to use the variables for the damage types provided by IDDS together with damagemodifiers? I tried to access the GetDamageType function directly in the DamageModifiers onDamageTaken method, but they return 1 for every damage type.

That is not something I can answer since I did not make IDDS.

Quote:

I would like to make the modifier behave differently with different damage types.
I use xedamage to achieve this effect.

Edit: Sinnergy: Can I assume your problem has been fixed?


All times are GMT. The time now is 08:00 PM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services