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

[vJASS] [System] Physical Damage Detection

Level 14
Joined
Dec 12, 2012
Messages
1,007
Give Dalvengyr some room for error, he is still learning.

I do, just explained my opinion about that topic :p

that's what I meant, whatever the reason is, it's still coded in JASS, not GUI.. but GUI friendly..

Well the thing is that with custom scripts there is no clear border between Jass and GUI. Is Bribes DDS a GUI System? One could say "of course", as it is coded in GUI. However a good portion of it are just Jass constructs (like functions) that don't even exist in GUI, so saying "no, thats a Jass System" is also not really wrong.

But you can disagree on that of course ;)
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
There are three unused variables in DamageEvent, which you might want to remove:

line 331: private function GetUnitSpellResistance takes unit u returns real
The parameter u is never used.

line 392: local real pureAmount = LoadReal(h, id, 2)

line 423: local real health
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
There are three unused variables in DamageEvent, which you might want to remove:

Ups, you are right. I guess those were left-over from debugging. New version removed those. I also decided to remove the optional support for TriggerRefresh library by Nestharus, for several reasons.

UPDATE Version 1.1.0.0:
- Removed two unused local variables
- Removed optional support for TriggerRefresh
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Is it possible to deal my own damage types?

Sure, as it is in general with all triggered damage:

JASS:
scope OnDamage initializer onInit
	globals
		integer myDamageType = 0
		constant integer DAMAGE_TYPE_USER_1 = 1 // Define your damagetypes
		constant integer DAMAGE_TYPE_USER_2 = 2
		constant integer DAMAGE_TYPE_USER_3 = 3
		unit myUnit
	endglobals

    private function OnDamage takes nothing returns nothing
        if myDamageType == DAMAGE_TYPE_USER_1 then // Check for them here
			call BJDebugMsg("user-defined damagetype 1 detected!")
			set myDamageType = 0 // Don't forget to reset this
		endif
    endfunction
    
    private function onInit takes nothing returns nothing
        call AddDamageHandler(function OnDamage)
    endfunction
endscope


scope Test initializer onInit
	private function callback takes nothing returns nothing
		set myDamageType = DAMAGE_TYPE_USER_1 // Set your damagetype right before dealing the damage
		call UnitDamageTarget(myUnit, myUnit, 50, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
	endfunction

	private function onInit takes nothing returns nothing
		set myUnit = CreateUnit(GetLocalPlayer(), 'hfoo', 0.0, 0.0, 0.0)
		call TimerStart(CreateTimer(), 5.0, false, function callback)
	endfunction
endscope
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
I have a design proposal.

Currently the UnitDamageTargetEx function is delayed to not mess up events. However, this creates problems, as damage should never be delayed without the user wanting to do that.

The solution would be to make the function check if you are currently running a damage event. If you are not, then it will deal damage as usual, with no delay.
If you are, then it will put the information in a stack.
Every time that you finish running the damage events you take 1 event from the stack and do the damage, triggering a recursive loop of events.
To avoid the op limit you can use TriggerEvaluations.

Currently I use a wrapper for all this, because the provided function is simply not right.

JASS:
library OnDamage initializer i requires DamageEvent
    globals
        private unit array Source
        private unit array Target
        private real array Amount
        private boolean array Spell
        private boolean array AoE
        private boolean array DoT
        private integer Count = 0
        
        boolean SPLL = false
        boolean AOE = false
        boolean DOT = false
        
        boolean DamageMod = false
    endglobals
    
    function DealDamage takes unit source,unit target,real amount, boolean spell,boolean aoe,boolean dot returns nothing
        if DamageMod then
            set Count = Count + 1
            set Source[Count] = source
            set Target[Count] = target
            set Amount[Count] = amount
            set Spell[Count] = spell
            set AoE[Count] = aoe
            set DoT[Count] = dot
        else
            set SPLL = spell
            set AOE = aoe
            set DOT = dot
            set DamageMod = true
            call UnitDamageTarget(source,target,amount,true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set DamageMod = false
            set SPLL = false
            set AOE = false
            set DOT = false
        endif
    endfunction
    
    private function OnDamage_Actions takes nothing returns nothing
        if not(SPLL) and not(AOE) and not(DOT) then//Basic attack
            if GetUnitAbilityLevel(source,'A016') > 0 then
                call AddUnitState(source,UNIT_STATE_MANA,GetHeroInt(source,true))
            endif
        endif

        set DamageMod = false
        
        if Count > 0 then
            set SPLL = Spell[Count]
            set AOE = AoE[Count]
            set DOT = DoT[Count]
            set Count = Count - 1
            call UnitDamageTarget(Source[Count+1],Target[Count+1],Amount[Count+1],true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            set SPLL = false
            set AOE = false
            set DOT = false
        endif
    endfunction
    
    private function i takes nothing returns nothing
        call AddDamageHandler(function OnDamage_Actions)
    endfunction
endlibrary
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I have a design proposal.

Currently the UnitDamageTargetEx function is delayed to not mess up events. However, this creates problems, as damage should never be delayed without the user wanting to do that.

Hi, can you please provide a concrete example where this causes problems/undesired behavior? Spell damage is "delayed" anyway with this system (practically it is not really delayed, because the damage events are sorted correctly), so I don't see where this would cause problems.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Hi, can you please provide a concrete example where this causes problems/undesired behavior? Spell damage is "delayed" anyway with this system (practically it is not really delayed, because the damage events are sorted correctly), so I don't see where this would cause problems.

Well, I am currently making a map where there are a variety of spells. One of them reverses any damage (turns it into healing). This ability is very powerful if timed well, but this is where delay becomes a problem.
At some point I switched all spells to use the function provided by your system instead of the usual one, as I hoped to detect spell damage by marking it that way (using a wrapper now). When I did that, this reversal ability seemed to break down, because units died after it had been cast on them.
In reality it turned out that the problem was actually spell damage being delayed. Damage that should have hit before the shield was placed affected the unit after it was shielded and thus, killing it when it should have been invulnerable. This is quite unintuitive for players, since basic attacks do not suffer this problem.
Eventually I just wrote the wrapper that I posted earlier to avoid using UnitDamageTargetEx and thus, to avoid the delay.

The delay, as I estimate, is about 0.1 seconds.

I understand why you made it with a delay, but I believe it could be improved.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Well, I am currently making a map where there are a variety of spells. One of them reverses any damage (turns it into healing). This ability is very powerful if timed well, but this is where delay becomes a problem.

Ok, sounds like no problem for the system.

At some point I switched all spells to use the function provided by your system instead of the usual one, as I hoped to detect spell damage by marking it that way (using a wrapper now).

What? Sorry, but that doesn't make sense at all, the function is not there to detect spell damage, but just to deal damage from a running damage handler. By no means you should replace all calls in your map with that function but only the calls from onDamage handlers. Everywhere else you should just use the normal UnitDamageTarget function.

I don't see why you "hope" to detect spell damage that way? The test map shows how to detect spell damage correctly.

The delay, as I estimate, is about 0.1 seconds.

Thats not possible, I guess you are doing something wrong. The system uses a 0-second timer, so no damage is ever delayed so long.

Please upload a full minimal example map/code that demonstrates the problem.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
In the attached map I've added a tester unit and necropolis to the upper part of the map.
Use the Q ability on the necropolis and you'll see that damage is clearly delayed, while the damage from W is not. (I made Q use UnitDamageTargetEx just for this test)
I don't know the exact reason, but I do know that it's the same thing that messed with the damage reversal spell, as changing all UnitDamageTargetEx functions to UnitDamageTarget fixed it.

Some time I had just UnitDamageTarget, but now I use a wrapper. It doesn't matter much though, as the damage functionality works exactly the same as calling the function yourself.

EDIT: Fixed the Q not dealing any damage at all. That was unrelated and due to some custom stats I've added after switching to my wrapper.
 

Attachments

  • Rise of Carnage v0.05showcase.w3x
    161 KB · Views: 47
Level 21
Joined
Mar 27, 2012
Messages
3,232
I don't protect my maps, but I guess this is from UMSWE GUI functions.
Also, this map can't be saved by anyone else without removing the triggers. I'll figure something out and then try to show again.

EDIT: Apparently in a blank map this delay doesn't exist. Getting interesting.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Since I wasn't able to reproduce it in an empty map, then we need to figure out which GUI functions are breaking the loading.

If its not reproducible in an empty map, the problem isn't related to the system. So it must be somehow related to UMSWE I guess.


Also I have no idea about UMSWE, I never used it so far. UMSWE has been reported many times to be buggy by several people in different forums, so I wouldn't use it if I were you. Why not just use the latest vJass version available?

All my spells are coded in vJASS. GUI is much more practical for some things though.

Really? I never was in a situation were I would prefer GUI over vJass, but ok. The question is, do you now use the vJass version of this system with GUI (this version), or do you use the GUI version (with GUI or Jass)?

Or do you use the vJass version with vJass? Generally I wouldn't recommend mixing those coding styles in a map (especially in a big project) ...
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
If its not reproducible in an empty map, the problem isn't related to the system. So it must be somehow related to UMSWE I guess.


Also I have no idea about UMSWE, I never used it so far. UMSWE has been reported many times to be buggy by several people in different forums, so I wouldn't use it if I were you. Why not just use the latest vJass version available?



Really? I never was in a situation were I would prefer GUI over vJass, but ok. The question is, do you now use the vJass version of this system with GUI (this version), or do you use the GUI version (with GUI or Jass)?

Or do you use the vJass version with vJass? Generally I wouldn't recommend mixing those coding styles in a map (especially in a big project) ...

I haven't used any UMSWE functions at all for damage, so that can't be the reason. The most likely cause seems to be that 0-timers are instant if you have few of them, but get slight delays if you have more of them (just a theory).
The jasshelper version that I use is late enough to run any system I've ever used, so that probably isn't a problem either.
UMSWE functions are not all evil. Some are so useful that they should have been in the editor in the first place (Is unit type tauren).

I use the vJASS version. The main places where I use GUI are configuration and simplest triggers, because JASS does have some slight development overhead in the name of debugging(I always make at least a few mistakes, so it takes a little time to fix), so I make some things in GUI just to not waste time overoptimizing.
If you come to the hive chat or somewhere, then I can post any code in the map. The reason why I can't remove UMSWE functions is that I have 52 triggers and I don't even know which ones use UMSWE. Also, many systems are interrelated.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
obviously the timers will take longer to fire if you have multiple of them, but they get fired one per logic frame, and you have fuck ton of logic frames every second(few thousand at least), so it is maybe 0.001 seconds delayed, which is 16.6666666 faster than the graphics logic. I really dont believe you can get 0.1 seconds delay between the call and the damage event
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Open the map that I attached earlier ingame. You'll see that there's a delay. I fixed it by using UnitDamageTarget, instead of -Ex.

However, the problem with using this is that I have to have my own wrapper for something that technically already exists in the system.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I haven't used any UMSWE functions at all for damage, so that can't be the reason.

Well, maybe UMSWE timer functions are bugged? I really can't say anything about that because I never used UMSWE.

The most likely cause seems to be that 0-timers are instant if you have few of them, but get slight delays if you have more of them (just a theory).

No thats definitly not the case. While developing the system I made tests with 1000 units attacking each other at the same time, or dealt periodic damage in a 0.001 timer loop. If timers would get slower the system wouldn't have passed those tests. Also many other systems that rely on 0-second timers wouldn't work then.

The jasshelper version that I use is late enough to run any system I've ever used, so that probably isn't a problem either.
UMSWE functions are not all evil. Some are so useful that they should have been in the editor in the first place (Is unit type tauren).

Well, just because they are practical (is unit type tauren) doesn't mean that they are good (in the sense of not evil), right? But again I have no idea about UMSWE, so I can't say which functions would be safe and which not.


I use the vJASS version. The main places where I use GUI are configuration and simplest triggers, because JASS does have some slight development overhead in the name of debugging(I always make at least a few mistakes, so it takes a little time to fix), so I make some things in GUI just to not waste time overoptimizing.

Ok, but for configuration and very simple triggers you shouldn't need the extended UMSWE GUI functionality, right? So maybe you could still change to Jass Newgen Pack 2.0.X as you use mostly vJass anyway?


If you come to the hive chat or somewhere, then I can post any code in the map. The reason why I can't remove UMSWE functions is that I have 52 triggers and I don't even know which ones use UMSWE. Also, many systems are interrelated.

Well, looking through all 52 triggers will be a lot work, so maybe you could first check which triggers use UMSWE functions? So deactivate UMSWE and all triggers and then reactivate triggers untill you get an error on saving. Once you identified all triggers that use UMSWE we can see if the problem still exists with all UMSWE triggers deactivated.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Ok, but for configuration and very simple triggers you shouldn't need the extended UMSWE GUI functionality, right? So maybe you could still change to Jass Newgen Pack 2.0.X as you use mostly vJass anyway?




Well, looking through all 52 triggers will be a lot work, so maybe you could first check which triggers use UMSWE functions? So deactivate UMSWE and all triggers and then reactivate triggers untill you get an error on saving. Once you identified all triggers that use UMSWE we can see if the problem still exists with all UMSWE triggers deactivated.

Quite the opposite. I use GUI for simple things because it's simple. WEU adds some functions that were originally not accessable to GUI, but still usable in JASS.

I just went through the map and deleted any trigger that isn't relevant to this test. That way I also hit the UMSWE triggers.
All spells are still there and probably working, but the spell selection mechanism I deleted too. So unless you add things in object editor it's only possible to try the 2 abilities that I brought out.
It should be openable now.

I've also attached all the imports that might be necessary to save the map.
 

Attachments

  • Rise of Carnage v0.05showcase2.w3x
    147.6 KB · Views: 66
  • Bonus.j
    5.5 KB · Views: 67
  • ExtraConstants.j
    1.2 KB · Views: 63
  • ExtraFunctions.j
    4.1 KB · Views: 70
  • LeakCheck.j
    2.1 KB · Views: 68
  • PlayerLeave.j
    636 bytes · Views: 63
  • BonusAbils.j
    6.5 KB · Views: 63
  • AutoFly.j
    657 bytes · Views: 61
Level 14
Joined
Dec 12, 2012
Messages
1,007
Ok, I can open and safe the map now... But I have to say its a total mess... By giving a quick look, I found the following points:

  • You don't use the latest version of the DDS. Please update.
  • You use UnitDamageTargetEx outside of OnDamage handlers, like for example in your StormMaul library. As already said, this is not the intended use for this function.
  • Your OnDamage handler is completly weird. Thats absolutly contrary to how the system should be used, you execute a very complicated logic there on every damage event which is not helpfull... You shouldn't check for physical damage by something like if not(SPLL) and not(AOE) and not(DOT) then//Basic attack. The system can do that by just using if damageType == PHYSICAL then. But you don't even use the damageType variable anywhere. I really don't get what you are doing there, but I can tell you that its not good.
  • In your OnDamage handler you use the native UnitDamageTarget, which is the only place where you should not use it, but the system function UnitDamageTargetEx
  • After looking through the abilities in the map, I can't find the system specific abilities DAMAGE_TYPE_DETECTOR and SET_MAX_LIFE. You declared them as 'A01V' and 'A01W', but I can't find the corresponding abilities with those rawcodes in your map. Without those abilities the system can't work at all.

Go through this list and fix each of that point, then try it out again.

Appart from that, I have to say that the code is a really crude mixture of vJass, GUI and to Jass converted GUI. I really recommend you to either use GUI or vJass, because this code is really hard to maintain... I also wouldn't use //! import for libraries, that makes things only more complicated when you want to share your map as you have to deliver those scripts too. Why not copy them into a trigger and add them directly to the map? Then you can also look at the code faster...

It seems that you didn't understand how to use the system, please take a look at the testmap for various examples. Also please make sure to follow the installation instructions.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Btw, what you are trying to achieve is really extremly simple with this system, I made a testmap where you can take a look at it.

In the testmap, all damage is dealt normally. However, if the Blademaster is in Windwalk, every damage that he takes is reverted and actually heals him. If you remove the display messages from the code, the whole functionality needs about 10 lines of code:

JASS:
struct OnDamage extends array
	private static method onDamage takes nothing returns nothing
		if target == gg_unit_Obla_0000 and GetUnitAbilityLevel(gg_unit_Obla_0000, 'BOwk') > 0 then // Check for buff here
			set amount = -RAbsBJ(amount) // Invert the damage amount
		endif
	endmethod
	private static method onInit takes nothing returns nothing
		call AddDamageHandler(function thistype.onDamage)
	endmethod
endstruct

This works 100% safe and also has no delay. Of course you can change the buff from Windwalk to whatever you like. That should be exactly what you wanted, right?

However, I would still recommend you to re-write several parts of your spells/systems in clean vJass. If you still have questions/problems feel free to ask.
 

Attachments

  • DamageHeal.w3x
    33.6 KB · Views: 55
Level 21
Joined
Mar 27, 2012
Messages
3,232
Btw, what you are trying to achieve is really extremly simple with this system, I made a testmap where you can take a look at it.

In the testmap, all damage is dealt normally. However, if the Blademaster is in Windwalk, every damage that he takes is reverted and actually heals him. If you remove the display messages from the code, the whole functionality needs about 10 lines of code:

JASS:
struct OnDamage extends array
	private static method onDamage takes nothing returns nothing
		if target == gg_unit_Obla_0000 and GetUnitAbilityLevel(gg_unit_Obla_0000, 'BOwk') > 0 then // Check for buff here
			set amount = -RAbsBJ(amount) // Invert the damage amount
		endif
	endmethod
	private static method onInit takes nothing returns nothing
		call AddDamageHandler(function thistype.onDamage)
	endmethod
endstruct

This works 100% safe and also has no delay. Of course you can change the buff from Windwalk to whatever you like. That should be exactly what you wanted, right?

However, I would still recommend you to re-write several parts of your spells/systems in clean vJass. If you still have questions/problems feel free to ask.

The healing part worked exactly as intended, except when combined with UnitDamageTargetEx the way I used it. Some of the code posted is my own wrapper for dealing damage(that works flawlessly without a timer). The reason I have so much code in the damage handler is that it really handles any kind of damage. I could not split it into multiple handlers because that would break any custom stats (I don't know a way to register an afterdamage handler with your system).

I'll go over the code today and see if it works better.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
The healing part worked exactly as intended, except when combined with UnitDamageTargetEx the way I used it.

Yes, because you used it wrong ;)
UnitDamageTargetEx is only for dealing damage from a running OnDamage event, nothing else and you must not use it anywhere else. It is really only there for reflecting damage.

Some of the code posted is my own wrapper for dealing damage(that works flawlessly without a timer). The reason I have so much code in the damage handler is that it really handles any kind of damage.

Not really, what you mean by "any kind of damage"?

This system also handles any kind of damage. The thing is that you use several features wrong (like UnitDamageTargetEx) and try to work around the errors you get because of that by building a very complicated system around your OnDamage handlers with a stack and everything, instead of just using the system correctly.

Thats not only useless (because the system does that allready for you), but will also introduce new problems and errors, which are not related to the system.

You can delete about 90% of the code in your OnDamage handler if you just would use the system right. You also don't need that complicated wrapper to deal damage. If you need custom Damage Types for your spells like DoT, just use an integer variable which indicates the custom type as described here. Independent of that you can just use the native UnitDamageTarget in all your spells without that wrapper and of course also without a timer. The system does all that for you.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
90%? I'm not sure how you can say that much, since the wrapper part is small.

Also, the reason why I use a wrapper is that I want there to be just 1 function to use for damage and that this functions could handle the basic spell tagging. I get it that I can make spells detectable through damage type, but what about whether they are AoE, DoT or anything like that? I'll still need a wrapper for that I guess.
The damage amount calculation based on armor is there because blizzard left negative armor to increase damage, despite what the armor reduction constant does.

I guess the original delay that I complained about was simply that the system only applies -Ex damage in the afterdamage function?
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
90%? I'm not sure how you can say that much, since the wrapper part is small.

The entire stack-system you built around the OnDamage handler is not needed. You can remove it. Again: the system handles this for you, and its not so easy to build a simple stack like you did. There are many corner-cases where this will fail, so you should just rely on the system.


Also, the reason why I use a wrapper is that I want there to be just 1 function to use for damage and that this functions could handle the basic spell tagging. I get it that I can make spells detectable through damage type, but what about whether they are AoE, DoT or anything like that? I'll still need a wrapper for that I guess.

I would do it as described in the link I posted. IMO this is easier and more flexible but of course you can also use a wrapper. But that should be then a two or three line function.

The damage amount calculation based on armor is there because blizzard left negative armor to increase damage, despite what the armor reduction constant does.

The damage calculation is up to you, so you can do everything you want to calculate your desired damage, thats not the problem here.

I guess the original delay that I complained about was simply that the system only applies -Ex damage in the afterdamage function?

Thats quite likely. The UnitDamageTargetEx function is only there for damage reflection, which you don't have in your map. You only have damage modification (inverting damage is also modification), so you don't need that function at all.
 
Level 3
Joined
Dec 8, 2013
Messages
51
guys I have a problem with this system - I need to remove the buff have a unit that has caused the damage, but what I do, the order refuses to work.Though unit (source ) does not see.
call UnitRemoveAbility(source,'B000')
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
guys I have a problem with this system - I need to remove the buff have a unit that has caused the damage, but what I do, the order refuses to work.Though unit (source ) does not see.
call UnitRemoveAbility(source,'B000')

Hi, what do you mean with "unit (source) does not see"?

If I understand you right you want to remove buffs of the unit that cause damage? This can be easily done like this for example:

JASS:
struct OnDamage
	private static method onDamage takes nothing returns nothing
		call UnitRemoveBuffs(source, true, true)
	endmethod

	private static method onInit takes nothing returns nothing
		call AddDamageHandler(function thistype.onDamage)
	endmethod
endstruct

This code works perfectly fine for me so maybe specify a bit more detailed whats your problem.
 
Level 3
Joined
Dec 8, 2013
Messages
51
Thanks for the help, but I only removed certain type of buff, and now it doesn't work.
call UnitRemoveAbility(source,'B000')
source if't see..
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Thanks for the help, but I only removed certain type of buff, and now it doesn't work.
call UnitRemoveAbility(source,'B000')
source if't see..

So which native buff is 'B000' based on? Because thats a custom buff it would make sense to say which buff you used to create your own custom buff.

Also I still don't see the problem. If I use this code:

JASS:
struct OnDamage
	private static method onDamage takes nothing returns nothing
		call UnitRemoveAbility(source, 'Bspl') // Remove spirit link from the source
	endmethod

	private static method onInit takes nothing returns nothing
		call AddDamageHandler(function thistype.onDamage)
	endmethod
endstruct

everything works perfectly fine, also with other buffs. So it doesn't matter if you remove specific buffs or not. And I still don't get what you want to say with "source if't see.."?

Amazing.When i cause additional damage...the source of strays....How?

What?

Please spend some more time to write understandable sentences otherwise I can't help you.
 
Level 11
Joined
Oct 11, 2012
Messages
711
I really want to use this DDS in my map (IMO, its the best on hive after Nes removed his DDS) but I have lots of spells based on runed bracers and elunes grace, as well as some of them based on finger of death, so I think it would be a headache to implement this system. :(
 
Level 3
Joined
Dec 8, 2013
Messages
51
:(
Sorry for my eng, okay.
When i use call UnitDamageTarget , source is strays.And therefore I cannot remove the buff.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I really want to use this DDS in my map (IMO, its the best on hive after Nes removed his DDS) but I have lots of spells based on runed bracers and elunes grace, as well as some of them based on finger of death, so I think it would be a headache to implement this system. :(

Well, spells based on runed bracers/elunes grace can be easily replaced. First remove their ability in the object editor then add the following code:

JASS:
private static method onDamage takes nothing returns nothing
    if GetUnitAbilityLevel(target, <your_ability_1>) > 0 then
        set damage = 0.5*amount // Reduce the damage by half
    endif
    if GetUnitAbilityLevel(target, <your_ability_2>) > 0 then
        set damage = 2.0*amount // Double the damage
    endif
    // and so on
endmethod

So even if you have 20 or more abilities base on bracers or elunes grace, doing this is a 10 minute work. But even better, you have much more control this way, because you can make those abilities stack or influence each other, which is not possible with the standard abilities.

The only problem of Finger of Death is, that it doesn't explode units correctly with this system. If you need that you can just add a SetUnitExploded call in your spells that are based on it.

:(
Sorry for my eng, okay.
When i use call UnitDamageTarget , source is strays.And therefore I cannot remove the buff.

The problem is not your english, but that you give to little information to let me help you:

  • What is your problem now, removing a buff or dealing damage or both? Or is the buff thing already solved with my last answer?
  • Which native buff you based your custom buff on is causing problems?
  • What you mean with "source is strays"? That the source dies? Or that the variable is invalid/returning the wrong unit?
  • "When i use call UnitDamageTarget": Where do you use it and who is supposed to deal damage?

The best would be if you post a minimal example code which demonstrates your problem. If you just want to deal damage to the source form a running onDamage event, do as Xonok told you and use the function UnitDamageTargetEx:

JASS:
struct OnDamage
    private static method onDamage takes nothing returns nothing
        // Remove the buff from the source
        call UnitRemoveAbility(source, 'Bspl')

        // Reflect half of the damage to the source
        call UnitDamageTargetEx(target, source, 0.5*amount, true, false, null, DAMAGE_TYPE_UNIVERSAL, null) 
    endmethod

    private static method onInit takes nothing returns nothing
        call AddDamageHandler(function thistype.onDamage)
    endmethod
endstruct

Important: Only use UnitDamageTargetEx within a function you added to the system with AddDamageHandler. Everywhere else use the standard UnitDamageTarget native.
 
Level 3
Joined
Dec 8, 2013
Messages
51
"use the function UnitDamageTargetEx"
I dont know how, but it's help me! Now I calmly answered buff!
Thanks to all.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
JASS:
/*
*   5.  As already mentioned you can't use the spell reduction ability when using this
*       system (runed bracers and elunes grace). If you want to use them, you can
*       trigger them by using the damage modifiers. Runed bracers is already considered
*       in this system, so you don't have to code it.
*/

what about abilities like Hardened Skin and those alike
 
Level 26
Joined
Mar 19, 2008
Messages
3,140
Best dds we got out here.
Nes' one has the highest amount of options/the most expanded one, yet we all know that Nes hides "few" additional requirements here and there ^)^

Codemonkey11' is also very nice yet I'd like to be able to read what I actually import into my map. I fail each time I read his scripts :(

This one is simple, readable, no overhead. Pretty much everything we need.
Not that I haven't been using any dds till now ;<

The only flaw is this part (it's quite dangerous):
JASS:
globals
        unit source
        unit target
        real amount
        integer damageType
        real damageEventTrigger
endglobals
You could have added them via module api or just within DamageEvent. I'd have no problem with writing: DamageEvent.source or DamageEvent.GetSource().
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Best dds we got out here.
Nes' one has the highest amount of options/the most expanded one, yet we all know that Nes hides "few" additional requirements here and there ^)^

Thx :)

The only flaw is this part (it's quite dangerous):

Yes, maybe I will do so in the future. For now I had to fix some really nasty bug:

Update to Version 1.1.2.0
- Replaced bj_mapInitialPlayableArea with GetWorldBounds()

Because under some circumstances (which I still don't know for sure) the former one returned a zero rect which disabled the DDS after the first clean-up period. With the GetWorldBounds native this problem does not appear.
 
Top