Darkchaoself
What is this i dont even
- Reaction score
- 106
Question, Will having a large amount of units, around 12, using them as models for spells, take off points for importability?
Can't give you official answer, but I guess it might remove a few points of coding. Why do you need so many units anyway?
Unleash a sphere in front of the caster. The sphere will start growing as it drains mana of nearly units. Whenever you stop the channeling the sphere will explode dealing damage to nearby units by an % of the mana drained. Mana Sphere overloads with a determined mana. 600 AoE For all levels, needs at least 100 mana to maintain the sphere
//!<--Start of my Spell-->!//
scope BunJeeShotStructed
//---------------------------------------------------------//
// BunJee Shot //
// by ~GaLs~ //
//---------------------------------------------------------//
//**Especially made for Official Spell Contest #1**//
//
//[Requires NewGen WorldEditor to get this spell work]
//[Download it from <a href="http://www.wc3campaigns.net]" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.wc3campaigns.net]</a>
//
//[3 Simple Step To Implement This Spell]
//
//Implementation Instruction:
//
//1. Things need to be copied from Object Editor to your map:
// << Unit >>
// a. A dummy unit named Stick DummyUse.
//
// << Ability >>
// b. The BunJee Shot ability.
//
//2. Copy this whole trigger to your map.
//
//3. Replace those rawcode in the configuration below. (Also modify those speed, effect at there.)
//---------------------------------------------------------//
// Thanks For Using My Spell //
// Please Give Credit //
//---------------------------------------------------------//
globals
//===================================================
//== Configuration ==
//===================================================
//-------------------------------------------------------------------------------------
//<--RawCode-->//
private constant integer BJS_Id = 039;A000039; //Rawcode of the main ability.
private constant integer BJS_TorchId = 039;h001039; //Rawcode of the Torch Unit.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Charging Speed-->//
private constant real BJS_ChargingSpeed = .07
//This is the charge speed of the charging period. (Channeling Period)
//The smaller the number, the faster the unit charge.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Rush Speed-->//
private constant real BJS_RushSpeed = 100.
//This is the rush speed of the rushing period. (After Channel)
//The larger the number, the faster it rush. BEWARE: Do not set it larger than 200 or less than 50, LAG warning.
//But the different between 50 and 200 is hard to different shape by naked eye.
//<--End-->//
//-------------------------------------------------------------------------------------
//<--Charge Effect-->//
private constant string BJS_ChargeEffect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
//This is the special effect that will be view when charging.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Lightning Effect-->//
//These are the lightning effect which is act as an elastic string. The level of it is sort by BJS_Lightning<Level>.
private constant string BJS_Lightning1 = "MFPB" //Mana Flare
private constant string BJS_Lightning2 = "MBUR" //Mana Burn
private constant string BJS_Lightning3 = "HWSB" //Healing Wave (Secondary)
private constant string BJS_Lightning4 = "SPLK" //Spirit Link
private constant string BJS_Lightning5 = "AFOD" //Finger Of Death
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Rush Effect-->//
private constant string BJS_RushEffect = "Abilities\\Spells\\Items\\WandOfNeutralization\\NeutralizationMissile.mdl"
//This is the effect that will be display at whole caster's body when the channeling had finished.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Channel ID-->//
private constant integer ChannelId = 852600
//Well, I was force to use 852600 because OrderId doesn't work for unknown reason. =.=
//<--End-->//
//-------------------------------------------------------------------------------------
//===================================================
//== End Configuration ==
//===================================================
//===================================
//== Unrelated Items ==
//===================================
//Comment: These 3 variable are variable that is needed to pass function. Advised to not take any care of them.
private group DummyDamaged
private unit DummyCaster
private real DummyDamage
//===================================
//== Unrelated Items End ==
//===================================
endglobals
//========================================================================================
//== WARNING! WARNING! WARNING! ==
//== DO NOT EDIT ANYTHING UNDER THIS LINE! ==
//========================================================================================
//! Comments below is only for emjlr3. (Judging purpose) !//
//===================================
//== BunjeeShot Struct ==
//===================================
private struct BunjeeShot
unit caster
unit array Torch [3]
real TarAngle
real ChannelTotal = 5
real Charged
real DamageOn
real RushDist
real CX
real CY
real TX
real TY
timer t
timer RushT
lightning array Elastic [3]
string LastLightningEffect
string array LightningEffect[6]
group Damaged
static method create takes unit cast, real TarX, real TarY returns BunjeeShot
local BunjeeShot BJS = BunjeeShot.allocate()
set BJS.caster = cast //set caster
set BJS.TX = TarX //set targeted position's X
set BJS.TY = TarY //set targeted position's Y
set BJS.CX = GetUnitX(BJS.caster) //set the caster's position to X and Y
set BJS.CY = GetUnitY(BJS.caster)
set BJS.TarAngle = bj_RADTODEG * Atan2(BJS.TY - BJS.CY, BJS.TX - BJS.CX) //This evaluate the angle from caster to the casting point
set BJS.t = CreateTimer() //create timer.
set BJS.RushT = CreateTimer() //create timer. (Which uses CSSafety xD)
set BJS.ChannelTotal = 5 //The maximun channel period.
set BJS.LightningEffect[1] = BJS_Lightning1 //Setting all those lightning string to array.
set BJS.LightningEffect[2] = BJS_Lightning2
set BJS.LightningEffect[3] = BJS_Lightning3
set BJS.LightningEffect[4] = BJS_Lightning4
set BJS.LightningEffect[5] = BJS_Lightning5
set BJS.Damaged = CreateGroup() //This group is to store damaged unit during the damaging period.
return BJS
endmethod
method offsetX takes real X, real distance, real angle returns real
return X + distance * Cos(angle * bj_DEGTORAD)
endmethod
method offsetY takes real Y, real distance, real angle returns real
return Y + distance * Sin(angle * bj_DEGTORAD)
endmethod
method CreLightning takes nothing returns nothing //This is a short system for creating the lightning effect as elastic. <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue :p" loading="lazy" data-shortname=":p" />
local integer start =0
local integer end = 5 //Thanks to the array I just set at the create method. I would use loop to finish this task.
loop
exitwhen start>end
if 5 - .ChannelTotal >start and 5-.ChannelTotal <start+1 then
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = AddLightningEx(.LightningEffect[start+1],true,GetUnitX(.Torch[1]),GetUnitY(.Torch[1]),0,GetUnitX(.caster),GetUnitY(.caster),GetUnitFlyHeight(.caster))
set .Elastic[2] = AddLightningEx(.LightningEffect[start+1],true,GetUnitX(.Torch[2]),GetUnitY(.Torch[2]),0,GetUnitX(.caster),GetUnitY(.caster),GetUnitFlyHeight(.caster))
endif
set start = start+1
endloop
endmethod
method EndLightning takes nothing returns nothing //This is what the lightning looks like when the channeling is done.
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = AddLightning(.LightningEffect[5],true,GetUnitX(.Torch[1]),GetUnitY(.Torch[1]),GetUnitX(.Torch[2]),GetUnitY(.Torch[2]))
set .Elastic[2] = AddLightning(.LightningEffect[5],true,GetUnitX(.Torch[2]),GetUnitY(.Torch[2]),GetUnitX(.Torch[1]),GetUnitY(.Torch[1]))
endmethod
method onDestroy takes nothing returns nothing //Cleans all leaks
set .caster = null
set .Torch[1] = null
set .Torch[2] = null
call DestroyTimer(.t)
call DestroyTimer(.RushT)
set .t = null
set .RushT = null
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = null
set .Elastic[2] = null
call DestroyGroup(.Damaged)
set .Damaged = null
endmethod
endstruct
//===================================
//== BunjeeShot Struct End ==
//===================================
//=======================================================================
//== Timer Call Back ==
//=======================================================================
private function BJS_DamagedCond takes nothing returns boolean
return IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0 and IsUnitInGroup(GetFilterUnit(),DummyDamaged) == false and IsUnitAlly(GetFilterUnit(),GetOwningPlayer(DummyCaster))==false
//The condition of damaging a unit.
endfunction
private function BJS_DamagedAct takes nothing returns nothing
call UnitDamageTarget(DummyCaster,GetEnumUnit(),DummyDamage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,null)
call GroupAddUnit(DummyDamaged,GetEnumUnit())
//To prevent double or even triple damage deal to a unit.
endfunction
private function BJS_RushTEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local BunjeeShot BJS = GetTimerStructB(t)
local group Damaged = CreateGroup()
set DummyDamaged = BJS.Damaged
set DummyCaster = BJS.caster //This 3 globals are to pass value through functions.
set DummyDamage = BJS.DamageOn //Don't worry, leaks are all cleaned when the struct is destroyed.
if BJS.RushDist > 0 then
set BJS.CX = BJS.offsetX(BJS.CX,BJS_RushSpeed,BJS.TarAngle)
set BJS.CY = BJS.offsetY(BJS.CY,BJS_RushSpeed,BJS.TarAngle)
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"chest"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"hand, left"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"hand, right"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"foot, left"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"foot, right"))
if IsTerrainPathable(BJS.CX,BJS.CY,PATHING_TYPE_WALKABILITY)==false then
call SetUnitX(BJS.caster,BJS.CX)
call SetUnitY(BJS.caster,BJS.CY)
endif
call GroupEnumUnitsInRange(Damaged, BJS.CX,BJS.CY,200, Condition(function BJS_DamagedCond))
call ForGroup(Damaged, function BJS_DamagedAct)
set BJS.Damaged = DummyDamaged
set BJS.RushDist = BJS.RushDist - BJS_RushSpeed
elseif BJS.RushDist < 0 then
call PauseTimer(t)
call DestroyTimer(t)
call BJS.destroy()
endif
set t = null
call DestroyGroup(Damaged)
set Damaged = null
endfunction
private function BJS_TimerEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local BunjeeShot BJS = GetTimerStructA(t)
if GetUnitCurrentOrder(BJS.caster) == ChannelId and BJS.ChannelTotal > 0 then
set BJS.CX = BJS.offsetX(BJS.CX, 5, BJS.TarAngle-180)//New X
set BJS.CY = BJS.offsetY(BJS.CY, 5, BJS.TarAngle-180)//New Y
if IsTerrainPathable(BJS.CX,BJS.CY,PATHING_TYPE_WALKABILITY)==false then //Avoid unit to crash outside of the map border.
call DestroyEffect(AddSpecialEffect(BJS_ChargeEffect,BJS.CX,BJS.CY))
call SetUnitX(BJS.caster,BJS.CX)
call SetUnitY(BJS.caster,BJS.CY)
endif
call BJS.CreLightning()
set BJS.ChannelTotal = BJS.ChannelTotal - .08
elseif GetUnitCurrentOrder(BJS.caster) != ChannelId or BJS.ChannelTotal < 0 then
call UnitApplyTimedLife(BJS.Torch[1],039;BTLF039;,.1)
call UnitApplyTimedLife(BJS.Torch[2],039;BTLF039;,.1)
set BJS.Charged = 5 - BJS.ChannelTotal
set BJS.DamageOn = (GetUnitAbilityLevel(BJS.caster,BJS_Id))*(BJS.Charged)*(50)
set BJS.RushDist = (GetUnitAbilityLevel(BJS.caster,BJS_Id)) * (100) * (BJS.Charged)
call SetTimerStructB(t,BJS)
call BJS.EndLightning()
call TimerStart(t,.01,true,function BJS_RushTEnd)
endif
set t = null
endfunction
//=======================================================================
//== Timer Call Back End ==
//=======================================================================
//=========================================================
//== Main Function ==
//=========================================================
private function BJS_Cond takes nothing returns boolean
return GetSpellAbilityId() == BJS_Id
endfunction
private function BJS_Act takes nothing returns nothing
local location TLoc = GetSpellTargetLoc()
local BunjeeShot BJS = BunjeeShot.create(GetSpellAbilityUnit(),GetLocationX(TLoc),GetLocationY(TLoc))
local integer LoopInt = 1
local real CreateDummyX
local real CreateDummyY
//<--Creating Torch-->//
loop
exitwhen LoopInt>2
if LoopInt == 1 then
set CreateDummyX = BJS.offsetX(BJS.CX,200,BJS.TarAngle+90)
set CreateDummyY = BJS.offsetY(BJS.CY,200,BJS.TarAngle+90)
set BJS.Torch[LoopInt] = CreateUnit(GetOwningPlayer(BJS.caster),BJS_TorchId,CreateDummyX,CreateDummyY,BJS.TarAngle)
elseif LoopInt == 2 then
set CreateDummyX = BJS.offsetX(BJS.CX,200,BJS.TarAngle-90)
set CreateDummyY = BJS.offsetY(BJS.CY,200,BJS.TarAngle-90)
set BJS.Torch[LoopInt] = CreateUnit(GetOwningPlayer(BJS.caster),BJS_TorchId,CreateDummyX,CreateDummyY,BJS.TarAngle)
endif
set LoopInt = LoopInt + 1
endloop
//<--End-->//
call SetTimerStructA(BJS.t,BJS)
call TimerStart(BJS.t,BJS_ChargingSpeed,true,function BJS_TimerEnd)
endfunction
//=========================================================
//== End Main Function ==
//=========================================================
//===========================================================================
function InitTrig_BunJee_Shot takes nothing returns nothing
local integer start = 0
local integer end = 15
set gg_trg_BunJee_Shot = CreateTrigger()
loop
exitwhen start>end
call TriggerRegisterPlayerUnitEvent(gg_trg_BunJee_Shot,Player(start),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set start = start + 1
endloop
call TriggerAddCondition(gg_trg_BunJee_Shot, Condition(function BJS_Cond))
call TriggerAddAction(gg_trg_BunJee_Shot, function BJS_Act)
endfunction
endscope
//!<--End of my Spell-->!//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//Thanks to Cohadar for his brilliant ABC system.
//==============================================================================
// ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v5.1
//==============================================================================
//------------------------------------------------------------------------------
// We will use textmacros to create multiple instances of system
//------------------------------------------------------------------------------
//! textmacro ABC takes X, NAME, TYPE
//------------------------------------------------------------------------------
// Global arrays represent our hash tables.
// System is currently using 3 hash tables per handle type. (A, B, C)
//------------------------------------------------------------------------------
globals
private $TYPE$ array $TYPE$Key$X$
private integer array $TYPE$Value$X$
private integer $TYPE$maxCollision$X$ = 0
endglobals
//------------------------------------------------------------------------------
// returns the maximum collision so far
//------------------------------------------------------------------------------
function Get$NAME$Collision$X$ takes nothing returns integer
return $TYPE$maxCollision$X$
endfunction
//------------------------------------------------------------------------------
// initializes hash arrays to prevent lag when ABC is used for the first time
//------------------------------------------------------------------------------
private function Init$NAME$Hash$X$ takes nothing returns nothing
set $TYPE$Key$X$[HASH_INDEX_LIMIT] = null
set $TYPE$Value$X$[HASH_INDEX_LIMIT] = 0
endfunction
//------------------------------------------------------------------------------
// attaches struct to a handle by using hash table
//------------------------------------------------------------------------------
function Set$NAME$Struct$X$ takes $TYPE$ t, integer s returns nothing
debug local integer collision
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
if $TYPE$Key$X$<i> == null then
set $TYPE$Value$X$<i> = s
set $TYPE$Key$X$<i> = t
return
endif
debug if $TYPE$Key$X$<i> == t then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t)))
debug return
debug endif
// if function gets below this line we have a collision
debug set collision = 1
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] overflow")
debug return
debug endif
debug set collision = collision + 1
set i = i + 1
exitwhen $TYPE$Key$X$<i> == null
debug if $TYPE$Key$X$<i> == t then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t)))
debug return
debug endif
endloop
debug if collision > $TYPE$maxCollision$X$ then
debug call BJDebugMsg("|cFFFF4444Warning: Hash[$X$] maximum collision is now: " + I2S(collision))
debug set $TYPE$maxCollision$X$ = collision
debug endif
set $TYPE$Value$X$<i> = s
set $TYPE$Key$X$<i> = t
return
endfunction
//------------------------------------------------------------------------------
// gets stored struct from a handle
//------------------------------------------------------------------------------
function Get$NAME$Struct$X$ takes $TYPE$ t returns integer
debug local integer collision
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
if $TYPE$Key$X$<i> == t then
return $TYPE$Value$X$<i>
endif
// if function gets below this line we have a collision
debug set collision = 1
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : get request on unknown handle")
debug return 0
debug endif
debug set collision = collision + 1
set i = i + 1
exitwhen $TYPE$Key$X$<i> == t
endloop
return $TYPE$Value$X$<i>
endfunction
//------------------------------------------------------------------------------
// clears stored struct from a handle, also returns cleared value
//------------------------------------------------------------------------------
function Clear$NAME$Struct$X$ takes $TYPE$ t returns integer
debug local integer collision
local integer ik
local integer ret
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
// first find the index on witch key is stored
debug set collision = 0
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : clear request on unknown handle")
debug return 0
debug endif
debug set collision = collision + 1
exitwhen $TYPE$Key$X$<i> == t
set i = i + 1
endloop
set ik = i
set ret = $TYPE$Value$X$[ik]
// then find last used key index in bucket
loop
set i = i + 1
// we use the fact bucket borders (mod 8 indexes) are always null
exitwhen $TYPE$Key$X$<i> == null
endloop
// shift last bucket entry to the place of removed one
set $TYPE$Key$X$[ik] = $TYPE$Key$X$[i-1]
set $TYPE$Value$X$[ik] = $TYPE$Value$X$[i-1]
// clear the previous last bucket entry
set $TYPE$Key$X$[i-1] = null
return ret
endfunction
//! endtextmacro
//==============================================================================
// Macro execution -- this is where real functions get created
//==============================================================================
library ABC initializer Init
globals
public constant integer HASH_SIZE = 8192
public constant integer HASH_INDEX_LIMIT = 8190
public constant integer HASH_DOWN = 524288 // 2^19
public constant integer HASH_UP = 2134900736 // 2^22 * 509
public constant integer HASH_BIAS = 4096 // HASH_SIZE / 2
public constant integer HASH_COLLISION_LIMIT = 7 // ABC v5.0 had limit 8
// 509 is the prime closest to 512
endglobals
//------------------------------------------------------------------------------
// conversion function used by the system internally
// you will not need to use it directly
//------------------------------------------------------------------------------
public function H2I takes handle h returns integer
return h
return 0
endfunction
//! runtextmacro ABC("A","Timer","timer")
//! runtextmacro ABC("B","Timer","timer")
//! runtextmacro ABC("C","Timer","timer")
//! runtextmacro ABC("A","Trigger","trigger")
//! runtextmacro ABC("B","Trigger","trigger")
//! runtextmacro ABC("C","Trigger","trigger")
//! runtextmacro ABC("A","Dialog","dialog")
//! runtextmacro ABC("B","Dialog","dialog")
//! runtextmacro ABC("C","Dialog","dialog")
private function Init takes nothing returns nothing
call InitTimerHashA()
call InitTimerHashB()
call InitTimerHashC()
call InitTriggerHashA()
call InitTriggerHashB()
call InitTriggerHashC()
call InitDialogHashA()
call InitDialogHashB()
call InitDialogHashC()
endfunction
endlibrary
//==============================================================================
// END OF ABC STRUCT ATTACHMENT SYSTEM
//==============================================================================</i></i></i></i></i></i></i></i></i></i></i></i></i></i>
//!<--Start of my Spell-->!//
scope BunJeeShotStructed
//---------------------------------------------------------//
// BunJee Shot //
// by ~GaLs~ //
//---------------------------------------------------------//
//**Especially made for Official Spell Contest #1**//
//
//[Requires NewGen WorldEditor to get this spell work]
//[Download it from <a href="http://www.wc3campaigns.net]" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.wc3campaigns.net]</a>
//
//[3 Simple Step To Implement This Spell]
//
//Implementation Instruction:
//
//1. Things need to be copied from Object Editor to your map:
// << Unit >>
// a. A dummy unit named Stick DummyUse.
//
// << Ability >>
// b. The BunJee Shot ability.
//
//2. Copy this whole trigger to your map.
//
//3. Replace those rawcode in the configuration below. (Also modify those speed, effect at there.)
//---------------------------------------------------------//
// Thanks For Using My Spell //
// Please Give Credit //
//---------------------------------------------------------//
globals
//===================================================
//== Configuration ==
//===================================================
//-------------------------------------------------------------------------------------
//<--RawCode-->//
private constant integer BJS_Id = 039;A000039; //Rawcode of the main ability.
private constant integer BJS_TorchId = 039;h001039; //Rawcode of the Torch Unit.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Charging Speed-->//
private constant real BJS_ChargingSpeed = .07
//This is the charge speed of the charging period. (Channeling Period)
//The smaller the number, the faster the unit charge.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Rush Speed-->//
private constant real BJS_RushSpeed = 100.
//This is the rush speed of the rushing period. (After Channel)
//The larger the number, the faster it rush. BEWARE: Do not set it larger than 200 or less than 50, LAG warning.
//But the different between 50 and 200 is hard to different shape by naked eye.
//<--End-->//
//-------------------------------------------------------------------------------------
//<--Charge Effect-->//
private constant string BJS_ChargeEffect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
//This is the special effect that will be view when charging.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Lightning Effect-->//
//These are the lightning effect which is act as an elastic string. The level of it is sort by BJS_Lightning<Level>.
private constant string BJS_Lightning1 = "MFPB" //Mana Flare
private constant string BJS_Lightning2 = "MBUR" //Mana Burn
private constant string BJS_Lightning3 = "HWSB" //Healing Wave (Secondary)
private constant string BJS_Lightning4 = "SPLK" //Spirit Link
private constant string BJS_Lightning5 = "AFOD" //Finger Of Death
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Rush Effect-->//
private constant string BJS_RushEffect = "Abilities\\Spells\\Items\\WandOfNeutralization\\NeutralizationMissile.mdl"
//This is the effect that will be display at whole caster's body when the channeling had finished.
//<--End-->//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//<--Channel ID-->//
private constant integer ChannelId = 852600
//Well, I was force to use 852600 because OrderId doesn't work for unknown reason. =.=
//<--End-->//
//-------------------------------------------------------------------------------------
//===================================================
//== End Configuration ==
//===================================================
//===================================
//== Unrelated Items ==
//===================================
//Comment: These 3 variable are variable that is needed to pass function. Advised to not take any care of them.
private group DummyDamaged
private unit DummyCaster
private real DummyDamage
//===================================
//== Unrelated Items End ==
//===================================
endglobals
//========================================================================================
//== WARNING! WARNING! WARNING! ==
//== DO NOT EDIT ANYTHING UNDER THIS LINE! ==
//========================================================================================
//! Comments below is only for emjlr3. (Judging purpose) !//
//===================================
//== BunjeeShot Struct ==
//===================================
private struct BunjeeShot
unit caster
unit array Torch [3]
real TarAngle
real ChannelTotal = 5
real Charged
real DamageOn
real RushDist
real CX
real CY
real TX
real TY
timer t
timer RushT
lightning array Elastic [3]
string LastLightningEffect
string array LightningEffect[6]
group Damaged
static method create takes unit cast, real TarX, real TarY returns BunjeeShot
local BunjeeShot BJS = BunjeeShot.allocate()
set BJS.caster = cast
set BJS.TX = TarX
set BJS.TY = TarY
set BJS.CX = GetUnitX(BJS.caster)
set BJS.CY = GetUnitY(BJS.caster)
set BJS.TarAngle = bj_RADTODEG * Atan2(BJS.TY - BJS.CY, BJS.TX - BJS.CX)
set BJS.t = CreateTimer()
set BJS.RushT = CreateTimer()
set BJS.ChannelTotal = 5
set BJS.LightningEffect[1] = BJS_Lightning1
set BJS.LightningEffect[2] = BJS_Lightning2
set BJS.LightningEffect[3] = BJS_Lightning3
set BJS.LightningEffect[4] = BJS_Lightning4
set BJS.LightningEffect[5] = BJS_Lightning5
set BJS.Damaged = CreateGroup()
return BJS
endmethod
method offsetX takes real X, real distance, real angle returns real
return X + distance * Cos(angle * bj_DEGTORAD)
endmethod
method offsetY takes real Y, real distance, real angle returns real
return Y + distance * Sin(angle * bj_DEGTORAD)
endmethod
method CreLightning takes nothing returns nothing
local integer start =0
local integer end = 5
loop
exitwhen start>end
if 5 - .ChannelTotal >start and 5-.ChannelTotal <start+1 then
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = AddLightningEx(.LightningEffect[start+1],true,GetUnitX(.Torch[1]),GetUnitY(.Torch[1]),0,GetUnitX(.caster),GetUnitY(.caster),GetUnitFlyHeight(.caster))
set .Elastic[2] = AddLightningEx(.LightningEffect[start+1],true,GetUnitX(.Torch[2]),GetUnitY(.Torch[2]),0,GetUnitX(.caster),GetUnitY(.caster),GetUnitFlyHeight(.caster))
endif
set start = start+1
endloop
endmethod
method EndLightning takes nothing returns nothing
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = AddLightning(.LightningEffect[5],true,GetUnitX(.Torch[1]),GetUnitY(.Torch[1]),GetUnitX(.Torch[2]),GetUnitY(.Torch[2]))
set .Elastic[2] = AddLightning(.LightningEffect[5],true,GetUnitX(.Torch[2]),GetUnitY(.Torch[2]),GetUnitX(.Torch[1]),GetUnitY(.Torch[1]))
endmethod
method onDestroy takes nothing returns nothing
set .caster = null
set .Torch[1] = null
set .Torch[2] = null
call DestroyTimer(.t)
call DestroyTimer(.RushT)
set .t = null
set .RushT = null
call DestroyLightning(.Elastic[1])
call DestroyLightning(.Elastic[2])
set .Elastic[1] = null
set .Elastic[2] = null
call DestroyGroup(.Damaged)
set .Damaged = null
endmethod
endstruct
//===================================
//== BunjeeShot Struct End ==
//===================================
//=======================================================================
//== Timer Call Back ==
//=======================================================================
private function BJS_DamagedCond takes nothing returns boolean
return IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0 and IsUnitInGroup(GetFilterUnit(),DummyDamaged) == false and IsUnitAlly(GetFilterUnit(),GetOwningPlayer(DummyCaster))==false
endfunction
private function BJS_DamagedAct takes nothing returns nothing
call UnitDamageTarget(DummyCaster,GetEnumUnit(),DummyDamage,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,null)
call GroupAddUnit(DummyDamaged,GetEnumUnit())
endfunction
private function BJS_RushTEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local BunjeeShot BJS = GetTimerStructB(t)
local group Damaged = CreateGroup()
set DummyDamaged = BJS.Damaged
set DummyCaster = BJS.caster
set DummyDamage = BJS.DamageOn
if BJS.RushDist > 0 then
set BJS.CX = BJS.offsetX(BJS.CX,BJS_RushSpeed,BJS.TarAngle)
set BJS.CY = BJS.offsetY(BJS.CY,BJS_RushSpeed,BJS.TarAngle)
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"chest"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"hand, left"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"hand, right"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"foot, left"))
call DestroyEffect(AddSpecialEffectTarget(BJS_RushEffect, BJS.caster,"foot, right"))
if IsTerrainPathable(BJS.CX,BJS.CY,PATHING_TYPE_WALKABILITY)==false then
call SetUnitX(BJS.caster,BJS.CX)
call SetUnitY(BJS.caster,BJS.CY)
endif
call GroupEnumUnitsInRange(Damaged, BJS.CX,BJS.CY,200, Condition(function BJS_DamagedCond))
call ForGroup(Damaged, function BJS_DamagedAct)
set BJS.Damaged = DummyDamaged
set BJS.RushDist = BJS.RushDist - BJS_RushSpeed
elseif BJS.RushDist < 0 then
call PauseTimer(t)
call DestroyTimer(t)
call BJS.destroy()
endif
set t = null
call DestroyGroup(Damaged)
set Damaged = null
endfunction
private function BJS_TimerEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local BunjeeShot BJS = GetTimerStructA(t)
if GetUnitCurrentOrder(BJS.caster) == ChannelId and BJS.ChannelTotal > 0 then
set BJS.CX = BJS.offsetX(BJS.CX, 5, BJS.TarAngle-180)
set BJS.CY = BJS.offsetY(BJS.CY, 5, BJS.TarAngle-180)
if IsTerrainPathable(BJS.CX,BJS.CY,PATHING_TYPE_WALKABILITY)==false then
call DestroyEffect(AddSpecialEffect(BJS_ChargeEffect,BJS.CX,BJS.CY))
call SetUnitX(BJS.caster,BJS.CX)
call SetUnitY(BJS.caster,BJS.CY)
endif
call BJS.CreLightning()
set BJS.ChannelTotal = BJS.ChannelTotal - .08
elseif GetUnitCurrentOrder(BJS.caster) != ChannelId or BJS.ChannelTotal < 0 then
call UnitApplyTimedLife(BJS.Torch[1],039;BTLF039;,.1)
call UnitApplyTimedLife(BJS.Torch[2],039;BTLF039;,.1)
set BJS.Charged = 5 - BJS.ChannelTotal
set BJS.DamageOn = (GetUnitAbilityLevel(BJS.caster,BJS_Id))*(BJS.Charged)*(50)
set BJS.RushDist = (GetUnitAbilityLevel(BJS.caster,BJS_Id)) * (100) * (BJS.Charged)
call SetTimerStructB(t,BJS)
call BJS.EndLightning()
call TimerStart(t,.01,true,function BJS_RushTEnd)
endif
set t = null
endfunction
//=======================================================================
//== Timer Call Back End ==
//=======================================================================
//=========================================================
//== Main Function ==
//=========================================================
private function BJS_Cond takes nothing returns boolean
return GetSpellAbilityId() == BJS_Id
endfunction
private function BJS_Act takes nothing returns nothing
local location TLoc = GetSpellTargetLoc()
local BunjeeShot BJS = BunjeeShot.create(GetSpellAbilityUnit(),GetLocationX(TLoc),GetLocationY(TLoc))
local integer LoopInt = 1
local real CreateDummyX
local real CreateDummyY
//<--Creating Torch-->//
loop
exitwhen LoopInt>2
if LoopInt == 1 then
set CreateDummyX = BJS.offsetX(BJS.CX,200,BJS.TarAngle+90)
set CreateDummyY = BJS.offsetY(BJS.CY,200,BJS.TarAngle+90)
set BJS.Torch[LoopInt] = CreateUnit(GetOwningPlayer(BJS.caster),BJS_TorchId,CreateDummyX,CreateDummyY,BJS.TarAngle)
elseif LoopInt == 2 then
set CreateDummyX = BJS.offsetX(BJS.CX,200,BJS.TarAngle-90)
set CreateDummyY = BJS.offsetY(BJS.CY,200,BJS.TarAngle-90)
set BJS.Torch[LoopInt] = CreateUnit(GetOwningPlayer(BJS.caster),BJS_TorchId,CreateDummyX,CreateDummyY,BJS.TarAngle)
endif
set LoopInt = LoopInt + 1
endloop
//<--End-->//
call SetTimerStructA(BJS.t,BJS)
call TimerStart(BJS.t,BJS_ChargingSpeed,true,function BJS_TimerEnd)
endfunction
//=========================================================
//== End Main Function ==
//=========================================================
//===========================================================================
function InitTrig_BunJee_Shot takes nothing returns nothing
local integer start = 0
local integer end = 15
set gg_trg_BunJee_Shot = CreateTrigger()
loop
exitwhen start>end
call TriggerRegisterPlayerUnitEvent(gg_trg_BunJee_Shot,Player(start),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set start = start + 1
endloop
call TriggerAddCondition(gg_trg_BunJee_Shot, Condition(function BJS_Cond))
call TriggerAddAction(gg_trg_BunJee_Shot, function BJS_Act)
endfunction
endscope
//!<--End of my Spell-->!//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//Thanks to Cohadar for his brilliant ABC system.
//==============================================================================
// ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v5.1
//==============================================================================
//------------------------------------------------------------------------------
// We will use textmacros to create multiple instances of system
//------------------------------------------------------------------------------
//! textmacro ABC takes X, NAME, TYPE
//------------------------------------------------------------------------------
// Global arrays represent our hash tables.
// System is currently using 3 hash tables per handle type. (A, B, C)
//------------------------------------------------------------------------------
globals
private $TYPE$ array $TYPE$Key$X$
private integer array $TYPE$Value$X$
private integer $TYPE$maxCollision$X$ = 0
endglobals
//------------------------------------------------------------------------------
// returns the maximum collision so far
//------------------------------------------------------------------------------
function Get$NAME$Collision$X$ takes nothing returns integer
return $TYPE$maxCollision$X$
endfunction
//------------------------------------------------------------------------------
// initializes hash arrays to prevent lag when ABC is used for the first time
//------------------------------------------------------------------------------
private function Init$NAME$Hash$X$ takes nothing returns nothing
set $TYPE$Key$X$[HASH_INDEX_LIMIT] = null
set $TYPE$Value$X$[HASH_INDEX_LIMIT] = 0
endfunction
//------------------------------------------------------------------------------
// attaches struct to a handle by using hash table
//------------------------------------------------------------------------------
function Set$NAME$Struct$X$ takes $TYPE$ t, integer s returns nothing
debug local integer collision
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
if $TYPE$Key$X$<i> == null then
set $TYPE$Value$X$<i> = s
set $TYPE$Key$X$<i> = t
return
endif
debug if $TYPE$Key$X$<i> == t then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t)))
debug return
debug endif
// if function gets below this line we have a collision
debug set collision = 1
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] overflow")
debug return
debug endif
debug set collision = collision + 1
set i = i + 1
exitwhen $TYPE$Key$X$<i> == null
debug if $TYPE$Key$X$<i> == t then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t)))
debug return
debug endif
endloop
debug if collision > $TYPE$maxCollision$X$ then
debug call BJDebugMsg("|cFFFF4444Warning: Hash[$X$] maximum collision is now: " + I2S(collision))
debug set $TYPE$maxCollision$X$ = collision
debug endif
set $TYPE$Value$X$<i> = s
set $TYPE$Key$X$<i> = t
return
endfunction
//------------------------------------------------------------------------------
// gets stored struct from a handle
//------------------------------------------------------------------------------
function Get$NAME$Struct$X$ takes $TYPE$ t returns integer
debug local integer collision
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
if $TYPE$Key$X$<i> == t then
return $TYPE$Value$X$<i>
endif
// if function gets below this line we have a collision
debug set collision = 1
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : get request on unknown handle")
debug return 0
debug endif
debug set collision = collision + 1
set i = i + 1
exitwhen $TYPE$Key$X$<i> == t
endloop
return $TYPE$Value$X$<i>
endfunction
//------------------------------------------------------------------------------
// clears stored struct from a handle, also returns cleared value
//------------------------------------------------------------------------------
function Clear$NAME$Struct$X$ takes $TYPE$ t returns integer
debug local integer collision
local integer ik
local integer ret
// hash using 32-bit integer overflow
local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
// first find the index on witch key is stored
debug set collision = 0
loop
debug if collision >= HASH_COLLISION_LIMIT then
debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : clear request on unknown handle")
debug return 0
debug endif
debug set collision = collision + 1
exitwhen $TYPE$Key$X$<i> == t
set i = i + 1
endloop
set ik = i
set ret = $TYPE$Value$X$[ik]
// then find last used key index in bucket
loop
set i = i + 1
// we use the fact bucket borders (mod 8 indexes) are always null
exitwhen $TYPE$Key$X$<i> == null
endloop
// shift last bucket entry to the place of removed one
set $TYPE$Key$X$[ik] = $TYPE$Key$X$[i-1]
set $TYPE$Value$X$[ik] = $TYPE$Value$X$[i-1]
// clear the previous last bucket entry
set $TYPE$Key$X$[i-1] = null
return ret
endfunction
//! endtextmacro
//==============================================================================
// Macro execution -- this is where real functions get created
//==============================================================================
library ABC initializer Init
globals
public constant integer HASH_SIZE = 8192
public constant integer HASH_INDEX_LIMIT = 8190
public constant integer HASH_DOWN = 524288 // 2^19
public constant integer HASH_UP = 2134900736 // 2^22 * 509
public constant integer HASH_BIAS = 4096 // HASH_SIZE / 2
public constant integer HASH_COLLISION_LIMIT = 7 // ABC v5.0 had limit 8
// 509 is the prime closest to 512
endglobals
//------------------------------------------------------------------------------
// conversion function used by the system internally
// you will not need to use it directly
//------------------------------------------------------------------------------
public function H2I takes handle h returns integer
return h
return 0
endfunction
//! runtextmacro ABC("A","Timer","timer")
//! runtextmacro ABC("B","Timer","timer")
//! runtextmacro ABC("C","Timer","timer")
//! runtextmacro ABC("A","Trigger","trigger")
//! runtextmacro ABC("B","Trigger","trigger")
//! runtextmacro ABC("C","Trigger","trigger")
//! runtextmacro ABC("A","Dialog","dialog")
//! runtextmacro ABC("B","Dialog","dialog")
//! runtextmacro ABC("C","Dialog","dialog")
private function Init takes nothing returns nothing
call InitTimerHashA()
call InitTimerHashB()
call InitTimerHashC()
call InitTriggerHashA()
call InitTriggerHashB()
call InitTriggerHashC()
call InitDialogHashA()
call InitDialogHashB()
call InitDialogHashC()
endfunction
endlibrary
//==============================================================================
// END OF ABC STRUCT ATTACHMENT SYSTEM
//==============================================================================</i></i></i></i></i></i></i></i></i></i></i></i></i></i>