Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GroupRecycler
//This system was made by The_Reborn_Devil so if you use this credits should be given to him.
globals
private constant integer MAX_GROUPS = 8191 //The maximum amount of groups
private group array G [MAX_GROUPS]
private integer Total = 0
endglobals
function NewGroup takes nothing returns group
if Total == 0 then
set G[0] = CreateGroup()
else
set Total = Total - 1
endif
return G[Total]
endfunction
function ReleaseGroup takes group g returns nothing
if g == null then
debug call BJDebugMsg("WARNING: Trying to release a null group!")
else
if Total == MAX_GROUPS then
debug call BJDebugMsg("WARNING: Limit has been reached! Destroying group!") //The map already got more trouble than it can handle.
call DestroyGroup(g)
else
call GroupClear(g)
set G[Total] = g
set Total = Total + 1
endif
endif
endfunction
endlibrary
//TESH.scrollpos=83
//TESH.alwaysfold=0
library Knockback initializer Init
// **************************************************************************
// ** **
// ** Knockback(Ex) **
// ** ————————————— **
// ** **
// ** A function made for efficient knockbacking **
// ** **
// ** By: Silvenon **
// ** **
// **************************************************************************
//=======================================//
//Credits to PitzerMike for this function//
//=======================================//
globals
private constant integer DUMMY_ID = 'h000'
endglobals
private function TreeFilter takes nothing returns boolean
local destructable d = GetFilterDestructable()
local boolean i = IsDestructableInvulnerable(d)
local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, GetWidgetX(d), GetWidgetY(d), 0)
local boolean result = false
call UnitAddAbility(u, 'Ahrl')
if i then
call SetDestructableInvulnerable(d, false)
endif
set result = IssueTargetOrder(u, "harvest", d)
call RemoveUnit(u)
if i then
call SetDestructableInvulnerable(d, true)
endif
set u = null
set d = null
return result
endfunction
//===========================================================================
globals
private timer Tim = CreateTimer()
private integer Total = 0
private boolexpr Cond = null
private integer array Ar
private boolean array BoolAr
private real MAX_X
private real MAX_Y
private real MIN_X
private real MIN_Y
endglobals
private constant function Interval takes nothing returns real
return 0.04
endfunction
private function KillTree takes nothing returns nothing
if BoolAr[0] then
call KillDestructable(GetEnumDestructable())
else
set BoolAr[1] = true
endif
endfunction
public struct Data
unit u
real d1
real d2
real sin
real cos
real r
string s = ""
effect e = null
static method create takes unit u, integer q, real d, real a, real r, integer t, string s, string p returns Data
local Data dat = Data.allocate()
set dat.u = u
set dat.d1 = 2 * d / (q + 1)
set dat.d2 = dat.d1 / q
set dat.sin = Sin(a)
set dat.cos = Cos(a)
set dat.r = r
if s != "" and s != null then
if t == 2 then
if p != "" and p != null then
set dat.e = AddSpecialEffectTarget(s, u, p)
else
set dat.e = AddSpecialEffectTarget(s, u, "chest")
endif
elseif t == 1 then
set dat.s = s
endif
endif
call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
call PauseUnit(u, true)
if Total == 0 then
call TimerStart(Tim, Interval(), true, function Data.Execute)
endif
set Total = Total + 1
set Ar[Total - 1] = dat
return dat
endmethod
static method Execute takes nothing returns nothing
local Data dat
local integer i = 0
local real x
local real y
local rect r
local real rad
loop
exitwhen i >= Total
set dat = Ar[i]
if dat.s != "" and dat.s != null then
set x = GetUnitX(dat.u)
set y = GetUnitY(dat.u)
call DestroyEffect(AddSpecialEffect(dat.s, x, y))
set x = x + dat.d1 * dat.cos
set y = y + dat.d1 * dat.sin
else
set x = GetUnitX(dat.u) + dat.d1 * dat.cos
set y = GetUnitY(dat.u) + dat.d1 * dat.sin
endif
if dat.r != 0 then
set BoolAr[0] = dat.r > 0
set rad = dat.r
if not BoolAr[0] then
set rad = rad * (-1)
endif
set r = Rect(x - rad, y - rad, x + rad, y + rad)
call EnumDestructablesInRect(r, Cond, function KillTree)
call RemoveRect(r)
set r = null
endif
if (x < MAX_X and y < MAX_Y and x > MIN_X and y > MIN_Y) and not BoolAr[1] then
call SetUnitX(dat.u, x)
call SetUnitY(dat.u, y)
endif
set dat.d1 = dat.d1 - dat.d2
if dat.d1 <= 0 or (x > MAX_X or y > MAX_Y or x < MIN_X or y < MIN_Y) or BoolAr[1] then
set Ar[i] = Ar[Total - 1]
set Total = Total - 1
call dat.destroy()
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
method onDestroy takes nothing returns nothing
if .e != null then
call DestroyEffect(.e)
endif
call PauseUnit(.u, false)
set BoolAr[0] = false
set BoolAr[1] = false
endmethod
endstruct
function KnockbackEx takes unit u, real d, real a, real w, real r, integer t, string s, string p returns nothing
call Data.create(u, R2I(w / Interval()), d, a, r, t, s, p)
endfunction
function Knockback takes unit u, real d, real a, real w returns nothing
call Data.create(u, R2I(w / Interval()), d, a, 0, 0, "", "")
endfunction
private function Init takes nothing returns nothing
set Cond = Filter(function TreeFilter)
set BoolAr[0] = false
set BoolAr[1] = false
set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea) - 64
set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea) - 64
set MIN_X = GetRectMinX(bj_mapInitialPlayableArea) + 64
set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea) + 64
endfunction
endlibrary
//TESH.scrollpos=70
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////
//Cyclone Leap v1.04 //
//by Adiktuz //
//Credits to The_Reborn_Devil and Silvenon for GroupRecycler and Knockback libraries //
//How to use: //
//1) Copy this whole library and paste into your map //
//2) Copy the spell data if you want //
//3)Modify the fields to your liking //
/////////////////////////////////////////////////////////////////////////////////////////
scope Leap initializer init
globals
private constant integer LEAP_ID = 'A000' //Rawcode of Leap spell
private constant integer FLY_ID = 'Amrf' //RAwcode of medivh's raven form
private constant string CYCLONE = "Abilities\\Spells\\Other\\Tornado\\TornadoElemental.mdl" //Path to the cyclone model
private constant real TICK = .03 //Timer interval
private constant string A_POINT = "origin" //The attachment point of the effect
private constant attacktype AT = ATTACK_TYPE_MAGIC
private constant damagetype DT = DAMAGE_TYPE_NORMAL
//Do not edit below the following globals
//There are some functions to edit values after this globals
private timer LEAP_TIMER = CreateTimer()
private group TEMP_GROUP = CreateGroup() //I cannot use NewGroup in a global block
private Leap data
private Leap instance
private real ANGLE = 0.00
private integer array DAT[8190]
private integer TOTAL = 0
private boolexpr FILTER
private real MaX
private real MiX
private real MaY
private real MiY
private unit FU = null
//
endglobals
//Various functions for some of the data
//This allows easier formula modification
private function DPS takes integer level returns real
return level*75.00
endfunction
private function RADIUS takes nothing returns real
return 250.00
endfunction
private function DIST_PER_SEC takes nothing returns real
return 600.00
endfunction
private function KB_DIST takes nothing returns real
return 100.00
endfunction
private function KB_TIME takes nothing returns real
return 1.00
endfunction
private function GRAV takes nothing returns real
return 100.00
endfunction
//End functions
struct Leap
unit caster
effect cyclone
integer level
player owner
real x
real y
real tx
real ty
real dx
real dy
group damagegroup
real damage
real distanceperloop
real totaldistance
real z
real dz
static method check takes nothing returns boolean
set FU = GetFilterUnit()
if IsUnitEnemy( FU, instance.owner) and GetWidgetLife(FU) >= .405 and IsUnitInGroup(FU, instance.damagegroup) != true then
call UnitDamageTarget(instance.caster, FU, instance.damage, false, false, AT, DT, null)
call GroupAddUnit(instance.damagegroup, FU)
call Knockback(FU, KB_DIST(), bj_DEGTORAD*(GetUnitFacing(FU) + 180.00),KB_TIME() )
endif
return true
endmethod
static method onLoop takes nothing returns nothing
local integer i = 0
loop
exitwhen i == TOTAL
set data = DAT[i]
set data.x = data.x + data.dx
set data.y = data.y + data.dy
if data.x <= MaX and data.x >= MiX then
call SetUnitX(data.caster, data.x)
endif
if data.y <= MaY and data.y >= MiY then
call SetUnitY(data.caster, data.y)
endif
set data.z = data.z + data.dz
set data.dz = data.dz - TICK*GRAV()
call SetUnitFlyHeight(data.caster, data.z, 0.00)
set instance = data
call GroupEnumUnitsInRange(TEMP_GROUP, data.x, data.y, RADIUS() , FILTER)
if data.z <= 0.00 then
call DestroyEffect(data.cyclone)
call ReleaseGroup(data.damagegroup)
call data.destroy()
set TOTAL = TOTAL - 1
set DAT[i] = DAT[TOTAL]
set i = i - 1
endif
set i = i + 1
endloop
if TOTAL == 0 then
call PauseTimer(LEAP_TIMER)
endif
endmethod
static method Create takes nothing returns thistype
set data = Leap.allocate()
set data.caster = GetTriggerUnit()
set data.cyclone = AddSpecialEffectTarget(CYCLONE, data.caster, A_POINT)
set data.owner = GetOwningPlayer(data.caster)
set data.tx = GetSpellTargetX()
set data.ty = GetSpellTargetY()
set data.x = GetUnitX(data.caster)
set data.y = GetUnitY(data.caster)
set ANGLE = Atan2(data.ty - data.y, data.tx - data.x)
set data.damagegroup = NewGroup()
set data.level = GetUnitAbilityLevel(data.caster, LEAP_ID)
set data.totaldistance = SquareRoot((data.tx - data.x)*(data.tx - data.x) + (data.ty - data.y)*(data.ty - data.y))
set data.distanceperloop = TICK*DIST_PER_SEC()
set data.z = 0.00
set data.dz = (GRAV() * (data.totaldistance/DIST_PER_SEC()))/2
//This next if is to ensure that the spell works correct when you cast in on your portrait
//coz it causes a weird bug...
if data.totaldistance <= 0.00 then
set data.totaldistance = 1.00
endif
set data.dx = data.distanceperloop*Cos(ANGLE)
set data.dy = data.distanceperloop*Sin(ANGLE)
set data.damage = DPS(data.level)
if UnitAddAbility(data.caster, FLY_ID) then
call UnitRemoveAbility(data.caster, FLY_ID)
endif
set DAT[TOTAL] = data
set TOTAL = TOTAL + 1
if TOTAL == 1 then
call TimerStart(LEAP_TIMER, TICK, true, function Leap.onLoop)
endif
return data
endmethod
endstruct
private function LeapCheck takes nothing returns boolean
return GetSpellAbilityId() == LEAP_ID
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
call TriggerAddAction(t, function Leap.Create)
call TriggerAddCondition(t, Filter(function LeapCheck))
loop
exitwhen i > 15
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
endloop
set FILTER = Filter(function Leap.check)
set MaX = GetRectMaxX(bj_mapInitialPlayableArea)
set MiX = GetRectMinX(bj_mapInitialPlayableArea)
set MaY = GetRectMaxY(bj_mapInitialPlayableArea)
set MiY = GetRectMinY(bj_mapInitialPlayableArea)
endfunction
endscope