1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The reforging of the races is complete. Come see the 14th Techtree Contest Results.
    Dismiss Notice
  4. It's time to choose your horse in the race - the 32nd Modeling Contest Poll is up!
    Dismiss Notice
  5. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Damage in a line

Discussion in 'World Editor Help Zone' started by GangSpear, Jul 29, 2011.

  1. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    How can i damage units in a line? Like shockwave,but this is loop.
    I WANT GUI,NOT JASS :p
    +REP :goblin_boom:
    EDIT: Daelin's Creating a line,that not damaging :p
    EDIT 2: i want to use Pick every unit in (Unit within XXX range of XXXXXX point)
     
  2. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,476
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    basically you do this buy picking all units in a rect around that line (black rect) and then testing whether or not unit u is in that line-area(blue rect)
    [​IMG]

    A possible more performant type of checking would to only group all units in a few rects, leaving out many units to test.

    [​IMG]

    I only got the jass function right now...i Guess it would be kinda ugly in GUI, I suppose you use the JNGP allready, why not pasting it into the map header and using a custom script?

    code

    Code (vJASS):
    library groupaddunitsnearline

    globals
        //upper bound for the collision size of units
        private constant real MAX_COLLISSION = 128.
        //this is aproximately how much space of the rects is used by the line
        //a higher value yields less unnecessary checks but also more rects
        private constant real desiredefficiency = 0.6
       
        //---
        private rect temprect = Rect(0,0,0,0)
        private group tempenumgroup = CreateGroup()
        private group tempgroup
        private real temppx
        private real temppy
        private real tempdnx
        private real tempdny
        private real tempwidth
        private real tempd
    endglobals


    //returns the maximum of 4 reals
    private function max4 takes real a, real b, real c, real d returns real
        local real max = a
        if b > max then
            set max = b
        endif
        if c > max then
            set max = c
        endif
        if d > max then
            set max = d
        endif
        return max
    endfunction

    //returns the minimum of 4 reals
    private function min4 takes real a, real b, real c, real d returns real
        local real min = a
        if b < min then
            set min = b
        endif
        if c < min then
            set min = c
        endif
        if d < min then
            set min = d
        endif
        return min
    endfunction

    private function Add takes nothing returns boolean
        //position of unit
        local real x = GetUnitX(GetFilterUnit())
        local real y = GetUnitY(GetFilterUnit())
        //vector from the beginning of the line to the unit
        local real dx = x - temppx
        local real dy = y - temppy
        //distance from the beginning of the line to that point on the line which is closest to the unit (uses dot-product)
        local real d = dx * tempdnx + dy * tempdny
        local real cx
        local real cy
        //cut off points outside the line
        if d <= 0 then
            set d = 0
        elseif d >= tempd then
            set d = tempd
        endif
        //the closest point to the unit on the line
        set cx = temppx + d * tempdnx
        set cy = temppy + d * tempdny

        if IsUnitInRangeXY(GetFilterUnit(), cx, cy, tempwidth) then
            call GroupAddUnit(tempgroup, GetFilterUnit())
        endif
        return false
    endfunction

    function GroupAddUnitsNearLine takes group g, real px, real py, real qx, real qy, real width returns nothing
        //the line width width
        local real l1x
        local real l1y
        local real l2x
        local real l2y
        local real l3x
        local real l3y
        local real l4x
        local real l4y
        //d = from p to q
        local real dx = qx - px
        local real dy = qy - py
        local real dlen = SquareRoot(dx*dx + dy*dy)
        //normalized d
        local real dxn = dx / dlen
        local real dyn = dy / dlen
        //divisions
        local integer divisions = 1
        //bonus for correct overlapping of rects
        local real bonusx = 0.
        local real bonusy = 0.
        //integer for loop    
        local integer i
        //the outer rect
        local real rectminx
        local real rectmaxx
        local real rectminy
        local real rectmaxy
       
       
        set width = width + MAX_COLLISSION
       
        //calculate the number of divisions needed to approximately match desiredefficiency
        if dx != 0 and dy != 0 then
            set divisions = 1 + R2I(SquareRoot(desiredefficiency*desiredefficiency / (width*width/(dx*dx) + width*width/(dy*dy))))  
        endif
       
        //this calculates a bonus so that there are intersections between the different rects
        //(without this we would miss some units between the rects)
        if dy != 0 and divisions > 1 then
            set bonusx = width / 2 * dlen / dx// ?dy
        endif
        if dx != 0 and divisions > 1 then
            set bonusy = width / 2 * dlen / dy // ? dx
        endif
       
       
        //calculate first line segment
        set l1x = - width*dyn
        set l1y =   width*dxn
        set l2x =   width*dyn
        set l2y = - width*dxn
        set l3x = l2x + dx/divisions + bonusx
        set l3y = l2y + dy/divisions + bonusy
        set l4x = l1x + dx/divisions + bonusx
        set l4y = l1y + dy/divisions + bonusy
       
       
       
        //calculate bounds of the first line segment    
        set rectminx = min4(l1x,l2x,l3x,l4x)
        set rectmaxx = max4(l1x,l2x,l3x,l4x)
        set rectminy = min4(l1y,l2y,l3y,l4y)
        set rectmaxy = max4(l1y,l2y,l3y,l4y)
       
       
        //set temp vars for groupenum
        set tempgroup = g
        set temppx = px
        set temppy = py
        set tempdnx = dxn
        set tempdny = dyn
        set tempwidth = width - MAX_COLLISSION
        set tempd = dlen
       
       
        set i = 0
        loop
            exitwhen i >= divisions
            //---
            //move rect to right position
            call SetRect(temprect, px + i * dx / divisions + rectminx, py + i * dy / divisions + rectminy, px + i * dx / divisions + rectmaxx, py + i * dy / divisions + rectmaxy)
            //enum units in rect
            call GroupEnumUnitsInRect(tempenumgroup, temprect, Condition(function Add))
            //---
            set i = i + 1
        endloop
    endfunction

    endlibrary

     



    using this function would be to call GroupAddUnitsNearLine with the needed parameters.
     
  3. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    i hate jass ==,
    Have another GUI triggers?
    I don't want JASS!!! WADAFAK!
    EDIT: Anyway,i will +rep to you also :p
     
  4. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,476
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    Why do you hate Jass? Its so much better than GUI and easy to use for GUI users also. But anyway~
    You could do this in GUI but you cant define your own functions in GUI, so this trigger would be a big, frikkin mess.
    I'd suggest you to use a custom script.
     
  5. millzy

    millzy

    Joined:
    Jul 9, 2008
    Messages:
    1,540
    Resources:
    6
    Maps:
    5
    Spells:
    1
    Resources:
    6
    so your after a way to damage units in a line like as a missle passes them?

    here is a spell that will help you
     

    Attached Files:

  6. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    It good,but i want make it always at the same position and daels the damage in a line.
    [​IMG]
     
  7. millzy

    millzy

    Joined:
    Jul 9, 2008
    Messages:
    1,540
    Resources:
    6
    Maps:
    5
    Spells:
    1
    Resources:
    6
    i dont understand it does damage in a line and it does damage units in the middle of the line
     
  8. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Here you got egzample how to trigger 'shockwave-like' spell using GUI + dummy unit.
     
  9. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    I want it damage from Caster between the Target Point every time,not just 1 time of a line.
    Any ideas?+REP to millzy :p
     
  10. millzy

    millzy

    Joined:
    Jul 9, 2008
    Messages:
    1,540
    Resources:
    6
    Maps:
    5
    Spells:
    1
    Resources:
    6
    im not realy understanding what ur saying do u wana damage all the units in the line at once???
     
  11. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Example DotA phoenix Sun Ray,do you know? :p
    I want to create a lightning effect to the target point,and i created it,problem is how can i damage the units between caster and target point :p
     
  12. D4RK_G4ND4LF

    D4RK_G4ND4LF

    Joined:
    Feb 4, 2009
    Messages:
    1,196
    Resources:
    20
    Models:
    3
    Spells:
    15
    Tutorials:
    2
    Resources:
    20
    like this?
    https://www.hiveworkshop.com/posts/1911382/
    I'll translate this to GUI in a few minutes

    edit:
    done
    Code
    • Ini
      • Events
        • Map initialization
      • Conditions
      • Actions
        • Set zLoc = (Point(0.00, 0.00))
    • DeathGaze_Cast
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Death Gaze
      • Actions
        • Set DeathGaze_Count = (DeathGaze_Count + 1)
        • Set DeathGaze_Caster[DeathGaze_Count] = (Triggering unit)
        • Set DeathGaze_Damage[DeathGaze_Count] = 10.00
        • Set DeathGaze_Distance[DeathGaze_Count] = 800.00
        • Set DeathGaze_Duration[DeathGaze_Count] = 5.00
        • Set DeathGaze_Time[DeathGaze_Count] = 0.00
        • Set DeathGaze_Width[DeathGaze_Count] = 80.00
        • Set DeathGaze_LightningStartZ[DeathGaze_Count] = 100.00
        • Set DeathGaze_LightningEndZ[DeathGaze_Count] = 35.00
        • Custom script: call MoveLocation(udg_zLoc, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
        • For each (Integer DeathGaze_Index) from 0 to 4, do (Actions)
          • Loop - Actions
            • Lightning - Create a Finger of Death lightning effect from source zLoc to target zLoc
            • Set DeathGaze_Lightning[((DeathGaze_Count x 5) + DeathGaze_Index)] = (Last created lightning effect)
        • Trigger - Turn on DeathGaze_Loop <gen>
    • DeathGaze_Loop
      • Events
        • Time - Every 0.03 seconds of game time
      • Conditions
      • Actions
        • For each (Integer DeathGaze_Index) from 1 to DeathGaze_Count, do (Actions)
          • Loop - Actions
            • Set u = DeathGaze_Caster[DeathGaze_Index]
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • u Not equal to No unit
                • (Life of u) Greater than 0.00
                • DeathGaze_Time[DeathGaze_Index] Less than DeathGaze_Duration[DeathGaze_Index]
              • Then - Actions
                • Set DeathGaze_Time[DeathGaze_Index] = (DeathGaze_Time[DeathGaze_Index] + 0.03)
                • Set r = DeathGaze_Distance[DeathGaze_Index]
                • Custom script: set udg_x = GetUnitX(udg_u)
                • Custom script: set udg_y = GetUnitY(udg_u)
                • Set a = (Facing of u)
                • Set x2 = (x + ((Cos(a)) x r))
                • Set y2 = (y + ((Sin(a)) x r))
                • Custom script: call MoveLocation(udg_zLoc, udg_x, udg_y)
                • Custom script: set udg_z = GetLocationZ(udg_zLoc)
                • Set z = (z + (DeathGaze_LightningStartZ[DeathGaze_Index] + (Current flying height of u)))
                • Custom script: call MoveLocation(udg_zLoc, udg_x2, udg_y2)
                • Custom script: set udg_z2 = GetLocationZ(udg_zLoc)
                • Set z2 = (z2 + DeathGaze_LightningEndZ[DeathGaze_Index])
                • For each (Integer DeathGaze_Index2) from 0 to 4, do (Actions)
                  • Loop - Actions
                    • Custom script: call MoveLightningEx(udg_DeathGaze_Lightning[udg_DeathGaze_Index*5+udg_DeathGaze_Index2], true, udg_x, udg_y, udg_z, udg_x2, udg_y2, udg_z2)
                • Set p = (Owner of u)
                • Set r2 = DeathGaze_Damage[DeathGaze_Index]
                • Set r3 = (r x DeathGaze_Width[DeathGaze_Index])
                • Custom script: call GroupEnumUnitsInRange(udg_g, udg_x, udg_y, udg_r, null)
                • Unit Group - Pick every unit in g and do (Actions)
                  • Loop - Actions
                    • Set u2 = (Picked unit)
                    • Custom script: set udg_x3 = GetUnitX(udg_u2)
                    • Custom script: set udg_y3 = GetUnitY(udg_u2)
                    • Set dx = (x2 - x3)
                    • Set dy = (y2 - y3)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • (Life of u2) Greater than 0.00
                        • ((dx x dx) + (dy x dy)) Less than or equal to (r x r)
                        • (u2 belongs to an enemy of p) Equal to True
                        • (Abs((((x2 - x) x (y - y3)) - ((x - x3) x (y2 - y))))) Less than or equal to r3
                      • Then - Actions
                        • Unit - Cause u to damage u2, dealing r2 damage of attack type Spells and damage type Normal
                      • Else - Actions
              • Else - Actions
                • For each (Integer DeathGaze_Index2) from 0 to 4, do (Actions)
                  • Loop - Actions
                    • Lightning - Destroy DeathGaze_Lightning[((DeathGaze_Index x 5) + DeathGaze_Index2)]
                    • Set DeathGaze_Lightning[((DeathGaze_Index x 5) + DeathGaze_Index2)] = DeathGaze_Lightning[((DeathGaze_Count x 5) + DeathGaze_Index2)]
                • Lightning - Destroy DeathGaze_Lightning[DeathGaze_Index]
                • Lightning - Destroy DeathGaze_Lightning[DeathGaze_Index]
                • Lightning - Destroy DeathGaze_Lightning[DeathGaze_Index]
                • Lightning - Destroy DeathGaze_Lightning[DeathGaze_Index]
                • Set DeathGaze_Caster[DeathGaze_Index] = DeathGaze_Caster[DeathGaze_Count]
                • Set DeathGaze_Damage[DeathGaze_Index] = DeathGaze_Damage[DeathGaze_Count]
                • Set DeathGaze_Distance[DeathGaze_Index] = DeathGaze_Distance[DeathGaze_Count]
                • Set DeathGaze_Duration[DeathGaze_Index] = DeathGaze_Duration[DeathGaze_Count]
                • Set DeathGaze_LightningEndZ[DeathGaze_Index] = DeathGaze_LightningEndZ[DeathGaze_Count]
                • Set DeathGaze_LightningStartZ[DeathGaze_Index] = DeathGaze_LightningStartZ[DeathGaze_Count]
                • Set DeathGaze_Time[DeathGaze_Index] = DeathGaze_Time[DeathGaze_Count]
                • Set DeathGaze_Width[DeathGaze_Index] = DeathGaze_Width[DeathGaze_Count]
                • Set DeathGaze_Count = (DeathGaze_Count - 1)
                • Set DeathGaze_Index = (DeathGaze_Index - 1)
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • DeathGaze_Count Less than 1
                  • Then - Actions
                    • Trigger - Turn off (This trigger)
                  • Else - Actions
    the math behind it is explained here
    http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html (14)
     

    Attached Files:

    Last edited: Jul 30, 2011
  13. GangSpear

    GangSpear

    Joined:
    Oct 25, 2009
    Messages:
    971
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Ya,thanks :p
    But where is the variables that can damage unit in a line?Confused @@
    +REP