Moderator
M
Moderator
02:37, 3rd Nov 2012
Magtheridon96: Approved.
Magtheridon96: Approved.
library GetUnitArmorType requires Ln /* v8
******************************************************************************************************************************************************************************************************************
*
* An armor detection system which returns a unit's armor amount, damage reduction (%), and the unit's armor type
* the origina system made by Daelin does not get the armor type and uses a slower logorithm. With this system you can get
* all of the mentioned by calling 3 different functions.
*
******************************************************************************************************************************************************************************************************************
* Credits:
* -------------------
* BLINKBOY: NaturalLogarithm
*
* DAELIN : ORIGINAL armor utils
*
* RISING_DUSK: Modified Armor Utils
*
******************************************************************************************************************************************************************************************************************
*
* Requires:
* ---------------
* NaturalLogarithm - hiveworkshop.com/forums/jass-resources-412/snippet-natural-logarithm-108059/
*
*
******************************************************************************************************************************************************************************************************************
*
*
* SETTINGS
*
*/
globals
private constant real ARMORDAMAGE = 1000 // amount of damage used to get armor
private constant real ARM = 0.06 // armor reduction multiplyer
public constant real ARMOR_INVULNERABLE = 999999999
private constant attacktype DMG2 = ATTACK_TYPE_PIERCE //attack used to get the armor amount
private constant attacktype DMG1 = ATTACK_TYPE_CHAOS //attack used to get the armor type
private constant real ACCURACY_FACTOR = 0.997
private constant integer GUA_HP_BONUS = 'rofl' //hp bonus ability copy it or make your own
endglobals
/*
*******************************************************************************************************************************************************************************************************************
* Functions:
*
* function GetUnitArmorValue takes unit u returns real
* - returns the amount of your unit's armor with up to 3 decimal figures
*
* function GetUnitArmorReduction takes unit u returns real
* - returns the % damage reduction your unit has to verify this check the damage reduction text in the armor tooltip, this system does not round the values so it the armor tooltip says 16% the system might have 0.157% *
*
* function GetUnitArmorType takes unit u returns integer
* - returns the type (an integer value) of armor your unit has. Refer to example trigger b for more info.
*
*******************************************************************************************************************************************************************************************************************
*/
function GetUnitArmorValue takes unit u returns real
local real life = GetWidgetLife(u)
local real life2 = life
local real calc = 0.
if not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0 then
if GetUnitState(u, UNIT_STATE_MAX_LIFE) <= ARMORDAMAGE then
call UnitAddAbility(u, GUA_HP_BONUS)
endif
if life <= ARMORDAMAGE - (ARMORDAMAGE * 0.20) then
call SetWidgetLife(u, ARMORDAMAGE + (ARMORDAMAGE * 0.50) )
endif
endif
set life2 = GetWidgetLife(u)
call UnitDamageTarget(u, u, ARMORDAMAGE, false, false, DMG1, DAMAGE_TYPE_NORMAL, null)
set calc = (ARMORDAMAGE - life2 + GetWidgetLife(u)) / ARMORDAMAGE
call UnitRemoveAbility(u, GUA_HP_BONUS)
call SetWidgetLife(u, life)
if calc >= 1. then
return ARMOR_INVULNERABLE
elseif calc < 0. then
return - 1 * logarithm(calc + 1.) / -0.061875
else
return calc / (ARM * (1. - calc))
endif
return 0.
endfunction
function GetUnitArmorReduction takes unit u returns real
local real armorAmount = GetUnitArmorValue(u)
if armorAmount > 0 then
return ((armorAmount) * ARM) / (1 + ARM * (armorAmount))
endif
return 1 - 2 + Pow(0.94, -armorAmount)
endfunction
function GetUnitArmorType takes unit u returns integer
local integer loopz1 = 0
local real reduc = 1
local real array expected
local real life = GetWidgetLife(u)
local real lifeMAX = life
local real reduction = GetUnitArmorReduction(u)
local real damage
local real accurasy = ACCURACY_FACTOR
local real dmgForThisTrigger = ((ARMORDAMAGE / 100) - ((ARMORDAMAGE / 100) * reduction) ) * ARMORDAMAGE
local real accuracy
local real accuracy2
/*
*higher armor values require higher accuracy due to the decrease in damage, lower armor especially armor which
*amplifies requires less accuracy
*/
if reduction > .90 then
set accurasy = 0.999
set accuracy = dmgForThisTrigger - (dmgForThisTrigger * accurasy)
elseif reduction <= -0.10 then
set accurasy = 0.990
set accuracy = dmgForThisTrigger - (dmgForThisTrigger * accurasy)
elseif reduction >= 0 and reduction <= .90 then
set accuracy = dmgForThisTrigger - (dmgForThisTrigger * ACCURACY_FACTOR)
endif
set accuracy2 = -(accuracy)
if reduction >= 0 then
loop
exitwhen loopz1 > 8
set loopz1 = loopz1 + 1
set expected[loopz1] = (dmgForThisTrigger - (dmgForThisTrigger * reduction)) * reduc
set reduc = reduc - 0.10
endloop
else
set loopz1 = 0
set reduc = 1.0
loop
exitwhen loopz1 > 8
set loopz1 = loopz1 + 1
set expected[loopz1] = ((dmgForThisTrigger + (dmgForThisTrigger * -reduction)) * reduc)
set reduc = reduc - 0.10
endloop
endif
if not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0 then
if GetUnitState(u, UNIT_STATE_MAX_LIFE) <= dmgForThisTrigger then
call UnitAddAbility(u, GUA_HP_BONUS)
set life = GetWidgetLife(u)
endif
if GetWidgetLife(u) <= dmgForThisTrigger - (dmgForThisTrigger * 0.20) then
call SetWidgetLife(u, dmgForThisTrigger + (dmgForThisTrigger * 0.50) )
endif
endif
set life = GetWidgetLife(u)
call UnitDamageTarget(u, u, dmgForThisTrigger, false, false, DMG2, DAMAGE_TYPE_NORMAL, null)
set damage = life - GetWidgetLife(u)
call UnitRemoveAbility(u, GUA_HP_BONUS)
call SetWidgetLife(u, lifeMAX)
set loopz1 = 0
loop
exitwhen loopz1 > 8
if damage - expected[loopz1] <= accuracy and damage - expected[loopz1] >= accuracy2 then
return loopz1
endif
set loopz1 = loopz1 + 1
endloop
return 0
endfunction
endlibrary