- Joined
- Feb 18, 2008
- Messages
- 69

v1.4

v1.4 - 5.19.2010- Fixed an issue when GetMostDamagePlayer function was returning wrong player
v1.3 - 5.15.2010- Minor edit
v1.2 - 5.15.2010- Removed some unnecessary nulling
- Changed name of the library
- Changed names of functions
v1.1 - 5.15.2010- Fixed an issue when system was creating unnecessary links, when damaged by same player more times
- Fixed an issue when system was counting more percent when the unit was damaged for more than actual hit points
- Both system structs privatized
v1.0 - 5.14.2010- First release

This damage counting will never fail, it won't fail when target is healed nor when target's maximum hp has been changed. It's great for preventing kill stealing in AoS games, but also for many other purposes.
Here's explanation how the system works.
Here's explanation how the system works.



- Make new trigger.
- Rename it to Precise Damage Counter or whatever you want.
- Edit -> Convert to custom text.
- Replace the whole trigger with the code.

JASS:
// |===========================================================================================|
// |*******************************************************************************************|
// |***** PRECISE DAMAGE COUNTER *****|
// |*** ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ****|
// |** by Furby ***|
// |***** v1.4 *****|
// |*******************************************************************************************|
// | - Requirements - |
// | AIDS |
// | Damage |
// |*******************************************************************************************|
// | - Functions - |
/* | PDC_GetDamagePercentUnit takes unit whatUnit, player whatPlayer returns real |*/
// | - returns damage done to the unit in percent |
/* PDC_GetMostDamagePlayer takes unit whatUnit returns player |*/
// | - returns player who done the most damage to unit |
// |*******************************************************************************************|
// | more info at thehelper.net |
// |===========================================================================================|
library PDC requires AIDS, Damage
// If this function will return true, unit will be counted as valid
private function ValidUnit takes unit u returns boolean
return true
endfunction
// If this function will return true, damage will be counted as valid
// uses the usual damage event responses
private function ValidDamage takes nothing returns boolean
return true
endfunction
// = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// DO NOT TOUCH BELOW UNLESS YOU KNOW WHAT'RE YOU DOING!
// = = = = = = = = = = = = = = = = = = = = = = = = = = = =
private struct DamageCount
real percent
player who
thistype next
private method onDestroy takes nothing returns nothing
set percent = 0.0
set who = null
endmethod
endstruct
private struct VictimUnit extends array
//! runtextmacro AIDS()
real done
DamageCount first
DamageCount last
private static method AIDS_filter takes unit u returns boolean
return ValidUnit(u)
endmethod
private method AIDS_onDestroy takes nothing returns nothing
local DamageCount dc = first
loop
call dc.destroy()
exitwhen(dc.next == dc or dc == 0)
set dc = dc.next
endloop
endmethod
private method AIDS_onCreate takes nothing returns nothing
set done = 0.0
endmethod
private static method onDamage takes nothing returns nothing
local unit u = GetTriggerUnit()
local thistype this = VictimUnit[u]
local real dmgPercent = 100.0 * (GetEventDamage() / GetUnitState(u, UNIT_STATE_MAX_LIFE))
local player p = GetOwningPlayer(GetEventDamageSource())
local real over = dmgPercent - (100 - done)
local DamageCount dc = 0
local DamageCount temp = 0
if GetEventDamage() > GetWidgetLife(u) then
set dmgPercent = 100.0 * (GetWidgetLife(u) / GetUnitState(u, UNIT_STATE_MAX_LIFE))
set over = dmgPercent - (100 - done)
endif
if over > 0 then
set dc = first
loop
exitwhen(over <= 0.0 or dc == 0)
if dc.percent - over > 0.0 then
set dc.percent = dc.percent - over
set over = 0.0
else
set over = over - dc.percent
set temp = dc
if dc.next > 0 then
set dc = dc.next
endif
call temp.destroy()
endif
endloop
if dc > 0 then
set first = dc
endif
if last.who == p then
set dc = last
else
set dc = DamageCount.create()
set dc.next = dc
set last.next = dc
set last = dc
endif
else
if first > 0 then
if last.who == p then
set dc = last
else
set dc = DamageCount.create()
set last.next = dc
set dc.next = dc
set last = dc
endif
else
set dc = DamageCount.create()
set first = dc
set dc.next = dc
set last = dc
endif
endif
set dc.percent = dc.percent + dmgPercent
set dc.who = p
set done = done + dmgPercent
set u = null
endmethod
private static method AIDS_onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call Damage_RegisterEvent(t)
call TriggerAddCondition(t, Condition(function ValidDamage))
call TriggerAddAction(t, function thistype.onDamage)
endmethod
endstruct
public function GetDamagePercentUnit takes unit whatUnit, player whatPlayer returns real
local DamageCount dc = VictimUnit[whatUnit].first
local real total = 0
loop
if dc.who == whatPlayer then
set total = total + dc.percent
endif
exitwhen(dc.next == dc or dc == 0)
set dc = dc.next
endloop
return total
endfunction
public function GetMostDamagePlayer takes unit whatUnit returns player
local real temp = 0
local player result = null
local integer i = 0
loop
exitwhen(i>15)
if GetDamagePercentUnit(whatUnit, Player(i)) > temp then
set result = Player(i)
set temp = GetDamagePercentUnit(whatUnit, Player(i))
endif
set i = i + 1
endloop
return result
endfunction
endlibrary

- What does this do?
- It counts percent of damage done to any unit on the map by all players. - Why would I need that?
- If you use anything related to bounty, this should help you. - Why not just count damage done and then calculate percent when unit dies?
- That would count healed units two times. - Hmm.
- Aha? - I will use it for my map.
- Ok? That's why it's here. - Do you want some credits?
- Sure, why not. - I need to edit it to fit my map!
- Go ahead, I don't care. - I don't understand vJass
- So?
Attachments
Last edited: