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
library LineGroup /* library LineGroup, used to group units in a line with a optional boolexpr-filter.
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
This resourse is a [url=http://www.wc3jass.com]www.wc3jass.com[/url] exclusive resource. Please PM RVonSonSnadtz there
or in-game should you ever have a problem with this or have ideas of improvments.
===============================================================================================
Extra thanks to Moyack, for troubleshooting and general code-help.
===============================================================================================
Requirements:
vJass (haven't tried it with regular Jass, might work. But GUI is definetely not recommended
due to the lack of control over handles such as the groups
How to use?
Copy the trigger and paste it in your map, or copy the contents from here into an empty
trigger in your map.
It needs an already existing group to function, and it wont empty the group by itself
(this could of course be used in certain situations, and is an important knowing.)
================================================================================================
Feel free to use this resource, but please give some creds atleast (:
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§*/
globals
private constant group GR = CreateGroup() //a constant unitgroup to avoid all CreateGroup, DestroyGroup and gr=null stuff
constant real RV_pi2 = Acos(0) //A half-pi, should not be changed
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.
endglobals
private function LineGroupFunc takes group g, real startx, real starty, real endx, real endy, real distance, real radius, real spread, boolexpr bex returns nothing
local real tx = endx - startx
local real ty = endy - starty
local real distr1 = SquareRoot(ty*ty+tx*tx)
local real distr2
local real angle = Atan2(ty,tx)
local real dx = (radius + UNITEXTRASIZE) * Cos(angle + RV_pi2)
local real dy = (radius + UNITEXTRASIZE) * Sin(angle + RV_pi2)
local real fx = tx/distr1
local real fy = ty/distr1
local real ex
local real ey
local unit u
local real ex2
local real ey2
call GroupEnumUnitsInRange(GR, startx + fx * distance/2, starty + fy * distance/2, distance/2 + UNITEXTRASIZE , bex)
if tx > 0 then
for u in GR // 0-90 deg (also 180-270 in reverse)
set ex = Atan2(GetUnitY(u) - starty + dy, GetUnitX(u) - startx + dx) + spread
set ex2 = Atan2(GetUnitY(u) - starty - dy, GetUnitX(u) - startx - dx) - spread
if ex > angle and ex2 < angle then
call GroupAddUnit(g, u)
endif
endfor
else
for u in GR // 90-180 deg (also 270-360 in reverse)
set ex = Atan2(GetUnitY(u)*-1 + starty - dy, GetUnitX(u)*-1 + startx - dx) + spread
set ex2 = Atan2(GetUnitY(u)*-1 + starty + dy, GetUnitX(u)*-1 + startx + dx) - spread
if ex > angle - RV_pi2*2 and ex2 < angle - RV_pi2*2 then
call GroupAddUnit(g, u)
endif
endfor
endif
endfunction
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.
local real rx = startx - endx //This is the function to call. To use it, create a group and call this function with the group.
local real ry = starty - endy
local real dist = SquareRoot(rx*rx+ry*ry)
set rx = rx / dist
set ry = ry / dist
if starty > endy then
set endx = startx - rx * distance
set endy = starty - ry * distance
call LineGroupFunc(g, endx, endy, startx, starty, distance, radius + Tan(spread)*distance, spread * -1, bex)
else
call LineGroupFunc(g, startx, starty, endx, endy, distance, radius, spread, bex)
endif
endfunction
endlibrary
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
function TestGroupLineBlaBla takes nothing returns nothing
local group g = CreateGroup //You need to have an already created goup in here.
local unit u = GetTriggerUnit()
local location loc = GetSpellTargetLoc()
call LineGroup(g, GetUnitX(u), GetUnitY(u), GetLocationX(loc), GetLocationY(loc), 800, 75, 15*bj_DEGTORAD, function SomeFilter)
/*Do the stuff with the group*/
call DestroyGoup(g)
call RemoveLocation(loc)
endfunction
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.. )