• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

GetUnitArmorType v8

  • Like
Reactions: Losam and Ofel
code:

JASS:
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


Keywords:
get ,unit ,armor ,type, reduction ,what, armor unit ,has ,noob, lol
Contents

GetUnitArmorType v5 (Map)

Reviews
02:37, 3rd Nov 2012 Magtheridon96: Approved.
Level 31
Joined
Jul 10, 2007
Messages
6,306
Use constants for the armor type and do an ArmorType struct with those constants in them, then return one of those constants.

edit
cache armor types with a table. No need to redo those huge calculations over and over again. Assume that unit types will generally be repeated in a given map.

edit
this should be a constant

private integer gua_hpbonus = 'rofl'

edit
as mag stated, your indentation is terrible, lol
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
put your code into editor

hit CTRL + A
mass hit SHIFT + TAB

every time a block opens, hit TAB
every time a block closes, tab back (backspace)

like so
JASS:
globals //start of block
    integer i //inside of block
    integer b //inside of block
endglobals // end of block

if () then //start of block
    if () then //start of block
         integer i //in block
    endif //end of block
endif //end of block

/*
*    comment title (possibly function?)
*
*        comment description (o-o)
*/

for more on comment headers
http://www.hiveworkshop.com/forums/jass-resources-412/repo-comment-headers-192184/
 
Top