Spell Epicenter

Naminator

Coming Back To Life
Reaction score
76
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.

Ok Ghan. Tell me when you finish the complete JASS version.
Thanksss for making this spell. +REP

(I believe that you make this spell after reading my post in your index?)

Thanks for the rep, and yes. :p
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
I think this is MUI:
 

Attachments

  • Epicenter.w3x
    15.6 KB · Views: 281

Naminator

Coming Back To Life
Reaction score
76
I think this is MUI:

That's the complete version of JASS?. Cause I saw the first trigger GUI. But I think that's it, cause you customize the seconds more than the first version you gave me. Just asking..thanks for doing it by the way. :D
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> Cause I saw the first trigger GUI.

Eh, who cares about that trigger? :p
It's necessary to set the variables there, but it doesn't really need to be in JASS; there's no point.
 

Naminator

Coming Back To Life
Reaction score
76
> Cause I saw the first trigger GUI.

Eh, who cares about that trigger? :p
It's necessary to set the variables there, but it doesn't really need to be in JASS; there's no point.

Ok, ok, no need to get angry:p.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> Ok, ok, no need to get angry

Angry?
No, not angry. Did I sound like it? Didn't mean to....
Just saying that there's no advantage to converting that trigger to JASS.
There's nothing to optimize. :p
 

Naminator

Coming Back To Life
Reaction score
76
> Ok, ok, no need to get angry

Angry?
No, not angry. Did I sound like it? Didn't mean to....
Just saying that there's no advantage to converting that trigger to JASS.
There's nothing to optimize. :p

I was just kidding Ghan. :p Got your point. :D and I upadate it.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Did you test it fully?
No bugs?
Very large giraffes do not pop out of the ground and eat your hero?
You don't have random floods?
 

Naminator

Coming Back To Life
Reaction score
76
Did you test it fully?
No bugs?
Very large giraffes do not pop out of the ground and eat your hero?
You don't have random floods?

Yes, now that you mention. I saw a bug. The crater made under there hero, does not move. When you move the hero while doing damage the crater stay at the same position when you cast the spell.
See in the GUI version that if you move the hero, the creater appears under you, every time.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
You mean while the spell is being cast, right?
Well, I would say that's a good thing, actually.
Why would the ground ripple move with the hero after the hero has supposedly finished casting the spell and it's just the effect going forward?
 

Naminator

Coming Back To Life
Reaction score
76
You mean while the spell is being cast, right?
Well, I would say that's a good thing, actually.
Why would the ground ripple move with the hero after the hero has supposedly finished casting the spell and it's just the effect going forward?

After the 2 seconds. When the ground start ripple, the craters has to move with the hero and the radious of damge also. It's the way that spell is made in DotA!. :p
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Ok, ok, fine. Have it your way.
This IS Burger King, isn't it? :p

New Code here, with new stuff as well. Elimination of one BJ, and addition of some new constant functions at the top, as well as one non-constant function....

JASS:
//These three 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

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

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
    local location unitloc = GetUnitLoc(GetEnumUnit())
    local location Epicenter_Caster_Loc = GetUnitLoc(udg_Epicenter_Caster)
    if ( DistanceBetweenPoints(Epicenter_Caster_Loc, unitloc) <= 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) <= 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) <= 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)
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 = GetUnitLoc(caster)
    local group Epicenter_Group = GetUnitsInRangeOfLocMatching(LargeDamageRange(), Epicenter_Caster_Loc, Condition(function Matching))
    call RemoveLocation (Epicenter_Caster_Loc)
    loop
      exitwhen Epicenter_Pulses == 0
      set Epicenter_Caster_Loc = GetUnitLoc(caster) 
      call TerrainDeformationCraterBJ( 0.5, false, Epicenter_Caster_Loc, LargeDamageRange()-40.00, 28.00 )
      call CreateNUnitsAtLoc( 1, 'h000', GetOwningPlayer(caster), Epicenter_Caster_Loc, bj_UNIT_FACING )
      call UnitAddAbility(GetLastCreatedUnit(), 'A001' )
      call IssueImmediateOrder( GetLastCreatedUnit(), "thunderclap" )
      call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 0.30 )
      set udg_Epicenter_Caster = caster
      call ForGroup( Epicenter_Group, function Picked )
      set Epicenter_Pulses = Epicenter_Pulses-1
      call RemoveLocation (Epicenter_Caster_Loc)
      call PolledWait(TimeBetweenRipples())
    endloop
    call DestroyGroup (Epicenter_Group)
    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
 

Naminator

Coming Back To Life
Reaction score
76
Ok, ok, fine. Have it your way.
This IS Burger King, isn't it? :p

New Code here, with new stuff as well. Elimination of one BJ, and addition of some new constant functions at the top, as well as one non-constant function....

JASS:
//These three 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

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

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
    local location unitloc = GetUnitLoc(GetEnumUnit())
    local location Epicenter_Caster_Loc = GetUnitLoc(udg_Epicenter_Caster)
    if ( DistanceBetweenPoints(Epicenter_Caster_Loc, unitloc) <= 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) <= 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) <= 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)
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 = GetUnitLoc(caster)
    local group Epicenter_Group = GetUnitsInRangeOfLocMatching(LargeDamageRange(), Epicenter_Caster_Loc, Condition(function Matching))
    call RemoveLocation (Epicenter_Caster_Loc)
    loop
      exitwhen Epicenter_Pulses == 0
      set Epicenter_Caster_Loc = GetUnitLoc(caster) 
      call TerrainDeformationCraterBJ( 0.5, false, Epicenter_Caster_Loc, LargeDamageRange()-40.00, 28.00 )
      call CreateNUnitsAtLoc( 1, 'h000', GetOwningPlayer(caster), Epicenter_Caster_Loc, bj_UNIT_FACING )
      call UnitAddAbility(GetLastCreatedUnit(), 'A001' )
      call IssueImmediateOrder( GetLastCreatedUnit(), "thunderclap" )
      call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 0.30 )
      set udg_Epicenter_Caster = caster
      call ForGroup( Epicenter_Group, function Picked )
      set Epicenter_Pulses = Epicenter_Pulses-1
      call RemoveLocation (Epicenter_Caster_Loc)
      call PolledWait(TimeBetweenRipples())
    endloop
    call DestroyGroup (Epicenter_Group)
    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

You fix that. But till there the last problem. The damage is made only in the range when you cast the spell. If you move to another position you will not damage nearby units.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
> The damage is made only in the range when you cast the spell.

Did you try it?
I don't think it will do that in the new code I posted....
 

Naminator

Coming Back To Life
Reaction score
76
> The damage is made only in the range when you cast the spell.

Did you try it?
I don't think it will do that in the new code I posted....

Yes I tried, with your new code. It goes like this. After you cast the spell, you start damaging all nearby units, but if you move to anothers unit, that there weren't near the position of when you cast the spell, the will not get damage, only slow.
 

Tinki3

Special Member
Reaction score
418
Just a few things to point out here:

- 'Epicenter pulses' can be used from the global variable from the endcast trigger.
- No locals are nullified apart from the unit variable 'caster'.
- All rawcodes should be made easy to configure by using some constant functions.
- 'IsUnitAliveBJ' can be simply 'GetWidgetLife(unit) > 0.405'.
- 'IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Epicenter_Caster)) == true'
will not work too well with different colored players using the spell.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Thanks for the tips, Tinki3!

Though, I have some questions:

> 'Epicenter pulses' can be used from the global variable from the endcast trigger.

Yes... though I was thinking it would make the trigger more independent... suppose it doesn't really matter either way.

> - 'IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Epicenter_Caster)) == true'
will not work too well with different colored players using the spell.

Why?

New Code:

JASS:
//These three 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 'A002'
endfunction

constant function DummyUnitCode takes nothing returns integer
    return 'h000'
endfunction

constant function DummyAbilityCode takes nothing returns integer
    return 'A001'
endfunction

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

function Matching takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 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) <= 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) <= 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) <= 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
    loop
      exitwhen Epicenter_Pulses == 0
      set udg_Epicenter_Caster = caster
      set Epicenter_Group = GetUnitsInRangeOfLocMatching(LargeDamageRange(), Epicenter_Caster_Loc, Condition(function Matching))
      set Epicenter_Caster_Loc = GetUnitLoc(caster) 
      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(), "thunderclap" )
      call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 0.30 )
      call ForGroup( Epicenter_Group, function Picked )
      set Epicenter_Pulses = Epicenter_Pulses-1
      call RemoveLocation (Epicenter_Caster_Loc)
      call DestroyGroup (Epicenter_Group)
      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
 

Tinki3

Special Member
Reaction score
418
> suppose it doesn't really matter either way

No, it doesn't.
You had an unused variable in the other trigger that's why I pointed it out.

Either way is fine.

> Why?

Well if you had 2 Epicenters cast at once, with both caster unit's owner's being
enemies to each other, both instances of the trigger will have to work off of
that single global variable.

Which means that the player who cast the spell second will be the player
who has the spell work correctly for them, as the global variable is overwritten
after the first instance.

New code looks better!
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
888
Well, when you cast it, it immediately stores the caster to a local and works from that, so it should work, shouldn't it?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top