Damage Engine 5.7.1.2

This bundle is marked as approved. It works and satisfies the submission rules.
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

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 "DamageEvent Equal to 1.00". 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 "DamageModifierEvent Becomes Equal to 1.00, 2.00 or 3.00". 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 "DamageModifierEvent Becomes Equal to 4.00". 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 "DamageModifierEvent" 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 1.00" 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 DamageModifierEvents up to 3.99
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, DamageModifierEvent 4.00 and up 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 DamageEvent 1.00. 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: 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 <DamageModifierEvent> becomes Equal to 1.00".
    • 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 "DamageModifierEvent 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
    • Conditions
    • Actions
      • -------- - --------
      • -------- New in Damage Engine 5.7 - you can use the below to automatically assign conditions --------
      • -------- - --------
      • -------- Equal to - Same as no conditions, works as it always has --------
      • -------- Less than - Same as IsDamageAttack Equal to True --------
      • -------- Less than or equal to - Same as IsDamageMelee Equal to True --------
      • -------- Greater than or equal to - Same as IsDamageRanged Equal to True --------
      • -------- Greater than - Same as IsDamageSpell Equal to True --------
      • -------- Not Equal to - Same as IsDamageCode Equal to True --------
      • -------- - --------
      • -------- 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
      • -------- - --------
      • -------- Added 25 July 2017 to allow detection of things like Bash or Pulverize or AOE spread --------
      • -------- - --------
      • Set VariableSet DamageEventAOE = 1
      • Set VariableSet DamageEventLevel = 1
      • -------- - --------
      • -------- In-game World Editor doesn't allow Attack Type and Damage Type comparisons. Therefore I need to code them as integers into GUI --------
      • -------- - --------
      • Set VariableSet ATTACK_TYPE_SPELLS = 0
      • Set VariableSet ATTACK_TYPE_NORMAL = 1
      • Set VariableSet ATTACK_TYPE_PIERCE = 2
      • Set VariableSet ATTACK_TYPE_SIEGE = 3
      • Set VariableSet ATTACK_TYPE_MAGIC = 4
      • Set VariableSet ATTACK_TYPE_CHAOS = 5
      • Set VariableSet ATTACK_TYPE_HERO = 6
      • -------- - --------
      • Set VariableSet DAMAGE_TYPE_UNKNOWN = 0
      • Set VariableSet DAMAGE_TYPE_NORMAL = 4
      • Set VariableSet DAMAGE_TYPE_ENHANCED = 5
      • Set VariableSet DAMAGE_TYPE_FIRE = 8
      • Set VariableSet DAMAGE_TYPE_COLD = 9
      • Set VariableSet DAMAGE_TYPE_LIGHTNING = 10
      • Set VariableSet DAMAGE_TYPE_POISON = 11
      • Set VariableSet DAMAGE_TYPE_DISEASE = 12
      • Set VariableSet DAMAGE_TYPE_DIVINE = 13
      • Set VariableSet DAMAGE_TYPE_MAGIC = 14
      • Set VariableSet DAMAGE_TYPE_SONIC = 15
      • Set VariableSet DAMAGE_TYPE_ACID = 16
      • Set VariableSet DAMAGE_TYPE_FORCE = 17
      • Set VariableSet DAMAGE_TYPE_DEATH = 18
      • Set VariableSet DAMAGE_TYPE_MIND = 19
      • Set VariableSet DAMAGE_TYPE_PLANT = 20
      • Set VariableSet DAMAGE_TYPE_DEFENSIVE = 21
      • Set VariableSet DAMAGE_TYPE_DEMOLITION = 22
      • Set VariableSet DAMAGE_TYPE_SLOW_POISON = 23
      • Set VariableSet DAMAGE_TYPE_SPIRIT_LINK = 24
      • Set VariableSet DAMAGE_TYPE_SHADOW_STRIKE = 25
      • Set VariableSet DAMAGE_TYPE_UNIVERSAL = 26
      • -------- - --------
      • -------- The below variables don't affect damage amount, but do affect the sound played --------
      • -------- They also give important information about the type of attack used. --------
      • -------- They can differentiate between ranged and melee for units who are both --------
      • -------- - --------
      • Set VariableSet WEAPON_TYPE_NONE = 0
      • -------- Metal Light/Medium/Heavy --------
      • Set VariableSet WEAPON_TYPE_ML_CHOP = 1
      • Set VariableSet WEAPON_TYPE_MM_CHOP = 2
      • Set VariableSet WEAPON_TYPE_MH_CHOP = 3
      • Set VariableSet WEAPON_TYPE_ML_SLICE = 4
      • Set VariableSet WEAPON_TYPE_MM_SLICE = 5
      • Set VariableSet WEAPON_TYPE_MH_SLICE = 6
      • Set VariableSet WEAPON_TYPE_MM_BASH = 7
      • Set VariableSet WEAPON_TYPE_MH_BASH = 8
      • Set VariableSet WEAPON_TYPE_MM_STAB = 9
      • Set VariableSet WEAPON_TYPE_MH_STAB = 10
      • -------- Wood Light/Medium/Heavy --------
      • Set VariableSet WEAPON_TYPE_WL_SLICE = 11
      • Set VariableSet WEAPON_TYPE_WM_SLICE = 12
      • Set VariableSet WEAPON_TYPE_WH_SLICE = 13
      • Set VariableSet WEAPON_TYPE_WL_BASH = 14
      • Set VariableSet WEAPON_TYPE_WM_BASH = 15
      • Set VariableSet WEAPON_TYPE_WH_BASH = 16
      • Set VariableSet WEAPON_TYPE_WL_STAB = 17
      • Set VariableSet WEAPON_TYPE_WM_STAB = 18
      • -------- Claw Light/Medium/Heavy --------
      • Set VariableSet WEAPON_TYPE_CL_SLICE = 19
      • Set VariableSet WEAPON_TYPE_CM_SLICE = 20
      • Set VariableSet WEAPON_TYPE_CH_SLICE = 21
      • -------- Axe Medium --------
      • Set VariableSet WEAPON_TYPE_AM_CHOP = 22
      • -------- Rock Heavy --------
      • Set VariableSet WEAPON_TYPE_RH_BASH = 23
      • -------- - --------
      • -------- Since GUI still doesn't provide Defense Type and Armor Types, I needed to include the below --------
      • -------- - --------
      • Set VariableSet ARMOR_TYPE_NONE = 0
      • Set VariableSet ARMOR_TYPE_FLESH = 1
      • Set VariableSet ARMOR_TYPE_METAL = 2
      • Set VariableSet ARMOR_TYPE_WOOD = 3
      • Set VariableSet ARMOR_TYPE_ETHEREAL = 4
      • Set VariableSet ARMOR_TYPE_STONE = 5
      • -------- - --------
      • Set VariableSet DEFENSE_TYPE_LIGHT = 0
      • Set VariableSet DEFENSE_TYPE_MEDIUM = 1
      • Set VariableSet DEFENSE_TYPE_HEAVY = 2
      • Set VariableSet DEFENSE_TYPE_FORTIFIED = 3
      • Set VariableSet DEFENSE_TYPE_NORMAL = 4
      • Set VariableSet DEFENSE_TYPE_HERO = 5
      • Set VariableSet DEFENSE_TYPE_DIVINE = 6
      • Set VariableSet DEFENSE_TYPE_UNARMORED = 7
      • -------- - --------
      • Set VariableSet DamageFilterAttackT = -1
      • Set VariableSet DamageFilterDamageT = -1
      • -------- - --------
      • 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.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 5.7.1.2 (Map)

Lua Damage Engine 1.0.2.3 (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 32
Joined
Mar 27, 2008
Messages
8,025
Bribe, just a question, how to use your system to differentiate damage is dealt either by Physical or Magical (Spell Damage) ?
I saw some variables such as DamageTypeSpell, DamageTypeDOT, DamageTypeRanged, is that something to do with this case ?
 
Level 16
Joined
Nov 13, 2006
Messages
1,814
Bribe, just a question, how to use your system to differentiate damage is dealt either by Physical or Magical (Spell Damage) ?
I saw some variables such as DamageTypeSpell, DamageTypeDOT, DamageTypeRanged, is that something to do with this case ?

these variables isnt setted automatical, i guess he added these variable for be more clear so like if u do this:

example:
DamageType=0 then it is physical damage and if DamageTypeDot=1 then it is physical dot damage type or
if damagetype=1 and u use like define magic damage and damagetype spell = 2 could be fire element damage type, but u must declare both variable

(i dont use them, simple use damagetype and used more ifs)
 
Level 32
Joined
Mar 27, 2008
Messages
8,025
@shadow
Can you show me the usage via trigger ?

  • Untitled Trigger 001
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • -------- WHAT SHOULD I DO HERE TO DIFFERENTIATE BETWEEN SPELL AND MAGICAL DAMAGE --------
 
Level 16
Joined
Nov 13, 2006
Messages
1,814
but i warn u for this u must trigger every ability in ur map :p


  • fire
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Firebolt (Neutral Hostile)
    • Actions
      • -------- when u use firebolt (neutral ability then declare the following things before the damage) --------
      • Set DamageEventType = 1
      • -------- lets say the 3 is fire damage --------
      • Set DamageTypeSpell = 3
      • -------- cant ake mistake since damage damage instant after variable was setted --------
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing 500.00 damage of attack type Hero and damage type Normal
  • lightning
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Storm Bolt
    • Actions
      • -------- when u use storm bolt ability then declare the following things before the damage --------
      • Set DamageEventType = 1
      • -------- lets say the 2 is lightning damage --------
      • Set DamageTypeSpell = 2
      • -------- cant ake mistake since damage damage instant after variable was setted --------
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing 500.00 damage of attack type Hero and damage type Normal
  • damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • -------- if damage type is 1 then it is magic damage and we check the spell type --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DamageEventType Equal to 1
        • Then - Actions
          • -------- in this example fire damage do 2x more and lightning damage do 3x more damage than others --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DamageTypeSpell Equal to 2
            • Then - Actions
              • Set DamageEventAmount = (DamageEventAmount x 3.00)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DamageTypeSpell Equal to 3
                • Then - Actions
                  • Set DamageEventAmount = (DamageEventAmount x 2.00)
                • Else - Actions
        • Else - Actions
      • -------- both damageeventtype and damagespelltype rested so cant be fire damage after u used ability then fast attack with normal attack, only ability will be declared like magic damage --------
whatever, for make elemental damage for creeps is far more easy because simple just do tricks in object editor, like example set all fire elemental creep point value to 3 and all lightning elemental creep point value to 2 then simple check if attacked is neutral hostile unit and if yes then check the unit custom value.

(also my advice use damageeventtype 0 for physical damage because then u dont need to declare the normal attack :p also u can use point value 100 for physical creeps because it is 100 by default the point value to every unit in object editor)
 
Last edited:

sentrywiz

S

sentrywiz

Question

Hi!

First of all, awesome system. I am using it right now to detect and show damage and its awesome. Thank you for making/upgrading it.

Now my questions-- I've been reading how to use it because I've come to a problem. You have this written inside the trigger:

Modify DamageEventAmount/ExplodesUnit/Override from a "DamageModifierEvent Equal to 1.00" trigger. To prevent your script's damage stacking with others, include the condition "DamageEventOverride Equal to false".

Likewise, set "DamageEventOverride" to true if you don't want other scripts to stack with it.

1. It says to prevent damage stacking set DamageEventOverride to false, then it says set it to true if you don't want other scripts to stack with it. To me this looks like the same thing, and whether you set variable to true/false it does the same thing?

2. I have trouble with the following thing:

-I am detecting critical/lifesteal with the following trigger

  • Crit Lifesteal
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • DamageEventOverride Equal to False
      • ((Unit-type of DamageEventSource) is A Hero) Equal to True
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random real number between 1.00 and 100.00) Less than or equal to Player_Critical[(Player number of (Owner of DamageEventSource))]
        • Then - Actions
          • Set DamageEventOverride = True
          • Set DamageEventAmount = (DamageEventAmount x 2.00)
          • Floating Text - Create floating text that reads ((String((Integer(DamageEventAmount)))) + !) above DamageEventTarget with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 90.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 0.75 seconds
          • Floating Text - Change the fading age of (Last created floating text) to 0.50 seconds
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Player_Lifesteal[(Player number of (Owner of DamageEventSource))] Greater than 0.00
              • DamageEventType Equal to 2
            • Then - Actions
              • Set Lifesteal_Heal = (DamageEventAmount x Player_Lifesteal[(Player number of (Owner of DamageEventSource))])
              • Floating Text - Create floating text that reads (+ + (String((Integer(Lifesteal_Heal))))) above DamageEventSource with Z offset 0.00, using font size 7.00, color (0.00%, 100.00%, 0.00%), and 25.00% transparency
              • Floating Text - Set the velocity of (Last created floating text) to 140.00 towards 90.00 degrees
              • Floating Text - Change (Last created floating text): Disable permanence
              • Floating Text - Change the lifespan of (Last created floating text) to 0.75 seconds
              • Floating Text - Change the fading age of (Last created floating text) to 0.50 seconds
              • Unit - Set life of DamageEventSource to ((Life of DamageEventSource) + Lifesteal_Heal)
            • Else - Actions
        • Else - Actions

This works flawlessly. I had to set DamageEventOverride to true to make critical be a separate event from damage but its okay, more learning to me.

I have also made the three damage types into:
Type1 - Spell Damage
Type2 - Physical Damage
Type3 - Physical Damage No Lifesteal

I am using damage type 3 in a spell that deals physical damage overtime. But that damage can both critical and heals from lifesteal. I don't want that. Here is the spell:

  • Rend
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • DamageEventOverride Equal to False
      • (Unit-type of DamageEventSource) Equal to Vampire
      • (Level of Rend (Vampire) for DamageEventSource) Greater than 0
    • Actions
      • Set rend_chance[(Player number of (Owner of DamageEventSource))] = (Real(((Level of Rend (Vampire) for (Triggering unit)) x 5)))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • rend_chance[(Player number of (Owner of DamageEventSource))] Less than or equal to (Random real number between 1.00 and 100.00)
          • (DamageEventTarget is in rend_group) Not equal to True
        • Then - Actions
          • Set rend_damage[(Player number of (Owner of DamageEventTarget))] = DamageEventAmount
          • Set rend_caster[(Player number of (Owner of DamageEventTarget))] = DamageEventSource
          • Set rend_time[(Player number of (Owner of DamageEventTarget))] = 5
          • Floating Text - Create floating text that reads <Rend> above DamageEventTarget with Z offset 0.00, using font size 8.00, color (70.00%, 40.00%, 5.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 360.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 0.75 seconds
          • Floating Text - Change the fading age of (Last created floating text) to 0.50 seconds
          • Unit Group - Add DamageEventTarget to rend_group
          • Special Effect - Create a special effect attached to the chest of DamageEventTarget using Objects\Spawnmodels\Human\HumanBlood\HumanBloodMortarTeam.mdl
          • Special Effect - Destroy (Last created special effect)
          • Trigger - Turn on Rend Loop <gen>
        • Else - Actions
  • Rend Loop
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in rend_group and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in rend_group) Greater than 0
            • Then - Actions
              • Set rend_pick = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • rend_time[(Player number of (Owner of rend_pick))] Greater than 0
                • Then - Actions
                  • Set DamageEventType = 3
                  • Set DamageEventOverride = False
                  • Set rend_time[(Player number of (Owner of rend_pick))] = (rend_time[(Player number of (Owner of rend_pick))] - 1)
                  • Unit - Cause rend_caster[(Player number of (Owner of rend_pick))] to damage rend_pick, dealing (rend_damage[(Player number of (Owner of rend_pick))] / 5.00) damage of attack type Hero and damage type Normal
                  • Special Effect - Create a special effect attached to the chest of rend_pick using Objects\Spawnmodels\Human\HumanBlood\HumanBloodMortarTeam.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
                  • Set rend_time[(Player number of (Owner of rend_pick))] = 0
                  • Floating Text - Create floating text that reads <Rend Fades> above rend_pick with Z offset 0.00, using font size 8.00, color (70.00%, 40.00%, 5.00%), and 0.00% transparency
                  • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 360.00 degrees
                  • Floating Text - Change (Last created floating text): Disable permanence
                  • Floating Text - Change the lifespan of (Last created floating text) to 0.75 seconds
                  • Floating Text - Change the fading age of (Last created floating text) to 0.50 seconds
                  • Unit Group - Remove rend_pick from rend_group
            • Else - Actions
              • Trigger - Turn off (This trigger)

I understand that I might be misusing the system and am confused. Thank you for understanding. i appreciate any help you can give me. Thank you :)
 
Level 16
Joined
Nov 13, 2006
Messages
1,814
why dont just make something like that in your map:

set the damageeventype at every ability/dot etc
DamageEventType = 0 (use for physical damage) //dont need to set this for autoattack coz default variable value is 0 anyway :D
DamageEventType = 1 (use for fire damage)
DamageEventType = 2 (use for water damage)
DamageEventType = 3 (use for lightning damage)
DamageEventType = 4 (use for physical dot damage)
DamageEventType = 5 (use for fire dot damage)
DamageEventType = 6 (use for water dot damage)
DamageEventType = 7 (use for lightning dot damage)

you can use as u want just make different damageeventtype value to dot and another damages :p
or just set the damageeventdot integer variable before trigger the dot damage and check the value in set damage trigger
 

sentrywiz

S

sentrywiz

Thank you for quick reply :)

Multiple damages sounds good. I can even create a separate damage type for every hero, if there is a need. Good advice

So how can I fix the lifesteal/crit that happens when a player that has lifesteal/crit > 0 and applies to spells too? Because that is the true problem, not the damage type.

Thank you!
 
Level 16
Joined
Nov 13, 2006
Messages
1,814
Thank you for quick reply :)

Multiple damages sounds good. I can even create a separate damage type for every hero, if there is a need. Good advice

So how can I fix the lifesteal/crit that happens when a player that has lifesteal/crit > 0 and applies to spells too? Because that is the true problem, not the damage type.

Thank you!

maybe u dont noticed why i wrote the damage event type.....

DamageEventType = 1 (use for fire damage)
DamageEventType = 2 (use for water damage)
DamageEventType = 3 (use for lightning damage)
DamageEventType = 4 (use for physical dot damage)
DamageEventType = 5 (use for fire dot damage)
DamageEventType = 6 (use for water dot damage)
DamageEventType = 7 (use for lightning dot damage)

at set damage:
if DamageEventType < 4 then
add chance for crit/life steal (if crit then DamageEventAmount = DamageEventAmount *2, if life steal the write out the stoled hp amount with floating text)
endif
write damage with floating text

or

if DamageEventTypeDot > 0 then
add chance for crit/life steal (if crit then DamageEventAmount = DamageEventAmount *2, if life steal the write out the stoled hp amount with floating text)
endif)
endif
write damage with floating text


why use Triggering unit when event is real depend event and not unit depend event (=>trigger unit not exist with real event, use DamageEventTarget, DamageEventSource)
  • Rend
  • Events
  • Game - DamageModifierEvent becomes Equal to 1.00
  • Conditions
  • DamageEventOverride Equal to False
  • (Unit - type of DamageEventSource) Equal to Vampire
  • (Level of Rend (Vampire) for DamageEventSource) Greater than 0
  • Actions
  • Set rend_chance[(Player number of (Owner of DamageEventSource))] = (Real(((Level of Rend (Vampire) for (Triggering unit)) x 5)))
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • rend_chance[(Player number of (Owner of DamageEventSource))] Less than or equal to (Random real number between 1.00 and 100.00)
      • (DamageEventTarget is in rend_group) Not equal to True
      • Then - Actions
      • Set rend_damage[(Player number of (Owner of DamageEventTarget))] = DamageEventAmount
      • Set rend_caster[(Player number of (Owner of DamageEventTarget))] = DamageEventSource
      • Set rend_time[(Player number of (Owner of DamageEventTarget))] = 5
      • Floating Text - Create floating text that reads < Rend > above DamageEventTarget with Z offset 0.00, using font size 8.00, color (70.00%, 40.00%, 5.00%), and 0.00% transparency
      • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 360.00 degrees
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Change the lifespan of (Last created floating text) to 0.75 seconds
      • Floating Text - Change the fading age of (Last created floating text) to 0.50 seconds
      • Unit Group - Add DamageEventTarget to rend_group
      • Special Effect - Create a special effect attached to the chest of DamageEventTarget using Objects\Spawnmodels\Human\HumanBlood\HumanBloodMortarTeam.mdl
      • Special Effect - Destroy (Last created special effect)
      • Trigger - Turn on Rend Loop < gen >
    • Else - Actions
i dont understand why need group and turning on or off the triggers for that?
 
Level 13
Joined
Dec 12, 2012
Messages
1,000
I encountered a bug in this system.

If I modify the damage to a value below the actual damage amount, it can happen that the attacked unit gets healed to full HP.

This happens more likely the more units attack one unit at the same time, but in theory two units are already sufficient. Also if you apply different damages in the same instance, it will heal to full HP.

These two lines in a row are enough to break the system and to demonstrate the behaviour when the modified amount is lower than the real amount:

JASS:
call UnitDamageTarget(source, target, amount, true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call UnitDamageTarget(source, target, amount, true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
 
Level 34
Joined
Sep 26, 2009
Messages
8,433
This system is currently designed to interpret negative damage as a heal, not 0 damage. It's a feature not a bug.

In regards to the cheat, that's interesting to know. But I have no love for cheat codes, so me not looking into it would also make that a feature, not a bug.

Nestharus has apparently discovered a way to treat all spell damage as negative damage, so I may design an addon to support that one day.
 
Level 13
Joined
Dec 12, 2012
Messages
1,000
This system is currently designed to interpret negative damage as a heal, not 0 damage. It's a feature not a bug.

No, this is not the case here.

I did not use a negative amount of damage, just dealt normal (positive) damage in a row in one script as explained above.
The damage then got reduced, but still to a positive value so it should never heal.

Try it out yourself.
 
Level 13
Joined
Dec 12, 2012
Messages
1,000
1.) Set the health of the mortar team in your testmap to 50% so that it starts with half HP.

2.) Set DamageEventAmount to a value of 10.0, so that all attacks should deal 10.0 damage.

3.) Use this script:

JASS:
scope DamageTest initializer i
    private function test_Actions takes nothing returns nothing
        call UnitDamageTarget(gg_unit_hmtm_0005, gg_unit_hmtm_0005, 1000.0, true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
        call UnitDamageTarget(gg_unit_hmtm_0005, gg_unit_hmtm_0005, 1000.0, true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
    endfunction

    private function i takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterTimerEvent(t, 1.0, false)
        call TriggerAddAction(t, function test_Actions)
        set t = null
    endfunction
endscope

After this, the mortar should have 0.5*360 - 20 = 160 health, but instead he gets healed to full HP.

This can also happen during normal fights, namely when two attacks are so close together that
they share the same instance.


EDIT:

Another bug is, that when you increase the DamageEventAmount, e.g. double it, units won't explode if killed by an artillery unit.
 
Last edited:
Level 14
Joined
Nov 17, 2010
Messages
1,267
I've used this in my campaign and it works great in the first map. The problem comes when I try to transition to the next map. When I copy the Damage Engine into the next map it won't allow it to open. It just kicks me back to the campaign loading screen. I'm wondering if there is anything I have to do differently or add to a game cache in order to get it to work on the other maps. Thanks.

EDIT: I tried it in other maps by just using the button to the corresponding map in the campaign screen and it worked fine. So the problem comes from the transition from one map to another using a Game Cache.
 
Last edited:

sentrywiz

S

sentrywiz

Issues with engine

Hi. I don't know if you're still active on the forum, I'll give it a shot.

I so badly want to use the engine, but I don't understand few things.

- I have 3 damage types, Physical, Spell and True

I don't understand how to use DamageEventOveride variables so that the system shows spell damage. As it is now, its working great for true and physical damage because those are checked on DamageModifierEvent.

Here are my triggers:


  • Damage Texts
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DamageEventType Equal to SpellDamage
        • Then - Actions
          • Floating Text - Create floating text that reads (Spell Dmg - + ((String(DamageEventAmount)) + !)) above DamageEventTarget with Z offset 0.00, using font size 7.00, color (100.00%, 25.00%, 66.00%), and 0.00% transparency
          • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 90.00 degrees
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
          • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DamageEventType Equal to PhysicalDamage
            • Then - Actions
              • Floating Text - Create floating text that reads (Physical Dmg - + ((String(DamageEventAmount)) + !)) above DamageEventTarget with Z offset 0.00, using font size 7.00, color (50.00%, 80.00%, 15.00%), and 0.00% transparency
              • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 90.00 degrees
              • Floating Text - Change (Last created floating text): Disable permanence
              • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
              • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DamageEventType Equal to TrueDamage
                • Then - Actions
                  • Floating Text - Create floating text that reads (True Dmg - + ((String(DamageEventAmount)) + !)) above DamageEventTarget with Z offset 0.00, using font size 9.00, color (15.00%, 15.00%, 25.00%), and 0.00% transparency
                  • Floating Text - Set the velocity of (Last created floating text) to 100.00 towards 90.00 degrees
                  • Floating Text - Change (Last created floating text): Disable permanence
                  • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
                  • Floating Text - Change the lifespan of (Last created floating text) to 1.00 seconds
                • Else - Actions



  • Attacks
    • 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
          • (DamageEventSource has buff Battle Roar) Equal to True
        • Then - Actions
          • Set DamageEventType = TrueDamage
          • Set DamageEventAmount = (Random real number between 1.00 and 25.00)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (DamageEventSource is A Hero) Equal to True
            • Then - Actions
              • Set DamageEventType = PhysicalDamage
              • Set DamageEventAmount = (Random real number between 1.00 and 10.00)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (DamageEventSource is A Hero) Not equal to True
                • Then - Actions
                  • Set DamageEventType = PhysicalDamage
                  • Set DamageEventAmount = (Random real number between 1.00 and 5.00)
                • Else - Actions



  • Piercing Arrow
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Piercing Shot
    • Actions
      • Set DamageEventType = SpellDamage
      • Set DamageEventAmount = (Random real number between 25.00 and 50.00)
      • Unit Group - Pick every unit in (Units owned by Neutral Hostile) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Casting unit) to damage (Picked unit), dealing DamageEventAmount damage of attack type Spells and damage type Normal


I really want to use the engine :( sadly I don't fully understand it I guess.
 
Level 34
Joined
Sep 26, 2009
Messages
8,433
It's ok, it's not that you don't fully understand it but because the feature to detect spell damage automatically is not provided by this system. There are workarounds for getting the spell damage but they all have big flaws. I recommend triggering all spell damage instead of letting object editor do it for you. that way you can set DamageEventType manually to do your exact bidding.
 

sentrywiz

S

sentrywiz

It's ok, it's not that you don't fully understand it but because the feature to detect spell damage automatically is not provided by this system. There are workarounds for getting the spell damage but they all have big flaws. I recommend triggering all spell damage instead of letting object editor do it for you. that way you can set DamageEventType manually to do your exact bidding.

Oh good you're still alive here.

So system is little flawed for spell damage? If that is so, then from the triggers I posted above, its simpler that I just don't use the system regarding spells and do them manually? Is this what you are suggesting?
 

sentrywiz

S

sentrywiz

This system is not flawed for spell damage, it's that Blizzard's game engine is flawed in that they didn't give users like us full access to the API. One of the reasons I don't code for WarCraft 3 any more. I've just had enough of being told what I can't do.

I think that is a good reason.

However, I'm sure you can do anything in any system, no matter how "limited" it seems to be. Though, thank you for telling me. I bet starcraft2's editor doesn't have challenges like these :)
 
I'm curious what you mean about the cross compatibility. I still have to install the system normally and if I don't want to redo the spells which use GDD then I also have to copy that script you posted?

Yes. Delete GDD, but keep the variables that come with it, then add that one script he posted so that all your spells that use GDD would still function normally.

That snippet of code essentially just simulates GDD while running of DamageEngine.
 
Level 32
Joined
Mar 27, 2008
Messages
8,025
How can I detect a 'miss' attack ?
I've tried several methods so far but failed

Method 1;
  • Detect Miss
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Custom script: if udg_DamageEventAmount == null then
      • Game - Display to (All players) the text: MISS
      • Custom script: endif
Method 2;
  • Detect Miss
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DamageEventAmount Equal to 0.00
        • Then - Actions
          • Game - Display to (All players) the text: MISS
        • Else - Actions
          • Game - Display to (All players) the text: HIT
Method 3;
  • Detect Miss
    • Events
      • Game - DamageEvent becomes Equal to 2.00
    • Conditions
    • Actions
      • Game - Display to (All players) the text: MISS
Method 4;
  • Detect Miss
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Custom script: if udg_DamageEventTarget == null then
      • Game - Display to (All players) the text: MISS
      • Custom script: endif
What other method can you show me ?
 
Level 12
Joined
Mar 24, 2013
Messages
1,105
How might I go about negating the damage to the DamageEventTarget (Set DamageEventAmount = 0), yet saving the DamageEventAmount to deal as damage to the DamageEventSource?

Attempting to make a reflecting damage ability that when a unit (trys to) damage(s) the reflecting hero, the hero takes 0 damage, and reflects the damage to the unit.
 
Level 30
Joined
Jul 10, 2007
Messages
6,307
no, he came up with his own strategy

he uses spell resistance to make all spell damage negative

his specific algorithm will cause a few problems, use mine instead (mine still has 1 problem at the moment, but it's a quick fix, when calculating actual damage in archetype plugin, instead of UnitDamageTarget(u, u, ..), change it to UnitDamageTarget(dummyUnit, u, ...) whatever that dummy unit is.

edit
you also need to make sure that your lifebars don't flicker and so on

just solve all of the problems that have to do with saving a unit ^)^, read lfh's review of DDS to see most of them
 
Level 2
Joined
Mar 9, 2014
Messages
8
Hey, First i'd like to say your damage engine is amazing. But I'm trying to make an ability redirect damage, and it seems like everything is in order so I'm completely lost.


The Triggers:
Sets the spell up:
  • Redirect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Redirect
    • Actions
      • Set PlayerNumber = (Player number of (Triggering player))
      • Unit Group - Add (Target unit of ability being cast) to Redirected[PlayerNumber]
      • Unit - Create 1 Dummy03 for (Triggering player) at (Position of (Triggering unit)) facing Default building facing degrees
      • Unit - Add Redirect Buff to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Frost Armor (Triggering unit)
      • Unit - Add a 0.20 second Generic expiration timer to (Last created unit)
Divvies up the damage
  • Redirect Damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • (DamageEventTarget has buff Redirecting ) Equal to True
          • DamageEventOverride Equal to False
    • Actions
      • Set DamageEventOverride = True
      • Set DamageEventAmount = 0.00
      • Unit Group - Pick every unit in Redirected[(Player number of (Owner of DamageEventTarget))] and do (Unit - Cause DamageEventTarget to damage (Picked unit), dealing DamageEventPrevAmt damage of attack type Spells and damage type Normal)
      • Unit Group - Pick every unit in Redirected[(Player number of (Owner of DamageEventTarget))] and do (Unit - Remove Redirect buff from (Picked unit))
      • Unit - Remove Redirecting buff from DamageEventTarget
      • Unit Group - Pick every unit in Redirected[(Player number of (Owner of DamageEventTarget))] and do (Unit Group - Remove (Picked unit) from Redirected[(Player number of (Owner of DamageEventTarget))])
      • Floating Text - Create floating text that reads (Redirected + !) above DamageEventTarget with Z offset 50.00, using font size 13.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
      • Floating Text - Set the velocity of (Last created floating text) to 75.00 towards 90.00 degrees
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Change the lifespan of (Last created floating text) to 3.50 seconds
      • Floating Text - Change the fading age of (Last created floating text) to 1.40 seconds
Ability description:
Target a unit to redirect the next instance of damage you take at it.

The problem: Nothing in the actions portion of the damage engine trigger do anything except the floating text.
Thanks in advance!
 
Top