Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F627642
smart_pan.as
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
smart_pan.as
View Options
#
priority
init
10
import
navigation.scopes
;
import
navigation.SmartCamera
;
from
input
import
activeCamera
;
import
elements.BaseGuiElement
;
const
int
TOPBAR_OFFSET
=
77
;
const
int
SCOPE_SPACING
=
4
;
const
int
SCOPE_WIDTH
=
50
;
const
int
SCOPE_HEIGHT
=
50
;
const
int
SCOPE_PADDING
=
2
;
const
double
SEARCH_INTERVAL
=
1.0
;
const
uint
MAX_SCOPES
=
16
;
Color
scopeColor
(
0xffffff40
);
Color
scopeHoverColor
(
0x00ff0040
);
Color
scopeActiveColor
(
0xff000040
);
Color
scopePanningColor
(
0x0000ff40
);
string
ellipsis
=
"-"
;
const
double
smartPanSpeed
=
10000.0
;
const
double
fadeDistanceMin
=
10000.0
;
const
double
fadeDistanceMax
=
16000.0
;
ScopeSearch
search
;
double
searchTimer
=
0.0
;
ScopeButton
@
panningButton
;
ScopeButton
@
[]
buttons
;
bool
shown
=
false
;
uint
displayedScopes
=
0
;
void
init
()
{
search
.
maxDistance
=
16000.0
;
@
panningButton
=
ScopeButton
();
panningButton
.
visible
=
false
;
buttons
.
length
=
MAX_SCOPES
;
for
(
uint
i
=
0
;
i
<
MAX_SCOPES
;
++
i
)
{
@
buttons
[
i
]
=
ScopeButton
();
buttons
[
i
].
visible
=
false
;
}
}
void
showSmartPan
()
{
shown
=
true
;
update
();
searchTimer
=
SEARCH_INTERVAL
;
}
void
hideSmartPan
()
{
shown
=
false
;
for
(
uint
i
=
0
;
i
<
MAX_SCOPES
;
++
i
)
buttons
[
i
].
visible
=
false
;
}
void
toggleSmartPan
()
{
if
(
shown
)
hideSmartPan
();
else
showSmartPan
();
}
void
update
()
{
search
.
position
=
activeCamera
.
lookAt
;
displayedScopes
=
searchScopes
(
search
,
MAX_SCOPES
);
for
(
uint
i
=
0
;
i
<
displayedScopes
;
++
i
)
{
Scope
@
scope
=
search
.
results
[
i
];
//Ignore current scope
if
(
search
.
position
.
distanceTo
(
scope
.
position
)
<
scope
.
radius
||
(
panningButton
.
visible
&&
panningButton
.
scope
is
scope
))
{
buttons
[
i
].
visible
=
false
;
continue
;
}
//Ready the scope button
buttons
[
i
].
visible
=
true
;
buttons
[
i
].
set
(
scope
);
buttons
[
i
].
updatePosition
();
}
//Hide extra buttons
for
(
uint
i
=
displayedScopes
;
i
<
MAX_SCOPES
;
++
i
)
buttons
[
i
].
visible
=
false
;
}
void
updatePositions
()
{
for
(
uint
i
=
0
;
i
<
displayedScopes
;
++
i
)
{
Scope
@
scope
=
buttons
[
i
].
scope
;
if
(
scope
is
null
||
search
.
position
.
distanceTo
(
scope
.
position
)
<
scope
.
radius
||
(
panningButton
.
visible
&&
panningButton
.
scope
is
scope
))
{
buttons
[
i
].
visible
=
false
;
}
else
{
buttons
[
i
].
visible
=
true
;
buttons
[
i
].
updatePosition
();
}
}
}
bool
waitForMove
=
true
;
int
buttonAlpha
=
80
;
void
tick
(
double
time
)
{
if
(!
shown
)
return
;
//Fade the buttons out at large distances
double
dist
=
activeCamera
.
distance
;
if
(
dist
>
fadeDistanceMin
)
{
if
(
dist
>=
fadeDistanceMax
)
{
buttonAlpha
=
0
;
return
;
}
else
{
buttonAlpha
=
80
-
ceil
(
80.0
*
(
dist
-
fadeDistanceMin
)
/
(
fadeDistanceMax
-
fadeDistanceMin
));
}
}
else
{
buttonAlpha
=
80
;
}
//Check if we're panning with a button
vec2i
mpos
=
mousePos
;
if
(
buttonAlpha
>
0
&&
mpos
.
x
<
6
||
mpos
.
x
>=
screenSize
.
width
-
6
)
{
if
(!
waitForMove
)
{
bool
found
=
false
;
if
(
panningButton
.
visible
)
{
if
(!
panningButton
.
AbsolutePosition
.
isWithin
(
mpos
))
{
panningButton
.
visible
=
false
;
}
else
{
double
tickPan
=
time
*
smartPanSpeed
;
if
(
activeCamera
.
panTo
(
panningButton
.
scope
.
position
,
tickPan
))
{
panningButton
.
visible
=
false
;
waitForMove
=
true
;
}
}
}
else
{
for
(
uint
i
=
0
;
i
<
displayedScopes
;
++
i
)
{
if
(
buttons
[
i
].
visible
&&
buttons
[
i
].
AbsolutePosition
.
isWithin
(
mpos
))
{
buttons
[
i
].
visible
=
false
;
panningButton
.
set
(
buttons
[
i
].
scope
);
panningButton
.
AbsolutePosition
=
buttons
[
i
].
AbsolutePosition
;
panningButton
.
AbsoluteClipRect
=
buttons
[
i
].
AbsoluteClipRect
;
panningButton
.
visible
=
true
;
}
}
}
}
}
else
{
panningButton
.
visible
=
false
;
waitForMove
=
false
;
}
//Update the buttons
//if(searchTimer <= 0.0) {
//searchTimer = SEARCH_INTERVAL;
update
();
//}
//else {
//updatePositions();
//searchTimer -= time;
//}
}
class
ScopeButton
:
BaseGuiElement
{
Scope
@
scope
;
string
name
;
bool
left
;
bool
Hovered
;
bool
Pressed
;
ScopeButton
()
{
Hovered
=
false
;
Pressed
=
false
;
super
(
null
,
recti
(
0
,
0
,
SCOPE_WIDTH
,
SCOPE_HEIGHT
));
}
void
updatePosition
()
{
vec3d
camPos
=
activeCamera
.
lookAt
;
vec3d
scopePos
=
scope
.
position
;
double
flatAngle
=
activeCamera
.
screenAngle
(
scopePos
);
double
percentage
=
0.0
;
vec2i
pos
();
if
(
flatAngle
>=
0
&&
flatAngle
<=
0.5
)
{
left
=
false
;
percentage
=
0.5
-
flatAngle
;
}
else
if
(
flatAngle
>
0.5
&&
flatAngle
<=
1.0
)
{
left
=
true
;
percentage
=
flatAngle
-
0.5
;
}
else
if
(
flatAngle
<
0
&&
flatAngle
>=
-
0.5
)
{
left
=
false
;
percentage
=
0.5
+
flatAngle
*
-
1.0
;
}
else
if
(
flatAngle
<
-
0.5
&&
flatAngle
>=
-
1.0
)
{
left
=
true
;
percentage
=
1.5
+
flatAngle
;
}
if
(
left
)
pos
.
x
=
0
;
else
pos
.
x
=
screenSize
.
width
-
size
.
width
;
pos
.
y
=
TOPBAR_OFFSET
;
pos
.
y
+=
double
(
screenSize
.
height
-
TOPBAR_OFFSET
-
SCOPE_HEIGHT
)
*
percentage
;
bool
overlap
;
do
{
overlap
=
false
;
recti
box
=
recti_area
(
pos
,
size
);
if
(
panningButton
.
visible
&&
panningButton
.
AbsolutePosition
.
overlaps
(
box
))
{
overlap
=
true
;
pos
.
y
=
panningButton
.
AbsolutePosition
.
topLeft
.
y
;
if
(
percentage
<
0.5
)
pos
.
y
+=
SCOPE_HEIGHT
+
SCOPE_SPACING
;
else
pos
.
y
-=
SCOPE_HEIGHT
+
SCOPE_SPACING
;
continue
;
}
for
(
uint
i
=
0
;
i
<
MAX_SCOPES
;
++
i
)
{
if
(
buttons
[
i
]
is
this
)
break
;
if
(
buttons
[
i
].
left
==
left
&&
buttons
[
i
].
AbsolutePosition
.
overlaps
(
box
))
{
overlap
=
true
;
pos
.
y
=
buttons
[
i
].
AbsolutePosition
.
topLeft
.
y
;
if
(
percentage
<
0.5
)
pos
.
y
+=
SCOPE_HEIGHT
+
SCOPE_SPACING
;
else
pos
.
y
-=
SCOPE_HEIGHT
+
SCOPE_SPACING
;
break
;
}
}
if
(
pos
.
y
<
0
||
pos
.
y
+
SCOPE_HEIGHT
>
screenSize
.
height
)
{
visible
=
false
;
return
;
}
}
while
(
overlap
);
position
=
pos
;
}
void
set
(
Scope
@
s
)
{
@
scope
=
s
;
name
=
scope
.
name
;
}
void
trigger
()
{
activeCamera
.
zoomTo
(
scope
.
position
);
}
bool
onGuiEvent
(
const
GuiEvent
&
event
)
{
if
(
event
.
caller
is
this
&&
buttonAlpha
>
0
)
{
switch
(
event
.
type
)
{
case
GUI_Mouse_Entered
:
Hovered
=
true
;
break
;
case
GUI_Mouse_Left
:
Hovered
=
false
;
Pressed
=
false
;
break
;
}
}
return
BaseGuiElement
::
onGuiEvent
(
event
);
}
bool
onMouseEvent
(
const
MouseEvent
&
event
,
IGuiElement
@
source
)
{
if
(
source
is
this
&&
buttonAlpha
>
0
)
{
switch
(
event
.
type
)
{
case
MET_Button_Down
:
if
(
event
.
button
==
0
)
{
Pressed
=
true
;
}
return
true
;
case
MET_Button_Up
:
if
(
event
.
button
==
0
&&
Pressed
)
{
Pressed
=
false
;
trigger
();
}
return
true
;
}
}
return
BaseGuiElement
::
onMouseEvent
(
event
,
source
);
}
void
draw
()
{
if
(
buttonAlpha
<=
0
)
return
;
Color
col
=
scopeColor
;
if
(
panningButton
is
this
)
col
=
scopePanningColor
;
else
if
(
Pressed
)
col
=
scopeActiveColor
;
else
if
(
Hovered
&&
!
panningButton
.
visible
)
col
=
scopeHoverColor
;
col
.
a
=
buttonAlpha
;
drawRectangle
(
AbsolutePosition
,
col
);
const
Font
@
fnt
=
skin
.
getFont
(
FT_Normal
);
recti
textPos
=
AbsolutePosition
;
textPos
.
topLeft
.
x
+=
SCOPE_PADDING
;
textPos
.
botRight
.
x
-=
SCOPE_PADDING
;
int
vpadd
=
(
textPos
.
height
-
fnt
.
getLineHeight
())
/
2
;
textPos
.
topLeft
.
y
+=
vpadd
;
textPos
.
botRight
.
y
-=
vpadd
;
fnt
.
draw
(
textPos
,
name
,
ellipsis
);
BaseGuiElement
::
draw
();
}
};
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Sun, Nov 15, 2:27 AM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
142079
Default Alt Text
smart_pan.as (7 KB)
Attached To
Mode
R80 StarRuler2-Source
Attached
Detach File
Event Timeline