13 years
edited 8 years
Introduction
Before I start, I would just like to credit Moyack for patience with testing and pointing out certain flaws, especially with how the code is presented.
Description
I have created a function, that can group units in line with; a distance-value that is unchanged no matter where the end-point may be, a radius-value, a optional spread-value (determined in radians, easiest way to get the spread-angle you want is to create a constant with the spreadangle * bj_DEGTORAD) and an optional boolean exp-filter.
Requirements
- vJass
Actual Code
What it does: it takes a group to fill (a group already existing), 4 coordinates (startx, starty, endx, endy), a real value distance (how far will this line go from the start-coordinates. It could reach and go further than the end-point or it could not get that far at all), a real angle expressed in radians that tells if and how much the line should change as it goes further (0.262 would give a 15~deg spread in angle, 0 will give a straight line) and a boolexpr "bex", this to actually lessen the cpu-usage in some cases, as the more units getting filtered away with the boolexpr, the less units it has to calculate for (just set this for null if you want it to take all units in the line)
How to import: Easiest way; download the testmap, open it with the NGJP-world editor, find the trigger named LineGroup and copy it, and paste it in your map. Alt. copy all text inside the LineGroup-trig and paste it in an empty text-trigger.
How to use:
Create a group with locals or use a group from an global variable, then call LineGroup with the group as the first value, and the rest with the values in the order told at a number of places in this text.
Sample Code
And a little extra, the code won't empty the group itself, so you could make some special stuff, like fan-shapes and stuff (this might require some further math, if someone is interested, I could show how.)
If you find any trouble with this, know a way to improve it or just have a question, just ask in this thread or PM me.
(the map have a non-other-than-me-user-friendly version of the TickTack, or ChainTimer as I have comed to call it. Dont mind that.. )
Before I start, I would just like to credit Moyack for patience with testing and pointing out certain flaws, especially with how the code is presented.
Description
I have created a function, that can group units in line with; a distance-value that is unchanged no matter where the end-point may be, a radius-value, a optional spread-value (determined in radians, easiest way to get the spread-angle you want is to create a constant with the spreadangle * bj_DEGTORAD) and an optional boolean exp-filter.
Requirements
- vJass
Actual Code
1 2 library LineGroup /* library LineGroup, used to group units in a line with a optional boolexpr-filter.
3
4 §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§5
6 This resourse is a [url=http://www.wc3jass.com]www.wc3jass.com[/url] exclusive resource. Please PM RVonSonSnadtz there7 or in-game should you ever have a problem with this or have ideas of improvments. 8 9 ===============================================================================================10
11 Extra thanks to Moyack, for troubleshooting and general code-help. 12 13 ===============================================================================================14
15 Requirements:16 vJass (haven't tried it with regular Jass, might work. But GUI is definetely not recommended17 due to the lack of control over handles such as the groups18 19
20 How to use?21 Copy the trigger and paste it in your map, or copy the contents from here into an empty22 trigger in your map. 23 24 It needs an already existing group to function, and it wont empty the group by itself 25 (this could of course be used in certain situations, and is an important knowing.)26 27 ================================================================================================28
29 Feel free to use this resource, but please give some creds atleast (:30
31 §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§*/32 33 34 globals35 private constant group GR = CreateGroup() //a constant unitgroup to avoid all CreateGroup, DestroyGroup and gr=null stuff
36 constant real RV_pi2 = Acos(0) //A half-pi, should not be changed
37 private constant real UNITEXTRASIZE = 16 //This number could be played with to fit your needs, it is basically just a number to make the radius-value more linear. Otherwise, only units with their centers in the cone passes the check.
38 endglobals 39 40 private function LineGroupFunc takes group g, real startx, real starty, real endx, real endy, real distance, real radius, real spread, boolexpr bex returns nothing
41 local real tx = endx - startx
42 local real ty = endy - starty
43 local real distr1 = SquareRoot(ty*ty+tx*tx)
44 local real distr2
45 local real angle = Atan2(ty,tx)
46 local real dx = (radius + UNITEXTRASIZE) * Cos(angle + RV_pi2)
47 local real dy = (radius + UNITEXTRASIZE) * Sin(angle + RV_pi2)
48 local real fx = tx/distr1
49 local real fy = ty/distr1
50 local real ex
51 local real ey
52 local unit u
53 local real ex2
54 local real ey2
55 call GroupEnumUnitsInRange(GR, startx + fx * distance/2, starty + fy * distance/2, distance/2 + UNITEXTRASIZE , bex)
56 if tx > 0 then
57 for u in GR // 0-90 deg (also 180-270 in reverse)
58 set ex = Atan2(GetUnitY(u) - starty + dy, GetUnitX(u) - startx + dx) + spread
59 set ex2 = Atan2(GetUnitY(u) - starty - dy, GetUnitX(u) - startx - dx) - spread
60 if ex > angle and ex2 < angle then
61 call GroupAddUnit(g, u)
62 endif63 endfor64 else65 for u in GR // 90-180 deg (also 270-360 in reverse)
66 set ex = Atan2(GetUnitY(u)*-1 + starty - dy, GetUnitX(u)*-1 + startx - dx) + spread
67 set ex2 = Atan2(GetUnitY(u)*-1 + starty + dy, GetUnitX(u)*-1 + startx + dx) - spread
68 if ex > angle - RV_pi2*2 and ex2 < angle - RV_pi2*2 then
69 call GroupAddUnit(g, u)
70 endif71 endfor72 endif73 endfunction74 75 function LineGroup takes group g, real startx, real starty, real endx, real endy, real distance, real radius, real spread, boolexpr bex returns nothing //spread is declared with angle in radians.
76 local real rx = startx - endx //This is the function to call. To use it, create a group and call this function with the group.
77 local real ry = starty - endy
78 local real dist = SquareRoot(rx*rx+ry*ry)
79 set rx = rx / dist
80 set ry = ry / dist
81 if starty > endy then
82 set endx = startx - rx * distance
83 set endy = starty - ry * distance
84 call LineGroupFunc(g, endx, endy, startx, starty, distance, radius + Tan(spread)*distance, spread * -1, bex)
85 else86 call LineGroupFunc(g, startx, starty, endx, endy, distance, radius, spread, bex)
87 endif88 endfunction89 90 endlibrary91
What it does: it takes a group to fill (a group already existing), 4 coordinates (startx, starty, endx, endy), a real value distance (how far will this line go from the start-coordinates. It could reach and go further than the end-point or it could not get that far at all), a real angle expressed in radians that tells if and how much the line should change as it goes further (0.262 would give a 15~deg spread in angle, 0 will give a straight line) and a boolexpr "bex", this to actually lessen the cpu-usage in some cases, as the more units getting filtered away with the boolexpr, the less units it has to calculate for (just set this for null if you want it to take all units in the line)
How to import: Easiest way; download the testmap, open it with the NGJP-world editor, find the trigger named LineGroup and copy it, and paste it in your map. Alt. copy all text inside the LineGroup-trig and paste it in an empty text-trigger.
How to use:
Create a group with locals or use a group from an global variable, then call LineGroup with the group as the first value, and the rest with the values in the order told at a number of places in this text.
Sample Code
1 2 function TestGroupLineBlaBla takes nothing returns nothing
3 local group g = CreateGroup //You need to have an already created goup in here.
4 local unit u = GetTriggerUnit()
5 local location loc = GetSpellTargetLoc()
6 call LineGroup(g, GetUnitX(u), GetUnitY(u), GetLocationX(loc), GetLocationY(loc), 800, 75, 15*bj_DEGTORAD, function SomeFilter)
7 /*Do the stuff with the group*/8 call DestroyGoup(g)
9 call RemoveLocation(loc)
10 endfunction11
And a little extra, the code won't empty the group itself, so you could make some special stuff, like fan-shapes and stuff (this might require some further math, if someone is interested, I could show how.)
If you find any trouble with this, know a way to improve it or just have a question, just ask in this thread or PM me.
(the map have a non-other-than-me-user-friendly version of the TickTack, or ChainTimer as I have comed to call it. Dont mind that.. )