Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////
// Nyctophobia 1.0
// Created by JonNny
//
// ° Mapmaking since 2006...
// °
// °
// °
// °°°ÛÜ
// °°X°ÛÛÛ ÛÛÛÛÛÛÛÛ ÿÜÛÛÛÛÛÛÛÛÜ
// °°XX° ÛÛÛ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXX°° ÛÛÛÛÛÛÜ ÛÛÛÜ ÛÛÛÛÛ ßÛÛÛÛÛ ßÛÛÛÛ ÛÛÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÜ
// ÛÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÜÛÛÛÛÛÛ
// °°XXXXX° ÛÛÛÛ ÛÛÛÜ ÛÛÛÛÛ ÛÛÛÛÛÛÜ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXXXX °° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛ °°°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°° ÛÛÛÛÛÛÛÛÛÛÛÛÛß
// ° XXXXX °°ÛÛÛÛÛ°°°°ÛÛÛÛÛÛÛÛ°°XX ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ XXX°°ÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛ
// °° XXXXX ÜÛÛÛÛÛÛ X ÛÛÛÛÛÛÛÛÛ XXX ÛÛÛÛÛÛÛÛÛÛÛ XXXXXX ÛÛÛÛÛÛÛ° ÛÛÛ
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°° °°°°
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°X°°
// °°° XXXXXXXXXX °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° XXXXXXXXXXXXXXXXX°°
// °°°°°°°°°°°°°°°° °°°°°°°° XXXXXXX °°°
// °°°°°° XX °°
// ...2009 and still moving on. °°°°°°°
// °°
//
//
//
//////////////////////////////////////Globals with important values////////////////////////////////////////
scope Nyctophobia initializer Init
globals
private constant integer Spell = 'A000'
//The Spell Ability
private constant integer DummyID = 'h000'
//Dummy Unit
private constant integer DummyVertex = 160
//Transparency of the dummy
private constant integer DummyDarkness = 200
// Darkness of the Dummy
private constant real MissileAim = 0.30
// The rate missiles aim
private constant real ZAdjustRate = 55
//how fast the missiles height adjustes
private constant real ReleaseSpeed = 10
//The Speed each missile is released in a random direction
private constant real MaxVZ = 28.00
private constant real MinVZ = 10.00
// The Speed in Z axe each missiles can be released at
private constant real MissileCollision = 40.00
//How far the Missiles have to reach the target till they damage it
private constant real Pushback = 1.75
////Knockback on hit (instant)
private constant real AnimSpeed = 1.75
//Animation Speed of the Dummy
private constant real TimerPeriod = 0.0325
//How fast the callbacl executes
private constant string AOEeffect = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
//Effect created if the unit is under the effect of Inner Blaze
///////////////////////////////////Globals that should not be changed////////////////////////////
private real MaxX = 0
private real MaxY = 0
private real MinX = 0
private real MinY = 0
private timer t = CreateTimer()
private boolexpr filter = null
endglobals
//////////////////////////////////Editable Functions/////////////////////////////////////////&/
private constant function MissilesNumberDirectly takes integer level returns integer
return 4 + 2 * level
//Amount of missiles released instantly
endfunction
private constant function MissilesNumberDelayed takes integer level returns integer
return 4 + 3 * level
//Amount of missiles released after the cast in the MissilesDelay intervals
endfunction
private constant function MissilesDelay takes integer level returns real
return 0.5
//The time between each Delayed Missile
endfunction
private constant function MissilesDamage takes integer level returns integer
return 6 + 2 * level
//Damage each missiles does
endfunction
private function RunCondition takes nothing returns boolean
return GetSpellAbilityId() == Spell
//The condition if the spell is casted
endfunction
private function DamageTarget takes real damage, unit target, unit dealer returns nothing
//Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
//If you dont want it to splash, replace it, e.g. with the one below or whichever you want
call IFDamage(damage,target,dealer,AOEeffect,"chest")
//call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction
///////////////////////////////////////////Main Script//////////////////////////////////////////////
private constant function NullFilter takes nothing returns boolean
return true
endfunction
private function Callback takes nothing returns nothing
local integer i = 0
local integer ii = 0
//Looping through each Struct
loop
exitwhen i >= Missiles.Index
//If no missiles (including the delayed and maybe not created missiles) are left the structs gets destroyed
if Missiles.Data[i].i == 0 then
set Missiles.Data[i].ta = null
set Missiles.Data[i].ca = null
call Missiles.destroy(Missiles.Data[i])
set Missiles.Index = Missiles.Index - 1
set Missiles.Data[i] = Missiles.Data[Missiles.Index]
//Else if the Target or Caster Dies the spell stops
elseif GetWidgetLife(Missiles.Data[i].ta) <= 0.405 or GetWidgetLife(Missiles.Data[i].ca) <= 0.405 then
set ii = 0
loop
exitwhen ii > Missiles.Data[i].i
call KillUnit(Missiles.Data[i].m[ii])
set Missiles.Data[i].m[ii] = null
set ii = ii + 1
endloop
set Missiles.Data[i].i = 0
else
//Else just move/create the missiles
call Missiles.Data[i].move()
set i = i + 1
endif
endloop
if Missiles.Index > 0 then
call TimerStart(t, TimerPeriod, true, function Callback)
endif
endfunction
struct Missiles
static integer Index = 0
static Missiles array Data
unit array m [23] //Missile dummy
unit ta //Target
unit ca //Caster
real array a [23] //Creation angle
real array vx [23] //Current x movement
real array vy [23] //Current y movement
real array vz [23] //curren z Movement
integer array d [23] //delay of creation
integer i = 0 //Number of Missile
real damage
static method create takes unit c, unit ta, integer level returns Missiles
local integer i = 0
local integer ii = 0
local integer r = 0
local Missiles data = Missiles.allocate()
local real a = 0.00
local real dp = 0.15 //delay per missile when releasing them directly
local integer n = MissilesNumberDirectly(level)
set Missiles.Data[Missiles.Index] = data
//looping throught each missiles which will be created
//The real creation of each missile will be in the Move method when the delay left
loop
exitwhen r == 2
loop
exitwhen ii == n
set a = GetRandomReal(0,2*bj_PI)
if r == 0 then
set data.d[i] = i
else
set data.d[i] = R2I(((ii+1)*dp)/TimerPeriod)
endif
set data.i = data.i + 1
set data.a[i] = a
set data.vx[i] = ReleaseSpeed * Cos(a)
set data.vy[i] = ReleaseSpeed * Sin(a)
set data.vz[i] = GetRandomReal(MinVZ,MaxVZ)
set ii = ii + 1
set i = 1 + i
endloop
set dp = MissilesDelay(level)
set n = MissilesNumberDelayed(level)
set ii = 0
set r = r + 1
endloop
set data.ca = c
set data.ta = ta
set data.damage = MissilesDamage(level)
if data.Index == 0 then
call TimerStart(t, TimerPeriod, true, function Callback)
endif
set Missiles.Index = Missiles.Index + 1
return data
endmethod
method move takes nothing returns nothing
local integer i = 0
local real x
local real y
local real d
local real a
loop
exitwhen i == this.i
//Creation of the Dummy
if this.d[i] == 0 and GetWidgetLife(this.ta) >= 0.405 then
set this.d[i] = -1
set this.m[i] = CreateUnit(GetOwningPlayer(this.ca),DummyID,GetUnitX(this.ca),GetUnitY(this.ca),this.a[i]*180.0/bj_PI)
call SetUnitTimeScale(this.m[i],AnimSpeed)
call SetUnitVertexColor(this.m[i],255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,DummyVertex)
// Decreasing Left Executions till creation
elseif this.d[i] > 0 and GetWidgetLife(this.ta) >= 0.405 then
set this.d[i] = this.d[i] - 1
// Move the dummy
elseif this.d[i] < 0 and this.m[i] != null and GetWidgetLife(this.ta) >= 0.405 then
set a = Atan2(GetUnitY(this.ta) - GetUnitY(this.m[i]), GetUnitX(this.ta) - GetUnitX(this.m[i]))
set x = GetUnitX(this.ta) - GetUnitX(this.m[i])
set y = GetUnitY(this.ta) - GetUnitY(this.m[i])
if GetUnitY(this.m[i]) < MaxY and GetUnitY(this.m[i]) > MinY and GetUnitX(this.m[i]) < MaxX and GetUnitX(this.m[i]) > MinX then
set d = SquareRoot(x*x+y*y)
call SetUnitY(this.m[i],this.vy[i]+GetUnitY(this.m[i])+(Sin(a) * ( -8 + MissileAim * -2 *this.d[i])))
set this.vy[i] = 0.98 * this.vy[i]
call SetUnitX(this.m[i],this.vx[i]+GetUnitX(this.m[i])+(Cos(a) * ( -8 + MissileAim * -2 *this.d[i])))
set this.vx[i] = 0.98 * this.vx[i]
call SetUnitFlyHeight(this.m[i],GetUnitFlyHeight(this.m[i])+this.vz[i] - (ZAdjustRate/(d+100))*(GetUnitFlyHeight(this.m[i])-GetUnitFlyHeight(this.ta)) ,0)
set this.vz[i] = 0.99 * this.vz[i]
set x = GetUnitX(this.ta) - GetUnitX(this.m[i])
set y = GetUnitY(this.ta) - GetUnitY(this.m[i])
call SetUnitFacing(this.m[i], a* bj_RADTODEG )
set this.d[i] = this.d[i] - 1
if d <= MissileCollision then
call DamageTarget(this.damage,this.ta,this.ca)
call SetUnitX(this.ta, GetUnitX(this.ta) + Pushback * Cos(a))
call SetUnitY(this.ta, GetUnitY(this.ta) + Pushback * Sin(a))
call KillUnit(this.m[i])
set this.m[i] = null
set this.i = this.i - 1
set this.m[i] = this.m[this.i]
set this.a[i] = this.a[this.i]
set this.vx[i] = this.vx[this.i]
set this.vy[i] = this.vy[this.i]
set this.vz[i] = this.vz[this.i]
set this.d[i] = this.d[this.i]
set i = i - 1
endif
else
call KillUnit(this.m[i])
set this.m[i] = null
set this.i = this.i - 1
set this.m[i] = this.m[this.i]
set this.a[i] = this.a[this.i]
set this.vx[i] = this.vx[this.i]
set this.vy[i] = this.vy[this.i]
set this.vz[i] = this.vz[this.i]
set this.d[i] = this.d[this.i]
set i = i - 1
endif
endif
set i = i + 1
endloop
endmethod
endstruct
private function InitMissiles takes nothing returns nothing
call Missiles.create(GetTriggerUnit(),GetSpellTargetUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger tr = CreateTrigger()
local integer index = 0
//Setting the max rects due the lil knockback can eventuelly push the target outside
set MaxX = GetRectMaxX(bj_mapInitialPlayableArea) - 64
set MaxY = GetRectMaxY(bj_mapInitialPlayableArea) - 64
set MinX = GetRectMinX(bj_mapInitialPlayableArea) + 64
set MinY = GetRectMinY(bj_mapInitialPlayableArea) + 64
set filter = Filter(function NullFilter)
loop
call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( tr, Condition( function RunCondition ) )
call TriggerAddAction( tr, function InitMissiles )
call Preload(AOEeffect) //Effect Preload
endfunction
endscope
//TESH.scrollpos=157
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////
// Combusting Brood 1.0
// Created by JonNny
//
// ° Mapmaking since 2006...
// °
// °
// °
// °°°ÛÜ
// °°X°ÛÛÛ ÛÛÛÛÛÛÛÛ ÿÜÛÛÛÛÛÛÛÛÜ
// °°XX° ÛÛÛ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXX°° ÛÛÛÛÛÛÜ ÛÛÛÜ ÛÛÛÛÛ ßÛÛÛÛÛ ßÛÛÛÛ ÛÛÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÜ
// ÛÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÜÛÛÛÛÛÛ
// °°XXXXX° ÛÛÛÛ ÛÛÛÜ ÛÛÛÛÛ ÛÛÛÛÛÛÜ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXXXX °° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛ °°°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°° ÛÛÛÛÛÛÛÛÛÛÛÛÛß
// ° XXXXX °°ÛÛÛÛÛ°°°°ÛÛÛÛÛÛÛÛ°°XX ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ XXX°°ÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛ
// °° XXXXX ÜÛÛÛÛÛÛ X ÛÛÛÛÛÛÛÛÛ XXX ÛÛÛÛÛÛÛÛÛÛÛ XXXXXX ÛÛÛÛÛÛÛ° ÛÛÛ
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°° °°°°
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°X°°
// °°° XXXXXXXXXX °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° XXXXXXXXXXXXXXXXX°°
// °°°°°°°°°°°°°°°° °°°°°°°° XXXXXXX °°°
// °°°°°° XX °°
// ...2009 and still moving on. °°°°°°°
// °°
//
//
//////////////////////////////////////Globals with important values////////////////////////////////////////
scope CombustingBrood initializer Init
globals
private constant integer Spell = 'A002'
//The Main Combusting Brood Spell
private constant integer DummyID = 'h001'
//The Missiles Dummy
private constant integer DummyVertex = 170
// How Transparent the missile is
private constant integer DummyDarkness = 170
// How dark the missiles is
private constant integer VertexChange = 10
// At the start the missile has 100% alpha and fades in in this step per interval
// To disable it set it to the DummyVertex or right
private constant real DamageBonus = 15.
// Bonus Damage for each remaining Jump if there are no valid targets left
private constant real DummyHeight = 80
//The base Height of the missile and the height it hits the target
private constant real JumpSpeed = 12
// Yeh, obv the missiles Speed
private constant real JumpHeight = 360
// Max Height reached in the jump
private constant real TimerPeriod = 0.0325
// Interval the timer executes
private constant string DamageEffect = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
// Effect displayed when the missile hits an enemy
private constant string AOEeffect = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
// Effect displayed when hitting a target under the effect of Inner Blaze
private constant boolean HitThree = true
// This declares how many units a missile must hit to hit the same target again
// True means the missile can hit the same target after hitting 2 others, if its cast at 2 units standing there it will end after hitting them both
// False means the missile needs to hit one other unit till it can hit the same again, if there are 2 units it can jump from each to each again
private integer array SpawnUnit [8]
// The Unit IDs of the summons when killing enemys, Index must be the max. jumps a missile can do
///////////////////////////////////Globals that should not be changed////////////////////////////
private timer t = CreateTimer()
private group g = CreateGroup()
private boolexpr filter = null
private boolexpr ufilter = null
endglobals
///////////////////////////////////Important Editable Functions////////////////////////////////////
private function RunCondition takes nothing returns boolean
return GetSpellAbilityId() == Spell
//The condition if the spell is casted
endfunction
private function SpawnUnitInit takes nothing returns nothing
//Sets the Spawntype for each Jump Left ( SpawnUnit[0] will also be the type when killing a unit during the jumps)
set SpawnUnit[0] = 'n000' // Minor brood (0)
set SpawnUnit[1] = 'nlv1' // Weak brood (1-2)
set SpawnUnit[2] = 'nlv1'
set SpawnUnit[3] = 'nlv2' // Brood (3-5)
set SpawnUnit[4] = 'nlv2'
set SpawnUnit[5] = 'nlv2'
set SpawnUnit[6] = 'nlv3' // Strong Brood (6-8)
set SpawnUnit[7] = 'nlv3'
set SpawnUnit[8] = 'nlv3'
endfunction
private function SpawnDuration takes integer jumps returns real
return 7.0 + 1.5 * jumps
// Duration of the Spawns per Jump Left (e.g. Minor brood will always have a 7 sec live due the 0 jumps left, Strong Brood have a duration from 16-19 seconds)
endfunction
private constant function MoveSpeedFaktor takes real x returns real
return JumpSpeed * 0.01 * (0.45 * x * x - 1.1 * x + 1.2)
// Defines the Speed of the Combusting Brood while its Movement (slower in the middle part and faster at the end, i you want to "reset" it change it to : JumpSpeed * 0.01
// Else if you dont really know what it should be dont modify it
endfunction
private constant function JumpsPerLevel takes integer level returns integer
return 2 + 2 * level
// How Many Jumps the Brood can do per level
endfunction
private function TargetUnitCondition takes unit a, unit b returns boolean
// Additional Condition for Targeting a new target
return IsPlayerEnemy(GetOwningPlayer(a),GetOwningPlayer(b))
endfunction
private constant function DamagePerLevel takes integer level returns integer
// Blablubb, Damager deal per level each jump obv
return 50 + 25 * level
endfunction
private constant function JumpRangePerLevel takes integer level returns real
// Range per level the Brood can jump/ search a new target in
return 220.0 + 40.0 * level
endfunction
private function UnitFilter takes nothing returns boolean
//Conditions of Targeting a Unit
return not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)) and not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction
private function DamageTarget takes real damage, unit target, unit dealer returns nothing
//Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
//If you dont want it to splash, replace it, e.g. with the one below or whichever you want
call IFDamage(damage,target,dealer,AOEeffect,"chest")
//call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction
///////////////////////////////////////////Main Script//////////////////////////////////////////////
private constant function NullFilter takes nothing returns boolean
return true
endfunction
private function GetUnitDistance takes unit a, unit b returns real
local real dx = GetUnitX(a) - GetUnitX(b)
local real dy = GetUnitY(a) - GetUnitY(b)
return SquareRoot(dx*dx+dy*dy)
endfunction
private function GetUnitsAngle takes unit a, unit b returns real
return Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
endfunction
private function GetNewTarget takes Brood d returns unit
local unit ret = null
local boolean finished = false
local unit a
call GroupEnumUnitsInRange(g, GetUnitX(d.b), GetUnitY(d.b),JumpRangePerLevel(d.level),ufilter)
//looping through each near target and checking it
loop
set a = FirstOfGroup(g)
exitwhen a == null or finished == true
//Checks if the units got already hit in the last 2 jumps
if a != d.l1 and a != d.l2 and TargetUnitCondition(d.b,a) then
call GroupClear(g)
set ret = a
set finished = true
else
call GroupRemoveUnit(g,a)
endif
endloop
return ret
endfunction
private function Callback takes nothing returns nothing
local integer i = 0
//looping throught all structs
loop
exitwhen i >= Brood.Index
//Destroying the struct
if Brood.Data[i].Jleft == 0 then
set Brood.Data[i].b = null
set Brood.Data[i].ta = null
set Brood.Data[i].amp = 0
call Brood.destroy(Brood.Data[i])
set Brood.Data[i] = Brood.Data[Brood.Index - 1]
set Brood.Index = Brood.Index - 1
else
//Calliing the move method
call Brood.Data[i].move()
set i = i + 1
endif
endloop
if Brood.Index > 0 then
call TimerStart(t, TimerPeriod, true, function Callback)
endif
endfunction
struct Brood
static integer Index = 0
static Brood array Data
unit c //Caster , deals the damage
unit b //Missile , Bombusting Brood
unit ta //Target
unit l1 //Unit hit 1 jump ago
unit l2 // Unit hit 2 jumps ago
integer Jleft //Amount of jumps left
integer level //Level of the Spell
integer Vertex // Current vertex of the missile
real amp //current Amplitude while the jump
static method create takes unit c, unit ta, integer level returns Brood
local Brood data = Brood.allocate()
local unit u = CreateUnit(GetOwningPlayer(c),DummyID,GetUnitX(c),GetUnitY(c),bj_RADTODEG * GetUnitsAngle(c,ta))
set Brood.Data[Brood.Index] = data
set data.c = c
set data.b = u
set data.ta = ta
set data.l1 = ta
set data.Jleft = JumpsPerLevel(level)
set data.level = level
set data.Vertex = 0
call SetUnitVertexColor(u,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,0)
if data.Index == 0 then
call TimerStart(t, TimerPeriod, true, function Callback)
endif
set Brood.Index = Brood.Index + 1
return data
endmethod
method move takes nothing returns nothing
local real step = MoveSpeedFaktor(this.amp) //Adjusting the speed depending on the function
local real x = ( step) / (bj_PI - this.amp + 0.25 )
local real b = GetUnitDistance(this.b,this.ta)
local real d = 0.5 + x * (25 + b)
local real a = GetUnitsAngle(this.b,this.ta)
local unit s
local unit u
local real damage = DamagePerLevel(this.level)
if d >= b then
set d = b //Avoid to speed up the target too fast if its very very near
endif
call SetUnitX(this.b,GetUnitX(this.b) + d * Cos(a))
call SetUnitY(this.b,GetUnitY(this.b) + d * Sin(a))
call SetUnitFacing(this.b,bj_RADTODEG * GetUnitsAngle(this.b,this.ta))
set this.amp = this.amp + step
call SetUnitFlyHeight(this.b,DummyHeight + JumpHeight * Sin(this.amp),0)
//Adjust its vertex
if this.Vertex <= DummyVertex then
set this.Vertex = this.Vertex + VertexChange
call SetUnitVertexColor(this.b,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
endif
//Reached its target , Damage deal / Summons ect
if this.amp >= bj_PI then
set u = GetNewTarget(this)
if u == null then
set damage = damage + (this.Jleft -1) * DamageBonus
endif
if GetWidgetLife(this.ta) >= 0.405 then
call DamageTarget(damage,this.ta,this.c)
// To remove its conntection replace it with a normal damage deal
if GetWidgetLife(u) >= 0.405 then
set u = GetNewTarget(this)
endif
call DestroyEffect(AddSpecialEffect(DamageEffect,GetUnitX(this.ta),GetUnitY(this.ta)))
if GetWidgetLife(this.ta) < 0.405 and u != null then
set s = CreateUnit(GetOwningPlayer(this.c),SpawnUnit[0],GetUnitX(this.ta),GetUnitY(this.ta),GetUnitFacing(this.ta))
call UnitApplyTimedLife(s, 'BTLF', SpawnDuration(0))
call SetUnitVertexColor(s,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
elseif GetWidgetLife(this.ta) < 0.405 and u == null then
set s = CreateUnit(GetOwningPlayer(this.c),SpawnUnit[this.Jleft-1],GetUnitX(this.ta),GetUnitY(this.ta),GetUnitFacing(this.ta))
call UnitApplyTimedLife(s, 'BTLF', SpawnDuration((this.Jleft-1)) )
call SetUnitVertexColor(s,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,this.Vertex)
endif
endif
if HitThree == true then
set this.l2 = this.l1
endif
set this.l1 = u
set this.ta = u
if this.ta == null then
call KillUnit(this.b)
set this.Jleft = 0
else
set this.amp = 0
set this.Jleft = this.Jleft - 1
if this.Jleft == 0 then
call KillUnit(this.b)
endif
endif
set s = null
set u = null
endif
endmethod
endstruct
private function InitBrood takes nothing returns nothing
call Brood.create(GetTriggerUnit(),GetSpellTargetUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger tr = CreateTrigger()
local integer index = 0
call SpawnUnitInit()
set filter = Filter(function NullFilter)
set ufilter = Filter(function UnitFilter)
loop
call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( tr, Condition( function RunCondition ) )
call TriggerAddAction( tr, function InitBrood )
//Preloading effects
call Preload(DamageEffect)
call Preload(AOEeffect)
endfunction
endscope
//TESH.scrollpos=74
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////
// Inner Blaze 1.0
// Created by JonNny
//
// ° Mapmaking since 2006...
// °
// °
// °
// °°°ÛÜ
// °°X°ÛÛÛ ÛÛÛÛÛÛÛÛ ÿÜÛÛÛÛÛÛÛÛÜ
// °°XX° ÛÛÛ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXX°° ÛÛÛÛÛÛÜ ÛÛÛÜ ÛÛÛÛÛ ßÛÛÛÛÛ ßÛÛÛÛ ÛÛÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÜ
// ÛÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÜÛÛÛÛÛÛ
// °°XXXXX° ÛÛÛÛ ÛÛÛÜ ÛÛÛÛÛ ÛÛÛÛÛÛÜ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXXXX °° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛ °°°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°° ÛÛÛÛÛÛÛÛÛÛÛÛÛß
// ° XXXXX °°ÛÛÛÛÛ°°°°ÛÛÛÛÛÛÛÛ°°XX ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ XXX°°ÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛ
// °° XXXXX ÜÛÛÛÛÛÛ X ÛÛÛÛÛÛÛÛÛ XXX ÛÛÛÛÛÛÛÛÛÛÛ XXXXXX ÛÛÛÛÛÛÛ° ÛÛÛ
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°° °°°°
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°X°°
// °°° XXXXXXXXXX °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° XXXXXXXXXXXXXXXXX°°
// °°°°°°°°°°°°°°°° °°°°°°°° XXXXXXX °°°
// °°°°°° XX °°
// ...2009 and still moving on. °°°°°°°
// °°
//
//
//////////////////////////////////////Globals with important values////////////////////////////////////////
library InnerFire initializer Init
globals
private constant integer InnerFireSpell = 'A001'
//Inner Blaze Ability
private constant integer PreloadDummy = 'h002'
//Dummy to preload the Damage Ability
private constant integer InnerFireBuffSpell = 'A003'
//Dummy Ability which gives the buff (the base ability (Immolation) has no buff)
private constant integer BonusAbility = 'A004'
//The Bonus Ability When Killing a Target, in this case its damage bonus
private constant integer InnerFireBuff = 'B000'
//The Buff the units under this Spell got
private constant real TimerPeriod = 0.05
//Timer Inverval used to change the lightnings vertex
private constant real LightningSpeed = 0.20
//The rate the lightning changes its vertex
private constant string Lightning = "AFOD"
//The Lightning type , its Finger Of Death
///////////////////////////////////Globals that should not be changed////////////////////////////
private group g = CreateGroup()
private boolexpr filter = null
private boolexpr unitfilter = null
private timer t = CreateTimer()
endglobals
///////////////////////////////////Important Editable Functions////////////////////////////////////
function DamageBonus takes integer level returns integer
return 1
// The number of level steps for the damage ability
// 1 means it will always be increased by 1 (ability gives 6 bonus per level) = 6 damage bonus on each level
endfunction
function IFAOEPart takes integer level returns real
return 0.15 + 0.15 * level
//The part of Spell damage which will be splashed , should be between 0 and 1
endfunction
function IFAOERadius takes integer level returns real
return 60.0 + 20.0 * level
// The Area of the Spell Damage Splash per level
endfunction
private function BonusDuration takes integer level returns real
return 8.0 + 4.0 * level
//Duration the bonus damage stays when killing a target with a Spell
endfunction
private function SplashCondition takes unit a , unit b returns boolean
// The condition if a unit is damaged
return IsPlayerEnemy(GetOwningPlayer(a),GetOwningPlayer(b)) // The condition if a unit is damaged
endfunction
private function UnitFilter takes nothing returns boolean
local boolean ret = false
if not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)) and not(IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)) then
set ret = IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and (GetWidgetLife(GetFilterUnit()) > 0.405)
endif
return ret
// The Condition a unit can be hit by a Damage Splash
endfunction
//The condition if trigger should run (refers to the event : EVENT_PLAYER_HERO_SKILL)
private function RunCondition takes nothing returns boolean
return GetLearnedSkill() == InnerFireSpell
endfunction
///////////////////////////////////////////Main Script//////////////////////////////////////////////
private constant function NullFilter takes nothing returns boolean
return true
endfunction
private function Callback takes nothing returns nothing
local integer i = 0
loop
//Looping through all structs
exitwhen i >= Li.Index
if Li.Data[i].left <= 0 then
set Li.Data[i].ta = null
call SetUnitAbilityLevel(Li.Data[i].h,BonusAbility, (GetUnitAbilityLevel(Li.Data[i].h,BonusAbility)-Li.Data[i].bonus))
set Li.Data[i].h = null
call Li.destroy(Li.Data[i])
set Li.Index = Li.Index - 1
set Li.Data[i] = Li.Data[Li.Index]
else
call Li.Data[i].looping()
set i = i + 1
endif
endloop
if Li.Index > 0 then
call TimerStart(t, TimerPeriod, false, function Callback)
endif
endfunction
struct Li // The lightning which appeas when a unit gets killed
static integer Index = 0
static Li array Data
lightning li
boolean inde = true //increase / decrease the lightnings alpha
unit h //hero
unit ta //Target
real alpha = 0.00 //Current alpha
integer bonus //Damage bonus a lightning gives
real left //Duration of the damage bonus left
static method create takes unit c, unit ta, integer level returns Li
//Creating the lightning and adding damage bonus
local Li data = Li.allocate()
local real a = 0.00
set data.ta = ta
set data.h = c
set data.li = AddLightning(Lightning, true , GetUnitX(ta), GetUnitY(ta), GetUnitX(c), GetUnitY(c))
call SetLightningColor(data.li,1.00,1.00,1.00,0.00)
//In case you dont want to create the lightning at full alpha thange the colour from 1.00 to any other below
set data.left = BonusDuration(level)
set data.bonus = DamageBonus(level)
set Li.Data[Li.Index] = data
call SetUnitAbilityLevel(c,BonusAbility, GetUnitAbilityLevel(c,BonusAbility)+data.bonus)
if data.Index == 0 then
call TimerStart(t, TimerPeriod, false, function Callback)
endif
set data.Index = data.Index + 1
return data
endmethod
method looping takes nothing returns nothing
//looplooploop changes the lightnings alpha
if this.li != null then
if this.alpha >= 1.0 and this.inde == true then
//Lightning reached its max visibility and its "fade" is declared
set this.inde = false
set this.alpha = 1.0
elseif this.alpha <= 1.0 and this.inde == true then
//Increase its visibility
set this.alpha = this.alpha + LightningSpeed
if this.alpha >= 1.00 then
set this.alpha = 1.00
endif
elseif this.alpha >= 0.0 and this.inde == false then
//Decrease its visibility
set this.alpha = this.alpha - LightningSpeed
endif
call SetLightningColor(this.li,1,1,1,this.alpha)
call MoveLightning(this.li,true, GetUnitX(this.ta), GetUnitY(this.ta), GetUnitX(this.h), GetUnitY(this.h))
if this.alpha <= 0.0 and this.inde == false then
call DestroyLightning(this.li)
set this.li = null
endif
endif
set this.left = this.left - TimerPeriod
endmethod
endstruct
//Thie is the main damage function used by all other spells which use the splash of Inner Blaze
function IFDamage takes real damage, unit t, unit s , string e, string attach returns nothing
local integer l = GetUnitAbilityLevel(s,InnerFireSpell)
local lightning li
local unit b
if GetUnitAbilityLevel(t,InnerFireBuff) == 0 or GetUnitAbilityLevel(s,InnerFireSpell) == 0 then
//If the target does not have the buff and the damage dealer does not have the ability its a normal damage deal
call UnitDamageTarget(s,t,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
elseif GetUnitAbilityLevel(s,InnerFireSpell) != 0 and GetWidgetLife(t) >= 0.405 then
//Else if the DamageDealer has the abiliy and the target is alive the damage is splaaashed
call DestroyEffect(AddSpecialEffectTarget(e,t,attach))
call UnitDamageTarget(s,t,damage*(1-IFAOEPart(l)),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
if GetWidgetLife(t) <= 0.405 and GetUnitFlyHeight(t) == 0 then
// Init Bonus with teh lightning
call Li.create(s,t,GetUnitAbilityLevel(s,InnerFireSpell))
endif
//Splashing damage with looping through all units near
call GroupEnumUnitsInRange(g, GetUnitX(t), GetUnitY(t),IFAOERadius(l), unitfilter)
loop
set b = FirstOfGroup(g)
exitwhen b==null
call GroupRemoveUnit(g,b)
//Checking conditions
if SplashCondition(s,b) == true then
//Damaging the target (also the main target, but it got less damage befor that it has 100% of it atall and not more)
call UnitDamageTarget(s,b,damage*IFAOEPart(l),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
if GetWidgetLife(b) <= 0.405 and GetUnitFlyHeight(b) == 0 then
// Init Bonus and lightning
call Li.create(s,b,GetUnitAbilityLevel(s,InnerFireSpell))
endif
endif
endloop
call GroupClear(g)
set b = null
set li = null
endif
endfunction
private function Actions takes nothing returns nothing
local unit c = GetTriggerUnit()
//Checking if the unit already got the dummy buff spell and increasing level /ading it
if (GetUnitAbilityLevel(c,InnerFireBuffSpell) == 0) then
call UnitAddAbility(c,BonusAbility)
call UnitAddAbility(c,InnerFireBuffSpell)
else
call SetUnitAbilityLevel(c,InnerFireBuffSpell, GetUnitAbilityLevel(c,InnerFireSpell))
endif
set c = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local integer index = 0
local boolexpr cond = Condition( function RunCondition )
local trigger t = CreateTrigger( )
//Preloading the damag ability due its big amount of levels leads into a lag else
local unit preload = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),PreloadDummy,0,0,0)
call UnitAddAbility(preload,BonusAbility)
call RemoveUnit(preload)
set filter = Filter(function NullFilter)
set unitfilter = Filter( function UnitFilter)
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_HERO_SKILL, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( t, cond )
call TriggerAddAction( t, function Actions )
set cond = null
set preload = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////
// Dark Soul 1.0
// Created by JonNny
//
// ° Mapmaking since 2006...
// °
// °
// °
// °°°ÛÜ
// °°X°ÛÛÛ ÛÛÛÛÛÛÛÛ ÿÜÛÛÛÛÛÛÛÛÜ
// °°XX° ÛÛÛ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °XX ° ÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXX°° ÛÛÛÛÛÛÜ ÛÛÛÜ ÛÛÛÛÛ ßÛÛÛÛÛ ßÛÛÛÛ ÛÛÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÜ
// ÛÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÛÛÛÛ
// °°°°°°°° ÛÛÛÛÛÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛÜ ÛÛÛÛÛÛÛÛ ÛÛÛÛÛÜ ÜÛÛÛÛÛÛ
// °°XXXXX° ÛÛÛÛ ÛÛÛÜ ÛÛÛÛÛ ÛÛÛÛÛÛÜ ßÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
// °°XXXXX °° ÛÛÛÛ ÛÛÛÛÜ ÛÛÛÛ °°°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°° ÛÛÛÛÛÛÛÛÛÛÛÛÛß
// ° XXXXX °°ÛÛÛÛÛ°°°°ÛÛÛÛÛÛÛÛ°°XX ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ XXX°°ÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛ
// °° XXXXX ÜÛÛÛÛÛÛ X ÛÛÛÛÛÛÛÛÛ XXX ÛÛÛÛÛÛÛÛÛÛÛ XXXXXX ÛÛÛÛÛÛÛ° ÛÛÛ
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°° °°°°
// °° XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°X°°
// °°° XXXXXXXXXX °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° XXXXXXXXXXXXXXXXX°°
// °°°°°°°°°°°°°°°° °°°°°°°° XXXXXXX °°°
// °°°°°° XX °°
// ...2009 and still moving on. °°°°°°°
// °°
// Thanks alot to bigapple90 for pointing out a bug appearing with the 1.24 patch according to this spell
//
//////////////////////////////////////Globals with important values////////////////////////////////////////
scope DuskySoul initializer Init
globals
private constant integer Spell = 'A005'
//Dark Soul Spell
private constant integer Summon = 'n001'
//Summoned unit (Dark Soul)
private constant integer AttackDummy = 'h002'
//An Attack dummy to fake an attack at the target
private constant integer AttackProjectile = 'h003'
//Projectile of the Dark Soud
private constant integer DummyVertex = 170
//Vertex the Summon has
private constant integer DummyDarkness = 255
//How dark the summon is
private constant real TimerPeriod = 0.0225
//Timer Interval of the custom projectiles
private constant real TimerPeriodDsys = 0.1
//Timer Interval for the Attack dummys locaation adjust (moves the dummy to the target to faake an attack)
private constant real CrueltyDamage = 0.14
//Percentage damage of hp missing
private constant real HitRange = 30
//Range in which the projectiles hit an enemy
private constant real HitHeight = 45
//Height in which the projectiles will reach the target (flying heigh wwill be additional)
private constant real ProjectileSpeed = 18
//Speed the Projectiles got, also affaectey by the timer period
private constant real ProjectileStartX = -12
// X Offset of the Projectile Creation (look at the model you used)
private constant real ProjectileStartY = 100
// Y Offset of the Projectile Creation (look at the model you used)
private constant real ProjectileStartZ = 130
// Z Offset of the Projectile Creation (look at the model you used)
private constant real ProjectileSway = 0.15
//Defines the amplitude of the projectiles movement (their distance to each other increaes while flying like a parabula
// 0.15 means the amplitube will be 15% of the flying distance
private constant real GrowSpeed = 7
//Rate the summon will grow and shring (played when creating it)
private constant real DummySize = 1.15
//The normal size of the Summon (needed for the grow/shrink)
private constant string AttackEffect = "Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl"
//The effects displayed the the darksould hands when releasing a missile
private constant string AOEeffect = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"
// AOE effect when hitting a target with Inner Blaze
private constant string StartAnimation = "Spell"
//The animation the dummy plays when being created
private constant boolean KillDS = false //Sets the action if the hero casts the ability while he already got one Dark soul summoned
//True = Kiling the current Dark Sould when casting it again
//False = Odering the caster to stop
///////////////////////////////////Globals that should not be changed////////////////////////////
private trigger array tr //Trigger for each hero casting and having the summoned unit to protect any damage
private trigger array tr2 //Trigger to get the damage of each attack dummy and create missiles then
private integer trin = 0 //Trigger index , how many Summoned units are ingame which use this custom system (equals number of dummies and current triggers Tr1 and Tr2)
private unit array ds //Dark soul (with trin index)
private unit array ad //Attack Dummy (with trin index)
private unit array targ //Target of each Dark sould (with trin index)
private unit array hero //Corrensponding hero (with trin index)
private timer t2 = CreateTimer()
private boolean cb = false // boolean if any callbacls should run
private boolexpr filter
private timer t = CreateTimer()
endglobals
/////////////////////////////////////////Function modifications////////////////////////////////////////////////////////
private function RunCondition takes nothing returns boolean
return GetSpellAbilityId() == Spell
//The condition if the spell is casted
endfunction
private constant function Duration takes integer level returns real
return 75.00
endfunction
private function DamageTarget takes real damage, unit target, unit dealer returns nothing
//Sets which function is used to deal the damage, now it is dependent on the IFDamage function in Inner Blaze which will cause its damage to splash if the unit got the buff
//If you dont want it to splash, replace it, e.g. with the one below or whichever you want
call IFDamage(damage,target,dealer,AOEeffect,"chest")
//call UnitDamageTarget(dealer,target,damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
endfunction
function DisplayDamage takes real damage, unit u returns nothing
//Displays the bonus damage of the Dark Soul
local texttag tt = null
if R2I(damage) != 0 then // does not display "+0" damage
set tt = CreateTextTag()
call SetTextTagText(tt, "|c00ff5656+"+I2S(R2I(damage))+"|r", 0.023)
//The color is set here
//Any other things you may want to modify or not
call SetTextTagPos(tt, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u))
call SetTextTagColor(tt,255,255,255,255)
call SetTextTagVisibility(tt, true)
call SetTextTagFadepoint(tt,3.00)
call SetTextTagPermanent(tt,false)
call SetTextTagVelocity(tt, 0, 0.0355)
call SetTextTagLifespan(tt, 4.00)
set tt = null
endif
endfunction
////////////////////////////////////////Main Script /////////////////////////////////////////////////////////////
private constant function NullFilter takes nothing returns boolean
return true
endfunction
private function GetHeroIndex takes unit a returns integer
local integer ret = -1
local integer i = 0
// Gets the trin of the hero to find its correnspoding summon ect
loop
exitwhen i == trin
if a == hero[i] then
set ret = i
endif
set i = i + 1
endloop
return ret
endfunction
private function GetTargIndex takes unit a returns integer
local integer ret = -1
local integer i = 0
// Gets the trin of a targeted unit to check if a unit s attacking it (cuz the attack dummy stay and else it would be still "attacked")
loop
exitwhen i == trin
if a == targ[i] then
set ret = i
endif
set i = i + 1
endloop
return ret
endfunction
private function GetDSIndex takes unit a returns integer
local integer ret = -1
local integer i = 0
/// Gets the trin of a Dark sould to let the hero deal the damage (needs to be for Inner Blaze cuz he has the ability)
loop
exitwhen i == trin
if a == ds[i] then
set ret = i
endif
set i = i + 1
endloop
return ret
endfunction
private function GetDummyIndex takes unit a returns integer
local integer ret = -1
local integer i = 0
// Gets the trin of a Dummy unit
loop
exitwhen i == trin
if a == ad[i] then
set ret = i
endif
set i = i + 1
endloop
return ret
endfunction
private function GetUnitsAngle takes unit a, unit b returns real
//angle between units, from a to b
return Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
endfunction
function GetUnitDistance takes unit a, unit b returns real
//Distance between 2 units
return SquareRoot((GetUnitX(a) - GetUnitX(b)) * (GetUnitX(a) - GetUnitX(b)) + (GetUnitY(a) - GetUnitY(b)) * (GetUnitY(a) - GetUnitY(b)))
endfunction
///////////////////////////////////////CallBack//////////////////////////////////////////////
private function Callback takes nothing returns nothing
local integer i = 0
local real db
//looping through each dark Sould (creation grow)
loop
exitwhen i >= DS.Index
if DS.Data[i].inc == -1 and DS.Data[i].size == DummySize then
set DS.Data[i].c = null
set DS.Data[i].Ds = null
call DS.destroy(DS.Data[i])
set DS.Index = DS.Index - 1
set DS.Data[i] = DS.Data[DS.Index]
else
call DS.Data[i].grow()
set i = i + 1
endif
endloop
set i = 0
//looping through each Projectile to move it
loop
exitwhen i >= Pr.Index
if GetUnitDistance(Pr.Data[i].pr[0],Pr.Data[i].target) <= HitRange then
//Here is defined if aa Projectile hits its target
set db = (GetUnitState(Pr.Data[i].target,UNIT_STATE_MAX_LIFE)-GetWidgetLife(Pr.Data[i].target)) * CrueltyDamage
call UnitDamageTarget(Pr.Data[i].ca,Pr.Data[i].target,0.001,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
call DamageTarget(Pr.Data[i].dmg+db,Pr.Data[i].target,Pr.Data[i].ma)
call DisplayDamage(db,Pr.Data[i].target)
call KillUnit(Pr.Data[i].pr[0])
call KillUnit(Pr.Data[i].pr[1])
call KillUnit(Pr.Data[i].pr[2])
set Pr.Data[i].pr[0] = null
set Pr.Data[i].pr[1] = null
set Pr.Data[i].pr[2] = null
set Pr.Data[i].ca = null
set Pr.Data[i].target = null
call Pr.destroy(Pr.Data[i])
set Pr.Index = Pr.Index - 1
set Pr.Data[i] = Pr.Data[Pr.Index]
else
call Pr.Data[i].move()
set i = i + 1
endif
endloop
if DS.Index > 0 or Pr.Index > 0 then
call TimerStart(t, TimerPeriod, false, function Callback)
else
set cb = false
endif
endfunction
////////////////////////////////////////Summon Projectile////////////////////////////////////////////
struct Pr //Projectile
static integer Index = 0
static Pr array Data
unit target//Missile dummy
unit ca //"Caster" , means its the attacking summon
unit ma //"Master" of the summon, the corrensponding hero
real maxd //Distance when creating the missile
real dmg //dmage stored
unit array pr [3] // the 3 Proectiles
static method create takes unit ca, unit ta, real damage returns Pr
local Pr data = Pr.allocate()
local real a = GetUnitsAngle(ca,ta)
local integer i = 0
local real x = GetUnitX(ca) + (Cos(a) * ProjectileStartY) + (Sin(a) * ProjectileStartX)
local real y = GetUnitY(ca) + (Cos(a) * ProjectileStartX) + (Sin(a) * ProjectileStartY)
local integer index = GetDSIndex(ca)
set Pr.Data[Pr.Index] = data
set data.ma = hero[index]
//Creating the 3 projectiles
loop
exitwhen i == 3
set data.pr[i] = CreateUnit(GetOwningPlayer(ca),AttackProjectile,x,y,a)
call SetUnitFlyHeight(data.pr[i],ProjectileStartZ,0)
set i = i + 1
endloop
set data.maxd = GetUnitDistance(ta,data.pr[1]) * 1.05 // lil bit bigger cuz else its amplitude will not be 0 at the end
set data.ca = ca
set data.target = ta
set data.dmg = damage
if cb == false then
call TimerStart(t, TimerPeriod,false, function Callback)
set cb = true
endif
set Pr.Index = Pr.Index + 1
return data
endmethod
method move takes nothing returns nothing
local integer i = 0
local real a = GetUnitsAngle(this.pr[1],this.target)
local real d = (ProjectileSpeed+GetUnitDistance(this.target,this.pr[1]))/this.maxd
local real offset = Sin(3.14159*d) * ProjectileSway * this.maxd
//Moving all 3 Missiles (refers to pr[1]´s x and y because its not affected by the amplitide
call SetUnitX(this.pr[1],GetUnitX(this.pr[1])+ProjectileSpeed*Cos(a))
call SetUnitY(this.pr[1],GetUnitY(this.pr[1])+ProjectileSpeed*Sin(a))
call SetUnitFlyHeight(this.pr[1],ProjectileStartZ + offset + (GetUnitFlyHeight(this.target) - ProjectileStartZ + HitHeight) * (1-d) ,0)
call SetUnitX(this.pr[0],GetUnitX(this.pr[1])+offset*Cos(a + (3.14159/2)) )
call SetUnitY(this.pr[0],GetUnitY(this.pr[1])+offset*Sin(a + (3.14159/2)) )
call SetUnitFlyHeight(this.pr[0],ProjectileStartZ + (GetUnitFlyHeight(this.target) - ProjectileStartZ + HitHeight) * (1-d) ,0)
call SetUnitX(this.pr[2],GetUnitX(this.pr[1])+offset*Cos(a - (3.14159/2)) )
call SetUnitY(this.pr[2],GetUnitY(this.pr[1])+offset*Sin(a - (3.14159/2)) )
call SetUnitFlyHeight(this.pr[2],ProjectileStartZ + (GetUnitFlyHeight(this.target) - ProjectileStartZ + HitHeight) * (1-d) ,0)
endmethod
endstruct
////////////////////////////////////////Damage System////////////////////////////////////////////////
function AdjustTarget takes nothing returns nothing
//If a summon gets aa new target its set here any the dummy is moved
local unit b = GetAttacker()
local integer index = GetDSIndex(b)
local unit a = GetTriggerUnit()
local real angle = GetUnitsAngle(b,ad[index])
if GetUnitTypeId(a) != AttackDummy and ad[index] != a then
set targ[index] = a
//Need to do this senseless crap here, else the Summons attack animation is not played properly (but i wonder why, it just gets the order to attack another unit)
// I <3 Blizzard logic
call SetUnitPosition(ad[index],GetUnitX(a),GetUnitY(a))
call IssueImmediateOrder(b, "stop" )
call PauseUnit(b,true)
call PauseUnit(b,false)
call IssueTargetOrder( b, "attack", ad[index])
endif
set b = null
set a = null
endfunction
function UnitDies takes nothing returns nothing
//If a unit dies which is "ttacked" by a summon it gets the stor order 8stopt attacking the neutral dummy
//Then it searched a new target
local unit u = GetTriggerUnit()
local integer i = GetTargIndex(u)
if i != -1 then
call IssueImmediateOrder(ds[i], "stop" )
endif
set u = null
endfunction
function InitDeath takes nothing returns nothing
local trigger d = CreateTrigger( )
local integer index = 0
// Creates a trigger to check if a target dies
loop
call TriggerRegisterPlayerUnitEvent(d, Player(index), EVENT_PLAYER_UNIT_DEATH , filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction( d, function UnitDies )
endfunction
function MoveDummy takes nothing returns nothing
local integer i = 0
//periodicly movinge the dummy to the real targets location
loop
exitwhen i > trin
call SetUnitX(ad[i],GetUnitX(targ[i]))
call SetUnitY(ad[i],GetUnitY(targ[i]))
set i = i + 1
endloop
if trin > 0 then
call TimerStart(t2, TimerPeriodDsys, false, function MoveDummy)
endif
endfunction
function StartMissile takes nothing returns nothing
//Event is when a dummy gets damage, then (due the attck of the sumon is instant) its damage is stored and projectiles are creted
local integer index = GetDummyIndex(GetTriggerUnit())
call DestroyEffect(AddSpecialEffectTarget(AttackEffect,GetEventDamageSource(),"hand, left"))
call DestroyEffect(AddSpecialEffectTarget(AttackEffect,GetEventDamageSource(),"hand, right"))
call Pr.create(GetEventDamageSource(),targ[index],GetEventDamage())
endfunction
function RightDamager takes nothing returns boolean
//Condition that a summon damaged thee dummy, could also happen with AOE spells
return GetUnitTypeId(GetEventDamageSource()) == Summon
endfunction
function InitGetDamage takes unit dummy returns nothing
//Initializing the Trigger when a Dummy takes damage
set tr2[trin] = CreateTrigger()
if trin == 0 then
call TimerStart(t2, TimerPeriodDsys, true, function MoveDummy)
endif
call TriggerRegisterUnitEvent( tr2[trin], dummy, EVENT_UNIT_DAMAGED )
call TriggerAddAction( tr2[trin], function StartMissile )
call TriggerAddCondition( tr2[trin], Condition( function RightDamager ) )
endfunction
function RightAttacker takes nothing returns boolean
//Condition that its a Summon which targets the dummy
return GetUnitTypeId(GetAttacker()) == Summon
endfunction
function InitDsys takes nothing returns nothing
local integer index = 0
local trigger trig = CreateTrigger( )
//Generally initializing the system with creating the trigger to get the point a dummy is attacked
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_ATTACKED, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction( trig, function AdjustTarget )
call TriggerAddCondition( trig, Condition( function RightAttacker ) )
endfunction
/////////////////////////////////////////////Damage Protection//////////////////////////////////
function ProtectDamage takes nothing returns nothing
local unit c = GetTriggerUnit()
local integer index = GetHeroIndex(c)
//Protects damage from the casting hero , event is that it takes damage,
call SetWidgetLife(c,GetWidgetLife(c) + GetEventDamage())
//Damages the summon instead
call UnitDamageTarget(GetEventDamageSource(),ds[index],GetEventDamage(),true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
set c = null
endfunction
function InitDamageProtect takes unit c, unit s returns nothing
//Initializing the damage protection for the hero
set tr[trin] = CreateTrigger()
set ds[trin] = s
set ad[trin] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackDummy,0,0,0)
set hero[trin] = c
call TriggerRegisterUnitEvent( tr[trin], c, EVENT_UNIT_DAMAGED )
call TriggerAddAction( tr[trin], function ProtectDamage )
call InitGetDamage(ad[trin])
set trin = trin + 1
endfunction
/////////////////////////////////////////////////////////////////////////////////////////////////
function DestroyTr takes nothing returns nothing
local integer index = GetDSIndex(GetTriggerUnit())
//Destroying all triggers and the dummy which are not needed anymore when a Summon dies
call RemoveUnit(ad[index])
set ds[index] = null
set hero[index] = null
set ad[index] = null
set targ[index] = null
call DestroyTrigger(tr[index])
set tr[index] = null
call DestroyTrigger(tr2[index])
set tr2[index] = null
set trin = trin - 1
set tr[index] = tr[trin]
set ds[index] = ds[trin]
set hero[index] = hero[trin]
set ad[index] = ad[trin]
set targ[index] = targ[trin]
endfunction
private function UnitDeath takes nothing returns boolean
//Condition that it should be a summon which dies to destroy its correspoding dummy and trigger
return GetUnitTypeId(GetTriggerUnit()) == Summon
endfunction
function DestroyTrInit takes nothing returns nothing
local integer index = 0
local trigger trig = CreateTrigger( )
//Initializes the destruction of the dummy and the trigger if a summons dies
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_DEATH, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction( trig,function DestroyTr )
call TriggerAddCondition( trig, Condition( function UnitDeath ) )
endfunction
struct DS //Dark Sould struct
static integer Index = 0
static DS array Data
unit c //Hero
unit Ds //Dark Soul
integer level //level of the spell
real size = DummySize //Current size
integer inc = 1 //Defines if the unit is groing or shrinking
unit ad //Attackdummy
static method create takes unit a, integer level returns DS
//Creates the Dark soul
local DS data = DS.allocate()
set data.c = a
set data.Ds = CreateUnit(GetOwningPlayer(a),Summon,GetUnitX(a),GetUnitY(a),GetUnitFacing(a))
call InitDamageProtect(a,data.Ds)
call SetUnitPathing(data.Ds,false)
call PauseUnit(data.Ds,true)
call SetUnitX(data.Ds,GetUnitX(a))
call SetUnitY(data.Ds,GetUnitY(a))
call SetUnitAnimation(data.Ds, StartAnimation)
call SetUnitVertexColor(data.Ds,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,DummyVertex)
set DS.Data[DS.Index] = data
if cb == false then
call TimerStart(t, TimerPeriod, true, function Callback)
set cb = true
endif
set data.Index = data.Index + 1
return data
endmethod
method grow takes nothing returns nothing
local real vertex = DummyVertex - (75*(this.size + (GrowSpeed * this.inc * 0.01) - DummySize) )
set this.size = this.size + (GrowSpeed * this.inc * 0.01)
if vertex <= 0.0 then
//Vertex reached 0, setting it to increase again
set this.inc = -1
call SetUnitPathing(this.Ds,true)
call SetUnitPosition(this.Ds,GetUnitX(this.c),GetUnitY(this.c))
call SetUnitAnimation(this.Ds, StartAnimation)
endif
if this.inc == -1 and this.size <= DummySize then
//Unit has its normal size again and animation is finished
set this.size = DummySize
set vertex = DummyVertex
call PauseUnit(this.Ds,false)
call UnitApplyTimedLife(this.Ds,0,Duration(this.level))
endif
call SetUnitScale(this.Ds,this.size,this.size,this.size)
call SetUnitVertexColor(this.Ds,255-DummyDarkness,255-DummyDarkness,255-DummyDarkness,R2I(vertex))
endmethod
endstruct
function Actions takes nothing returns nothing
local integer check = GetHeroIndex(GetTriggerUnit())
if check == -1 then
call DS.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
else
if KillDS == true then
call KillUnit(ds[check])
call DS.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
else
call IssueImmediateOrder(GetTriggerUnit(), "stop" )
endif
//A hero cannot have more than one Dark Soul a the same time
endif
endfunction
private function Init takes nothing returns nothing
local trigger tr = CreateTrigger()
local integer index = 0
//Preloading the Units
local unit preload = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackProjectile,0,0,0)
local unit preload2 = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),AttackDummy,0,0,0)
call KillUnit(preload)
call KillUnit(preload2)
//Preloading Effects
call Preload(AttackEffect)
call Preload(AOEeffect)
set filter = Filter(function NullFilter)
//Initializing the 3 systems
call DestroyTrInit() //General thing if a Summon dies / removing dummy + destroying other triggers
call InitDeath() //General thing if a target dies
call InitDsys() //General Damage System with custom projectiles
loop
call TriggerRegisterPlayerUnitEvent(tr, Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, filter)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( tr, Condition( function RunCondition ) )
call TriggerAddAction( tr, function Actions )
set preload = null
endfunction
endscope