- Joined
- Apr 24, 2012
- Messages
- 5,113
[jass=]library RefractionCharge
globals
private constant integer ABIL_CODE = 'A000'
private constant real TIMEOUT = 0.03125
private constant integer CROW_FORM = 'Amrf'
//Damage types and attack types
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_DIVINE
//SFX
private constant string CHARGE_SFX = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"//Refers to the sfx created when charging.
private constant string CHARGE_ATTACH = "chest"//Refers to the attachment of ^ SFX
private constant string DAMAGE_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"//Refers to the sfx when damaging
private constant string DAMAGE_ATTACH = "overhead"
private constant string SWORD_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"//Refers to the sfx of the sword when charging.
private constant string SWORD_ATTACH = "weapon"
//Animation
private constant integer ANIM_ID = 6 //Refers to the walking animation
private constant real ANIM_SPEED = 2
endglobals
//Damage Function
private function GetDamage takes unit u returns real
return I2R((GetHeroAgi(u,true) * GetUnitAbilityLevel(u,ABIL_CODE)) + 1) + 100
endfunction
//Get Speed
private function GetSpeed takes nothing returns real
return 500 * TIMEOUT
endfunction
//Running Spell
struct RefractionCharge
private thistype next
private thistype prev
private static timer iterator = CreateTimer()
private static integer count = 0
private unit caster
private unit target
private effect sword
private method destroy takes nothing returns nothing
/*
* Deallocate this instance.
*/
call this.deallocate()
/*
* We remove the instance from the linked list.
*/
set this.next.prev = this.prev
set this.prev.next = this.next
/*
* We decrease the count by 1.
* If the count is 0, we pause the timer.
*/
set count = count - 1
if count == 0 then
call PauseTimer(iterator)
endif
/*
* We null the data in the struct.
* This is completely optional. It doesn't really make a difference
* at all. (Unless you're casting the spell some hundreds of times.)
* If you have some real memory intense systems in your map,
* you might want to do this, especially if your struct has a lot of data.
*
* These are global variables, so they will be recycled eventually.
* It's all up to you, my friend.
*/
call DestroyEffect(this.sword)
set this.sword = null
call ResetUnitAnimation(this.caster)
call SetUnitTimeScale(this.caster,1)
set this.caster = null
set this.target = null
endmethod
private static method periodic takes nothing returns nothing
/*
* Starting from the first instance, we loop
* over all the instance in the list until we hit
* a dead-end.
*/
local real x
local real y
local real x2
local real y2
local real dist
local real angle
local thistype this = thistype(0).next
loop
exitwhen this == 0
set x = GetUnitX(this.caster)
set y = GetUnitY(this.caster)
set x2 = GetUnitX(this.target)
set y2 = GetUnitY(this.target)
set angle = Atan2(y2 - y,x2 - x)
set dist = SquareRoot(Pow(x2-x,2) + Pow(y2-y2,2))
if not IsUnitType(this.caster,UNIT_TYPE_DEAD) and not IsUnitType(this.target,UNIT_TYPE_DEAD) then
if dist >= 50 then
set x = x + GetSpeed() * Cos(angle)
set y = y + GetSpeed() * Sin(angle)
//Adding Crow Form for flying
if UnitAddAbility(this.caster,CROW_FORM)and UnitRemoveAbility(this.caster,CROW_FORM) then
endif
//Moving Unit
call SetUnitPosition(this.caster,x,y)
call DestroyEffect(AddSpecialEffect(CHARGE_SFX,x,y))
call SetUnitAnimationByIndex(this.caster,ANIM_ID)
call SetUnitFacing(this.caster,angle * bj_RADTODEG)
else
call UnitDamageTargetBJ(this.caster,this.target,GetDamage(this.caster),ATTACK_TYPE,DAMAGE_TYPE)
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_SFX,this.target,DAMAGE_ATTACH))
call this.destroy()
endif
else
call this.destroy()
endif
set this = this.next
endloop
endmethod
private static method run takes nothing returns boolean
/*
* We allocate an instance.
*/
local thistype this = thistype.allocate()
/*
* We add the instance to the linked list.
*/
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
/*
* We increase the count by 1.
* If the count is 1, we start the timer to loop through
* the instances. This is because recasting the spell while
* an instance is already running shouldn't restart the timer.
*/
set count = count + 1
if count == 1 then
call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
endif
/*
* We set our struct data.
*/
set this.caster = GetTriggerUnit()
set this.target = GetSpellTargetUnit()
set this.sword = AddSpecialEffectTarget(SWORD_SFX,this.caster,SWORD_ATTACH)
//Setting Animation Speed
call SetUnitTimeScale(this.caster,ANIM_SPEED)
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.run))
set t = null
endmethod
endstruct
endlibrary[/code]
There is something wrong in here,but i dont know.
If i cast this on a unit in the same axis,it just stops,no matter how far.But if not on the same axis,it just move smoothly,Any help?
globals
private constant integer ABIL_CODE = 'A000'
private constant real TIMEOUT = 0.03125
private constant integer CROW_FORM = 'Amrf'
//Damage types and attack types
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_DIVINE
//SFX
private constant string CHARGE_SFX = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"//Refers to the sfx created when charging.
private constant string CHARGE_ATTACH = "chest"//Refers to the attachment of ^ SFX
private constant string DAMAGE_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"//Refers to the sfx when damaging
private constant string DAMAGE_ATTACH = "overhead"
private constant string SWORD_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"//Refers to the sfx of the sword when charging.
private constant string SWORD_ATTACH = "weapon"
//Animation
private constant integer ANIM_ID = 6 //Refers to the walking animation
private constant real ANIM_SPEED = 2
endglobals
//Damage Function
private function GetDamage takes unit u returns real
return I2R((GetHeroAgi(u,true) * GetUnitAbilityLevel(u,ABIL_CODE)) + 1) + 100
endfunction
//Get Speed
private function GetSpeed takes nothing returns real
return 500 * TIMEOUT
endfunction
//Running Spell
struct RefractionCharge
private thistype next
private thistype prev
private static timer iterator = CreateTimer()
private static integer count = 0
private unit caster
private unit target
private effect sword
private method destroy takes nothing returns nothing
/*
* Deallocate this instance.
*/
call this.deallocate()
/*
* We remove the instance from the linked list.
*/
set this.next.prev = this.prev
set this.prev.next = this.next
/*
* We decrease the count by 1.
* If the count is 0, we pause the timer.
*/
set count = count - 1
if count == 0 then
call PauseTimer(iterator)
endif
/*
* We null the data in the struct.
* This is completely optional. It doesn't really make a difference
* at all. (Unless you're casting the spell some hundreds of times.)
* If you have some real memory intense systems in your map,
* you might want to do this, especially if your struct has a lot of data.
*
* These are global variables, so they will be recycled eventually.
* It's all up to you, my friend.
*/
call DestroyEffect(this.sword)
set this.sword = null
call ResetUnitAnimation(this.caster)
call SetUnitTimeScale(this.caster,1)
set this.caster = null
set this.target = null
endmethod
private static method periodic takes nothing returns nothing
/*
* Starting from the first instance, we loop
* over all the instance in the list until we hit
* a dead-end.
*/
local real x
local real y
local real x2
local real y2
local real dist
local real angle
local thistype this = thistype(0).next
loop
exitwhen this == 0
set x = GetUnitX(this.caster)
set y = GetUnitY(this.caster)
set x2 = GetUnitX(this.target)
set y2 = GetUnitY(this.target)
set angle = Atan2(y2 - y,x2 - x)
set dist = SquareRoot(Pow(x2-x,2) + Pow(y2-y2,2))
if not IsUnitType(this.caster,UNIT_TYPE_DEAD) and not IsUnitType(this.target,UNIT_TYPE_DEAD) then
if dist >= 50 then
set x = x + GetSpeed() * Cos(angle)
set y = y + GetSpeed() * Sin(angle)
//Adding Crow Form for flying
if UnitAddAbility(this.caster,CROW_FORM)and UnitRemoveAbility(this.caster,CROW_FORM) then
endif
//Moving Unit
call SetUnitPosition(this.caster,x,y)
call DestroyEffect(AddSpecialEffect(CHARGE_SFX,x,y))
call SetUnitAnimationByIndex(this.caster,ANIM_ID)
call SetUnitFacing(this.caster,angle * bj_RADTODEG)
else
call UnitDamageTargetBJ(this.caster,this.target,GetDamage(this.caster),ATTACK_TYPE,DAMAGE_TYPE)
call DestroyEffect(AddSpecialEffectTarget(DAMAGE_SFX,this.target,DAMAGE_ATTACH))
call this.destroy()
endif
else
call this.destroy()
endif
set this = this.next
endloop
endmethod
private static method run takes nothing returns boolean
/*
* We allocate an instance.
*/
local thistype this = thistype.allocate()
/*
* We add the instance to the linked list.
*/
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
/*
* We increase the count by 1.
* If the count is 1, we start the timer to loop through
* the instances. This is because recasting the spell while
* an instance is already running shouldn't restart the timer.
*/
set count = count + 1
if count == 1 then
call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
endif
/*
* We set our struct data.
*/
set this.caster = GetTriggerUnit()
set this.target = GetSpellTargetUnit()
set this.sword = AddSpecialEffectTarget(SWORD_SFX,this.caster,SWORD_ATTACH)
//Setting Animation Speed
call SetUnitTimeScale(this.caster,ANIM_SPEED)
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.run))
set t = null
endmethod
endstruct
endlibrary[/code]
There is something wrong in here,but i dont know.
If i cast this on a unit in the same axis,it just stops,no matter how far.But if not on the same axis,it just move smoothly,Any help?