scope DemonicPentagram initializer DemonicPentagramInit
globals
// ___ _ ___ _
// | \ ___ _ __ ___ _ _ (_)__ | _ \___ _ _| |_ __ _ __ _ _ _ __ _ _ __
// | |) / -_) ' \/ _ \ ' \| / _| | _/ -_) ' \ _/ _` / _` | '_/ _` | ' \
// |___/\___|_|_|_\___/_||_|_\__| |_| \___|_||_\__\__,_\__, |_| \__,_|_|_|_|
// |___/
// Made by "esdo" ( HiveWorkshop.com ) v 1.1a
//
// AUTHOR'S NOTE:
// My first vJass spell uploaded on hive... Hope you guys enjoy this efficient,
// leakless spell... Please give me credit if you ever use this!!!
// AUTHOR'S NOTE END
//
// DESCRIPTION:
// Curses an area, slowing and disabling all enemies inside, preventing spellcasting
// and any kind of attack. A pentagram is slowly drawn inside the area and, once its
// complete, the whole area will violently explode, dealing damage based on the caster's
// selected stat.
// DESCRIPTION END
//
// CREDITS:
// - Me, "esdo", for creating this spell.
// - "Deathismyfriend" and many other members of the Hive, that helped me learn Jass
// and fix my code.
// CREDITS END
//
// CONFIGURATION:
// "Size" defines the radius of the cursed area. Remember to change the radius effect
// to match this one in the "Pentagram [Effect 1]" spell!
private constant real SIZE = 300
//
// "ATTRIBUTE_USED" defines the used attribute for damage. You should edit only the latter
// part of the var, that is, the "_" and the last three letters. Use _STR for strenght,
// _AGI for agility and _INT for intelligence.
private constant integer ATTRIBUTE_USED = bj_HEROSTAT_STR
//
endglobals
//
// This function allows the user to configure it's own desired spell damage. It takes
// the hero's attribute and skill level as parameters.
private function GetDamageDealt takes real attribute, real level returns real
return attribute * level // <== This will be the damage done.
endfunction
globals
//
// "ATTACK_TYPE" defines the type of the attack dealt when the pentagram explodes.
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS
//
// "DAMAGE_TYPE" is the type of damage dealt by the pentagram explosion.
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
//
// "EFFECT_PATH" is the \\path of the special effect shown upon pentagram explosion.
private constant string EFFECT_PATH = "Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl"
//
// "DUMMY_ID" is the integer ID of the "Dummy" unit.
private constant integer DUMMY_ID = 'e000'
//
// "EFFECT_ID" is the inreger ID of the "Pentagram Dummy" unit.
private constant integer EFFECT_ID = 'e001'
//
// "SPELL1_ID" is the integer ID of the "Demonic Pentagram" spell.
private constant integer SPELL1_ID = 'A000'
//
// "SPELL2_ID" is the integer ID of the "Pentagram [Effect1]" spell.
private constant integer SPELL2_ID = 'A001'
//
// CONFIGURATION END
endglobals
private struct Pentagram
unit Caster
unit Draw
unit Dummy
group Effects
real Distance
integer SidesDrawn
real Facing
endstruct
globals
private timer Periodic = CreateTimer()
private integer Index = 0
private real TriSideSize = ( 0.95 * SIZE ) * 2
private Pentagram array Data
private integer Expire
endglobals
private function DemonicPentagramDraw takes nothing returns nothing
local effect s
local unit u
local integer i = 1
local real ox
local real oy
local real nx
local real ny
local real a
local player p
local group g = CreateGroup()
loop
exitwhen i > Index
set p = GetOwningPlayer( Data[i].Caster )
set ox = GetUnitX( Data[i].Draw )
set oy = GetUnitY( Data[i].Draw )
set nx = ox + 10 * Cos( Data[i].Facing * bj_DEGTORAD)
set ny = oy + 10 * Sin( Data[i].Facing * bj_DEGTORAD)
call SetUnitPosition( Data[i].Draw, nx, ny )
call GroupAddUnit( Data[i].Effects, CreateUnit( p, EFFECT_ID, nx, ny, 0 ))
set Data[i].Distance = Data[i].Distance + 10
if ( Data[i].Distance >= TriSideSize ) then
set Data[i].Distance = 0
set Data[i].Facing = Data[i].Facing - 144
set Data[i].SidesDrawn = Data[i].SidesDrawn + 1
if ( Data[i].SidesDrawn == 5 ) then
set ox = GetUnitX(Data[i].Dummy)
set oy = GetUnitY(Data[i].Dummy)
call KillUnit( Data[i].Draw )
call KillUnit( Data[i].Dummy )
set Expire = i
call GroupEnumUnitsInRange( g, ox, oy, SIZE, null )
loop
set u = FirstOfGroup( g )
exitwhen u == null
if ( IsPlayerAlly( GetOwningPlayer( Data[i].Caster ), GetOwningPlayer(u)) == false ) then
call UnitDamageTarget( Data[i].Caster, u, GetDamageDealt( GetHeroStatBJ( ATTRIBUTE_USED, Data[i].Caster, true ),IncUnitAbilityLevel( Data[i].Caster, SPELL1_ID )) , true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
endif
call GroupRemoveUnit( g, u )
endloop
loop
set u = FirstOfGroup( Data[i].Effects )
exitwhen u == null
set ox = GetUnitX( u )
set oy = GetUnitY( u )
set s = AddSpecialEffect( EFFECT_PATH, ox, oy )
call DestroyEffect( s )
call KillUnit(u)
call GroupRemoveUnit( Data[i].Effects, u )
endloop
set Data[i] = Data[Index]
call Data[Index].destroy()
set Index = Index - 1
if ( Index == 0 ) then
call PauseTimer( Periodic )
endif
set i = i - 1
endif
endif
set i = i + 1
endloop
call DestroyGroup(g)
set s = null
set u = null
set g = null
endfunction
private function Trig_DemonicPentagram_Actions takes nothing returns nothing
local integer i = 0
local player p
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real dx
local real dy
set Index = Index + 1
set Data[Index] = Pentagram.create()
set Data[Index].SidesDrawn = 0
set Data[Index].Caster = GetTriggerUnit()
set Data[Index].Facing = 108
set p = GetOwningPlayer( Data[Index].Caster )
set Data[Index].Dummy = CreateUnit( p, DUMMY_ID, x, y , 0 )
call UnitAddAbility( Data[Index].Dummy, SPELL2_ID)
call IssuePointOrder( Data[Index].Dummy, "cloudoffog", x, y )
set Data[Index].Draw = CreateUnit( p, DUMMY_ID, x, (y-SIZE), 108 )
set x = GetUnitX( Data[Index].Dummy )
set y = GetUnitY( Data[Index].Dummy )
set Data[Index].Distance = 0
call DestroyGroup( Data[Index].Effects )
set Data[Index].Effects = CreateGroup()
loop
exitwhen i == 360
set dx = x + SIZE * Cos( i * bj_DEGTORAD)
set dy = y + SIZE * Sin( i * bj_DEGTORAD)
call GroupAddUnit( Data[Index].Effects, CreateUnit( p, EFFECT_ID, dx, dy, 0 ))
set i = i + 2
endloop
if ( Index == 1 ) then
call TimerStart( Periodic, 0.03, true, function DemonicPentagramDraw )
endif
set p = null
endfunction
private function Trig_DemonicPentagram_Conditions takes nothing returns boolean
if ( GetSpellAbilityId() == SPELL1_ID ) then
call Trig_DemonicPentagram_Actions()
endif
return false
endfunction
//===========================================================================
private function DemonicPentagramInit takes nothing returns nothing
set gg_trg_DemonicPentagram = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_DemonicPentagram, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_DemonicPentagram, Condition( function Trig_DemonicPentagram_Conditions ) )
endfunction
endscope