Spell Temporal Vortex

BlackRose

Forum User
Reaction score
239
Dragon Lance -- Random REP to me? Thanks :)

WolfieNoCT --

call SetUnitPositionLoc(aTV, PolarProjectionBJ(atTV, I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance, GetRandomReal(0.00, 360.00)))

It's a leak isn't it?
 
Reaction score
341
JASS:
local unit dBU


Can become

JASS:
local unit dbU  = CreateUnit(GetOwningPlayer(tvaU), dummyBuffer, tvaX, tvaY, GetUnitFacing(tvaU))


Just remove the set dbU line.

JASS:
call TriggerSleepAction(loopSFXTime)


ew, inaccurate waits, why not setup some timer.

And you also have an unneeded BJ.

JASS:
call SetUnitPositionLoc(aTV, PolarProjectionBJ(atTV, I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance, GetRandomReal(0.00, 360.00)))


to fix that just do something like...

JASS:
    if GetUnitAbilityLevel(aTV, buff_TVDBid) < 1 then
        if GetUnitAbilityLevel(tTV, buff_TVBid) > 0 then
            set ddbU = CreateUnit(GetOwningPlayer(tTV), dummyCaster, aTVX, aTVY, GetUnitFacing(aTV))
            call SetUnitAbilityLevel(ddbU, ability_TVDBid, GetUnitAbilityLevel(tTV, ability_TVid))
            call IssueTargetOrder(ddbU, dbTry, aTV)
            call UnitApplyTimedLife(ddbU, 'BTLF', 1.00)
            call DestroyEffect(AddSpecialEffectTarget(offEffect, tTV, offAttachPoint))
            call DestroyEffect(AddSpecialEffectLoc(startEffect, atTV))
            set x = aTVY + (I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance) * Cos(GetRandomReal(0.00, 360.00) * bj_DEGTORAD)
            set y = aTVY + (I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance) * Sin(GetRandomReal(0.00, 360.00) * bj_DEGTORAD)
            call SetUnitPosition(aTV, x, y)
            call DestroyEffect(AddSpecialEffectTarget(endEffect, aTV, attachPoint))
            call RemoveLocation(atTV)
        endif
    endif


did it pretty quick so not sure if thats the correct facing angle you wanted it.

If not, then sorry :p

Now your init trigger could be simplified like...

JASS:
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(t, Condition(function TVAConditions))
    call TriggerAddAction(t, function TVAActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function TVConditions))
    call TriggerAddAction(t, function TVActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(TVRtrig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(t, Condition(function TVRConditions))
    call TriggerAddAction(t, function TVRActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(TRYtrig, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(t, Condition(function TRYConditions))
    call TriggerAddAction(t, function TRYActions)
endfunction


Though thats only a personal choice.

JASS:
scope TemporalVortex initializer Init

// +-------------------------------------+
// |       -=-=- MODIFY HERE -=-=-       |
// |       -=-=- MODIFY HERE -=-=-       |
// |       -=-=- MODIFY HERE -=-=-       |
// +-------------------------------------+

globals
    private constant integer ability_TVid = 'A001'
    // Raw code of 'Temporal Vortex' ability
    
    private constant integer ability_TVDBid = 'A002'
    // Raw code of 'Temporal Vortex (Debuff)' ability
    
    private constant integer buff_TVBid = 'B000'
    // Raw code of 'Temporal Vortex (Buff)' buff
    
    private constant integer buff_TVDBid = 'B001'
    // Raw code of 'Temporal Vortex (Debuff)' buff
    
    private constant integer dummyCaster = 'n000'
    // Raw code of 'DummyCaster' unit
    
    private constant integer dummyBuffer = 'n001'
    // Raw code of 'DummyBuffer' unit
    
    private constant integer tvMin = 1
    // Minimum for vortex chance
                        // I recommend leaving these two at '1' and '100'
    private constant integer tvMax = 100
    // Maximum for vortex chance
    
    private constant integer tvChance = 100
    // Chance to cast Temporal Vortex (0-100) (NOTE: This value is for level 1)
    // This value will double for each level
    // So if you set it to 25, the chances would be 25/50/75/100
    // Set it to 15, chances would be 15/30/45/60
    
    private constant string startEffect = "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    // Path for SFX when the unit starts to teleport
    
    private constant string endEffect = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
    // Path for SFX when the unit finished teleporting
    
    private constant string attachPoint = "origin"
    // Attachment point of the above SFX
    
    private constant string offEffect = "Abilities\\Weapons\\GyroCopter\\GyroCopterImpact.mdl"
    // Path for SFX above attacked unit when Temporal Vortex goes off
    
    private constant string offAttachPoint = "overhead"
    // Attachment point of the above SFX
    
    private constant string auraEffect = "Abilities\\Weapons\\GyroCopter\\GyroCopterImpact.mdl"
    // Path for SFX at units feet when Temporal Vortex is on
    
    private constant real teleDistance = 125.00
    // Distance the attacking unit teleports
    // This value will double for each level
    // So if you set this to 200, the distance would be 200/400/600/800
    // Set it to 75, distance would be 75/150/225/300
    
    private constant string tvOn = "innerfireon"
    // 'Order String Activate' for 'Temporal Vortex' ability
    
    private constant string tvOff = "innerfireoff"
    // 'Order String Deactivate for 'Temporal Vortex' ability
    
    private constant string tvTry = "innerfire"
    // 'Order String Use/Turn On' for 'Temporal Vortex' and 'Temporal Vortex (Buff)' abilities
    
    private constant string dbTry = "slow"
    // 'Order String Use/Turn On' for 'Temporal Vortex (Debuff)' ability
    
    private constant real loopSFXTime = 1.50
    // Time to wait in between the Temporal Vortex SFX at units feet spawning
endglobals

// +----------------------------------------------+
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// +----------------------------------------------+

private function TVAConditions takes nothing returns boolean
    return GetIssuedOrderId() == OrderId(tvOn)
endfunction

private function TVAActions takes nothing returns nothing
    local unit tvaU = GetTriggerUnit()
    local real tvaX = GetUnitX(tvaU)
    local real tvaY = GetUnitY(tvaU)
    local unit dbU  = CreateUnit(GetOwningPlayer(tvaU), dummyBuffer, tvaX, tvaY, GetUnitFacing(tvaU))
    call IssueTargetOrder(dbU, tvTry, tvaU)
    call UnitApplyTimedLife(dbU, 'BTLF', 1.00)
    loop
        exitwhen GetUnitAbilityLevel(tvaU, buff_TVBid) < 1
            call DestroyEffect(AddSpecialEffectTarget(auraEffect, tvaU, attachPoint))
            call TriggerSleepAction(loopSFXTime)
    endloop
    set dbU = null
    set tvaU = null
endfunction

private function TVConditions takes nothing returns boolean
    return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetAttacker())) and GetRandomInt(tvMin, tvMax) <= tvChance * GetUnitAbilityLevel(GetTriggerUnit(), ability_TVid) and GetUnitAbilityLevel(GetTriggerUnit(), ability_TVid) > 0
endfunction

private function TVActions takes nothing returns nothing
    local unit tTV = GetTriggerUnit()
    local unit aTV = GetAttacker()
    local location atTV = GetUnitLoc(aTV)
    local real aTVX = GetUnitX(aTV)
    local real aTVY = GetUnitY(aTV)
    local unit ddbU
    local real x
    local real y
    
    if GetUnitAbilityLevel(aTV, buff_TVDBid) < 1 then
        if GetUnitAbilityLevel(tTV, buff_TVBid) > 0 then
            set ddbU = CreateUnit(GetOwningPlayer(tTV), dummyCaster, aTVX, aTVY, GetUnitFacing(aTV))
            call SetUnitAbilityLevel(ddbU, ability_TVDBid, GetUnitAbilityLevel(tTV, ability_TVid))
            call IssueTargetOrder(ddbU, dbTry, aTV)
            call UnitApplyTimedLife(ddbU, 'BTLF', 1.00)
            call DestroyEffect(AddSpecialEffectTarget(offEffect, tTV, offAttachPoint))
            call DestroyEffect(AddSpecialEffectLoc(startEffect, atTV))
            set x = aTVY + (I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance) * Cos(GetRandomReal(0.00, 360.00) * bj_DEGTORAD)
            set y = aTVY + (I2R(GetUnitAbilityLevel(tTV, ability_TVid)) * teleDistance) * Sin(GetRandomReal(0.00, 360.00) * bj_DEGTORAD)
            call SetUnitPosition(aTV, x, y)
            call DestroyEffect(AddSpecialEffectTarget(endEffect, aTV, attachPoint))
            call RemoveLocation(atTV)
        endif
    endif
    set ddbU = null
    set aTV = null
    set tTV = null
endfunction

private function TVRConditions takes nothing returns boolean
    return GetIssuedOrderId() == OrderId(tvOff)
endfunction

private function TVRActions takes nothing returns nothing
    local unit tvrU = GetTriggerUnit()
    call UnitRemoveAbility(tvrU, buff_TVBid)
    set tvrU = null
endfunction

private function TRYConditions takes nothing returns boolean
    return GetSpellAbilityId() == ability_TVid
endfunction

private function TRYActions takes nothing returns nothing
    local unit tryU = GetTriggerUnit()
    call IssueImmediateOrder(tryU, "stop")
    call TriggerSleepAction(0.01)
    call SetUnitAnimation(tryU, "walk")
    set tryU = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(t, Condition(function TVAConditions))
    call TriggerAddAction(t, function TVAActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(t, Condition(function TVConditions))
    call TriggerAddAction(t, function TVActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(TVRtrig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(t, Condition(function TVRConditions))
    call TriggerAddAction(t, function TVRActions)
    
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(TRYtrig, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(t, Condition(function TRYConditions))
    call TriggerAddAction(t, function TRYActions)
endfunction

endscope
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Can become
Should've noticed that, thanks.

ew, inaccurate waits, why not setup some timer.
  1. I don't know how to use systems yet
  2. It's just a loop for an SFX, doesn't really matter if it's off

And you also have an unneeded BJ.
to fix that just do something like...
did it pretty quick so not sure if thats the correct facing angle you wanted it.
If not, then sorry :p
I didn't know how to use all those, thanks for fixing that.

Now your init trigger could be simplified like...
Though thats only a personal choice.
I think I'll keep it the way I have it;
Personal choice for me ;) !

Thank you for fixing all of that;
I put credits to you in changelog.


UPDATE
Changelog
v1.3
- Fixed up code
Credits to 'TriggerHappy'
 

Magoiche

Member
Reaction score
20
Cool spell.
But as kirbyman said it need more eyecandness!

You can attach a effect on the chest of the teleported unit before it teleports.
When it reaches the destination you destroy it.
The effect must be something like Phoenix Fire effect.

Good Job.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Cool spell.
But as kirbyman said it need more eyecandness!

You can attach a effect on the chest of the teleported unit before it teleports.
When it reaches the destination you destroy it.
The effect must be something like Phoenix Fire effect.

Good Job.
Read these:
Too much eye-candy is actually a bad thing, IMO.
That's a matter of opinion how much/how little SFX there should be.
I feel too much makes the spell feel like an ultimate.
The SFX are customizable to make them bigger/better SFX if you want :) .
I don't want to add more eye-candy as I don't want to make the spell look like an ultimate ;) !
And as I've said before, the SFX used are customizable;
So you can change them to a bigger/better SFX to achieve more eye-candy if so desired.
;) .

Anymore comments/suggestions, not relating to SFX :p ?
 

Magoiche

Member
Reaction score
20
Why overpowered? i.i

Ok. Ok.

Just add a chance that the attacking unit changes place with the near unit that have the lowest HP.

This can't be overpowred!...(I think) u.u
 

marvey323

Member
Reaction score
1
When I copy/paste your trigger into my map why do I get these errors after i enable the trigger ??

Line 93: Expected end of line
Line 103: Expected a reserve type or handle type
Line 106: Expected a reserve type or handle type
Line 107: Expected a reserve type or handle type
Line 109: Expected a reserve type or handle type
Line 112: Expected a reserve type or handle type
..
.
..

.
. and it goes on like this... at least another 50 lines
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
591
JASS:
scope TemporalVortex initializer Init


Uses vJass, you need a vJass pre-processor. New Gen is the most popular.
 

Romek

Super Moderator
Reaction score
963
> -Insanely customizable
Comes standard with Jass

> -vJASS
And this is a pro.. How?

JASS:
private function TVRActions takes nothing returns nothing
    local unit tvrU = GetTriggerUnit()
    call UnitRemoveAbility(tvrU, buff_TVBid)
    set tvrU = null
endfunction

Should be:
JASS:
private function TVRActions takes nothing returns nothing
    call UnitRemoveAbility(GetTriggerUnit(), buff_TVBid)
endfunction


Haven't looked through the code in detail yet.

Edit:
JASS:
private function Init takes nothing returns nothing
    local trigger TVAtrig = CreateTrigger()
    local trigger TVtrig = CreateTrigger()
    local trigger TVRtrig = CreateTrigger()
    local trigger TRYtrig = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(TVAtrig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(TVAtrig, Condition(function TVAConditions))
    call TriggerAddAction(TVAtrig, function TVAActions)
    
    call TriggerRegisterAnyUnitEventBJ(TVtrig, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(TVtrig, Condition(function TVConditions))
    call TriggerAddAction(TVtrig, function TVActions)
    
    call TriggerRegisterAnyUnitEventBJ(TVRtrig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(TVRtrig, Condition(function TVRConditions))
    call TriggerAddAction(TVRtrig, function TVRActions)
    
    call TriggerRegisterAnyUnitEventBJ(TRYtrig, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(TRYtrig, Condition(function TRYConditions))
    call TriggerAddAction(TRYtrig, function TRYActions)
endfunction

Could become:
JASS:
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(trig, Condition(function TVAConditions))
    call TriggerAddAction(trig, function TVAActions)
    
    set trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(trig, Condition(function TVConditions))
    call TriggerAddAction(trig, function TVActions)
    
    set trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    call TriggerAddCondition(trig, Condition(function TVRConditions))
    call TriggerAddAction(trig, function TVRActions)
    
    set trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(trig, Condition(function TRYConditions))
    call TriggerAddAction(trig, function TRYActions)
endfunction
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Comes standard with Jass
I've looked at lots of spells and (some) don't offer the customization to the extent my spell does.

And this is a pro.. How?
I'll remove that ;) .

Also, fixed the code improvements you listed.

Looks to mee like the dota spell "Greater Bash" rip off.
How so :confused: ?
That spell bashes, deals damage, slides units.
This spell doesn't do any of those.


UPDATE
v1.4 released with a new subskill!
So now when you learn Temporal Vortex, you get "Temporal Vortex (Defense)" and "Temporal Vortex (Offense)"
Learn Temporal Vortex]Temporal Vortex comes as two subskills: [COLOR="DarkOrange said:
Defense:[/COLOR] Causes attackers to have a chance to randomly teleport away from this Hero. Teleported units cannot be affected by the vortex again for a certain period.
Level 1 - 3% chance, 150 units away, 5 second debuff.
Level 2 - 6% chance, 300 units away, 4 second debuff.
Level 3 - 9% chance, 450 units away, 3 second debuff.
Level 4 - 12% chance, 600 units away, 2 second debuff.

Offense: Every 3 seconds, units are randomly chosen in a 600 AoE around the Hero. These chosen units are pulled into the Hero.
Level 1 - 7% chance, pulls 1 unit.
Level 2 - 14% chance, pulls up to 2 units.
Level 3 - 21% chance, pulls up to 3 units.
Level 4 - 28% chance, pulls up to 4 units.
Changelog
v1.4
- Fixed up code more
- Added new subskill
Temporal Vortex (Offense)
 

lindenkron

You can change this now in User CP
Reaction score
102
Nice nice, like the new offensive spell as well.

Even though, considder making it enemy units only? Pulling your own units to you is quiet useless? :rolleyes:

Also, what is it that over-rules the "Hold" function? Was quiet annoying that my hero ignored the hold when I wanted to test the offensive function.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Nice nice, like the new offensive spell as well.
Thanks :) !

Even though, considder making it enemy units only? Pulling your own units to you is quiet useless? :rolleyes:
In the next version I'll implement it only pulling enemies.
And there could be a couple useful situations ;) !

Also, what is it that over-rules the "Hold" function? Was quiet annoying that my hero ignored the hold when I wanted to test the offensive function.
Discussed, fixed.


UPDATE
Changelog
v1.4b
- Fixed bug with hero stopping instead of holding
- Fixed spells to make them uncastable
 

Flare

Stops copies me!
Reaction score
662
JASS:
    local group offGroup = GetRandomSubGroup(GetUnitAbilityLevel(offtTV, ability_OFFTVid), GetUnitsInRangeOfLocAll(pullRange, GetUnitLoc(offtTV)))

Multiple leaks
1) GetUnitsInRangeOfLocAll not set to a variable
2) Enumerating function with a null boolexpr leaks IIRC (check the Function List and you'll see it)
3) GetUnitLoc

JASS:
//In OffTVActions
        call GroupClear(offGroup)
        call DestroyGroup(offGroup)

That GroupClear is unnecessary - group is going to be destroyed anyway, why spend time emptying it

Also, move those leak-removing/nulling stuff outside the if's - if these conditions aren't met
JASS:
if GetRandomInt(OFFMin, OFFMax) <= OFFChance * GetUnitAbilityLevel(offtTV, ability_OFFTVid) then

You're leaking the group, location and some handles

Code:
                loop
                    set pickedUnit = FirstOfGroup(offGroup)
                    exitwhen pickedUnit == null
                        set pickedUnit = FirstOfGroup(offGroup)
                        call DestroyEffect(AddSpecialEffectTarget(pullStart, pickedUnit, startAttach))
                        call SetUnitPosition(pickedUnit, tTVX, tTVY)
                        call DestroyEffect(AddSpecialEffectTarget(pullEnd, pickedUnit, endAttach))
                        call GroupRemoveUnit(offGroup, pickedUnit)
                        set pickedUnit = null
                    [COLOR="Red"]set i = i + 1[/COLOR]
                endloop
What's the point of the integer? I can't see anything else using it

JASS:
    private constant integer tvMin = 1
    // Minimum for vortex chance (defense)
                        // I recommend leaving these two at '1' and '100'
    private constant integer tvMax = 100
    // Maximum for vortex chance (defense)

Why? Quite pointless to have those there, nobody needs to modify them anyway

JASS:
    private constant integer tvChance = 3
    // Chance to cast Temporal Vortex (Defense) (0-100) (NOTE: This value is for level 1)
    // This value will double for each level
    // So if you set it to 25, the chances would be 25/50/75/100
    // Set it to 15, chances would be 15/30/45/60

Why not make that into a formula function, rather than restricting it to a multiplier of ability level e.g.
JASS:
function GetChance takes integer stat returns nothing
  return 5 + stat * 5
endfunction

and let people devise their own method of determining the % chance
 
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