//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
A_ActiveSpells | integer | No | |
A_AllBirdsGroup | group | No | |
A_AttackedUnits | group | No | |
A_Birds | unit | Yes | |
A_FinalTarget | unit | No | |
A_GeneralInteger | integervar | Yes | |
A_Hero | unit | Yes | |
A_HeroesGroup | group | No | |
A_Level | integer | Yes | |
A_MUIInteger | integer | No | |
A_RadReal | real | No | |
A_TargetGroups | group | Yes | |
A_TempPoint | location | Yes | |
A_TravelingBirds | group | No | |
AnimationSpeedChange | real | No | |
Arthasenter | effect | No | |
BF | integervar | No | |
BF_Angel | real | Yes | |
BF_AOE | real | Yes | |
BF_Damage | real | Yes | |
BF_Distance | real | Yes | |
BF_Distance_Height | real | Yes | |
BF_Fly | real | Yes | |
BF_Formula | real | Yes | |
BF_Group | group | Yes | |
BF_Hero | unit | Yes | |
BF_Max_Height | real | Yes | |
BF_Now | real | Yes | |
BF_Number | integer | Yes | |
BF_Off | boolean | Yes | |
BF_Point | location | Yes | |
BF_Projectile | unit | Yes | |
BF_SpecialEffect | string | Yes | |
BF_Speed | real | Yes | |
BF_Times_All | integer | Yes | |
Blade | location | Yes | |
BladeG | group | No | |
BladeU | group | No | |
CageAnimHoldTimer | timer | Yes | |
CageAnimLock | boolean | Yes | |
caster | unit | No | |
Caster | unit | No | |
CasterLoc | location | No | |
CastingUnit | unit | Yes | |
Chemicalexplosive | unit | No | |
CItemType | itemcode | Yes | |
ConeMaximumDegrees | real | No | |
ConeMinimumDegrees | real | No | |
d | unit | Yes | |
DarkDummyGroup | group | Yes | |
DarkOrigin | unit | Yes | |
Devi | group | No | |
Devi2 | group | No | |
DevinePoint | location | Yes | |
Devourer_caster | unit | Yes | |
Dice | integer | No | |
drainlife_ability_point | location | No | |
Dream_blast | location | No | |
Dream_blast_group | group | No | |
Dwarf | unit | No | |
Dwarf_Grenade | location | Yes | |
EC | integervar | No | |
EC_Anlge | real | Yes | |
EC_Distance | real | Yes | |
EC_Dummy1 | unit | Yes | |
EC_Dummy_Chain | unit | Yes | |
EC_Dummy_Chain2 | unit | Yes | |
EC_Dummy_Chain3 | unit | Yes | |
EC_Dummy_Chain4 | unit | Yes | |
EC_Floating | texttag | Yes | |
EC_Fly | real | Yes | |
EC_Height | real | Yes | |
EC_Max_Distance | real | Yes | |
EC_Off | boolean | Yes | |
EC_Part | integer | Yes | |
EC_Point | location | Yes | |
EC_Power | real | Yes | |
EC_Skip | integer | No | |
EC_Special | effect | Yes | |
EC_Special1 | effect | Yes | |
EC_Special3 | effect | Yes | |
EC_Special4 | effect | Yes | |
EC_Speed | real | Yes | |
EC_String | string | Yes | |
EC_Struggle | real | Yes | |
EC_Target | unit | Yes | |
EC_Times | integer | No | |
EC_Weight | real | Yes | |
EffectsAttachmentPoints | string | Yes | |
EffectsAttachments | string | No | |
EntangelGroup | group | No | |
EntangelP | location | Yes | |
Entangler | group | No | |
Entangling_wave_level | abilcode | No | |
FD_AoE | real | Yes | |
FD_Caster | unit | Yes | |
FD_Damage | real | Yes | |
FD_DegreeInterval | real | Yes | |
FD_Degrees | real | Yes | |
FD_Dummy | unit | Yes | |
FD_Duration | real | Yes | |
FD_Index | integer | Yes | |
FD_Index_maxSize | integer | No | |
FD_Index_Size | integer | No | |
FD_LOOP | integervar | No | |
FD_Offset | real | Yes | |
FD_TempInt | integer | No | |
FD_TempLoc | location | Yes | |
FD_TempLoc3 | location | Yes | |
FF | integervar | No | |
FF_AOE | integer | Yes | |
FF_Boolean | boolean | Yes | |
FF_Damage | group | Yes | |
FF_Damage2 | group | Yes | |
FF_Distance | real | Yes | |
FF_Dummy | unit | Yes | |
FF_FF_Time | integer | Yes | |
FF_FLY | real | Yes | |
FF_Foff | real | Yes | |
FF_Formula | real | Yes | |
FF_Group | group | No | |
FF_Hero | unit | Yes | |
FF_Max_Height | real | Yes | |
FF_Point | location | Yes | |
FF_REAL | real | Yes | |
FF_Skip | integer | Yes | |
FF_Speed | real | Yes | |
FF_Target | location | Yes | |
FF_Times | integer | No | |
Fire_Group | group | No | |
Fire_Trap | unit | No | |
FireBall | unit | Yes | |
FireDummyGroup | group | Yes | |
FireG | group | No | |
FireNot | group | No | |
FirePoint | location | Yes | |
FireTrap_Caster | unit | No | |
Firetrap_Point | location | No | |
Firetrap_Position | location | No | |
forest_monster_bosses | unit | Yes | |
Frag_Grenade_group | group | No | |
FrostDummy | unit | Yes | |
FrostSphere | boolean | Yes | |
Game_Time | real | No | |
Gauntlet_tele | effect | Yes | |
GI_Caster | unit | No | |
GI_Casterpoint | location | No | |
GI_Group | group | No | |
GI_Point | location | No | |
Grenade_explosion | effect | Yes | |
Hammer | unit | Yes | |
heated_bullet | unit | Yes | |
Heated_bullet_point | location | Yes | |
Hero | unit | Yes | |
Hits | integer | No | |
Hole | group | No | |
hsCollide | real | Yes | |
hsDamage | real | Yes | |
hsDart | unit | Yes | |
hsDetect | real | Yes | |
hsIndex | integer | Yes | |
hsSpeedMax | real | Yes | |
hsTarg | unit | Yes | |
hsTargPoint | location | Yes | |
hstPoint | location | Yes | |
hstReal | real | Yes | |
hstUGroup | group | No | |
hsTurn | real | Yes | |
Human_players | force | No | |
i | integer | No | |
IsCastingFrostSphere | boolean | Yes | |
Item | item | No | |
Item_roller | integer | Yes | |
K | integervar | No | |
K_Angle | real | Yes | |
K_Distance | real | Yes | |
K_Formula | real | Yes | |
K_Group | group | No | |
K_Off | boolean | Yes | |
K_Point | location | Yes | |
K_Skip | integer | No | |
K_Spam | integer | Yes | |
K_Speed | real | Yes | |
K_Times | integer | No | |
K_Unit | unit | Yes | |
L | location | No | |
Leaprechaun_spawn | location | Yes | |
lighningdevour | effect | No | |
lightningeffect1 | lightning | No | |
Loop | integer | Yes | |
marked_player | player | Yes | |
Move | group | No | |
MoveFast | group | No | |
MoveSlow | group | No | |
MultiPoint | location | Yes | |
MultiPoint4 | location | Yes | |
MultiPoint5 | location | Yes | |
Orb_Caster | unit | No | |
Orb_Casterpos | location | No | |
Orb_Destination | location | No | |
Orc_players | force | No | |
order | integer | No | |
pb_angle_1 | real | Yes | |
pb_angle_2 | real | Yes | |
pb_caster | unit | Yes | |
pb_caster_loc | location | Yes | |
pb_counter | real | Yes | |
pb_distance_1 | real | Yes | |
pb_distance_2 | real | Yes | |
pb_effect_1 | unit | Yes | |
pb_effect_2 | unit | Yes | |
pb_effect_3 | unit | Yes | |
pb_index1 | integer | No | |
pb_index2 | integer | No | |
pb_index3 | integer | No | |
pb_light_1 | lightning | Yes | |
pb_light_2 | lightning | Yes | |
pb_loopon | boolean | Yes | |
pb_segment_1 | location | Yes | |
pb_segment_2 | location | Yes | |
pb_segment_3 | location | Yes | |
pb_target_loc | location | Yes | |
PE_Chance | integer | No | |
PE_Chance2 | integer | No | |
Peonsacrifice | unit | No | |
Picked | unit | No | |
picked_unit | location | Yes | |
PickedNail | unit | Yes | |
PickGroup | group | No | |
players | player | Yes | |
Plus | integer | No | |
position_of_casterfororcs | location | No | |
Real | real | Yes | |
RealHero4 | real | Yes | |
RockSummon | unit | Yes | |
Rootcraft_Caster | unit | No | |
RootCraft_Group | group | No | |
Rootcraft_Picked | location | No | |
Rootcraft_Point | location | No | |
Rootcraft_Timer | timer | No | |
Seek_Random | unit | No | |
SeekLight_Caster | unit | No | |
SeekLight_Group | group | No | |
SeekLight_Target | unit | No | |
SeekLight_TargetPoint | location | No | |
SeekLight_Timer | timer | No | |
Slash | location | Yes | |
Sludgemonster | unitcode | Yes | |
Special | string | Yes | |
SpecialEffect | effect | Yes | |
Specialeffectworm | effect | Yes | |
SpecialX | effect | Yes | |
SpellTarget | rect | Yes | |
Spider_Caster | unit | No | |
Spider_Point | location | No | |
Spider_Trap | unit | No | |
Spiritdamage_Point | location | No | |
SpiritGroup | group | No | |
Spiritheal_Point | location | No | |
SpiritLoc | location | Yes | |
SpiritMend_Caster | unit | No | |
SpiritMend_Group | group | No | |
SpiritMend_Group2 | group | No | |
SpiritMend_Point | location | No | |
Spirituel | group | No | |
ST_Caster | unit | No | |
ST_Point | location | No | |
Stealth_Timer | timer | No | |
StealthWait_Timer | timer | No | |
summon_effect | effect | Yes | |
Target | group | Yes | |
TargetPoint | location | Yes | |
TempLoc3 | location | No | |
TempLoc4 | location | No | |
TempPoint | location | No | |
TempPoint1 | location | No | |
TempPoint2 | location | No | |
TempPoint3 | location | No | |
ThunderBall | unit | Yes | |
ThunderBallGroup | group | No | |
TimeGroup | group | No | |
TimeHoleP | location | Yes | |
Timeofday | boolean | No | |
TS | integervar | No | |
TS2 | integervar | No | |
TS_Angle | real | Yes | |
TS_Aoe | real | Yes | |
TS_Candy | integervar | Yes | |
TS_Countdown | integer | Yes | |
TS_DEBUG_GROUP | group | No | |
TS_Formula | real | Yes | |
TS_Group | group | Yes | |
TS_Height | real | Yes | |
TS_Hero | unit | Yes | |
TS_Off | boolean | Yes | |
TS_Point | location | Yes | |
TS_Skip | integer | No | |
TS_SPam | integer | Yes | |
TS_Swap | integer | Yes | |
TS_TargetPoint | location | Yes | |
TS_Times | integer | No | |
Twice_Caster | unit | No | |
Twice_Point | location | No | |
Twice_Target | unit | No | |
u | unit | No | |
unit | unit | No | |
UnitGroup | group | Yes | |
Unitgroup_lifedrain | group | No | |
Unitgroup_lifedrain_2 | group | No | |
Weather_Timer | timer | No | |
Weatherinmiddle | weathereffect | No | |
WindDistance | real | Yes | |
Wip | location | Yes | |
Wips | unit | Yes | |
WipUnit | group | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DDItemCombineBasic initializer Init
globals
// *** Edit to your own will ***
private constant string ITEM_COMBINE_EFFECT = "Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl"
private constant string ATTACH_POINT = "origin"
// *** End edit ***
private sound ItemCombineSound = null
private integer array CType[8191]
private integer ItemN = 0
endglobals
function NewItemGroup takes nothing returns nothing
local integer i = ItemN*6 + 7
local integer h = 1
set ItemN = ItemN + 1
loop
exitwhen (h == 7)
set udg_CItemType[i] = udg_CItemType[h]
set udg_CItemType[h] = 0
set h = h + 1
set i = i + 1
endloop
set CType[ItemN-1] = udg_CItemType[0]
set udg_CItemType[0] = 0
endfunction
private function UnitRemoveItemById takes unit whichUnit, integer itemId returns nothing
local integer i = 0
local item it
loop
exitwhen (i >= bj_MAX_INVENTORY)
set it = UnitItemInSlot(whichUnit, i)
if GetItemTypeId(it) == itemId then
call RemoveItem(it)
exitwhen (true)
endif
set i = i + 1
endloop
set it = null
endfunction
private function Actions takes nothing returns nothing
local integer n = 0
local integer array it
local integer i = 7
local integer h = 0
local integer x = 0
local unit u = GetTriggerUnit()
local boolean b = true
local integer y = 0
local integer z = 0
local integer array hero_item_type
// Get hero items
loop
exitwhen (x >= bj_MAX_INVENTORY)
set hero_item_type[x] = GetItemTypeId(UnitItemInSlot(u, x))
set x = x + 1
endloop
loop
exitwhen (n >= ItemN)
set h = i + 6
set x = 0
set it[x] = hero_item_type[x]
set x = x + 1
set it[x] = hero_item_type[x]
set x = x + 1
set it[x] = hero_item_type[x]
set x = x + 1
set it[x] = hero_item_type[x]
set x = x + 1
set it[x] = hero_item_type[x]
set x = x + 1
set it[x] = hero_item_type[x]
set x = x + 1
set y = 0 // N of items that hero has ()
set z = 0 // N of items needed ()
loop
exitwhen (i >= h or udg_CItemType[i] == 0)
set z = z + 1
// Does unit contain item n
set x = 0
loop
exitwhen (x >= bj_MAX_INVENTORY)
if (it[x] == udg_CItemType[i]) then
// Kick out the item
set it[x] = 0
set y = y + 1
// And increase by 1
exitwhen (true)
endif
set x = x + 1
endloop
set i = i + 1
endloop
set i = h
if (y == z) then
set h = i
set i = i-6
loop
exitwhen (i > h or udg_CItemType[i] == 0)
call UnitRemoveItemById(u, udg_CItemType[i])
set i = i + 1
endloop
call UnitAddItemById(u, CType[n])
call SetSoundPosition(ItemCombineSound, GetUnitX(u), GetUnitY(u), 0.)
call StartSound(ItemCombineSound)
call DestroyEffect(AddSpecialEffectTarget(ITEM_COMBINE_EFFECT, u, ATTACH_POINT))
set u = null
return
endif
set n = n + 1
endloop
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction( t, function Actions )
call Preload(ITEM_COMBINE_EFFECT)
set ItemCombineSound = CreateSound( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImage.wav", false, true, true, 10, 10, "" )
call SetSoundParamsFromLabel( ItemCombineSound, "MirrorImage" )
call SetSoundDuration( ItemCombineSound, 1756 )
call SetSoundPitch(ItemCombineSound, 1.2)
call SetSoundVolume(ItemCombineSound, 100)
endfunction
endlibrary
function Trig_Unit_Move_Code_Enum takes nothing returns nothing
local unit u = GetEnumUnit()
call SetUnitPosition(u, GetUnitX(u)+27.0*Cos(GetUnitFacing(u)*0.01745), GetUnitY(u)+27.0*Sin(GetUnitFacing(u)*0.01745))
set u = null
endfunction
function Trig_Unit_Move_Code_Enum_Fast takes nothing returns nothing
local unit u = GetEnumUnit()
call SetUnitPosition(u, GetUnitX(u)+36.0*Cos(GetUnitFacing(u)*0.01745), GetUnitY(u)+36.0*Sin(GetUnitFacing(u)*0.01745))
set u = null
endfunction
function Trig_Unit_Move_Code_Enum_Slow takes nothing returns nothing
local unit u = GetEnumUnit()
call SetUnitPosition(u, GetUnitX(u)+18.0*Cos(GetUnitFacing(u)*0.01745), GetUnitY(u)+18.0*Sin(GetUnitFacing(u)*0.01745))
set u = null
endfunction
function Trig_Unit_Move_Code_Actions takes nothing returns nothing
call ForGroup(udg_Move, function Trig_Unit_Move_Code_Enum)
call ForGroup(udg_MoveFast, function Trig_Unit_Move_Code_Enum_Fast)
call ForGroup(udg_MoveSlow, function Trig_Unit_Move_Code_Enum_Slow)
endfunction
//===========================================================================
function InitTrig_Unit_Move_Code takes nothing returns nothing
set gg_trg_Unit_Move_Code = CreateTrigger()
call TriggerAddAction(gg_trg_Unit_Move_Code, function Trig_Unit_Move_Code_Actions)
call TriggerRegisterTimerEvent(gg_trg_Unit_Move_Code, 0.03, true)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Haunt initializer init
//===================================================================================
//= Haunt by Ciebron v1.2
//=
//= Requires: -The Custom Model in the Import list
//=
//=
//= Description: Shoots a projectile towards target unit it will deal Damage to him
//= and then return to the caster and heal him for % of the damage
//=
//= Extra: This spell needs the imported model 'dummy.mdx'. else you wont be able to
//= attach a SFX to the dummy
//===================================================================================
globals
//The RawCode of the spell
private constant integer Abil_id = 'A040'
//The RawCode of the dummy
private constant integer Dummy_id = 'h01J'
//NOTE: only change this if u have changed the crow from ability in the editor
private constant integer Fly_id = 'Amrf'
//The SFX that will apear when the projectile hits the Target
private constant string HitSFX = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
//The SFX that will apear when the projectile hits the Caster
private constant string HealSFX = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
//The SFX that will attach too the projectile when it travels to the target
private constant string Projectile1 = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
//The SFX that will attach too the projectile when it travels back to the caster
private constant string Projectile2 = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
//Where the SFX will get attached to the projectile
private constant string AttachPoint = "origin"
//Where the SFX will attach when the projectile hits the target/caster
private constant string AttachTargetPoint = "origin"
// Defines how fast the projectile will move
private constant real Move_Speed = 20.
//How much the caster will be healed of the procentage. eg. 1. is 100% of the dmg, 0.75 is 75% of the damage.
private constant real Heal_Amount = 1
//The Dummy's Fly Height (set it to what ever that fit's your SFX)
private constant real Dummy_Height = 75.
//The Attacktype of the spell
//Usefull information about damage types. http://www.wc3campaigns.net/showpost.php?p=1030046&postcount=19
private constant attacktype AtkType = ATTACK_TYPE_MAGIC
//The Damagetype of the spell
private constant damagetype DmgType = DAMAGE_TYPE_MAGIC
//The Weapontype of the spell (sound)
private constant weapontype WepType = null
//Timer Intervals
private constant real Interval = 0.03
endglobals
//This function is for setting the spells damage
private constant function Damage takes integer Level returns real
return 100.+(Level*100)
endfunction
//===========================================================================================
globals
private constant real Projectile_Size = Move_Speed * 2 + 1
endglobals
private struct Data
unit Caster
unit Target
unit Dummy
real Damage
real z
player Play
effect SFX
static integer array Ar
static integer Total = 0
static timer Time = CreateTimer()
static real x
static real y
static real tx
static real ty
static real x2
static real y2
static real angle
static real nH
method NewHeight takes real h returns real // A method used for setting the missile's height
set .nH = (h-.z) / ( SquareRoot((.tx-.x)*(.tx-.x)+(.ty - .y)*(.ty-.y)) / Move_Speed * Interval ) //DSG - Works out rate of change needed by working out the change in height and the time to reach target.
if .nH < 0 then //DSG - If rate of change of height is - it will not work so this inverts it to be positive.
set .nH = -.nH
endif
call SetUnitFlyHeight(.Dummy, h+Dummy_Height, .nH ) // Setting the missiles new height at a calculated rate
return h
endmethod
static method create takes unit u,unit t returns Data
local Data Dat = Data.allocate()
local real Height = GetUnitFlyHeight(t)
set Dat.Caster = u
set Dat.Target = t
set Dat.x = GetUnitX(Dat.Caster)
set Dat.y = GetUnitY(Dat.Caster)
set Dat.tx = GetUnitX(Dat.Target)
set Dat.ty = GetUnitY(Dat.Target)
set Dat.angle = Atan2(Dat.ty-Dat.y,Dat.tx-Dat.x)
set Dat.Play = GetOwningPlayer(Dat.Caster)
set Dat.Dummy = CreateUnit(Dat.Play,Dummy_id,Dat.x+50*Cos(Dat.angle),Dat.y+50*Sin(Dat.angle),(Dat.angle*57.29582))
set Dat.Damage = Damage(GetUnitAbilityLevel(Dat.Caster,Abil_id))
set Dat.SFX = AddSpecialEffectTarget(Projectile1,Dat.Dummy,AttachPoint)
set Dat.z = Dummy_Height
call UnitAddAbility(Dat.Dummy, Fly_id)
call SetUnitFlyHeight(Dat.Dummy,Dummy_Height,0.)
call UnitRemoveAbility(Dat.Dummy, Fly_id)
if Height > 0. then
set Dat.z = Dat.NewHeight(Height)
endif
if Dat.Total == 0 then
call TimerStart(Dat.Time, Interval, true, function Data.Loop)
endif
set Dat.Ar[Dat.Total] = Dat
set Dat.Total = Dat.Total + 1
set u = null
set t = null
return Dat
endmethod
static method Loop takes nothing returns nothing
local Data Dat
local integer i = 0
loop
exitwhen i >= Dat.Total
set Dat = Dat.Ar[i]
set Dat.x = GetUnitX(Dat.Dummy)
set Dat.y = GetUnitY(Dat.Dummy)
set Dat.tx = GetUnitX(Dat.Target)
set Dat.ty = GetUnitY(Dat.Target)
set Dat.x2 = Dat.tx-Dat.x
set Dat.y2 = Dat.ty-Dat.y
if SquareRoot(Dat.x2 * Dat.x2 + Dat.y2 * Dat.y2) <= Projectile_Size then
if Dat.Target != Dat.Caster then
call DestroyEffect(AddSpecialEffectTarget(HitSFX,Dat.Target,AttachTargetPoint))
call DestroyEffect(Dat.SFX)
call KillUnit(Dat.Dummy)
if not IsUnitType(Dat.Target,UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(Dat.Target) > .305 then
call UnitDamageTarget(Dat.Caster,Dat.Target,Dat.Damage,false,false,AtkType,DmgType,WepType)
set Dat.Target = Dat.Caster
set Dat.x = GetUnitX(Dat.Target)
set Dat.y = GetUnitY(Dat.Target)
set Dat.angle = Atan2(Dat.y-Dat.ty,Dat.x-Dat.tx)
//! Yes i could reuse the old dummy but cause it will look wierd i create a new one
set Dat.Dummy = CreateUnit(Dat.Play,Dummy_id,Dat.tx+50*Cos(Dat.angle),Dat.ty+50*Sin(Dat.angle),Dat.angle*57.29582)
//! New dummy new "fly hack"
call UnitAddAbility(Dat.Dummy, Fly_id)
call SetUnitFlyHeight(Dat.Dummy, Dat.z,0. )
call UnitRemoveAbility(Dat.Dummy, Fly_id)
//! Make so it will fly down to the caster again smoothly
call Dat.NewHeight(GetUnitFlyHeight(Dat.Target))
set Dat.SFX = AddSpecialEffectTarget(Projectile2,Dat.Dummy,AttachPoint)
else
set Dat.Total = Dat.Total - 1
set Dat.Ar[i] = Dat.Ar[Dat.Total]
set i = i - 1
call Dat.destroy()
endif
else
call SetWidgetLife(Dat.Caster,GetWidgetLife(Dat.Caster)+(Dat.Damage*Heal_Amount))
call DestroyEffect(AddSpecialEffectTarget(HealSFX,Dat.Caster,AttachTargetPoint))
call KillUnit(Dat.Dummy)
call DestroyEffect(Dat.SFX)
set Dat.Total = Dat.Total - 1
set Dat.Ar[i] = Dat.Ar[Dat.Total]
set i = i - 1
call Dat.destroy()
endif
else
set Dat.angle = Atan2(Dat.ty-Dat.y,Dat.tx-Dat.x)
call SetUnitX(Dat.Dummy,Dat.x+Move_Speed*Cos(Dat.angle))
call SetUnitY(Dat.Dummy,Dat.y+Move_Speed*Sin(Dat.angle))
call SetUnitFacing(Dat.Dummy,(Dat.angle*57.29582))
endif
set i = i + 1
endloop
if Dat.Total == 0 then
call PauseTimer(Dat.Time)
endif
endmethod
method onDestroy takes nothing returns nothing
set .Caster = null
set .Target = null
set .Play = null
set .Dummy = null
set .SFX = null
endmethod
endstruct
private function OnCast takes nothing returns boolean
local Data Dat
local unit u
local unit t
if GetSpellAbilityId()==Abil_id then
set u = GetTriggerUnit()
set t = GetSpellTargetUnit()
set Dat = Data.create(u,t)
set u = null
set t = null
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Filter(function OnCast))
call Preload(HitSFX)
call Preload(HealSFX)
call Preload(Projectile1)
call Preload(Projectile2)
set trig = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DroneSystem initializer init
// nothing to customize!!
//just copy and paste this trigger into your map
globals
private integer total = 0
private integer array DATAS
private timer tim = CreateTimer()
private group g = CreateGroup()
endglobals
private struct data
unit u
unit t
real d
real r
endstruct
private function Execute takes nothing returns nothing
local integer i = 0
local real x
local real y
local data dat
local real f
loop
exitwhen i >= total
set dat = DATAS[i]
set f = GetUnitFacing(dat.u)
set x = GetUnitX(dat.u) + dat.d * Cos((f+dat.r) * bj_DEGTORAD)
set y = GetUnitY(dat.u) + dat.d * Sin((f+dat.r) * bj_DEGTORAD)
call SetUnitX(dat.t,x)
call SetUnitY(dat.t,y)
if GetUnitCurrentOrder(dat.t) == OrderId("move") then
call IssueImmediateOrder(dat.t,"stop")
endif
set i = i + 1
endloop
endfunction
function AddDrone takes unit source, integer drone, real distance, real angle, boolean attackable returns unit
local data dat = data.create()
local real x = GetUnitX(source) + distance * Cos((GetUnitFacing(source)+angle) * bj_DEGTORAD)
local real y = GetUnitY(source) + distance * Sin((GetUnitFacing(source)+angle) * bj_DEGTORAD)
set dat.u = source
set dat.t = CreateUnit(GetOwningPlayer(source),drone,x,y,GetUnitFacing(dat.u))
set dat.r = angle
set dat.d = distance
call SetUnitPathing(dat.t,false)
call SetUnitInvulnerable(dat.t, not attackable)
call SetUnitUserData(dat.t,total)
call GroupAddUnit(g,dat.t)
set DATAS[total] = dat
set total = total + 1
if total == 1 then
call TimerStart(tim,0.01,true,function Execute)
endif
return dat.t
endfunction
function RemoveDrone takes unit drone returns nothing
local integer i = GetUnitUserData(drone)
local data dat = DATAS[i]
set total = total - 1
set DATAS[i] = DATAS[total]
call RemoveUnit(dat.t)
call GroupRemoveUnit(g,dat.t)
call dat.destroy()
endfunction
private function remove takes nothing returns boolean
if IsUnitInGroup(GetTriggerUnit(),g) then
call RemoveDrone(GetTriggerUnit())
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddCondition(t,Condition(function remove))
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//=========================================================================//
// //
// How to import: //
// //
// - First you must import each script, by either making a trigger //
// and converting it to custom script then pasting the text, //
// or completely copying the above script. //
// - Then you must copy over all the abilities needed for each //
// spell. //
// - Then you must change the raw codes to the new ones in your map. //
// Copying the ability and changing the code one at a time may be //
// easier. //
// - You must then import both the Dirt.mdx and SlideWater.mdx files //
// into your map and save them under the those those names. Only do //
// this if you are going to use Stone Guardians or Earth Prison. //
// - If you are going to use Stone Skin or Earth Prison import the //
// SandWaveDamage.mdx file into your map, or use another effect. // //
// - Change the configurables section to your liking and then test. //
// //
//=========================================================================//
//TESH.scrollpos=0
//TESH.alwaysfold=0
//=========================================================================//
// //
// Credits: //
// //
// - JetFangInferno - For the SandWaveDamage.mdx model. //
// - Vile - For the Dirt.mdx and SlideWater.mdx models (i think). //
// - Emjlr3 - For his help with Stone Guardians. //
// - WILLTHEALMIGHTY - For his NewDirtEXNofire.mdx model. //
// //
//=========================================================================//
//TESH.scrollpos=3
//TESH.alwaysfold=0
scope SeismicSlam initializer Init
globals
// Configurables:
// Skills:
private constant integer Abil_id = 'A049'
// Raw code of the main hero ability.
private constant integer Abil2_id = 'A047'
// Raw code of the stomp used at the end.
private constant integer Flytrick = 'Amrf'
// Raw code for "Crow Form". Does not need to be changed in most cases.
// Units:
private constant integer Dummy_id = 'h01Z'
// Raw code of the dummy "spinning" unit used for the leap.
private constant integer Treedummy_id = 'u007'
// Raw code of the dummy unit used to destroy trees.
// Others:
private constant real Interval = 0.04 // Interval for periodic timer.
private constant real Diff = 0.00 // Distance from cast point that the unit will land.
private constant real Timescale = 3.00 // How fast the unit spins.
private constant string End_anim = "spell slam"
// End animation of the unit.
private constant string Dirt_sfx = "dust.mdx"
// Effect made at the end of the spell on land.
private constant string Water_sfx = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
// Same as above but for landing on water.
private constant boolean Destroytrees = true
// Whether or not to destroy trees.
private constant boolean AllowPreload = true
// Whether or not to allow preloading of the effects.
endglobals
//=======================================================================
private function Area takes integer lvl returns real
return 225.00 // Area of effect for destroying trees.
endfunction
private function Airtime takes integer lvl returns real
return 1.45-(0.15*lvl) // Air time of the leap.
endfunction
//=======================================================================//
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! //
//=======================================================================//
private keyword Data
globals
private integer Total = 0
private Data array D
private timer Timer = null
private rect Rect1 = null
private boolexpr Treefilt = null
private boolexpr Truefilt = null
private unit Treedummy = null
private real Game_maxX = 0.00
private real Game_minX = 0.00
private real Game_maxY = 0.00
private real Game_minY = 0.00
endglobals
//=======================================================================
private function KillEnumDestructables takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function TreeCheck takes nothing returns boolean
local destructable dest = GetFilterDestructable()
local boolean result
if GetDestructableLife(dest) > 0.405 then
call ShowUnit(Treedummy,true)
call SetUnitX(Treedummy,GetWidgetX(dest))
call SetUnitY(Treedummy,GetWidgetY(dest))
set result = IssueTargetOrder(Treedummy,"harvest",dest)
call IssueImmediateOrder(Treedummy,"stop")
call ShowUnit(Treedummy,false)
return result
endif
set dest = null
return false
endfunction
//=======================================================================
private function SafeX takes real x returns real
if x<Game_minX then
return Game_minX
elseif x>Game_maxX then
return Game_maxX
endif
return x
endfunction
private function SafeY takes real y returns real
if y<Game_minY then
return Game_minY
elseif y>Game_maxY then
return Game_maxY
endif
return y
endfunction
//=======================================================================
private function MoveDist takes real Maxdist, integer lvl returns real
return Maxdist/(Airtime(lvl)/Interval)
endfunction
private function ConvertCount takes integer i, integer lvl returns real
return (50.00/(Airtime(lvl)/Interval))*i
endfunction
//=======================================================================
private struct Data
unit cast
unit dum
real castx
real casty
real cos
real sin
real maxdist
real movedist
integer i = 1
integer lvl
static method create takes nothing returns Data
local Data d = Data.allocate()
local location loc
local real angle
local real targx
local real targy
set d.cast = GetTriggerUnit()
set d.castx = GetUnitX(d.cast)
set d.casty = GetUnitY(d.cast)
set loc = GetSpellTargetLoc()
set angle = Atan2((GetLocationY(loc)-d.casty),(GetLocationX(loc)-d.castx))
set d.cos = Cos(angle)
set d.sin = Sin(angle)
set targx = GetLocationX(loc)-Diff*d.cos
set targy = GetLocationY(loc)-Diff*d.sin
set d.lvl = GetUnitAbilityLevel(d.cast,Abil_id)
set d.maxdist = SquareRoot((targx-d.castx)*(targx-d.castx)+(targy-d.casty)*(targy-d.casty))
set d.movedist = MoveDist(d.maxdist,d.lvl)
set d.dum = CreateUnit(GetOwningPlayer(d.cast),Dummy_id,d.castx,d.casty,angle*bj_RADTODEG)
call UnitAddAbility(d.dum,Flytrick)
call UnitRemoveAbility(d.dum,Flytrick)
call SetUnitTimeScale(d.dum,Timescale)
call SetUnitPathing(d.dum,false)
call PauseUnit(d.dum,true)
call ShowUnit(d.cast,false)
set Total = Total + 1
if Total == 1 then
call TimerStart(Timer,Interval,true,function Data.Update)
endif
set D[Total] = d
call RemoveLocation(loc)
set loc = null
return d
endmethod
static method Update takes nothing returns nothing
local integer i = 1
local real count
local real height
local real speed
local real newx
local real newy
loop
exitwhen i > Total
if D[i].i < (Airtime(D[i].lvl) / Interval) then
set count = ConvertCount(D[i].i,D[i].lvl)
set height = (count-25.00) * (count-25.00)
set speed = D[i].i * D[i].movedist
set newx = D[i].castx + speed * D[i].cos
set newy = D[i].casty + speed * D[i].sin
call SetUnitPosition(D[i].dum,SafeX(newx),SafeY(newy))
call SetUnitPosition(D[i].cast,SafeX(newx),SafeY(newy))
call SetUnitFlyHeight(D[i].dum,625.00-height,0.00)
call SetUnitFlyHeight(D[i].cast,625.00-height,0.00)
set D[i].i = D[i].i + 1
else
call D[i].destroy()
set D[i] = D[Total]
set Total = Total - 1
set i = i - 1
endif
set i = i + 1
endloop
if Total <= 0 then
call PauseTimer(Timer)
set Total = 0
endif
endmethod
private method onDestroy takes nothing returns nothing
local real newx = GetUnitX(.dum) + Diff * .cos
local real newy = GetUnitY(.dum) + Diff * .sin
local unit u = CreateUnit(GetOwningPlayer(.cast),Treedummy_id,newx,newy,0.00)
call SetUnitFlyHeight(.dum,GetUnitDefaultFlyHeight(.cast),0.00)
call PauseUnit(.dum,false)
call SetUnitPathing(.dum,true)
if Destroytrees then
call SetRect(Rect1,newx-Area(.lvl),newy-Area(.lvl),newx+Area(.lvl),newy+Area(.lvl))
call EnumDestructablesInRect(Rect1,Treefilt,function KillEnumDestructables)
endif
call UnitAddAbility(u,Abil2_id)
call SetUnitAbilityLevel(u,Abil2_id,.lvl)
call IssueImmediateOrder(u,"stomp")
call UnitApplyTimedLife(u,'BTLF',1.00)
if IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_FLOATABILITY) then
call DestroyEffect(AddSpecialEffect(Dirt_sfx,newx,newy))
elseif not IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_WALKABILITY) then
call DestroyEffect(AddSpecialEffect(Water_sfx,newx,newy))
endif
call RemoveUnit(.dum)
call SetUnitPosition(.cast,newx,newy)
call ShowUnit(.cast,true)
call SetUnitAnimation(.cast,End_anim)
if GetLocalPlayer() == GetOwningPlayer(.cast) then
call ClearSelection()
call SelectUnit(.cast,true)
endif
set .cast = null
set .dum = null
set u = null
endmethod
endstruct
//=======================================================================
private function Actions takes nothing returns nothing
call Data.create()
endfunction
//=======================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == Abil_id
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
set Timer = CreateTimer()
set Rect1 = Rect(0.00,0.00,1.00,1.00)
set Treefilt = Filter(function TreeCheck)
set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-64.00
set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-64.00
set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+64.00
set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+64.00
set Truefilt = Filter(function TrueFilt)
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function Conditions))
call TriggerAddAction(trig,function Actions)
set Treedummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Treedummy_id,0.00,0.00,0.00)
call SetUnitPathing(Treedummy,false)
call ShowUnit(Treedummy,false)
if AllowPreload then
call KillUnit(CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00))
call DestroyEffect(AddSpecialEffect(Dirt_sfx,0.00,0.00))
call DestroyEffect(AddSpecialEffect(Water_sfx,0.00,0.00))
endif
endfunction
endscope
//TESH.scrollpos=21
//TESH.alwaysfold=0
scope StoneGuardians initializer Init
globals
// Configurables:
// Skills:
private constant integer Abil_id = 'A04A'
// Raw code for the main hero ability.
private constant integer Abil2_id = 'A01P'
// Raw code for the Stone Skin hero ability.
private constant integer Abil3_id = 'A046'
// Raw code for the SG Armour Bonus ability.
// Units:
private constant integer Dummy_id = 'u006'
// Raw code for the stone guardian dummy unit.
// Others:
private constant real Interval = 0.04 // Interval for periodic timer.
private constant real Height = 30.00 // height of the stones.
private constant real Collision = 60.00 // How close a unit must be to get hit by a stone.
private constant real Distance = 150.00 // Distance from the target at which units are created.
private constant string Start_sfx = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
// Special effect used when the stones are created.
private constant string Dirt_sfx = "Dust.mdx"
// Special effect used for when units are knocked back.
private constant string Water_sfx = "SlideWater.mdx"
// Same as above but for when units are on water.
private constant string Point = "origin"
// Attachment point for Dirt_sfx and Water_sfx.
private constant boolean Allowmove = false
// Whether or not units are allowed to move while being knocked back.
private constant boolean AllowPreload = false
// Whether or not to allow preloading of the effects.
// Attack/Damage/Weapon types of damage dealt.
private constant attacktype A_type = ATTACK_TYPE_CHAOS
private constant damagetype D_type = DAMAGE_TYPE_UNIVERSAL
private constant weapontype W_type = WEAPON_TYPE_WHOKNOWS
endglobals
//=======================================================================
private function MaxDuration takes integer lvl returns real
return 12.00 // Duration of the stone guardians.
endfunction
private function KnockDuration takes integer lvl returns real
return 1.00 // Knockback duration.
endfunction
private function KnockDistance takes integer lvl returns real
return 100.00+(25.00*lvl) // Knockback distance.
endfunction
private function StoneNumber takes integer lvl returns integer
return 1+(1*lvl) // Number of stones per level. Try to keep it under 9 if you dont know how to change it.
endfunction
private function Damage takes integer lvl returns real
return 35.00+(10.00*lvl) // Damage dealt when stones hit units.
endfunction
private function Speed takes integer lvl returns real
return 325.00-(25.00*lvl) // The speed at which the stones rotate around the target.
endfunction
//=======================================================================//
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! //
//=======================================================================//
private keyword Data
private keyword Knock
globals
private boolexpr Enemyfilt
private boolexpr Truefilt
private timer Timer = null
private integer DT = 0
private integer KT = 0
private Data array D
private Knock array K
private real Game_maxX = 0.00
private real Game_minX = 0.00
private real Game_maxY = 0.00
private real Game_minY = 0.00
endglobals
//=======================================================================
private function IsPointOutside takes real x, real y returns boolean
return (x > Game_maxX or y > Game_maxY or x < Game_minX or y < Game_minY)
endfunction
private function TerrainType takes unit u returns integer
local real x = GetUnitX(u)
local real y = GetUnitY(u)
if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
return 1
elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
return 2
endif
return 0
endfunction
//=======================================================================
private struct Data
unit cast
unit targ
unit array stone[10]
integer stones = 0
integer alive = 0
integer dead = 0
integer lvl = 0
real time = 0.00
real speed = 0.00
real array ang[10]
group g = CreateGroup()
private method onDestroy takes nothing returns nothing
local integer i = 1
loop
exitwhen i > .stones
if GetWidgetLife(.stone[i]) > 0.405 then
call KillUnit(.stone[i])
set .stone[i] = null
endif
set i = i + 1
endloop
if GetUnitAbilityLevel(.targ,Abil3_id) > 0 then
call UnitRemoveAbility(.targ,Abil3_id)
endif
set .cast = null
call GroupClear(.g)
call DestroyGroup(.g)
endmethod
endstruct
//=======================================================================
private struct Knock
unit targ
real speed = 0.00
real decrease = 0.00
real cos = 0.00
real sin = 0.00
effect sfx
integer sfxmode
private method onDestroy takes nothing returns nothing
set .targ = null
if .sfx != null then
call DestroyEffect(.sfx)
set .sfx = null
endif
endmethod
endstruct
//=======================================================================
private function FilterEnemies takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false
endfunction
//=======================================================================
private function Update takes nothing returns nothing
local integer h = 1
local integer i = 1
local integer j = 1
local Knock k = 0
local integer newmode
local real targx
local real targy
local real newx
local real newy
local real dist
local real ang
local real diff
local unit u
loop
exitwhen i > DT
if D[i].time > MaxDuration(D[i].lvl) or D[i].dead == D[i].stones or GetWidgetLife(D[i].targ) < 0.405 then
call D[i].destroy()
set D[i] = D[DT]
set DT = DT - 1
set i = i - 1
else
set targx = GetUnitX(D[i].targ)
set targy = GetUnitY(D[i].targ)
if GetUnitAbilityLevel(D[i].targ,Abil3_id) > 0 then
call SetUnitAbilityLevel(D[i].targ,Abil3_id,D[i].alive)
elseif GetUnitAbilityLevel(D[i].targ,Abil3_id) == 0 and GetUnitAbilityLevel(D[i].cast,Abil2_id) > 0 then
call UnitAddAbility(D[i].targ,Abil3_id)
call SetUnitAbilityLevel(D[i].targ,Abil3_id,D[i].alive)
endif
loop
exitwhen j > D[i].stones
if GetWidgetLife(D[i].stone[j]) > 0.405 then
call SetUnitX(D[i].stone[j],targx + Distance * Cos(D[i].ang[j]*bj_DEGTORAD))
call SetUnitY(D[i].stone[j],targy + Distance * Sin(D[i].ang[j]*bj_DEGTORAD))
call SetUnitFlyHeight(D[i].stone[j],GetUnitFlyHeight(D[i].targ)+Height,0.00)
set D[i].ang[j] = D[i].ang[j] + D[i].speed
call GroupEnumUnitsInRange(D[i].g,GetUnitX(D[i].stone[j]),GetUnitY(D[i].stone[j]),Collision,Enemyfilt)
loop
set u = FirstOfGroup(D[i].g)
exitwhen u == null
call GroupRemoveUnit(D[i].g,u)
if IsUnitEnemy(u,GetOwningPlayer(D[i].cast)) and (GetUnitFlyHeight(u) >= (GetUnitFlyHeight(D[i].stone[j])-(Height*2.00)) and GetUnitFlyHeight(u) <= (GetUnitFlyHeight(D[i].stone[j])+(Height*2.00))) then
call UnitDamageTarget(D[i].cast,u,Damage(D[i].lvl),false,false,A_type,D_type,W_type)
set k = Knock.create()
set k.targ = u
set ang = Atan2(GetUnitY(k.targ)-GetUnitY(D[i].stone[j]),GetUnitX(k.targ)-GetUnitX(D[i].stone[j]))
set k.speed = (2.00*KnockDistance(D[i].lvl)) / (KnockDuration(D[i].lvl)/Interval)
set k.decrease = k.speed / (KnockDuration(D[i].lvl)/Interval)
set k.sfxmode = TerrainType(k.targ)
if k.sfxmode == 1 then
set k.sfx = AddSpecialEffectTarget(Dirt_sfx,k.targ,Point)
elseif k.sfxmode == 2 then
set k.sfx = AddSpecialEffectTarget(Water_sfx,k.targ,Point)
endif
set k.cos = Cos(ang)
set k.sin = Sin(ang)
set KT = KT + 1
set K[KT] = k
call KillUnit(D[i].stone[j])
set D[i].dead = D[i].dead + 1
set D[i].alive = D[i].alive - 1
set u = null
endif
endloop
endif
set j = j + 1
endloop
set j = 1
// Thanks to emjlr3 for his help with this. Below is basically his idea.
loop
exitwhen j > D[i].stones
if GetWidgetLife(D[i].stone[j]) > 0.405 then
if j != D[i].stones and D[i].alive != 1 then
set h = j + 1
loop
exitwhen h == j or GetWidgetLife(D[i].stone[h]) > 0.405
if h > D[i].stones then
set h = 1
else
set h = h + 1
endif
endloop
if h != j then
if h > j then
set diff = D[i].ang[h] - D[i].ang[j]
else
set diff = D[i].ang[j] - D[i].ang[h]
endif
if diff > (360.00 / D[i].alive) then
set D[i].ang[j] = D[i].ang[j] + 1.00
elseif diff < (360.00 / D[i].alive) then
set D[i].ang[j] = D[i].ang[j] - 1.00
endif
endif
endif
endif
set j = j + 1
endloop
set D[i].time = D[i].time + Interval
set j = 1
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > KT
set newmode = K[i].sfxmode
set newx = GetUnitX(K[i].targ)
set newy = GetUnitY(K[i].targ)
set K[i].sfxmode = TerrainType(K[i].targ)
if K[i].sfxmode == 1 and newmode == 2 then
call DestroyEffect(K[i].sfx)
set K[i].sfx = AddSpecialEffectTarget(Dirt_sfx,K[i].targ,Point)
elseif K[i].sfxmode == 2 and newmode == 1 then
call DestroyEffect(K[i].sfx)
set K[i].sfx = AddSpecialEffectTarget(Water_sfx,K[i].targ,Point)
endif
if K[i].speed <= 0.00 or IsPointOutside(newx,newy) or GetWidgetLife(K[i].targ) < 0.405 then
call K[i].destroy()
set K[i] = K[KT]
set KT = KT - 1
set i = i - 1
else
set newx = newx + K[i].speed * K[i].cos
set newy = newy + K[i].speed * K[i].sin
if Allowmove then
call SetUnitX(K[i].targ,newx)
call SetUnitY(K[i].targ,newy)
else
call SetUnitPosition(K[i].targ,newx,newy)
endif
set K[i].speed = K[i].speed - K[i].decrease
endif
set i = i + 1
endloop
if DT <= 0 and KT <= 0 then
call PauseTimer(Timer)
set DT = 0
set KT = 0
endif
endfunction
//=======================================================================
private function Actions takes nothing returns nothing
local Data d = Data.create()
local integer i = 1
local real targx
local real targy
local real newx
local real newy
local real ang
set d.cast = GetTriggerUnit()
set d.targ = GetSpellTargetUnit()
set targx = GetUnitX(d.targ)
set targy = GetUnitY(d.targ)
set d.lvl = GetUnitAbilityLevel(d.cast,Abil_id)
set d.speed = Speed(d.lvl) / (1.00/Interval)
set d.stones = StoneNumber(d.lvl)
set d.alive = d.stones
set ang = 360.00 / d.stones
loop
exitwhen i > d.stones
set newx = targx + Distance * Cos((ang*i)*bj_DEGTORAD)
set newy = targy + Distance * Sin((ang*i)*bj_DEGTORAD)
set d.stone[i]= CreateUnit(GetOwningPlayer(d.cast),Dummy_id,newx,newy,0.00)
call DestroyEffect(AddSpecialEffect(Start_sfx,newx,newy))
call SetUnitFlyHeight(d.stone[i],GetUnitFlyHeight(d.targ)+Height,0.00)
set d.ang[i] = ang * i
set i = i + 1
endloop
if GetUnitAbilityLevel(d.cast,Abil2_id) > 0 then
call UnitAddAbility(d.targ,Abil3_id)
call SetUnitAbilityLevel(d.targ,Abil3_id,d.stones)
endif
set DT = DT + 1
if DT == 1 and KT == 0 then
call TimerStart(Timer,Interval,true,function Update)
endif
set D[DT] = d
endfunction
//=======================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == Abil_id
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
local unit dum = null
set Timer = CreateTimer()
set Enemyfilt = Filter(function FilterEnemies)
set Truefilt = Filter(function TrueFilt)
set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-64.00
set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-64.00
set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+64.00
set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+64.00
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function Conditions))
call TriggerAddAction(trig,function Actions)
if AllowPreload then
set dum = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00)
call UnitAddAbility(dum,Abil3_id)
call KillUnit(dum)
call DestroyEffect(AddSpecialEffect(Start_sfx,0.00,0.00))
endif
set dum = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope StoneSkin initializer Init
globals
// Configurables:
// Skills:
private constant integer Abil_id = 'A04C'
// Raw code of the main hero ability.
private constant integer Abil2_id = 'A048'
// Raw code of the mini-stun unit ability.
private constant integer Dummy_id = 'h01J'
// Raw code of the dummy unit that casts war stomp.
private constant real MinDamage = 20.00
// Minimum damage that can trigger the spell.
private constant real MinHp = 500
// If the hero is under this hp, the spell will not trigger.
private constant string Absorb_sfx = "SandWaveDamage.mdx"
// Special effect created on the hero when triggered.
private constant string Absorb_point = "origin"
// Attachment point of the above effect.
private constant string DamageDirt_sfx = "SandWaveDamage.mdx"
// Special effect created on each damaged unit when they are on land.
private constant string DamageWater_sfx = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl"
// Same as above but for when units are on shallow water.
private constant string Damage_point = "origin"
// Attachment point of the above effects.
private constant boolean AllowPreload = true
// Whether or not to allow preloading of the effects.
// Attack/Damage/Weapon types of damage dealt.
private constant attacktype A_type = ATTACK_TYPE_CHAOS
private constant damagetype D_type = DAMAGE_TYPE_UNIVERSAL
private constant weapontype W_type = WEAPON_TYPE_WHOKNOWS
// Do not touch these.
private boolexpr Truefilt = null
private boolexpr Enemyfilt = null
private group Group = null
private unit Dummy = null
endglobals
//=======================================================================
private function Radius takes integer lvl returns real
return 150.00+(50.00*lvl) // Area of effect in which units are damaged.
endfunction
private function AbsorbPercent takes integer lvl returns real
return 0.15+(0.15*lvl) // Percentage of damage absorbed.
endfunction
private function DamagePercent takes integer lvl returns real
return 0.60+(0.10*lvl) // Percentage of absorbed damage dealt to units.
endfunction
private function DamageCap takes integer lvl returns real
return 50.00+(25.00*lvl) // Damage cap of above damage.
endfunction
//=======================================================================//
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! //
//=======================================================================//
private function Chance takes unit u returns real
return (GetUnitState(u,UNIT_STATE_LIFE) / GetUnitState(u,UNIT_STATE_MAX_LIFE)) / 2.00
endfunction
private function EnemyFilt takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) == false
endfunction
//=======================================================================
private function Update takes nothing returns boolean
local unit cast = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(cast,Abil_id)
local real dam = GetEventDamage()*AbsorbPercent(lvl)
local unit u = null
if dam > MinDamage and GetWidgetLife(cast) > MinHp then
if GetRandomReal(0.00,1.00) <= Chance(cast) then
call SetUnitAnimation(cast,"spell slam")
call SetWidgetLife(cast,GetWidgetLife(cast)+dam)
call DestroyEffect(AddSpecialEffectTarget(Absorb_sfx,cast,Absorb_point))
set dam = dam*DamagePercent(lvl)
if dam > DamageCap(lvl) then
set dam = DamageCap(lvl)
endif
set Dummy = CreateUnit(GetOwningPlayer(cast),Dummy_id,GetUnitX(cast),GetUnitY(cast),0.00)
call UnitAddAbility(Dummy,Abil2_id)
call SetUnitAbilityLevel(Dummy,Abil2_id,lvl)
call IssueImmediateOrder(Dummy,"stomp")
call RemoveUnit(Dummy)
set Dummy = null
call GroupEnumUnitsInRange(Group,GetUnitX(cast),GetUnitY(cast),Radius(lvl),Enemyfilt)
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group,u)
if IsUnitEnemy(u,GetOwningPlayer(cast)) then
call UnitDamageTarget(cast,u,dam,false,false,A_type,D_type,W_type)
if IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_FLOATABILITY) then
call DestroyEffect(AddSpecialEffectTarget(DamageDirt_sfx,u,Damage_point))
elseif not IsTerrainPathable(GetUnitX(u),GetUnitY(u),PATHING_TYPE_WALKABILITY) then
call DestroyEffect(AddSpecialEffectTarget(DamageWater_sfx,u,Damage_point))
endif
endif
endloop
endif
endif
set cast = null
return false
endfunction
//=======================================================================
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local trigger trig
if GetLearnedSkill() == Abil_id and GetUnitAbilityLevel(cast,Abil_id) == 1 and IsUnitIllusion(cast) == false then
set trig = CreateTrigger()
call TriggerRegisterUnitEvent(trig,cast,EVENT_UNIT_DAMAGED)
call TriggerAddCondition(trig,Condition(function Update))
endif
set cast = null
set trig = null
endfunction
//=======================================================================
private function TrueFilt takes nothing returns boolean
return true
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
local unit dum = null
set Group = CreateGroup()
set Truefilt = Filter(function TrueFilt)
set Enemyfilt = Filter(function EnemyFilt)
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_HERO_SKILL,Truefilt)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(trig,function Actions)
if AllowPreload then
set dum = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),Dummy_id,0.00,0.00,0.00)
call UnitAddAbility(dum,Abil2_id)
call IssueImmediateOrder(dum,"stomp")
call UnitApplyTimedLife(dum,'BTLF',1.00)
call DestroyEffect(AddSpecialEffect(DamageDirt_sfx,0.00,0.00))
call DestroyEffect(AddSpecialEffect(DamageWater_sfx,0.00,0.00))
endif
set dum = null
endfunction
endscope
//TESH.scrollpos=45
//TESH.alwaysfold=0
scope test initializer setup
function setup takes nothing returns nothing
//!//////////////////////////////
//! Murloc hut spawn gauntlet //
//!//////////////////////////////
local unit hut = gg_unit_n01T_0429 // Thats the gnoll hut Placed on the map where units should spawn
local player p = Player(8) // Units spawn for this Player (Player 12, Brown)
local integer SpawnType = 'nscb' // The Unittype which spawns (Burglars)
local real facing = 450 // The facing of the spawn (Faces a bit in the direction where the heroes will come from)
local real EnemyRange = 300 // Does only spawn with any enemy in rangee of 400 near the hut
local real SpawnInterval = 8 // If enemys are near every 3.25 seconds a unit Spawns
local integer MaxEnemys = 6 // Spawn Stops while there are 5 spawns
local real CountRange = 300 // Max amount of spawns is counted in this range near the hut
local string SpawnEffect = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" // Effect while a unit spawns
//Actually calls the function with the values set above which initializes the library for the hut
call AddSpawnToHut(hut,p,SpawnType,facing,EnemyRange,SpawnInterval,MaxEnemys,CountRange,SpawnEffect)
// spawn effects: Fire/mechanical: Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl | Water: Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl | Nature: Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl
// Ice/other: Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl | black: Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl
//!///////////////////////
//! Human stage 1 Spawn //
//!///////////////////////
call AddSpawnToHut(gg_unit_n01U_0436,Player(8),'nsc3',300,600,16,4,600,"Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" )
call AddSpawnToHut(gg_unit_n01U_0437,Player(8),'nsc3',150,400,16,4,400,"Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" )
//set
call AddSpawnToHut(gg_unit_n01T_0425,Player(8),'nscb',450,300,8,6,300,"Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" )
call AddSpawnToHut(gg_unit_n01T_0435,Player(8),'nscb',0,300,8,6,300,"Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" )
call AddSpawnToHut(gg_unit_n01T_0427,Player(8),'nscb',0,300,8,6,300,"Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" )
//!///////////////////////
//! Human stage 2 Spawn //
//!///////////////////////
call AddSpawnToHut(gg_unit_n01V_0444,Player(8),'nplb',300,500,8,3,500,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
call AddSpawnToHut(gg_unit_n01V_0432,Player(8),'nplb',300,500,8,3,500,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
call AddSpawnToHut(gg_unit_n01V_0443,Player(8),'nplb',300,500,8,3,500,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
//!///////////////////////
//! Human stage 3 Spawn //
//!///////////////////////
call AddSpawnToHut(gg_unit_n01W_0438,Player(8),'nskm',300,700,6,6,600,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0426,Player(8),'nskm',300,700,6,6,600,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
//set
call AddSpawnToHut(gg_unit_n01W_0442,Player(8),'nzom',300,300,4,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0439,Player(8),'nzom',300,300,4,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0441,Player(8),'nzom',300,300,4,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
//!/////////////////////
//! Orc stage 1 Spawn //
//!/////////////////////
call AddSpawnToHut(gg_unit_n01Y_0455,Player(8),'nslh',600,550,8,6,600,"Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl" )
call AddSpawnToHut(gg_unit_n01Y_0457,Player(8),'nslh',300,550,8,6,600,"Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl" )
call AddSpawnToHut(gg_unit_n01Y_0456,Player(8),'nslh',600,550,8,6,600,"Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl" )
call AddSpawnToHut(gg_unit_n01Y_0458,Player(8),'nslh',300,550,8,6,600,"Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl" )
//!/////////////////////
//! Orc stage 2 Spawn //
//!/////////////////////
call AddSpawnToHut(gg_unit_n01Z_0424,Player(8),'nfrl',300,550,8,4,600,"Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" )
call AddSpawnToHut(gg_unit_n01Z_0428,Player(8),'nfrl',300,550,8,4,600,"Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" )
call AddSpawnToHut(gg_unit_n01Z_0451,Player(8),'nfrl',300,550,8,4,600,"Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" )
//set
call AddSpawnToHut(gg_unit_n020_0452,Player(8),'ngnw',300,600,8,5,600,"Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" )
call AddSpawnToHut(gg_unit_n020_0430,Player(8),'ngnw',300,600,8,5,600,"Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" )
//!/////////////////////
//! Orc stage 3 Spawn //
//!/////////////////////
call AddSpawnToHut(gg_unit_n01V_0446,Player(8),'nplb',700,500,6,7,500,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
call AddSpawnToHut(gg_unit_n01V_0447,Player(8),'nplb',700,500,6,7,500,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
//set
call AddSpawnToHut(gg_unit_n01X_0445,Player(8),'nplg',700,700,12,7,650,"Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" )
//!/////////////////////
//! Orc stage 4 Spawn //
//!/////////////////////
call AddSpawnToHut(gg_unit_n01W_0448,Player(8),'nzom',0,500,3,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0434,Player(8),'nzom',0,500,3,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0449,Player(8),'nzom',0,350,3,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
call AddSpawnToHut(gg_unit_n01W_0450,Player(8),'nzom',0,400,3,6,100,"Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
//blablubb
set hut = null
set p = null
endfunction
endscope
//TESH.scrollpos=3
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////
// Spawn Library 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. °°°°°°°
// °°
//
// What you need to use this Library :
// - Jass New Gen Pack due it uses vJass
//
// How to use this Library :
// - The only thing you really need is the AddSpawnToHut function
// - For detailed information about each variable check the struct in line 143 or better take a look at the Test trigger added to this testmap
//
// Please give Credits when using
library SL initializer init
globals
private constant real TimerPeriod = 0.25
// The Interval all checks and spawns are executed
// Its also the min. Step of Spawn Intervals
endglobals
function AddSpawnToHut takes unit hut, player Owner, integer Spawn, real Facing, real EnemyRange, real SpawnInterval, integer MaxUnits, real CountRange, string SpawnEffect returns nothing
// This is the main Function of this system to be used
// It initializes the spawn of the hut
// Fo detailed information what each variable stands for look in the struct
call SL.create(hut,Owner,Spawn,Facing,EnemyRange,SpawnInterval,MaxUnits,CountRange,SpawnEffect)
endfunction
/////////////////////////////////////////////System Script////////////////////////////////////////
globals
// Systems Variables
private timer t = CreateTimer()
private group g = CreateGroup()
private boolexpr ufilter = null
endglobals
private function UnitFilter takes nothing returns boolean
// Any Units counted in range of the hut (enemy/Spawns) have to match this condition
return (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction
private function CountUnitsInRangeOfType takes unit hut, real Range, integer UnitType, boolean Enemy returns integer
// This functions counts all units in range
// If the boolean Enemys == false it counts all units of the unittype in range
// If the boolean Enemys == true it counts every Enemy unit in range
local integer i = 0
local unit u
call GroupEnumUnitsInRange(g, GetUnitX(hut), GetUnitY(hut),Range, ufilter)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
//Condition for counting, set up as described above
if (GetUnitTypeId(u) == UnitType and GetOwningPlayer(u) == GetOwningPlayer(hut) and Enemy == false ) or ( IsPlayerEnemy(GetOwningPlayer(u),GetOwningPlayer(hut)) == true and Enemy == true ) then
set i = i + 1
endif
endloop
set u = null
return i
endfunction
private function Callback takes nothing returns nothing
local integer i = 0
local unit u
local SL d
loop
//Looping through all structs
exitwhen i >= SL.Index
set d = SL.Data[i]
//Sure the hut or unit where all spawns are created shouldnt be dead
if GetWidgetLife(d.hut) >= 0.405 then
set d.Counter = d.Counter + TimerPeriod
//Checks if enemys are near to spawn and if the max. amount of spawns isn reached
if CountUnitsInRangeOfType(d.hut,d.CountRange, d.SpawnType,false) < d.MaxUnits and CountUnitsInRangeOfType(d.hut,d.EnemyRange, d.SpawnType,true) != 0 then
if d.Counter >= d.SpawnInterval then
set d.Counter = d.Counter - d.SpawnInterval
//Spawning the unit
set u = CreateUnit(d.Owner,d.SpawnType,GetUnitX(d.hut),GetUnitY(d.hut),d.Facing)
call DestroyEffect(AddSpecialEffect(d.SpawnEffect,GetUnitX(u),GetUnitY(u)))
endif
else
// Even if no enemys are near or the max amout of units is reached the hut "prepares" to spawn
// that if the conditions above are true and a unit should be spawned it is spaned directly
// because i think it useless if you get near a hut in range and then after the spawn interval the first unit spawns
if d.Counter >= d.SpawnInterval then
set d.Counter = d.SpawnInterval - TimerPeriod
endif
endif
set i = i + 1
else
// Hut is destroeyed, struct gets removed
set d.hut = null
set d.Owner = null
call SL.destroy(d)
set SL.Index = SL.Index - 1
set SL.Data[i] = SL.Data[SL.Index]
endif
endloop
if SL.Index == 0 then
call PauseTimer(t)
endif
set u = null
endfunction
struct SL
static integer Index = 0
static SL array Data
unit hut // Main building or unit where all spawns are created
player Owner // The owner of the Spawns (should be the owner of the Hut)
integer SpawnType // The units which Spawn
real Facing // Units Facing when spawning
real EnemyRange // Units do only Spawn if an enemy is in this range
real SpawnInterval // IThe interval in which units Spawn if enemys are near
integer MaxUnits // Maximum units spawned at the same time
real CountRange // Max. Amount of units near the hut is counted in this range
string SpawnEffect // Special Effect created when a unit Spawns
real Counter // Current Counter of the Spawn
static method create takes unit hut, player Owner, integer Spawn, real Facing, real EnemyRange, real SpawnInterval, integer MaxUnits, real CountRange, string SpawnEffect returns SL
local SL d = SL.allocate()
// Setting all Variables
set d.hut = hut
set d.Owner = Owner
set d.SpawnType = Spawn
set d.EnemyRange = EnemyRange
set d.SpawnInterval = SpawnInterval
set d.MaxUnits = MaxUnits
set d.CountRange = CountRange
set d.SpawnEffect = SpawnEffect
set d.Facing = d.Facing
set d.Counter = SpawnInterval - TimerPeriod
set SL.Data[SL.Index] = d
//Starting the timer if it isnt already
if d.Index == 0 then
call TimerStart(t, TimerPeriod, true, function Callback)
endif
set d.Index = d.Index + 1
return d
endmethod
endstruct
private function init takes nothing returns nothing
//Setting up the unit filter
set ufilter = Filter(function UnitFilter)
endfunction
endlibrary