Hatebreeder
So many apples
- Reaction score
- 381
Requirements:
- Jass New Gen Package
- Cohadars TT (Timer Ticker)
Static Discharge
Imbues ones attacks with a static charge. Static charge discharges apon impact, dealing damage to all units in a 225 AOE, knocking all other units but the target itself away from the impact.
Level 1: adds 25 Damage to each attack
Level 2: adds 50 Damage to each attack
Level 3: adds 75 Damage to each attack
Level 4: adds 100 Damage to each attack
JASS:
scope StaticDischarge initializer Init
globals
private constant integer ID = 039;A000039; //Spell ID
private constant integer LIMIT = 8191 //Limit of Unit register (initiates reset after it hits limit).
private constant real AOE = 225. //Area of Effect of the Spell
private constant real DISTANCE = 200. //Knockback Distance
private constant real SPEED = 12. //Knockback Dpeed
private constant group GROUP = CreateGroup()
private constant string ORDERID = "flamingarrows" // Order Id for activation
private constant string ORDERIDOFF = "unflamingarrows" // Order Id for deactivation
private constant string FX = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" //Knockback Dust
private constant string SFX = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" //OnDamage Effect
private trigger array TRIG
private integer COUNT = 0
endglobals
private constant function DamageAmount takes integer Level returns real
return 25. * Level
endfunction
private function SetUnitXY takes unit u, real x, real y returns nothing
if x<GetRectMaxX(bj_mapInitialPlayableArea) and x>GetRectMinX(bj_mapInitialPlayableArea) and y<GetRectMaxY(bj_mapInitialPlayableArea) and y>GetRectMinY(bj_mapInitialPlayableArea) then
call SetUnitX(u,x)
call SetUnitY(u,y)
endif
endfunction
private struct Data
unit Target
real Dist = DISTANCE
real Angle
static method Timer takes nothing returns boolean
local Data this = TT_GetData()
local real TX = GetUnitX(.Target)
local real TY = GetUnitY(.Target)
local real X = TX + SPEED * Cos(.Angle * bj_DEGTORAD)
local real Y = TY + SPEED * Sin(.Angle * bj_DEGTORAD)
set .Dist = .Dist - SPEED
call DestroyEffect(AddSpecialEffect(FX,X,Y))
call SetUnitXY(.Target,X,Y)
if .Dist <= 0 or IsUnitType(.Target,UNIT_TYPE_DEAD) == true then
call .destroy()
return true
endif
return false
endmethod
static method create takes unit u, unit t returns Data
local Data this = Data.allocate()
local unit Damager = u
local real DX = GetUnitX(Damager)
local real DY = GetUnitY(Damager)
local real TX
local real TY
set .Target = t
set TX = GetUnitX(.Target)
set TY = GetUnitY(.Target)
set .Angle = bj_RADTODEG * Atan2(TY - DY,TX - DX)
set Damager = null
if IsUnitType(.Target,UNIT_TYPE_DEAD) == false then
call TT_Start(function Data.Timer,this)
else
call .destroy()
endif
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
if GetIssuedOrderId() == OrderId(ORDERID) then
call GroupAddUnit(GROUP,GetOrderedUnit())
endif
if GetIssuedOrderId() == OrderId(ORDERIDOFF) then
call GroupRemoveUnit(GROUP,GetOrderedUnit())
endif
// Spell Detection
if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT and GetSpellAbilityId() == ID then
return true
endif
//Attack Detection
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED and GetUnitAbilityLevel(GetAttacker(),ID) != 0 and IsUnitInGroup(GetAttacker(),GROUP) then
return true
endif
return false
endfunction
private function DamageConditions takes nothing returns boolean
return GetUnitAbilityLevel(GetEventDamageSource(),ID) != 0
endfunction
private function DamageActions takes nothing returns nothing
local Data array Dat
local unit Damaged = GetTriggerUnit()
local unit Damager = GetEventDamageSource()
local unit Picked
local integer Count = 0
local integer CountEx = 0
local integer Level = GetUnitAbilityLevel(Damager,ID)
local real Damage = GetEventDamage()
local real X = GetUnitX(Damaged)
local real Y = GetUnitY(Damaged)
local group Group = CreateGroup()
loop
exitwhen Count >= COUNT
set Count = Count + 1
if GetTriggeringTrigger() == TRIG[Count] then
call TriggerClearActions(TRIG[Count])
call TriggerClearConditions(TRIG[Count])
call DestroyTrigger(TRIG[Count])
set TRIG[Count] = null
call DestroyEffect(AddSpecialEffect(SFX,X,Y))
call UnitDamageTarget(Damager,Damaged,DamageAmount(Level),true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,null)
call GroupEnumUnitsInRange(Group,X,Y,AOE,null)
loop
set Picked = FirstOfGroup(Group)
exitwhen Picked == null
if IsUnitEnemy(Picked,GetOwningPlayer(Damager)) == true and IsUnitType(Picked,UNIT_TYPE_DEAD) == false and IsUnitType(Picked,UNIT_TYPE_STRUCTURE) == false and IsUnit(Picked,Damaged) == false then
set CountEx = CountEx + 1
set Dat[CountEx] = Dat[CountEx].create(Damaged,Picked)
call UnitDamageTarget(Damager,Picked,DamageAmount(Level) + Damage,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,null)
endif
call GroupRemoveUnit(Group,Picked)
endloop
endif
endloop
set Picked = null
set Damager = null
set Damaged = null
call DestroyGroup(Group)
set Group = null
endfunction
private function Actions takes nothing returns nothing
local unit Target
local integer Count = 0
if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
set Target = GetSpellTargetUnit()
endif
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED then
set Target = GetTriggerUnit()
endif
set COUNT = COUNT + 1
if TRIG[COUNT] == null then
set TRIG[COUNT] = CreateTrigger()
call TriggerRegisterUnitEvent(TRIG[COUNT],Target,EVENT_UNIT_DAMAGED)
call TriggerAddCondition(TRIG[COUNT], Condition(function DamageConditions))
call TriggerAddAction(TRIG[COUNT],function DamageActions)
endif
if COUNT >= LIMIT then
loop
exitwhen Count >= LIMIT
set Count = Count + 1
call TriggerClearActions(TRIG[Count])
call TriggerClearConditions(TRIG[Count])
call DestroyTrigger(TRIG[Count])
set TRIG[Count] = null
endloop
debug call BJDebugMsg("You have reached the Limit. Resetting Trigger Count.")
set COUNT = 0
set COUNT = COUNT + 1
endif
set Target = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger Trig = CreateTrigger( )
call Preload(FX)
call Preload(SFX)
call TriggerRegisterAnyUnitEventBJ( Trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerRegisterAnyUnitEventBJ( Trig, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerRegisterAnyUnitEventBJ( Trig, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddCondition( Trig, Condition( function Conditions ) )
call TriggerAddAction( Trig, function Actions )
set Trig = null
endfunction
endscope
Launches 5 Coils of death towards a target location in a fan-like arc. Any enemy unit a coil encounters, causes the Coil to burst apon impact, dealing damage to that unit. If a allied unit encounters a coil, it will be healed for 75% of the damage it would deal to an enemy unit.
Level 1: Deals 75 Damage
Level 2: Deals 150 Damage
Level 3: Deals 225 Damage
Level 4: Deals 300 Damage
JASS:
scope MorbidDoctrine initializer Init
globals
private constant integer ID = 039;A001039; // Spell ID
private constant integer DUMMY = 039;u001039; // Dummy Raw Code
private constant integer BOLTS = 5 //Number of coils
private constant real RADIUS = 110. //effective damage radius of coil
private constant real ARC = 90. //effective arc, in which each coil will be launched (any number between 45 and 180 is possible for a nice arc)
private constant real EDGES = ARC / BOLTS //Edges of an Arc (don't change this)
private constant real BAIL = 45. //range of the creation of the coils infront of the caster
private constant real DISTANCE = 750. // max. distance that the coils move
private constant real SPEED = 18. //speed of the coils
private constant string SFX = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl" // impact effect
endglobals
private constant function Damage takes integer Level returns real
return 75. * Level //Damage of each coil
endfunction
private constant function Heal takes real Amount returns real
return Amount * 0.75 //heal percentage
endfunction
private function SetUnitXY takes unit u, real x, real y returns nothing
if x<GetRectMaxX(bj_mapInitialPlayableArea) and x>GetRectMinX(bj_mapInitialPlayableArea) and y<GetRectMaxY(bj_mapInitialPlayableArea) and y>GetRectMinY(bj_mapInitialPlayableArea) then
call SetUnitX(u,x)
call SetUnitY(u,y)
endif
endfunction
private struct Data
unit Caster
unit array Dummys[BOLTS]
real array Angles[BOLTS]
real array Dists [BOLTS]
boolean array IsHit[BOLTS]
group Group = CreateGroup()
group Check = CreateGroup()
static method Timer takes nothing returns boolean
local Data this = TT_GetData()
local real DX
local real DY
local real X
local real Y
local integer Count = 0
local group Group = CreateGroup()
local unit Picked
loop
exitwhen Count >= BOLTS
set Count = Count + 1
if IsUnitType(.Dummys[Count],UNIT_TYPE_DEAD) == false then
set DX = GetUnitX(.Dummys[Count])
set DY = GetUnitY(.Dummys[Count])
set X = DX + SPEED * Cos(.Angles[Count] * bj_DEGTORAD)
set Y = DY + SPEED * Sin(.Angles[Count] * bj_DEGTORAD)
call SetUnitXY(.Dummys[Count],X,Y)
set .Dists[Count] = .Dists[Count] - SPEED
if .Dists[Count] <= 0 then
call DestroyEffect(AddSpecialEffect(SFX,X,Y))
call KillUnit(.Dummys[Count])
call GroupRemoveUnit(.Check,.Dummys[Count])
endif
call GroupEnumUnitsInRange(Group,X,Y,RADIUS,null)
set Picked = FirstOfGroup(Group)
if Picked != null then
loop
set Picked = FirstOfGroup(Group)
exitwhen Picked == null or .IsHit[Count] == true
if IsUnitType(Picked,UNIT_TYPE_DEAD) == false and IsUnitType(Picked,UNIT_TYPE_STRUCTURE) == false and IsUnitInGroup(Picked,.Group) == false and IsUnit(Picked,.Caster) == false then
if IsUnitEnemy(Picked,GetOwningPlayer(.Caster)) == true then
call UnitDamageTarget(.Caster,Picked,Damage(GetUnitAbilityLevel(.Caster,ID)),true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,null)
set .IsHit[Count] = true
endif
if IsUnitEnemy(Picked,GetOwningPlayer(.Caster)) == false then
call SetUnitState(Picked,UNIT_STATE_LIFE,GetUnitState(Picked,UNIT_STATE_LIFE) + Heal(Damage(GetUnitAbilityLevel(.Caster,ID))))
set .IsHit[Count] = true
endif
endif
call GroupAddUnit(.Group,Picked)
call GroupRemoveUnit(Group,Picked)
endloop
if .IsHit[Count] == true then
call DestroyEffect(AddSpecialEffect(SFX,X,Y))
call KillUnit(.Dummys[Count])
call GroupRemoveUnit(.Check,.Dummys[Count])
endif
endif
endif
endloop
set Picked = FirstOfGroup(.Check)
if Picked == null then
call GroupClear(Group)
call DestroyGroup(Group)
set Group = null
set Picked = null
call .destroy()
return true
endif
set Picked = null
call GroupClear(Group)
call DestroyGroup(Group)
set Group = null
return false
endmethod
static method create takes unit C, unit T returns Data
local Data this = Data.allocate()
local unit Target = T
local real CasterX
local real CasterY
local real X
local real Y
local real TargetX
local real TargetY
local real Angle
local integer Count = 0
set .Caster = C
set CasterX = GetUnitX(.Caster)
set CasterY = GetUnitY(.Caster)
set TargetX = GetUnitX(Target)
set TargetY = GetUnitY(Target)
set Angle = bj_RADTODEG * Atan2(TargetY - CasterY, TargetX - CasterX)
set X = CasterX + BAIL * Cos(Angle * bj_DEGTORAD)
set Y = CasterY + BAIL * Sin(Angle * bj_DEGTORAD)
loop
exitwhen Count >= BOLTS
set Count = Count + 1
set .Angles[Count] = ( Angle - ARC / 2 ) + ( EDGES * Count )
set .Dummys[Count] = CreateUnit(GetOwningPlayer(.Caster),DUMMY,X,Y,.Angles[Count])
set .Dists [Count] = DISTANCE
set .IsHit [Count] = false
call GroupAddUnit(.Check,.Dummys[Count])
endloop
set Target = null
return this
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ID
endfunction
private function Actions takes nothing returns nothing
local Data this = Data.create(GetTriggerUnit(),GetSpellTargetUnit())
call TT_Start(function Data.Timer,this)
endfunction
private function Init takes nothing returns nothing
local trigger Trig = CreateTrigger( )
call Preload(SFX)
call TriggerRegisterAnyUnitEventBJ( Trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( Trig, Condition( function Conditions ) )
call TriggerAddAction( Trig, function Actions )
set Trig = null
endfunction
endscope
I was a long time since i last submitted something to TheHelper.net, therefore I thought: "Hey, Summer Vacation is nearly over and I should at least do something non contra-productive to end this." So i came up with these two spells.
Both Spells are rather dry on the Eye candy, but nevertheless, they are fun IMO.
Implementation Instructions are listed in the trigger section.
I present you...
Lightning Missle
It doesn't look very decent in the picture, but In-Game it looks very decent, just take a look.
Thanks to Tinki3 for the Spell Template Map.
Sorry for the Zip thing. My Computer won't let me attach files to Zip Folders due to some weird error.
Could someone do this for me?
Hope you like this Spellpack + Model.
Please comment and rate =)