HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Omnislash - in Jass

09-24-2006, 08:27 PM#1
Fulla
k, thought id try a simpler spell in Jass from my previous thread first :D

Collapse JASS:
function Trig_Omnislash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A077'
endfunction


function Trig_Omnislash_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit t
    local integer i = 0
    call SetUnitInvulnerable( u, true )
    loop
        exitwhen i == 5
        set t = GroupPickRandomUnit(GetUnitsInRangeOfLocAll(500.00, GetUnitLoc(u)))
        call SetUnitPositionLoc( u, GetUnitLoc(t))
        set i = i + 1
        call TriggerSleepAction( 0.80 )
    endloop
    call SetUnitInvulnerable( u, false )
endfunction

//===========================================================================
function InitTrig_Omnislash takes nothing returns nothing
    set gg_trg_Omnislash = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Omnislash, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Omnislash, Condition( function Trig_Omnislash_Conditions ) )
    call TriggerAddAction( gg_trg_Omnislash, function Trig_Omnislash_Actions )
endfunction

Im not sure how to add condition in selecting random unit.

- Is owned of u enemy of owner of random unit
- Is random unit alive

thx for any help
Fulla
09-24-2006, 08:46 PM#2
The)TideHunter(
Well, create a group, add all units in range of 500, remove all units not matching the condition, get a random unit from the remaining units, like this:

Collapse JASS:
function Trig_Omnislash_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit t
    local integer i = 0
    local group g = CreateGroup()
    local group ta = CreateGroup()
    local location uloc = GetUnitLoc(u)
    local location tloc
    call SetUnitInvulnerable(u, true)
    loop
        exitwhen i == 5
        set g = GetUnitsInRangeOfLocAll(500.00, uloc)
        loop
            set t = FirstOfGroup(g)
            exitwhen t==null
            if(GetWidgetLife(t) < 0.305 and IsUnitEnemy(u, GetOwningPlayer(t))) then
                call GroupAddUnit(ta, t)
            endif
            call GroupRemoveUnit(g, t)
        endloop
        set t = GroupPickRandomUnit(ta)        
        call SetUnitPositionLoc(u, tloc)
        set i = i + 1
        call TriggerSleepAction(0.80)
    endloop
    call SetUnitInvulnerable(u, false)
    call DestroyGroup(g)
    call DestroyGroup(ta)
    call RemoveLocation(tloc)
    call RemoveLocation(uloc)
    set u = null
    set t = null
    set g = null
    set ta = null
    set tloc = null
    set uloc = null
endfunction

Well, i hope that works, it should.
EDIT: Some locations are leaked, i fixed them.
09-24-2006, 10:08 PM#3
Fulla
hmmm I tried it, it doesnt work ;/


Collapse JASS:
call SetUnitPositionLoc(u, tloc)

Hmm I cant see where your are setting the location tloc?
Is it not just null through out trigger?
09-24-2006, 10:24 PM#4
wyrmlord
Quote:
Originally Posted by The)TideHunter(
Collapse JASS:
[b]if(GetWidgetLife(t) < 0.305[/b] and IsUnitEnemy(u, GetOwningPlayer(t))) then
There's your problem, it won't be adding units to the group unless their life is less than .305, I think TideHunter meant it to be if(GetWidgetLife(t) > 0.305...
Also, here's my version of the spell:
Collapse JASS:
function Omnislash takes nothing returns nothing
 local unit caster = GetTriggerUnit()
 local group g = CreateGroup()
 local unit p
 local integer i = 0
    call GroupEnumUnitsInRange(g, GetUnitX(caster), GetUnitY(caster), 500, null)
    call SetUnitInvulnerable(caster, true)
    loop
        set p = FirstOfGroup(g)
        exitwhen p == null or i == 5
        if IsUnitEnemy(p, GetOwningPlayer(caster)) and GetWidgetLife(p) > .305 then
            call SetUnitPosition(caster, GetUnitX(p), GetUnitY(p))
            set i = i + 1
            call TriggerSleepAction(.8)
        endif
        call GroupRemoveUnit(g, p)
    endloop
    call DestroyGroup(g)
    call SetUnitInvulnerable(caster, false)
 set caster = null
 set g = null
 set p = null
endfunction
09-24-2006, 10:32 PM#5
Rising_Dusk
I recommend using a timer and running through that instead of using a loop.
As suggested by the others in this thread, your caster will all in a single instant hit every single unit.

If you ran it through a timer (0.2 intervalish) and do the omnislash effect in the callback, then it would look visually more appealing in game.
Just a suggestion though.
09-24-2006, 11:09 PM#6
Fulla
I tried your one wyrm>

comes up expected a name on this line
Collapse JASS:
call GroupEnumUnitsInRange(g, GetUnitX(caster), GetUnity(caster), 500, null)

@Dusk, theres a 0.80 second wait in the loop so it shouldnt happen all at same time?

Is a timer more efficient then? Id prefably like to learn the most efficient method.
09-24-2006, 11:27 PM#7
Rising_Dusk
A timer is always the best option, but requires slightly more work.
If you dont care about accuracy then a wait will suffice.

And in Wyrm's code, "GetUnity" should be "GetUnitY".
09-25-2006, 02:46 AM#8
The_AwaKening
In something like omnislash, a timer is unnecessary. TriggerSleepAction should suffice since it is only for looks really.

If you can't get yours working right, I already have an omnislash trigger built in JASS with 0 globals. Very easy to change to your liking. Let me know if you need and I will share it.
09-25-2006, 03:08 AM#9
Rising_Dusk
In my opinion, timers add professionalism to skills.
Especially since TriggerSleeps are so innaccurate it's miserable.

But whatever, matter of preference. :P
09-25-2006, 03:49 AM#10
DotA_DR
use Filter

Collapse JASS:

function FilterEnemy takes nothing returns boolean
   return IsUnitEnemy(GetFilterUnit(), udg_tempplayer)
endfunction

...
set udg_tempplayer = GetOwningPlayer(caster)
// not add between this line Sleep and IssueOrder action
call GroupEnumUnitsInRange(g, GetUnitX(caster), GetUnity(caster), 500, Filter(function FilterEnemy))
set udg_tempplayer = null
...

g group would contain enemy units in range 500
09-25-2006, 04:46 AM#11
The_AwaKening
Correct me if I'm wrong, but I believe GetWidgetLife(p)>0.305 should be GetWidgetLife(p)>0.405
09-25-2006, 06:54 AM#12
The)TideHunter(
Oops!
Change it too:

Collapse JASS:
function Trig_Omnislash_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit t
    local integer i = 0
    local group g = CreateGroup()
    local group ta = CreateGroup()
    local location uloc = GetUnitLoc(u)
    local location tloc
    call SetUnitInvulnerable(u, true)
    loop
        exitwhen i == 5
        set g = GetUnitsInRangeOfLocAll(500.00, uloc)
        loop
            set t = FirstOfGroup(g)
            exitwhen t==null
            if(GetWidgetLife(t) > 0.305 and IsUnitEnemy(u, GetOwningPlayer(t))) then
                call GroupAddUnit(ta, t)
            endif
            call GroupRemoveUnit(g, t)
        endloop
        set t = GroupPickRandomUnit(ta)
        set tloc = GetUnitLoc(t)        
        call SetUnitPositionLoc(u, tloc)
        call RemoveLocation(tloc)
        set i = i + 1
        call TriggerSleepAction(0.80)
    endloop
    call SetUnitInvulnerable(u, false)
    call DestroyGroup(g)
    call DestroyGroup(ta)
    call RemoveLocation(uloc)
    set u = null
    set t = null
    set g = null
    set ta = null
    set tloc = null
    set uloc = null
endfunction

Try that.
09-25-2006, 07:07 AM#13
Anitarf
wyrmlord's code is considerably shorter, but it works a bit differently, it never picks the same target twice, which you may or may not want. The)TideHunter('s code gets a new unit group for each attack so it allows the hero to "follow" a line of enemy units while wyrmlord's will only jump between the targets in the initial AoE of the spell.

The)TideHunter(, GetUnitsInRangeOfLocAll() calls GetUnitsInRangeOfLocMatching() which creates it's own unit group *cough*and has a not set to null leak*cough*, so you shouldn't initialize g when you declare it and you should destroy it within the loop.
09-25-2006, 07:49 AM#14
DotA_DR
try this
Collapse JASS:
function Trig_Omnislash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A077'
endfunction

function FilterAliveEnemy takes nothing returns boolean
    return (not IsUnitDeadBJ(GetEnumUnit())) and (IsUnitEnemy(GetEnumUnit(), udg_tempplayer))
endfunction

function Trig_Omnislash_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local unit Target
    local player Owner = GetOwningPlayer(Caster)
    local group Targets = CreateGroup()
    local integer Index = 0
    call PauseUnit(Caster, IsUnitPaused(Caster)) // to prevent reset cooldown bug, need test, usually use TriggerSleepAction(0)
    call SetUnitInvulnerable(Caster, true)
    loop
        set udg_tempplayer = Owner
        call GroupEnumUnitsInRange(Targets, GetUnitX(Caster), GetUnitY(Caster), 500, Filter(function FilterAliveEnemy)) // select alive emeny units in range 500
        set udg_tempplayer = null
        set Target = GroupPickRandomUnit(Targets) // select random units
        exitwhen Target == null // exit if nobody near
        call SetUnitPosition(Caster, GetUnitX(Target), GetUnitY(Targer)) // move to Target
        exitwhen Index == 4 // do 5 times 0, 1, 2, 3, 4
        set Index = Index + 1
        call TriggerSleepAction(0.80)
    endloop
    call SetUnitInvulnerable(Caster, false)
    call DestroyGroup(Targets)
    set Caster = null
    set Target = null
    set Targets = null
endfunction

//===========================================================================
function InitTrig_Omnislash takes nothing returns nothing
    set gg_trg_Omnislash = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Omnislash, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Omnislash, Condition( function Trig_Omnislash_Conditions ) )
    call TriggerAddAction( gg_trg_Omnislash, function Trig_Omnislash_Actions )
endfunction
09-25-2006, 08:46 AM#15
Fulla
Ok, both Wyrmlords / Tidehunters methods worked fine.
Tidehunters method would be prefable as its possible to cast the spell on a single unit? If it cant teleport hero to same unit twice.

This 'cooldown' bug yea it comes up, a hero could cast it non stop, assuming he had the mana?
@Dota_Dr your using Globals? would that not make it multi-instanceable?

thx