Moderator
M
Moderator
15:03, 5th Feb 2010
TriggerHappy:
Took my updates.
TriggerHappy:
Took my updates.
library Windcut initializer InitWindCut requires TimerUtils,GroupUtils,MathBasic,TimedFadeUnit,TimedAnimationStop,Group2Group
//SETTINGS
globals
// ID's
private constant integer Spell_ID = 'A000' // spell ID must match this value
private constant integer Dummy_ID = 'e000' // dummy unit Id must match this value
// end of ID setup
private constant boolean InvulnerableCaster = false // if true caster is invulnerable
// damage
private constant real BaseDamage = 60.00 // base damage per slash
private constant real DamageInc = 25 // damage added on base damage with every levelup of the ability
// end of damage options
// eyecandy
private constant string SlashEff = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" // effect created on unit strike
private constant string WeaponEff = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl" // effect created on illusions blade
private constant string TrailEff = "Abilities\\Weapons\\GlaiveMissile\\GlaiveMissileTarget.mdl" // trail effect which is created on the ground as the hero moves
private constant integer ESR = 3 // ESR = Effect Spam Ration, increase in this = less effects, decrease = more effects (used for trail effects)
// end of eyecandy options
// fade options
private constant real CasterFade = 0.55 // takes a value from 0.00 to 1.00; 0.00 is transparent, 1.00 is normal value of every unit.
// 0.7 = 70% visibility, 30% transparency
private constant real ImageFade = 0.45 // same as CasterFade but for illusions
private constant real FadeTime = 0.3 // fade time for illusions, 0.3 = 0.3 seconds of delay before the trail illusions behind the heroes are removed
private constant real AnimStopValue = 0.85 // varies from model to model, takes a value when the animation is stoped
// blademaster's animation of attack ("attack") is 1.167 seconds so this is
// a user defined value, there is no equation for it
private constant real FadeTimeEx = 3.00 // this value is used for the illusions that play the attack animation
// this value should be larget than FadeTime to show the full eyecandy
// and the effect of TimedAnimationStop
// end of fade options
// speed related things
private constant real FPS = 30.00 // optimal values from 30 to 60
private constant real ChargeSpeed = 1025 * (1/FPS) // speed of the hero,uses WC3 movement speed values, don't touch anything after the sign *
private constant real AoE = 366.66 // AoE which is actualy used for a strange AoE calculated by distance from caster to cast point
// end of speed options
endglobals
//END OF SETTINGS
// Don't Touch the stuff bellow this point
globals
private unit TU = null
private player TP = null
private real TR = 0.00
private group FG = CreateGroup()
private constant real MinOffset = 50.00
endglobals
private function GroupFilter takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > .405 and IsUnitInGroup(GetFilterUnit(),FG)==false and GetFilterUnit() != TU and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)==false and IsUnitEnemy(GetFilterUnit(),TP) and IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL)==false
endfunction
private function groupfunc takes nothing returns nothing
call GroupAddUnit(FG,GetEnumUnit())
endfunction
private constant function GetDamage takes integer lvl returns real
return BaseDamage + (lvl-1)*DamageInc
endfunction
private function ExtractInteger takes real r returns integer
local integer i = R2I(r)
local real s = r - I2R(i)
if s >= 0.50 then
set i = i+1
endif
return i
endfunction
private function condition2run takes nothing returns boolean
local windcut this
local real d
local integer groupnum
local integer i
local real x
local real y
if GetSpellAbilityId() == Spell_ID then
set this = windcut.Create()
set this.g = NewGroup()
set this.d = NewGroup()
set this.u = GetTriggerUnit()
set this.t = NewTimer()
set this.x = GetUnitX(this.u)
set this.y = GetUnitY(this.u)
set this.tpx = GetSpellTargetX()
set this.tpy = GetSpellTargetY()
set this.rad = RBL(this.x,this.y,this.tpx,this.tpy)
set this.dmg = GetDamage(GetUnitAbilityLevel(this.u,Spell_ID))
call SetUnitVertexColor(this.u,255,255,255, 255 - R2I(CasterFade*255))
if InvulnerableCaster then
call SetUnitInvulnerable(this.u,true)
endif
call PauseUnit(this.u,true)
set d = DBL(this.x,this.y,this.tpx,this.tpy)
set groupnum = ExtractInteger(d / AoE)
set i = 0
set x = this.x
set y = this.y
if groupnum < 1 then
set groupnum = 1
endif
loop
exitwhen i > groupnum
set TU = this.u
set TP = GetOwningPlayer(TU)
call GroupEnumUnitsInRange(this.d,x,y,AoE,Filter(function GroupFilter))
call ForGroup(this.d,function groupfunc)
call Group2Group(this.d,this.g)
set x = x + (AoE) * Cos(this.rad)
set y = y + (AoE) * Sin(this.rad)
call GroupClear(this.d)
set i = i+1
endloop
call GroupClear(FG)
call SetTimerData(this.t,integer(this))
call TimerStart(this.t,1/FPS,true,function windcut.motion)
set this.tar = FirstOfGroup(this.g)
set this.tx = GetUnitX(this.tar)
set this.ty = GetUnitY(this.tar)
set this.rad = RBL(this.x,this.y,this.tx,this.ty)
endif
return false
endfunction
struct windcut
unit u
unit tar
group g
group d
timer t
real x
real y
real tx
real ty
real rad
real tpx
real tpy
real dmg
method onDestroy takes nothing returns nothing
call SetUnitVertexColor(this.u,255,255,255,255)
if InvulnerableCaster then
call SetUnitInvulnerable(this.u,false)
endif
call PauseUnit(this.u,false)
set this.u = null
call GroupClear(this.g)
call GroupClear(this.d)
call ReleaseGroup(this.g)
call ReleaseGroup(this.d)
set this.g = null
set this.d = null
endmethod
static method Create takes nothing returns windcut
local windcut this = windcut.allocate()
return(this)
endmethod
static method motion takes nothing returns nothing
local windcut this = GetTimerData(GetExpiredTimer())
local unit tu = CreateUnit(GetOwningPlayer(this.u),Dummy_ID,this.x,this.y,this.rad*bj_RADTODEG)
call SetUnitX(tu,this.x)
call SetUnitY(tu,this.y)
call SetUnitFacing(this.u,this.rad*bj_RADTODEG)
if this.tar != null then
set this.tx = GetUnitX(this.tar)
set this.ty = GetUnitY(this.tar)
set this.rad = RBL(this.x,this.y,this.tx,this.ty)
set this.x = this.x + ChargeSpeed * Cos(this.rad)
set this.y = this.y + ChargeSpeed * Sin(this.rad)
call SetUnitX(this.u,this.x)
call SetUnitY(this.u,this.y)
if TrailEff != "" and GetRandomInt(0,ESR) == ESR then
call DestroyEffectTimed(AddSpecialEffect(TrailEff,this.x,this.y),1)
endif
if DBL(this.x,this.y,this.tx,this.ty) <= 128 and this.tar != null then
call UnitDamageTarget(this.u,this.tar,this.dmg,true,false,null,null,null)
if WeaponEff != "" then
call DestroyEffectTimed(AddSpecialEffectTarget(WeaponEff,tu,"weapon"),3)
endif
if SlashEff != "" then
call DestroyEffectTimed(AddSpecialEffectTarget(SlashEff,this.tar,"chest"),2)
endif
call SetUnitAnimation(tu,"attack")
call FadeUnitTimed(tu,FadeTimeEx,ImageFade)
call StopAnimationTimed(tu,0.80)
call GroupRemoveUnit(this.g,this.tar)
set this.tar = FirstOfGroup(this.g)
else
call FadeUnitTimed(tu,FadeTime,ImageFade)
endif
else
if DBL(this.x,this.y,this.tpx,this.tpy) <= MinOffset then
call RemoveUnit(tu)
call PauseTimer(GetExpiredTimer())
call ReleaseTimer(GetExpiredTimer())
set this.t = null
call this.destroy()
else
if TrailEff != "" and GetRandomInt(0,ESR) == ESR then
call DestroyEffectTimed(AddSpecialEffect(TrailEff,this.x,this.y),1)
endif
set this.rad = RBL(this.x,this.y,this.tpx,this.tpy)
set this.x = this.x + ChargeSpeed * Cos(this.rad)
set this.y = this.y + ChargeSpeed * Sin(this.rad)
call SetUnitX(this.u,this.x)
call SetUnitY(this.u,this.y)
call FadeUnitTimed(tu,FadeTime,ImageFade)
endif
endif
if this.x > MaxX or this.x < MinX or this.y > MaxY or this.y < MinY then
set this.tar = null
set this.x = this.x - ChargeSpeed * Cos(this.rad)
set this.y = this.y - ChargeSpeed * Sin(this.rad)
set this.tpx = this.x
set this.tpy = this.y
endif
endmethod
endstruct
private function InitWindCut takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function condition2run))
call GroupClear(FG)
endfunction
endlibrary