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.");
}
}
}
}
}