Dirac
22710180
- Reaction score
- 147
Hidan, the Death Acolyte
made by Dirac
made by Dirac
Hey are you a big fan of Naruto? me neither. However i did find interesting this character (Hidan) who has some uncommon battle techniques, so i made this hero about it.
Concept of the hero: This is a hero that plays with his own hp in order to damage enemies, he takes all the risks to do a lot of damage. I'm not a roleplayer so i'll stop here and let your imagination flow.
Abilities:
Axe Hurl
Hurls an axe towards a target location, dealing damage to nearby enemies and drags them back for a short distance.
Level 1 - 90 damage.
Level 2 - 140 damage.
Level 3 - 190 damage.
Level 4 - 240 damage.
JASS:
scope AxeHurl initializer start
// Axe Hurl made by Dirac
// thanks to Ryushi for providing an equation used to determine flying height
globals
private constant string TARGETFX = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl" // landing animation
private constant string MISSILEFX = "Abilities\\Weapons\\RexxarMissile\\RexxarMissile.mdl" // projectile
private constant string CHAINFX = "Abilities\\Weapons\\WardenMissile\\WardenMissile.mdl" // projectile
private constant integer ABIL = 039;A000039; // ability ID
private constant integer DUMMY = 039;h000039; // the projectile, works best with vexorian's dummy model
private constant integer MODEL = 039;h001039; // if you want a remaining effect on the ground fill this level with an unit whose model is the one wanted
private constant boolean GROUNDFX = true // this means you want a remaining effect on the ground.
private constant real TIMEOUT = 0.03125 // periodic timeout
private constant real SPEED = 40. // projectile speed
private constant real CHAINSPEED = 15. // chain speed
private constant real CHAINHEIGHT = 120. // chain initial height from the ground
private constant real SIZE = 0.7 //projectile size
private constant real HEIGHT = 340. // the max height the projectile reaches
private constant real INITIALHEIGHT = 160. // the height from where the projectile starts
private constant real AOE = 90. // the area where the damage is dealt
endglobals
private function dmg takes unit u returns real
return (GetUnitAbilityLevel(u, ABIL)*50.)+40.
endfunction
//=============DO NOT MODIFY PAST THIS POINT=============//
globals
private integer array DATA
private integer DATACOUNT = 0
private timer TIMER = CreateTimer()
private unit TEMPUNIT
endglobals
private struct data
unit c
unit array chain[1000]
effect array chainfx[1000]
integer chaincount
boolean b
real a
real z
real s
real cosa
real sina
real d
method destroy takes nothing returns nothing
call .deallocate()
endmethod
method DestroyChain takes nothing returns nothing
local integer n = 1
local real array x
local real array y
local real a
loop
exitwhen n > .chaincount
set x[1] = GetUnitX(.c)
set y[1] = GetUnitY(.c)
set x[0] = GetUnitX(.chain[n])
set y[0] = GetUnitY(.chain[n])
set a = Atan2(y[1]-y[0],x[1]-x[0])
call UnitAddAbility(.chain[n],039;Amrf039;)
call SetUnitFlyHeight(.chain[n],((CHAINHEIGHT*(n-1))/(.chaincount-1)),0.)
call UnitRemoveAbility(.chain[n],039;Amrf039;)
call SetUnitX(.chain[n],x[0]+(SPEED*Cos(a)))
call SetUnitY(.chain[n],y[0]+(SPEED*Sin(a)))
set n = n+1
if SquareRoot((x[0]-x[1])*(x[0]-x[1])+(y[0]-y[1])*(y[0]-y[1])) <= SPEED then
call RemoveUnit(.chain[.chaincount])
set .chaincount = .chaincount-1
endif
endloop
endmethod
method CreateChain takes nothing returns nothing
local real array x
local real array y
local real a
set x[0] = GetUnitX(.chain[.chaincount])
set y[0] = GetUnitY(.chain[.chaincount])
set x[1] = GetUnitX(.c)
set y[1] = GetUnitY(.c)
set a = Atan2(y[0]-y[1],x[0]-x[1])
loop
exitwhen CHAINSPEED >= SquareRoot((x[1]-x[0])*(x[1]-x[0])+(y[1]-y[0])*(y[1]-y[0]))
set .chaincount = .chaincount+1
set .chain[.chaincount] = CreateUnit(GetOwningPlayer(.c),DUMMY,x[0]-CHAINSPEED*Cos(a),y[0]-CHAINSPEED*Sin(a),bj_RADTODEG*a)
set .chainfx[.chaincount] = AddSpecialEffectTarget(CHAINFX,.chain[.chaincount],"origin")
set x[0] = GetUnitX(.chain[.chaincount])
set y[0] = GetUnitY(.chain[.chaincount])
endloop
endmethod
endstruct
private function drag takes nothing returns boolean
local unit u = GetFilterUnit()
local real a = Atan2(GetUnitY(TEMPUNIT)-GetUnitY(u),GetUnitX(TEMPUNIT)-GetUnitX(u))
if IsUnitEnemy(u, GetOwningPlayer(TEMPUNIT)) == true then
call SetUnitX(u,GetUnitX(u)+(SPEED*0.8*Cos(a)))
call SetUnitY(u,GetUnitY(u)+(SPEED*0.8*Sin(a)))
endif
return false
endfunction
private function filter takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitEnemy(u, GetOwningPlayer(TEMPUNIT)) == true then
call UnitDamageTarget(TEMPUNIT,u,dmg(TEMPUNIT),true,false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
endif
return false
endfunction
private function periodic takes nothing returns nothing
local real x
local real y
local real x1
local real y1
local real z
local integer i = 1
local integer n
local data d
local effect fx
local unit u
local group g
loop
exitwhen i>DATACOUNT
set d = DATA<i>
if d.b == false then
set d.z = d.z+SPEED
set x1 = GetUnitX(d.c)
set y1 = GetUnitY(d.c)
call d.CreateChain()
set d.s = 0.
set x = GetUnitX(d.chain[1])+(SPEED*d.cosa)
set y = GetUnitY(d.chain[1])+(SPEED*d.sina)
call UnitAddAbility(d.chain[1],039;Amrf039;)
set z = ((2*INITIALHEIGHT-4*HEIGHT)/(d.d*d.d))*d.z*d.z+((4*HEIGHT-3*INITIALHEIGHT)/d.d)*d.z+INITIALHEIGHT
call SetUnitFlyHeight(d.chain[1],z,0.)
call UnitRemoveAbility(d.chain[1],039;Amrf039;)
call SetUnitX(d.chain[1],x)
call SetUnitY(d.chain[1],y)
set n = 2
if d.z >= d.d then
set TEMPUNIT = d.c
set g = CreateGroup()
call GroupEnumUnitsInRange(g,x,y,AOE,Condition(function filter))
call DestroyGroup(g)
set d.b = true
endif
loop
exitwhen n > d.chaincount
set x = GetUnitX(d.chain[n])+(SPEED*d.cosa)
set y = GetUnitY(d.chain[n])+(SPEED*d.sina)
call SetUnitX(d.chain[n],x)
call SetUnitY(d.chain[n],y)
call UnitAddAbility(d.chain[n],039;Amrf039;)
call SetUnitFlyHeight(d.chain[n],(((CHAINHEIGHT-z)*(n-1))/(d.chaincount-1))+z,0.)
call UnitRemoveAbility(d.chain[n],039;Amrf039;)
set n = n+1
endloop
else
set x = GetUnitX(d.chain[1])
set y = GetUnitY(d.chain[1])
set fx = AddSpecialEffect(TARGETFX,x,y)
call DestroyEffect(fx)
set TEMPUNIT = d.chain[1]
set g = CreateGroup()
call GroupEnumUnitsInRange(g,x,y,AOE,Condition(function drag))
call DestroyGroup(g)
call d.DestroyChain()
if d.chaincount == 1 then
set DATA<i> = DATA[DATACOUNT]
set DATACOUNT = DATACOUNT - 1
call RemoveUnit(d.chain[1])
call d.destroy()
endif
endif
set i = i+1
endloop
if DATACOUNT == 0 then
call PauseTimer(TIMER)
endif
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real x1 = GetSpellTargetX()
local real y1 = GetSpellTargetY()
local data d = data.create()
set d.c = u
set d.chain[0] = u
set d.d = RMaxBJ(SquareRoot((x1-x)*(x1-x)+(y1-y)*(y1-y)),200.)
set d.a = Atan2(y1-y,x1-x)
set d.cosa = Cos(d.a)
set d.sina = Sin(d.a)
set d.z = 0.
set d.s = 0.
set d.b = false
set d.chaincount = 1
set d.chain[1] = CreateUnit(GetOwningPlayer(d.c),DUMMY,x,y,bj_RADTODEG*d.a)
set d.chainfx[1] = AddSpecialEffectTarget(MISSILEFX,d.chain[d.chaincount],"origin")
call SetUnitScale(d.chain[1],SIZE,SIZE,SIZE)
call UnitAddAbility(d.chain[1],039;Amrf039;)
call SetUnitFlyHeight(d.chain[1],INITIALHEIGHT,0.)
call UnitRemoveAbility(d.chain[1],039;Amrf039;)
set DATACOUNT = DATACOUNT + 1
set DATA[DATACOUNT] = d
if DATACOUNT == 1 then
call TimerStart(TIMER,TIMEOUT,true, function periodic)
endif
endfunction
private function Conditions takes nothing returns boolean
if GetSpellAbilityId()==ABIL then
call Actions()
endif
return false
endfunction
private function start takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
endfunction
endscope</i></i>
REQUIRES: vJass
Comments: pretty simple projectile made from scratch with a chain system, used for initiating purposes
Pros: It's very fast and deals decent damage, it's ranged
Cons: Low AoE
Jashin Ritual
Creates a link between the last unit Hidan dealt damage to and himself. Damage received will be caused to that unit while still inside the ritual's circle. 200 radius.
Level 1 - 40% damage.
Level 2 - 60% damage.
Level 3 - 80% damage.
Level 4 - 100% damage.
JASS:
scope JashinRitual initializer start
//Jashin Ritual made by Dirac.
globals
private constant integer ABIL = 039;A001039; // ability ID
private constant integer DUMMY = 039;h000039; // dummy ID
private constant integer FXNUMBER = 12 // number of effects surrounding the caster
private constant integer CASTERFXALPHA = 30 // percentage of transparency (0 is invisible) of the effect created at the caster
private constant real DURATION = 30. // duration of the ability
private constant real AOEFX = 350. // relation between the size of the effect and the spell's AOE
private constant real SIZE = 0.6 // size of the effects surrounding the caster
private constant string TARGETFX = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl" // effect on target every time it receives damage
private constant string DUMMYFX = "Abilities\\Spells\\Undead\\Graveyard\\GraveMarker.mdl" // effect that surrounds the caster
private constant string CASTERFX = "war3mapImported\\GrandUndeadAura.mdx" // effect placed at caster location
private constant string LINKFX = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" // effect that marks which unit is target
private constant boolean DEBUG = true // If there's any error it will be shown
private constant boolean EXIT = true // exiting the circle will cause the ability to finish
endglobals
private function getaoe takes unit u returns real
return ((GetUnitAbilityLevel(u, ABIL)*0.)+200.)
endfunction
private function getdmg takes unit u returns real
return ((GetUnitAbilityLevel(u, ABIL)*0.2)+0.2)
endfunction
//=============DO NOT MODIFY PAST THIS POINT=============//
globals
private integer array DATA
private integer DATACOUNT = 0
private timer TIMER = CreateTimer()
private trigger TRIGG = CreateTrigger()
private integer array INSTANCE
endglobals
private struct DamageData extends array
unit source
static method AIDS_filter takes unit u returns boolean
return GetUnitAbilityLevel(u,ABIL) > 0
endmethod
//! runtextmacro AIDS()
endstruct
private function LastDamagedUnit takes unit u returns unit
if IsUnitAlly(DamageData<u>.source,GetOwningPlayer(u)) then
return null
else
return DamageData<u>.source
endif
endfunction
private function ClearLastDamagedUnit takes unit u returns nothing
set DamageData<u>.source = null
endfunction
//=====================================================//
private struct data
unit a
unit c
unit array u [FXNUMBER]
effect array fx [FXNUMBER]
unit e
effect fxe
real x
real y
real d
endstruct
private function GetDatacount takes unit u returns integer
local integer i = 1
local integer n = 0
local data d
loop
exitwhen i > DATACOUNT
set d = DATA<i>
if u == d.c then
set n = n+1
set INSTANCE[n] = i
endif
set i = i+1
endloop
return n
endfunction
//=====================================================//
private function Damage takes nothing returns nothing
local effect fx
local unit eds = GetEventDamageSource()
local unit gtu = GetTriggerUnit()
local data d
local DamageData l
local real y
local real x
local real e = GetEventDamage()
local integer i = 1
if GetUnitAbilityLevel(eds,039;A001039;) > 0 then
set l = DamageData[eds]
set l.source = gtu
endif
loop
exitwhen i > GetDatacount(gtu)
set d = INSTANCE<i>
set x = GetUnitX(d.c)
set y = GetUnitY(d.c)
if d.c == gtu and SquareRoot((d.x-x)*(d.x-x)+(d.y-y)*(d.y-y)) <= getaoe(d.c) then
call DisableTrigger(TRIGG)
call UnitDamageTarget(d.c,d.a,getdmg(d.c)*e,true,false,ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
call EnableTrigger(TRIGG)
set fx = AddSpecialEffectTarget(TARGETFX,d.a,"chest")
call DestroyEffect(fx)
endif
set i = i+1
endloop
endfunction
private function periodic takes nothing returns nothing
local integer i = 1
local integer n
local data d
local real x
local real y
loop
exitwhen i > DATACOUNT
set d = DATA<i>
set x = GetUnitX(d.c)
set y = GetUnitY(d.c)
if d.d <= 0 or GetUnitState(d.a,UNIT_STATE_LIFE) <= 0 or (EXIT==true and SquareRoot((d.x-x)*(d.x-x)+(d.y-y)*(d.y-y)) > getaoe(d.c)) then
set DATA<i> = DATA[DATACOUNT]
set DATACOUNT = DATACOUNT-1
call DestroyEffect(d.fxe)
call RemoveUnit(d.e)
set n = 0
loop
exitwhen n == FXNUMBER
call DestroyEffect(d.fx[n])
call KillUnit(d.u[n])
set n = n+1
endloop
call ClearLastDamagedUnit(d.c)
call d.destroy()
if DATACOUNT == 0 then
call PauseTimer(TIMER)
endif
else
set d.d = d.d-0.1
endif
set i = i+1
endloop
endfunction
private function Actions takes nothing returns nothing
local data d = data.create()
local real x
local real y
local integer i = 0
local effect fx
local unit c = GetTriggerUnit()
local unit a
set a = LastDamagedUnit(c)
if a != null then
set d.x = GetUnitX(c)
set d.y = GetUnitY(c)
loop
exitwhen i == FXNUMBER
set x = d.x + getaoe(c)*Cos((360/FXNUMBER)*i*bj_DEGTORAD)
set y = d.y + getaoe(c)*Sin((360/FXNUMBER)*i*bj_DEGTORAD)
set d.u<i> = CreateUnit(GetOwningPlayer(c),DUMMY,x,y,bj_RADTODEG * Atan2(y-d.y,x-d.x))
set d.fx<i> = AddSpecialEffectTarget(DUMMYFX,d.u<i>,"origin")
call SetUnitScale(d.u<i>,SIZE,SIZE,SIZE)
set i = i+1
endloop
set d.c = c
set d.a = a
set d.d = DURATION
set fx = AddSpecialEffectTarget(LINKFX,d.c,"origin")
call DestroyEffect(fx)
set fx = AddSpecialEffectTarget(LINKFX,d.a,"origin")
call DestroyEffect(fx)
set d.e = CreateUnit(GetOwningPlayer(c),DUMMY,d.x,d.y,0)
set d.fxe = AddSpecialEffectTarget(CASTERFX,d.e,"origin")
call SetUnitScale(d.e,getaoe(c)/AOEFX,getaoe(c)/AOEFX,getaoe(c)/AOEFX)
call SetUnitVertexColor(d.e,255,255,255,CASTERFXALPHA*255/100)
set DATACOUNT = DATACOUNT+1
set DATA[DATACOUNT] = d
if DATACOUNT == 1 then
call TimerStart(TIMER,0.1,true,function periodic)
elseif DEBUG == true and DATACOUNT == 8191 then
call BJDebugMsg("More than 8191 indexes were used")
endif
endif
endfunction
private function Conditions takes nothing returns boolean
if GetSpellAbilityId()==ABIL then
call Actions()
endif
return false
endfunction
private function start takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call Damage_RegisterEvent(TRIGG)
call TriggerAddAction(TRIGG,function Damage)
endfunction
endscope</i></i></i></i></i></i></i></i></u></u></u>
REQUIRES: vJass, Damage
Comments: this is the MAIN ability of the hero, gives it's personal touch and signature.
Pros: Creates a very inconvenient situation for the target, damaging you could result in it's own death
Cons: You must remain inside the circle for it to do damage
Blood Craze
Whenever Hidan deals 200 damage he gains a layer of Blood Craze, each layer lasts 10 and while active makes Hidan gain hit points everytime he deals spell or attack damage. Max to 5 layers.
Level 1 - Gains 4% of attack or spell damage per layer.
Level 2 - Gains 5.5% of attack or spell damage per layer.
Level 3 - Gains 7% of attack or spell damage per layer.
Level 4 - Gains 8.5% of attack or spell damage per layer.
JASS:
scope BloodCraze initializer start
globals
private constant integer ABIL = 039;A003039; // set here the ID of the ability or buff
private constant real DAMAGE = 200. // damage that activates layers
private constant real DURATION = 10. // duration of each layers
private constant integer LAYERS = 5 // max number of layers
endglobals
private function getmult takes unit u returns real // damage reduction equation
return (GetUnitAbilityLevel(u,ABIL)*0.015)+0.025
endfunction
//=============DO NOT MODIFY PAST THIS POINT=============//
globals
private group GROUP = CreateGroup()
private integer array DATA
private integer DATACOUNT = 0
endglobals
private struct dmg
unit u
integer i
real x
timer array t[LAYERS]
endstruct
private function end takes nothing returns nothing
local dmg d = GetTimerData(GetExpiredTimer())
if d.x >= DAMAGE then
set d.x = d.x - DAMAGE
call TimerStart(GetExpiredTimer(),DURATION,false,function end)
else
set d.i = d.i-1
call SetUnitVertexColor(d.u,255-(d.i*(255/LAYERS)),255-(d.i*(255/LAYERS)),255-(d.i*(255/LAYERS)),255)
call ReleaseTimer(GetExpiredTimer())
endif
endfunction
private function Actions takes nothing returns nothing
local dmg d
local unit u = GetEventDamageSource()
local real e = GetEventDamage()
local integer i = 1
if IsUnitInGroup(u,GROUP) == false then
set d = dmg.create()
set d.u = u
set d.i = 0
set d.x = e
set DATACOUNT = DATACOUNT+1
set DATA[DATACOUNT] = d
call GroupAddUnit(GROUP,d.u)
else
loop
exitwhen i > DATACOUNT
set d = DATA<i>
if d.u == u then
set d.x = d.x + e
call SetUnitState(d.u,UNIT_STATE_LIFE,GetUnitState(d.u,UNIT_STATE_LIFE)+(getmult(u)*e*d.i))
if d.x >= DAMAGE and d.i < LAYERS then
set d.x = d.x - DAMAGE
set d.t[d.i] = NewTimer()
call SetTimerData(d.t[d.i],d)
call TimerStart(d.t[d.i],DURATION,false,function end)
set d.i = d.i + 1
call SetUnitVertexColor(d.u,255-(d.i*(255/LAYERS)),255-(d.i*(255/LAYERS)),255-(d.i*(255/LAYERS)),255)
endif
if GetUnitState(d.u,UNIT_STATE_LIFE) <= 0 then
set DATA<i> = DATA[DATACOUNT]
set DATACOUNT = DATACOUNT - 1
call GroupRemoveUnit(GROUP,d.u)
endif
endif
set i = i+1
endloop
endif
endfunction
private function Conditions takes nothing returns boolean
if GetUnitAbilityLevel(GetEventDamageSource(),ABIL) > 0 then
call Actions()
endif
return false
endfunction
private function start takes nothing returns nothing
local trigger t = CreateTrigger()
call Damage_RegisterEvent(t)
call TriggerAddCondition(t,Condition(function Conditions))
endfunction
endscope</i></i>
REQUIRES: vJass, Damage, TimerUtils
Comments: This ability adds survivability to the hero, fades the hero to black depending on the number of layers.
Pros: Makes you resistant against dps
Cons: nukes only trigger 1 layer
Pain Empathy
Redirects a portion of the damage taken by allies surrounding Hidan to himself. Lasts 10 seconds.
Level 1 - 25% damage.
Level 2 - 35% damage
Level 3 - 45% damage.
JASS:
scope PainEmpathy initializer start
globals
private constant integer ABIL = 039;A002039; // ability ID
private constant integer BUFFID = 039;B000039; //buff ID
private constant real AOE = 2000. // area of effect
private constant boolean DEBUG = false // set this to true if you want to see damage data as the spell is casted
private constant boolean PROJECTILE = true // set this to true if you want the spell to use projectiles instead of instant damage
private constant string PROJECTILEFX = "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl" // the model the projectile uses
endglobals
function getdmg takes unit u returns real
return (GetUnitAbilityLevel(u,ABIL)*0.1)+0.15
endfunction
function getlyf takes unit u returns real
return (GetUnitAbilityLevel(u,ABIL)*0.)+0.
endfunction
//=============DO NOT MODIFY PAST THIS POINT=============//
globals
private boolean BOOL = false
private unit array UNIT
private unit GTU
private integer UNITCOUNT = 0
endglobals
private function check takes nothing returns boolean
if GetUnitAbilityLevel(GetFilterUnit(),BUFFID)>0 and IsUnitAlly(GetFilterUnit(),GetOwningPlayer(GTU)) == true and GTU != GetFilterUnit() then
set BOOL = true
set UNITCOUNT = UNITCOUNT+1
set UNIT[UNITCOUNT] = GetFilterUnit()
endif
return true
endfunction
private function dmg takes nothing returns nothing
local unit e = GetEventDamageSource()
local real d = GetEventDamage()
local group g = CreateGroup()
local integer i = 1
set GTU = GetTriggerUnit()
set BOOL = false
if GetUnitAbilityLevel(e,BUFFID)>0 then
call SetUnitState(e,UNIT_STATE_LIFE,GetUnitState(e,UNIT_STATE_LIFE)+getlyf(e)*d)
if DEBUG == true then
call BJDebugMsg(GetUnitName(e)+" recieves "+R2S(getlyf(e))+" healing.")
endif
endif
if GetUnitAbilityLevel(GTU,BUFFID) == 0 then
call GroupEnumUnitsInRange(g,GetUnitX(GTU),GetUnitY(GTU), AOE,Condition(function check))
endif
if BOOL == true then
loop
exitwhen i > UNITCOUNT
call Damage_Block(d*getdmg(UNIT<i>))
if PROJECTILE == true then
call CreateProjectile(GTU,UNIT<i>,e,d*getdmg(UNIT<i>),40.,0.5,PROJECTILEFX)
else
call UnitDamageTarget(e,UNIT<i>,d*getdmg(UNIT<i>),true,false,ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
endif
if DEBUG == true then
call BJDebugMsg(R2S(d*getdmg(UNIT<i>))+" damage redirected to "+GetUnitName(UNIT<i>))
endif
set UNIT<i> = null
set i = i+1
endloop
set UNITCOUNT = 0
endif
call DestroyGroup(g)
endfunction
private function start takes nothing returns nothing
local trigger t = CreateTrigger()
call Damage_RegisterEvent(t)
call TriggerAddAction(t,function dmg)
endfunction
endscope</i></i></i></i></i></i></i></i>
REQUIRES: vJass, Damage, My own SimpleProjectile sytem
JASS:
library SimpleProjectile
globals
private timer TIMER = CreateTimer()
private real TIMEOUT = 0.0325
private integer array DATA
private integer DATACOUNT = 0
private integer DUMMY = 039;h000039;
endglobals
private struct proj
unit u
unit a
unit b
unit c
real x
real y
real z
effect fx
endstruct
private function periodic takes nothing returns nothing
local real x
local real y
local integer i = 1
local real a
local proj d
loop
exitwhen i>DATACOUNT
set d = DATA<i>
set a = Atan2(GetUnitY(d.b)-GetUnitY(d.u),GetUnitX(d.b)-GetUnitX(d.u))+d.z
set x = GetUnitX(d.u)
set y = GetUnitY(d.u)
call SetUnitX(d.u,x+d.y*Cos(a))
call SetUnitY(d.u,y+d.y*Sin(a))
if SquareRoot((GetUnitX(d.b)-x)*(GetUnitX(d.b)-x)+(GetUnitY(d.b)-y)*(GetUnitY(d.b)-y)) <= d.y+1 then
call UnitDamageTarget(d.c,d.b,d.x,true,false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
call KillUnit(d.u)
call DestroyEffect(d.fx)
call d.destroy()
set DATA<i> = DATA[DATACOUNT]
set DATACOUNT = DATACOUNT-1
if DATACOUNT == 0 then
call PauseTimer(TIMER)
endif
endif
set i = i+1
endloop
endfunction
function CreateProjectile takes unit origin, unit target, unit hostile, real damage, real speed, real curve, string fx returns nothing
local proj d = proj.create()
set d.u = CreateUnit(GetOwningPlayer(hostile),DUMMY,GetUnitX(origin),GetUnitY(origin),bj_RADTODEG*Atan2(GetUnitY(target)-GetUnitY(origin),GetUnitX(target)-GetUnitX(origin)))
set d.a = origin
set d.b = target
set d.c = hostile
set d.x = damage
set d.y = speed
set d.z = curve
set d.fx = AddSpecialEffectTarget(fx,d.u,"chest")
call SetUnitScale(d.u,.5,.5,.5)
set DATACOUNT = DATACOUNT+1
set DATA[DATACOUNT] = d
if DATACOUNT == 1 then
call TimerStart(TIMER,TIMEOUT,true,function periodic)
endif
endfunction
endlibrary</i></i>
Comments: I guess this ability is the core of all the hero synergy, if used while Jashin Ritual is active, the damage you take from this ability is transfered to the target. Both the ritual and this ability sound very situational and risky to use, but combined makes the hero an unstoppable dps truck
Pros: Prevents damage done to allies, if combined with ritual, deals a lot of damage too
Cons: If used the wrong way it can and will kill you
Screenshot
Things you may say in this thread and their answers:
This hero sounds nothing like Hidan, you have dishonored him by creating this piece of cr*p
Ok
Your coding skills are terrible
This is the first time i ever use NewGen vJass or system. Help me improve my skills
Special Thanks:
Romek for his amazing vJass tutorial
DuckieKing for his struct tutorial
emjlr3 he didnt actually helped me, but i learned some techniques from his coding in other abilities, so thanks him for that
Ryushi for the equation he provided that calculates flying height
Jesus4Lyf for his helpful systems
Vexorian and do i have to say why
Laiev for his help with codes and systems
CHANGELOG:
Version 1.0
- Submission
Version 1.1
- Death Pact damage reduction now works properly when multiple units use it at the same time
- Jashin Ritual now doesn't require GetUnitUserData to work
- Masochism layer's will now drop properly when it reaches to 5
- Fixed some weird minor bugs on Jashin Ritual's target
Version 1.2
-Jashin Ritual is now completely MUI and supports multiple isntances from the same unit
-Fixed some mayor bugs regarding Jashin Ritual
-Improved the code
Version 2.0
-Reworked most of the hero
-Death Pact is now named Pain Empathy and no longer adds the bonus global lifesteal
-Masochism is now named Blood Craze and instead of preventing damage adds bonus global lifesteal
-Axe Hurl now has a chain effect and drags enemies back a little
+rep if you liked the hero and credit if used are both very welcome