Spell Epicenter

Naminator

Coming Back To Life
Reaction score
76
Here's a DotA Spell. Call Epicenter, from Crixalis. I don't if it's right the damage when units are more closer. Tell if something leaks or how can I improve, so then I can add it to the index. Thanks.

It's GUI and JASS.

epicenter1qc1.jpg
epicenter2kv8.jpg



Epicenter:
Sends a disturbance into the earth, causing it to shudder violently. All caught within range will take damage and become slowed. The closer to the epicenter, the more damage taken.

Level 1 - 2.0 second casting time, 6 pulses of 110 damage.
Level 2 - 2.0 second casting time, 8 pulses of 110 damage.
Level 3 - 2.0 second casting time, 10 pulses of 110 damage.

Epicenter GUI:

Code:
Epicenter
    Events
        Unit - A unit Finishes casting an ability
    Conditions
        (Ability being cast) Equal to Epicenter 
    Actions
        Set Epicenter_Caster = (Triggering unit)
        Set Epicenter_Caster_Loc = (Position of Epicenter_Caster)
        Set Epicenter_Pulses = (4 + (2 x (Level of Epicenter  for Epicenter_Caster)))
        Set Epicenter_Damage = 110
        Trigger - Turn on Epicenter Action <gen>
        Wait until (Epicenter_Pulses Equal to 0), checking every 0.10 seconds
        Trigger - Turn off Epicenter Action <gen>

Code:
Epicenter Action
    Events
        Time - Every 0.30 seconds of game time
    Conditions
    Actions
        Set Epicenter_Pulses = (Epicenter_Pulses - 1)
        Set Epicenter_Caster_Loc = (Position of Epicenter_Caster)
        Set Epicenter_Group = (Units within 600.00 of Epicenter_Caster_Loc matching ((((Matching unit) belongs to an enemy of (Owner of Epicenter_Caster)) Equal to True) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) is A structure) Equal to False))))
        Environment - Create a 0.50 second Temporary crater deformation at Epicenter_Caster_Loc with radius 560.00 and depth 28.00
        Unit - Create 1 Dummy Unit for (Owner of Epicenter_Caster) at Epicenter_Caster_Loc facing Default building facing degrees
        Unit - Add Epicenter Slow  to (Last created unit)
        Unit - Order (Last created unit) to Human Mountain King - Thunder Clap
        Unit - Add a 0.30 second Generic expiration timer to (Last created unit)
        Unit Group - Pick every unit in Epicenter_Group and do (Actions)
            Loop - Actions
                Set Epicenter_Picked_Loc = (Position of (Picked unit))
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Distance between Epicenter_Caster_Loc and Epicenter_Picked_Loc) Less than or equal to 200.00
                    Then - Actions
                        Unit - Cause Epicenter_Caster to damage (Picked unit), dealing ((Real(Epicenter_Damage)) + 20.00) damage of attack type Spells and damage type Universal
                    Else - Actions
                        Custom script:   call RemoveLocation (udg_Epicenter_Picked_Loc)
                        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            If - Conditions
                                (Distance between Epicenter_Caster_Loc and Epicenter_Picked_Loc) Less than or equal to 400.00
                            Then - Actions
                                Unit - Cause Epicenter_Caster to damage (Picked unit), dealing ((Real(Epicenter_Damage)) - 20.00) damage of attack type Spells and damage type Universal
                            Else - Actions
                                Custom script:   call RemoveLocation (udg_Epicenter_Picked_Loc)
                                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    If - Conditions
                                        (Distance between Epicenter_Caster_Loc and Epicenter_Picked_Loc) Less than or equal to 600.00
                                    Then - Actions
                                        Unit - Cause Epicenter_Caster to damage (Picked unit), dealing ((Real(Epicenter_Damage)) - 30.00) damage of attack type Spells and damage type Universal
                                    Else - Actions
                Custom script:   call RemoveLocation (udg_Epicenter_Caster_Loc)
        Custom script:   call RemoveLocation (udg_Epicenter_Picked_Loc)
        Custom script:   call DestroyGroup (udg_Epicenter_Group)

Epicenter JASS:

JASS:
//These constant functions control the range of the damage and deformation. Just change the values in these functions to alter the trigger.

constant function LargeDamageRange takes nothing returns real
    return 600.00
endfunction

constant function MediumDamageRange takes nothing returns real
    return 400.00
endfunction

constant function SmallDamageRange takes nothing returns real
    return 200.00
endfunction

constant function TimeBetweenRipples takes nothing returns real
    return 0.3
endfunction

constant function EpicenterAbilityCode takes nothing returns integer
    return &#039;A002&#039;
endfunction

constant function DummyUnitCode takes nothing returns integer
    return &#039;h000&#039;
endfunction

constant function DummyAbilityCode takes nothing returns integer
    return &#039;A001&#039;
endfunction

function NumberOfPulses takes unit caster returns integer
    return ( 4 + ( 2 * GetUnitAbilityLevel(caster, EpicenterAbilityCode()) ) )
endfunction

function Matching takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Epicenter_Caster)) == true
endfunction

function Picked takes nothing returns nothing
    local location unitloc = GetUnitLoc(GetEnumUnit())
    local location Epicenter_Caster_Loc = GetUnitLoc(udg_Epicenter_Caster)
    if ( DistanceBetweenPoints(Epicenter_Caster_Loc, unitloc) &lt;= SmallDamageRange() ) then
        call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) + 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
    else
        if ( DistanceBetweenPoints(Epicenter_Caster_Loc, unitloc) &lt;= MediumDamageRange() ) then
            call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
        else
            if ( DistanceBetweenPoints(Epicenter_Caster_Loc, unitloc) &lt;= LargeDamageRange() ) then
                call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 30.00 ),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
            else
            endif
        endif
    endif
    call RemoveLocation (unitloc)
    call RemoveLocation (Epicenter_Caster_Loc)
    set unitloc = null
    set Epicenter_Caster_Loc = null 
endfunction

function Trig_Epicenter_Action_Actions takes nothing returns nothing
    local unit caster = udg_Epicenter_Caster
    local integer Epicenter_Pulses = NumberOfPulses(caster)
    local location Epicenter_Caster_Loc
    local group Epicenter_Group
    local boolexpr b
    loop
      exitwhen Epicenter_Pulses == 0
      set udg_Epicenter_Caster = caster
      set Epicenter_Caster_Loc = GetUnitLoc(caster)
      set b = Condition(function Matching)
      set Epicenter_Group = GetUnitsInRangeOfLocMatching(LargeDamageRange(), Epicenter_Caster_Loc, b) 
      call TerrainDeformationCraterBJ( 0.5, false, Epicenter_Caster_Loc, LargeDamageRange()-40.00, 28.00 )
      call CreateNUnitsAtLoc( 1, DummyUnitCode(), GetOwningPlayer(caster), Epicenter_Caster_Loc, bj_UNIT_FACING )
      call UnitAddAbility(GetLastCreatedUnit(), DummyAbilityCode() )
      call IssueImmediateOrder( GetLastCreatedUnit(), &quot;thunderclap&quot; )
      call UnitApplyTimedLife(GetLastCreatedUnit(), &#039;BTLF&#039;, 0.30 )
      call ForGroup( Epicenter_Group, function Picked )
      set Epicenter_Pulses = Epicenter_Pulses-1
      call RemoveLocation (Epicenter_Caster_Loc)
      call DestroyGroup (Epicenter_Group)
      call DestroyBoolExpr(b)
      set b = null
      set Epicenter_Caster_Loc = null
      set Epicenter_Group = null
      call PolledWait(TimeBetweenRipples())
    endloop
    set caster = null
endfunction

//===========================================================================
function InitTrig_Epicenter_Action takes nothing returns nothing
    set gg_trg_Epicenter_Action = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Epicenter_Action, function Trig_Epicenter_Action_Actions )
endfunction
 

Attachments

  • [Epicenter] GUI Version.w3x
    15.4 KB · Views: 790
  • [Epicenter] JASS Version.w3x
    16.1 KB · Views: 416

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Code:
Set Epicenter_Picked_Loc = (Position of (Picked unit))

That needs to be cleared in the loop. You have it outside the loop right now.
 

Naminator

Coming Back To Life
Reaction score
76
Code:
Set Epicenter_Picked_Loc = (Position of (Picked unit))

That needs to be cleared in the loop. You have it outside the loop right now.

Fixed it, thanks.. So what do you think ghan? Have you test it? Did it lag?.
 

0zaru

Learning vJASS ;)
Reaction score
60
In the mapp.... what is this doing there?????!!!

Code:
For each (Integer A) from 1 to Epicenter_Pulses, do (Actions)
    Loop - Actions
:p trigger epicenter
 

Naminator

Coming Back To Life
Reaction score
76
In the mapp.... what is this doing there?????!!!

Code:
For each (Integer A) from 1 to Epicenter_Pulses, do (Actions)
    Loop - Actions
:p trigger epicenter

No. I erase that, I was trying something..never mid.. I upadate it.

So tell what do you think? Is it good? Did it lag?
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Couple things:

1. Use Starts the Effect of an Ability on the first trigger.
2. Did it lag? Well, no, not really....
But that could have been a by-product of me converting the action trigger to JASS and optimizing it. :p
If you want, here's the code behind it:

JASS:
function Matching takes nothing returns boolean
    return IsUnitAliveBJ(GetFilterUnit()) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Epicenter_Caster)) == true
endfunction

function Picked takes nothing returns nothing
    set udg_Epicenter_Picked_Loc = GetUnitLoc(GetEnumUnit())
    if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 200.00 ) then
        call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) + 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
    else
        if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 400.00 ) then
            call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
        else
            if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 600.00 ) then
                call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 30.00 ),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
            else
            endif
        endif
    endif
    call RemoveLocation (udg_Epicenter_Picked_Loc)
endfunction

function Trig_Epicenter_Action_Actions takes nothing returns nothing
    set udg_Epicenter_Pulses = ( udg_Epicenter_Pulses - 1 )
    set udg_Epicenter_Caster_Loc = GetUnitLoc(udg_Epicenter_Caster)
    set udg_Epicenter_Group = GetUnitsInRangeOfLocMatching(600.00, udg_Epicenter_Caster_Loc, Condition(function Matching))
    call TerrainDeformationCraterBJ( 0.5, false, udg_Epicenter_Caster_Loc, 560.00, 28.00 )
    call CreateNUnitsAtLoc( 1, &#039;h000&#039;, GetOwningPlayer(udg_Epicenter_Caster), udg_Epicenter_Caster_Loc, bj_UNIT_FACING )
    call UnitAddAbility(GetLastCreatedUnit(), &#039;A001&#039; )
    call IssueImmediateOrder( GetLastCreatedUnit(), &quot;thunderclap&quot; )
    call UnitApplyTimedLife(GetLastCreatedUnit(), &#039;BTLF&#039;, 0.30 )
    call ForGroupBJ( udg_Epicenter_Group, function Picked )
    call DestroyGroup (udg_Epicenter_Group)
    call RemoveLocation (udg_Epicenter_Caster_Loc)
endfunction

//===========================================================================
function InitTrig_Epicenter_Action takes nothing returns nothing
    set gg_trg_Epicenter_Action = CreateTrigger(  )
    call DisableTrigger( gg_trg_Epicenter_Action )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Epicenter_Action, 0.30 )
    call TriggerAddAction( gg_trg_Epicenter_Action, function Trig_Epicenter_Action_Actions )
endfunction

If you're interested, there are a few more things I could do to make it easier to manipulate.
 

Naminator

Coming Back To Life
Reaction score
76
Couple things:

1. Use Starts the Effect of an Ability on the first trigger.
2. Did it lag? Well, no, not really....
But that could have been a by-product of me converting the action trigger to JASS and optimizing it. :p
If you want, here's the code behind it:

JASS:
function Matching takes nothing returns boolean
    return IsUnitAliveBJ(GetFilterUnit()) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Epicenter_Caster)) == true
endfunction

function Picked takes nothing returns nothing
    set udg_Epicenter_Picked_Loc = GetUnitLoc(GetEnumUnit())
    if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 200.00 ) then
        call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) + 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
    else
        if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 400.00 ) then
            call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 20.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
        else
            if ( DistanceBetweenPoints(udg_Epicenter_Caster_Loc, udg_Epicenter_Picked_Loc) &lt;= 600.00 ) then
                call UnitDamageTarget( udg_Epicenter_Caster, GetEnumUnit(), ( I2R(udg_Epicenter_Damage) - 30.00 ),true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
            else
            endif
        endif
    endif
    call RemoveLocation (udg_Epicenter_Picked_Loc)
endfunction

function Trig_Epicenter_Action_Actions takes nothing returns nothing
    set udg_Epicenter_Pulses = ( udg_Epicenter_Pulses - 1 )
    set udg_Epicenter_Caster_Loc = GetUnitLoc(udg_Epicenter_Caster)
    set udg_Epicenter_Group = GetUnitsInRangeOfLocMatching(600.00, udg_Epicenter_Caster_Loc, Condition(function Matching))
    call TerrainDeformationCraterBJ( 0.5, false, udg_Epicenter_Caster_Loc, 560.00, 28.00 )
    call CreateNUnitsAtLoc( 1, &#039;h000&#039;, GetOwningPlayer(udg_Epicenter_Caster), udg_Epicenter_Caster_Loc, bj_UNIT_FACING )
    call UnitAddAbility(GetLastCreatedUnit(), &#039;A001&#039; )
    call IssueImmediateOrder( GetLastCreatedUnit(), &quot;thunderclap&quot; )
    call UnitApplyTimedLife(GetLastCreatedUnit(), &#039;BTLF&#039;, 0.30 )
    call ForGroupBJ( udg_Epicenter_Group, function Picked )
    call DestroyGroup (udg_Epicenter_Group)
    call RemoveLocation (udg_Epicenter_Caster_Loc)
endfunction

//===========================================================================
function InitTrig_Epicenter_Action takes nothing returns nothing
    set gg_trg_Epicenter_Action = CreateTrigger(  )
    call DisableTrigger( gg_trg_Epicenter_Action )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Epicenter_Action, 0.30 )
    call TriggerAddAction( gg_trg_Epicenter_Action, function Trig_Epicenter_Action_Actions )
endfunction

If you're interested, there are a few more things I could do to make it easier to manipulate.


Ghan. The reason why I use a Unit - Unit finished casting an ability, is for the channeling. The spell has 2 seconds channeling, that's why, I bases it on startfall.
And please tell me what you want. If you want make a JASS version and I the GUI. So the people can have both. Tell me if GUI version is ok.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> The reason why I use a Unit - Unit finished casting an ability, is for the channeling.

Aha.
That's fine, then.
I don't play DotA much, and I've never seen this ability, so I didn't know. :p

> And please tell me what you want. If you want make a JASS version and I the GUI. So the people can have both. Tell if GUI version is ok.

Oh, it's totally up to you.
I just made it JASS to get a little practice and have fun. :p
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> that's parcial optimized

I'm sure it is.
Keep in mind, I don't know JASS.
It's certainly better than what the GUI turned out. :eek:
 

0zaru

Learning vJASS ;)
Reaction score
60
Hmm i am not sure about this but.. if you remove the Position of Picked unit not inside the Group loop wouldn't it leak ? Just thinked about it :p

The spell didn't lag, works fine and seems fun (Maybe add a little more channel :p)
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> if you remove the Position of Picked unit not inside the Group loop wouldn't it leak ?

Ghan_04 said:
That needs to be cleared in the loop. You have it outside the loop right now.

:rolleyes:
 

Naminator

Coming Back To Life
Reaction score
76
Ok Ghan. Made the JASS version, and then upload the map here...;). When you finish the JASS Version I add this Spell to the index.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
JASS Version:
 

Attachments

  • Epicenter.w3x
    15.4 KB · Views: 273

Tinki3

Special Member
Reaction score
418
The JASS Version is not much of a "JASS Version"...
Pretty much just converted GUI.
Well, half of it is anyway...

If you're going to have a JASS Version of the spell available, at least make it MUI
so that we can call it "JASS".

From what I can see it's not alot different at all compared to the GUI Version,
which makes me wonder, why have a JASS Version?
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Can I do nothing right? :(

It's true that I didn't change any of the fundamental workings of the trigger, but it's not just converted GUI.
 

Tinki3

Special Member
Reaction score
418
I'm not telling you to remove it or anything, just that it's a bit pointless
to create a JASS version that's not MUI, that's all.

This is what you should aim to do with JASS sripts - make them MUI.
JASS has lots of flexible options, why not use them? :)
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
To tell you the truth, I completely didn't think about making it MUI. :p
Totally forgot.

So!
I'll probably work on that later if I can. Maybe tomorrow.
 

NapaHero

Back from the dead...
Reaction score
43
Thanksss for making this spell. +REP :D

(I believe that you make this spell after reading my post in your index?)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top