| 09-24-2006, 08:27 PM | #1 |
k, thought id try a simpler spell in Jass from my previous thread first :D 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 |
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: 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 |
hmmm I tried it, it doesnt work ;/ 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 | |
Quote:
Also, here's my version of the spell: 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 |
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 |
I tried your one wyrm> comes up expected a name on this line 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 |
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 |
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 |
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 |
use Filter 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 |
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 |
Oops! Change it too: 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 |
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 |
try this 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 |
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 |
