1. Head to the 33rd Modeling Contest Poll and drink to your heart's desire.
    Dismiss Notice
  2. Choose your means of doom in the 17th Mini Mapping Contest Poll.
    Dismiss Notice
  3. A slave to two rhythms, the 22nd Terraining Contest is here.
    Dismiss Notice
  4. The heavens smile on the old faithful. The 16th Techtree Contest has begun.
    Dismiss Notice
  5. The die is cast - the 6th Melee Mapping Contest results have been announced. Onward to the Hive Cup!
    Dismiss Notice
  6. The glory of the 20th Icon Contest is yours for the taking!
    Dismiss Notice
  7. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] Damage Detection System

Discussion in 'Triggers & Scripts' started by Deuterium, Feb 2, 2010.

  1. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Hello dear hivers :D

    Well, in short:
    I wonder if anyone could give me a link to a simple damage-detection system which allows me to know when a unit gets damaged.

    I know Rising_Dusks system, but it's too complicated and too extensive for my needs. I just need to know when a unit gets damaged in order to run the trigger.

    Thank you all!
     
  2. Darkness-4ever

    Darkness-4ever

    Joined:
    Nov 4, 2007
    Messages:
    763
    Resources:
    0
    Resources:
    0
  3. YourNameHere

    YourNameHere

    Joined:
    Apr 29, 2007
    Messages:
    745
    Resources:
    4
    Maps:
    1
    Spells:
    2
    JASS:
    1
    Resources:
    4
    edit/ Okay, rewrote it abit to make it better. I think it's still pretty easy to use.

    Old code
    Code (vJASS):
    //! zinc

        library DamageDetection
        {
            type eventHandler extends function(unit);
           
            eventHandler event[];
            integer count = 0;
           
            trigger exec = CreateTrigger();
           
            public function TriggerRegisterAnyUnitDamageEvent(eventHandler func)
            {
                event[count] = func;
                count += 1;
            }
           
            function onInit()
            {
                trigger t = CreateTrigger();
               
                //To register all units that exist at the beginning
                group g = CreateGroup();
                GroupEnumUnitsInRange(g, 0, 0, 999999, function() -> boolean
                {
                    TriggerRegisterUnitEvent(exec, GetFilterUnit(), EVENT_UNIT_DAMAGED);
                    return false;
                });
               
                DestroyGroup(g);
                g = null;
               
                //To register units that are created after the beginning
                TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea);
                TriggerAddCondition(t, function() -> boolean
                {
                    TriggerRegisterUnitEvent(exec, GetTriggerUnit(), EVENT_UNIT_DAMAGED);
                    return false;
                });
               
                //Actual function
                TriggerAddCondition(exec, function() -> boolean
                {
                    integer i = 0;
                   
                    while(i < count)
                    {
                        event[i].evaluate(GetTriggerUnit());
                        i += 1;
                    }
                   
                    return false;
                });
            }
        }
       
    //! endzinc
     


    New code
    Code (vJASS):
    //! zinc

        library DamageDetection
        {
            //CONFIGURATION
                constant boolean    REFRESH             = true; //Should it really refresh?
                constant real       REFRESH_INTERVAL    = 600;  //In seconds. 600 = 10 minutes
               
                constant boolean    CHECK               = true; //If it should check if the damage is atleast a
                                                                //specified amount
                constant real       CHECK_DAMAGE        = 1.0;  //Amount of damage it has to have
            //CONFIGURATION
       
            //Damaged unit, damaging unit, damage
            type eventHandler extends function(unit, unit, real);
           
            eventHandler event[];
            integer count = 0;
           
            trigger exec = CreateTrigger();
           
            public function TriggerRegisterAnyUnitDamageEvent(eventHandler func)
            {
                event[count] = func;
                count += 1;
            }
           
            function Damage() -> boolean
            {
                integer i = 0;
               
                static if (CHECK)
                {
                    if (GetEventDamage() < CHECK_DAMAGE) { return false; }
                }
               
                while(i < count)
                {
                    event[i].evaluate(GetTriggerUnit(), GetEventDamageSource(), GetEventDamage());
                    i += 1;
                }
               
                return false;
            }
           
            function DamageEnum() -> boolean
            {
                TriggerRegisterUnitEvent(exec, GetFilterUnit(), EVENT_UNIT_DAMAGED);
                return false;
            }
           
            function onInit()
            {
                trigger t = CreateTrigger();
               
                timer r;
               
                //To register all units that exist at the beginning
                group g = CreateGroup();
                GroupEnumUnitsInRange(g, 0, 0, 999999, function DamageEnum);
               
                DestroyGroup(g);
                g = null;
               
                //To register units that are created after the beginning
                TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea);
                TriggerAddCondition(t, function() -> boolean
                {
                    TriggerRegisterUnitEvent(exec, GetTriggerUnit(), EVENT_UNIT_DAMAGED);
                    return false;
                });
               
                TriggerAddCondition(exec, function Damage);
               
                static if(REFRESH)
                {
                    r = CreateTimer();
                    TimerStart(r, REFRESH_INTERVAL, true, function()
                    {
                        group g = CreateGroup();
                   
                        DestroyTrigger(exec);
                        exec = CreateTrigger();
                       
                        GroupEnumUnitsInRange(g, 0, 0, 999999, function DamageEnum);
                       
                        DestroyGroup(g);
                        g = null;
                       
                        TriggerAddCondition(exec, function Damage);
                    });
                }
            }
        }
       
    //! endzinc
     


    Sample usage:
    Sample
    Code (vJASS):
    library Test initializer init
        private function test2 takes unit u, unit d, real damage returns nothing
            call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl", u, "origin"))
        endfunction

        private function test takes unit u, unit d, real damage returns nothing
            call BJDebugMsg(GetUnitName(u) + " took " + I2S(R2I(damage)) + " damage from " + GetUnitName(d) + "!")
        endfunction

        private function init takes nothing returns nothing
            call TriggerRegisterAnyUnitDamageEvent(test)
            call TriggerRegisterAnyUnitDamageEvent(test2)
        endfunction
    endlibrary
     
    Last edited: Feb 2, 2010
  4. baassee

    baassee

    Joined:
    Nov 14, 2008
    Messages:
    3,220
    Resources:
    17
    Spells:
    14
    Tutorials:
    3
    Resources:
    17
  5. dardas

    dardas

    Joined:
    Sep 12, 2008
    Messages:
    649
    Resources:
    0
    Resources:
    0
    Hmm, if you still need it.. i could give you mine.. its pretty nice..
    pm me if you need it..
    its only like 2 triggers..(1 = write X damage taken, 2 = Pick every unit..)
     
  6. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    well YourName thanks for your effort... but I think I'm gonna use baassee's link :)

    BUT WTF is this //! zinc thing? :p
    I can see it's a bit similar to C++, but is there like any new operators or anything useful which isn't in vJass?
     
  7. baassee

    baassee

    Joined:
    Nov 14, 2008
    Messages:
    3,220
    Resources:
    17
    Spells:
    14
    Tutorials:
    3
    Resources:
    17
    vJass, cJass and ZINC ... all the same almost ^^ but I think ZINC is included in the latest JNGP
     
  8. YourNameHere

    YourNameHere

    Joined:
    Apr 29, 2007
    Messages:
    745
    Resources:
    4
    Maps:
    1
    Spells:
    2
    JASS:
    1
    Resources:
    4
    Zinc is a C-like feature which comes with the latest JassHelper version.
    It introduces a few things which ease the use of coding (like anonymous functions) and offers you a completely new style of coding imo, escpecially when you prefer a C-like syntax.
     
  9. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    off-topic:

    Well I hope Jass looked like C++, I mean even cJass - let's be honest - barely looks like C++ syntax.

    Zinc seems like a nice idea, I'd definitely would be interested into getting back to Jassing if I like it enough.

    And anonymous functions? Hehe I like that idea :p

    Well nice idea from Vex!
    YourNameHere, since you seem to know about C-syntax, please check this out :)
    Prototypes in vJass?

    Thanks guys!
     
  10. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Apparently guys I need something that also checks if damage is meelee...

    Here are the exact functions I would need:

    - One that runs the trigger on damage event
    - One that checks if the damage is attack-damage not spell-damage
    - One that returns the damage of the event

    And even if its a complicated system... I wouldnt mind anymore :p
    Thank you guys! =D

    PS: you don't need to MAKE me one :p just gimme a link to some system that you think is good! I'm bad at finding systems :p
     
  11. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,220
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    You can't check whether the damagetype is meele or not.
     
  12. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Sorry I didn't mean melee... i meant one that checks if the damage is through normal attack... not spell.
    Get my pt?
     
  13. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,220
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Pt?
    And yeah, you either have to use orbs at every unit or have to trigger every spell damage and let it run over your system.
     
  14. themerion

    themerion

    Joined:
    Jan 27, 2010
    Messages:
    132
    Resources:
    0
    Resources:
    0
    It's slightly difficult to differentiate between spell damage and attack damage. It's also difficult to separate ranged damage from melee damage. (shit, I'm typing too slowly :p)

    1. Old approach:
    Since damage detection registers all units anyway, we can give all units the same Orb-effect ability (an ability that leaves a buff on attack, like Orb of Corruption). As soon as a unit is damaged, we check for the buff of the orb, and remove it. If it had the buff, the damage was not caused by a spell.

    Cons:
    - You have to script/trigger all orb effects.
    - You can't use splash damage, since (orb-effect + splash damage) causes crash. (at least did when I last tested, a year ago or so)

    2. New approach:
    By scripting all damaging spells, you can let your damage detection engine know that the damage you're about to deal is spell damage.

    Cons:
    - You have to script all damaging spells.
     
  15. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,220
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Its funny how I said exactly the same in one sentence before your post^^
     
  16. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    @Anachron: 'pt' is abbreviation for 'point' :p not some net standard, it's real grammar :p

    Well, ok if you check the Maze spell in my Metaversal Spellpack, you'll notice that the DD library I use provide an option to check if damage is spell or attack.

    I just don't get why TriggerHappy is SO against me using the DD system, although it provides ALL i need and up till now, after 100's of tests, never bugged...
     
  17. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,220
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Its about standards :D.
    We have some really good DD systems out there, and they should be used.
    I for myself prefer IDDS. Also I kinda like ADamage by Anitarf, because its highly customizeable.

    However, CG made a small leakless DD system here.

    If you like unit recycling.
     
  18. themerion

    themerion

    Joined:
    Jan 27, 2010
    Messages:
    132
    Resources:
    0
    Resources:
    0
    I looked through the code, and I think it works this way:

    If I throw a slow moving missile, and then attack before the missile hits, that attack would register as spell damage.

    In other words, the system seem to be based on the assumption that there can't be two attack/spell-events in row without a damage event in between.

    My post is at least a bit more descriptive, don't you think? :p
     
  19. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Damn I should stop using abbreviations :p
    I was talking about the Dark_Dragon (i.e. DD :p) systems I used in my spellpack :p
    Up till now it's the only system that actually checks whether damage is attack or spell...

    I've seen IDDS, but it has all that about setting damage types and priorities... and the thing is, I don't want to use the script for a map, but for a spell to go into the spells section, so IDDS doesnt seem suitable.

    I saw CG's, but it doesn't check if damage is attack or spell like Dark_Dragon's... same goes for Anitarf's...

    Ukhh I'm really hating TriggerHappy for this :mad:

    EDIT:
    Guys, to get what I mean, please test the Maze spell in my Metaversal Spellpack... and you'd see how the stun is removed ONLY when the damage is through normal (hero) attack damage and not spell... and I've done that simply by using some function: IsDamageMelee - i guess that's the name - from Dark_Dragon's systems...
     
  20. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,220
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Relax.

    Your way is bugged as Themerion already said.