• 🏆 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 3
Joined
Aug 29, 2007
Messages
28
The event should work as long as the registered variable it exists. If the variable doesn't exist, the map won't load.

If the variable does not exist, the map should not even compile.

I can do some tests, but all i did was load my map with the new editor, if i disable damage engine, it works fine, if i enable it, the map doesn't even load in-game. It compiles fine, it just doesn't load in game.
 
Level 2
Joined
Nov 9, 2019
Messages
9
Hello everyone,
I've decided to come back to Warcraft III after not having touched it for pretty much a decade now. I'm trying to make a map and I've felt like this engine would be just what I needed to make some interesting abilities. However I'm having a problem importing the triggers into the map, the code won't compile. I get an odd error about there being too many nested ifs (max is 50). This is strange because very clearly, the if are not nested. It's as if the end are completely ignored or something. The map simply won't save unless I deactivate every single triggers. Additionally, there are some oddities I've noticed with the map uploaded here, the first of which is that there is no way to deactivate JassHelper (I can if I make another map). I'm wondering if I'm not missing something that's really obvious. I'm running on 1.31b (is this an issue? should it be just 1.31?)

Edit: Also, if I remove the demo triggers from the original map and run it it crashes on the first damage received. I'm bewildered right now.

Second edit: The non LUA version works very well for what I need. I'm good to go on my end but if you need more information I'll provide them.

Third edit: I think I found the problem, the script language is set to LUA on your map, but it's set to JASS when I create new ones. The dropdown is readonly, can't change it.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
If the variable does not exist, the map should not even compile.

I can do some tests, but all i did was load my map with the new editor, if i disable damage engine, it works fine, if i enable it, the map doesn't even load in-game. It compiles fine, it just doesn't load in game.
Runtime string error vs compile time syntax error.

I still don't see how this could be the case, as the variables exist for all registered events.

Especially weird that disabling damage engine - not the triggers which host the events - fixes the problem.
 
Level 3
Joined
Aug 29, 2007
Messages
28
Runtime string error vs compile time syntax error.

I still don't see how this could be the case, as the variables exist for all registered events.

Especially weird that disabling damage engine - not the triggers which host the events - fixes the problem.

This is the line that causes the issue, it's at the very end of the Library. If we comment it out, the map loads.
Code:
hook TriggerRegisterVariableEvent PreSetup
 
Today while testing this trigger:
Code:
function Trig_Black_shield_passive_Conditions takes nothing returns boolean
    return UnitHasItemOfTypeBJ(udg_DamageEventTarget, 'Iyc6') and IsUnitEnemy(udg_DamageEventSource,GetOwningPlayer(udg_DamageEventTarget)) and (udg_IsDamageMelee or udg_IsDamageRanged)
endfunction

function Trig_Black_shield_passive_Actions takes nothing returns nothing
    local integer d3 = GetRandomInt(1,3)
    if d3==3 then
    set bj_lastCreatedEffect=AddSpecialEffectTarget("Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl",udg_DamageEventSource,"head")
    call BlzPlaySpecialEffect( GetLastCreatedEffectBJ(), ANIM_TYPE_DEATH )
    call DestroyEffectBJ( GetLastCreatedEffectBJ() )
    call UnitDamageTargetBJ( udg_DamageEventTarget, udg_DamageEventSource, I2R(( BlzGetUnitBaseDamage(udg_DamageEventTarget, 0) + ( BlzGetUnitDiceNumber(udg_DamageEventTarget, 0) * GetRandomInt(1, BlzGetUnitDiceSides(udg_DamageEventTarget, 0)) ) )), ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL )
    endif
endfunction

//===========================================================================
function InitTrig_Black_shield_passive takes nothing returns nothing
    set gg_trg_Black_shield_passive = CreateTrigger(  )
    call TriggerRegisterVariableEvent( gg_trg_Black_shield_passive, "udg_AfterDamageEvent", EQUAL, 1.00 )
    call TriggerAddCondition( gg_trg_Black_shield_passive, Condition( function Trig_Black_shield_passive_Conditions ) )
    call TriggerAddAction( gg_trg_Black_shield_passive, function Trig_Black_shield_passive_Actions )
endfunction
I found that damage done via this UnitDamageTargetBJ function can return IsDamageMelee or IsDamageRanged (depending on the type of the DamageEventTarget). Maybe you should look into it since only damage from attacks should return IsDamageMelee/Ranged?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
I had put a "set udg_NextDamageType = udg_DamageType..." line before UnitDamageTargetBJ, but it still returns IsDamageMelee/IsDamageRanged (I tested this on a unit that has an ability that always triggers when IsDamageMelee==true)

Hmm. It sounds like you're using it for the wrong reason. The first thing you want to look out for is to make sure the damage isn't a spell. You can also check the attack type via DamageEventAttackT. Otherwise it is determined by other factors. What are you trying to do?
 
Hmm. It sounds like you're using it for the wrong reason. The first thing you want to look out for is to make sure the damage isn't a spell. You can also check the attack type via DamageEventAttackT. Otherwise it is determined by other factors. What are you trying to do?
I'm trying to make an item that gives the wearer a % chance to physically damage an enemy attacker.
This goes on well until I put that item on a Hero that has a "deals extra damage upon hitting an enemy with attack damage" passive. Then I find that the Damage Event resulted from the damage caused by the armor will cause that passive to trigger as well, even though the Hero is standing still. Of course, when the damage caused by the armor doesn't fit the profile of a physical attack's damage, then the passive won't fire since it checks for udg_IsDamageMelee or udg_IsDamageRanged.
I've included a test map in this post.
  • Paladin passive damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (Level of Devotion Aura for DamageEventSource) Greater than 0
      • (IsDamageMelee Equal to True) or (IsDamageRanged Equal to True)
    • Actions
      • Custom script: call BJDebugMsg("The passive has triggered.")
  • Sobi mask passive
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has an item of type Sobi Mask) Equal to True
      • (IsDamageMelee Equal to True) or (IsDamageRanged Equal to True)
    • Actions
      • Unit - Cause DamageEventTarget to damage DamageEventSource, dealing 20.00 damage of attack type Hero and damage type Normal
 

Attachments

  • Testmap 1 - damage event.w3x
    39.9 KB · Views: 29
Last edited:
Sure, that will fix it, but I don't think that addresses the original issue of being able to return IsDamageMelee or IsDamageRanged when the damage event doesn't come from an attack.
Anyway, I just had to bring this up because you basically replied "udg_IsDamageMelee is true when physical damage comes from a melee attack" in post #1079, and I assume this would be apply for udg_IsDamageRanged as well, when after testing it becomes apparent that they are actually true when physical damage comes from a melee/ranged unit.
 
Level 5
Joined
Feb 13, 2019
Messages
128
Can someone help me o_O

I was upgrading from 3.8

Deleted and copied the folder over

and this trigger doesn't seem to work anymore o_O


  • Scale Firebolt test
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to True
    • Actions
      • Set AttackingUnit = DamageEventSource
      • Set AttackedUnit = DamageEventTarget
      • Set HeroINT[1] = (Intelligence of AttackingUnit (Include bonuses))
      • Set HeroIntReal[1] = (Real(HeroINT[1]))
      • Set DamageEventAmount = (DamageEventAmount + HeroIntReal[1])
 
Level 3
Joined
Aug 15, 2014
Messages
24
I really don't understand what I'm doing wrong here...
I do as it says; Copy/paste the damage engine category.

As I'm saving the map, the following errors happen:

With the "regular" version, I get a hole wall of errors on pretty much every custom script.
With the LUA, it says "to many nested ifs (max is 50)".

The map I'm using has next to nothing on it.
I'm using World Editor 1.31b (no modifications etc).
I've activated to create unknown variables bla bla bla.
I allow negative values, if that has anything to do with it...

Any help would be nice!
(I'm most likely just stupid, been a while since I played with these things)
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Sure, that will fix it, but I don't think that addresses the original issue of being able to return IsDamageMelee or IsDamageRanged when the damage event doesn't come from an attack.
Anyway, I just had to bring this up because you basically replied "udg_IsDamageMelee is true when physical damage comes from a melee attack" in post #1079, and I assume this would be apply for udg_IsDamageRanged as well, when after testing it becomes apparent that they are actually true when physical damage comes from a melee/ranged unit.
The type of damage you deal is indistinguishable from a normal attack because of the attack type and damage type you use.

If you had the Lua version, you wouldn't run into this error.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Can someone help me o_O

I was upgrading from 3.8

Deleted and copied the folder over

and this trigger doesn't seem to work anymore o_O


  • Scale Firebolt test
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to True
    • Actions
      • Set AttackingUnit = DamageEventSource
      • Set AttackedUnit = DamageEventTarget
      • Set HeroINT[1] = (Intelligence of AttackingUnit (Include bonuses))
      • Set HeroIntReal[1] = (Real(HeroINT[1]))
      • Set DamageEventAmount = (DamageEventAmount + HeroIntReal[1])

Your event needs to be DamageModifierEvent rather than DamageEvent.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
I really don't understand what I'm doing wrong here...
I do as it says; Copy/paste the damage engine category.

As I'm saving the map, the following errors happen:

With the "regular" version, I get a hole wall of errors on pretty much every custom script.
With the LUA, it says "to many nested ifs (max is 50)".

The map I'm using has next to nothing on it.
I'm using World Editor 1.31b (no modifications etc).
I've activated to create unknown variables bla bla bla.
I allow negative values, if that has anything to do with it...

Any help would be nice!
(I'm most likely just stupid, been a while since I played with these things)
I have no idea what could be causing this one. My guess is your map is predisposed to JASS, which is why you get the Lua error. But then why would it fail with JASS? I'll need more info about your map.
 
Level 3
Joined
Aug 15, 2014
Messages
24
I have no idea what could be causing this one. My guess is your map is predisposed to JASS, which is why you get the Lua error. But then why would it fail with JASS? I'll need more info about your map.

Funny thing, I made a new map, without anything. Copied the folder and tried to save. Still a lot of errors! :D
Usually, I can manage because the errors are pretty straight forward, but all the errors are "unknown".
 
Level 4
Joined
Sep 25, 2018
Messages
81
I have a custom single targeted spell, based on Acid Bomb, which does damage multiplied by intelligence called "Fireball". I am trying to make it so that my Fireball spell does fire damage to the target. The triggers to deal the damage are working fine.

  • FireballDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Fireball (Dummy Buff)) Equal to True
    • Actions
      • Set DamageEventAmount = (80.00 + ((10.00 x (Real((Level of Fireball for DamageEventSource)))) + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 1.40)))
      • Set DamageEventAttackT = ATTACK_TYPE_SPELLS
      • Set DamageEventDamageT = DAMAGE_TYPE_FIRE
      • Unit - Remove Fireball (Dummy Buff) buff from DamageEventTarget
The problem I am having is I'd like to make Undead units weak to fire (increase fire damage by 20% against Undead). I have been testing the fire damage amp by using Flame Strike on Undead targets, and its amplifies Flame Strike by 20%. But I can't seem to get it to amplify my Fireball spell's damage by 20%.


  • Set Damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • True Equal to True
    • Actions
      • Game - Display to (All players) the text: (String((Mana of DamageEventTarget)))
      • Custom script: DamageEngine_inception = true
      • Unit - Cause DamageEventTarget to damage DamageEventSource, dealing DamageEventAmount damage of attack type CONVERTED_ATTACK_TYPE[DamageEventAttackT] and damage type CONVERTED_DAMAGE_TYPE[DamageEventDamageT]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IsDamageSpell Equal to True
          • (DamageEventTarget is Undead) Equal to True
          • DamageEventDamageT Equal to DAMAGE_TYPE_FIRE
        • Then - Actions
          • Set DamageEventAmount = (DamageEventPrevAmt x 1.20)
        • Else - Actions
I am still using the draft trigger from the download, I am currently just trying out what is possible with the DDS. Please help :)
 
Last edited:
Level 5
Joined
Feb 13, 2019
Messages
128
I have a custom single targeted spell, based on Acid Bomb, which does damage multiplied by intelligence called "Fireball". I am trying to make it so that my Fireball spell does fire damage to the target. The triggers to deal the damage are working fine.

JavaScript:
FireballDamage
    Events
        Game - DamageModifierEvent becomes Equal to 1.00
    Conditions
        (DamageEventTarget has buff Fireball (Dummy Buff)) Equal to True
    Actions
        Set DamageEventAmount = ((20.00 x (Real((Level of Fireball  for DamageEventSource)))) + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 2.00))
        Set DamageEventAttackT = ATTACK_TYPE_SPELLS
        Set DamageEventDamageT = DAMAGE_TYPE_FIRE
        Unit - Remove Fireball (Dummy Buff) buff from DamageEventTarget

The problem I am having is I'd like to make Undead units weak to fire (increase fire damage by 20% against Undead). I have been testing the fire damage amp by using Flame Strike on Undead targets, and its amplifies Flame Strike by 20%. But I can't seem to get it to amplify my Fireball spell's damage by 20%.


JavaScript:
Set Damage
    Events
        Game - DamageModifierEvent becomes Equal to 1.00
    Conditions
        True Equal to True
    Actions
        Game - Display to (All players) the text: (String((Mana of DamageEventTarget)))
        Custom script:   DamageEngine_inception = true
        Unit - Cause DamageEventTarget to damage DamageEventSource, dealing DamageEventAmount damage of attack type CONVERTED_ATTACK_TYPE[DamageEventAttackT] and damage type CONVERTED_DAMAGE_TYPE[DamageEventDamageT]
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                IsDamageSpell Equal to True
                (DamageEventTarget is Undead) Equal to True
                DamageEventDamageT Equal to DAMAGE_TYPE_FIRE
            Then - Actions
                Set DamageEventAmount = (DamageEventPrevAmt x 1.20)
            Else - Actions

I am still using the draft trigger from the download, I am currently just trying out what is possible with the DDS. Please help :)



I’m just curious because I’m actually doing something similar have you found a way to set the scaling of damage for spells to work in separate instances?

I’d like war stomps damage to scale off STR, and have more magical skills scale off INT, and some off DEX.


EDIT: Oh it looks like you’re using dummy buffs, I was thinking about that but was hoping for an easier work around.

I need to just learn to trigger and make custom spells. :/
 
Level 4
Joined
Sep 25, 2018
Messages
81
I’m just curious because I’m actually doing something similar have you found a way to set the scaling of damage for spells to work in separate instances?

I’d like war stomps damage to scale off STR, and have more magical skills scale off INT, and some off DEX.


EDIT: Oh it looks like you’re using dummy buffs, I was thinking about that but was hoping for an easier work around.

I need to just learn to trigger and make custom spells. :/

I found what the problem was, I needed to trigger the damage normally using the Unit - Damage Target Action. Actually quite a simple solution, and is working for my different magic types. (I have lightning magic which gets amplified by the amount of armour the target has).

My new issue is that the damage tags are not showing the correct amount of damage. My level 4 Fireball spell will do 260 damage (Intelligence 100) and will successfully damage the target for that amount. It will even damage for 312 for Undead units. The strange thing is, the damage tag keeps showing 259 for the damage (and 311 for the damage against Undead units). Its very strange!

  • FireballDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventTarget has buff Fireball (Dummy Buff)) Equal to True
    • Actions
      • Set DamageEventAmount = 0.00
      • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (80.00 + ((10.00 x (Real((Level of Fireball for DamageEventSource)))) + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 1.40))) damage of attack type Spells and damage type Fire
      • Unit - Remove Fireball (Dummy Buff) buff from DamageEventTarget
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Hi @rkemsley , you may need to add 0.01 to the damage tag before converting to integer in order for the truncation to display correctly. I think i should update this in the demo map.

To those who hve previously reported unresolved issues, I don't plan to have any of it figured out before next month. Let's wait for Reforged to drop (hopefully with new natives) and then go from there to see what I should do about all this.
 
Level 4
Joined
Sep 25, 2018
Messages
81
@Bribe
Hi @rkemsley , you may need to add 0.01 to the damage tag before converting to integer in order for the truncation to display correctly.

In the Damage Tag trigger function, I can't seem to find the part where is converts display to an integer. (First time using your system, so its a little overwhelming).
 
Level 24
Joined
Feb 9, 2009
Messages
1,783
I’m just curious because I’m actually doing something similar have you found a way to set the scaling of damage for spells to work in separate instances?

I’d like war stomps damage to scale off STR, and have more magical skills scale off INT, and some off DEX.


EDIT: Oh it looks like you’re using dummy buffs, I was thinking about that but was hoping for an easier work around.

I need to just learn to trigger and make custom spells. :/

There is an ability trigger to set the "real" field of a select ability, you need only ensure the field matches the damage on the ability, I.e. Damage field on Fireball versus Fan of Knives might be completely different!
Once I've finished meddling with my graphics card I'll post a pic, it's super easy peasy.
Also I've posted a stress test for the "detect" buff style of spell damage detection to show the inaccuracies, you can find and try the test map here: Damage Engine 5.4.2.3

Heres 3 screenies of using one line to change acid bomb's primary damage to deal 10 >>>> 5 + (25% of INT) per second.
  1. Go to Object Editor, to the spell you want, find the field you want and hit Ctrl + D, this will display the raw fields, in this case, primary damage is Nab4
  2. Open trigger editor the "Set Ability Real Level Field" there are similar ones that do not work, you must find this one to make it work!
  3. Navigate RealLevelField and find "Primary Damage - Nab4" (hit P for primary to find it quickly!)
  4. Due to silly changes with the editor level 0 is level 1
  5. use this in a casting trigger and you're damage should update!
  6. experiment!

Acidbomb stat based.png
Acidbomb stat based 2.png
Acidbomb stat based 3.png
 
Last edited:
Level 4
Joined
Sep 25, 2018
Messages
81
Heres 3 screenies of using one line to change acid bomb's primary damage to deal 10 >>>> 5 + (25% of INT) per second.

So you are saying, since the update back in May, you can trigger the damage of any spell damaging by editing its primary damage via the new trigger options?!

Edit: I’m currently on my phone at the moment so I wasn’t able to take a look at your “stress test” map. Are you saying that using buffs to trigger spell damage with this DDS was unreliable (especially MUI spells)?
 
Level 24
Joined
Feb 9, 2009
Messages
1,783
So you are saying, since the update back in May, you can trigger the damage of any spell damaging by editing its primary damage via the new trigger options?!

Edit: I’m currently on my phone at the moment so I wasn’t able to take a look at your “stress test” map. Are you saying that using buffs to trigger spell damage with this DDS was unreliable (especially MUI spells)?

The stress test I have there is to test 100 peasants throwing a modified acid bomb set to be modified to deal 1 damage each, using the basic damage modifier event 1.00 & remove buff process.
If you set the conditions to detect the buff, 60 - 66 of the 100 fireballs will deal their damage.
And now I'm sorry to inform you that the way I presented with the new trigger (which I just tested now) has even worse results because there is no trigger to remove the buff when hit so only upwards of 28 - 33 of the 100 fireballs deal their damage, that's nearly 50% worse!
But in reality, unless you are spamming over 30 projectiles at the same time, you shouldn't have issue, and this is only affecting acid bomb as it relies on it's buff to deal damage.

perhaps reforged or some new treasures from dear Mr. Bribe will present us with an alternative, one can dream~...
 
Level 4
Joined
Sep 25, 2018
Messages
81
The stress test I have there is to test 100 peasants throwing a modified acid bomb set to be modified to deal 1 damage each, using the basic damage modifier event 1.00 & remove buff process.
If you set the conditions to detect the buff, 60 - 66 of the 100 fireballs will deal their damage.
And now I'm sorry to inform you that the way I presented with the new trigger (which I just tested now) has even worse results because there is no trigger to remove the buff when hit so only upwards of 28 - 33 of the 100 fireballs deal their damage, that's nearly 50% worse!
But in reality, unless you are spamming over 30 projectiles at the same time, you shouldn't have issue, and this is only affecting acid bomb as it relies on it's buff to deal damage.

perhaps reforged or some new treasures from dear Mr. Bribe will present us with an alternative, one can dream~...
Interesting! I think reasonably, at the very most, I potentially could have up to 15-20 spells going at once (highly unlikely). So it sounds like this system is more than capable of handling the buff way of differentiating between the spell’s damage.
 
Level 5
Joined
Feb 13, 2019
Messages
128
The stress test I have there is to test 100 peasants throwing a modified acid bomb set to be modified to deal 1 damage each, using the basic damage modifier event 1.00 & remove buff process.
If you set the conditions to detect the buff, 60 - 66 of the 100 fireballs will deal their damage.
And now I'm sorry to inform you that the way I presented with the new trigger (which I just tested now) has even worse results because there is no trigger to remove the buff when hit so only upwards of 28 - 33 of the 100 fireballs deal their damage, that's nearly 50% worse!
But in reality, unless you are spamming over 30 projectiles at the same time, you shouldn't have issue, and this is only affecting acid bomb as it relies on it's buff to deal damage.

perhaps reforged or some new treasures from dear Mr. Bribe will present us with an alternative, one can dream~...



So if I'm not using a buff I can still do this with no problems?


Bruhhhhh that's FUCKING RAD.

+Rep yoooo


Edit:
But wait, wouldn't this permanently change the spell? What if 2 players with different attributes we're to cast the spell at the same time? o_O
 
Last edited:
Level 24
Joined
Feb 9, 2009
Messages
1,783
But wait, wouldn't this permanently change the spell? What if 2 players with different attributes we're to cast the spell at the same time? o_O
Please follow Grog'nar's example and use the edit button.

I did a test with two acid bomb's with two casters with 100% difference in the effecting stat, looks fine so far; but i'm sure you'll need to update it with that trigger each time the unit casts it.
 
Level 7
Joined
Jul 4, 2007
Messages
249
This gives sooo many opportunities to do amazing stuff, I just wish I had started using this earlier because I've got a shitload of things I need to recreate now.
 
Level 6
Joined
Jul 12, 2017
Messages
139
Hi, I wanna do something like 'every 4th attacks of basic attack do bonus damage', but I don't know how to do it. I think I have to use this system in order to do that, so anyone can gimme an example of that?

every x attacks do smth (heal, dmg, AOE, etc.).

Edit: Also, I want 2 different types of this trigger, one is where you do attack the same target for that bonus and other for different target but it still counts or this kind of trigger works in one way or another?
 
Hi, I wanna do something like 'every 4th attacks of basic attack do bonus damage', but I don't know how to do it. I think I have to use this system in order to do that, so anyone can gimme an example of that?

every x attacks do smth (heal, dmg, AOE, etc.).

Edit: Also, I want 2 different types of this trigger, one is where you do attack the same target for that bonus and other for different target but it still counts or this kind of trigger works in one way or another?
You should do it so:

Event - damage detection event
Condition - IsDamageMelee or IsDamageRanged = true, other conditions for the unit that has this ability
Action - Add 1 to a counter, if the counter >= X (in this case X = 4), then do the effect you want.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
You should do it so:

Event - damage detection event
Condition - IsDamageMelee or IsDamageRanged = true, other conditions for the unit that has this ability
Action - Add 1 to a counter, if the counter >= X (in this case X = 4), then do the effect you want.

IsDamageSpell Equal to False is the simpler condition to checking melee or ranged.

The way Damage Engine processes the logic is:

Spell attack type? Yes: end with spell damage. No: continue

Unit type melee attacker? Yes: continue. No: end with ranged damage

Unit type ranged attacker? Yes: continue. No: end with melee damage

Weapon type other than 0? Yes: end with melee damage. No: end with ranged damage
 
Level 6
Joined
Jul 12, 2017
Messages
139
I wanna do it like the unit gives aura to nearby allies to have a chance to do bonus damage but is there no short way to do this? I mean I usually use Real x (0.5 x Level of ability for triggering unit) to make it short for the damage dealer, but there's nothing like owner of buff or level of the buff to scale with level of the ability. It's kinda hard to explain but this is what I usually do with damage trigger.

  • Pillar Bonus DMG
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DamageEventTarget belongs to an enemy of (Owner of DamageEventSource)) Equal to True
          • (Level of Pillage Bonus (Nazgrel) for DamageEventSource) Greater than or equal to 1
          • IsDamageSpell Equal to False
          • (Random integer number between 1 and 100) Less than or equal to 30
        • Then - Actions
          • Set NextDamageType = DamageTypePure
          • Set Real1 = (Real((Strength of DamageEventSource (Include bonuses))))
          • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (Real1 x (2.50 + (0.50 x (Real((Level of Pillage Bonus (Nazgrel) for DamageEventSource)))))) damage of attack type Spells and damage type Normal
          • Player - Add (1 x (Level of Pillage Bonus (Nazgrel) for DamageEventSource)) to (Owner of DamageEventSource) Current gold
          • Special Effect - Create a special effect attached to the origin of DamageEventTarget using Abilities\Spells\Other\Transmute\PileofGold.mdl
          • Special Effect - Destroy (Last created special effect)
        • Else - Actions
As you can see, there's like (Real x (2.50 + (0.50 x etc.) I want an ally with specific buff to gain a chance to do bonus damage, and this bonus scale with the ability of the owner of the buff. I cannot find a short way to do this so I usually do it like 10 triggers for this as this ability has 10 levels but it takes too much time.

I hope you guys understand what I mean though.
 
Level 4
Joined
Sep 25, 2018
Messages
81
I can't seem to get my damage to work properly...

I have a single targeted spell which is suppose to do 105 - 150 (Based on level of spell) + (Intelligence x 0.8) lightning damage. (It also has a little effect after which purges the unit, that part is working fine)

  • LightningBoltDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to True
      • DamageEventPrevAmt Equal to (90.00 + (15.00 x (Real((Level of Lightning Bolt for DamageEventSource)))))
      • DamageEventDamageT Equal to DAMAGE_TYPE_LIGHTNING
    • Actions
      • Set DamageEventAmount = 0.00
      • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (90.00 + ((15.00 x (Real((Level of Lightning Bolt for DamageEventSource)))) + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 0.80))) damage of attack type Spells and damage type Lightning
      • Unit - Create 1 Dummy (Shocked) for (Owner of DamageEventSource) at (Position of DamageEventSource) facing (Position of DamageEventTarget)
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Order (Last created unit) to Orc Shaman - Purge DamageEventTarget
When I "Set DamageEventAmount" 0.00, it does some strange stuff behind the scenes. For example, when casting this spell on an ethereal unit, it does 235 damage as appose to 130. So it seems to not remove the original 105 damage that the spell does to detect if it has landed or not.

I was wondering if I could trigger the damage entirely using the "Set DamageEventAmount".

  • LightningBoltDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to True
      • DamageEventPrevAmt Equal to (90.00 + (15.00 x (Real((Level of Lightning Bolt for DamageEventSource)))))
      • DamageEventDamageT Equal to DAMAGE_TYPE_LIGHTNING
    • Actions
      • Set DamageEventAmount = ((90.00 + (15.00 x (Real((Level of Lightning Bolt for DamageEventSource))))) + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 0.80))
      • Set DamageEventAttackT = ATTACK_TYPE_SPELLS
      • Set DamageEventDamageT = DAMAGE_TYPE_LIGHTNING
      • Unit - Create 1 Dummy (Shocked) for (Owner of DamageEventSource) at (Position of DamageEventSource) facing (Position of DamageEventTarget)
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Order (Last created unit) to Orc Shaman - Purge DamageEventTarget
This seems to turn the damage into something else, because now it no longer does damage if the target is ethereal...


Edit: So I think I have found what the issue is. So, I probably should have said this first, but the plan is that every elemental damage type has a different effect on their target.

For example; Undead units take 20% more fire damage.

Anyway, the plan is to have lightning damage do increased damage based off the units armour. (1 armour does +2% damage amp)

  • Set Damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • True Equal to True
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IsDamageSpell Equal to True
          • DamageEventDamageT Equal to DAMAGE_TYPE_LIGHTNING
        • Then - Actions
          • Set DamageEventAmount = (DamageEventPrevAmt x (1.00 + ((Armor of DamageEventTarget) x 0.02)))
        • Else - Actions
It does increase the damage when the targeted unit has more armour (detects both base and bonus armour). However, not by the correct amount. From my testing, it seems that this DDS seems to just amp the damage by a % to 3 decimal places. I have a feeling that 3 decimal places isn't enough, therefore the rounding up (or down?) is causing the damage amp to fall slightly short.


Edit: Edit: Forgot to add the now working configuration for my lightning spell.

  • LightningBoltDamage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to True
      • DamageEventPrevAmt Equal to (90.00 + (15.00 x (Real((Level of Lightning Bolt for DamageEventSource)))))
      • DamageEventDamageT Equal to DAMAGE_TYPE_LIGHTNING
    • Actions
      • Set DamageEventAmount = (DamageEventAmount + ((Real((Intelligence of DamageEventSource (Include bonuses)))) x 0.80))
      • Set DamageEventAttackT = ATTACK_TYPE_SPELLS
      • Set DamageEventDamageT = DAMAGE_TYPE_LIGHTNING
      • Unit - Create 1 Dummy (Shocked) for (Owner of DamageEventSource) at (Position of DamageEventSource) facing (Position of DamageEventTarget)
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Order (Last created unit) to Orc Shaman - Purge DamageEventTarget
 
Last edited:
I wanna do it like the unit gives aura to nearby allies to have a chance to do bonus damage but is there no short way to do this? I mean I usually use Real x (0.5 x Level of ability for triggering unit) to make it short for the damage dealer, but there's nothing like owner of buff or level of the buff to scale with level of the ability. It's kinda hard to explain but this is what I usually do with damage trigger.
As you can see, there's like (Real x (2.50 + (0.50 x etc.) I want an ally with specific buff to gain a chance to do bonus damage, and this bonus scale with the ability of the owner of the buff. I cannot find a short way to do this so I usually do it like 10 triggers for this as this ability has 10 levels but it takes too much time.

I hope you guys understand what I mean though.
You do it normally but as you check for the DamageEventSource's aura buff, check if in all units within X range of DamageEventSource there's a unit with the aura (buff provider). Then you get the picked unit's level of its aura.
 
Level 6
Joined
Jul 12, 2017
Messages
139
  • You have done well DMG 1
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IsDamageSpell Equal to False
          • (DamageEventSource has buff You've done well 1 (Nazgrel) ) Equal to True
          • (Random integer number between 1 and 100) Less than or equal to 12
          • (All units of (Units within 900.00 of (Position of DamageEventSource) matching ((Level of You've done well (Nazgrel) for (Matching unit)) Greater than or equal to 1)) are in (Playable map area)) Equal to True
        • Then - Actions
          • Set NextDamageType = DamageTypePure
          • Set Real1 = (Real((Base Damage of DamageEventSource for weapon index 0)))
          • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (Real1 x 0.50) damage of attack type Spells and damage type Normal
          • Special Effect - Create a special effect attached to the origin of DamageEventTarget using Objects\Spawnmodels\Critters\Albatross\CritterBloodAlbatross.mdl
          • Special Effect - Destroy (Last created special effect)
        • Else - Actions
Like this?
 
  • You have done well DMG 1
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IsDamageSpell Equal to False
          • (DamageEventSource has buff You've done well 1 (Nazgrel) ) Equal to True
          • (Random integer number between 1 and 100) Less than or equal to 12
          • (All units of (Units within 900.00 of (Position of DamageEventSource) matching ((Level of You've done well (Nazgrel) for (Matching unit)) Greater than or equal to 1)) are in (Playable map area)) Equal to True
        • Then - Actions
          • Set NextDamageType = DamageTypePure
          • Set Real1 = (Real((Base Damage of DamageEventSource for weapon index 0)))
          • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (Real1 x 0.50) damage of attack type Spells and damage type Normal
          • Special Effect - Create a special effect attached to the origin of DamageEventTarget using Objects\Spawnmodels\Critters\Albatross\CritterBloodAlbatross.mdl
          • Special Effect - Destroy (Last created special effect)
        • Else - Actions
Like this?
No, like "Number of units in (Units within 900 of (Position of DamageEventSource) matching (Level of Ability for Matching unit > 0) and (Matching unit is an ally of Owner of DamageEventSource)) is > 0"
But your trigger also leaks a lot so you'll have to clean it up using variables.
 
Level 6
Joined
Jul 12, 2017
Messages
139
So even if I put it like this, it still leaks?

  • Titan Roars AOE Damage
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Titan Roar (Sargeras)
    • Actions
      • Set Point1 = (Position of (Casting unit))
      • Set Real1 = (Real((Strength of (Casting unit) (Include bonuses))))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 300.00 of Point1) and do (Actions)
        • Loop - Actions
          • Set TempUnit = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TempUnit belongs to an enemy of (Owner of (Casting unit))) Equal to True
              • (TempUnit is alive) Equal to True
            • Then - Actions
              • Unit - Cause (Casting unit) to damage TempUnit, dealing ((100.00 x (Real((Level of Titan Roar (Sargeras) for (Casting unit))))) + (Real1 x (0.50 + (0.50 x (Real((Level of Titan Roar (Sargeras) for (Casting unit)))))))) damage of attack type Spells and damage type Normal
            • Else - Actions
      • Custom script: call RemoveLocation(udg_Point1)
 
That doesn't leak, but if you use "bj_wantDestroyGroup = true" followed by a "Unit Group - Pick every unit in <whatever group variable>" then that group variable will be destroyed, preventing you from using it again in the same trigger once the "Unit Group - Pick every unit" function finishes running.
The safest way for GUI is always set your variable to a group, then call DestroyGroup at the end.
 
Level 6
Joined
Jul 12, 2017
Messages
139
So is it supposed to be like this then?

  • You have done well DMG 1
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IsDamageSpell Equal to False
          • (DamageEventSource has buff You've done well (Nazgrel) ) Equal to True
          • (Random integer number between 1 and 100) Less than or equal to 12
        • Then - Actions
          • Set Point1 = (Position of DamageEventSource)
          • Set Real1 = (Real((Base Damage of DamageEventSource for weapon index 0)))
          • Unit Group - Pick every unit in (Units within 900.00 of Point1) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in (Units within 900.00 of Point1 matching ((Level of You've done well (Nazgrel) for DamageEventSource) Greater than or equal to 1))) Greater than or equal to 1
                • Then - Actions
                  • Set NextDamageType = DamageTypePure
                  • Set Real1 = (Real((Base Damage of DamageEventSource for weapon index 0)))
                  • Unit - Cause DamageEventSource to damage DamageEventTarget, dealing (Real1 x (0.25 + (0.25 x (Real((Level of You've done well (Nazgrel) for (Picked unit))))))) damage of attack type Spells and damage type Normal
                  • Special Effect - Create a special effect attached to the origin of DamageEventTarget using Objects\Spawnmodels\Critters\Albatross\CritterBloodAlbatross.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
        • Else - Actions
 
Top