• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

TasUnitBonus

Introduction


TasUnitBonus is a unit Stat Lua system for Warcraft 3 V1.31 or higher, also can be used by GUI.
It gives an one way api to inc/dec unit stats, the types of stats is "easy" expandable. Includes addons to handle bonus over Buffs, Items, LevelUps, Learning Skills & Skill-Fields.

To increase a stat of an unit using TasUnitBonus you would run TasUnitBonus(unit, key, value) key is one of the supported keys of TasUnitBonus. As said before you can add own custom keys/stats pretty easy, checkout the examples at the bottom.

The main System contains prebuilt warcraft 3 stats, the stats prebuilt only use code no ability-features -> no object Editor setup required.
Life -- max life + heal
Mana
MaxLife --no heal
MaxMana
LifeReg
ManaReg
Armor
Attack
AttackM -- only Melee
AttackR -- only Ranged
AttackSpeed
AttackSpeedM
AttackSpeedR
AttackRange -- (Not V1.31.1)
AttackRangeR -- (Not V1.31.1) only Ranged
MoveSpeed
Agi
Str
Int
Primary
StrAgiInt
CastPoint
CastBackswing
TurnSpeed
UnitLevel
HeroLevel
EXP -- hero EXP
Ability
Ability2 Ability3 Ability4
AbilityInc
AbilityInc2 AbilityInc3 AbilityInc4
Spell -- like Ability but keeps cooldown when lost & regained by this key (in Warcraft 3 V1.31.1 spell is silenced)
Spell2 Spell3 Spell4
Tech
Tech2 Tech3 Tech4
AggroRange --same as AcquireRange
AcquireRange


Add 10 Primary Hero Stat (white numbers) TasUnitBonus(unit, "Primary", 10)
Bonus Strenght is an ability feature for such is the TasUnitBonusSkill addon, can require custom abilities and object Editor setup.

The Addons:
TasUnitBonusSkill handles & adds TasUnitBonus-Keys that require abilities to be given like bonus str, bonus def, bonus attack, evasion, default crit and such in the default all Keys of this Section end with + like "STR+".
TasUnitBonusItem gives TasUnitBonus on pick/drop items has unit-events. You can define data-Lua-tables for specific items and of items with a given rawCode.
TasUnitBonusHero give TasUnitBonus on Levelups for any hero, that hero and Heroes of class x, Has unit-events.
TasUnitBonusBuff attach a TasUnitBonus to a Warcraft 3 BuffCode. You need to tell the types of bonuses once and then when the buff is gained by an unit tell how much of each stat.
TasUnitBonusBuffTable kinda like TasUnitBonusBuff but use bonusTables instead of multiargs
TasUnitBonusLearn give TasUnitBonus when Learning a Skill over warcraft 3 Hero Learn ui, can be called from the outside in case you heroes gain skills in a other way, Has unit-events.
TasUnitBonusEquipment give TasUnitBonus while items are inside a custom Inventory + that custom inventory.
TasUnitBonusItemTooltip addon for TasUnitBonusItem/TasUnitBonusEquipment update tooltips to display TasUnitBonus gained by items.
TasUnitBonusSuperHero adds BonusKeys that alter the gameplay very much like %Bonus to Spell dmg, %Heal for spells, scale HP/ATK of summons ...

How to install


Option Seperated
Requiers Warcraft 3 1.31+ or higher
  • Copy the TasUnitBonus Script/Folder (trigger Editor).
  • Or Copy the TasUnitBonus code from this post in your map, probably the addons aswell.
  • Without Total Init run InitTasUnitBonusHero() & InitTasUnitBonusItem() & InitTasUnitBonusLearn() & InitTasUnitBonusEquipment() inside a mapInit/function main action to create events.
  • if you want to use TasUnitBonusEquipment then you need the fdf&TOC (map imported files) and TasFrameAction
  • Check the data in TasUnitBonusSkill, make sure that the skills used work for your map and are of expected base behaviour.
  • Installed

Option AlInOne
  • Download AllInOne.Lua copy paste all of it into a Script Trigger Edtior
  • Without Total Init run AllInOneTasUnitBonusInit() to create warcraft 3 unit events
  • if you want to use TasUnitBonusEquipment then you need the fdf&TOC (map imported files) and TasFrameAction

Demos & Examples


TasUnitBonusItem

TasUnitBonusItem leveling Item

Custom Stats

TasUnitBonusLearn

TasUnitBonusBuff

TasUnitBonusBuffTable

GUI

TasUnitBonusEquipment


Simple Items
Lua:
--[[
 example use of TasUnitBonusItem
 setup what each items of RawCode gives while carried by a hero
--]]
do
    itemPower = TasUnitBonusItem -- need to write less text
    itemPower[FourCC'I000'] = {Armor = 3} -- 3 base armor
    itemPower[FourCC'I001'] = {["STR+"] = 3} -- +3 bonus str
    itemPower[FourCC'I002'] = {["MOVE+"] = 50} 
    itemPower[FourCC'I003'] = {Int = 6} -- + 6 base int
    itemPower[FourCC'I004'] = {Attack = 9} -- + 9 base dmg
    itemPower[FourCC'I005'] = {["INT+"] = 4, ["AGI+"] = 4} -- gives 4 bonus agi and int
    itemPower[FourCC'I006'] = {["DMG+"] = 6} -- + 6 bonus dmg    
    
    itemPower[FourCC'I007'] = {["PRIMARY+"] = 15}
    itemPower[FourCC'I00B'] = {["ATKSP+"] = 0.25}

    itemPower[FourCC'I00C'] = {"STR+", 4, "AGI+", 4} -- gives 4 bonus agi and str Format2 key. value, key takes less performance
end

Lua:
-- MaskOfDeath is an example for item specific TasUnitBonus combined with itemCode bonus.
--+20 ATK|n+5 for each last hit done while holding this item, upto 100 additional ATK.

MaskOfDeathCode = FourCC'I008'
function MaskOfDeath()
    TasUnitBonusItem[MaskOfDeathCode] = {["DMG+"] = 20} -- + 20 bonus dmg

    local trig = CreateTrigger()
    TriggerAddAction(trig, function()
        local killer = GetKillingUnit()
        if not IsUnitType(killer, UNIT_TYPE_HERO) then return end

        for i = 0, bj_MAX_INVENTORY -1 do
            local item = UnitItemInSlot(killer, i)
            if GetItemTypeId(item) == MaskOfDeathCode then

                -- create item speicifc table when not existing yet
                if not TasUnitBonusItem[item] then TasUnitBonusItem[item] = {["DMG+"] = 0} end
                if TasUnitBonusItem[item]["DMG+"] < 100 then 
                    TasUnitBonusItem[item]["DMG+"] = TasUnitBonusItem[item]["DMG+"] + 5
                    
                    -- give the bonus now, because TasUnitBonusItem is only given and taken on PIckUP/drop events
                    TasUnitBonus(killer, "DMG+", 5)
                    
                    -- update item name & tooltip
                    TasUnitBonusItemTooltip(item)
                    BlzSetItemName(item, GetObjectName(MaskOfDeathCode) .. "(+".. TasUnitBonusItem[item]["DMG+"] ..")")
                end
            end
        end

    end)
    TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DEATH)
end

Lua:
--example of 2 custom types backstab and UndeadSlayer
-- backstab gives Bonus ATK when hitting into the back
-- UndeadSlayer gives Bonus ATK when attacking units with the UNDEAD-Class


-- needed for backstab
function AngleW2W(source, target)
    return bj_RADTODEG * Atan2(GetWidgetY(target) - GetWidgetY(source), GetWidgetX(target) - GetWidgetX(source))
end
do -- 
    function CustomStats()
        udg_BackStab = __jarray(0)
        udg_UndeadSlayer = __jarray(0)
        TasUnitBonus.AddSimpleType("udg_BackStab")
        TasUnitBonus.AddSimpleType("udg_UndeadSlayer")

        itemPower[FourCC'I009'] = {udg_UndeadSlayer = 27}
        itemPower[FourCC'I00A'] = {udg_BackStab = 35}

-- current Bonus used for reset
        local oldBackStab = __jarray(0)
        local oldUndeadSlayer = __jarray(0)
        local trig = CreateTrigger()
        TriggerAddAction(trig, function()
            local unit, attacker = GetTriggerUnit(), GetAttacker()
            local newValue = udg_BackStab[attacker]
            if oldBackStab[attacker] ~= 0 or newValue ~= 0 then
                if CosBJ(AngleW2W(attacker, unit) - GetUnitFacing(unit)) < 0 then newValue = 0 end
                TasUnitBonus(attacker, "ATK+", newValue - oldBackStab[attacker])
                oldBackStab[attacker] = newValue
            end

            newValue = udg_UndeadSlayer[attacker]
            if oldUndeadSlayer[attacker] ~= 0 or newValue ~= 0 then
                if not IsUnitType(unit, UNIT_TYPE_UNDEAD) then newValue = 0 end
                TasUnitBonus(attacker, "ATK+", newValue - oldUndeadSlayer[attacker])
                oldUndeadSlayer[attacker] = newValue
            end
        end)
        TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ATTACKED)
    end
end

Lua:
TasUnitBonusLearn[FourCC'AHhb'] = { -- HolyLight
  ["DMG+"] = 3 -- 3 Bonus ATK every time Skilled
 ,[2] = { Str = 10} -- Skilling level 2 10 base Str
}

Lua:
-- example for TasUnitBonusBuff

function InitDemoSpellCast()
    -- define once what bonus keys buffs give
    TasUnitBonusBuff.DefineKeys('Binv', "MOVE+")
    TasUnitBonusBuff.DefineKeys('Binf', "STR+")
    TasUnitBonusBuff.DefineKeys('Bblo', "Ability")

-- do not run this again
    InitDemoSpellCast = nil
end

function DemoSpellCast()
    if InitDemoSpellCast then InitDemoSpellCast() end

    -- the spellcasts tell TasUnitBonusBuff how much to add for a given buffCode

--Invis buff gives 500 movespeed
    if GetSpellAbilityId() == FourCC'Aivs' then TasUnitBonusBuff.add(GetSpellTargetUnit(), 'Binv', 500) end

-- inner fire gives hero str
-- first cast adds 15 recast give 5 more 15 20 25 30
    local buffCode = FourCC'Binf'
    if GetSpellAbilityId() == FourCC'Ainf' then
        local value = TasUnitBonusBuff.Data[buffCode]["STR+"][GetSpellTargetUnit()] or 0
 	if value  < 15 then value  = 15 else value  = value + 5 end
        TasUnitBonusBuff.add(GetSpellTargetUnit(), buffCode, value ) end

-- bloodlust gives an endurance aura
    local skill = FourCC'AIae'
    if GetSpellAbilityId() == FourCC'ACbb' then TasUnitBonusBuff.add(GetSpellTargetUnit(), 'Bblo', skill) end    
end

Lua:
-- example for TasUnitBonusBuffTable
do
    local bonusInvis = {["MOVE+"]=500}
    local bonusBlood = {Ability='AIae'}

    local frostArmor = {
        {}
        ,{Life = 100}
        ,{Life = 100, LifeReg = 5}
    }
    function DemoSpellCast()
        local unit = GetSpellTargetUnit()
        -- the spellcasts tell TasUnitBonusBuff how much to add for a given buffCode
    --Invis buff gives 500 movespeed
        if GetSpellAbilityId() == FourCC'Aivs' then TasUnitBonusBuffTable.add(unit, 'Binv', bonusInvis) end
    

    -- inner fire gives hero str
    -- first cast adds 15, recast give 5 more; 15 20 25 30
        local buffCode = FourCC'Binf'
        if GetSpellAbilityId() == FourCC'Ainf' then
            local value = 0
            local buffData = TasUnitBonusBuffTable.Data[buffCode]
            if buffData and buffData[unit] then value = buffData[unit]["STR+"] end
            if value  < 15 then value = 15 else value  = value + 5 end
            TasUnitBonusBuffTable(unit, buffCode, {["STR+"]= value})
        end

    -- bloodlust gives an endurance aura
        if GetSpellAbilityId() == FourCC'ACbb' then TasUnitBonusBuffTable.add(unit, 'Bblo', bonusBlood) end    

    -- Frost armog gives with the first rebuff 100 HP with the second Rebuff also HP/s
    local buffCode = FourCC'BUfa'
    if GetSpellAbilityId() == FourCC'ACfa' then
        local currentBonus = TasUnitBonusBuffTable.get(unit, buffCode)
        local newBonus = currentBonus
        if not currentBonus then newBonus = frostArmor[1]
        elseif currentBonus == frostArmor[1] then newBonus = frostArmor[2]
        elseif currentBonus == frostArmor[2] then newBonus = frostArmor[3]
        end
        TasUnitBonusBuffTable(unit, buffCode, newBonus)
    end
    end    
end

  • DemoGUISobiMask
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set TasUnitBonus_ItemCode = Sobi-Maske
      • Set TasUnitBonus_Key = ManaReg
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • Set TasUnitBonus_ItemCode = Sobi-Maske
      • Set TasUnitBonus_Key = INT+
      • Set TasUnitBonus_Amount = 2.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • Set TasUnitBonus_Item = Sobi-Maske 0210 <gen>
      • Gegenstand - Set Extended Tooltip of TasUnitBonus_Item to ((Extended Item Tooltip of TasUnitBonus_Item) + |n+15 ATK vs Undead)
      • Gegenstand - Set Name of TasUnitBonus_Item to ((Name of TasUnitBonus_Item) + Paladin)
      • Set TasUnitBonus_Key = udg_UndeadSlayer
      • Set TasUnitBonus_Amount = 15.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • Set TasUnitBonus_Item = Sobi-Maske 0208 <gen>
      • Gegenstand - Set Extended Tooltip of TasUnitBonus_Item to ((Extended Item Tooltip of TasUnitBonus_Item) + |n+15 ATK vs Undead)
      • Gegenstand - Set Name of TasUnitBonus_Item to ((Name of TasUnitBonus_Item) + Paladin)
      • Set TasUnitBonus_Key = udg_UndeadSlayer
      • Set TasUnitBonus_Amount = 15.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
GUI example for a instant self Buff with static power. The power of the buff is setuped once on first cast and then applied to caster units.
The benefitting unit should gain/have the buff now or in the next 0.1 seconds.
  • DemoGUIWindWalk
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Windlauf
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Execution count of (This trigger)) Equal to 1
        • Then - Actions
          • -------- First use -> create the bonus --------
          • -------- Unit gains 11 HP/s --------
          • Set TasUnitBonus_BuffCode = Windlauf
          • Set TasUnitBonus_Key = LifeReg
          • Set TasUnitBonus_Amount = 11.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
          • -------- Custom GUI Array is increased under this buff --------
          • -------- Requires an UnitIndexer --------
          • Set TasUnitBonus_BuffCode = Windlauf
          • Set TasUnitBonus_Key = udg_UnitSneaks
          • Set TasUnitBonus_Amount = 1.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
        • Else - Actions
      • -------- apply the bonus to the casting unit --------
      • -------- while it has the buff it benefits from the bonus for this buff --------
      • Set TasUnitBonus_Unit = (Triggering unit)
      • Set TasUnitBonus_BuffCode = Windlauf
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
GUI example for a instant target Buff, the power of the buff depends on the current Mana of the caster.
The benefitting unit should gain/have the buff now or in the next 0.1 seconds.
  • DemoGUIInnerFireMana
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inneres Fire (Mana)
    • Actions
      • -------- Each Cast has unique Data --------
      • Set TasUnitBonus_BuffCode = Inneres Fire Mana
      • Trigger - Run TasUnitBonusGUIMakeBuff <gen> (ignoring conditions)
      • -------- Setup BuffBonus --------
      • Set TasUnitBonus_BuffCode = Inneres Fire Mana
      • Set TasUnitBonus_Key = ATK+
      • Set TasUnitBonus_Amount = ((Mana of (Triggering unit)) x 0.20)
      • -------- ATK+ needs to be an integer --------
      • Set TasUnitBonus_Amount = (Real((Integer(TasUnitBonus_Amount))))
      • Game - Display to (All players) the text: (String(TasUnitBonus_Amount))
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- Apply Buff Bonus --------
      • Set TasUnitBonus_Unit = (Target unit of ability being cast)
      • Set TasUnitBonus_BuffCode = Inneres Fire Mana
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
      • -------- Pay Custom cost --------
      • Unit - Set mana of (Triggering unit) to ((Percentage mana of (Triggering unit)) - 35.00)%
  • DemoGUIBladeMaster
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --- --------
      • -------- Possible Keys you find at top of TasUnitBonus --------
      • -------- Also inside TasUnitBonusSkill --------
      • -------- --- --------
      • -------- I want to make a special bonus given at level 5 --------
      • -------- Therefore the blademaster bonusTable needs to be in mapFormat --------
      • Set TasUnitBonus_Format = True
      • -------- --- --------
      • -------- BladeMaster gets +2 Agi on levelUps --------
      • Set TasUnitBonus_HeroCode = Klingenmeister
      • Set TasUnitBonus_Key = AGI+
      • Set TasUnitBonus_Amount = 2.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- BladeMaster gets +1 ATK on levelUps --------
      • Set TasUnitBonus_HeroCode = Klingenmeister
      • Set TasUnitBonus_Key = ATK+
      • Set TasUnitBonus_Amount = 1.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- BladeMaster At Level 5 get 20 Str+ --------
      • Set TasUnitBonus_HeroCode = Klingenmeister
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_HeroLevel = 5
      • Set TasUnitBonus_Amount = 20.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- Revert back to arrayFormat, now used by new bonuses --------
      • Set TasUnitBonus_Format = False
      • -------- --- --------
      • -------- Possible Keys you find at top of TasUnitBonus --------
      • -------- Also inside TasUnitBonusSkill thisData["STR+"] = -> STR+ is the key --------
      • -------- --- --------
      • -------- make an GUI array useable in TasUnitBonus --------
      • -------- in GUI this feature requires an unit indexer that makes Custom Unit Value unique for each unit --------
      • -------- dont forget the prefix udg_ --------
      • Set TasUnitBonus_Key = udg_UnitSneaks
      • Trigger - Run TasUnitBonusGUINewKey <gen> (ignoring conditions)
  • DemoGUI AddStats
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set TasUnitBonus_Unit = Oger-Magier 0029 <gen>
      • Set TasUnitBonus_Key = ATK+
      • Set TasUnitBonus_Amount = 11.00
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
      • Set TasUnitBonus_Unit = Oger-Magier 0137 <gen>
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
  • DemoGUIKrit
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Level Specific bonuses require the map format --------
      • Set TasUnitBonus_Format = True
      • -------- Learning every Level of Krit give + 12 ATK --------
      • Set TasUnitBonus_LearnCode = Kritischer Schlag
      • Set TasUnitBonus_Key = ATK+
      • Set TasUnitBonus_Amount = 12.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- Learning Level 3 gives +5 Int --------
      • Set TasUnitBonus_LearnCode = Kritischer Schlag
      • Set TasUnitBonus_Key = INT+
      • Set TasUnitBonus_Level = 3
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- new bonuses will be in array format --------
      • Set TasUnitBonus_Format = False

TasUnitBonusEquipment is an addon for TasUnitBonus that gives a custom Inventory with UI. It gives a TasUnitBonus while items are inside that custom inventory.
Items move into the custom Inventory when the hero clicks them in the Warcraft 3 inventory, items need to have a valid active for that. Option B Items are equiped when autoequip is enabled and it would be added to the hero's warcraft 3 inventory.
The first free slot, valid for this item, is taken by the new equip.
Autoequip will not unequip items when no slot is free. While active equiping will unequip and take the last valid slot for that item.
Lua:
TasUnitBonusEquipment.UIAutoEquip = {} -- equip items gained (not tomes) can be set for [0] or [hero] or [player] or [unitTypeId]


The custom inventory needs setup.

How many inventory buttons are there and how are they structured?

The inventoryButtons use the Position of the Parent aka local Pos. For their structure there are 2 choices a scrollable grid requires TasFrameList
Lua:
this.UIGridMode = false -- (true) requires TasFrameList, (false) -> use this.UIFormation
this.UIGridModeRows = 9 -- should not be changed after InitTasUnitBonusEquipment() run
this.UIGridModeCols = 6
The other options is to have a fixed amount of buttons with chooseable positions called UIFormation in this system. One does that with a Lua table of x,y pairs (x1,y1, x2,y2, x3,y3, ...)
Lua:
-- 2d offset array each x&y set is one button and how much to move from the previous button, from center to next center
local formationU10 = {-2,0, 0,-1, 0,-1, 0,-1,   1,0, 1,0, 1,0,   0,1, 0,1, 0,1}
local formationTriAngle9 = { 0,0, -1,-1, -1,-1, 1,0, 1,0,1,0,1,0, -1,1, -1,0}
this.UIFormation = formationU10 -- used inside the frame creation when InitTasUnitBonusEquipment() runs
One can choose a new formation during the match with TasUnitBonusEquipment.ApplyFormation(formation).
/data/ratory-images/342/342017-4c7ed3d82e5aaa2bbcb88979da4fbef4_tn.jpg

What items can units equip?

The previous setup was for the ui. One also needs to setup what units can put into the custom Inventory. this is done over the table TasUnitBonusEquipment.Inventory.
it holds the rule what an inventory can hold and it defines as what an item counts.
Lua:
TasUnitBonusEquipment.Inventory[unit] a rule for this unit only
TasUnitBonusEquipment.Inventory[GetUnitTypeId] all paladins use TasUnitBonusEquipment.Inventory.Hpal
TasUnitBonusEquipment.Inventory[Player(0)] units owned by Red Player
TasUnitBonusEquipment.Inventory[0] is the rule used by everyone when the others dont apply for a unit.
prio unit > GetUnitTypeId > player > 0

TasUnitBonusEquipment.Inventory is an array, each entry is one slot for an item.
-1 or ITEM_TYPE_ANY allows any item
-- slot values with special behaviour
this.INV_SLOT_ANY = -1 
this.INV_SLOT_BAG = -2 -- inventory slot that can hold anything, but dont give stats
this.INV_SLOT_NONE = -3 -- hidden Slot that cant hold items
supports warcraft 3 itemTypes like ITEM_TYPE_ARTIFACT
or random madeUp numbers, Strings, Lua table

TasUnitBonusEquipment.Inventory[0] = {-1,-1,-1,-1,-1,-1,-1,-1,-1} -- all heroes can equip 9 items of any type

--bloodMage can equip 4 items then has 2 bag Slots
TasUnitBonusEquipment.Inventory[FourCC'Hblm'] = {-1,-1,-1,-1, -2,-2}

equipPower = TasUnitBonusEquipment -- need to write less text

EquipClass_Wand = 3 -- define a new EquipClass
--equipPower.Strings[EquipClass_Wand] = "Wand"

-- i want to write less
InventoryRules = TasUnitBonusEquipment.Inventory

-- bloodMage can equip 10 items and auto equips them
-- 2 ARTIFACT and 7 normal items and 1 Wand
InventoryRules.Hblm = {}
for i= 1, 2 do InventoryRules.Hblm[i] = ITEM_TYPE_ARTIFACT end
for i= 3, 9 do InventoryRules.Hblm[i] = ITEM_TYPE_PERMANENT end
InventoryRules.Hblm[10] = EquipClass_Wand
equipPower.UIAutoEquip[FourCC'Hblm'] = true

Where is the inventory?

The invenotry has possitions for its show drop button and for the custom inventory.
Lua:
local Pos = function(frame) -- where to place this ui
    --BlzFrameSetPoint(frame, FRAMEPOINT_TOPRIGHT, BlzGetFrameByName("ResourceBarSupplyText", 0), FRAMEPOINT_TOPRIGHT, 0, 0)
    BlzFrameSetAbsPoint(frame, FRAMEPOINT_TOPRIGHT, 0.55, 0.25)
end
this.OpenButton.Pos = function(frame) -- where to place this ui      
    BlzFrameSetAbsPoint(frame, FRAMEPOINT_TOPRIGHT, 0.79, 0.55)
end
this.DropAllButton.Pos = function(frame) -- where to place this ui      
    BlzFrameSetAbsPoint(frame, FRAMEPOINT_TOPRIGHT, 0.79, 0.52)
end

local ParentFunc = function() -- who is the parent of this ui
    return BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
end
There a 2 ui control buttons, one shows/hides the custom UI when clicked, the other drops all inside the custom UI. Both can be hidden in the setup and therefore made not useable by the player.

Stats given by Equipment

Like TasUnitBonusItem you setup table(s) that hold infos what an item gives.
One can set a bonus for an specific item and of its TypeId/ItemCode, the item will give both.
Supports all the things TasUnitBonus can do.
TasUnitBonusEquipment Bonus only is given while items are in the custom inventory.
Lua:
TasUnitBonusEquipment[FourCC'I00G'] = {"STR+", 6} -- while equipred I00G gives 6 green STR
TasUnitBonusEquipment.I00I = {"Life", 150, "Spell", (FourCC'AIse')}

TasUnitBonusEquipment[item] = {"Mana", 100, "Life", 50, "Attack", 5}
342048-b980917eaa75f5acec061eb80b03baf4.jpg


When you change the stats of an specific item during the game it is recommented to use this 2 functions. They add the stats to the current holder. When nobody was able to hold it yet then you can just make the table as shown above.
TasUnitBonusEquipment.Add(item, key, amount)
TasUnitBonusEquipment.Remove(item[, key, amount])


ChangeLog


1.27) added TasUnitBonusSuperHero
1.25) Add TasUnitBonus.Temp can give a bonusTable for dur seconds, AllInOne made a init function calls itself when already gamestarted by bj global.
1.24) Removed TasUnitBonus.Heal
1.23 animation Equip
1.22) Removed TasUnitBonus.Heal, Life & mana also reduce current amount but dont kill
1.21) TasUnitBonusEquipment animation for gaining/losing equip, another losing animation
1.20) TasUnitBonus calls TasUnitBonus.UnitAdd
1.19) TasUnitBonusEquipment Compare Items and show diff
1.18+++) TasUnitBonusEquipment default position open/drop buttons
1.18++) Bugfix TasUnitBonusEquipment [player] inventory
1.18) faster update TasUnitBonusEquipment
1.17) STRAGIINT+ & StrAgiInt, updates for TasUnitBonusEquipment
1.16) ChargeBoxes TasUnitBonusEquipment
1.15+) TasUnitBonusEquipment GUI support
1.15) TasUnitBonusEquipment INV_SLOT_BAG & INV_SLOT_NONE
1.14) optional Condition for TasUnitBonusSkill, new TasUnitBonusSkill Keys, fix key Spell
1.13) More TasUnitBonus base Keys
1.12) Updated TasUnitBonusItemTooltip, new Addon TasUnitBonusEquipment, disabled the included cheatBox in multiplayer
1.11+) TasUnitBonusGUI hold items
1.11) Add for TasUnitBonusHero & TasUnitBonusItem updated TasUnitBonusItemTooltip
1.10++ & 10+) Added GUI support
1.10) TasUnitBonusHero supports array format
1.9) Additonal Format for TasUnitBonus.UnitAdd
1.8) TasUnitBonus.AddSimpleType can create an array, added config TasUnitBonus.Heal, added TasUnitBonusBuffTable.get
1.7b) small error fix
1.7a) fixed an critical error of 1.7, args of TasUnitBonus.UnitAdd reordered, improve comments
1.7) fixed a desync possiblity, call TasUnitBonusBuffTable, NewType copies FourCCValueKey, +Key Ability2 to 4
1.6a) improved TasUnitBonusBuffTable rebuff
1.6) improve comments, Improved Keys Ability,AbilityInc,Tech
1.5) improve comments, ability survives morphs, seperated TasUnitBonusSkill more from TasUnitBonus, Added Key Tech inc/dec Reserach by 1
1.4) fix key AttackRange
1.3x) Added TasUnitBonusLearn
1.3) Added TasUnitBonusItemTooltip & 4 stats
1.2c) Fixed TasUnitBonusHero
1.2b) added TasUnitBonusHero
1.2a) replaced HealUnit(Mana) with native aviable functions


Tags: RPG, Hero, Stats, Unit Bonus, Str, Agi, Int, ATK, Inventory, Bag, Equipment, Item, Buff​
Previews
Contents

AllInOne (Binary)

TasUnitBonus (Map)

Reviews
Antares
A nice collection of quality-of-life libraries that make adding/removing abilities and stat bonuses much easier. Almost any stat/ability is included and the system can easily be expanded to include your own types. Approved
Another one of Tasyen's subscription systems, I wish Blizzard had the same dedication to Warcraft as you and the community here at Hivework Shop.

Apparently it adds a skill that has a bonus that it will increase to the Hero, but how does it increase CastPoint and CastBackswing?

And another thing, will there be a Jass version?
 
And another thing, will there be a Jass version?
I will not make a vjass version of this. vjass cant do this dynamic function mapping which is a core feature.

but how does it increase CastPoint and CastBackswing?
castpoint and castbackswing are unit stats when an ability is gained the ability copies the unit's current castpoint & castbackswing values.
To make already owned abilities be cast faster you would change the unit castpoint then lose the castable spells from the unit and readd them.

Edit: would be easier when one would have the ability_RealFields for castpoint but sadly no, so only doable by readding spells.
 
Updated to V1.2b)
Added the addon TasUnitBonusHero, I forgot to port it from my map.
TasUnitBonus.UnitAdd does not use numbers as key anymore. "1" is still allowed 1 not.
TasUnitBonusHero manages TasUnitBonuses on level ups for any hero [0] and [unit] and [RawCode].
Lua:
TasUnitBonusHero[FourCC'Hpal'] = { -- paladin levelup Bonus
 Str = 1
 ,["DMG+"] = 5 -- gain 5 Bonus ATK every LevelUp
 ,[2] = { Ability = FourCC'AHbz'} -- at level 2 add Blizzard
 ,[4] = {["STR+"] = 12}
}

Edit:
V1.2c)
fixed serious bugs of TasUnitBonusHero.
 
Last edited:
You're so talented, I also wish I knew how to make an off-screen interface like that, but this is way beyond my level, like the photo I posted, you can do for those positions is add a container Hero's items?
HOI4.PNG
 
You're so talented,
I trained many years. in gui, then java and some other none warcraft 3 stuff, after that jass, then i trained Lua and warcraft 3 custom UI (was quite bad at some point in that subject). But y, I guess have talent for some parts of math/order.
TasUnitBonus is the result of systems, I wrote before, some not public released and only for my map or as a experiment. In that systems I encountered the problem that I needed to give unit stats and so I came to this idea. My Talent system is one of these concept-ancestors it has a stat systems by Lua tables.

One can create many types of ui but warcraft 3 frames are based on rectangles -> images are easier than models. One can create a custom ui with buttons to contain: items like a bag, yes. I made such and some others did as well. Making more default item/command/hero buttons is not doable with the ui-frame api. In such a case one would need to recreate the whole feature.




The image shows TasCheatbox, if one wonders, i added that as demo to have some tester super powers like dispel buffs and such.
normaly the 3 & 4 page would create items & units but in this map the were replaced with "cheats" using TasUnitBonus.
 
Updated to V1.3)
added 4 prebuilt stats

2 over skills
"PRIMARY+"
"LIFE_STEAL+" item lifesteal

2 but they dont work in V1.31.1 cause they use Unit Weaponfields.
AttackRange
AttackRangeR

AttackRangeR is AttackRange but wont do anthing if the unit is not ranged.

improved AbilityInc
now should be able to decrease current level like key Ability with a -value.

What common important stat is missing?

Ported another addon TasUnitBonusItemTooltip. Updates item tooltips to include the stats given by that item + itemCode. Items only use this feature when you call it onto it.
TasUnitBonusItemTooltip(item)

TasUnitBonusItemTooltip replaces a placeholder: There are 2 options.
$ replaces all tooltip
$item inser the StatList here keep the rest as it is.

I think all addons for TasUnitBonus are now ported.
 
Last edited:
I think all addons for TasUnitBonus are now ported.
I was wrong. Still got one that gives TasUnitBonus when a hero learns a skill. But I cant port the version from my map, it has weird featues and was constructed for 1 level skills only that give another bonus after dozens of levels and maybe (also/only) affecting other units.

Could make an simpler version that works kinda like TasUnitBonusHero. Would then be called TasUnitBonusLearn.

Edit:
Updated, includes now the addon TasUnitBonusLearn, should be suited for the normal warcraft 3 Learning system.
TasUnitBonusLearn uses the same format as TasUnitBonusHero it does not have the any key with 0 and instead of hero level, skill levels matter, it also can be called from the outside.
TasUnitBonusLearnAction(unit, spellCode, learnedLevel)

Lua:
TasUnitBonusLearn[FourCC'AHhb'] = { -- HolyLight
  ["DMG+"] = 3 -- 3 Bonus ATK every time Skilled
 ,[2] = { Str = 10} -- Skilling level 2 10 base Str
}
 
Last edited:
Adds a new supported type by key the function runs when a request to add to this key.
The function needs to do the inc.
instead of a function you can give an already existing key to make key do the same.
I don't know what that means.

Please use an AI assistant like ChatGPT to help you with the translation or have someone help you with the documentation. I'm sure there are a lot of people who would be happy to.

The description in the OP is fine, but for the comments in the code, I just don't know what it's trying to tell me.

It doesn't help that the formatting is all messed up. It looks like the scope in TasUnitBonus is closed on line 34. Please fix the indentation and add some empty lines.

I'm sure the code itself is superb as always, but we're trying to be more stringent when it comes to documentation, as to increase the accessibility of this section.

Awaiting Update
 
Updated to V1.5)
improved api comments
key Ability; ability survives morphs
seperated TasUnitBonusSkill more from TasUnitBonus
Added Key Tech, it increases/decreases a Research by 1.

TasUnitBonusHero mentions that a Hero benefits from upto 3 tabels at once [0] [GetUnitTypeId] & [unit]
TasUnitBonusItem mentions that an item supports boh at the same time [GetItemTypeId] & [item]
 
Last edited:
Updated to V1.6)
List bases Types below the TasUnitBonus function.

Ability, AbilityInc & Tech now do the FourCC when needed and work better in TasUnitBonus.UnitAdd.

Added addon TasUnitBonusBuffTable a "clone" of TasUnitBonusBuff, but instead of multiargs it works by a bonusTable like used in TasUnitBonus.UnitAdd

TasUnitBonusBuffTable.add(unit, 'Binf', {Life = 200, Str = 5})

The demo for it
Lua:
-- example for TasUnitBonusBuffTable
do
    local bonusInvis = {["MOVE+"]=500}
    local bonusBlood = {Ability='AIae'}

    function DemoSpellCast()
        local unit = GetSpellTargetUnit()
        -- the spellcasts tell TasUnitBonusBuff how much to add for a given buffCode
    --Invis buff gives 500 movespeed
        if GetSpellAbilityId() == FourCC'Aivs' then TasUnitBonusBuffTable.add(unit, 'Binv', bonusInvis) end
    

    -- inner fire gives hero str
    -- first cast adds 15, recast give 5 more; 15 20 25 30
        local buffCode = FourCC'Binf'
        if GetSpellAbilityId() == FourCC'Ainf' then
            local value = 0
            local buffData = TasUnitBonusBuffTable.Data[buffCode]
            if buffData and buffData[unit] then value = buffData[unit]["STR+"] end
            if value  < 15 then value = 15 else value  = value + 5 end
            TasUnitBonusBuffTable.add(unit, buffCode, {["STR+"]= value}) end

    -- bloodlust gives an endurance aura
        if GetSpellAbilityId() == FourCC'ACbb' then TasUnitBonusBuffTable.add(unit, 'Bblo', bonusBlood) end    
    end    
end

Edit: Updated to V1.6a)
improved performance for TasUnitBonusBuffTable rebuffing the same thing an unit already has.

Edit: Updated to V1.7)
TasUnitBonusBuffTable can now be called directly,
fixed a posible desync reason with bonusTable
NewType copies the flag in FourCCValueKey for the copied key.
added Clone Types, they do the same as the normal but allow one bonus to apply 4 different abilities/techs
Ability2 Ability3 Ability4
AbilityInc2 AbilityInc3 AbilityInc4
Tech2 Tech3 Tech4

Edit: Updated to V1.7a)
Fixed an critical bug of V1.7 which broke TasUnitBonus.UnitAdd after an level up.

TasUnitBonus.UnitAdd(bonusTable, bonusTable, add)
-> TasUnitBonus.UnitAdd(unit, bonusTable, add)
therefore all addons were updated aswell.

changed some comments.

Edit: Updated to V1.7b)
updated a small typo in the unsupported key metatable
 
Last edited:
What are the key differences that separate this from Cbopinski’s New Bonus? I Is there a difference in performance? I would love if a newer and more efficient alternative has become available.

What I have found is that this system modifies the base stats via natives thus changing the white numbers. While New bonus uses abilities (requiring object editor) and modifies the green numbers.
 
The key difference is one can add more easy new stats/keys to TasUnitBonus, even without touching the TasUnitBonus code. This custom stats can be any number array, it is simple to use an GUI array. While keys also could target more complicated fields like UnitData[unit].Stats.Str, although here one needs to write a add function (oneline function).

The addons handle the events to apply the stats, therefore one can setup TasUnitBonuses just as data at map init or such like the demos show. learning skills, buffs, items, level-Ups can give any TasUnitBonus. (except for buffs these need an runtime event in which the bonus is applied to an specific unit)

Level-up demo for Paladins.
Lua:
TasUnitBonusHero[FourCC'Hpal'] = { -- paladin levelup Bonus
 Str = 1
 ,["DMG+"] = 5 -- gain 5 Bonus ATK every LevelUp
 ,[2] = { Ability = FourCC'AHbz'} -- at level 2 add Blizzard
 ,[4] = {["STR+"] = 12}
}

TasUnitBonus only adds/takes away stats, it can not tell you how much you have.
The default keys of TasUnitBonus change base stats. The Addon TasUnitBonusSkill adds keys to add green stats which need abilities.

I dont know about performance diffs, wasnt my goal to perform faster than new Bonus, I wanted this data setup outside of events.

TasUnitBonus can not be used in (v)jass mode maps.
 
Last edited:
uploaded a small update V1.8)
TasUnitBonus.AddSimpleType has now an optional second arg. When provided it will create an new global array with the key in _G, this array returns 0 like the GUI arrays.
TasUnitBonus.AddSimpleType("MyUnitStat", true) -> add "MyUnitStat" to TasUnitBonus and also create such an array.
TasUnitBonus.AddSimpleType("MyUnitStat") -> only add "MyUnitStat" to TasUnitBonus.


TasUnitBonus.Heal a config when true the Key Life & Mana will increase current Life/Mana, default enabled.

Added TasUnitBonusBuffTable.get(unit, buffCode). It returns the current bonusTable for this unit & buffCode or nil.

Added a new Demo that shows buff stacking, but only 2 rebuffs make the buff better, This demo uses a finite amount of tables, made at the beginning.

Lua:
local frostArmor = {
    {}
    ,{Life = 100}
    ,{Life = 100, LifeReg = 5}
}
-- Frost armog gives with the first rebuff 100 HP with the second Rebuff also HP/s
local buffCode = FourCC'BUfa'
if GetSpellAbilityId() == FourCC'ACfa' then
    local currentBonus = TasUnitBonusBuffTable.get(unit, buffCode)
    local newBonus = currentBonus
    if not currentBonus then newBonus = frostArmor[1]
    elseif currentBonus == frostArmor[1] then newBonus = frostArmor[2]
    elseif currentBonus == frostArmor[2] then newBonus = frostArmor[3]
    end
    TasUnitBonusBuffTable(unit, buffCode, newBonus)
end
 
Last edited:
Updated to V1.9)
TasUnitBonus.UnitAdd supports now a second format for the bonusTable. instead of a map it can now be an array, it automatic chooses the currently used format when called. The array format takes less performance. The performance difference grows with the amount of stats one bonusTable includes.
map = {Str = 2, Agi = 7, Int = 5 }
array = {"Str",5, "Agi", 3, "Int", 2 }

Most of the addons use TasUnitBonus.UnitAdd. Therefore they also support the new format. The 2 formats can not be mixed in one bonusTable. As soon the conditions for array are fullfilled, then the map keys are ignored. The array conditions are the bonusTable has [1] & [2] and [1] is a string.
TasUnitBonusHero can only use the map format when you want that a hero gains bonuses at level x and also every level. With only a every level bonus you can use the array format. the bonus applied by Level x, can use the array format even when the hero bonusTable can not.
 
Last edited:
Updated to V1.10)
TasUnitBonusHero can now use array format. {"Str",2, "Agi",2, ...}

it is small patch, one line was changed inside TasUnitBonusHero.
Lua:
for i = lastLevel[unit] + 1, newLevel do if data[i] then TasUnitBonus.UnitAdd(unit, data[i], 1) end end
->
for i = lastLevel[unit] + 1, newLevel do if data[i] and type(data[i]) == "table" then TasUnitBonus.UnitAdd(unit, data[i], 1) end end
 
ok, I'll try to make a GUI interface for some features of TasUnitBonus.

Edit: Updated to V1.10++ added a GUI API.
it can use all addons, but for buffs it will only use TasUnitBonusBuffTable.
-> buffs that become stronger or scale with stats are not doable in GUI setup of this version.
The hero levelup bonus for all heroCodes can not be setuped in GUI.
Custom GUI arrays need an Unit Indexer to be useable in TasUnitBonus, this only matters for arrays registered over the GUI api.
Key Tech & Ability are not diretly useable as one can not choose the skill/tech in the dialog, one would write the objectType as number. I could add 2 more variables to pick a tech/ability, but I will only when wanted.
 
Last edited:
ok, I'll try to make a GUI interface for some features of TasUnitBonus.

Edit: Updated to V1.10++ added a GUI API.
Thank you
it can use all addons, but for buffs it will only use TasUnitBonusBuffTable.
-> buffs that become stronger or scale with stats are not doable in GUI setup of this version.
What does it mean, it can use only TasUnitBonusBuffTable?
(I tried casting Windwalk - but no hp regen was given to the hero)
  • DemoGUIWindWalk
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Wind Walk
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Execution count of (This trigger)) Equal to 1
        • Then - Actions
          • -------- First use -> create the bonus --------
          • -------- Unit gains 11 HP/s --------
          • Set TasUnitBonus_BuffCode = Wind Walk
          • Set TasUnitBonus_Key = LifeReg
          • Set TasUnitBonus_Amount = 11.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
          • -------- Custom GUI Array is increased under this buff --------
          • -------- Requires an UnitIndexer --------
          • Set TasUnitBonus_BuffCode = Wind Walk
          • Set TasUnitBonus_Key = udg_UnitSneaks
          • Set TasUnitBonus_Amount = 1.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
        • Else - Actions
      • -------- apply the bonus to the casting unit --------
      • -------- while it has the buff it benefits from the bonus for this buff --------
      • Set TasUnitBonus_Unit = (Triggering unit)
      • Set TasUnitBonus_BuffCode = Wind Walk
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)

And iv tried to add a custom Ensnare that would decrease target armor by 10, but it also doesn't work for me.
  • Net
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ensnare
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Execution count of (This trigger)) Equal to 1
        • Then - Actions
          • -------- First use -> create the bonus --------
          • -------- Unit gains 11 HP/s --------
          • Set TasUnitBonus_BuffCode = Ensnare (General)
          • Set TasUnitBonus_Key = Armor
          • Set TasUnitBonus_Amount = -10.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
          • -------- Custom GUI Array is increased under this buff --------
          • -------- Requires an UnitIndexer --------
          • Set TasUnitBonus_BuffCode = Wind Walk
          • Set TasUnitBonus_Key = udg_UnitSneaks
          • Set TasUnitBonus_Amount = 1.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
        • Else - Actions
      • -------- apply the bonus to the casting unit --------
      • -------- while it has the buff it benefits from the bonus for this buff --------
      • Set TasUnitBonus_Unit = (Target unit of ability being cast)
      • Set TasUnitBonus_BuffCode = Ensnare (General)
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
 
Updated TasUnitBonusGUI.
TasUnitBonusGUIUse now resets udg_TasUnitBonus_Unit to nil/no unit.

(I tried casting Windwalk - but no hp regen was given to the hero)
I made only one Add function which does stuff based on which variable has a value then resets. TasUnitBonusGUIUse did not reset TasUnitBonus_Unit from Trigger DemoGUI AddStats which i added later. Therefore the add in windwalk made something unwanted (an leveling bonus for the oger). Fixed with the update. When I made this demo triggers I first made the windwalk it worked, then I added the direct Stat add for the ogers which broke windwalk. But i did not test wind walk again.


TasUnitBonusGUIUse has to be called at the moment the unit has/gains the buff. Ensnare buff is delayed by a missile.

What does it mean, it can use only TasUnitBonusBuffTable?
There are 2 addons about Buffs TasUnitBonusBuffTable & TasUnitBonusBuff they store the data a little bit different.
 
Last edited:
Did not test it in V.2.0. Would not know why it should not work for this version :|

it can help in making a new stat like charisma. One can setup what gives it with TasUnitBonus. But you still would need to trigger what charisma does.

Edit: Update TasUnitBonusGUI to 1.2)
There is now TasUnitBonusGUIMakeBuff which creates a new Table for udg_TasUnitBonus_BuffCode. This allows to have buffs with dynamic power/scale based on the situation when casted.
2 new Demos.
One that shows the dynamic Power Buff.
Added One sobi mask to each pulk that gives 15 ATK vs Undead, shows item specific bonuses.
 
Last edited:
Did not test it in V.2.0. Would not know why it should not work for this version :|

it can help in making a new stat like charisma. One can setup what gives it with TasUnitBonus. But you still would need to trigger what charisma does.

Edit: Update TasUnitBonusGUI to 1.2)
There is now TasUnitBonusGUIMakeBuff which creates a new Table for udg_TasUnitBonus_BuffCode. This allows to have buffs with dynamic power/scale based on the situation when casted.
2 new Demos.
One that shows the dynamic Power Buff.
Added One sobi mask to each pulk that gives 15 ATK vs Undead, shows item specific bonuses.
What Unit Indexer would one use for LUA?
 
no idea.
When you only need the unique index feature of unit indexers. Then making Get Unit User Data return the unit itself will do the deal for almost free.
they did other stuff as far I know, which this would not.

This would do what I said above. To use it make a new script in your map and copy paste.
Lua:
do
    oldGetUnitUserData = GetUnitUserData 
    function GetUnitUserData(unit) return unit or 0 end
end
Edit: one could it make smarter so it would return the choosen value when you used Set Unit Custom Value
Edit2: Added return unit or 0 to avoid nil pointer error

Edit: Ic Bribe did some stuff for it.
 
Last edited:
no idea.
When you only need the unique index feature of unit indexers. Then making Get Unit User Data return the unit itself will do the deal for almost free.
they did other stuff as far I know, which this would not.

This would do what I said above. To use it make a new script in your map and copy paste.
Lua:
do
    oldGetUnitUserData = GetUnitUserData
    function GetUnitUserData(unit) return unit end
end
Edit: one could it make smarter so it would return the choosen value when you used Set Unit Custom Value

Edit: Ic Bribe did some stuff for it.
As a GUI user, i didn't understand much from it TBH :huh:
Nvm got it.
 
Last edited:
So I am trying to increase some stats of the item - Broken Sword via a power type item (socket) that the hero has in inventory, but for some reason the bonus stats does not apply (however if another hero picks the item - the added stats work), What am i doing wrong?
  • Broken Sword Basic
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- - --------
      • Set TasUnitBonus_ItemCode = Broken Sword
      • Set TasUnitBonus_Key = DMG+
      • Set TasUnitBonus_Amount = 7.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- - --------

  • Broken Sword Sockets
    • Events
      • Unit - A unit Sells an item (from shop)
    • Conditions
      • (Item-type of (Sold Item)) Equal to Sword Socket
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Buying unit) has an item of type Broken Sword) Equal to True
        • Then - Actions
          • Set TasUnitBonus_Item = (Item carried by (Buying unit) of type Broken Sword)
          • Item - Set Extended Tooltip of TasUnitBonus_Item to ((Extended Item Tooltip of TasUnitBonus_Item) + |n+5 damage)
          • Item - Set Name of TasUnitBonus_Item to ((Name of TasUnitBonus_Item) + Paladin)
          • Set TasUnitBonus_Key = DMG+
          • Set TasUnitBonus_Amount = 5.00
          • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
        • Else - Actions
1741623808394.png

1741623818770.png
1741623825565.png
1741623839080.png
1741623845373.png
 
So I am trying to increase some stats of the item - Broken Sword via a power type item (socket) that the hero has in inventory, but for some reason the bonus stats does not apply (however if another hero picks the item - the added stats work), What am i doing wrong?
TasUnitBonusItem does not give a bonus when the item already was hold. But it will remove the bonus when droped. One would add the additional bonus to the unit aswell, like the Lua mask of death example shows.
 
The bonus is set for the item. It is just that it only applies and removes the bonus on a pick & drop items event.
I don't know LUA much, but calling the function directly wouldn't allow for such implementation on top of the pick/drop only event?
like the Lua mask of death example shows.
Can you provide an example for such events for GUI? (if it's possible)
 
I don't know LUA much, but calling the function directly wouldn't allow for such implementation on top of the pick/drop only event?
If that solution is acceptable to you, all you need to do is forcibly drop the item and then have the unit pick it back up immediately. The Action function that updates the bonuses when an item is picked up/dropped is a local non-public-facing function that cannot be directly called from outside the library.
 
I don't know LUA much, but calling the function directly wouldn't allow for such implementation on top of the pick/drop only event?
That requires something I didnt want to do.
For the itemCode: One would need to loop all units and if they have such an item then add the additional bonus, sounds costly to me. Far smarter to set the bonus before any unit can pick it up. Except when you want to upgrade all items of type x during the match then it needs the loop all units or replace it with a new item Type on item pick up.

For a specific item: Need to keep track of the current holder as the game does not tell who that is, Then apply it also to the current holder.
^^Alternative Keep track of bonuses provided by items for units and only take away the given bonus on item drop. This would add a big amount of data to be stored or compared (depends how one would implement this).

Can you provide an example for such events for GUI? (if it's possible)
Updated the uploaded map, added a new GUI example:
EchtSilber Hammer
+5 STR
Activ: Destroy an target item this gives 5 more STR

Also added a disabled lua code that upgrades Get Unit/Item Custom Value to return the Unit/Item itself or the choosen Value. so it can be directly used as Index like mentioned in this TasUnitBonus

  • DemoGUIEchtSilberHammer
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- All EchtSeliber Hammer gives 5 STR on base --------
      • Set TasUnitBonus_ItemCode = EchtSilber Hammer
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
  • DemoGUIEchtSilberHammerUse
    • Events
      • Unit - A unit Uses an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to EchtSilber Hammer
    • Actions
      • -------- Display current Power as item Charge --------
      • Item - Set charges remaining in (Item being manipulated) to ((Charges remaining in (Item being manipulated)) + 2)
      • -------- make this Hammer Stronger --------
      • Set TasUnitBonus_Item = (Item being manipulated)
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- Give the new bonus to the unit now. Because the item is hold and the system takes/gives the bonus on a drop/Pickup event --------
      • Set TasUnitBonus_Unit = (Hero manipulating item)
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
  • DemoGUIEchtSilberHammerCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to AbsorbItem
    • Actions
      • Item - Remove (Target item of ability being cast)
 
Last edited:
That requires something I didnt want to do.
For the itemCode: One would need to loop all units and if they have such an item then add the additional bonus, sounds costly to me. Far smarter to set the bonus before any unit can pick it up. Except when you want to upgrade all items of type x during the match then it needs the loop all units or replace it with a new item Type on item pick up.

For a specific item: Need to keep track of the current holder as the game does not tell who that is, Then apply it also to the current holder.
^^Alternative Keep track of bonuses provided by items for units and only take away the given bonus on item drop. This would add a big amount of data to be stored or compared (depends how one would implement this).


Updated the uploaded map, added a new GUI example:
EchtSilber Hammer
+5 STR
Activ: Destroy an target item this gives 5 more STR

Also added a disabled lua code that upgrades Get Unit/Item Custom Value to return the Unit/Item itself or the choosen Value. so it can be directly used as Index like mentioned in this TasUnitBonus

  • DemoGUIEchtSilberHammer
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- All EchtSeliber Hammer gives 5 STR on base --------
      • Set TasUnitBonus_ItemCode = EchtSilber Hammer
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
  • DemoGUIEchtSilberHammerUse
    • Events
      • Unit - A unit Uses an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to EchtSilber Hammer
    • Actions
      • -------- Display current Power as item Charge --------
      • Item - Set charges remaining in (Item being manipulated) to ((Charges remaining in (Item being manipulated)) + 2)
      • -------- make this Hammer Stronger --------
      • Set TasUnitBonus_Item = (Item being manipulated)
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
      • -------- Give the new bonus to the unit now. Because the item is hold and the system takes/gives the bonus on a drop/Pickup event --------
      • Set TasUnitBonus_Unit = (Hero manipulating item)
      • Set TasUnitBonus_Key = STR+
      • Set TasUnitBonus_Amount = 5.00
      • Trigger - Run TasUnitBonusGUIUse <gen> (ignoring conditions)
  • DemoGUIEchtSilberHammerCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to AbsorbItem
    • Actions
      • Item - Remove (Target item of ability being cast)
Thanks, also is the MOVE+ working with negative values?
  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Set TasUnitBonus_ItemCode = Boots of DE Speed
      • Set TasUnitBonus_Key = MOVE+
      • Set TasUnitBonus_Amount = -250.00
      • Trigger - Run TasUnitBonusGUIAdd <gen> (ignoring conditions)
I tested this, and while the movement speed (MS) shows as reduced (with the red color indicating a decrease), the actual movement speed remains unchanged. The hero still runs at the same speed as one without boots.
Screenshot_6.jpg
 
the ability is not needed. I just have bad experience with the trigger function that changes movespeed, it does not check for movespeed limits and therefore can in edgecases perma change move speed in unwanted ways.


This would add Move as new key to change movespeed using the trigger feature. Put that somewhere in your map script after TasUnitBonus.
Lua:
TasUnitBonus.NewType("Move", function(unit, value, key)
   SetUnitMoveSpeed(unit, GetUnitMoveSpeed(unit) + value)
end)
 
the ability is not needed. I just have bad experience with the trigger function that changes movespeed, it does not check for movespeed limits and therefore can in edgecases perma change move speed in unwanted ways.


This would add Move as new key to change movespeed using the trigger feature. Put that somewhere in your map script after TasUnitBonus.
Lua:
TasUnitBonus.NewType("Move", function(unit, value, key)
   SetUnitMoveSpeed(unit, GetUnitMoveSpeed(unit) + value)
end)
This seems to work just fine! :thumbs_up:
 
Updated to V1.11)
The addons TasUnitBonusHero, TasUnitBonusItem & TasUnitBonusItemTooltip were updated.

Added utility to add & remove bonuses from specific hero/items during a match.
Added local function AllowedUser(unit, item, itemCode) inside TasUnitBonusItem allows a unit to use TasUnitBonusItem , used in the pick up and drop item action instead of the hardcoded is hero check.

TasUnitBonusItemTooltip now works for both formats (array, map)
TasUnitBonusItemTooltip .Apply(item) now returns the stat-text that would/is added.

Lua:
[[
TasUnitBonusHero.Add(unit, key, amount[, level])
    add a levelupBonus for unit in the unit specific bonus
    with a level the bonus is only given once reaching that level, if the hero already reached that level applies the bonus right now.
    it adds the bonus in array format, which conflicts with at level x bonus.
    When you want level x bonuses for this unit specific bonus data, then always state a level (in this function).

TasUnitBonusItem.Add(item, key, amount)
    add a new bonus to the items specific bonus table in array format
    the unit holding the item will gain the bonus now

TasUnitBonusItem.Remove(item[, key, amount])
    remove item specific bonus from its array format, when hold the holderUnit lose the bonus.
    no key & amount -> remove last added bonus
    key -> find a bonus with that key but any amount, from the last to the first added
    key & amount -> find a bonus with that key and amount
        does nothing when no fitting one is found
    returns key amount when a bonus is removed
]]


Edit: Updated to V1.11+)
The "GUi API Add" used onto an item (specific item bonus) now give the bonus to the holder.
Updated TasUnitBonusItem can get the itemHolder from outside TasUnitBonusItem.ItemHolder[item]

Updated the EchtsilberHammer demo, previous one needed to add 5 STR+ onto the unit. not anymore
 
Last edited:
Updated to V1.12)
Fixed included cheatbox, new Addon TasUnitBonusEquipment, updated TasUnitBonusItemTooltip.

The included cheatbox is now single player only, as this thing is not meant to be used in multiplayer and might produce dcs.

improved TasUnitBonusItemTooltip, display of Object Editor refs, respects the ignored keys from TasUnitBonus and it now supports TasUnitBonusEquipment. The function is a bit stupid, hence it does not work probably when an item has both TasUnitBonusEquipment & TasUnitBonusItem which is a strange thing to do imo anyway. While it is possible to do so just the tooltip generator does not work probably in this case.

new Addon TasUnitBonusEquipment.
TasUnitBonusEquipment is a custom Inventory that gives TasUnitBonus while items are equiped. Equiping is done by clicking an item in the normal warcraft 3 inventory, that moves it into the custom inventory.

Units/unitCodes can have inventories with different sizes and different item-class restrictions.
For example bloodmage could equip 1 wand, 7 ITEM_TYPE_PERMANENT and 2 ITEM_TYPE_ARTIFACT. All other heroes can equip 3 items of any type. This item classes are done by warcraft 3 types, if you want and by map script types which you can define yourself.
Lua:
TasUnitBonusEquipment.Inventory[0] = {-1,-1,-1} -- all heroes can equip 3 items of any type

EquipClass_Wand = 3 -- define a new EquipClass

InventoryRules = TasUnitBonusEquipment.Inventory
-- bloodMage can equip 10 items and auto equips them
-- 2 aretfacts and 7 normal items and 1 Wand
InventoryRules.Hblm = {}
for i= 1, 2 do InventoryRules.Hblm[i] = ITEM_TYPE_ARTIFACT end
for i= 3, 9 do InventoryRules.Hblm[i] = ITEM_TYPE_PERMANENT end
InventoryRules.Hblm[10] = EquipClass_Wand
The Inventory can use FrameList to make a scrollable grid of custom inventory buttons or a fixed amount.
Or you can choose the formation of the fix buttons. To make a triangle, an U, O or whatever you like as long you are capable of displaying it as a chain of relative positions. like 1 left& 1up, then 2 left and 1 down, then 3 right, 1 down ...
script wise that would look like this
Lua:
local formationPlus5 = { 0,0, -1,-1, 1,-1, 1,1, -1,0}
local formationGrid6 = { 0,0, 1,0, 0,-1, -1,0, 0,-1, 1,0}
TasUnitBonusEquipment.UIFormation = formationU10 -- used inside the frame creation when InitTasUnitBonusEquipment() runs

When an item is unequiped it moves into the warcraft 3 inventory or on the ground.

has its own table for TasUnitBonus
Lua:
TasUnitBonusEquipment[item] = { "Attack", 20}
TasUnitBonusEquipment[FourrCC'I00A'] = { "Attack", 20}

As TasUnitBonusEquipment uses events and frames one needs to init it. either call InitTasUnitBonusEquipment() or have Total Initialization.

TasUnitBonusEquipment UI has a show UI button and a drop all button (unequip all).
pressing ESC will close the ui.

Edit: Updated to 1.13)
Added base keys to TasUnitBonus.
Spell __like Ability remember cooldown
Spell2 Spell3 Spell4
MoveSpeed
MaxLife no Heal
MaxMana
AggroRange / AcquireRange
AttackM
AttackR
AttackSpeedM
AttackSpeedR

The Equipment wand demo now uses Spell instead of Ability

Edit: Updated to 1.14)
fixed a nil pointer with TasUnitBonus key Spell
Updated TasUnitBonusSkill
TasUnitBonusSkill supports now Condition to only give a stat to melee for example.
Added
ATKM+
ATKR+
ATKSPM+
ATKSPR+
DEFR+
DEFM+

Edit: Updated to 1.15)
TasUnitBonusEquipment gained 2 new special behaviour inventory slots. There are now "constants" for them.
Lua:
TasUnitBonusEquipment.INV_SLOT_ANY = -1 
TasUnitBonusEquipment.INV_SLOT_BAG = -2 -- inventory slot that can hold anything but dont give stats
TasUnitBonusEquipment.INV_SLOT_NONE = -3 -- hidden Slot that cant hold items

Edit: Updated to 1.15+)
Added a GUI boolean TasUnitBonus_Equip while true bonuses added for item/itemcode target TasUnitBonusEquipment over the GUI api.
only TasUnitBonusGUI was updated code wise.
added a new demo item vitality

Edit: Updated to 1.16)
Updated TasUnitBonusEquipment & new fdf
Shows item charges.
new api function TasUnitBonusEquipment.CountItems(unit)
TasUnitBonusEquipment.UIAutoEquip[0] = true, enables it for everyone.
Shows how many items are "equiped" by the current Unit as charges on the openbutton.
Added an autoupdate timer, one can disable it, this.UIAutoUpdate = 0.2 set it to 0, lower or to nil.
 
Last edited:
Updated to V1.17)
Added StrAgiInt in TasUnitBonus
Added STRAGIINT+ in TasUnitBonusSkill

TasUnitBonusEquipment
prevents equiping the same item multiple times (this was possible by mass ordering hold shift)
Unequips items on death when item or inventory want it.
new function TasUnitBonusEquipment.UnitHasItem(unit, item) item can also be an integer or FourCC String. returns true/false and, 1 or count
function TasUnitBonusEquipment.UnitEquip can now create new items when an integer or FourCC String is given instead of an item.

Edit: Updated to V1.18)
TasUnitBonusEquipment skips unneeded Updates (while the ui is shown). improves performance drastically when nothing was changed since last refresh (checks for itemTypeId, inventoryTable, ...).
Added TasUnitBonusEquipment.EnforceUpdate = true

Added TasUnitBonusEquipment.ApplyFormation(formationTable)
repos the UIbuttons to the formationTable
creates new buttons when required

Added a new Frame, TasUnitBonusEquipment.ParentInventory all inventory buttons are now children of it.

Added 2 new UIFormations, inspired by HeroesIV and Warlods battlecry 3
Edit: Updated to V1.18+) Fixed a bug that showed wrong items when an new unit without any TasUnitBonusEquipment data was selected.
Edit: Updated to V1.18++) supports player based inventory size/equip rules

Edit: Updated to V1.18+++) changed default Position of drop/open buttons. added more equip info text, used tabs for the demo/examples

Edit: Updated to V1.19) TasUnitBonusEquipment shows diff in stats of an item hovered in Warcraft 3 inventory and the equiped item it would replace.
this feature only works when the lib HoverOringButton is found
 
Last edited:
There is an update for TasUnitBonusEquipment 1.7)
has now a small animation that happpens when an item enters/leaves the custom inventory. Can be disabled. (new fdf) can be disabled or enabled.

Updated the included TasCheatBox.

Edit: TasUnitBonusEquipment 1.8)
new fdf
there are now 2 variations of the in and out animation. can choose them with the settings.
TasUnitBonusEquipment.Animat.TypeOut = 1 or 2
TasUnitBonusEquipment.Animat.TypeIn = 1 or 2

"In 2" adds an 3rd img that is at the edge of the bag showing more clear that it moved into the bag

"Out 2", fades in a red X over the item img that left the bag. Fading away the item img is "Out 1".
 
Last edited:
Back
Top