System Damage

i think i need to learn a lil more about JASS before understanding what you just said :)

dont really get the whole scope thing
 
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. :)
 
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.
 
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.
 
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?"
 
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. :)
 
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. :)
 
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.
 
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...
 
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.
 
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.
 
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.
 
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. :)
 
->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.
 
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 The Helper:
    alternatively if you not making at least 23 an hour you could work in an Aldi warehouse
  • Varine Varine:
    Yeah I've been thinking about using AI for shit. I'm on vacation next week so I'm going to spend some time reorganizing everything and getting all my shit back in order
  • Varine Varine:
    lol I technically make less than 23 right now because I'm on salary and am there all the time, but it's a lot more than a normal wage still. I also have a meeting soon to renegotiate my pay because I want about a 25% increase to account for what I'm actually doing or a re-evaluation of our duties so that that my responsibilities are more in line with my pay. Depending on how that goes I'm prepared to give notice and move on, I don't mind taking less money so I'd have time for the rest of my life, but I'd rather they just fucking pay me enough to justify the commitment on my end. Plus right now I hold pretty much all the cards since I'm the only one actually qualified for my position.
    +1
  • Varine Varine:
    The other chef was there before me and got his position by virtue of being the only adult when the old general manager got married and didn't want to deal with the kitchen all the time, and happened to be in the position when the GM quit. New GM is fine with front of house but doesn't know enough about the kitchen side to really do anything or notice that I'm the one primarily maintaining it. Last time I left they hired like 3 people to replace me and there was still a noticeable drop in quality, so I got offered like 6 dollars an hour more and a pretty significant summer bonus to come back
  • Varine Varine:
    So honestly even if I leave I think it would last a couple of months until it's obvious that I am not exactly replaceable and then I would be in an even better position.
  • Varine Varine:
    But as of right now I have two other job offers that are reasonably close to what my hourly equivalency would be, and I would probably have more time for my other projects. The gap would be pretty easy to fill up if I had time to do my side jobs. I use to do some catering and private events, personal lessons, consultations, ect, and I charge like 120 an hour for those. But they aren't consistent enough for a full time job, too small of a town. And I'm not allowed to move for another year until my probation is over
  • Varine Varine:
    I guess I could get it transferred, but that seems like a hassle.
  • Varine Varine:
    Plus I have a storage room full of broken consoles I need to fix. I need to build a little reflow oven so I can manufacture some mod chips still, but it'll get there.
    +1
  • Varine Varine:
    I would like to get out of cooking in general at some point in the next ten years, but for the time being I can make decent money and pump that into savings. I've been taking some engineering classes online, but those aren't exactly career oriented at the moment, but I think getting into electronic or computer engineering of some sort would be ideal. I'm just going to keep taking some classes here and there until there's one that I am really into.
    +2
  • The Helper The Helper:
    There is money in fixing and reselling consoles. Problem is people know that so they are doing it
  • The Helper The Helper:
    If you can find a source of broken consoles though you can make money fixing them - sometimes some big money
  • Varine Varine:
    I was buying them on Ebay, but it's pretty competitive, so more recently I've just been telling the thrift stores to call me and I will come take all their electronics they can't sell. I've volunteered there before and people use them like a dump sometimes, and so they just have a massive amount of broken shit they throw away
  • Varine Varine:
    The local GoodWill was pretty into it, surprisingly the animal shelter store was not. The lady I talked to there seemed to think I was trying to steal stuff or something, she wasn't very nice about it. Like I'm just trying to stop you having to throw a bunch of electronics away, if you can sell it great. I'd probably pay you for the broken shit too if you wanted
  • Varine Varine:
    Then I make posts on Facebook yard sale pages sometimes saying I want your old electronics, but Facebook being Facebook people on there are also wary about why I want it, then want a bunch of money like it's going to be very worth it
  • Varine Varine:
    Sooner than later I'm going to get my archives business going a little more. I need some office space that is kind of hard to get at the moment, but without it, I have to be like "Yeah so go ahead and just leave your family heirlooms and hundred year old photographs here at my shitty apartment and give me a thousand dollars, and next month I'll give you a thumb drive. I promise I'll take care of them!"
    +1
  • Varine Varine:
    I can do some things with them at their home, but when people have thousands of slides and very delicate newspaper clippings and things, not really practical. I
  • Varine Varine:
    I would be there for days, even with my camera set up slides can take a long time, and if they want perfect captures I really need to use my scanners that are professionally made for that. My camera rig works well for what it is, but for enlargements and things it's not as good.
  • Varine Varine:
    I've only had a couple clients with that so far, though. I don't have a website or anything yet though.
  • Varine Varine:
    Console repair can be worthwhile, but it's also not a thing I can do at scale in my house. I just don't have room for the equipment. I need an office that I can segregate out for archival and then electronic restoration.
  • Varine Varine:
    But in order for that to be real, I need more time, and for more time I need to work less, and to work less I need a different job, and for a different job I need more money to fall back on so that I can make enough to just pay like, rent and utilities and use my savings to find these projects
    +1
  • Varine Varine:
    Another couple years. I just need to take it slow and it'll get there.
  • jonas jonas:
    any chance to get that stolen money back?
  • jonas jonas:
    Maybe you can do console repair just as a side thing, especially if there's so much competition business might be slow. Or do you need a lot of special equipment for that?
  • jonas jonas:
    I recently bought a used sauna and the preowner told me some component is broken, I took a look and it was just a burnt fuse, really cheap to fix. I was real proud of my self since I usually have two left hands for this kinda stuff :p
  • tom_mai78101 tom_mai78101:
    I am still playing Shapez 2. What an awful thing to happen, Varine, and hopefully everything has been sorted out soon. Always use multi-factor authentication whenever you have the opportunity to do so.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top