показывает количество нанесенного урона, сколько осталось жизни у моба, регенерация жизни и т.д.
Скорость регинирации
private keyword Data // DO NOT TOUCH!
globals
private constant integer AID = 'A001' // ability triggering this
private constant integer BID = 'B000' // buff placed by AID on the target unit
private constant integer DAMAGE_MOD_PRIORITY = 0 // refer to DamageModifiers documentation
private real array AOE // Heals all units around the damaged target in this area
private integer array MAXIMUM_HEALINGS // number of times an instance can trigger. Set to 0 to unlimit.
private real array HEAL_AMOUNT // Amount of HP healed on affected units. Values in between 0 and 1 (excluding the borders) turn it into an amount relative to the current maximum HP of the affected unit.
private constant string HEAL_FX = "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl"
private constant string HEAL_FX_ATTPT = "origin"
private constant real HEAL_FX_DURATION = 1.833 // 0 or less only plays the death animation
private constant real TICK = 1./8
endglobals
private function SetUpAOE takes nothing returns nothing
set AOE[1]=200.
set AOE[2]=275.
set AOE[3]=350.
endfunction
private function Aoe takes integer level returns real
return AOE[level]
endfunction
private function SetUpMAXIMUM_HEALINGS takes nothing returns nothing
set MAXIMUM_HEALINGS[1]=0
set MAXIMUM_HEALINGS[2]=0
set MAXIMUM_HEALINGS[3]=0
endfunction
private function Maximum_Healings takes integer level returns integer
return MAXIMUM_HEALINGS[level]
endfunction
private function SetUpHEAL_AMOUNT takes nothing returns nothing
set HEAL_AMOUNT[1]=15.
set HEAL_AMOUNT[2]=20.
set HEAL_AMOUNT[3]=25.
endfunction
private function Heal_Amount takes integer level returns real
return HEAL_AMOUNT[level]
endfunction
private function ValidHealTarget takes unit u, Data s returns boolean
return IsUnitEnemy(u, GetOwningPlayer(s.caster))==false/*
*/ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/*
*/ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/*
*/ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/*
*/ and u!=s.target/*
*/
endfunction
//
private struct Data extends DamageModifier
unit caster
unit target
integer level
integer healings=0
private integer i
private static thistype array Structs
private static integer Count=0
private static timer T=CreateTimer()
private static thistype tmps
private static boolexpr HealFilter
private method onDestroy takes nothing returns nothing
set .caster=null
set .target=null
set .Count=.Count-1
set .Structs[.i]=Structs[.Count]
set .Structs[.i].i=.i
if .Count==0 then
call PauseTimer(.T)
endif
endmethod
private static method HealFilterFunc takes nothing returns boolean
local unit u=GetFilterUnit()
if ValidHealTarget(u, .tmps) then
if Heal_Amount(.tmps.level)>=1 then
call SetWidgetLife(u, GetWidgetLife(u)+Heal_Amount(.tmps.level))
elseif Heal_Amount(.tmps.level)>0 then
call SetWidgetLife(u, GetWidgetLife(u)+(Heal_Amount(.tmps.level)*GetUnitState(u, UNIT_STATE_MAX_LIFE)))
endif
if HEAL_FX_DURATION>0 then
call DestroyEffectTimed(AddSpecialEffectTarget(HEAL_FX, u, HEAL_FX_ATTPT), HEAL_FX_DURATION)
else
call DestroyEffect(AddSpecialEffectTarget(HEAL_FX, u, HEAL_FX_ATTPT))
endif
endif
set u=null
return false
endmethod
method onDamageTaken takes unit damageSource, real damage returns real
set .tmps=this
call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(.target), GetUnitY(.target), Aoe(.level), .HealFilter)
if HEAL_FX_DURATION>0 then
call DestroyEffectTimed(AddSpecialEffectTarget(HEAL_FX, .target, HEAL_FX_ATTPT), HEAL_FX_DURATION)
else
call DestroyEffect(AddSpecialEffectTarget(HEAL_FX, .target, HEAL_FX_ATTPT))
endif
set .healings=.healings+1
if Maximum_Healings(.level)>0 and .healings>=Maximum_Healings(.level) then
call UnitRemoveAbility(.target, BID)
call .destroy()
endif
if Heal_Amount(.level)>=1 then
return -Heal_Amount(.level)
elseif Heal_Amount(.level)>0 then
return -(Heal_Amount(.level)*GetUnitState(.target, UNIT_STATE_MAX_LIFE))
endif
return 0.
endmethod
private static method Callback takes nothing returns nothing
local integer i=.Count-1
local thistype s
loop
exitwhen i<0
set s=.Structs[i]
if GetUnitAbilityLevel(s.target, BID)<=0 then
call s.destroy()
endif
set i=i-1
endloop
endmethod
static method create takes unit caster, unit target returns thistype
local thistype s=.allocate(target, DAMAGE_MOD_PRIORITY)
set s.caster=caster
set s.target=target
set s.level=GetUnitAbilityLevel(caster, AID)
set .Structs[.Count]=s
set s.i=.Count
if .Count==0 then
call TimerStart(.T, TICK, true, function thistype.Callback)
endif
set .Count=.Count+1
return s
endmethod
private static method onInit takes nothing returns nothing
set .HealFilter=Condition(function thistype.HealFilterFunc)
call SetUpAOE()
call SetUpMAXIMUM_HEALINGS()
call SetUpHEAL_AMOUNT()
endmethod
endstruct
private function CastResponse takes nothing returns nothing
call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit)
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectResponse(AID, CastResponse)
endfunction
endlibrary
Длительный срок
private keyword Data
globals
private constant integer AID = 'A000'
private constant integer BID = 'B001'
private constant string FX = "Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl"
private constant string FX_ATTPT = "origin"
private constant integer PRIORITY = 0 // Refer to DamageModifiers documentation
private real array HEALTH_RESTORED // values >0 but <1 are values relative to the targets maximum health, values >=1 are absolute values
private constant real TICK = 1./8
endglobals
private function SetUpHEALTH_RESTORED takes nothing returns nothing
set HEALTH_RESTORED[1]=0.10
set HEALTH_RESTORED[2]=0.20
set HEALTH_RESTORED[3]=0.30
endfunction
private function Health_Restored takes integer level returns real
return HEALTH_RESTORED[level]
endfunction
//
private struct Data extends DamageModifier
unit target
integer level
private integer i
private static thistype array Structs
private static integer Count=0
private static timer T=CreateTimer()
static thistype array Instance
private method onDestroy takes nothing returns nothing
set Instance[GetUnitId(.target)]=0
set .target=null
set .Count=.Count-1
set .Structs[.i]=Structs[.Count]
set .Structs[.i].i=.i
if .Count==0 then
call PauseTimer(.T)
endif
endmethod
private method onDamageTaken takes unit origin, real damage returns real
if GetUnitAbilityLevel(.target, BID)<=0 then
call .destroy()
return 0.
endif
if damage>=GetWidgetLife(.target)-0.406 then
if Health_Restored(.level)>=1 then
set damage=GetWidgetLife(.target)-Health_Restored(.level)-damage
call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT))
elseif Health_Restored(.level)>0 then
set damage=GetWidgetLife(.target)-Health_Restored(.level)*GetUnitState(.target, UNIT_STATE_MAX_LIFE)-damage
call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT))
else
// break here, user doesnt want me to do anything (GET YER DAMN CONFIG RIGHT!)
set damage=0
endif
call UnitRemoveAbility(.target, BID)
call .destroy()
return damage
endif
return 0.
endmethod
private static method Callback takes nothing returns nothing
local integer i=.Count-1
local thistype s
loop
exitwhen i<0
set s=.Structs[i]
if GetUnitAbilityLevel(s.target, BID)<=0 then
call s.destroy()
endif
set i=i-1
endloop
endmethod
static method create takes unit caster, unit target returns thistype
local thistype s=Instance[GetUnitId(target)]
if s==0 then
set s=.allocate(target, PRIORITY)
set s.target=target
set s.level=GetUnitAbilityLevel(caster, AID)
set Instance[GetUnitId(target)]=s
set .Structs[.Count]=s
set s.i=.Count
if .Count==0 then
call TimerStart(.T, TICK, true, function thistype.Callback)
endif
set .Count=.Count+1
else
if s.level
endif
endif
return s
endmethod
endstruct
private function CastResponse takes nothing returns nothing
call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit)
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectResponse(AID, CastResponse)
call SetUpHEALTH_RESTORED()
endfunction
endlibrary
Сокрушения рвения
globals
private constant integer AID = 'A002'
private constant string DAMAGE_FX = "Abilities\\Spells\\Human\\Feedback\\SpellBreakerAttack.mdl"
private constant string DAMAGE_FX_ATTPT = "overhead"
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
private real array AOE // enemy units within this radius get damaged
private real array MANA_COST // this ability drains this much additional mana from the caster, values >0 but <1 are values relative to the maximum mana of the caster
private constant integer ATTRIBUTE = bj_HEROSTAT_INT // use an invalid value to use the highest attribute of the caster
private real array ATTRIBUTE_FACTOR // the heros attribute used multiplied by this gives the amount of damage inflicted
private real array FALLBACK_DAMAGE // only used if caster has no attributes > 0 (typically because he is not a hero)
endglobals
private function SetUpAOE takes nothing returns nothing
set AOE[1]=300.
set AOE[2]=375.
set AOE[3]=450.
endfunction
private function Aoe takes integer level returns real
return AOE[level]
endfunction
private function SetUpMANA_COST takes nothing returns nothing
set MANA_COST[1]=20.
set MANA_COST[2]=20.
set MANA_COST[3]=20.
endfunction
private function Mana_Cost takes integer level returns real
return MANA_COST[level]
endfunction
private function SetUpATTRIBUTE_FACTOR takes nothing returns nothing
set ATTRIBUTE_FACTOR[1]=2.
set ATTRIBUTE_FACTOR[2]=3.
set ATTRIBUTE_FACTOR[3]=4.
endfunction
private function Attribute_Factor takes integer level returns real
return ATTRIBUTE_FACTOR[level]
endfunction
private function SetUpFALLBACK_DAMAGE takes nothing returns nothing
set FALLBACK_DAMAGE[1]=60.
set FALLBACK_DAMAGE[2]=120.
set FALLBACK_DAMAGE[3]=180.
endfunction
private function Fallback_Damage takes integer level returns real
return FALLBACK_DAMAGE[level]
endfunction
private function ValidateTarget takes unit u returns boolean
return IsUnitEnemy(u, GetOwningPlayer(SpellEvent.CastingUnit))/*
*/ and IsUnitType(u, UNIT_TYPE_DEAD)==false/*
*/ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/*
*/ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/*
*/ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/*
*/ and IsUnitVisible(u, GetOwningPlayer(SpellEvent.CastingUnit))/*
*/
endfunction
//
globals
private boolexpr DamageFilter
private real tmpdam
endglobals
private function DamageFilterFunc takes nothing returns boolean
local unit u=GetFilterUnit()
if ValidateTarget(u) then
call UnitDamageTarget(SpellEvent.CastingUnit, u, tmpdam, true, true, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_FX, u, DAMAGE_FX_ATTPT))
endif
set u=null
return false
endfunction
private function CastResponse takes nothing returns nothing
local integer level = GetUnitAbilityLevel(SpellEvent.CastingUnit, AID)
local integer attrib
if level>0 then
set attrib=GetHeroStatBJ(ATTRIBUTE, SpellEvent.CastingUnit, true)
if attrib<=0 then
set attrib=IMaxBJ(IMaxBJ(GetHeroStr(SpellEvent.CastingUnit, true), GetHeroAgi(SpellEvent.CastingUnit, true)), GetHeroInt(SpellEvent.CastingUnit, true))
endif
if attrib>0 then
set tmpdam=attrib*Attribute_Factor(level)
else
set tmpdam=Fallback_Damage(level)
endif
call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(SpellEvent.CastingUnit), GetUnitY(SpellEvent.CastingUnit), Aoe(level), DamageFilter)
if Mana_Cost(level)>=1 then
call SetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA, GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA)-Mana_Cost(level))
elseif Mana_Cost(level)>0 then
call SetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA, GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA) - Mana_Cost(level)*GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA))
endif
endif
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectResponse(0, CastResponse)
set DamageFilter=Condition(function DamageFilterFunc)
call SetUpAOE()
call SetUpMANA_COST()
call SetUpATTRIBUTE_FACTOR()
call SetUpFALLBACK_DAMAGE()
endfunction
endlibrary
Нанесения урона
private keyword Data
globals
private constant integer AID = 'A003'
private constant integer BID = 'B002'
private constant integer PRIORITY = 0 // refer to DamageModifiers documentation
private constant string FX = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
private constant string FX_ATTPT = "head"
private constant real FX_DURATION = 0 // 0 or less only plays the death animation
private real array MAX_REVERSED // reverses this much damage at most
private constant real TICK = 1./8
endglobals
private function SetUpMAX_REVERSED takes nothing returns nothing
set MAX_REVERSED[1]=100.
endfunction
private function Max_Reversed takes integer level returns real
return MAX_REVERSED[level]
endfunction
private struct Data extends DamageModifier
unit target
integer level
private integer i
private static thistype array Structs
private static integer Count=0
private static timer T=CreateTimer()
static integer array Instances
private method onDestroy takes nothing returns nothing
local integer id=GetUnitId(.target)
set .Instances[id]=.Instances[id]-1
if .Instances[id]<=0 then
call UnitRemoveAbility(.target, BID)
endif
set .target=null
set .Count=.Count-1
set .Structs[.i]=Structs[.Count]
set .Structs[.i].i=.i
if .Count==0 then
call PauseTimer(.T)
endif
endmethod
private method onDamageTaken takes unit origin, real damage returns real
if GetUnitAbilityLevel(.target, BID)>0 then
if damage>0 then
set damage=RMinBJ(damage, Max_Reversed(.level)) // 0 < damage < Max_Reversed
if FX_DURATION>0 then
call DestroyEffectTimed(AddSpecialEffectTarget(FX, .target, FX_ATTPT), FX_DURATION)
else
call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT))
endif
call .destroy()
return -2*damage
else // target is already being healed, dont do anything
return 0.
endif
endif
call .destroy()
return 0.
endmethod
private static method Callback takes nothing returns nothing
local integer i=.Count-1
local thistype s
loop
exitwhen i<0
set s=.Structs[i]
if GetUnitAbilityLevel(s.target, BID)<=0 then
call s.destroy()
endif
set i=i-1
endloop
endmethod
static method create takes unit caster, unit target returns thistype
local thistype s=.allocate(target, PRIORITY)
set s.target=target
set s.level=GetUnitAbilityLevel(caster, AID)
set .Instances[GetUnitId(target)]=.Instances[GetUnitId(target)]+1
set .Structs[.Count]=s
set s.i=.Count
if .Count==0 then
call TimerStart(.T, TICK, true, function thistype.Callback)
endif
set .Count=.Count+1
return s
endmethod
endstruct
private function CastResponse takes nothing returns nothing
call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit)
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectResponse(AID, CastResponse)
call SetUpMAX_REVERSED()
endfunction
endlibrary