• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] Damage Detection System

Status
Not open for further replies.
Level 17
Joined
Mar 17, 2009
Messages
1,349
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!
 
Level 11
Joined
Apr 29, 2007
Messages
826
edit/ Okay, rewrote it abit to make it better. I think it's still pretty easy to use.

JASS:
//! 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

JASS:
//! 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:
JASS:
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:
Level 11
Joined
Apr 29, 2007
Messages
826
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?
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.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
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!
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
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
 
Level 4
Joined
Jan 27, 2010
Messages
133
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.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
@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...
 
Level 4
Joined
Jan 27, 2010
Messages
133
I just don't get why TriggerHappy is SO against me using the DD system...

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.

Its funny how I said exactly the same in one sentence before your post^^

My post is at least a bit more descriptive, don't you think? :p
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
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...
 
Status
Not open for further replies.
Top