• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Damage Engine 5.A.0.0

This bundle is marked as director's cut. It exceeds all expectations and excels in every regard.
Damage Engine

Three GUI Damage systems for the community of The Hive,
Seven vJass Damage systems for the JASS-heads on their pedestals high,
Nine competing Damage systems, doomed to die,
One for Bribe on his dark throne
In the Land of the Hive where the Workshop lies.
One Damage Engine to rule them all, One Damage Engine to find them,
One Damage Engine to bring them all and in cross-compatibility unite them.


Whether you're looking for a simple DDS (Damage Detection System), need to modify damage or even if you want a complex network of damage pre-and post-processing, this resource is for you. Damage Engine is the most adapted DDS in existence to take full advantage of the new damage detection natives, and is constantly evaluated and scrutinized by both the community and myself for performance improvements, bug fixes and new features alike.

What started with humble beginnings to bring a Unit Indexer-based version of DDS to GUI users to improve on the previous standard (at the time it was Weep's GDDS) would eventually evolve to incorporate other aspects of damage systems out there. @looking_for_help had identified an extremely useful technique with negative spell resistance being used to detect spell damage, and for a time his Physical Damage Detection system became the new standard. It wouldn't be until much later when Damage Engine would resurface and use the same technique in order to be more useful for the community.

Fast forward to 2020, and you'll find not only that cross-compatibility with Weep's and LFH's systems are incorporated, but the most popular DDS systems in existence - even vJass ones - are fully supported via stripped-down API wrappers. All of the functionality of prior DDS systems has been infused into Damage Engine 5.7, and as such the transition to a "one size fits all" DDS is complete. I hope you find this to be useful, and I also hope that it will help you in developing your map to be more dynamic what than you had previously thought possible.

Features

Legacy Code & Requirements

How it works

How to install/upgrade

Video Guides

FAQs

Thanks


  • Damage Type, Attack Type, Weapon Type, Armor Type and Defense Type detection and modification to alter/understand the fundamentals of WarCraft 3's damage processing;
  • Access to the view and change the damage amount before and/or after reduction by armor, armor type and shields.
  • Fully cross-compatible with every major DDS - vJass and GUI alike.
  • Correctly distribute/negate Spirit Link damage.
  • Differentiate between Ranged, Melee, Spell or other types of attack.
  • Does not require any Object Editor data nor Unit Indexer.
  • As of 5.4, it is now completely recursion-proof.
  • Other features:
    • Damage Blocking, reducing, amplifying and/or conversion to healing
    • Does not require you to know nor use Jass NewGen Pack nor any custom script
    • Custom DamageType association available to be set before and/or during damage event
    • Detect when multiple targets were hit simultaneously via DamageEventAOE > 1.
    • Detect when the same unit was hit simultaneously by the same source via DamageEventLevel > 1.
  • Detect damage: use the event "OnDamageEventEqual to <any value>". You have access to the following variables for reference:
    • DamageEventSource - the unit dealing the damage
    • DamageEventTarget - the unit receiving the damage
    • DamageEventAmount - the amount of damage the unit will receive
    • DamageEventPrevAmt - the amount of damage prior to being modified by the game engine.
    • DamageEventAttackT - the attack type (Chaos, Spells, Pierce, etc.)
    • DamageEventDamageT - the damage type - for comprehensive info, click here.
    • DamageEventWeaponT - the weapon type determines if an attack plays some kind of sound on attack (ie. Metal Heavy Bash). It is always NONE for spells and almost always NONE for ranged attacks.
    • DamageEventArmorT - the armor type (Flesh, Stone, Ethereal, etc.)
    • DamageEventDefenseT - the defense type (Hero, Fortified, Unarmored, etc.)
    • DamageEventArmorPierced - if DAMAGE_TYPE_NORMAL, how much armor was set to be ignored by the user.
    • IsDamageSpell, IsDamageRanged, IsDamageMelee - determine the source category of damage dealt.
    • IsDamageCode - Determine if the damage was dealt natively or by the user. This can give incorrect readings if the user has not identified to Damage Engine that it is code damage. Therefore I recommend setting NextDamageType prior to dealing damage.
    • DamageEventType - An integer identifier that can be referenced by you for whatever extra differentiation you need. You can also create your own special damage types and add them to the definitions in the Damage Event Config trigger. If you the unit should explode on death by that damage, use a damage type integer less than 0. If you want the damage to ignore all modifications, use DamageTypePure.
  • To change damage before it's processed by the WarCraft 3 engine: use the event "PreDamageEvent Becomes Equal to <any value>". Whether you just want to use one monolithic trigger for all damage modification like I do in the demo map, or use the different modifier events here, is up to you.
  • To interact with damage after it's been factored for armor and resistances, use "ArmorDamageEvent Becomes Equal to <any value>". This is typically useful for custom shields. If you fully block or absorb DamageEventAmount (setting it to 0 or less), this event doesn't run.
  • To set the DamageEventType before dealing triggered Damage, use:
    - Set NextDamageType = DamageTypeWhatever
    - Unit - Cause...
  • You can modify the following variables from a "PreDamageEvent" trigger:
    • DamageEventAmount
    • DamageEventAttackT/DamageT/WeaponT/ArmorT/DefenseT
    • DamageEventArmorPierced
    • DamageEventType
    • DamageEventOverride - You can set this if you want to remind yourself not to modify the damage further. If you use the UNKOWN damage type from a Unit - Damage Target native or set "NextDamageType = DamageTypePure" before that function, damage modification is skipped.
  • To catch a unit the moment before it would die from damage, use LethalDamageEvent Becomes Equal to 1.00. Instead of modifying the DamageEventAmount here, modify LethalDamageHP to let the system know how much life to keep the unit alive with. Or you can just reference that LethalDamageHP value in order to know how much "overkill" damage was dealt.
  • To catch a unit as soon as the damage is applied against its Hit Points, use AfterDamageEvent Equal to 1.00.
  • Usage of the "<Event> becomes EQUAL to <value>" can be extrapolated as per the below:
    • EQUAL works as it always has - will run for any damage.
    • NOT EQUAL only runs for code damage.
    • LESS THAN only runs for damage from attacks but not coded attacks.
    • LESS THAN OR EQUAL only runs for melee attacks but not coded attacks.
    • GREATER THAN OR EQUAL only runs for ranged attacks but not coded attacks.
    • GREATER THAN only runs for Spell damage but not coded spell damage.

  • Damage Engine 5 and higher requires the latest Warcraft 3 patch (currently 1.32).
  • For people who did not update their game to Reforged / have not updated to Reforged yet. Alternatively, adding the below JASS script to the top of the DamageEngine library SHOULD enable it to work too:

    JASS:
    function BlzGetEventIsAttack takes nothing returns boolean
         return BlzGetEventDamageType() == DAMAGE_TYPE_NORMAL
    endfunction
  • I have created a Pastebin for all information pertaining to Damage Engine 3.8, including the link to download it, via: Damage Engine 3.8.0.0 | HIVE.
  • As of 20 June 2020, JNGP users who are still on WarCraft 3 1.26 can benefit from Damage Engine 3A, which integrates many of the design choices added in various stages of Damage Engine 5. This is a special update which only requires the JASS script be replaced (no new GUI variables added). Can be found here: Damage Engine 3A.0.0.0 and 3.8.0.0 | HIVE

1
Unit attacks or casts a spell. The pure damage is assessed at this point - damage dice, evasion, critical strike. There is currently no event to affect or modify these at source.
→ →
2
The projectile or weapon hits the target unit
→ →
3
EVENT_UNIT_DAMAGING is fired before any modifications to the damage are made.
→ ↓
↓ ←
6
User changes to DamageEventAmount and/or to DamageEventDamageT/AttackT/WeaponT are saved into the WC3 engine.
← ←
5
If any recursive damage is detected from any of those events, it is postponed and the current damage will continue first.
← ←
4
Damage Engine deploys the PreDamageEvent
7
WarCraft 3 processes the user damage.
→ →
8
WarCraft 3 then distributes the user damage into Spirit Link (before armor)
→ →
9
WarCraft 3 runs any interrupting events, such as spirit link or defensive damage like Thorns Aura
→ ↓
↓ ←
12
The EVENT_UNIT_DAMAGED event runs. This is the original event we have always had access to. Damage Engine will either keep using the original variables from the DAMAGING event, or if there was Spirit Link/defensive damage it will freshly retrieve the event values from WC3 and only retain DamageEventPrevAmt.
← ←
11
Once any potential recursive WarCraft 3 damage is processed, the armor/mana shield modifications to the damage are performed.
← ←
10
If such events such as Spirit Link were detected, they fire their own EVENT_UNIT_DAMAGING & EVENT_UNIT_DAMAGED, and DamageEngine processes it along the way for the user.
13
If the damage is above zero, ArmorDamageEvent will run. If any recursive damage is detected, it is postponed.
→ →
14
The user can make modification to the damage here with the after-damage amount.
→ →
15
The user can access DamageEventPrevAmount if they want to know the damage amount before user changes/WarCraft 3 changes.
→ ↓
↓ ←
18
The user can specify whether or not to change LethalDamageHP in order to stop the unit from dying.
← ←
17
If the damage is still above zero, check if the damage is lethal. If so, run LethalDamageEvent 1.00. If any recursive damage is detected, it is postponed.
← ←
16
If the user wants the value that DamageEngine used to have with DamageEventPrevAmt (after WarCraft 3 processing but before user changes) they multiply DamageEventPrevAmt x DamageScalingWC3.
19
Once all modification is done, run OnDamageEvent. If any recursive damage is detected, it is postponed.
→ →
20
After a new damage instance is detected, or the 0.00 timer expires, run AfterDamageEvent. If any recursive damage is detected, it is postponed.
→ →
21
Run all potential recursive Unit - Damage Target function calls in chronological order (first in, first out).

How to install Damage Engine:
  1. Use WarCraft 3 Version 1.32
  2. If you're upgrading from 3.8 or prior, please delete the entire "Damage Engine" category from your map.
  3. Copy & Paste the Damage Engine category from the attached map to your own map.
How do I upgrade to the latest Damage Engine?
- Depending on the complexity, you'll either need to re-copy the Damage Engine category or just the Damage Engine script. Generally, you can use this as a guide:

  • Damage Engine _._._.x - only requires copying of the JASS script
  • Damage Engine _._.x._ - generally only needs copying of the JASS script, but read the patch notes in case there are changes you may want to make to your own code in order to utilize the changes.
  • Damage Engine _.x._._ - delete your current Damage Engine category or manually add the missing variables to your Variable Editor, and update your JASS script.
  • Damage Engine x._._._ - this occurs very infrequently. Typically requires changes to the way Damage Engine needs to be installed and used.

Notes about upgrading from Damage Engine 4.0 or prior:
  • Revert any custom Object Editor changes made (such as Life Drain reversal, Spell Damage Reduction inversion, etc).
  • You can safely delete the custom spells "Spell Damage Detection" and "Cheat Death Ability"
  • You can delete the Unit Indexer trigger if you do not use it or would prefer to use a different indexer.
  • You should delete any "Mana Shield fix" or "Finger of Death fix" you may have imported, as well as revert any Object Editor data that was required to make it work, as these are no longer needed.
  • !!!DEPRECATED FEATURE!!! As of 5.4, do not bother to take any recursive damage mitigation - Damage Engine will now handle all of that for you!
  • !!!DEPRECATED FEATURE!!! Do not use "ClearDamageEvent" - it does nothing. Just delete it.
  • !!!DEPRECATED FEATURE!!! Do not use "NextDamageOverride" - set NextDamageType = DamageTypePure instead.
  • !!!CHANGED FEATURE!!! If the system detects code damage and the user did not specify it as any particular DamageEvenType, the system will assign it DamageTypeCode automatically.
  • !!!CHANGED FEATURE!!! DamageModifierEvent 1.00-3.00 now run prior to armor reduction. This enables the user to modify the damage before armor and resistance changes are applied - also before Mana Shield and Anti-Magic shell kick in, so no more need for special triggers.


  • Q: Why am I getting a bunch of 'trigger was disabled' errors when I save my map?
  • A: This issue is not unique to Damage Engine, but to all vJass resources. Blizzard has taken the very confusing decision to make JassHelper 'disabled' by default, meaning that every new map that uses a vJass resource has to manually enable JassHelper. Please see this thread if you want to know where to find the Enable JassHelper option.
    .
  • Q: How can I detect when a unit gets damaged?
  • A: Create a trigger with the event: "Game - Value of Real Variable <DamageEvent> becomes Equal to 1.00".
    • Use the following custom variables to reference the event responses:
      • DamageEventSource - the unit dealing the damage
      • DamageEventTarget - the unit getting damaged
      • DamageEventAmount - how much damage is being dealt
      • DamageEventAttackT - which attack type was used by DamageEventSource to damage DamageEventTarget
      • DamageEventDamageT - which damage type was used to damage the target (ie. UNIVERSAL for ultimate damage, or NORMAL for damage that gets reduced by armor).
      • DamageEventDefenseT - which defense type does the target unit have (ie. Hero, Fortified, Unarmored).
      • DamageEventArmorT - which armor type does the target unit have (ie. Flesh, Ethereal, Stone).
      • DamageEventPrevAmt - what the value of the damage was before being modified by armor, ethereal/item bonuses or user changes.
        .
  • Q: How do I modify the damage that is dealt to a unit?
  • A: Create a trigger with the event: "Game - Value of Real Variable <PreDamageEvent> becomes Equal to <any value>".
    • You can change the following variables to affect the damage that will be dealt:
      • DamageEventAmount - how much damage will be dealt (before armor reductions)
      • DamageEventAttackT - which attack type will be used by DamageEventSource to damage DamageEventTarget
      • DamageEventDamageT - which damage type will be used to damage the target.
      • DamageEventDefenseT - which defense type should the target unit have during this attack.
      • DamageEventArmorT - which armor type should the target unit have during this attack.
      • DamageEventArmorPierced - how much armor value to ignore when dealing this damage (applies to DAMAGE_TYPE_NORMAL only, otherwise all armor is ignored).
        .

  • Q: How do I deal Pure damage to a unit (bypassing armor/skipping user modification)?
  • A: Use the following actions:
    • Set NextDamageType = DamageTypePure
    • Unit - Cause Source to damage Target for Amount using attack type Spells and damage type Universal
      .

  • Q: How do I protect against recursive damage?
  • A: Damage Engine 5.4 and above is completely recursion-proof, using vJass hooks to detect registered Damage Event triggers.
    .

  • Q: I've been using <insert Damage system here>. Can I use those with Damage Engine?
  • A: Better - Damage Engine has integrated cross-compatibility with all other approved Damage systems and even the major ones from outside of Hiveworkhop.
    .

  • Q: Can I cause an attack to 'Miss' its target?
  • A: Kind of. Ranged attacks will still explode on the target, and on-hit effects will still apply, but you can do the following:
    • Use the event "PreDamageEvent becomes Equal to 1.00"
    • Use the following actions:
      • Set DamageEventAmount = 0.00
      • Set DamageEventArmorT = ARMOR_TYPE_NONE
      • Set DamageEventWeaponT = WEAPON_TYPE_NONE
    • Setting the weapon type and armor type to none like the above will stop any on-hit sounds from playing. When the Peasant attacks in the demo map, this is the trick I'm using. Instead of saying "MISSED!" I have the Floating Text saying "FAIL!" because - again - it's not exactly a "miss".

Thank you to Blizzard for continuing to work on this amazing game to give us awesome new natives that have the best possible control over incoming damage. Damage Engine brings that power to GUI. Also, a very special thank you to @KILLCIDE for getting me motivated to start up the 5.0 project in the first place.

Thank you to the users of this system who have helped me mold this project into the stable, powerful form it is in today!

For versions 3.8 and prior:

Thank you @looking_for_help for finding the spell damage detection method used in Damage Engine 3 - it was the greatest find since the undefend bug.

Thanks to Jesus4Lyf and @Nestharus for building the inspiration that originally led me to create DamageEngine.

Thank you Wietlol and looking_for_help for challenging me on this project to integrate solutions to problems I had not been made aware of, such as the importance of an After-Damage Event.

Thanks to @Spellbound for several crucial bug reports.


Damage Engine Config

Damage Engine vJass

Damage Engine Lua

Changelog


  • Damage Engine Config
    • Events
      • Map initialization
      • Game - DamageModifierEvent becomes Greater than 0.00
      • Game - LethalDamageEvent becomes Less than or equal to 0.00
      • Game - DamageEvent becomes Not equal to 0.00
      • Game - AfterDamageEvent becomes Less than 0.00
      • Game - AOEDamageEvent becomes Greater than or equal to 0.00
      • Game - SourceDamageEvent becomes Equal to 0.00
      • Game - PreDamageEvent becomes Equal to 0.00
      • Game - ArmorDamageEvent becomes Equal to 0.00
      • Game - ZeroDamageEvent becomes Equal to 0.00
    • Conditions
    • Actions
      • -------- You can add extra classifications here if you want to differentiate between your triggered damage --------
      • -------- Use DamageTypeExplosive (or any negative value damage type) if you want a unit killed by that damage to explode --------
      • -------- - --------
      • -------- The pre-defined type Code might be set by Damage Engine if Unit - Damage Target is detected and the user didn't define a type of their own. --------
      • -------- "Pure" is especially important because it overrides both the Damage Engine as well as WarCraft 3 damage modification. --------
      • -------- I therefore gave the user "Explosive Pure" in case one wants to combine the functionality of the two. --------
      • -------- - --------
      • Set VariableSet DamageTypePureExplosive = -2
      • Set VariableSet DamageTypeExplosive = -1
      • Set VariableSet DamageTypeCode = 1
      • Set VariableSet DamageTypePure = 2
      • -------- - --------
      • Set VariableSet DamageTypeHeal = 3
      • Set VariableSet DamageTypeBlocked = 4
      • Set VariableSet DamageTypeReduced = 5
      • -------- - --------
      • Set VariableSet DamageTypeCriticalStrike = 6
      • -------- - --------
      • Custom script: call DamageEngine_DebugStr()

BribeFromTheHive/DamageEngine

Lua 1.0.2.3 - Fixed to match adjustment made in vJass version 5.4.2.3.
Lua 1.0.2.2 - Fixed to match adjustment made in vJass version 5.4.2.2.
Lua 1.0.2.1 - Fixed to match adjustment made in vJass version 5.4.2.1.
Lua 1.0.2.0 - Added support for Lua Fast Triggers ([Lua] Ridiculously Fast Triggers). Fixed an issue where the AfterDamageEvent wasn't always timed the correct way like it was in the JASS verion.
Lua 1.0.1.0 - Fixed encapsulation issue and recursion issue with DamageEngine_inception. Now hooks UnitDamageTarget.
Lua 1.0.0.0 - Release based on Damage Engine 5.4.2.0

5.9.0.0 - Added the following clearer event names to make things less confusing for new users:
  • PreDamageEvent - can be used in place of DamageModifierEvent pre-armor modification
  • ArmorDamageEvent - can be used in place of DamageModifierEvent post-armor modification
  • OnDamageEvent - can be used instead of a non-zero DamageEvent
  • ZeroDamageEvent - can be used instead of a zero damage DamageEvent
  • SourceDamageEvent - runs at the same time as AOEDamageEvent, but doesn't need to hit multiple units.
Added "DamageFilterRunChance" - odds for the trigger to BE run (works inversely to DamageFilterFailChance).
Shortened the Configuration trigger so that it focuses primarily on what the user can modify.
Organized all variables into categories to help users better understand what does what.
Installation or updating from a previous version will require re-copying the entire Damage Engine folder.
Updated the demo map's text tag production to include a new custom update for ArcingTextTag, thanks to @Ugabunda and @Kusanagi Kuro.
Side note - the Demo Map's triggers have been heavily cleaned up and will now no longer cause crashes when being imported into a new map.
5.8.0.0 -
  • Added a new functionality to the AOEDamageEvent, which allows it to fire even when only one unit is hit, if the AOEDamageEvent is registered as "Not Equal" instead of "Equal to". This is useful in a very specific scenario where an AfterDamageEvent may not be able to be relied upon to properly deallocate data from a running instance that needs to be able to function when multiple units are hit, but also needs to not fail when only one unit is hit.
  • Added additional filters for GUI users to avoid using trigger conditions in even more scenarios:
    • DamageFilterSource/TargetI (has item)
    • DamageFilterSource/TargetA (has ability)
    • DamageFilterSource/TargetC (has a certain classification, like hero or Tauren)
    • DamageFilterFailChance - odds for the trigger to not be run (ideal for critical strike or evasion)
  • Provided a way for GUI to un-register a Damage Event by setting "RemoveDamageEvent" to true from within their trigger's actions.
  • Moved the CreateTimer/CreateTrigger/CreateGroup calls that had been included in the globals block down to the onInit block as per request of @Ricola3D
  • Minor performance improvements thanks to @BLOKKADE
5.7.1.2 - Fixed an issue with armor penetration sometimes bugging out.
5.7.1.1 - Fixed an issue with the eventFilter not retaining its value during an AOE event. Fixed an issue with eventFilter when USE_MELEE_RANGE was set to false. Both issues reported by @lolreported
5.7.1.0 -
I have fixed several potential points of failure reported by multiple users that stopped Damage Engine from working for the rest of the game. In any case there should no longer be ANY SITUATION where Damage Engine just "stops working", even in ways I can't predict. The most likely issue was with DamageScalingWC3/User having possible 0-division errors.​
Fixed the "configured" issue reported by @lolreported where manual configuration didn't work unless the damage and attack type checks were initialized tto -1.​
In addition to these fixed bugs, I have added several more static ifs so that advanced users have more control over getting rid of features they might not care about.​

5.7.0.3 - Fixed the issue reported by @KitsuneTailsPrower wherein the DamageInterface extension wasn't working. This needed to be fixed both in the Damage Engine source as well as the DamageInterface plugin itself.
5.7.0.2 - Fixed the issue reported by @Wazzz where the armor reduction wasn't taken into consideration. Actually there was a much bigger flaw that I had overlooked that was prompting this.
5.7.0.1 - Improved the logic of the 0 damage event.
5.7.0.0:

  • Usage of the "DamageEvent becomes EQUAL to 1.00" now can be extrapolated further than ever before:
    • EQUAL works as it always has.
    • NOT EQUAL only runs for code damage.
    • LESS THAN only runs for damage from attacks.
    • LESS THAN OR EQUAL only runs for melee attacks.
    • GREATER THAN OR EQUAL only runs for ranged attacks.
    • GREATER THAN only runs for Spell damage.
  • Fully adapted Damage Engine to work with every other major DDS
  • Rewrote the internal script to use vJass structs: Damage and DamageTrigger.
  • Changed some of the vJass API. You can find the API listed in the Damage Engine trigger. Notably:
    • I removed UnitDamageTargetEx. You can replace this with Damage.apply.
      • The reason for this change is because of cross-compatibility. Rising Dusk's IDDS uses a different set of parameters for this function, so I removed it from my library to allow this to work seamlessly.
    • TriggerRegisterDamageEvent -> TriggerRegisterDamageEngine
    • RegisterDamageEvent -> RegisterDamageEngine
      • The reason for the above two changes is, like for UnitDamageTargetEx, because Rising Dusk's IDDS uses them. I don't want to make the same mistake I did with Table's API and preferred to walk back my API choices before things got out of hand again.
  • Various performance tweaks, bug fixes and re-commenting of variables.
  • Recursive damage is now processed more intelligently and possibly be more performance-friendly.
  • Adapted the cross-compatibility libraries for Weep and LFH's systems to use textmacros to insert themselves into Damage Engine (this might have been in the 5.6 update, but these two updates were both tailored to achieve similar goals).
5.6.2.0 - Fixed a bug with Damage modification and laid groundwork for a bunch of optional vJass compatibility addons.
5.6.1.0 - Patchwork on Melee/Ranged detection, recursion tracking. Also added the ability to modify damage from a DamageEvent to make it easier on beginners.
5.6.0.1 - Fixed an issue where the DamageEventType for recursive damage that used NextDamageType would always default to DamageTypeCode.
5.6.0.0
Rewrote a significant amount of the internal code so that struct and GUI syntax both work - and are synchronized with each other. vJass-exclusive users can disable the GUI synchronization if they don't use any GUI damage events in their maps.​
Four new variables must be added to your variable editor:​
  • boolean NextDamageIsAttack
  • boolean NextDamageIsMelee
  • boolean NextDamageIsRanged
  • integer NextDamageWeaponT
Struct syntax should not need too much introduction - Damage.index is the triggering event ID, and the syntax is Damage.index.amount/source/target/etc. To initialize a JASS damage event, use:​
JASS:
function RegisterDamageEvent takes code c, string eventName, real value returns nothing
The string is simplified: "Modifier", "" (for simple DamageEvent), "After", "Lethal", "AOE"​
Finally, a neat QOL improvement is that I have assigned weight to each of the events. When registering an event, you can include numbers different than 1, 2, 3 or 4 (for modification) or just the plain "1" for the others. Now you can set your own sequencing and use 1.5, 3.14 or even -1 to give an even more extreme priority to something. Lower numbers run first, higher ones last.​
5.5.0.0 - Added support for the new native BlzGetEventIsAttack via "IsDamageAttack". Also updated the Config trigger to make importing a bit easier
5.4.2.3 - Fixed a mis-flag of the IsDamageSpell value when not being actual spell damage.
5.4.2.2 - Actually fixed the Cold Arrows issue (division by 0.00001 or something ...somehow... either way, it is fixed).
5.4.2.1 - A fix which should hopefully quell the recent reports of damage events failing in complex situations involving Cold Arrows.
5.4.2.0 - A ton of fixes to repair the issues plaguing Sunken City and anyone else who might be pushing this engine well beyond what I imagined it would be used for. Also added a couple of variables intended to be used to ricochet damage: CONVERTED_ATTACK_TYPE and CONVERTED_DAMAGE_TYPE. Check the demo map for how they can be used in a Unit - Damage Target action.
5.4.1.0 - The "Inception" update. Advanced users can interact with Damage Engine via custom script to set DamageEvent_inception = true to allow their damage to potentially go recursive (to a fixed extent).
5.4.0.1 - Hotfixed that modifiers 2 and 3 weren't running.
5.4.0.0 - By using an innovative approach of hooking TriggerRegisterVariableEvent, I've permanently eliminated all risks of recursion in the engine.
5.3.0.1 - Fixed unexpected behavior with DamageTypePure when it is affected by Anti-Magic Shell or Mana Shield. DamageTypePure now no longer ignores DamageScalingWC3.
5.3.0.0 - Fixed an issue with AfterDamageEvent sometimes being delayed. Added DamageScalingUser to track the ratio of user modified damage, as well as DamageEventArmorPierced which allows the user to define how much armor to ignore when working with DAMAGE_TYPE_NORMAL.
5.2.0.1 - Fixed an issue where with the final unit in a Spirit Link chain or the retaliating damage of Thorns/Carapace would not deploy an AfterDamageEvent. Also fixed an issue where AfterDamageEvent would still fire from DAMAGE_TYPE_UNKNOWN if it was greater than 0. Simply copy over the JASS from this post in order to update your own implementation.
5.2.0.0

  • Now features DamageEventArmorT and DamageEventDefenseT, which pull from the target unit's Object Editor data in order to allow you more complete access to detect and even MODIFY those defenses. Changes must be made in a DamageModifierEvent, and they are reverted as soon as armor is calculated.
  • Re-introduced AfterDamageEvent, which is the moment after the unit's life is changed, but before any recursive damage has run.

5.1.3.1 - Bug fixes and performance improvements. No, really. Fixed an issue with the DAMAGED event running even though it was turned off (who would've guessed that?)
5.1.3.0 - Engine re-tooling to improve accuracy and get Spirit Link/Defensive damage out of hardcoded mode - it will now work even in circumstances I haven't tested for (in case those weren't the only issues). Also fixed the Is Unit Moving resource.
5.1.2.1 - Fixed an issue with Spiked Carapace and Thorns Aura where the melee attacker would not get recorded correctly. This required the same fix as I needed to apply for the initial target in a spirit link chain.
5.1.2.0 - Tweaked recursion and fixed a few bugs. Re-introduced the zero damage event now that patch 1.31.1 brought it back.
5.1.1.1 - Minor tweak to Spirit Link in rare situation.
5.1.1.0 - Fixed issues related to Spirit Link. Now works intuitively as expected.
5.1.0.0 - Crazy improvements - check out the details in "How to upgrade from Damage Engine 4.0 or earlier" and "How to use Damage Engine 5.1"
5.0.0.0 - Oh man. Where do I even start?
  • You can now set/compare DamageEventDamageT, DamageEventAttackT or DamageEventWeaponT
  • No longer needs Unit Indexer nor any custom Object Editor data nor modifications.
  • Requires WarCraft 3 1.31 or higher.
  • Changed vanilla JASS code to vJass to clean up a lot of things such as making certain variables private.
  • Look for more details in "How to upgrade from Damage Engine 4.0 or earlier"

4.0.0.0 - Never officially released, but was the first iteration which used SetEventDamage.
For 3.8.0.0 and prior, see: Damage Engine 3.8.0.0 | HIVE


Cross-Compatibility:

BribeFromTheHive/DamageEngine

Keywords:unit indexer, damage detection, damage event, weep, nestharus, looking_for_help, EVENT_PLAYER_UNIT_DAMAGED, damage engine, spell, physical, EVENT_PLAYER_UNIT_DAMAGED, attacktype, damagetype, weapontype, armortype, defensetype, BlzSetEventDamage
Previews
Contents

Damage Engine Demo Map (Map)

Lua Damage Engine 2.0.0.0 (Map)

Reviews
23:20, 11th Jan 2015, BPower Criticism: On the one hand Damage Engine offers extremely high utility to every spell, system and map maker independent of the coding style ( GUI, JASS, vJass, .... ) on the other hand it's very easy to import and...
Level 4
Joined
May 14, 2018
Messages
34
You would delete all the JASS from the 3.8 damage engine script and replace it with the vJass of the 3A script. I am pretty sure that the Config trigger does not need to be amended.
Same problem appears even if i replace.

JassHelper says:

1648309447897.png
 
I think you screwed up the formatting somewhere in the description.
Also, I think the reverse of DamageEventFailChance (DamageEventRunChance for example) would be more intuitive for on-damage effects like casting a spell or applying a critical bonus.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
I'd really love some more details on the filters, how to use them and why they are good.
Currently there are fairly minimal amount of information about the new filters, how to use them and how they work.
Thanks for reminding me - this is actually quite difficult to infer based on the variables. Also to the other poster who mentioned the DamageFilterFailChance - this variable exists for someone who had been using a beta version of 5.8 a couple of years ago (can’t remember who though). I agree that it would make sense to include a “chance to succeed” kind of variable, so the next time I update the Config trigger with a release I will include it (in addition to what’s already there, so they would counteract each other if a user were to integrate both).
 
I'd really love some more details on the filters, how to use them and why they are good.
Currently there are fairly minimal amount of information about the new filters, how to use them and how they work.
I think you are supposed to put them on the top part of the Action block.
e.g.:
Code:
Actions
Set DamageFilterSourceA = Storm Bolt
Set DamageFilterSourceI = Scroll of Town Portal
--> The damage event trigger would only run if the damage source has Storm Bolt ability and Scroll of Town Portal item.
However, I don't know what happens if a filter variable is set to multiple different values throughout the trigger actions.
This is probably more useful for GUI users who make many different damage event triggers, than it is useful for someone (like me) who already consolidates multiple actions that depend on one damage event into a single trigger.
Also, because the filter variables must be set in the Action block, using the filter variables in the Conditions block like this:
Code:
Conditions
DamageFilterSourceA equals to Storm Bolt
will not work.
 
Level 3
Joined
Oct 5, 2019
Messages
8
My trigger doesnt seem to work as i thought (the damage tag doesnt display) or because i'm i doing it wrong?.
P/S: I'm using 1.31 WE and Damage Engine v5.8. And the damage engine register is run once my map finished initialization
JASS:
function DamageTag_create takes string value, unit u, real r, real g, real b returns nothing
local texttag tt = CreateTextTagUnitBJ(value, u, 50.0, 14.0, r, g, b, 0.0)
call SetTextTagVelocityBJ(tt, 60.0, 90.0)
call SetTextTagPermanentBJ(tt, false)
call SetTextTagLifespanBJ(tt, 1.5)
call SetTextTagFadepointBJ(tt, 1.4)
endfunction

function GetSpellRed takes integer dtype returns real
if (dtype == 20) then
return 0.0
endif
if (dtype == 21) then
return 255.0
endif
if (dtype == 22) then
return 7.0
endif
if (dtype == 23) then
return 0.0
endif
if (dtype == 24) then
return 173.0
endif
if (dtype == 25) then
return 49.0
endif
if (dtype == 26) then
return 255.0
endif
return 0.0
endfunction

function GetSpellGreen takes integer dtype returns real
if (dtype == 20) then
return 84.0
endif
if (dtype == 21) then
return 0.0
endif
if (dtype == 22) then
return 42.0
endif
if (dtype == 23) then
return 153.0
endif
if (dtype == 24) then
return 216.0
endif
if (dtype == 25) then
return 0.0
endif
if (dtype == 26) then
return 249.0
endif
return 0.0
endfunction

function GetSpellBlue takes integer dtype returns real
if (dtype == 20) then
return 119.0
endif
if (dtype == 21) then
return 0.0
endif
if (dtype == 22) then
return 108.0
endif
if (dtype == 23) then
return 0.0
endif
if (dtype == 24) then
return 230.0
endif
if (dtype == 25) then
return 63.0
endif
if (dtype == 26) then
return 196.0
endif
return 0.0
endfunction

function DamageTag_critTag takes integer amt, unit u, integer dt returns nothing
if (dt == udg_DamageTypeCritA) then
    call DamageTag_create(I2S(amt)+"!", u, 255.0, 56.0,0.0)
elseif (dt == udg_DamageTypeCritB) then
    call DamageTag_create(I2S(amt)+"!!", u, 255.0, 0.0, 0.0)
elseif (dt == udg_DamageTypeCritC)  then
    call DamageTag_create(I2S(amt)+"!!!", u, 255.0, 245.0, 137.0)
endif
endfunction
function DamageTag_actions takes nothing returns nothing
local integer dt = udg_DamageEventType
local integer amt = R2I(udg_DamageEventAmount)
local unit u = udg_DamageEventTarget
local integer elmt = udg_DamageTypeElmType
if (amt == 0 or ODT_damage > 0) then
set amt = R2I(ODT_damage) // used to filter out 0 damage because of elemental damage system
endif
if (udg_IsDamageAttack) then
    call DamageTag_create(I2S(amt), u, 255.0, 215.0, 0.0)
elseif (dt == udg_DamageTypeElement) then
    call DamageTag_create(I2S(amt), u, GetSpellRed(elmt), GetSpellGreen(elmt), GetSpellBlue(elmt))
elseif (dt >= udg_DamageTypeCritA or dt <= udg_DamageTypeCritC) then
    call DamageTag_critTag(amt, u, dt)
elseif (dt == udg_DamageTypeShielded) then
    call DamageTag_create("Shielded "+ I2S(amt), u, 178.0, 255.0, 102.0)
elseif (dt == udg_DamageTypeInvul) then
    call DamageTag_create("Immune", u, 0.0, 0.0, 0.0)
elseif (dt == udg_DamageTypeHeal) then
    call DamageTag_create(I2S(amt), u, 0.0, 255.0, 0.0)
elseif (dt == udg_DamageTypeBlock) then
    call DamageTag_create("Blocked", u, 160.0, 160.0, 160.0)
elseif (dt == udg_DamageTypeEvade) then
    call DamageTag_create("Evaded", u, 153.0, 204.0, 255.0)
else
    call DamageTag_create(R2S(amt), u, 255.0, 255.0, 255.0) // Pure damage should be here
endif
endfunction
JASS:
// This function will fired once map finished initialization
function DamageEngine_register takes nothing returns nothing
call RegisterDamageEngine(function DamageTag_actions, "", 1.0)
endfunction
 
Last edited:
Level 11
Joined
Jul 4, 2016
Messages
627
Needs to be init function for the damage register or you call that function somewhere else

Doesn't the "" have to be the event variable at least from what I read of the function paramters.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Try the below for a fix to your problem. I am not sure what happened to the formatting of your code, but I fixed it?

JASS:
library DamageTag initializer Init requires DamageEngine

function DamageTag_create takes string value, unit u, real r, real g, real b returns nothing
    local texttag tt = CreateTextTagUnitBJ(value, u, 50.0, 14.0, r, g, b, 0.0)
    call SetTextTagVelocityBJ(tt, 60.0, 90.0)
    call SetTextTagPermanentBJ(tt, false)
    call SetTextTagLifespanBJ(tt, 1.5)
    call SetTextTagFadepointBJ(tt, 1.4)
endfunction

function GetSpellRed takes integer dtype returns real
    if (dtype == 20) then
        return 0.0
    elseif (dtype == 21) then
        return 255.0
    elseif (dtype == 22) then
        return 7.0
    elseif (dtype == 23) then
        return 0.0
    elseif (dtype == 24) then
        return 173.0
    elseif (dtype == 25) then
        return 49.0
    elseif (dtype == 26) then
        return 255.0
    endif
    return 0.0
endfunction

function GetSpellGreen takes integer dtype returns real
    if (dtype == 20) then
        return 84.0
    elseif (dtype == 21) then
        return 0.0
    elseif (dtype == 22) then
        return 42.0
    elseif (dtype == 23) then
        return 153.0
    elseif (dtype == 24) then
        return 216.0
    elseif (dtype == 25) then
        return 0.0
    elseif (dtype == 26) then
        return 249.0
    endif
    return 0.0
endfunction

function GetSpellBlue takes integer dtype returns real
    if (dtype == 20) then
        return 119.0
    elseif (dtype == 21) then
        return 0.0
    elseif (dtype == 22) then
        return 108.0
    elseif (dtype == 23) then
        return 0.0
    elseif (dtype == 24) then
        return 230.0
    elseif (dtype == 25) then
        return 63.0
    elseif (dtype == 26) then
        return 196.0
    endif
    return 0.0
endfunction

function DamageTag_critTag takes integer amt, unit u, integer dt returns nothing
    if (dt == udg_DamageTypeCritA) then
        call DamageTag_create(I2S(amt)+"!", u, 255.0, 56.0,0.0)
    elseif (dt == udg_DamageTypeCritB) then
        call DamageTag_create(I2S(amt)+"!!", u, 255.0, 0.0, 0.0)
    elseif (dt == udg_DamageTypeCritC)  then
        call DamageTag_create(I2S(amt)+"!!!", u, 255.0, 245.0, 137.0)
    endif
endfunction

function DamageTag_actions takes nothing returns nothing
    local integer dt = udg_DamageEventType
    local integer amt = R2I(udg_DamageEventAmount)
    local unit u = udg_DamageEventTarget
    local integer elmt = udg_DamageTypeElmType
    if (amt == 0 or ODT_damage > 0) then
        set amt = R2I(ODT_damage) // used to filter out 0 damage because of elemental damage system
    endif
    if (udg_IsDamageAttack) then
        call DamageTag_create(I2S(amt), u, 255.0, 215.0, 0.0)
    elseif (dt == udg_DamageTypeElement) then
        call DamageTag_create(I2S(amt), u, GetSpellRed(elmt), GetSpellGreen(elmt), GetSpellBlue(elmt))
    elseif (dt >= udg_DamageTypeCritA or dt <= udg_DamageTypeCritC) then
        call DamageTag_critTag(amt, u, dt)
    elseif (dt == udg_DamageTypeShielded) then
        call DamageTag_create("Shielded "+ I2S(amt), u, 178.0, 255.0, 102.0)
    elseif (dt == udg_DamageTypeInvul) then
        call DamageTag_create("Immune", u, 0.0, 0.0, 0.0)
    elseif (dt == udg_DamageTypeHeal) then
        call DamageTag_create(I2S(amt), u, 0.0, 255.0, 0.0)
    elseif (dt == udg_DamageTypeBlock) then
        call DamageTag_create("Blocked", u, 160.0, 160.0, 160.0)
    elseif (dt == udg_DamageTypeEvade) then
        call DamageTag_create("Evaded", u, 153.0, 204.0, 255.0)
    else
        call DamageTag_create(R2S(amt), u, 255.0, 255.0, 255.0) // Pure damage should be here
    endif
endfunction

function Init takes nothing returns nothing
    call RegisterDamageEngine(function DamageTag_actions, "", 1.0)
endfunction

endlibrary
[code]
 
Level 3
Joined
Oct 5, 2019
Messages
8
Try the below for a fix to your problem. I am not sure what happened to the formatting of your code, but I fixed it?
Tried but it doesnt work. Is it because of my code?. The engine it self still work fine
I also added a debug message replaced the damage tag function but it doesn't run either
Even though the trigger/code is registered but it doesnt run

Edit: Tried both 5.8 and 3.A, they aren't work for me, but the 3.8 seem work as normal for me.
In both 5.8 and 3.A my trigger/code is registered but they doesn't run when they should be. Seem like vJASS isnt run correctly for me or it something else

Needs to be init function for the damage register or you call that function somewhere else

Doesn't the "" have to be the event variable at least from what I read of the function paramters.
In the Damage Engine doc, it said that i could use "" to reference the "udg_DamageEvent" and "Modifier" or "Mod" to "udg_DamageModifierEvent", etc.
Also just tried as you say but it doesnt seem to work either, the engine it self is fine but my function doesnt really run at all.
JASS:
//The string in the aruments below requires the following API:
//  "" for standard damage event
//  "Modifier(or Mod if you prefer)/After/Lethal/AOE" for the others
static method registerTrigger takes trigger whichTrig, string var, real value returns nothing

//The accepted strings here use the same criteria as DamageTrigger.getIndex/registerTrigger/unregister
function RegisterDamageEngine takes code c, string eventName, real value returns nothing
 
Last edited:
Level 2
Joined
Apr 2, 2019
Messages
11
I am having trouble. I disabled 4 demo triggers (Keeper, Archimond Healing, Elemental Healing, Prevent Lethal).
I added 2 triggers (one trigger spawn 50 mobs on the map, the other spawns a mob when a mob dies).
After killing enough mobs to be hero level 30-70 (seems random timing, i have been level 100+ when it occred) the map experiences sudden extreme frame loss 0fps unplayable, and does not recover.
I tried setting it to remove units from the game when they die, then i experienced sudden extreme frame loss after a couple dozen or so kills (screenshot top left only hero level 7).

I was using this system in another map and when i experienced sudden extreme frame loss i went through and thought it might be the DDS, maybe i deleted something i wasn't supposed to, not sure if it's something I am doing or not doing or what, but then i made this map to isolate things and sure enough it's still happening and only when the DDS is imported.
your help and time is appreciated :)
 

Attachments

  • untitled.png
    untitled.png
    2.4 MB · Views: 14
  • untitled.png
    untitled.png
    33.5 KB · Views: 16
  • untitled 3.w3m
    80.2 KB · Views: 11
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
I am having trouble. I disabled 4 demo triggers (Keeper, Archimond Healing, Elemental Healing, Prevent Lethal).
I added 2 triggers (one trigger spawn 50 mobs on the map, the other spawns a mob when a mob dies).
After killing enough mobs to be hero level 30-70 (seems random timing, i have been level 100+ when it occred) the map experiences sudden extreme frame loss 0fps unplayable, and does not recover.
I tried setting it to remove units from the game when they die, then i experienced sudden extreme frame loss after a couple dozen or so kills (screenshot top left only hero level 7).

I was using this system in another map and when i experienced sudden extreme frame loss i went through and thought it might be the DDS, maybe i deleted something i wasn't supposed to, not sure if it's something I am doing or not doing or what, but then i made this map to isolate things and sure enough it's still happening and only when the DDS is imported.
your help and time is appreciated :)
In your “Neutral Hostile Dies” trigger you have a memory leak. You need to do “set bj_wantDestroyGroup = true” before the if-block.

Tried but it doesnt work. Is it because of my code?. The engine it self still work fine
I also added a debug message replaced the damage tag function but it doesn't run either
Even though the trigger/code is registered but it doesnt run


In the Damage Engine doc, it said that i could use "" to reference the "udg_DamageEvent" and "Modifier" or "Mod" to "udg_DamageModifierEvent", etc.
Also just tried as you say but it doesnt seem to work either, the engine it self is fine but my function doesnt really run at all.
JASS:
//The string in the aruments below requires the following API:
//  "" for standard damage event
//  "Modifier(or Mod if you prefer)/After/Lethal/AOE" for the others
static method registerTrigger takes trigger whichTrig, string var, real value returns nothing

//The accepted strings here use the same criteria as DamageTrigger.getIndex/registerTrigger/unregister
function RegisterDamageEngine takes code c, string eventName, real value returns nothing
I will try to test it tonight (CET).
 
Level 2
Joined
Apr 2, 2019
Messages
11
Thank you Bribe; your solution worked (as I'm sure you knew it would).
Side note, during testing I experienced no crashing when I disabled the triggers "damage engine" and "damage engine config" and ran only the spawning, ran for over an hour before I quit, so I assumed it was the DDS, but obviously I still have much to learn.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
My trigger doesnt seem to work as i thought (the damage tag doesnt display) or because i'm i doing it wrong?.
P/S: I'm using 1.31 WE and Damage Engine v5.8. And the damage engine register is run once my map finished initialization
JASS:
function DamageTag_create takes string value, unit u, real r, real g, real b returns nothing
local texttag tt = CreateTextTagUnitBJ(value, u, 50.0, 14.0, r, g, b, 0.0)
call SetTextTagVelocityBJ(tt, 60.0, 90.0)
call SetTextTagPermanentBJ(tt, false)
call SetTextTagLifespanBJ(tt, 1.5)
call SetTextTagFadepointBJ(tt, 1.4)
endfunction

function GetSpellRed takes integer dtype returns real
if (dtype == 20) then
return 0.0
endif
if (dtype == 21) then
return 255.0
endif
if (dtype == 22) then
return 7.0
endif
if (dtype == 23) then
return 0.0
endif
if (dtype == 24) then
return 173.0
endif
if (dtype == 25) then
return 49.0
endif
if (dtype == 26) then
return 255.0
endif
return 0.0
endfunction

function GetSpellGreen takes integer dtype returns real
if (dtype == 20) then
return 84.0
endif
if (dtype == 21) then
return 0.0
endif
if (dtype == 22) then
return 42.0
endif
if (dtype == 23) then
return 153.0
endif
if (dtype == 24) then
return 216.0
endif
if (dtype == 25) then
return 0.0
endif
if (dtype == 26) then
return 249.0
endif
return 0.0
endfunction

function GetSpellBlue takes integer dtype returns real
if (dtype == 20) then
return 119.0
endif
if (dtype == 21) then
return 0.0
endif
if (dtype == 22) then
return 108.0
endif
if (dtype == 23) then
return 0.0
endif
if (dtype == 24) then
return 230.0
endif
if (dtype == 25) then
return 63.0
endif
if (dtype == 26) then
return 196.0
endif
return 0.0
endfunction

function DamageTag_critTag takes integer amt, unit u, integer dt returns nothing
if (dt == udg_DamageTypeCritA) then
    call DamageTag_create(I2S(amt)+"!", u, 255.0, 56.0,0.0)
elseif (dt == udg_DamageTypeCritB) then
    call DamageTag_create(I2S(amt)+"!!", u, 255.0, 0.0, 0.0)
elseif (dt == udg_DamageTypeCritC)  then
    call DamageTag_create(I2S(amt)+"!!!", u, 255.0, 245.0, 137.0)
endif
endfunction
function DamageTag_actions takes nothing returns nothing
local integer dt = udg_DamageEventType
local integer amt = R2I(udg_DamageEventAmount)
local unit u = udg_DamageEventTarget
local integer elmt = udg_DamageTypeElmType
if (amt == 0 or ODT_damage > 0) then
set amt = R2I(ODT_damage) // used to filter out 0 damage because of elemental damage system
endif
if (udg_IsDamageAttack) then
    call DamageTag_create(I2S(amt), u, 255.0, 215.0, 0.0)
elseif (dt == udg_DamageTypeElement) then
    call DamageTag_create(I2S(amt), u, GetSpellRed(elmt), GetSpellGreen(elmt), GetSpellBlue(elmt))
elseif (dt >= udg_DamageTypeCritA or dt <= udg_DamageTypeCritC) then
    call DamageTag_critTag(amt, u, dt)
elseif (dt == udg_DamageTypeShielded) then
    call DamageTag_create("Shielded "+ I2S(amt), u, 178.0, 255.0, 102.0)
elseif (dt == udg_DamageTypeInvul) then
    call DamageTag_create("Immune", u, 0.0, 0.0, 0.0)
elseif (dt == udg_DamageTypeHeal) then
    call DamageTag_create(I2S(amt), u, 0.0, 255.0, 0.0)
elseif (dt == udg_DamageTypeBlock) then
    call DamageTag_create("Blocked", u, 160.0, 160.0, 160.0)
elseif (dt == udg_DamageTypeEvade) then
    call DamageTag_create("Evaded", u, 153.0, 204.0, 255.0)
else
    call DamageTag_create(R2S(amt), u, 255.0, 255.0, 255.0) // Pure damage should be here
endif
endfunction
JASS:
// This function will fired once map finished initialization
function DamageEngine_register takes nothing returns nothing
call RegisterDamageEngine(function DamageTag_actions, "", 1.0)
endfunction
Sorry, I tried to test this for you, but you have a LOT of undeclared variables here mixed in. I shortened it just to test the fundamentals (e.g. that you are indeed interfacing correctly with Damage Engine) and there were no issues. This is the code I tested with (simply added it to my demo map and then turned off my own demo damage tags):

JASS:
library DamageTag initializer Init requires DamageEngine

function DamageTag_create takes string value, unit u, real r, real g, real b returns nothing
    local texttag tt = CreateTextTagUnitBJ(value, u, 50.0, 14.0, r, g, b, 0.0)
    call SetTextTagVelocityBJ(tt, 60.0, 90.0)
    call SetTextTagPermanentBJ(tt, false)
    call SetTextTagLifespanBJ(tt, 1.5)
    call SetTextTagFadepointBJ(tt, 1.4)
endfunction

function DamageTag_actions takes nothing returns nothing
    call DamageTag_create(R2S(udg_DamageEventAmount), udg_DamageEventTarget, 255.0, 255.0, 255.0) // Pure damage should be here
endfunction

function Init takes nothing returns nothing
    call RegisterDamageEngine(function DamageTag_actions, "", 1.0)
endfunction

endlibrary
 
Level 3
Joined
Oct 5, 2019
Messages
8
Sorry, I tried to test this for you, but you have a LOT of undeclared variables here mixed in. I shortened it just to test the fundamentals (e.g. that you are indeed interfacing correctly with Damage Engine) and there were no issues. This is the code I tested with (simply added it to my demo map and then turned off my own demo damage tags):
Sorry for my late reply, i will send you the map with the my code/trigger, i already commented out the damage tags display and put a bj debug mesasge inside it but it won't run.
Edit: My maps by default run on 1.31
 

Attachments

  • t.w3x
    150 KB · Views: 10
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Sorry for my late reply, i will send you the map with the my code/trigger, i already commented out the damage tags display and put a bj debug mesasge inside it but it won't run.
Thanks, I will try to have another go at it tonight.

Edit: your map is proving to be extremely buggy, and I’ve tried re-copying the Damage Engine folder over but am getting syntax errors. I’ll need more time, but so far it is not making any sense.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
@Bribe
Damage Engine [Lua] is crashing my Wc3, whenever two units hit each other.

I attached an example map for you, which is completely empty apart of Damage Engine and two adjacent footmans.
It crashes a second after map start, as soon as the footmans hit with their attacks.

hey nice system but i have a problem. my hero has multishoot based on vanillia barage and when he attacks it detects his attack with trigger 3 times because he shoots 3 arrows 1 basic one +2 from multishoot. any idea how can i make it so it detects only his main attack? Because then all of my trigger is ruined if it decets his attack 3 times all futher actions dont work propley.


i know about condition ,,is an attack'' that has been aded recently but i cant really use it because when i updated my damage engine my game started to have low fps so i must now take away the new ver of damage engine and test it on old one again to check if it was the reason of low fps.


there are also screenshoots of my problemw ith hero's attack https://cdn.discordapp.com/attachments/311662737015046144/808092454150471680/unknown.png

if its checked 3 times at once then all spells are added too quickly. it should be checked and ran 1 time per heroes attack

Hey! Seems to be having a strange inconsistency issue with this DDS.

I have an ability, based on Envenomed Spears, which deals damage based on the attacking units agility, and removes 1 strength every second that the target is poisened.

  • EnfeeblingPoisonDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Enfeebling Poison (Stacking)) Equal to True
      • DamageEventPrevAmt Equal to 5.00
    • Actions
      • -------- Add to EP_UnitGroup --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DamageEventTarget is in EP_UnitGroup.) Not equal to True
        • Then - Actions
          • Unit Group - Add DamageEventTarget to EP_UnitGroup
          • Hashtable - Save (Ability: (Unit: DamageEventTarget's Ability with Ability Code: Attribute Bonus )'s Integer Level Field Strength Bonus ('Istr'), of Level: 0) as (Key EP_AttributeHandle.) of (Key EP_TempHandle.) in EP_HastTable.
        • Else - Actions
      • -------- - --------
      • -------- Turn on EnfeeblingPoisonTimer --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (EnfeeblingPoisonTimer <gen> is on) Not equal to True
        • Then - Actions
          • Trigger - Turn on EnfeeblingPoisonTimer <gen>
        • Else - Actions
      • -------- - --------
      • -------- Set Damage --------
      • Set VariableSet DamageEventAmount = (Real(((Integer(((Real((Agility of DamageEventSource (Include bonuses)))) / 10.00))) x (Integer(DamageEventPrevAmt)))))
      • -------- - --------
      • -------- Reduce Strength if total Strength greater than 0 --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Strength of DamageEventTarget (Include bonuses)) Greater than 0
        • Then - Actions
          • Ability - Set Ability: (Unit: DamageEventTarget's Ability with Ability Code: Attribute Bonus )'s Integer Level Field: Strength Bonus ('Istr') of Level: 0 to ((Ability: (Unit: DamageEventTarget's Ability with Ability Code: Attribute Bonus )'s Integer Level Field Strength Bonus ('Istr'), of Level: 0) - 1)
          • Unit - Increase level of Attribute Bonus for DamageEventTarget
          • Unit - Decrease level of Attribute Bonus for DamageEventTarget
        • Else - Actions

  • EnfeeblingPoisonTimer
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in EP_UnitGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) has buff Enfeebling Poison (Stacking)) Not equal to True
            • Then - Actions
              • Ability - Set Ability: (Unit: (Picked unit)'s Ability with Ability Code: Attribute Bonus )'s Integer Level Field: Strength Bonus ('Istr') of Level: 0 to (Load (Key EP_AttributeHandle.) of (Key EP_TempHandle.) from EP_HastTable.)
              • Unit - Increase level of Attribute Bonus for (Picked unit)
              • Unit - Decrease level of Attribute Bonus for (Picked unit)
              • Hashtable - Clear all child hashtables of child (Key EP_TempHandle.) in EP_HastTable.
              • Unit Group - Remove (Picked unit) from EP_UnitGroup.
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in EP_UnitGroup) Less than or equal to 0
            • Then - Actions
              • Trigger - Turn off (This trigger)
            • Else - Actions

The problem is that the ability only works with my Blood Mage unit (I was using the Blood Mage initally to test the damage part of the ability). When I add the Ability to other units, the damage and the strength reduction doesn't work.

Wondering what could be the problem!

Would someone know why the following trigger is not being recognized as doing AOE damage?
It picks every unit within 300 AOE and damages them, but Damage Engine does not recognize it being an area damage...

  • Soldier Deal AOE damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.20
    • Conditions
      • DamageEventAttackT Equal to ATTACK_TYPE_NORMAL
      • DamageEventDamageT Equal to DAMAGE_TYPE_NORMAL
      • (Owner of DamageEventSource) Equal to Player 1 (Red)
    • Actions
      • Game - Display to (All players) the text: Soldier is attacking
      • Set VariableSet TempLoc = (Position of DamageEventTarget)
      • Unit Group - Pick every unit in (Units within 300.00 of TempLoc.) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Picked unit) Not equal to DamageEventTarget
            • Then - Actions
              • Unit - Cause DamageEventSource to damage (Picked unit), dealing 100.00 damage of attack type Spells and damage type Magic
            • Else - Actions

  • Soldier isAOE
    • Events
      • Game - AOEDamageEvent becomes Equal to 1.30
    • Conditions
    • Actions
      • Game - Display to (All players) the text: (String(DamageEventAOE))


Here the above trigger within the test map:

I'm quoting these messages from the past couple of years so that I can work on them over the next days/weeks/months/years/decades/millenia. (trying not to make promises that I can't keep)

If I've missed anything from anyone else, it may be because I (incorrectly?) assumed that someone else already answered your question. I will try to care more about the requests people have, because I am INTENDING on:

1. Damage Engine 6 that breaks backwards-compatibility just to clean some shit up (better event names, and fewer default events - PreDamageEvent/OnDamageEvent/AfterDamageEvent/SourceDamageEvent), but would include an add-on to dirty things up again to re-enable backwards-compatibility for things like DamageModifierEvent/DamageEvent/LethalDamageEvent/AOEDamageEvent. I just don't like that I've backed myself into a corner with what variables one can assign to those, and I feel the current names make things a bit too confusing for new users.

2. Update to Lua Damage Engine that works without Lua Fast Triggers, that would incorporate the Filter variables added in newer releases of the vJass Damage Engine. If the user wishes to use Fast Triggers, I'd like to somehow make that work from within the same resource, so that I don't have to support two branches of it.

3. Version 3B that incorporates more of the features of Damage Engine 6 into the more "accessible" WarCraft 3 patches.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
5.9.0.0 - Added the following clearer event names to make things less confusing for new users:
  • PreDamageEvent - can be used in place of DamageModifierEvent pre-armor modification
  • ArmorDamageEvent - can be used in place of DamageModifierEvent post-armor modification
  • OnDamageEvent - can be used instead of a non-zero DamageEvent
  • ZeroDamageEvent - can be used instead of a zero damage DamageEvent
  • SourceDamageEvent - runs at the same time as AOEDamageEvent, but doesn't need to hit multiple units.
Added "DamageFilterRunChance" - odds for the trigger to BE run (works inversely to DamageFilterFailChance).
Shortened the Configuration trigger so that it focuses primarily on what the user can modify.
Organized all variables into categories to help users better understand what does what.
Installation or updating from a previous version will require re-copying the entire Damage Engine folder.
Updated the demo map's text tag production to include a new custom update for ArcingTextTag, thanks to @Ugabunda and @Kusanagi Kuro.
Side note - the Demo Map's triggers have been heavily cleaned up and will now no longer cause crashes when being imported into a new map.

Thanks for the update, seems this is exactly what I needed for my map :peasant-cheers-back:

Edit: If you could maybe add this to your list, would be super glad! Arcing Floating Text 1.0.0.3 (dynamically increase the text size to a specific size when e.g. spell damage is done)
This has now been added, though I changed it even further so that now one has to use ArcingTextTag.createEx in order to achieve it. Setting the size/timescale was looking very weird when I set it after the text tag was created.

Sorry for my late reply, i will send you the map with the my code/trigger, i already commented out the damage tags display and put a bj debug mesasge inside it but it won't run.
Edit: My maps by default run on 1.31
This has been fixed in the latest update. I had to delete ALL GUI variables from your map and re-copy over the Damage Engine category. Your map has some kind of corruption in it that took a long time for me to resolve, but this method works (at least on 1.32). I think, since you have 1.31, that the only thing you'll need to do differently is (once again) copy over the custom BlzGetDamageIsAttack.

I've attached a copy of your map that I just freshly-imported just to make sure it works. I of course had to comment-out your duplicate-declared global variables to avoid the syntax errors, but that was it for me.
 

Attachments

  • t (1).w3x
    147.2 KB · Views: 10
Last edited:
Level 4
Joined
May 18, 2018
Messages
38
I didn't see this mentioned before, and I don't know if this is something you'd want to fix in the library, it might be better if devs made sure to check it in their map, but abilities that deal damage but can't kill still trigger the lethal damage event. So, for example Phoenix Fire's damage per second, Disease Cloud and probably (haven't tested) Envenomed Weapons and other poison abilities too, I don't know if there's any others beside those.
 

Attachments

  • Damage Engine v5.9.0.0 lethal dmg test.w3x
    96.4 KB · Views: 9
So:
Event in 5.9+
Equivalent in 5.8
PreDamageEventDamageModifierEvent 1.00 - 3.99
ArmorDamageEventDamageModifierEvent 4.00
OnDamageEventDamageEvent 1.00 but only runs for DamageEventAmount > 0
ZeroDamageEventDamageEvent 1.00 but only runs for DamageEventAmount = 0
Do I get these correctly? Does PreDamageEvent still allow 1.00 - 3.99 in its syntax to determine the sequence of damage event execution?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
So:
Event in 5.9+
Equivalent in 5.8
PreDamageEventDamageModifierEvent 1.00 - 3.99
ArmorDamageEventDamageModifierEvent 4.00
OnDamageEventDamageEvent 1.00 but only runs for DamageEventAmount > 0
ZeroDamageEventDamageEvent 1.00 but only runs for DamageEventAmount = 0
Do I get these correctly? Does PreDamageEvent still allow 1.00 - 3.99 in its syntax to determine the sequence of damage event execution?
No, you don’t need to change any existing code because the old API will still work with the “classic” event names. You have lined up the events somewhat correctly.

The NEW event names are just alternatives. But they no longer confuse users by requiring a specific variable value.

Just to give you an idea of how confusing they are, you have some errors in your example / incomplete understanding.

The new variable value freedom still represents the order priority of the trigger Event sequence - lowest values run first.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
So for those new event variables (PreDamageEvent, ArmorDamageEvent, OnDamageEvent, ZeroDamageEvent, so on), the symbols (<,>,!=, so on) are still used in the same way as before, but real values for new event variables have complete freedom and smaller values run first.
Yes, exactly. Just that.
 
Level 3
Joined
Oct 5, 2019
Messages
8
This has been fixed in the latest update. I had to delete ALL GUI variables from your map and re-copy over the Damage Engine category. Your map has some kind of corruption in it that took a long time for me to resolve, but this method works (at least on 1.32). I think, since you have 1.31, that the only thing you'll need to do differently is (once again) copy over the custom BlzGetDamageIsAttack.

I've attached a copy of your map that I just freshly-imported just to make sure it works. I of course had to comment-out your duplicate-declared global variables to avoid the syntax errors, but that was it for me.
Thanks you for your hard work. I dont really know why and how it got corrupted, maybe it was my jasshelper compile error or the tesh 2.0 i used
Also i would like to send you a coffe but aint got a visa and dont know how to send it to other people outside of my country yet. So for now, the only i can do is thanks you.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Thanks you for your hard work. I dont really know why and how it got corrupted, maybe it was my jasshelper compile error or the tesh 2.0 i used
Also i would like to send you a coffe but aint got a visa and dont know how to send it to other people outside of my country yet. So for now, the only i can do is thanks you.
No problem- the fact is that it works and helped me to improve the import/export process for everyone.
 
Level 3
Joined
Jan 3, 2019
Messages
25
I think you are supposed to put them on the top part of the Action block.
e.g.:
Code:
Actions
Set DamageFilterSourceA = Storm Bolt
Set DamageFilterSourceI = Scroll of Town Portal
--> The damage event trigger would only run if the damage source has Storm Bolt ability and Scroll of Town Portal item.
However, I don't know what happens if a filter variable is set to multiple different values throughout the trigger actions.
This is probably more useful for GUI users who make many different damage event triggers, than it is useful for someone (like me) who already consolidates multiple actions that depend on one damage event into a single trigger.
Also, because the filter variables must be set in the Action block, using the filter variables in the Conditions block like this:
Code:
Conditions
DamageFilterSourceA equals to Storm Bolt
will not work.
Hello sir!
Can you help me please, why this trigger is not filtering damage?
All damage in the map becomes 200



EDIT
Omg i am an idiot, i thought DAMAGE_TRIIGER_CONFIG is not a big deal lmao
 

Attachments

  • sOe9PG7mmco.jpg
    sOe9PG7mmco.jpg
    24.4 KB · Views: 25
Level 3
Joined
Jan 3, 2019
Messages
25
Hey guys, i have a hard times with LethalDamageEvent.

I am trying to make scaling ability, if ability kills unit - damage of ability grows +2.
Sounds simple. I am giving to my unit BUFF when i cast ability, next attack is empowered, if it kills - variable SoulEaterDamageBonus grows, I am removing buff from my unit.

LethalDamageEvent = 1
If DamageEventSource has buff
SoulEaterDamageBonus = SoulEaterDamageBonus + 2

It is working perfectly!
Untill...

If my ability ONESHOT unit - i get no bonus.
Why?

I know something wrong with damage processing order, but i can't figure out what


P.S
I am genius, this is how i solved it.
1650544835892.png
 
Last edited:
Level 22
Joined
Jun 11, 2017
Messages
641
Hi @Bribe!
Recently (just now) I've add your Lua-based Damage Engine into my RPG map - "Pearl of Azshara". For strange behavior, map began to slowly loading and warcraft became frozen.
I shutted down it and now have a question - does it happens when I work with my map as foulder? Or it doesn't matter? Either matter or not, how I can use Lua-based Damage Engine without slow-frozen map loading on my big rpg map?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hi @Bribe!
Recently (just now) I've add your Lua-based Damage Engine into my RPG map - "Pearl of Azshara". For strange behavior, map began to slowly loading and warcraft became frozen.
I shutted down it and now have a question - does it happens when I work with my map as foulder? Or it doesn't matter? Either matter or not, how I can use Lua-based Damage Engine without slow-frozen map loading on my big rpg map?
I am not sure what could be causing that, but I can fill you in that I have been hard at work on developing the Lua framework that will be going into the next Lua Damage Engine, so in 1-2 weeks this problem may be resolved by updating to v2.0.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hello guys, i have a question, is it possible to modify floating text parameters of damage engine? Can't find where(
In the folder "Text Tags" there is a trigger called "Damage Tag" where you can edit these things. Be sure to copy the Arcing Text Tag trigger, too, if you intend to bring that into a new map.
 
Level 4
Joined
Apr 22, 2022
Messages
31
Hey @Bribe ! New account on the forums but I have been a lurker for awhile using various assets and systems throughout HIVE including your Damage Engine. I love the system and have been using 5.7.1.2 for awhile, but just today decided to put in some work and make the upgrade to 5.9 and I also decided to implement the text tag system and have been loving it! Although I am having an issue getting +heals to show any text tags from custom spells based off of chain heal, holy light, or the regeneration of rejuvenation/inner fire. I did not change the heal portion of the trigger other than removing duration change, adjusting size and changing color, I copied from the Damage Engine v5.9 map so I am not sure what the issue is. (Also couldn't get heal tags to show with the 5.7.1.2 Damage Tag trigger.) Perhaps it isn't detecting the heal as any type or amount of damage? Any help would be greatly appreciated!
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • DamageEventAmount Less than -0.99
    • Then - Actions
      • Set VariableSet DmgSize = 1.00
      • Set VariableSet DmgStr = (|cff8cff05+ + ((String((Integer((0.00 - DamageEventAmount))))) + |r))
    • Else - Actions
Thanks a ton and keep up the amazing work!!
 
Last edited:
Hey @Bribe ! New account on the forums but I have been a lurker for awhile using various assets and systems throughout HIVE including your Damage Engine. I love the system and have been using 5.7.1.2 for awhile, but just today decided to put in some work and make the upgrade to 5.9 and I also decided to implement the text tag system and have been loving it! Although I am having an issue getting +heals to show any text tags from custom spells based off of chain heal, holy light, or the regeneration of rejuvenation/inner fire. I did not change the heal portion of the trigger other than removing duration change, adjusting size and changing color, I copied from the Damage Engine v5.9 map so I am not sure what the issue is. (Also couldn't get heal tags to show with the 5.7.1.2 Damage Tag trigger.) Perhaps it isn't detecting the heal as any type or amount of damage? Any help would be greatly appreciated!
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • DamageEventAmount Less than -0.99
    • Then - Actions
      • Set VariableSet DmgSize = 1.00
      • Set VariableSet DmgStr = (|cff8cff05+ + ((String((Integer((0.00 - DamageEventAmount))))) + |r))
    • Else - Actions
Thanks a ton and keep up the amazing work!!
You haven't had the action (Custom Script) that displays the text tag. See the sample text tag trigger to know how it works.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hey @Bribe ! New account on the forums but I have been a lurker for awhile using various assets and systems throughout HIVE including your Damage Engine. I love the system and have been using 5.7.1.2 for awhile, but just today decided to put in some work and make the upgrade to 5.9 and I also decided to implement the text tag system and have been loving it! Although I am having an issue getting +heals to show any text tags from custom spells based off of chain heal, holy light, or the regeneration of rejuvenation/inner fire. I did not change the heal portion of the trigger other than removing duration change, adjusting size and changing color, I copied from the Damage Engine v5.9 map so I am not sure what the issue is. (Also couldn't get heal tags to show with the 5.7.1.2 Damage Tag trigger.) Perhaps it isn't detecting the heal as any type or amount of damage? Any help would be greatly appreciated!
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • DamageEventAmount Less than -0.99
    • Then - Actions
      • Set VariableSet DmgSize = 1.00
      • Set VariableSet DmgStr = (|cff8cff05+ + ((String((Integer((0.00 - DamageEventAmount))))) + |r))
    • Else - Actions
Thanks a ton and keep up the amazing work!!
You'll need to use Heal Event for GUI, version 1.1.1.1 for detecting heals from non-damaging spells such as Healing Wave, Holy Light, Healing Spray, etc.
 
Level 4
Joined
Apr 22, 2022
Messages
31
@Spacebuns I have the custom script action to display the text at the bottom of the trigger just like in the trigger from the download map. I just showed the heal portion of the trigger, was unaware I also needed the Heal Event system. Thanks for the responses!

EDIT: @Bribe I'll quote one of your heal event posts "I could also add a Max-life variable and factor in max life gain with any heading gain to see if there's any difference. If not, it's not a heal." How would I go about adding this in? My map has a lot of triggers and items that increase a unit's max life or strength and I do not want that to show as +healing.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
@Spacebuns I have the custom script action to display the text at the bottom of the trigger just like in the trigger from the download map. I just showed the heal portion of the trigger, was unaware I also needed the Heal Event system. Thanks for the responses!

EDIT: @Bribe I'll quote one of your heal event posts "I could also add a Max-life variable and factor in max life gain with any heading gain to see if there's any difference. If not, it's not a heal." How would I go about adding this in? My map has a lot of triggers and items that increase a unit's max life or strength and I do not want that to show as +healing.
Please remind me in a few weeks; I should be done with the systems I am working on by then (Lua Damage Engine 2.0, then Lua Spell System, then Lua Unit Event).
 
Level 4
Joined
Apr 22, 2022
Messages
31
Hey Bribe, I have an issue since I updated from 5.7.1.2. You had made an addition in 5.8: "Added a new functionality to the AOEDamageEvent, which allows it to fire even when only one unit is hit, if the AOEDamageEvent is registered as "Not Equal" instead of "Equal to". This is useful in a very specific scenario where an AfterDamageEvent may not be able to be relied upon to properly deallocate data from a running instance that needs to be able to function when multiple units are hit, but also needs to not fail when only one unit is hit."

I believe my issue stems from this upgrade. My units have an attack type of Missile(Splash) and I have triggers to detect when a unit attacks/deals damage to do an effect to the damage target or source. I have a condition that reads "DamageEventAOE Equal to 0" to make the trigger only run when the primary damage was detected on the attacked target, and not from the splash damage. Now since I am on 5.9 these triggers do not seem to run anymore. Was wondering what I should change so it detects attack damage on the primary target from Missile(Splash), but ignores AOE or splash damage on other targets. Thanks again!
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hey Bribe, I have an issue since I updated from 5.7.1.2. You had made an addition in 5.8: "Added a new functionality to the AOEDamageEvent, which allows it to fire even when only one unit is hit, if the AOEDamageEvent is registered as "Not Equal" instead of "Equal to". This is useful in a very specific scenario where an AfterDamageEvent may not be able to be relied upon to properly deallocate data from a running instance that needs to be able to function when multiple units are hit, but also needs to not fail when only one unit is hit."

I believe my issue stems from this upgrade. My units have an attack type of Missile(Splash) and I have triggers to detect when a unit attacks/deals damage to do an effect to the damage target or source. I have a condition that reads "DamageEventAOE Equal to 0" to make the trigger only run when the primary damage was detected on the attacked target, and not from the splash damage. Now since I am on 5.9 these triggers do not seem to run anymore. Was wondering what I should change so it detects attack damage on the primary target from Missile(Splash), but ignores AOE or splash damage on other targets. Thanks again!
You would not use DamageEventAOE for this; but just as a tip AOE starts at 1 not 0.

You’d just check if DamageEventTarget is Equal to EnhancedDamageTarget and use any damage event to do your thing (doesn’t have to be the AOE one).
 
Level 4
Joined
Apr 22, 2022
Messages
31
Thanks!! That seemed to have fixed it, I didn't know about the EnhancedDamageTarget variable, is that just a reference to the targeted unit of an attack? Or does it also have reference if you deal Enhanced (Fan of Knives for example) damage type to a target? Also I am using the event "DamageEvent equal to 1.00". I was just checking for DamageEventAOE equal to 0 so it would only run for the target of the attack, not the nearby units taking splash / AOE damage which it worked perfectly back in 5.7.1.2. Glad it was an easy fix for my error. I am really appreciative of your systems and responses!
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hello guys.
What is DmgDuration, DmgSize and DmgStr?

Is there a list of all variables with description?
The text tags are only a part of the demo code, rather than part of Damage Engine itself. Those variables in particular correlate with ArcingTextTag, written by Maker and featured in the map.
 
Level 1
Joined
Apr 29, 2022
Messages
2
Hey Bribe, I have 3 probably really simple questions that might have been asked hundreds of times already lol.
Is it recommended to filter with the damage engine filters rather than conditions in the function, or is there virtually no difference at all?
e.g. using
JASS:
private function damageCheck takes nothing returns boolean
    // do stuff
    return false
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterDamageEngine(t, "Pre", 1.00)
    set DamageTrigger.lastRegistered.sourceClass = udg_UNIT_CLASS_HERO
    set DamageTrigger.lastRegistered.targetClass = udg_UNIT_CLASS_HERO
    set DamageTrigger.lastRegistered.configured = true
    call TriggerAddCondition(t, Condition(function damageCheck))
endfunction
as opposed to

JASS:
private function damageCheck takes nothing returns boolean
    if IsUnitType(Damage.target) == UNIT_TYPE_HERO and IsUnitType(Damage.source) == UNIT_TYPE_HERO then
        // do stuff
    endif
    return false
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterDamageEngine(t, "Pre", 1.00)
    call TriggerAddCondition(t, Condition(function damageCheck))
endfunction

Same with multiple triggers vs one large trigger, is there a recommendation or does it not matter in the slightest? I plan on having multiple triggers either way, but I also plan to stack them in groups. So for example:

JASS:
private function damageCheck takes nothing returns boolean
    if IsUnitType(Damage.target) == UNIT_TYPE_HERO and IsUnitType(Damage.source) == UNIT_TYPE_HERO then
        if GetUnitAbilityLevel(Damage.source, BUFF_A) > 0 then
            // do stuff
        endif
        if GetUnitAbilityLevel(Damage.source, BUFF_B) > 0 then
            // do different stuff
        endif
        // probably a lot more of those
    endif
    return false
endfunction

vs. a separate trigger for each check. Lastly, Damage.source/Damage.target/Damage.amount has returned the correct stuff so far for my basic triggers (ex. damage increase/reduce). Is it recommended to swap to Damage.index.source and etc, or I guess what is the usefulness of those indexed variables? Sorry for the basic question + for the long code blocks, I'm new to this so I didn't want to get misinterpreted.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Updated to Lua version 2.0 (for those who only use vJass, this update should not be applied to your map).

This is a complete re-write of Lua Damage Engine. Version 2.0 integrates the brand-new "Global Variable Remapper" which is able to completely empower GUI users by allowing normal variables to be treated as functions. Nearly all "udg_" syntax has been removed from the code, and it may even be posible to run this engine successfully with no GUI variable support (which would be the first time ever that it's been possible with Damage Engine).
  • Update requires re-copying the Damage Engine category (or just the Lua script if no GUI variables are needed).
  • "Lua Fast Triggers" no longer required, but several new libraries are (e.g. Global Variable Remapper).
  • The demo map is unfinished, but there is a polished Lua UnitIndexer (mostly for show, as nothing is using it) that uses Global Variable Remapper as well.
  • There is a refined version of Lua ArcingTextTag in the map now, rather than the old one that was poorly-hacked into existence.
I'd like to add that, since I needed to create so many libraries to support the underlying mechanics that went into Damage Engine, that this will dramatically reduce the amount of development time I'll need to release the next Lua projects of mine:

Lua Unit Event (estimated time: 3 days from now)
Lua Heal Event (estimated time: 4 days from now)
Lua Spell System (estimated time: 1-2 weeks from now)
 
Level 12
Joined
May 7, 2008
Messages
330
Updated to Lua version 2.0 (for those who only use vJass, this update should not be applied to your map).

This is a complete re-write of Lua Damage Engine. Version 2.0 integrates the brand-new "Global Variable Remapper" which is able to completely empower GUI users by allowing normal variables to be treated as functions. Nearly all "udg_" syntax has been removed from the code, and it may even be posible to run this engine successfully with no GUI variable support (which would be the first time ever that it's been possible with Damage Engine).
  • Update requires re-copying the Damage Engine category (or just the Lua script if no GUI variables are needed).
  • "Lua Fast Triggers" no longer required, but several new libraries are (e.g. Global Variable Remapper).
  • The demo map is unfinished, but there is a polished Lua UnitIndexer (mostly for show, as nothing is using it) that uses Global Variable Remapper as well.
  • There is a refined version of Lua ArcingTextTag in the map now, rather than the old one that was poorly-hacked into existence.
I'd like to add that, since I needed to create so many libraries to support the underlying mechanics that went into Damage Engine, that this will dramatically reduce the amount of development time I'll need to release the next Lua projects of mine:

Lua Unit Event (estimated time: 3 days from now)
Lua Heal Event (estimated time: 4 days from now)
Lua Spell System (estimated time: 1-2 weeks from now)

Great work!

Speaking of Heal Event, is it possible somehow to detect the source of the heal?

Example:

Owner of Heal_Source equal to User?

That would be an awesome addition if it's possible!
 
Level 3
Joined
Jan 3, 2019
Messages
25
Hello guys, sorry if someone already asked.
Is it possible to check if damage dealt from specific ability?

DamageEventFIlterA cheks only if unit HAS ability
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
Hello guys, sorry if someone already asked.
Is it possible to check if damage dealt from specific ability?

DamageEventFIlterA cheks only if unit HAS ability

You can use REPO in progress - mapping damage types to their abilities to narrow down the damage to a smaller group of damaging abilities based on their damage types. It won't differentiate between cloned abilities (e.g. if you have two different Flame Strikes in your map) but could help you speculate the ability if you are expecting ability A, ability B or ability C and each has their own unique damage type.

For example, the Demon Hunter has 2 damaging abilities: Mana Burn and Immolation. If the damage source is a Demon Hunter and the damage type is MAGIC, then it came from Mana Burn. IF the damage type is FIRE, it came from Immolation.
 
Top