- Joined
- May 7, 2008
- Messages
- 346
EDIT - Solution has been found, scroll down below to find it!
I'm very new to this, and I'm a little bit stuck on the next thing I want to do
As for now, I'm sure you all know that ''A unit is attacked'' event is highly abusive, and that's where my problem lies.
I'm trying to use this damage / unit indexing to check if the damage has been made, so far it works for one of the imported spells called ''Fatal Bonds'' which was made by one of the users here on Hive, however I have no idea how to actually apply it.
This is my code:
It works without ''DamageEvent Equal to 1.00'' but spamming hold or stop and then attacking will result in abusive scenarios, which I do not prefer.
And then I'm using this
and
and
and it says in the ''Damage Engine Trigger'' that all I have to do is use ''DamageEvent Equal to 1.00'' so that's what I've implemented in my trigger, but after trying it few times the spell never actually gets triggered.
Any ideas why?
Thanks, as usual!
I'm very new to this, and I'm a little bit stuck on the next thing I want to do
As for now, I'm sure you all know that ''A unit is attacked'' event is highly abusive, and that's where my problem lies.
I'm trying to use this damage / unit indexing to check if the damage has been made, so far it works for one of the imported spells called ''Fatal Bonds'' which was made by one of the users here on Hive, however I have no idea how to actually apply it.
This is my code:
-
Wrath of Nature
-
Events
-
Unit - A unit Is attacked
-
-
Conditions
-
(Unit-type of (Attacking unit)) Equal to |cffff8080Elder Spirit|r
-
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Random integer number between 1 and 100) Less than or equal to 12
-
DamageEvent Equal to 1.00
-
-
Then - Actions
-
Set VariableSet TempPoint = (Position of (Attacking unit))
-
Unit - Create 1 Caster Dummy for (Owner of (Attacking unit)) at TempPoint facing Default building facing degrees
-
Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
-
Unit - Add Wrath of Nature Passive to (Last created unit)
-
Unit - Order (Last created unit) to Neutral Sea Witch - Forked Lightning (Attacked unit)
-
-------- . --------
-
Floating Text - Create floating text that reads |cff80ff80Wrath of ... at TempPoint with Z offset 0.00, using font size 8.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
-
Floating Text - Set the velocity of (Last created floating text) to 80.00 towards 140.00 degrees
-
Floating Text - Change (Last created floating text): Disable permanence
-
Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
-
Floating Text - Change the fading age of (Last created floating text) to 2.00 seconds
-
Custom script: call RemoveLocation(udg_TempPoint)
-
-
Else - Actions
-
-
-
It works without ''DamageEvent Equal to 1.00'' but spamming hold or stop and then attacking will result in abusive scenarios, which I do not prefer.
And then I'm using this
-
Unit Indexer
-
Events
-
Map initialization
-
-
Conditions
-
Actions
-
Custom script: call ExecuteFunc("InitializeUnitIndexer")
-
Custom script: endfunction
-
Custom script:
-
Custom script: function ClearUnitIndex takes nothing returns nothing
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
(Custom value of UDexUnits[UDex]) Equal to 0
-
-
Then - Actions
-
Set VariableSet UnitIndexLock[UDex] = (UnitIndexLock[UDex] - 1)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
UnitIndexLock[UDex] Equal to 0
-
-
Then - Actions
-
Set VariableSet UDexNext[UDexPrev[UDex]] = UDexNext[UDex]
-
Set VariableSet UDexPrev[UDexNext[UDex]] = UDexPrev[UDex]
-
Set VariableSet UDexPrev[UDex] = 0
-
Set VariableSet UnitIndexEvent = 0.00
-
Set VariableSet UnitIndexEvent = 2.00
-
Set VariableSet UnitIndexEvent = 0.00
-
Set VariableSet UDexUnits[UDex] = No unit
-
Set VariableSet UDexNext[UDex] = UDexRecycle
-
Set VariableSet UDexRecycle = UDex
-
-
Else - Actions
-
-
-
Else - Actions
-
-
Custom script: endfunction
-
Custom script:
-
Custom script: function IndexUnit takes nothing returns boolean
-
Custom script: local integer pdex = udg_UDex
-
Custom script: local integer ndex
-
-------- - --------
-
-------- You can customize the following block - if conditions are false the (Matching unit) won't be indexed. --------
-
-------- - --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
UnitIndexerEnabled Equal to True
-
(Custom value of (Matching unit)) Equal to 0
-
-
Then - Actions
-
Set VariableSet UDexWasted = (UDexWasted + 1)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
UDexWasted Equal to 32
-
-
Then - Actions
-
Set VariableSet UDexWasted = 0
-
Set VariableSet UDex = UDexNext[0]
-
Custom script: loop
-
Custom script: exitwhen udg_UDex == 0
-
Custom script: set ndex = udg_UDexNext[udg_UDex]
-
Custom script: call ClearUnitIndex()
-
Custom script: set udg_UDex = ndex
-
Custom script: endloop
-
-
Else - Actions
-
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
UDexRecycle Equal to 0
-
-
Then - Actions
-
Set VariableSet UDex = (UDexGen + 1)
-
Set VariableSet UDexGen = UDex
-
-
Else - Actions
-
Set VariableSet UDex = UDexRecycle
-
Set VariableSet UDexRecycle = UDexNext[UDex]
-
-
-
Set VariableSet UDexUnits[UDex] = (Matching unit)
-
Unit - Set the custom value of UDexUnits[UDex] to UDex
-
Set VariableSet UDexPrev[UDexNext[0]] = UDex
-
Set VariableSet UDexNext[UDex] = UDexNext[0]
-
Set VariableSet UDexNext[0] = UDex
-
Set VariableSet UnitIndexLock[UDex] = 1
-
Set VariableSet UnitIndexEvent = 0.00
-
Set VariableSet UnitIndexEvent = 1.00
-
Set VariableSet UnitIndexEvent = 0.00
-
Custom script: set udg_UDex = pdex
-
-
Else - Actions
-
-
Custom script: return false
-
Custom script: endfunction
-
Custom script:
-
Custom script: function InitializeUnitIndexer takes nothing returns nothing
-
Custom script: local integer i = 16
-
Custom script: local boolexpr b = Filter(function IndexUnit)
-
Custom script: local region re = CreateRegion()
-
Custom script: local trigger t = GetTriggeringTrigger()
-
Custom script: local rect r = GetWorldBounds()
-
Custom script: call RegionAddRect(re, r)
-
Custom script: call TriggerRegisterEnterRegion(t, re, b)
-
Custom script: call TriggerClearActions(t)
-
Custom script: call TriggerAddAction(t, function ClearUnitIndex)
-
Set VariableSet UnitIndexerEnabled = True
-
Custom script: loop
-
Custom script: set i = i - 1
-
Custom script: call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), b)
-
Custom script: exitwhen i == 0
-
Custom script: endloop
-
Custom script: call RemoveRect(r)
-
Custom script: set re = null
-
Custom script: set r = null
-
Custom script: set t = null
-
Custom script: set b = null
-
Set VariableSet UnitIndexEvent = 3.00
-
Set VariableSet UnitIndexEvent = 0.00
-
-
and
-
Damage Engine Config
-
Events
-
Conditions
-
(UDexUnits[UDex] is A structure) Equal to False
-
-
Actions
-
-------- - --------
-
-------- This trigger's conditions let you filter out units you don't want detection for. --------
-
-------- NOTE: By default, units with Locust will not pass the check. --------
-
-------- TIP: The unit is called UDexUnits[UDex] and its custom value is UDex --------
-
-------- - --------
-
-------- Copy the Cheat Death Ability from Object Editor into your map and set the following variable respectively: --------
-
-------- - --------
-
Set VariableSet DamageBlockingAbility = Cheat Death Ability (+500,000)
-
-------- - --------
-
-------- Copy the Detect Spell Damage Ability from Object Editor into your map and set the following variable respectively: --------
-
-------- - --------
-
Set VariableSet SpellDamageAbility = Detect Spell Damage
-
-------- - --------
-
-------- 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 --------
-
-------- - --------
-
Set VariableSet DamageTypeExplosive = -1
-
Set VariableSet DamageTypeCriticalStrike = 1
-
Set VariableSet DamageTypeHeal = 2
-
Set VariableSet DamageTypeReduced = 3
-
Set VariableSet DamageTypeBlocked = 4
-
-------- - --------
-
-------- Leave the next Set statement disabled if you modified the Spell Damage Reduction item ability to 1.67 reduction --------
-
-------- Otherwise, if you removed that ability from Runed Bracers, you'll need to enable this line: --------
-
-------- - --------
-
Set VariableSet DmgEvBracers = Runed Bracers
-
-------- - --------
-
-------- Set the damage multiplication factor (1.00 being unmodified, increasing in damage over 1.00 and at 0 damage with 0.00) --------
-
-------- NOTE. With the default values, Runed Bracers is reduces 33%, Elune's Grace reduces 20% and Ethereal increases 67% --------
-
-------- - --------
-
Set VariableSet DAMAGE_FACTOR_BRACERS = 0.67
-
Set VariableSet DAMAGE_FACTOR_ELUNES = 0.80
-
Set VariableSet DAMAGE_FACTOR_ETHEREAL = 1.67
-
-------- - --------
-
-------- Do not enable any of the following lines as they are simply variable declarations to make copying easier --------
-
-------- - --------
-
Set VariableSet AfterDamageEvent = (DamageEvent + DamageModifierEvent)
-
Set VariableSet ClearDamageEvent = (This trigger)
-
Set VariableSet DamageEventAmount = DamageEventPrevAmt
-
Set VariableSet DamageEventOverride = NextDamageOverride
-
Set VariableSet DamageEventSource = DamageEventTarget
-
Set VariableSet DamageEventTrigger = DmgEvTrig
-
Set VariableSet DamageEventType = (LastDmgPrevType[0] + NextDamageType)
-
Set VariableSet DamageEventsWasted = DmgEvRecursionN
-
Set VariableSet DmgEvRunning = DmgEvStarted
-
Set VariableSet IsDamageSpell = LastDmgWasSpell[0]
-
Set VariableSet LastDamageHP = (Elapsed time for DmgEvTimer)
-
Set VariableSet LastDmgPrevAmount[0] = LastDmgValue[0]
-
Set VariableSet LastDmgSource[0] = LastDmgTarget[0]
-
Set VariableSet HideDamageFrom[0] = False
-
Set VariableSet UnitDamageRegistered[0] = False
-
-
and
JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
// Damage Engine lets you detect, amplify, block or nullify damage. It even
// lets you detect if the damage was physical or from a spell. Just reference
// DamageEventAmount/Source/Target or the boolean IsDamageSpell, to get the
// necessary damage event data.
//
// - Detect damage: use the event "DamageEvent Equal to 1.00"
// - To change damage before it's dealt: use the event "DamageModifierEvent Equal to 1.00"
// - Detect damage after it was applied, use the event "AfterDamageEvent Equal to 1.00"
// - Detect spell damage: use the condition "IsDamageSpell Equal to True"
// - Detect zero-damage: use the event "DamageEvent Equal to 2.00" (an AfterDamageEvent will not fire for this)
//
// You can specify the DamageEventType before dealing triggered damage. To prevent an already-improbable error, I recommend running the trigger "ClearDamageEvent (Checking Conditions)" after dealing triggered damage from within a damage event:
// - Set NextDamageType = DamageTypeWhatever
// - Unit - Cause...
// - Trigger - Run ClearDamageEvent (Checking Conditions)
//
// You can modify the DamageEventAmount and the DamageEventType from a "DamageModifierEvent Equal to 1.00" trigger.
// - If the amount is modified to negative, it will count as a heal.
// - If the amount is set to 0, no damage will be dealt.
//
// If you need to reference the original in-game damage, use the variable "DamageEventPrevAmt".
//
//===========================================================================
// Programming note about "integer i" and "udg_DmgEvRecursionN": integer i
// ranges from -1 upwards. "udg_DmgEvRecursionN" ranges from 0 upwards.
// "integer i" is always 1 less than "udg_DmgEvRecursionN"
//
function DmgEvResetVars takes nothing returns nothing
local integer i = udg_DmgEvRecursionN - 2
set udg_DmgEvRecursionN = i + 1
if i >= 0 then
set udg_DamageEventPrevAmt = udg_LastDmgPrevAmount[i]
set udg_DamageEventAmount = udg_LastDmgValue[i]
set udg_DamageEventSource = udg_LastDmgSource[i]
set udg_DamageEventTarget = udg_LastDmgTarget[i]
set udg_IsDamageSpell = udg_LastDmgWasSpell[i]
set udg_DamageEventType = udg_LastDmgPrevType[i]
endif
endfunction
function CheckDamagedLifeEvent takes boolean clear returns nothing
if clear then
set udg_NextDamageOverride = false
set udg_NextDamageType = 0
endif
if udg_DmgEvTrig != null then
call DestroyTrigger(udg_DmgEvTrig)
set udg_DmgEvTrig = null
if udg_IsDamageSpell then
call SetWidgetLife(udg_DamageEventTarget, RMaxBJ(udg_LastDamageHP, 0.41))
if udg_LastDamageHP <= 0.405 then
if udg_DamageEventType < 0 then
call SetUnitExploded(udg_DamageEventTarget, true)
endif
//Kill the unit
call DisableTrigger(udg_DamageEventTrigger)
call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, -999, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(udg_DamageEventTrigger)
endif
elseif GetUnitAbilityLevel(udg_DamageEventTarget, udg_DamageBlockingAbility) > 0 then
call UnitRemoveAbility(udg_DamageEventTarget, udg_DamageBlockingAbility)
call SetWidgetLife(udg_DamageEventTarget, udg_LastDamageHP)
endif
if udg_DamageEventAmount != 0.00 and not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_AfterDamageEvent = 0.00
set udg_AfterDamageEvent = 1.00
set udg_AfterDamageEvent = 0.00
endif
call DmgEvResetVars()
endif
endfunction
function DmgEvOnExpire takes nothing returns nothing
set udg_DmgEvStarted = false
call CheckDamagedLifeEvent(true)
endfunction
function PreCheckDamagedLifeEvent takes nothing returns boolean
call CheckDamagedLifeEvent(true)
return false
endfunction
function OnUnitDamage takes nothing returns boolean
local boolean override = udg_DamageEventOverride
local integer i = udg_DmgEvRecursionN - 1
local string s
local real prevAmount
local real life
local real prevLife
local unit u
call CheckDamagedLifeEvent(false) //in case the unit state event failed and the 0.00 second timer hasn't yet expired
if i >= 0 then
if i < 16 then
set udg_LastDmgPrevAmount[i]= udg_DamageEventPrevAmt
set udg_LastDmgValue[i] = udg_DamageEventAmount
set udg_LastDmgSource[i] = udg_DamageEventSource
set udg_LastDmgTarget[i] = udg_DamageEventTarget
set udg_LastDmgWasSpell[i] = udg_IsDamageSpell
set udg_LastDmgPrevType[i] = udg_DamageEventType
else
set s = "WARNING: Recursion error when dealing damage! Make sure when you deal damage from within a DamageEvent trigger, do it like this:\n\n"
set s = s + "Trigger - Turn off (This Trigger)\n"
set s = s + "Unit - Cause...\n"
set s = s + "Trigger - Turn on (This Trigger)"
//Delete the next couple of lines to disable the in-game recursion crash warnings
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 999.00, s)
return false
endif
endif
set udg_DmgEvRecursionN = i + 2
set u = GetTriggerUnit()
set prevAmount = GetEventDamage()
set udg_DamageEventSource = GetEventDamageSource()
set udg_DamageEventAmount = prevAmount
set udg_DamageEventTarget = u
set udg_DamageEventType = udg_NextDamageType
set udg_NextDamageType = 0
set udg_DamageEventOverride = udg_NextDamageOverride
set udg_NextDamageOverride = false
if prevAmount == 0.00 then
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEventPrevAmt = 0.00
set udg_DamageEvent = 0.00
set udg_DamageEvent = 2.00
set udg_DamageEvent = 0.00
endif
call DmgEvResetVars()
else
if not udg_DmgEvStarted then
set udg_DmgEvStarted = true
call TimerStart(udg_DmgEvTimer, 0.00, false, function DmgEvOnExpire)
endif
set udg_IsDamageSpell = prevAmount < 0.00
if udg_IsDamageSpell then
set prevAmount = -udg_DamageEventAmount
set life = 1.00
if IsUnitType(u, UNIT_TYPE_ETHEREAL) and not IsUnitType(u, UNIT_TYPE_HERO) then
set life = life*udg_DAMAGE_FACTOR_ETHEREAL //1.67
endif
if GetUnitAbilityLevel(u, 'Aegr') > 0 then
set life = life*udg_DAMAGE_FACTOR_ELUNES //0.80
endif
if udg_DmgEvBracers != 0 and IsUnitType(u, UNIT_TYPE_HERO) then
//Inline of UnitHasItemOfTypeBJ without the potential handle ID leak.
set i = 6
loop
set i = i - 1
if GetItemTypeId(UnitItemInSlot(u, i)) == udg_DmgEvBracers then
set life = life*udg_DAMAGE_FACTOR_BRACERS //0.67
exitwhen true
endif
exitwhen i == 0
endloop
endif
set udg_DamageEventAmount = prevAmount*life
endif
set udg_DamageEventPrevAmt = prevAmount
set udg_DamageModifierEvent = 0.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 1.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 2.00
set udg_DamageModifierEvent = 3.00
endif
endif
set udg_DamageEventOverride = override
if udg_DamageEventAmount > 0.00 then
set udg_DamageModifierEvent = 4.00
endif
set udg_DamageModifierEvent = 0.00
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEvent = 0.00
set udg_DamageEvent = 1.00
set udg_DamageEvent = 0.00
endif
call CheckDamagedLifeEvent(true) //in case the unit state event failed from a recursive damage event
//All events have run and the damage amount is finalized.
set life = GetWidgetLife(u)
set udg_DmgEvTrig = CreateTrigger()
call TriggerAddCondition(udg_DmgEvTrig, Filter(function PreCheckDamagedLifeEvent))
if not udg_IsDamageSpell then
if udg_DamageEventAmount != prevAmount then
set life = life + prevAmount - udg_DamageEventAmount
if GetUnitState(u, UNIT_STATE_MAX_LIFE) < life then
set udg_LastDamageHP = life - prevAmount
call UnitAddAbility(u, udg_DamageBlockingAbility)
endif
call SetWidgetLife(u, RMaxBJ(life, 0.42))
endif
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, LESS_THAN, RMaxBJ(0.41, life - prevAmount/2.00))
else
set udg_LastDamageHP = GetUnitState(u, UNIT_STATE_MAX_LIFE)
set prevLife = life
if life + prevAmount*0.75 > udg_LastDamageHP then
set life = RMaxBJ(udg_LastDamageHP - prevAmount/2.00, 1.00)
call SetWidgetLife(u, life)
set life = (life + udg_LastDamageHP)/2.00
else
set life = life + prevAmount*0.50
endif
set udg_LastDamageHP = prevLife - (prevAmount - (prevAmount - udg_DamageEventAmount))
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, GREATER_THAN, life)
endif
set u = null
endif
return false
endfunction
function CreateDmgEvTrg takes nothing returns nothing
set udg_DamageEventTrigger = CreateTrigger()
call TriggerAddCondition(udg_DamageEventTrigger, Filter(function OnUnitDamage))
endfunction
function SetupDmgEv takes nothing returns boolean
local integer i = udg_UDex
local unit u
if udg_UnitIndexEvent == 1.00 then
set u = udg_UDexUnits[i]
if GetUnitAbilityLevel(u, 'Aloc') == 0 and TriggerEvaluate(gg_trg_Damage_Engine_Config) then
set udg_UnitDamageRegistered[i] = true
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, u, EVENT_UNIT_DAMAGED)
call UnitAddAbility(u, udg_SpellDamageAbility)
call UnitMakeAbilityPermanent(u, true, udg_SpellDamageAbility)
endif
set u = null
else
set udg_HideDamageFrom[i] = false
if udg_UnitDamageRegistered[i] then
set udg_UnitDamageRegistered[i] = false
set udg_DamageEventsWasted = udg_DamageEventsWasted + 1
if udg_DamageEventsWasted == 32 then //After 32 registered units have been removed...
set udg_DamageEventsWasted = 0
//Rebuild the mass EVENT_UNIT_DAMAGED trigger:
call DestroyTrigger(udg_DamageEventTrigger)
call CreateDmgEvTrg()
set i = udg_UDexNext[0]
loop
exitwhen i == 0
if udg_UnitDamageRegistered[i] then
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, udg_UDexUnits[i], EVENT_UNIT_DAMAGED)
endif
set i = udg_UDexNext[i]
endloop
endif
endif
endif
return false
endfunction
//===========================================================================
function InitTrig_Damage_Engine takes nothing returns nothing
local unit u = CreateUnit(Player(15), 'uloc', 0, 0, 0)
local integer i = 16
//Create this trigger with UnitIndexEvents in order add and remove units
//as they are created or removed.
local trigger t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
call TriggerAddCondition(t, Filter(function SetupDmgEv))
set t = null
//Run the configuration trigger to set all configurables:
if gg_trg_Damage_Engine_Config == null then
//It's possible this InitTrig_ function ran first, in which case use ExecuteFunc.
call ExecuteFunc("Trig_Damage_Engine_Config_Actions")
else
call TriggerExecute(gg_trg_Damage_Engine_Config)
endif
//Create trigger for storing all EVENT_UNIT_DAMAGED events.
call CreateDmgEvTrg()
//Create GUI-friendly trigger for cleaning up after UnitDamageTarget.
set udg_ClearDamageEvent = CreateTrigger()
call TriggerAddCondition(udg_ClearDamageEvent, Filter(function PreCheckDamagedLifeEvent))
//Disable SpellDamageAbility for every player.
loop
set i = i - 1
call SetPlayerAbilityAvailable(Player(i), udg_SpellDamageAbility, false)
exitwhen i == 0
endloop
//Preload abilities.
call UnitAddAbility(u, udg_DamageBlockingAbility)
call UnitAddAbility(u, udg_SpellDamageAbility)
call RemoveUnit(u)
set u = null
endfunction
and it says in the ''Damage Engine Trigger'' that all I have to do is use ''DamageEvent Equal to 1.00'' so that's what I've implemented in my trigger, but after trying it few times the spell never actually gets triggered.
Any ideas why?
Thanks, as usual!
Last edited by a moderator: