• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] How to find units between points?

Status
Not open for further replies.
Level 3
Joined
Jun 14, 2007
Messages
56
Trying to code a manual swing sword. Point targeted.

What i do is:
-I use (GroupEnumUnitsInRangeOfLoc) to Group the units within 50 range of a polar projected point towards the cast location.
-I loop this so the location groups units at small sections at a time, with projected point getting further from caster each loop. stops when distance = 200
-then i execute functions for the units in that group (loop FirstOfGroup etc) so that all units in the group are hit



It works on occasion, but it isnt very effective, usually misses grouping the units it should have hit.


















For those who want to see the code.
Code:
Function ExecuteSwingSword takes nothing returns nothing
local unit c = GetTriggerUnit()
local real a = AngleBetweenPoints(GetUnitLoc(c),  GetSpellTargetLoc())
local real distance = 0
local group g = CreateGroup()
local location loc
local unit f
local location p = GetUnitLoc(c)
call TriggerSleepAction(0.1) // animation hits after 0.1 seconds
loop
exitwhen distance >= 200
set distance = distance + 20
set loc = PolarProjectionBJ(p, distance, a)
call GroupEnumUnitsInRangeOfLoc(g, loc, 100, null)
endloop
loop
set f = FirstOfGroup(g)
exitwhen f == null
call GroupRemoveUnit(g, f)
<<damage / knockback functions>>
endloop
endfunction



trying to get an accurate projection of a forwards blade swing, and make sure units that should be hit (even right next to the blademaster, but not behind) are getting hit!

It just seems to be missing, and doesnt really hit in the immediate. is there a more effective way of doing this?
 
Level 3
Joined
Jun 14, 2007
Messages
56
for those who still need this answer solved, just copy this function into your map and call it with the parameters indicated. you can set the 2 points to group between and the width of the grouping

Code:
function GroupEnumUnitsInLine takes group g, real x1, real y1, real x2, real y2, real width returns nothing
    local real angle = Atan2(y2-y1,x2-x1)
    local real dist = SquareRoot( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) )
    local real cdist = 0
    local group temp
    loop
        exitwhen (cdist > dist)
        set temp = CreateGroup()
        call GroupEnumUnitsInRange(temp,x1,y1,width/2,null)
        set bj_wantDestroyGroup = true
        call GroupAddGroup(temp,g)
        set x1 = x1+((width/4)*Cos(angle))
        set y1 = y1+((width/4)*Sin(angle))
        set cdist = cdist + (width/4)
    endloop
    set temp = null
endfunction
 
Level 9
Joined
Apr 5, 2008
Messages
529
Your problem is the loops you have, you should nest the unit one in the group one like this:

JASS:
Function ExecuteSwingSword takes nothing returns nothing
  local unit c = GetTriggerUnit()
  local real a = AngleBetweenPoints(GetUnitLoc(c),  GetSpellTargetLoc())
  local real distance = 0
  local group g = CreateGroup()
  local location loc
  local unit f
  local location p = GetUnitLoc(c)
  call TriggerSleepAction(0.1) // animation hits after 0.1 seconds

  loop
  exitwhen distance >= 200
   set loc = PolarProjectionBJ(p, distance, a)
   call GroupEnumUnitsInRangeOfLoc(g, loc, 100, null)
    loop
    set f = FirstOfGroup(g)
    exitwhen f == null
     <<damage / knockback functions>>
     call GroupRemoveUnit(g, f)
   endloop
  set distance = distance + 20
  endloop

  //You should probably also remove the leaks
 call RemoveLocation(loc)
 call RemoveLocation(p)
 set p = null
 set loc = null
 set c = null
 call DestroyGroup(g)
 set g = null
endfunction

And TriggerSleepAction is evil, learn to use timers.
 
Status
Not open for further replies.
Top