- Joined
- Aug 1, 2009
- Messages
- 963
I made a better (and more efficient) traceline system for my map that doesn't loop a hundred times.
Because lots of people are probably using the other kind of traceline, which is annoyingly inefficient, I decided to share this with you! Hooray!
Now, notice that this doesn't include height detection or a Z axis, mostly because those things are irrelevant in the project I created. However, a 3 dimesional line is nothing more than 3 2 dimensional lines, one on the x/y plane, one on the y/z plane, and one on the x/z plane, so it shouldn't be too difficult to figure out. Additionally, what is (are?) terrain height and cliffs but a complex 2 dimensional piecewise function?
[TRIGGER=Tracelines]Tracelines
Options: Function
Return Type: Unit
Parameters
distance = 0.0 <Real>
StartPoint = No Point <Point>
SourceUnit = No Unit <Unit>
Angle = 0.0 <Real>
Local Variables
a = (-Sin(Angle)) <Real>
b = (Cos(Angle)) <Real>
g = (Any units in (Region((StartPoint offset by (distance / 2.0) towards Angle degrees), (distance / 2.0))) owned by player Any Player matching Excluded: Psionic, Missile, Dead, Hidden, with at most Any Amount) <Unit Group>
g2 = (Empty unit group) <Unit Group>
u = No Unit <Unit>
u2 = No Unit <Unit>
x = 0.0 <Real>
y = 0.0 <Real>
x1 = (X of StartPoint) <Real>
y1 = (Y of StartPoint) <Real>
Actions
------- Coded by mrzwach, alias fernsauce.
Unit Group - Remove SourceUnit from g //This is simply so that it cannot return the unit from which the line is being traced.
Unit Group - For each unit u in g do (Actions)
Actions
Variable - Set x = ((X of (Position of u)) - x1) //Because my formula for the line being traced is ax+by=0, the origin (and source position) is (0, 0).
Variable - Set y = ((Y of (Position of u)) - y1) //Since the actual location in the coordinate grid is not (0, 0) I must adjust the coordinates of units being checked.
General - If (Conditions) then do (Actions) else do (Actions)
If
(u Radius (Current)) >= (Abs(((a * x) + (b * y))) //Derived from distance to line formula
Then
Unit Group - Add u to g2
Else
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in g2) == 0
Then
General - Return No Unit
Else
General - While (Conditions) are true, do (Actions)
Conditions
(Number of Living units in g2) >= 1
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in g2) > 1
Then
Variable - Set u = (Unit 1 from g2)
Variable - Set u2 = (Unit 2 from g2)
General - If (Conditions) then do (Actions) else do (Actions)
If //This part is to check which unit is closer, so that it can return the closest unit.
(Distance between (Position of u) and StartPoint) >= (Distance between StartPoint and (Position of u2))
Then
Unit Group - Remove u from g2
Else
Unit Group - Remove u2 from g2
Else
Variable - Set u = (Unit 1 from g2)
Unit Group - Remove u from g2
General - Return u
General - Return No Unit //The only reason for this part is that SC2 will pop up with a syntax error otherwise, even if it is impossible
[/TRIGGER]
Because lots of people are probably using the other kind of traceline, which is annoyingly inefficient, I decided to share this with you! Hooray!
Now, notice that this doesn't include height detection or a Z axis, mostly because those things are irrelevant in the project I created. However, a 3 dimesional line is nothing more than 3 2 dimensional lines, one on the x/y plane, one on the y/z plane, and one on the x/z plane, so it shouldn't be too difficult to figure out. Additionally, what is (are?) terrain height and cliffs but a complex 2 dimensional piecewise function?
[TRIGGER=Tracelines]Tracelines
Options: Function
Return Type: Unit
Parameters
distance = 0.0 <Real>
StartPoint = No Point <Point>
SourceUnit = No Unit <Unit>
Angle = 0.0 <Real>
Local Variables
a = (-Sin(Angle)) <Real>
b = (Cos(Angle)) <Real>
g = (Any units in (Region((StartPoint offset by (distance / 2.0) towards Angle degrees), (distance / 2.0))) owned by player Any Player matching Excluded: Psionic, Missile, Dead, Hidden, with at most Any Amount) <Unit Group>
g2 = (Empty unit group) <Unit Group>
u = No Unit <Unit>
u2 = No Unit <Unit>
x = 0.0 <Real>
y = 0.0 <Real>
x1 = (X of StartPoint) <Real>
y1 = (Y of StartPoint) <Real>
Actions
------- Coded by mrzwach, alias fernsauce.
Unit Group - Remove SourceUnit from g //This is simply so that it cannot return the unit from which the line is being traced.
Unit Group - For each unit u in g do (Actions)
Actions
Variable - Set x = ((X of (Position of u)) - x1) //Because my formula for the line being traced is ax+by=0, the origin (and source position) is (0, 0).
Variable - Set y = ((Y of (Position of u)) - y1) //Since the actual location in the coordinate grid is not (0, 0) I must adjust the coordinates of units being checked.
General - If (Conditions) then do (Actions) else do (Actions)
If
(u Radius (Current)) >= (Abs(((a * x) + (b * y))) //Derived from distance to line formula
Then
Unit Group - Add u to g2
Else
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in g2) == 0
Then
General - Return No Unit
Else
General - While (Conditions) are true, do (Actions)
Conditions
(Number of Living units in g2) >= 1
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in g2) > 1
Then
Variable - Set u = (Unit 1 from g2)
Variable - Set u2 = (Unit 2 from g2)
General - If (Conditions) then do (Actions) else do (Actions)
If //This part is to check which unit is closer, so that it can return the closest unit.
(Distance between (Position of u) and StartPoint) >= (Distance between StartPoint and (Position of u2))
Then
Unit Group - Remove u from g2
Else
Unit Group - Remove u2 from g2
Else
Variable - Set u = (Unit 1 from g2)
Unit Group - Remove u from g2
General - Return u
General - Return No Unit //The only reason for this part is that SC2 will pop up with a syntax error otherwise, even if it is impossible
[/TRIGGER]
Last edited: