Spell Blink Back

WolfieeifloW

WEHZ Helper
Reaction score
372
:eek: , AceHart the grand comments my spell!
"Init" should be private too.
Don't know why I forgot that.
Fixed.

> set pickedUnit = null
Not needed.
Oh :eek: .
Fixed.

> Casting range improves per level.
I'd suggest using a "range" function in that case.
Along with a "damage" function.
to give people an easy way to customize it.
I tried to do a function kind of thing for the damage but couldn't figure it out;
Still new to JASS :( .
Although the range can be customized in Object Editor itself :) !


UPDATE
Changelog
v1.0c
- Code cleanup
Thanks to AceHart
- Added condition to check if units alive
Prevents SFX from showing on dead units
 

WolfieeifloW

WEHZ Helper
Reaction score
372
I don't understand?
If you check the map, it works fine.
Level 1 makes you be closer then level 2 when you try to blink.
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
Well,
private constant integer BBAoEBB = 450
call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), BBAoEBB, ...

On an AoE spell, I expect to see that area when casting it.
Hence the need to set it in the Object Editor.
And I can edit that constant to fit.

However, what if I want a larger area per level?
Setting that in the OE is easy, but how would the trigger know what area to use?


So, something like
JASS:
private function GetAOE takes integer level returns real
    return R2I(level) * 50 + 300
endfunction

and
call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), GetAOE(level), ...

The function doesn't really need to use fancy math.
The basic if level == 1 then return 400 elseif level == ... will do just fine.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
I thought we were talking about casting range :p .
The AoE is for when the unit blinks back to his original position, not when he blinks to the target.
You don't get to see the AoE where units will be damaged, it's just around where you blinked from.
The skills not really meant to gain a larger AoE per level.
I can add that in I guess though.

EDIT: Error: Expected a name.
JASS:
private function GetAOE takes integer level returns real
    return R2I(level) * 50 + 300
endfunction   // Error on this line

JASS:
scope BlinkBack initializer Init

globals
    private constant integer ability_BBid = 'A000'
    // Raw code of 'Blink Back' ability
    
    private constant real BBDelay = 0.50
    // Delay for unit to blink back to original location (NOTE: This value is for level 1)
    
    private constant integer BBDmg = 50
    // Target damage (NOTE: This value is for level 1)
    
    private constant integer BBAOEDmg = 30
    // AoE damage (NOTE: This value if for level 1)
    
    //private constant integer BBAoEBB = 450
    // AoE damage gets dealt in
    
    private function GetAOE takes integer level returns real
        return R2I(level) * 50 + 300
    endfunction
    
    private constant string BBSFXStart = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    // Path for SFX when unit blinks to the target
    
    private constant string BBSFXEnd = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
    // Path for SFX when unit arrives at target    
    
    private constant string BBSFXBV = "Abilities\\Spells\\Orc\\AncestralSpirit\\AncestralSpiritCaster.mdl"
    // Path for SFX when unit arrives back at original location
    
    private constant string BBSFXAOE = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"
    // Path for SFX of units that get hit in the AoE
    
    private constant string SFXAP = "origin"
    // Attachment point for all above SFX
    
    private constant attacktype bbAttackType = ATTACK_TYPE_HERO
    // Attack type of Blink Back
    
    private constant damagetype bbDamageType = DAMAGE_TYPE_FIRE
    // Damage type of Blink Back
endglobals

private function BBConditions takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and IsUnitAliveBJ(GetFilterUnit())
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ability_BBid
endfunction

private function Actions takes nothing returns nothing
    local unit BBC = GetTriggerUnit()
    local unit BBT = GetSpellTargetUnit()
    local real BBCX = GetUnitX(BBC)
    local real BBCY = GetUnitY(BBC)
    local real BBTX = GetUnitX(BBT)
    local real BBTY = GetUnitY(BBT)
    local group BBAOE = CreateGroup()
    local unit pickedUnit
    local effect sfx
    set BBCX = GetUnitX(BBC)
    set BBCY = GetUnitY(BBC)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXStart, BBC, SFXAP))
    call PauseUnit(BBC, true)
    call SetUnitPosition(BBC, BBTX, BBTY)
    call PauseUnit(BBC, false)
    call UnitDamageTarget(BBC, BBT, (BBDmg * GetUnitAbilityLevel(BBC, ability_BBid)), true, true, bbAttackType, bbDamageType, WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXEnd, BBC, SFXAP))
    call TriggerSleepAction(GetUnitAbilityLevel(BBC, ability_BBid) * BBDelay)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXStart, BBC, SFXAP))
    call SetUnitPosition(BBC, BBCX, BBCY)
    //call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), BBAoEBB, Condition(function BBConditions))
    call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), GetAoE(level), Condition(function BBConditions))
    loop
        set pickedUnit = FirstOfGroup(BBAOE)
        exitwhen pickedUnit == null
            call UnitDamageTarget(BBC, pickedUnit, (GetUnitAbilityLevel(BBC, ability_BBid) * BBAOEDmg), true, true, bbAttackType, bbDamageType, WEAPON_TYPE_WHOKNOWS)
            call DestroyEffect(AddSpecialEffectTarget(BBSFXAOE, pickedUnit, SFXAP))
            call GroupRemoveUnit(BBAOE, pickedUnit)
    endloop
    set sfx = AddSpecialEffectTarget(BBSFXBV, BBC, SFXAP)
    call TriggerSleepAction(1.00)
    call DestroyEffect(sfx)
    call DestroyGroup(BBAOE)
    set BBAOE = null
    set BBT = null
    set BBC = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
endfunction

endscope
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
> return R2I(level) * 50 + 300

return I2R(level) * 50.0 + 300.0

> I thought we were talking about casting range

Same there.
If I wanted to put in my own range, where do I put that?
If I had a function though, GetRange... I'd still have to edit a function to fit my needs,
but that's still easier than trying to find out where the code is doing that.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Still the same error.

And the casting range can be changed in Object Editor.
Level # - Stats - Cast Range.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Even more errors, I suck at this :eek: .
Undeclared variable level
Undeclared function GetAoE
Cannot convert null to real
JASS:
scope BlinkBack initializer Init
globals
    private constant integer ability_BBid = 'A000'
    // Raw code of 'Blink Back' ability
    
    private constant real BBDelay = 0.50
    // Delay for unit to blink back to original location (NOTE: This value is for level 1)
    
    private constant integer BBDmg = 50
    // Target damage (NOTE: This value is for level 1)
    
    private constant integer BBAOEDmg = 30
    // AoE damage (NOTE: This value if for level 1)
    
    //private constant integer BBAoEBB = 450
    // AoE damage gets dealt in
    
    private constant string BBSFXStart = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    // Path for SFX when unit blinks to the target
    
    private constant string BBSFXEnd = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
    // Path for SFX when unit arrives at target    
    
    private constant string BBSFXBV = "Abilities\\Spells\\Orc\\AncestralSpirit\\AncestralSpiritCaster.mdl"
    // Path for SFX when unit arrives back at original location
    
    private constant string BBSFXAOE = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"
    // Path for SFX of units that get hit in the AoE
    
    private constant string SFXAP = "origin"
    // Attachment point for all above SFX
    
    private constant attacktype bbAttackType = ATTACK_TYPE_HERO
    // Attack type of Blink Back
    
    private constant damagetype bbDamageType = DAMAGE_TYPE_FIRE
    // Damage type of Blink Back
endglobals

    private function GetAOE takes integer level returns real
        return I2R(level) * 50.0 + 300.0
    endfunction

private function BBConditions takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and IsUnitAliveBJ(GetFilterUnit())
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ability_BBid
endfunction

private function Actions takes nothing returns nothing
    local unit BBC = GetTriggerUnit()
    local unit BBT = GetSpellTargetUnit()
    local real BBCX = GetUnitX(BBC)
    local real BBCY = GetUnitY(BBC)
    local real BBTX = GetUnitX(BBT)
    local real BBTY = GetUnitY(BBT)
    local group BBAOE = CreateGroup()
    local unit pickedUnit
    local effect sfx
    set BBCX = GetUnitX(BBC)
    set BBCY = GetUnitY(BBC)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXStart, BBC, SFXAP))
    call PauseUnit(BBC, true)
    call SetUnitPosition(BBC, BBTX, BBTY)
    call PauseUnit(BBC, false)
    call UnitDamageTarget(BBC, BBT, (BBDmg * GetUnitAbilityLevel(BBC, ability_BBid)), true, true, bbAttackType, bbDamageType, WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXEnd, BBC, SFXAP))
    call TriggerSleepAction(GetUnitAbilityLevel(BBC, ability_BBid) * BBDelay)
    call DestroyEffect(AddSpecialEffectTarget(BBSFXStart, BBC, SFXAP))
    call SetUnitPosition(BBC, BBCX, BBCY)
    //call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), BBAoEBB, Condition(function BBConditions))
    call GroupEnumUnitsInRange(BBAOE, GetUnitX(BBC), GetUnitY(BBC), GetAoE(level), Condition(function BBConditions))
    loop
        set pickedUnit = FirstOfGroup(BBAOE)
        exitwhen pickedUnit == null
            call UnitDamageTarget(BBC, pickedUnit, (GetUnitAbilityLevel(BBC, ability_BBid) * BBAOEDmg), true, true, bbAttackType, bbDamageType, WEAPON_TYPE_WHOKNOWS)
            call DestroyEffect(AddSpecialEffectTarget(BBSFXAOE, pickedUnit, SFXAP))
            call GroupRemoveUnit(BBAOE, pickedUnit)
    endloop
    set sfx = AddSpecialEffectTarget(BBSFXBV, BBC, SFXAP)
    call TriggerSleepAction(1.00)
    call DestroyEffect(sfx)
    call DestroyGroup(BBAOE)
    set BBAOE = null
    set BBT = null
    set BBC = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
endfunction

endscope
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
> GetAoE(level)

Level is not defined.
GetAoE(GetUnitAbilityLevel(BBC, ability_BBid))

Or store it in some variable:
local integer level = GetUnitAbilityLevel(BBC, ability_BBid)


And, JASS is case sensitive: AOE != AoE.
 

perkeyone

something clever
Reaction score
71
great work
maybe you could add some sort of timer to display how much blink time is left
you could use a generic expiration timer or replace the spell with a different one that does nothing and use it automatically to activate the cooldown just so it shows some sort of "this is how much time you have left until you return to the casting point"


edit: on second thought i think the timer would look funny and replacing it with a dummy ability might look odd
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Yeah, the "timer" would look weird (as we discussed) .
Thanks for the comment though!

Anyone else have any more comments/suggestions?
 

Lumograph090

New Member
Reaction score
22
Very cool ability. Effective for both defense on a fragile intellect based her and still usable for beefy tank heroes!
 

WolfieeifloW

WEHZ Helper
Reaction score
372
I think that would make it sort've bad.
The blink back part of it is a surprise kind of thing.
If enemies are running by and see a big "X" or whatever at the spot, they'll either;
Gather up and wait for the hero to blink back,
Or avoid that spot to not get damaged.

Oh yeah, bump :p .
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top