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.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      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