System Damage

W!†A_cRaft

Ultra Cool Member
Reaction score
28
i think i need to learn a lil more about JASS before understanding what you just said :)

dont really get the whole scope thing
 

Jesus4Lyf

Good Idea™
Reaction score
397
Convert any GUI trigger with an event into JASS. At the bottom, you will see the trigger get created, and an event gets registered. Replace that register with Damage_RegisterEvent(...) where the ... is simply the trigger. That will cause the trigger to fire every time any unit takes damage. Use conditions or if statements to narrow down when you want things to take place, and you can do damage blocking inside it. :)
 

SanKakU

Member
Reaction score
21
what jesus4lyf mentioned is the starters in using jass...that's not really explaining vjass...and i see how kingking's post could've been confusing.

scopes are used to make things easier or more difficult to access, with ease. you don't have to have things named really bonkers names like what happens when you convert to custom text. so every function in a scope, if labeled private, will not be accessible outside of the scope. this means you can copy and past large chunks of code without bothering to rename so much of it. you just put it in a scope and keep changing the scope names.

same thing with local variables in functions, they are not accessible outside of the function.

scope whatever initializer I

kingking might've confused you with those < and > characters. scope name is whatever and initializer anme is I. a lot of folks make initializer be named Init, but really, you can name it whatever you want.

the initializer is where you have the trigger's event registered and where you give it conditions and actions.

i recommend reading cohadar's vjass tutorial. that is what really helped me. that, and just importing lots of systems into your map and checking them out. that, and examining how other maps work, assuming they don't lock up their code.
 

AoW_Hun7312

I'm a magic man, I've got magic hands.
Reaction score
76
Is there anyway to get the damage amount using this system? If not, could you add it? If someone receives negative damage, it still triggers the damage event.
 

W!†A_cRaft

Ultra Cool Member
Reaction score
28
If i made a function like this:

JASS:
function irrelevant takes nothing returns nothing
        local trigger threat T
        set threatT = CreateTrigger()
        call Damage_RegisterEvent(threatT)


Now this should register a "any unit takes damage" event to the trigger? Am I correct?

Now if lets say I use a "summoning spell" or use some different trigger to create additional units, will they be registered with into this trigger as well?

The basic question is: "Does this register only the units preset in the map at the moment of it's activation, or all units in general?"
 

jrhetf4xb

Member
Reaction score
12
You've got a syntax error but I guess it's just a quickly written example.
It registers all units in general. And also you'd have to add a condition/action but you probably know that already. :)
 

Jesus4Lyf

Good Idea™
Reaction score
397
The basic question is: "Does this register only the units preset in the map at the moment of it's activation, or all units in general?"
All units in general. Every unit that is created will also trigger that event, even if it was not made when the trigger had the event registered. :)
 

Bribe

vJass errors are legion
Reaction score
67
Damage_Pure must have use ATTACK_TYPE_CHAOS and not DAMAGE_TYPE_NORMAL, because only chaos damage can affect divine armour for those cases, even though you are using DAMAGE_TYPE_UNIVERSAL. Needs a fix.
 

Weep

Godspeed to the sound of the pounding
Reaction score
401
Damage_Pure must have use ATTACK_TYPE_CHAOS and not DAMAGE_TYPE_NORMAL, because only chaos damage can affect divine armour for those cases, even though you are using DAMAGE_TYPE_UNIVERSAL. Needs a fix.
Well, to be very specific, chaos damage has a 1x multiplier for every armor type by default, but that's changeable in the map configuration so there's no guarantee. It might be wise to list "1x multiplier for chaos damage" as a system requirement.

I agree it ought to be chaos type.

I was also curious recently about illusions with non-1x damage multiplier (or units with Berserk) - in the case of triggering crit. strike, the damage will be multiplied before detection, and again upon the bonus being dealt, thus affecting it twice (although, somehow, when I tried, it only happened with damage decreases). It's something to keep in mind...
 

Switch33

New Member
Reaction score
12
The only sane way is to just trigger all the damage. Change all the data table ratios to 1.0 in the map. Then assign a single attack type and defense type to each unit. And when units attack get their attack type and the defending unit's defense type so you can look up the correct value to multiply.

As for critical strike/evasion it only makes sense to trigger that as well. That way you know when a critical strike occurred or an unit missed etc.

As for illusions you check for the unit being of type illusion and always set it to 1.0 for their damage and damage they recieve as you can modify it in triggers.

It's pointless trying to keep wc3 as wc3 if you really want to control it. You gotta trigger somethings completely.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Yea, with these new libs, Damage is kinda useless ;P.
No, with Damage, making these new libs, is kinda useless.

Believe it or not, your opinion with no evidence is still what it always has been: worthless, and commonly proved to be wrong at a later date. :p

You can use Damage_Pure to achieve said objective.

Anyway, philosophy behind Damage systems are very subjective, so I'd appreciate no absolutes on such things in this thread. Things like should you be able to add bonus damage without retriggering the event, etc. Everyone has their own way of doing stuff..

I still haven't seen a system that works as flawlessly as this one.
 

Nestharus

o-o
Reaction score
84
Yea, there are many philosophies on damage detection systems and manipulating damage and so on.

Here is just some food for thought.


What a lot of people strive for now when making systems isn't super customization, like custom projectile systems and custom this and custom that, but rather working off of wc3 systems already in place, like warcraft 3 projectiles, warcraft 3 damage, and etc.

There are also lots of questions floating around on how to implement pure damage that completely ignores armor (armor type and value) regardless of the map while giving the killer bounty.

Newer systems work with any other system that don't override wc3 damage, meaning that users don't have to use a special damage function in order to see an attack's general type (physical, spell, or jass). Well, the latest at wc3c can only detect physical atm, and it does so with bugs.

If a system runs on a timer and always applies bonus life to a unit, then a user can use SetWidgetLife to deal pure damage, something that a lot of people have been waiting for and only one system can do at the moment. There is not one system online besides 1 that can deal pure damage regardless of armor and the map settings. Actually, I take that back, if you set all of the armor types to take 0% damage, then all units will be immortal as bounty can only be done via UnitDamageTarget, so I guess that's still a problem.


It may be a different philosophy, but one method has less limitations than another method, more features, and is just as bugless. Originally, the idea with always applying bonus life and using a timer was bugged as it ruined artillery type attacks (attacks that explode units). There was also a problem with buffs for detecting physical attacks. All of the bugs are solved now, so there is no reason not to get on the bandwagon. You can even now detect whether a damage was a non splash attack, a missile splash attack, or an artillery attack, and whether damage marks the unit to explode or not.

Now, if you just need base damage with total amounts (all damage dealt), I think your library would actually be the best as others are bogged down with other features, but yours still has the issue of applying pure damage.


You may say that Damage makes making other new libs bad, but the fact is that it can't do this w/o specifically working through it, something that a lot more people are finding useful (hence why the people at wc3c are now trying to get on board with their own stuff)


*Detect the major damage type (was it physical, spell, or jass)


Also, yours can't deal out pure damage, something that a lot of people have been asking about (yes, I've seen a lot of questions on how to deal pure damage on all the major wc3 modding sites).


Just recently, someone at THW was asking how to detect physical attacks only (just regular wc3 physical attacks).


You can say my opinions are irrelevant, but that doesn't change the facts ;P.

If you want any sort of shield (remember that most shields don't block all attacks, they typically either block physical or spell attacks), then I'm afraid your system will be pretty useless.

I'm just recommending that you update it to use some of the newer techniques. Since I solved the explosion bug with detecting physical attacks, there is no reason not to update it now. I posted the solution at wc3c under the PhysicalAttack thread.

http://www.wc3c.net/showpost.php?p=1130116&postcount=13


There are 3 forums with 3 different standard resources, meaning 1 main type of system for each forum ; \. I'm just saying that the DDS at TH is falling behind the ones at wc3c and THW now, and if you say it isn't, I need only point to the hard facts of what your system can't do and the others can do and how those features are extremely useful in most every situation. I have never ever needed to block plain damage that could have come from anywhere, nor have I ever heard of a mapper that actually needed that. Most people coming on forums asking about DDS always ask about blocking physical damage or blocking spell damage. I haven't even seen anyone asking about how to block damage in general, it's always one or the other (yes, never seen anyone asking about blocking general JASS damage either, lol..).




I also wrote a little mini tut on LUA_FILE_HEADER if you want to make your object generation safe. There are plenty of example scripts around if you know where to look. Here is one from Purge for his ReviveUnit script

JASS:

//! externalblock extension=lua ObjectMerger $FILENAME$
    //! runtextmacro LUA_FILE_HEADER()
    //! i dofile(&quot;GetVarObject&quot;)

    //! i local rez = getvarobject(&quot;AHre&quot;, &quot;abilities&quot;, &quot;ABILITIES_REVIVE_UNIT_RESURRECTION&quot;, true)
        //! i createobject(&quot;AHre&quot;,rez)
        //! i makechange(current,&quot;anam&quot;,&quot;DumResurrection&quot;)
        //! i makechange(current,&quot;aher&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;acat&quot;,&quot;&quot;)
        //! i makechange(current,&quot;atat&quot;,&quot;&quot;)
        //! i makechange(current,&quot;Hre1&quot;,&quot;1&quot;,&quot;1&quot;)
        //! i makechange(current,&quot;aare&quot;,&quot;1&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;aran&quot;,&quot;1&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;acdn&quot;,&quot;1&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;amcs&quot;,&quot;1&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;atar&quot;,&quot;1&quot;,&quot;Air,Dead,Enemy,Friend,Ground,Neutral&quot;)

    //! i local dummy = getvarobject(&quot;ushd&quot;, &quot;units&quot;, &quot;UNITS_REVIVE_UNIT_DUMMY&quot;, true)
        //! i createobject(&quot;ushd&quot;,dummy)
        //! i makechange(current,&quot;unam&quot;,&quot;Dummy&quot;)
        //! i makechange(current,&quot;uabi&quot;,rez .. &quot;,Aloc,Avul&quot;)
        //! i makechange(current,&quot;ucbs&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;ucpt&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;umdl&quot;,&quot;none.mdl&quot;)
        //! i makechange(current,&quot;usca&quot;,&quot;0.01&quot;)
        //! i makechange(current,&quot;ushu&quot;,&quot;None&quot;)
        //! i makechange(current,&quot;umvh&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;umvs&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;ufoo&quot;,&quot;0&quot;)
        //! i makechange(current,&quot;umpi&quot;,&quot;100000&quot;)
        //! i makechange(current,&quot;umpm&quot;,&quot;100000&quot;)
        //! i makechange(current,&quot;umpr&quot;,&quot;1000&quot;)

        //! i updateobjects()
//! endexternalblock


Once you get the hang of how to use it, it's really pretty easy =P.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Way too long, man. Got bored reading. Got better things to do.

From what I managed to read:

Pure damage with Damage:
JASS:
function OMG4REALZ takes unit source, unit target, real amount returns nothing
    if amount&gt;GetWidgetLife(target) then
        call Damage_Pure(source, target, 99999999)
    else
        call SetWidgetLife(target, GetWidgetLife(target)-amount)
    endif
endfunction

I am considering updating the Damage_Pure function to do this, but I dunno. Seems pretty simple, right?

>Well, the latest at wc3c can only detect physical atm, and it does so with bugs.
Same old, same old, Damage just works. :thup:

Damage is really cool. It supports Damage_Block(amount). :p

Also, stop spamming your object generation script in all my threads. I got the point the first time, ok? I'll think about letting you make a version which uses it, which I'd then let you submit in a post in the thread already existing, and I could link directly to said post. Still thinking about it. :)
 

Nestharus

o-o
Reaction score
84
->Same old, same old, Damage just works
So does AdvDamageEvent ;P, and almost any system, as I said, needs to detect either physical or spell damage, so you should really work at updating ;p.

Information and Solution
Regular Damage-
1 damage event fires, buff applied before damage event

Missile Splash Damage
2 damage events fire for target unit
first damage event runs w/ dmg and w/o buff
second damage event runs w/ 0 damage and buff

2 damage event fires for rest of units
damage event runs w/ dmg and w/o buff
damage event runs w/ 0 damage and w/0 buff (wc3 bug??)

buff applied on rest of units on next period

Artillery Splash Damage
1 damage event fires
Buff applied to all units on next period

You have to use 2 abilities to get it working, and the two that appear to work are Frost Breath and Item Frost Damage Bonus. I have tried many combos and many abilities =).

JASS:

        if (UnitAlive(GetUnitById(targetId))) then
            if (GetUnitAbilityLevel(GetUnitById(targetId), DUMMY_BUFF) &gt; 0) then
                //was a physical attack
                if (ec[eventCount]) then
                    //initial splash (runs through w/ only splash abils on splash attack)
                    loop
                        set eventType<i> = PHYSICAL
                        set es<i> = 0
                        set i = i - 1
                        exitwhen not ec<i> or es<i> != sourceId
                        set ec<i> = false
                    endloop
                else
                    //not splash (doesn&#039;t run w/ splash abil no non splash attack)
                    set eventCount = eventCount + 1
                    set eventType[eventCount] = PHYSICAL
                    set update = true
                endif
            elseif (ls == sourceId and eventType[eventCount] == PHYSICAL) then
                //this will only run with non-splash abil and splash abil on splash attack
                //first the 0 dmg runs, then the actual damage runs, alternates
                if (ec[eventCount]) then
                    set ec[eventCount] = false
                else
                    set eventCount = eventCount + 1
                    set eventType[eventCount] = PHYSICAL
                    set ec[eventCount] = true
                    set update = true
                endif
            elseif (hooked[sourceId] &gt; 0) then
                //JASS attack
                set hooked[sourceId] = hooked[sourceId] - 1
                set eventCount = eventCount + 1
                set eventType[eventCount] = JASS
                set update = true
            elseif (overType != 0) then
                //known attack
                set eventType[eventCount] = overType
                set overType = 0
                set update = true
            else
                //unknown attack
                //will initially run for all splash attacks
                //artillery attacks won&#039;t be known until after timer
                set eventCount = eventCount + 1
                set eventType[eventCount] = 0
                set update = true
                set ec[eventCount] = true
                set es[eventCount] = sourceId
            endif
            //for chaining attacks together, last source = current source
            set ls = sourceId
            //if update (didn&#039;t skip), then add to timer stack
            if (update) then
                set eventSourceId[eventCount] = sourceId
                set eventTargetId[eventCount] = targetId
                set eventDamage[eventCount] = amount
            
                //if haven&#039;t saved the unit, add life abil to save it
                if (saved[targetId] == 0) then
                    set life = GetWidgetLife(GetUnitById(targetId))
                    call UnitAddAbility(GetUnitById(targetId), ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY)
                    call SetWidgetLife(GetUnitById(targetId), life+500000)
                endif
                //always increase the save count so life ability is removed at right time
                set saved[targetId] = saved[targetId] + 1
                
                //start the timer to actually handle (only needed because of artillery attacks)
                //artillery attacks are *never* known until after timer
                call TimerStart(eventTimer, 0, false, function thistype.handleEvent)
            endif
        endif
</i></i></i></i></i>


->Here is the final step inside of the timer method for retrieving type
JASS:

                if (type == 0) then
                    if (GetUnitAbilityLevel(target, DUMMY_BUFF) &gt; 0) then
                        set type = PHYSICAL
                        set explode = true
                    else
                        set type = SPELL
                        set explode = false
                    endif
                else
                    set explode = false
                endif
                if (type == PHYSICAL) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, &quot;PHYSICAL&quot;)
                    call UnitRemoveAbility(target, DUMMY_BUFF)
                endif
                call ANY.fire()
                call Event(type).fire()


->And killing
JASS:

                set life = GetWidgetLife(target)-500000
                set saved[targetId] = saved[targetId] - 1
                if (life &lt; .405) then
                    call SetUnitExploded(target, explode)
                    set saved[targetId] = 0
                    call SetWidgetLife(target, .5)
                    call disable()
                    call UnitDamageTarget(GetUnitById(sourceId), GetUnitById(targetId), 100, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
                    call enable()
                elseif (saved[targetId] == 0) then
                    call UnitRemoveAbility(GetUnitById(targetId), ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY)
                    call SetWidgetLife(target, life)
                endif


Also, you can't add the ability all willy nilly or you'll ruin explosions with artillery attacks, so detecting between dif types of physical attacks is kind of a necessity to fix the explosion bug.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
is there a way to block percent of damage taken? if not, why don't you replace this:
JASS:
public function BlockAll takes nothing returns nothing
    set ToBlock[TypeStackLevel]=ToBlock[TypeStackLevel]+GetEventDamage()
endfunction

with this:
JASS:
public function BlockPercent takes real percent returns nothing
    set ToBlock[TypeStackLevel]=ToBlock[TypeStackLevel] + GetEventDamage()*percent
endfunction

percent being any number between 0 and 1

I've changed it like that for my map (hope you don't mind) and it works
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top