- Joined
- Jul 10, 2007
- Messages
- 6,306
important note
Due to a horrible warcraft 3 bug, artillery units running on this system can't be ordered to attack ground or wacraft 3 will instantly crash
->http://forums.battle.net/thread.html?topicId=27807930612&sid=3000
It is impossible to remove the artillery command from an artillery unit, so players need to be warned about this. It's impossible to stop the bug. It is all up to Blizzard to fix it.
Also, units with bouncing attacks will not attack due to yet another wc3 bug.
As this uses ice abilities like frost attack and frozen breath and they don't stack, maps with those types of abilities will not work with this.
Also, wc3 doesn't correctly remove ice/frost buffs, meaning that even when the ability is removed, if a unit was hit enough times, that unit will permanently be frozen >.>.
The wc3 engine is just a major failure. This resource counts on wc3 working correctly, which it does not.
end important note
An extension to DamageEvent that allows one to retrieve the type of damage dealt (Physical, Spell, or JASS).
Physical damage is a result of melee/ranged attacks from a unit
Spell damage is a result of an ability, aura, buff, and etc
JASS is a result of damage inflicted by code
Also allows you to use SetWidgetLife to deal direct damage without screwing up bounty
Can retrieve all damage dealt as well as the original amount (in case you want to deal damage based on %)
Must use properties within the system to retrieve unit life and unit max life (unit life can actually be negative in this) (accurate)
Can retrieve buffs from attacks on damage (buffs normally applied after damage, so this is a plus)
Coupled with DamageEvent because that's the way it has to be done to be accurate.
LUA_DUMMY_PHYSICAL_ABILITY
LUA_FILE_HEADER
Installation Script
Library
Due to a horrible warcraft 3 bug, artillery units running on this system can't be ordered to attack ground or wacraft 3 will instantly crash
->http://forums.battle.net/thread.html?topicId=27807930612&sid=3000
It is impossible to remove the artillery command from an artillery unit, so players need to be warned about this. It's impossible to stop the bug. It is all up to Blizzard to fix it.
Also, units with bouncing attacks will not attack due to yet another wc3 bug.
As this uses ice abilities like frost attack and frozen breath and they don't stack, maps with those types of abilities will not work with this.
Also, wc3 doesn't correctly remove ice/frost buffs, meaning that even when the ability is removed, if a unit was hit enough times, that unit will permanently be frozen >.>.
The wc3 engine is just a major failure. This resource counts on wc3 working correctly, which it does not.
end important note
An extension to DamageEvent that allows one to retrieve the type of damage dealt (Physical, Spell, or JASS).
Physical damage is a result of melee/ranged attacks from a unit
Spell damage is a result of an ability, aura, buff, and etc
JASS is a result of damage inflicted by code
Also allows you to use SetWidgetLife to deal direct damage without screwing up bounty
Can retrieve all damage dealt as well as the original amount (in case you want to deal damage based on %)
Must use properties within the system to retrieve unit life and unit max life (unit life can actually be negative in this) (accurate)
Can retrieve buffs from attacks on damage (buffs normally applied after damage, so this is a plus)
Coupled with DamageEvent because that's the way it has to be done to be accurate.
LUA_DUMMY_PHYSICAL_ABILITY
LUA_FILE_HEADER
Installation Script
JASS:
//! externalblock extension=lua ObjectMerger $FILENAME$
//! runtextmacro LUA_FILE_HEADER()
//! i dofile("DummyPhysicalAbility")
//! i local object = getdummyphysicalability("ADV_DAMAGE_EVENT", 1, false)
//! i writejass("AdvDamageEvent_GLOBALS",
//! i [[//! textmacro ADV_DAMAGE_EVENT_EXT_GLOB_1
//! i globals
//! i private constant integer DUMMY_ABILITY=']] .. object.ability .. [['
//! i private constant integer DUMMY_ABILITY_2=']] .. object.ability2 .. [['
//! i private constant integer DUMMY_BUFF=']] .. object.buffs[1] .. [['
//! i endglobals
//! i //! endtextmacro]])
//! i local saveBuff = getvarobject("AIlf", "abilities", "ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY", true)
//! i createobject("AIlf", saveBuff)
//! i makechange(current, "Ilif", "1", "500000")
//! i makechange(current, "ahdu", "1", "1")
//! i makechange(current, "adur", "1", "1")
//! i local playerDamage = getvarobject("AIlf", "abilities", "ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY", true)
//! i updateobjects()
//! endexternalblock
Library
JASS:
library AdvDamageEvent uses /*
*/DamageEvent, /* Version: 2.1.0.5
hiveworkshop.com/forums/submissions-414/snippet-damageevent-186829/
*/
//Version 4.0.1.0
//static constant Event PHYSICAL
//static constant Event SPELL
//static constant Event JASS
//readonly static integer type
//readonly static real unitLife
//readonly static real totalDamage
//readonly static real unitMaxLife
//static method fireSpell takes unit source, unit target, real damage returns nothing
//static method firePhysical takes unit whichUnit, unit target, real amount, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
//static method fireJASS takes unit whichUnit, unit target, real amount, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
//! textmacro DAMAGE_EVENT_ADV_EXT_0
globals
private integer array hooked
private integer array damageType
private boolean array ec
private integer array es
private integer ls = 0
endglobals
//! endtextmacro
//! textmacro DAMAGE_EVENT_ADV_EXT_1
private function H takes unit u returns nothing
local integer i
if (DamageEvent.enabled and DamageEvent.overType == 0) then
set i = GetUnitUserData(u)
set hooked[i] = hooked[i] + 1
endif
endfunction
private function HDP takes unit u, real d, real r, real x, real y, real a, boolean a2, boolean r2, attacktype a3, damagetype d2, weapontype w returns nothing
call H(u)
endfunction
private function HDT takes unit u, widget t, real a, boolean a2, boolean r, attacktype a3, damagetype d, weapontype w returns nothing
call H(u)
endfunction
private function HPL takes unit u, real d, real r, location l, real a, attacktype w, damagetype w2 returns nothing
call H(u)
endfunction
private function HTB takes unit u, unit t, real a, attacktype w, damagetype w2 returns nothing
call H(u)
endfunction
hook UnitDamagePoint HDP
hook UnitDamageTarget HDT
hook UnitDamagePointLoc HPL
hook UnitDamageTargetBJ HTB
//! endtextmacro
//! textmacro DAMAGE_EVENT_ADV_EXT_2
readonly static Event PHYSICAL = 0
readonly static Event SPELL = 0
readonly static Event JASS = 0
readonly static integer type = 0
private static timer eventTimer = CreateTimer()
private static integer array saved
private static integer array eventSourceId
private static integer array eventTargetId
private static integer array eventType
private static real array eventDamage
private static integer eventCount = 0
private static integer array eventBuffer
private static integer eventBufferCount = 0
private static real prevLife = 0
private static boolean ran = false
readonly static integer overType = 0
static method operator unitMaxLife takes nothing returns real
return GetUnitState(GetUnitById(targetId), UNIT_STATE_MAX_LIFE)-500000
endmethod
static method operator unitLife takes nothing returns real
return GetWidgetLife(GetUnitById(targetId))-500000
endmethod
static method operator totalDamage takes nothing returns real
return prevLife-(GetWidgetLife(GetUnitById(targetId))-500000)
endmethod
static method fireSpell takes unit source, unit target, real damage returns nothing
set overType = SPELL
call UnitDamageTarget(source, target, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
endmethod
static method firePhysical takes unit whichUnit, unit target, real amount, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
set overType = PHYSICAL
call UnitDamageTarget(whichUnit, target, amount, true, ranged, attackType, damageType, weaponType)
endmethod
static method fireJASS takes unit whichUnit, unit target, real amount, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
set overType = JASS
call UnitDamageTarget(whichUnit, target, amount, false, ranged, attackType, damageType, weaponType)
endmethod
private static method handleEvent takes nothing returns nothing
local UnitIndex prev = sourceId
local UnitIndex prev2 = targetId
local real prev3 = amount
local integer prev4 = type
local integer curEvent = 0
local real life
local real prev5 = prevLife
local boolean explode = false
local integer maxEvent = eventBufferCount
local integer i
set ran = true
loop
set curEvent = curEvent + 1
set i = eventBuffer[curEvent]
set sourceId = eventSourceId[i]
set targetId = eventTargetId[i]
set amount = eventDamage[i]
set type = eventType[i]
set ec[sourceId] = false
set es[sourceId] = 0
set prevLife = GetWidgetLife(target)-500000+amount
if (type == 0) then
if (GetUnitAbilityLevel(target, DUMMY_BUFF) > 0) then
set type = PHYSICAL
set explode = true
else
set type = SPELL
set explode = false
endif
else
set explode = false
endif
if (type == PHYSICAL) then
call UnitRemoveAbility(target, DUMMY_BUFF)
endif
call ANY.fire()
call Event(type).fire()
call sourceId.unlock()
call targetId.unlock()
set life = GetWidgetLife(target)-500000
set saved[targetId] = saved[targetId] - 1
if (life < .405) then
call SetUnitExploded(target, explode)
set saved[targetId] = 0
call disable()
call SetWidgetLife(target, .5)
call UnitDamageTarget(GetUnitById(sourceId), GetUnitById(targetId), 10000, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
call enable()
elseif (saved[targetId] == 0) then
call SetWidgetLife(target, GetUnitState(target, UNIT_STATE_MAX_LIFE))
call UnitRemoveAbility(GetUnitById(targetId), ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY)
call SetWidgetLife(target, life)
endif
exitwhen curEvent == maxEvent
endloop
set ran = false
set eventBufferCount = 0
set sourceId = prev
set targetId = prev2
set amount = prev3
set type = prev4
set prevLife = prev5
set ls = 0
if (eventCount != i) then
loop
set i = i + 1
set eventBufferCount = eventBufferCount + 1
set eventBuffer[eventBufferCount] = i
exitwhen i == eventCount
endloop
else
set eventCount = 0
endif
endmethod
//! endtextmacro
//! textmacro DAMAGE_EVENT_ADV_EXT_4
if (GetWidgetLife(GetUnitById(targetId)) >= .405) then
if (GetUnitAbilityLevel(GetUnitById(targetId), DUMMY_BUFF) > 0) then
//was a physical attack
if (ec[eventCount]) then
//initial splash (runs through w/ only splash abils on splash attack)
loop
set eventType[i] = PHYSICAL
set es[i] = 0
set i = i - 1
exitwhen not ec[i] or es[i] != sourceId
set ec[i] = false
endloop
else
//not splash (doesn't run w/ splash abil no non splash attack)
set eventCount = eventCount + 1
set eventType[eventCount] = PHYSICAL
set update = true
endif
elseif (ls == sourceId and eventType[eventCount] == PHYSICAL) then
//this will only run with non-splash abil and splash abil on splash attack
//first the 0 dmg runs, then the actual damage runs, alternates
if (ec[eventCount]) then
set ec[eventCount] = false
else
set eventCount = eventCount + 1
set eventType[eventCount] = PHYSICAL
set ec[eventCount] = true
set update = true
endif
elseif (hooked[sourceId] > 0) then
//JASS attack
set hooked[sourceId] = hooked[sourceId] - 1
set eventCount = eventCount + 1
set eventType[eventCount] = JASS
set update = true
elseif (overType != 0) then
//known attack
set eventCount = eventCount + 1
set eventType[eventCount] = overType
set overType = 0
set update = true
else
//unknown attack
//will initially run for all splash attacks
//artillery attacks won't be known until after timer
set eventCount = eventCount + 1
set eventType[eventCount] = 0
set update = true
set ec[eventCount] = true
set es[eventCount] = sourceId
endif
//for chaining attacks together, last source = current source
set ls = sourceId
//if update (didn't skip), then add to timer stack
if (update) then
set eventSourceId[eventCount] = sourceId
set eventTargetId[eventCount] = targetId
set eventDamage[eventCount] = amount
call sourceId.lock()
call targetId.lock()
if (not ran) then
set eventBufferCount = eventBufferCount + 1
set eventBuffer[eventBufferCount] = eventCount
endif
//if haven't saved the unit, add life abil to save it
if (saved[targetId] == 0) then
set life = GetWidgetLife(GetUnitById(targetId))
call UnitAddAbility(GetUnitById(targetId), ADV_DAMAGE_EVENT_SAVE_UNIT_ABILITY)
call SetWidgetLife(GetUnitById(targetId), life+500000)
endif
//always increase the save count so life ability is removed at right time
set saved[targetId] = saved[targetId] + 1
//start the timer to actually handle (only needed because of artillery attacks)
//artillery attacks are *never* known until after timer
call TimerStart(eventTimer, 0, false, function thistype.handleEvent)
endif
endif
//! endtextmacro
//! textmacro DAMAGE_EVENT_ADV_EXT_6
call UnitAddAbility(GetIndexedUnit(), DUMMY_ABILITY)
call UnitMakeAbilityPermanent(GetIndexedUnit(), true, DUMMY_ABILITY)
call UnitAddAbility(GetIndexedUnit(), DUMMY_ABILITY_2)
call UnitMakeAbilityPermanent(GetIndexedUnit(), true, DUMMY_ABILITY_2)
//! endtextmacro
//! textmacro DAMAGE_EVENT_ADV_EXT_7
set PHYSICAL = CreateEvent()
set SPELL = CreateEvent()
set JASS = CreateEvent()
//! endtextmacro
endlibrary
Last edited: