Name | Type | is_array | initial_value |
Dest | destructable | No | |
DestChecker | unit | No | |
IsDestTree | boolean | No | |
IsDestTreeTrigger | trigger | No | |
TempLoc | location | No | |
TempUnit | unit | No | |
TreeKill | boolean | No | |
WAx_A2 | real | No | |
WAx_B | real | No | |
WildAxes_A | real | Yes | |
WildAxes_Ability | abilcode | No | |
WildAxes_Ang | real | Yes | |
WildAxes_Angle | real | Yes | |
WildAxes_Area | real | Yes | |
WildAxes_AT | attacktype | No | |
WildAxes_Atan2 | real | No | |
WildAxes_Axe | unit | Yes | |
WildAxes_Caster | unit | Yes | |
WildAxes_CasterX | real | Yes | |
WildAxes_CasterY | real | Yes | |
WildAxes_CoordX | real | No | |
WildAxes_CoordY | real | No | |
WildAxes_Damage | real | Yes | |
WildAxes_DT | damagetype | No | |
WildAxes_Dummy | unitcode | No | |
WildAxes_FirstPhase | boolean | Yes | |
WildAxes_Group | group | Yes | |
WildAxes_Index | integer | No | |
WildAxes_Level | integer | Yes | |
WildAxes_LocationX | real | Yes | |
WildAxes_LocationY | real | Yes | |
WildAxes_LoopTime | real | No | |
WildAxes_LoopTimer | timer | No | |
WildAxes_LoopTrigger | trigger | No | |
WildAxes_MaxIndex | integer | No | |
WildAxes_OutputX | real | Yes | |
WildAxes_OutputY | real | Yes | |
WildAxes_Player | player | Yes | |
WildAxes_Point | location | No | |
WildAxes_SFX | string | No | |
WildAxes_SFX_Attachment | string | No | |
WildAxes_Speed | real | Yes | |
WildAxes_StartLoop | boolean | No | |
WildAxes_TempGroup | group | No | |
WildAxes_UnitInGroup | unit | No | |
WildAxes_Width | real | Yes |
//TESH.scrollpos=67
//TESH.alwaysfold=0
scope WildAxes
//******************************************************************************************
//*
//* Wild Axes - By emjlr3, Original seen in DotA Allstars
//*
//* Hurl two axes outward, which then intersect and return. Each axe can
//* only damage a unit once and destroys trees in its wake.
//*
//* Requires:
//* - "TT" trigger copied to your map, if not already there
//* - The "Wild Axes" ability copied to your map
//* - The "Wild Axes" unit copied to your map
//* - A vJASS Preprocessor
//*
//******************************************************************************************
globals
// Config. Globals:
private constant integer abil_id = 'A001' // Wild Axes ability rawcode
private constant integer dummy_id = 'e000' // Wild Axes unit rawcode
private constant real speed = .028 // Speed for axes, this is an arbitrary value, increasing it increases the axes speed, while decreasing it decreases their speed
private constant real width = 375. // Width for bezier curve, larger values give a wider arc, and vice versa
private constant real area = 150. // Area to damage units around axes and destroy trees
private constant string sfx = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" // Effect created on hit units
private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type for damage
private constant damagetype damage_type = DAMAGE_TYPE_MAGIC // Damage type for damage
// Needed Globals:
public trigger Trigger = null // Output trigger will be WildAxes_Trigger, which can be used publically
private group G = CreateGroup()
private group TempG = null
private player P = null
private location L = null
private rect R = null
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
return 20.+(lvl*40.) // Damage/lvl
endfunction
private struct data
unit u
unit axe
player p
group grp
real x
real y
real xl
real yl
real a = 1.
real outx
real outy
real ang
integer lvl
boolean first = true
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId()==abil_id
endfunction
private function Filt takes nothing returns boolean
return not IsUnitInGroup(GetFilterUnit(),TempG) and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and IsUnitEnemy(GetFilterUnit(),P)
endfunction
private function Kill_Trees takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function Effects takes unit u, real x, real y, group grp, integer lvl returns nothing
local unit dum
set R = Rect(x-150.,y-150.,x+150.,y+150.)
call EnumDestructablesInRect(R,null,function Kill_Trees)
call RemoveRect(R)
call GroupClear(G)
set P = GetOwningPlayer(u)
set TempG = grp
call GroupEnumUnitsInRange(G,x,y,area,Condition(function Filt))
loop
set dum = FirstOfGroup(G)
exitwhen dum==null
call GroupRemoveUnit(G,dum)
call UnitDamageTarget(u,dum,Damage(lvl),false,false,attack_type,damage_type,null)
call DestroyEffect(AddSpecialEffectTarget(sfx,dum,"chest"))
call GroupAddUnit(grp,dum)
endloop
endfunction
private function Movement takes nothing returns boolean
local data d = TT_GetData()
local real b = 1.-d.a
call SetUnitX(d.axe,d.x*d.a*d.a+d.outx*2*d.a*b+d.xl*b*b)
call SetUnitY(d.axe,d.y*d.a*d.a+d.outy*2*d.a*b+d.yl*b*b)
call Effects(d.u,GetUnitX(d.axe),GetUnitY(d.axe),d.grp,d.lvl)
if d.first then
set d.a = d.a-speed
else
set d.a = d.a+speed
set d.x = GetUnitX(d.u)
set d.y = GetUnitY(d.u)
endif
if d.a<0. and d.first then
set d.first = false
set d.outx = d.x+width*Cos(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
set d.outy = d.y+width*Sin(Atan2(d.yl-d.y,d.xl-d.x)+d.ang)
endif
if d.a>1. and d.first==false then
call DestroyGroup(d.grp)
call RemoveUnit(d.axe)
call d.destroy()
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local data d1 = data.create()
local data d2 = data.create()
set d1.u = GetTriggerUnit()
set d2.u = d1.u
set d1.x = GetUnitX(d1.u)
set d2.x = d1.x
set d1.y = GetUnitY(d1.u)
set d2.y = d1.y
set d1.p = GetOwningPlayer(d1.u)
set d2.p = d1.p
set d1.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d2.axe = CreateUnit(d1.p,dummy_id,d1.x,d1.y,0.)
set d1.grp = CreateGroup()
set d2.grp = CreateGroup()
set d1.lvl = GetUnitAbilityLevel(d1.u,abil_id)
set d2.lvl = d1.lvl
set L = GetSpellTargetLoc()
set d1.xl = GetLocationX(L)
set d2.xl = d1.xl
set d1.yl = GetLocationY(L)
set d2.yl = d1.yl
set d1.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d1.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)+45.)
set d2.outx = d1.x+width*Cos(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d2.outy = d1.y+width*Sin(Atan2(d1.yl-d1.y,d1.xl-d1.x)-45.)
set d1.ang = -45.
set d2.ang = 45.
call TT_Start(function Movement,d1)
call TT_Start(function Movement,d2)
call RemoveLocation(L)
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
set Trigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trigger, Condition( function Conditions ) )
call TriggerAddAction( Trigger, function Actions )
endfunction
endscope
//TT by Cohadar
//TESH.scrollpos=32
//TESH.alwaysfold=0
//==============================================================================
// TT -- TIMER TICKER SYSTEM BY COHADAR -- v3.3
//==============================================================================
//
// PURPOUSE OF TT:
// * Passing data to timers
// * using only one timer for all actions
//
// PROS:
// * It is ridiculously easy to use.
// * It is faster than ABC (and any other attaching system)
//
// CONS:
// * It can be used only for high-frequency timers
// This method fails if PERIOD > 0.1 second
//
// FUNCTIONS:
// * TT_Start(userFunc, struct)
// TT_GetData() -> struct
//
// * userFunc is a user function that takes nothing and return boolean
// it will be periodically called by the system untill it returns true.
//
// * TT_GetData() is a function that can be used inside userFunc
// TT_GetData() will return struct passed to Start function
//
// DETAILS:
// * All user functions that should be run on same period are stored in an array
// Timer that runs periodically will call all those functions each period
//
// * While user function return false timer will continue to call it each period
// Once user function returns true it will be removed from system
//
// * When there are no user functions to run system will pause itself.
//
// THANKS TO:
// * Vexorian - he was nagging me so much about how attaching to timers is bad
// that I finally had to do something about it.
//
// HOW TO IMPORT:
// * Just create a trigger named TT
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library TT
globals
public constant real PERIOD = 0.035
private trigger array Triggz
private integer array Dataz
private integer Counter = 0
private timer Timer = null
private integer I
private trigger swap
endglobals
//==============================================================================
private function Handler takes nothing returns nothing
local integer i = Counter
loop
exitwhen i<=0
set I = i
if TriggerEvaluate(Triggz[i]) then
call TriggerClearConditions(Triggz[i])
set swap = Triggz[i]
set Triggz[i] = Triggz[Counter]
set Triggz[Counter] = swap
set Dataz[i] = Dataz[Counter]
set Counter = Counter - 1
endif
set i = i - 1
endloop
endfunction
//==============================================================================
public function Start takes code userFunc, integer data returns nothing
if userFunc == null then
call BJDebugMsg("ERROR: TT_Start - null userFunc")
return
endif
set Counter = Counter + 1
if Triggz[Counter] == null then
set Triggz[Counter] = CreateTrigger()
endif
call TriggerAddCondition(Triggz[Counter], Condition(userFunc))
set Dataz[Counter] = data
if Timer == null then
set Timer = CreateTimer()
call TimerStart(Timer, PERIOD, true, function Handler)
endif
endfunction
//==============================================================================
public function GetData takes nothing returns integer
return Dataz[I]
endfunction
endlibrary
//==============================================================================
// END OF TIMER TICKER SYSTEM
//==============================================================================