Antares
Spell Reviewer
- Joined
- Dec 13, 2009
- Messages
- 982
This is a new system or moved from Code Archive?
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.TasUnitBonus(unit, "Primary", 10)
if Debug then Debug.beginFile "TasUnitBonus" end
do
--[[ TasUnitBonus 1.9 by Tasyen
A system to provide various bonuses to Units over one way. This only defines Types and their callbacks to increase or decrease the wanted stat.
Apply a bonus: TasUnitBonus(unit, key, value)
TasUnitBonus(udg_Unit, "Life", 100) -- add 100 HP to udg_Unit
TasUnitBonus(udg_Unit, "Ability", FourCC'AHbz') -- add Blizzard
TasUnitBonus(udg_Unit, "AttackSpeed", -0.1) -- improve base ATK cooldown by 0.1
base-Keys
Life
Mana
Armor
Attack
AttackSpeed
AttackRange (Not V1.31.1)
AttackRangeR (Not V1.31.1)
LifeReg
ManaReg
Agi
Str
Int
Primary
CastPoint
CastBackswing
TurnSpeed
UnitLevel
Ability
Ability2 Ability3 Ability4
AbilityInc
AbilityInc2 AbilityInc3 AbilityInc4
Tech
Tech2 Tech3 Tech4
TasUnitBonus.UnitAdd(unit, bonusTable, add)
apply many bonuses with one call, supports 2 formats
{Str = x, Agi = y, Int = z ,...}
{"Str",x, "Agi", y, "Int", z ,...}
bonusTable is affecting unit by add Times (add needs to be an integer). Use -1 to remove bonus. 1 to add bonus
Ignores number keys
TasUnitBonus.NewType(key, function(unit, value, key) end)
Adds a new supported bonus reached by key, key should be unique.
The function runs when calling TasUnitBonus with that key, and it needs to do the wanted effect, in most cases increase some unit stat; newValue = oldValue + value.
instead of a function you can give an already existing key to make keyB do the same as keyA, for TasUnitBonus.UnitAdd keyA and keyB are 2 separate stats.
TasUnitBonus.NewType("ATK", "Attack") -- now TasUnitBonus(unit, "ATK", 22) & TasUnitBonus(unit, "Attack", 22) do the same
TasUnitBonus.NewType("MyUnitStat", function(unit, value, key)
local unitData = UnitData[unit]
unitData[key] = unitData[key] + value
end)
TasUnitBonus.AddSimpleType(key[, createArray])
add a new supported type meant for an global array in env _G.
Which would result into key[unit] = key[unit] + bonus
TasUnitBonus.AddSimpleType("udg_Unit_Super_Power")
createArray (true) -> create a new array and store it at _G[key]. This array will return 0 on default
this.AddSimpleTypeBatch = function(...)
add many AddSimpleType as once
AddSimpleTypeBatch("MagicPower", "WeaponPower",...)
]]
local this = {}
TasUnitBonus = this
this.Heal = true -- Key Life & Mana will give current amount
this.IgnoreUnsupported = {Aktiv = true} -- do not throw erros for these unsupported keys encountered in TasUnitBonus.UnitAdd; expects Key = true, Key2 = true
this.FourCCValueKey = {AbilityInc = true, Ability = true, Tech = true} -- for this BonusTypes the value is a Object Editor RawCode
this.AddSimpleType = function(key, createArray)
this.Types[key] = this.Types.SimpleBonusType
if createArray then
_G[key] = __jarray(0)
end
end
this.NewType = function(key, action)
if type(action) == "function" then
this.Types[key] = action
elseif type(action) == "string" then
this.Types[key] = this.Types[action]
if this.FourCCValueKey[action] then this.FourCCValueKey[key] = true end
end
end
this.AddSimpleTypeBatch = function(...) for _, k in ipairs({...}) do this.AddSimpleType(k) end end
local tempKeys = {}
-- bonusTable is affecting unit by add Times. Use -1 to remove bonus. 1 to add bonus
this.UnitAdd = function (unit, bonusTable, add)
if not unit then return end
if GetUnitTypeId(unit) == 0 then return end -- this might be smart to do when you only use units
if not add then add = 1 end
-- which format is used, {Key = x} or Sequzenz {"Str",20 ,"Int",5}?
if bonusTable[1] and bonusTable[2] and type(bonusTable[1]) == "string" then
-- format Sequzenz {"Str",4,"Agi",6}
-- loop the bonusTable and apply any key that is in TasUnitBonus.Types
for i = 1, #bonusTable, 2 do
local key = bonusTable[i]
local value = bonusTable[i + 1]
if this.IgnoreUnsupported[key] or type(key) == "number" then
elseif this.Types[key] then
-- supported Type call it
-- That key has an Object Editor RawCode value, therefore only support +1/-1 for add
if this.FourCCValueKey[key] then
if type(value) == "string" then value = FourCC(value) end
this.Types[key](unit, value*ISignBJ(add), key)
else
this.Types[key](unit, value*add, key)
end
else print("TasUnitBonus.UnitAdd - Unsuported Key", key)
end
end
else
local keyCount = 0
for key in pairs(bonusTable) do
-- only keys are accepted & executed
if type(key) == "string" then
keyCount = keyCount + 1
tempKeys[keyCount] = key
end
end
table.sort(tempKeys)
-- loop the bonusTable and apply any key that is in TasUnitBonus.Types
for __,key in ipairs(tempKeys) do
local value = bonusTable[key]
if this.IgnoreUnsupported[key] or type(key) == "number" then
elseif this.Types[key] then
-- supported Type call it
-- That key has an Object Editor RawCode value, therefore only support +1/-1 for add
if this.FourCCValueKey[key] then
if type(value) == "string" then value = FourCC(value) end
this.Types[key](unit, value*ISignBJ(add), key)
else
this.Types[key](unit, value*add, key)
end
else print("TasUnitBonus.UnitAdd - Unsuported Key", key)
end
end
for i = 1, keyCount do
tempKeys[i] = nil
end
end
end
setmetatable(this, {__call = function(table, unit, key, value)
if not unit then return end
--if string.find(tostring(unit), "unit:") and GetUnitTypeId(unit) == 0 then print("TasUnitBonus - no Unit: ",key, value) return end
if GetUnitTypeId(unit) == 0 then print("TasUnitBonus - no Unit: ",key, value) return end
if this.Types[key] then
this.Types[key](unit, value, key)
-- elseif TasUnitBonusSkill and TasUnitBonusSkill.Data[key] then
-- TasUnitBonusSkill.Add(unit, key, value)
else
print("TasUnitBonus - Unsupported Key: ",key)
end
end})
function this.ConvertFourCC(value)
if type(value) == "string" then
if string.byte(value) == 45 then -- starts with - ? "-AHbz"
return -FourCC(string.sub(value, 2))
else
return FourCC(value)
end
end
return value
end
-- supported Types and what to do for them. the functions should work for -value and +value
this.Types = {
Life = function(unit, value) BlzSetUnitMaxHP(unit, BlzGetUnitMaxHP(unit) + value) if value > 0 and this.Heal then SetWidgetLife(unit, GetWidgetLife(unit) + value) end end
,Mana = function(unit, value) BlzSetUnitMaxMana(unit, BlzGetUnitMaxMana(unit) + value) if value > 0 and this.Heal then SetUnitState(unit, UNIT_STATE_MANA, GetUnitState(unit, UNIT_STATE_MANA) + value) end end
,Armor = function(unit, value) BlzSetUnitArmor(unit, BlzGetUnitArmor(unit) + value) end
,Attack = function(unit, value) BlzSetUnitBaseDamage(unit, BlzGetUnitBaseDamage(unit, 0) + value, 0) end
,AttackSpeed = function(unit, value) BlzSetUnitAttackCooldown(unit, BlzGetUnitAttackCooldown(unit, 0) + value, 0) end
-- AttackRange does not work in warcraft 3 v1.31
,AttackRange = function(unit, value) BlzSetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1, value + BlzGetUnitWeaponRealField(unit, UNIT_WEAPON_RF_ATTACK_RANGE, 1)) end
,AttackRangeR = function(unit, value) if IsUnitIdType(GetUnitTypeId(unit), UNIT_TYPE_RANGED_ATTACKER) then this.Types.AttackRange(unit, value) end end
,LifeReg = function(unit, value) BlzSetUnitRealField(unit, UNIT_RF_HIT_POINTS_REGENERATION_RATE, BlzGetUnitRealField(unit, UNIT_RF_HIT_POINTS_REGENERATION_RATE) + value) end
,ManaReg = function(unit, value) BlzSetUnitRealField(unit, UNIT_RF_MANA_REGENERATION, BlzGetUnitRealField(unit, UNIT_RF_MANA_REGENERATION) + value) end
,Agi = function(unit, value) SetHeroAgi(unit, GetHeroAgi(unit, false) + value, true) end
,Str = function(unit, value) SetHeroStr(unit, GetHeroStr(unit, false) + value, true) end
,Int = function(unit, value) SetHeroInt(unit, GetHeroInt(unit, false) + value, true) end
,Primary = function(unit, value)
local stat = BlzGetUnitIntegerField(unit, UNIT_IF_PRIMARY_ATTRIBUTE)
if stat == GetHandleId(HERO_ATTRIBUTE_STR) then
this.Types.Str(unit, value)
elseif stat == GetHandleId(HERO_ATTRIBUTE_AGI) then
this.Types.Agi(unit, value)
elseif stat == GetHandleId(HERO_ATTRIBUTE_INT) then
this.Types.Int(unit, value)
end
end
-- CastPoint CastBackswing don't affect abilities the unit already has. One would have to lose and regain all to make it work.
,CastPoint = function(unit, value) BlzSetUnitRealField(unit, UNIT_RF_CAST_POINT, BlzGetUnitRealField(unit, UNIT_RF_CAST_POINT) + value) end
,CastBackswing = function(unit, value) BlzSetUnitRealField(unit, UNIT_RF_CAST_BACK_SWING, BlzGetUnitRealField(unit, UNIT_RF_CAST_BACK_SWING) + value) end
,TurnSpeed = function(unit, value) SetUnitTurnSpeed(unit, GetUnitTurnSpeed(unit) + value) end
,UnitLevel = function(unit, value)
if not IsUnitType(unit, UNIT_TYPE_HERO) and not IsHeroUnitId(GetUnitTypeId(unit)) then
BlzSetUnitIntegerField(unit, UNIT_IF_LEVEL, BlzGetUnitIntegerField(unit, UNIT_IF_LEVEL) + value)
end
end
-- example of a custom variable setting, MagicDef should bedefined to catch nilpointers with __jarray(0)
--,MagicDef = function(unit, value) MagicDef[unit] = MagicDef[unit] + value end
,Ability = function(unit, value)
value = this.ConvertFourCC(value)
if value >= 0 then
UnitMakeAbilityPermanent(unit, true, value)
UnitAddAbility(unit, value)
else
UnitRemoveAbility(unit, -value)
end
end
,AbilityInc = function(unit, value)
value = this.ConvertFourCC(value)
if value >= 0 then IncUnitAbilityLevel(unit, value)
else DecUnitAbilityLevel(unit, -value) end
end
,Tech = function(unit, value)
value = this.ConvertFourCC(value)
if value >= 0 then
AddPlayerTechResearched(GetOwningPlayer(unit), value, 1)
else
BlzDecPlayerTechResearched(GetOwningPlayer(unit), -value, 1)
end
end
,SimpleBonusType = function(unit, value, key) _G[key][unit] = _G[key][unit] + value end
-- Key+ uses skills to provide non base bonus
-- You need to provide abilities and update the references inside TasUnitBonusSkill
-- the "+" key iself should not be used it is the base for all TasUnitBonusSkill
,["+"] = function(unit, value, key) TasUnitBonusSkill.Add(unit, key, value) end
}
-- setup equals
TasUnitBonus.NewType("ATK", "Attack") -- now TasUnitBonus(unit, "ATK", 22) & TasUnitBonus(unit, "Attack", 22) do the same
TasUnitBonus.NewType("Ability2", "Ability")
TasUnitBonus.NewType("Ability3", "Ability")
TasUnitBonus.NewType("Ability4", "Ability")
TasUnitBonus.NewType("AbilityInc2", "AbilityInc")
TasUnitBonus.NewType("AbilityInc3", "AbilityInc")
TasUnitBonus.NewType("AbilityInc4", "AbilityInc")
TasUnitBonus.NewType("Tech2", "Tech")
TasUnitBonus.NewType("Tech3", "Tech")
TasUnitBonus.NewType("Tech4", "Tech")
-- custom ones
--this.AddSimpleTypeBatch("TasCasterLevel","WeaponPower","WeaponDef","MagicPower", "MagicDefAstral","MagicDef")
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusSkill" end
--[[
TasUnitBonusSkill 1.2a by Tasyen
Addon for TasUnitBonus handles bonus provided over an ability (green +)
needs custom map setup, make sure the Abilities in the data setup is okay in your map.
Scroll down to Data Setup
when a skill provides more than one thing make sure the base in object Editor don't conflicts with your goal
^^ for abilities with multiple fields you should make a custom version with default values good for your purposes like hero stat skill 0 0 0.
the abilities should not be used otherwise
======
function TasUnitBonusSkill.Remove(unit, whichType)
removes the ability providing the bonus
function TasUnitBonusSkill.Set(unit, whichType, amount)
add the ability and set the bonus provided
function TasUnitBonusSkill.Get(unit, whichType)
function TasUnitBonusSkill.Add(unit, whichType, amount)
adds amount to the current bonus
======
--]]
do
TasUnitBonusSkill = {Data = {}}
local this = TasUnitBonusSkill
this.HideSkills = true -- hide the skills gained by this system with BlzUnitHideAbility?
local this = TasUnitBonusSkill
local thisData = TasUnitBonusSkill.Data
-- enforce update functions
local function UpdateLevel(unit, data)
IncUnitAbilityLevel(unit, data.Skill)
DecUnitAbilityLevel(unit, data.Skill)
end
local function UpdateInt(unit, data)
SetHeroInt(unit, GetHeroInt(unit, false)+1, true)
SetHeroInt(unit, GetHeroInt(unit, false)-1, true)
end
local function UpdateStr(unit, data)
SetHeroStr(unit, GetHeroStr(unit, false)+1, true)
SetHeroStr(unit, GetHeroStr(unit, false)-1, true)
end
-- shortcuts
local iGet = BlzGetAbilityIntegerLevelField
local iSet = BlzSetAbilityIntegerLevelField
local rGet = BlzGetAbilityRealLevelField
local rSet = BlzSetAbilityRealLevelField
--[[
define abilities providing the bonuses and which field is update using which function for Get and Set
Skill = FourCC(abiliCode)
Field = field to read/write
Get = function used to read
Set = function used to write
Update = call a function to apply changes, needed for some values.
]]
--======
-- Data Setup
--======
--ability clone of 'Aamk' Hero Attributes
thisData["STR+"] = {Skill = FourCC('TU00'), Field = ABILITY_ILF_STRENGTH_BONUS_ISTR, Get = iGet, Set = iSet, Update = UpdateLevel}
thisData["AGI+"] = {Skill = FourCC('TU00'), Field = ABILITY_ILF_AGILITY_BONUS, Get = iGet, Set = iSet, Update = UpdateLevel}
thisData["INT+"] = {Skill = FourCC('TU00'), Field = ABILITY_ILF_INTELLIGENCE_BONUS, Get = iGet, Set = iSet, Update = UpdateLevel}
--claw of attack
thisData["ATK+"] = {Skill = FourCC('AItg'), Field = ABILITY_ILF_ATTACK_BONUS, Get = iGet, Set = iSet, Update = UpdateLevel}
thisData["DMG+"] = thisData["ATK+"] -- one can also use "DMG+" for attack damage
--gloves
thisData["ATKSP+"] = {Skill = FourCC('AIsx'), Field = ABILITY_RLF_ATTACK_SPEED_INCREASE_ISX1, Get = rGet, Set = rSet, Update = UpdateLevel}
--armor item
thisData["DEF+"] = {Skill = FourCC('AId1'), Field = ABILITY_ILF_DEFENSE_BONUS_IDEF, Get = iGet, Set = iSet, Update = UpdateLevel}
--based on 'ACev'
thisData["EVADE+"] = {Skill = FourCC('AIev'), Field = ABILITY_RLF_CHANCE_TO_EVADE_EEV1, Get = rGet, Set = rSet}
--trunken fighter or orc crit
thisData["KRIT_CHANCE+"] = {Skill = FourCC('AIcs'), Field = ABILITY_RLF_CHANCE_TO_CRITICAL_STRIKE, Get = rGet, Set = rSet}
thisData["KRIT_FACTOR+"] = {Skill = FourCC('AIcs'), Field = ABILITY_RLF_DAMAGE_MULTIPLIER_OCR2, Get = rGet, Set = rSet}
thisData["KRIT_DAMAGE+"] = {Skill = FourCC('AIcs'), Field = ABILITY_RLF_DAMAGE_BONUS_OCR3, Get = rGet, Set = rSet}
thisData["KRIT_EVADE+"] = {Skill = FourCC('AIcs'), Field = ABILITY_RLF_CHANCE_TO_EVADE_OCR4, Get = rGet, Set = rSet}
thisData["KRIT_TRUE_STRIKE+"] = {Skill = FourCC('AIcs'), Field = ABILITY_ILF_SUMMONED_UNIT_COUNT_NPA5, Get = iGet, Set = iSet}
thisData["KRIT_BONUS+"] = {Skill = FourCC('AIcs'), Field = ABILITY_ILF_WAVE_COUNT_NHS6, Get = iGet, Set = iSet}
--boots of speed skill, they don't stack anyway
thisData["MOVE+"] = {Skill = FourCC('AIms'), Field = ABILITY_ILF_MOVEMENT_SPEED_BONUS, Get = iGet, Set = iSet, Update = UpdateLevel}
--elunes grace 'Aegr'
thisData["MAGIC_RES+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_MAGIC_DAMAGE_REDUCTION_DEF5, Get = rGet, Set = rSet}
thisData["PIERCE_RES+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_DAMAGE_TAKEN_PERCENT_DEF1, Get = rGet, Set = rSet}
-- Deflect has to be enabled inside Game constants
thisData["DEFLECT_CHANCE+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_CHANCE_TO_DEFLECT, Get = rGet, Set = rSet}
thisData["DEFLECT_DAMAGE_MAGIC+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_DEFLECT_DAMAGE_TAKEN_SPELLS, Get = rGet, Set = rSet}
thisData["DEFLECT_DAMAGE_PIERCE+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_DEFLECT_DAMAGE_TAKEN_PIERCING, Get = rGet, Set = rSet}
-- multiplies basic attack without UI-Feedback
thisData["DAMAGE_FACTOR+"] = {Skill = FourCC('AIdd'), Field = ABILITY_RLF_DAMAGE_DEALT_PERCENT_DEF2, Get = rGet, Set = rSet}
-- spell ress brace item skill
-- beaware this can break the the Aegr magic res feature for this unit
thisData["SPELL_RES+"] = {Skill = FourCC('AIsr'), Field = ABILITY_RLF_DAMAGE_REDUCTION_ISR2, Get = rGet, Set = rSet, Update = UpdateLevel}
--based on 'Ansk'
thisData["BLOCK_AMOUNT+"] = {Skill = FourCC('Ansk'), Field = ABILITY_RLF_IGNORED_DAMAGE, Get = rGet, Set = rSet}
thisData["BLOCK_MIN+"] = {Skill = FourCC('Ansk'), Field = ABILITY_RLF_MINIMUM_DAMAGE, Get = rGet, Set = rSet}
thisData["BLOCK_CHANCE+"] = {Skill = FourCC('Ansk'), Field = ABILITY_RLF_CHANCE_TO_REDUCE_DAMAGE_PERCENT, Get = rGet, Set = rSet}
--'ACce' MeleeCleave
thisData["CLEAVE_DAMAGE+"] = {Skill = FourCC('ACce'), Field = ABILITY_RLF_DISTRIBUTED_DAMAGE_FACTOR_NCA1, Get = rGet, Set = rSet}
thisData["CLEAVE_AOE+"] = {Skill = FourCC('ACce'), Field = ABILITY_RLF_AREA_OF_EFFECT, Get = rGet, Set = rSet}
--'ACpv'
thisData["PULV_CHANCE+"] = {Skill = FourCC('ACpv'), Field = ABILITY_RLF_CHANCE_TO_STOMP_PERCENT, Get = rGet, Set = rSet}
thisData["PULV_DAMAGE+"] = {Skill = FourCC('ACpv'), Field = ABILITY_RLF_DAMAGE_DEALT_WAR2, Get = rGet, Set = rSet}
thisData["PULV_AOE+"] = {Skill = FourCC('ACpv'), Field = ABILITY_RLF_FULL_DAMAGE_RADIUS_WAR3, Get = rGet, Set = rSet}
thisData["PULV_AOE_HALF+"] = {Skill = FourCC('ACpv'), Field = ABILITY_RLF_HALF_DAMAGE_RADIUS_WAR4, Get = rGet, Set = rSet}
thisData["PULV_SFX+"] = {Skill = FourCC('ACpv'), Field = ABILITY_SLF_SPECIAL, Get = BlzGetAbilityStringLevelField, Set = BlzSetAbilityStringLevelField}
--'Afbk'
thisData["FEEDBACK_MANA+"] = {Skill = FourCC('Afbb'), Field = ABILITY_RLF_MAX_MANA_DRAINED_UNITS, Get = rGet, Set = rSet}
thisData["FEEDBACK_MANA_HERO+"] = {Skill = FourCC('Afbb'), Field = ABILITY_RLF_MAX_MANA_DRAINED_HEROS, Get = rGet, Set = rSet}
thisData["FEEDBACK_DAMAGE+"] = {Skill = FourCC('Afbb'), Field = ABILITY_RLF_DAMAGE_RATIO_UNITS_PERCENT, Get = rGet, Set = rSet}
thisData["FEEDBACK_DAMAGE_HERO+"] = {Skill = FourCC('Afbb'), Field = ABILITY_RLF_DAMAGE_RATIO_HEROS_PERCENT, Get = rGet, Set = rSet}
thisData["FEEDBACK_DAMAGE_SUMMON+"] = {Skill = FourCC('Afbb'), Field = ABILITY_RLF_SUMMONED_DAMAGE, Get = rGet, Set = rSet}
--'Apxf'
thisData["AUTO_SHOT_DAMAGE+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_INITIAL_DAMAGE_PXF1, Get = rGet, Set = rSet, Update = UpdateLevel}
thisData["AUTO_SHOT_DPS+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_DAMAGE_PER_SECOND_PXF2, Get = rGet, Set = rSet, Update = UpdateLevel}
thisData["AUTO_SHOT_DUR+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_DURATION_NORMAL, Get = rGet, Set = rSet, Update = UpdateLevel}
thisData["AUTO_SHOT_DUR_HERO+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_DURATION_HERO, Get = rGet, Set = rSet, Update = UpdateLevel}
thisData["AUTO_SHOT_AOE+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_AREA_OF_EFFECT, Get = rGet, Set = rSet, Update = UpdateLevel}
thisData["AUTO_SHOT_TIME+"] = {Skill = FourCC('Apxf'), Field = ABILITY_RLF_COOLDOWN, Get = rGet, Set = rSet, Update = UpdateLevel}
--'ANss'
thisData["SPELL_SHIELD+"] = {Skill = FourCC('ANss'), Field = ABILITY_RLF_COOLDOWN, Get = rGet, Set = rSet}
--'ACrn'
thisData["REINCARNATION_COOLDOWN+"] = {Skill = FourCC('ACrn'), Field = ABILITY_RLF_COOLDOWN, Get = rGet, Set = rSet}
thisData["REINCARNATION_DUR+"] = {Skill = FourCC('ACrn'), Field = ABILITY_RLF_REINCARNATION_DELAY, Get = rGet, Set = rSet}
--Bash
thisData["BASH_CHANCE+"] = {Skill = FourCC('AIbx'), Field = ABILITY_RLF_CHANCE_TO_BASH, Get = rGet, Set = rSet}
thisData["BASH_DAMAGE+"] = {Skill = FourCC('AIbx'), Field = ABILITY_RLF_DAMAGE_BONUS_HBH3, Get = rGet, Set = rSet}
thisData["BASH_DUR+"] = {Skill = FourCC('AIbx'), Field = ABILITY_RLF_DURATION_NORMAL, Get = rGet, Set = rSet}
thisData["BASH_DURHERO+"] = {Skill = FourCC('AIbx'), Field = ABILITY_RLF_DURATION_HERO, Get = rGet, Set = rSet}
thisData["BASH_TRUE_STRIKE+"] = {Skill = FourCC('AIbx'), Field = ABILITY_ILF_SUMMONED_UNIT_COUNT_NPA5, Get = iGet, Set = iSet}
-- Item Lifesteal skill 'AIva'
thisData["LIFE_STEAL+"] = {Skill = FourCC('AIva'), Field = ABILITY_RLF_DAMAGE_DEALT_ESF1, Get = rGet, Set = rSet, Update = UpdateLevel}
--Poison Buff Placer 'ACvs'
thisData["POISON_DPS+"] = {Skill = FourCC('ACvs'), Field = ABILITY_RLF_DAMAGE_PER_SECOND_POI1, Get = rGet, Set = rSet}
thisData["POISON_SLOW_ATK+"] = {Skill = FourCC('ACvs'), Field = ABILITY_RLF_ATTACK_SPEED_FACTOR_POI2, Get = rGet, Set = rSet}
thisData["POISON_SLOW_MOVE+"] = {Skill = FourCC('ACvs'), Field = ABILITY_RLF_MOVEMENT_SPEED_FACTOR_POI3, Get = rGet, Set = rSet}
thisData["POISON_TYPE+"] = {Skill = FourCC('ACvs'), Field = ABILITY_ILF_STACKING_TYPE_POI4, Get = iGet, Set = iSet}
thisData["POISON_DUR+"] = {Skill = FourCC('ACvs'), Field = ABILITY_RLF_DURATION_NORMAL, Get = rGet, Set = rSet}
thisData["POISON_DUR_HERO+"] = {Skill = FourCC('ACvs'), Field = ABILITY_RLF_DURATION_HERO, Get = rGet, Set = rSet}
TasUnitBonus.NewType("PRIMARY+", function(unit, value, key)
local stat = BlzGetUnitIntegerField(unit, UNIT_IF_PRIMARY_ATTRIBUTE)
if stat == GetHandleId(HERO_ATTRIBUTE_STR) then
this.Add(unit, "STR+", value)
elseif stat == GetHandleId(HERO_ATTRIBUTE_AGI) then
this.Add(unit, "AGI+", value)
elseif stat == GetHandleId(HERO_ATTRIBUTE_INT) then
this.Add(unit, "INT+", value)
end
end)
--======
-- System functions
--======
setmetatable(thisData, {__index = function(table, key)
print("TasUnitBonusSkill - Error - invalid Key", key)
return nil
end})
function this.Set(unit, whichType, amount)
local data = thisData[whichType]
--if not BlzGetUnitAbility(unit, data.Skill) then UnitAddAbility(unit, data.Skill) end
UnitAddAbility(unit, data.Skill)
UnitMakeAbilityPermanent(unit, true, data.Skill)
if this.HideSkills then BlzUnitHideAbility(unit, data.Skill, true) end
data.Set(BlzGetUnitAbility(unit, data.Skill), data.Field, 0, amount)
if data.Update then
data.Update(unit, data)
end
end
function this.Get(unit, whichType)
local spell = BlzGetUnitAbility(unit, thisData[whichType].Skill)
if not spell then
return 0
else
return thisData[whichType].Get(spell, thisData[whichType].Field, 0)
end
end
function this.Remove(unit, whichType)
UnitRemoveAbility(unit, thisData[whichType].Skill)
end
function this.Add(unit, whichType, amount)
this.Set(unit, whichType, this.Get(unit, whichType) + amount)
end
-- add all they keys from TasUnitBonusSkill to to TasUnitBonus
-- they all use the same function
for key in pairs(this.Data) do
TasUnitBonus.NewType(key,"+")
end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusBuff" end
--[[
TasUnitBonusBuff V1c
by Tasyen
Addon for TasUnitBonus; Give bonuses as long an unit has an Ability/Buff. Has to be evoked when an unit gains the buff.
function TasUnitBonusBuff.add(unit, buffCode, ...)
as long unit has buffCode it benefits from the given amount
Overwrites the current boni which first is lost
TasUnitBonusBuff.add(unit, 'Binf', 200, 5) -- Gives 200 of the first Key in TasUnitBonusBuff.DefineKeys and 5 for the second
function TasUnitBonusBuff.DefineKeys(buffCode, ...)
Which keys are used By buffCode (keys are from TasUnitBonus). This will generate Tables for it, only do this once at map init before using any buff placer.
TasUnitBonusBuff.DefineKeys('Binf', "Life", "Str")
--]]
do
TasUnitBonusBuff = {
-- current Buffs
Unit = {}
,BuffCode = {}
,Count = 0
-- BuffCode Data
,Data = {}
-- to interpret the given Data
,Keys = {}
-- KeysWaitingForRgister
,Delayed = {}
}
local this = TasUnitBonusBuff
function this.DefineKeys(buffCode, ...)
if not buffCode then print("TasUnitBonusBuff.DefineKeys - Invalid buffCode", buffCode) return end
if type(buffCode) == "string" then buffCode = FourCC(buffCode) end
if this.Keys[buffCode] then if Debug then print("TasUnitBonusBuff.DefineKeys - Twice ", buffCode, string.pack(">I4", buffCode)) end return end
this.Data[buffCode] = {}
this.Keys[buffCode] = {}
-- make for the buffCode one table for each Key
-- unitspecific data is stored at --this.Data[buffCode][Key][unit]
-- that way after each buffCode has define keys no Table has to be created anymore
for i, key in ipairs({...}) do
this.Data[buffCode][key] = {}
this.Keys[buffCode][i] = key -- this is required to call the TasUnitBonus
end
-- has unit Buff & Time Buff Gained
this.Data[buffCode][0] = {}
end
function this.StoreKey(...)
if this.Delayed then
table.insert(this.Delayed, {...})
else
this.DefineKeys({...})
end
end
function this.ApplyStoredKeys()
for _, v in ipairs(this.Delayed) do this.DefineKeys(table.unpack(v)) end
this.Delayed = nil
end
function this.add(unit, buffCode, ...)
if type(buffCode) == "string" then buffCode = FourCC(buffCode) end
if not unit then print("TasUnitBonusBuff.add No Unit") return end
if not this.Timer then this.Timer = CreateTimer() end
if not this.Data[buffCode] then
print("TasUnitBonusBuff.add - Not Registered BuffCode", buffCode, string.pack(">I4", buffCode))
return
end
-- new buff?
if not this.Data[buffCode][0][unit] then
-- the Time buff gained
this.Data[buffCode][0][unit] = 5
this.Count = this.Count + 1
this.Unit[this.Count] = unit
this.BuffCode[this.Count] = buffCode
-- apply bonus
local key
for i, value in ipairs({...}) do
key = this.Keys[buffCode][i]
this.Data[buffCode][key][unit] = value
TasUnitBonus(unit, key, value)
end
if this.Count == 1 then TimerStart(this.Timer, 0.1, true, this.TimerAction) end
else
-- rebuff
local dif
local key
for i, value in ipairs({...}) do
key = this.Keys[buffCode][i]
dif = value - this.Data[buffCode][key][unit]
this.Data[buffCode][key][unit] = value
TasUnitBonus(unit, key, dif)
end
end
end
function this.TimerAction()
local buffCode, unit, unitCode
-- print(this.Count)
for index = this.Count, 1, -1 do
-- Have buff Lost? And atleast 0.5 seconds expired
buffCode = this.BuffCode[index]
unit = this.Unit[index]
unitCode = GetUnitTypeId(unit)
--print(buffCode, GetFourCC(buffCode))
if unitCode == 0 or ( not BlzGetUnitAbility(unit, buffCode)
and (this.Data[buffCode][0][unit] <= 0)
) then
-- print("expired",buffCode, GetFourCC(buffCode), TimerGetElapsed(udg_SpielZeit), TasUnitBonusBuff.Data[buffCode][0][unit])
-- revert bonus
for _, key in ipairs(this.Keys[buffCode]) do
if unitCode > 0 then TasUnitBonus(unit, key, -this.Data[buffCode][key][unit]) end
this.Data[buffCode][key][unit] = nil
end
-- unmark having TasUnitBonusBuff
this.Data[buffCode][0][unit] = nil
-- reindex
this.Unit[index] = this.Unit[this.Count]
this.BuffCode[index] = this.BuffCode[this.Count]
this.Unit[this.Count] = nil
this.Count = this.Count - 1
if this.Count <= 0 then PauseTimer(this.Timer) end
elseif this.Data[buffCode][0][unit] > 0 then
this.Data[buffCode][0][unit] = this.Data[buffCode][0][unit] - 1
end
end
buffCode = nil
unit = nil
end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusBuffTable" end
--[[
TasUnitBonusBuffTable V1d
by Tasyen
Addon for TasUnitBonus; Give bonuses as long an unit has an Ability/Buff. Has to be evoked when an unit gains the buff.
This version of TasUnitBonusBuff only works with tables.
function TasUnitBonusBuffTable.add(unit, buffCode, bonusTable)
unit benefits from bonusTable as long it has buffCode
one buffCode can give each unit only one bonusTable at once. When it already benefits from one the old bonus is undone.
TasUnitBonusBuffTable.add(unit, 'Binf', {Life = 200, Str = 5})
TasUnitBonusBuffTable(unit, buffCode, bonusTable) is supported as well
function TasUnitBonusBuffTable.get(unit, buffCode)
returns the current bonusTable for this unit & buffCode or nil
--]]
do
TasUnitBonusBuffTable = {
-- current Buffs
Unit = {}
,BuffCode = {}
,Count = 0
-- BuffCode Data
,Data = {}
,Protected = {}
}
local this = TasUnitBonusBuffTable
setmetatable(this, {__call = function(table, unit, buffCode, bonusTable) table.add(unit, buffCode, bonusTable) end})
function this.add(unit, buffCode, bonusTable)
if type(buffCode) == "string" then buffCode = FourCC(buffCode) end
if not unit then print("TasUnitBonusBuffTable.add No Unit") return end
if not this.Timer then this.Timer = CreateTimer() end
if not this.Data[buffCode] then
-- has unit Buff & Time Buff Gained
this.Data[buffCode] = {}
this.Protected[buffCode] = __jarray(0)
end
-- new buff?
if not this.Data[buffCode][unit] then
-- the Time buff gained
this.Protected[buffCode][unit] = 5
this.Count = this.Count + 1
this.Unit[this.Count] = unit
this.BuffCode[this.Count] = buffCode
TasUnitBonus.UnitAdd(unit, bonusTable, 1)
this.Data[buffCode][unit] = bonusTable
if this.Count == 1 then TimerStart(this.Timer, 0.1, true, this.TimerAction) end
elseif this.Data[buffCode][unit] ~= bonusTable then
-- rebuff, only do something when it is a new table
TasUnitBonus.UnitAdd(unit, this.Data[buffCode][unit], -1)
TasUnitBonus.UnitAdd(unit, bonusTable, 1)
this.Data[buffCode][unit] = bonusTable
end
end
function this.get(unit, buffCode)
if not this.Data[buffCode] then return nil end
return this.Data[buffCode][unit]
end
function this.TimerAction()
local buffCode, unit, unitCode
-- print(this.Count)
for index = this.Count, 1, -1 do
-- Have buff Lost? And atleast 0.5 seconds expired
buffCode = this.BuffCode[index]
unit = this.Unit[index]
unitCode = GetUnitTypeId(unit)
--print(buffCode, GetFourCC(buffCode))
if unitCode == 0 or ( not BlzGetUnitAbility(unit, buffCode)
and (this.Protected[buffCode][unit] <= 0)
) then
-- revert bonus
TasUnitBonus.UnitAdd(unit, this.Data[buffCode][unit], -1)
-- unmark having TasUnitBonusBuffTable
this.Protected[buffCode][unit] = nil
this.Data[buffCode][unit] = nil
-- reindex
this.Unit[index] = this.Unit[this.Count]
this.BuffCode[index] = this.BuffCode[this.Count]
this.Unit[this.Count] = nil
this.Count = this.Count - 1
if this.Count <= 0 then PauseTimer(this.Timer) end
elseif this.Protected[buffCode][unit] > 0 then
this.Protected[buffCode][unit] = this.Protected[buffCode][unit] - 1
end
end
buffCode = nil
unit = nil
end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusItem" end
do
--[[ TasUnitBonusItem 1.4c by Tasyen
Code driven Bonus for items. Also can be used for powerups.
requires TasUnitBonus
can use FourCCTable & Total Initialization
without Total Initialization you need to run InitTasUnitBonusItem() to create the events
example; the keys used need to be suported by TasUnitBonus, before such an item is picked Up/Droped
TasUnitBonusItem['I000'] = {
Attack = 20 --add 20 ATK
,Mana = 100
,Life = 30
,Armor = 1.5 -- + 1.5 Armor
,LifeReg = 2.2
,ManaReg = 1.0 -- +1.0 Mana/s
,Agi = 1
,Str = 3
,Int = 5
}
one can set a bonus for an specific item, both TasUnitBonusItem[GetItemTypeId] & TasUnitBonusItem[item] are gained/lost.
TasUnitBonusItem[udg_Item] = { Attack = 20 }
]]
if CreateFourCCTable then TasUnitBonusItem = CreateFourCCTable()
else TasUnitBonusItem = {} end
local this = TasUnitBonusItem
local function Action(unit, item, itemCode, add)
if IsUnitType(unit, UNIT_TYPE_HERO) then
if this[itemCode] then TasUnitBonus.UnitAdd(unit, this[itemCode], add) end
if this[item] then TasUnitBonus.UnitAdd(unit, this[item], add) end
end
end
function InitTasUnitBonusItem()
InitTasUnitBonusItem = DoNothing
local trig = CreateTrigger()
TriggerAddAction(trig, function()
local unit, item, itemCode = GetManipulatingUnit(), GetManipulatedItem(), GetItemTypeId(GetManipulatedItem())
-- heroes only
if not IsUnitType(unit, UNIT_TYPE_HERO) then return end
-- skip the drop part for powerups, to have a permanent boni :)
if not IsItemPowerup(item) then
Action(unit, item, itemCode, -1)
end
end)
TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_DROP_ITEM)
trig = CreateTrigger()
TriggerAddAction(trig, function()
local unit, item, itemCode = GetManipulatingUnit(), GetManipulatedItem(), GetItemTypeId(GetManipulatedItem())
-- heroes only
if not IsUnitType(unit, UNIT_TYPE_HERO) then return end
Action(unit, item, itemCode, 1)
end)
TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_PICKUP_ITEM)
end
if OnInit then OnInit.trig(InitTasUnitBonusItem) end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusItemTooltip" end
--[[
TasUnitBonusItemTooltip by Tasyen
Addon for TasUnitBonusItem rewrites the tooltips with stats given by an item.
Only does something when called onto an item. to use this is an item needs to have the placeholders inside its default extended tooltip.
$ replaces all tooltip
$item inser the StatList here
TasUnitBonusItemTooltip(item)
]]
TasUnitBonusItemTooltip = {}
do
local this = TasUnitBonusItemTooltip
PercentChar = "\x25"
this.DisplayMulti = {
-- multi the value for display purposes
-- for given keys
["ATKSP+"] = 100
,ATKSP = 100
}
this.DisplayFormat = {
-- rounding rules for display purposes
["ATKSP+"] = PercentChar..".0f"
,ATKSP = PercentChar..".0f"
}
this.Strings = {
-- strings used in the tooltip gen
-- the values are thrown into GetLocalizedString
Str = "STRENGTH"
,Agi = "AGILITY"
,Int = "INTELLECT"
,STR = "STRENGTH"
,AGI = "AGILITY"
,INT = "INTELLECT"
}
setmetatable(this.Strings, {__index = function(table, key)
return key end -- default fallback
} )
setmetatable(this, {__call = function(table, item) this.Apply(item) end } )
function this.Formater(key, value)
if this.DisplayFormat[key] then return string.format(this.DisplayFormat[key], value) end
return value
end
function this.AddStat(obj, key, value)
-- + not allowed In StringList, therefore drop it
local keyString = key
if string.sub(keyString, - 1) == "+" then keyString = string.sub(keyString, 1 , -2) end
if (type(value) == "number") then
if not obj[keyString] then obj[keyString] = value
else obj[keyString] = obj[keyString] + value
end
end
end
function this.Apply(item)
local itemCode = GetItemTypeId(item)
if not TasUnitBonusItem[itemCode] and not TasUnitBonusItem[item] then return end
--local text = BlzGetItemExtendedTooltip(item)
local text = BlzGetAbilityExtendedTooltip(itemCode, 0)
local temp = {}
if TasUnitBonusItem[itemCode] then for key, value in pairs(TasUnitBonusItem[itemCode]) do this.AddStat(temp ,key, value) end end
if TasUnitBonusItem[item] then for key, value in pairs(TasUnitBonusItem[item]) do this.AddStat(temp ,key, value) end end
local addText = ""
for key, value in pairs(temp) do
addText = addText .. this.Formater(key, value*(this.DisplayMulti[key] or 1)) .." ".. GetLocalizedString(this.Strings[key]).."|n"
end
-- all dynamic
if (text == "$") then
BlzSetItemExtendedTooltip(item, addText)
BlzSetItemDescription(item, addText)
-- add all itemstats here
elseif string.find(text, "$item") then
local oldText = text
text = string.gsub(oldText, "$item", addText)
BlzSetItemExtendedTooltip(item, text)
BlzSetItemDescription(item, text)
end
end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusHero" end
do
--[[ TasUnitBonusHero 1.1c by Tasyen
Code driven Stat Bonus for HeroLevels.
requires TasUnitBonus
can use FourCCTable & Total Initialization
without Total Initialization you need to run InitTasUnitBonusHero() to create the events
example, the keys need to be supported by TasUnitBonus
TasUnitBonusHero[FourCC'Hpal'] = {
Str = 1
,["DMG+"] = 5 -- gain 5 Bonus ATK every LevelUp
,[2] = { Ability = FourCC'AHbz'} -- at level 2 add Blizzard
,[4] = {["STR+"] = 12} -- Level 4 gain 12 bonus Str
}
TasUnitBonusHero[0] = { -- hero levelup bonus for all heroes
Primary = 1
,Str = 1
,Agi = 1
,Int = 1
}
TasUnitBonusHero[udg_Unit] = { Primary = 2} -- specific levelup bonus
Level [1] can not give a bonus.
A Hero benefits from TasUnitBonusHero[0], TasUnitBonusHero[GetUnitTypeId] & TasUnitBonusHero[unit] at once.
]]
local lastLevel = __jarray(1)
if CreateFourCCTable then TasUnitBonusHero = CreateFourCCTable()
else TasUnitBonusHero = {} end
local this = TasUnitBonusHero
local function apply(data, unit, newLevel, levelUps)
if not data then return end
TasUnitBonus.UnitAdd(unit, data, levelUps)
for i = lastLevel[unit] + 1, newLevel do if data[i] and type(data[i]) == "table" then TasUnitBonus.UnitAdd(unit, data[i], 1) end end
end
function InitTasUnitBonusHero()
InitTasUnitBonusHero = DoNothing
local trig = CreateTrigger()
TriggerAddAction(trig, function()
local unit = GetTriggerUnit()
local level = GetHeroLevel(unit)
local levelUps = level - lastLevel[unit]
local unitCode = GetUnitTypeId(unit)
apply(this[unit], unit, level, levelUps) -- hero specific bonus
apply(this[0], unit, level, levelUps) -- any hero-class bonus
apply(this[unitCode], unit, level, levelUps) -- this hero-class bonus
lastLevel[unit] = level
end)
TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_HERO_LEVEL)
end
if OnInit then OnInit.trig(InitTasUnitBonusHero) end
end
if Debug then Debug.endFile() end
if Debug then Debug.beginFile "TasUnitBonusLearn" end
do
--[[ TasUnitBonusLearn by Tasyen
Code driven Stat Bonus for Heroes Learning Skills.
requires TasUnitBonus
can use FourCCTable & Total Initialization
without Total Initialization you need to run InitTasUnitBonusLearn() to create the events
you can give a bonus with TasUnitBonusLearnAction(unit, spellCode, learnedLevel).
You could do this when a skill is not learned over the default warcraft 3 learn ui.
example, the keys need to be suported by TasUnitBonus
TasUnitBonusLearn[FourCC'AHhb'] = {
["DMG+"] = 5 -- gain 5 Bonus ATK every time Skilled
,[2] = { Str = 10} -- Skilling level 2 10 base Str
}
]]
if CreateFourCCTable then TasUnitBonusLearn = CreateFourCCTable()
else TasUnitBonusLearn = {} end
local this = TasUnitBonusLearn
function TasUnitBonusLearnAction(unit, spellCode, learnedLevel)
local data = TasUnitBonusLearn[spellCode]
if not data then return end
TasUnitBonus.UnitAdd(unit, data, 1)
if data[learnedLevel] then TasUnitBonus.UnitAdd(unit, data[learnedLevel], 1) end
end
function InitTasUnitBonusLearn()
InitTasUnitBonusLearn = DoNothing
local trig = CreateTrigger()
TriggerAddAction(trig, function() TasUnitBonusLearnAction(GetTriggerUnit(), GetLearnedSkill(), GetLearnedSkillLevel()) end)
TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_HERO_SKILL)
end
if OnInit then OnInit.trig(InitTasUnitBonusLearn) end
end
if Debug then Debug.endFile() end
--[[
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
TasUnitBonusLearn[FourCC'AHhb'] = { -- HolyLight
["DMG+"] = 3 -- 3 Bonus ATK every time Skilled
,[2] = { Str = 10} -- Skilling level 2 10 base Str
}
-- 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
--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
-- 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