Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

HUD Autopositioning Script

Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
09-16-2009 10:23
This complete script will automatically rotate and correctly position a HUD worn from inventory. The user may also chose to attach to a different HUD attachment point, and in either case a dialog comes up asking the user if the HUD is positioned correctly. If they respond "No", the HUD is repositioned to the center of the attachment point, making it visible. The developer can determine the correct position to supply by using llGetLocalPos() to get the HUD object's current position, and the correct rotation by using llGetLocalRot() [this will normally be <0,0,0> when expressed in Euler degrees]. llSetPos() is used to set the location because it applies a position relative to the HUD attachment point for objects worn on the HUD, not the regional or global coordinates (this is not the case for rotations - llGetLocalRot & llSetLocalRot must be used, and there is no llSetLocalPos()).

A default attachment point and position is supplied in global variables which may be overwritten by the user. Hard-coded references to ATTACH_HUD_CENTER_2 should be preserved in the code as it is used to test if an attachment went to a body part or a HUD location.

When a HUD is worn for the first time, or when it changes to a different attachment point, the user is presented a dialog asking if the HUD is correctly positioned. If they respond "No" the HUD is repositioned to be at or near the zero coordinate for the attachment point, slightly inset towards the center if necessary to make it visible.

It also uses a sufficiently pseudo-random dialog channel based on the object's key to prevent conflicts.

CODE

integer attach_point;
integer dlg_channel;
integer dlg_handle;
integer dlg_wait = 10;
list menu_main = ["Yes","No"];
string menu_context = "main";
key id_agent;
integer attach_default_ap = ATTACH_HUD_BOTTOM_LEFT;
vector attach_default_pos = <0,-0.1, 0.1>;

call_menu()
{
llSetTimerEvent(dlg_wait);
llListenControl(dlg_handle, TRUE);
if (menu_context == "main") {
llDialog(id_agent, "A Personal Information Manager (PIM) HUD has just been attached.\n\n"
+" Is it positioned correctly?",
menu_main, dlg_channel
);
}
}
default
{
state_entry()
{
attach_point = -1;
dlg_channel = (integer)("0x"+llGetSubString((string)llGetKey(),-8,-1));
dlg_handle = llListen(dlg_channel,"","","");
llRequestPermissions( llGetOwner(), PERMISSION_ATTACH );
}
changed(integer change)
{
if(change & CHANGED_OWNER) {
llResetScript();
}
}
run_time_permissions( integer vBitPermissions )
{
if (vBitPermissions & PERMISSION_ATTACH) {
if (attach_point == -1) {
llAttachToAvatar(attach_default_ap);
}
else if (attach_point < ATTACH_HUD_CENTER_2) {
llOwnerSay(llGetObjectName()+" should be worn on the HUD -- detaching");
llDetachFromAvatar();
}
}
}
on_rez(integer rez)
{
if(!llGetAttached()) {
llResetScript();
}
}
timer()
{
llSetTimerEvent(0.0);
llListenControl(dlg_handle, FALSE);
menu_context = "main";
}
attach(key AvatarKey)
{
if (AvatarKey) {
if (llGetAttached()) {
if (llGetAttached() < ATTACH_HUD_CENTER_2) {
llRequestPermissions(AvatarKey, PERMISSION_ATTACH);
}
else {
if (attach_point == llGetAttached()) {
attach_default_ap = llGetAttached();
attach_default_pos = llGetLocalPos();
}
else {
attach_point = llGetAttached();
llSetLocalRot(llEuler2Rot(<0,0,0>*DEG_TO_RAD));
if (attach_point == ATTACH_HUD_BOTTOM_LEFT) llSetPos(attach_default_pos);
id_agent = llGetOwner();
call_menu();
}
}
}
}
}
listen(integer chan, string name, key id, string cmd)
{
llSetTimerEvent(0);
llListenControl(dlg_handle, FALSE);
if (chan == dlg_channel && menu_context == "main") {
if (llListFindList(menu_main, [cmd]) != -1) {
if (cmd == "No") {
if (llGetAttached() == ATTACH_HUD_TOP_LEFT ) llSetPos(<0,-0.1,-0.1>);
if (llGetAttached() == ATTACH_HUD_TOP_CENTER ) llSetPos(<0, 0.0,-0.1>);
if (llGetAttached() == ATTACH_HUD_TOP_RIGHT ) llSetPos(<0, 0.1,-0.1>);
if (llGetAttached() == ATTACH_HUD_BOTTOM_LEFT ) llSetPos(<0,-0.1, 0.1>);
if (llGetAttached() == ATTACH_HUD_BOTTOM ) llSetPos(<0, 0.0, 0.1>);
if (llGetAttached() == ATTACH_HUD_BOTTOM_RIGHT) llSetPos(<0, 0.1, 0.1>);
if (llGetAttached() == ATTACH_HUD_CENTER_1 ) llSetPos(<0,0,0>);
if (llGetAttached() == ATTACH_HUD_CENTER_2 ) llSetPos(<0,0,0>);
llOwnerSay("Resetting to default position for HUD attachment point.");
llOwnerSay("Right click the HUD and use the arrow keys to reposition it on your screen.");
}
}
}
}
}
Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
09-17-2009 20:36
I rewrote several sections of the code to improve functionality.
1) You will only be asked if the HUD is visible when attaching for the first time, or when the attachment point changes.
2) When reattaching the HUD, it keeps the previous attachment point and position as the default "wear" attachment point and position (mimics normal behavior)
3) when you reply "No" to "is the HUD visible", instead of setting the position to <0,0,0> it slightly insets the position when the attachment point is on the edge (e.g. top left, bottom) by 0.1 towards the center of the screen. This makes sure the HUD is visible when it is small.

If anyone tries this out, I'd love some feedback - and corrections if required.

Thanks!
Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
09-18-2009 07:09
No additional changes to the code - some of the notes had to be rewritten since they referred to features / limitations of the old code.
Vladimir Petrichor
Registered User
Join date: 6 Apr 2006
Posts: 19
09-19-2009 05:46
Soen, would you mind if I linked to this from my wiki, or added it as a page in its full extent? All proper credits would be given regardless , of course.

Here is the url of the wiki itself if you would like to check that out first.

http://vladwerkz.wikidot.com/start
Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
09-19-2009 15:51
Knock yourself out, its public domain.

(9/19 change: fixed default position and removed debugging code)