| 1 |
///////////////// |
|---|
| 2 |
// |
|---|
| 3 |
// HUD_compensator.lsl 1 |
|---|
| 4 |
// by Max Case |
|---|
| 5 |
// |
|---|
| 6 |
// This script allows you to set offsets/position info for HUDs |
|---|
| 7 |
// It will then compensate, depending on the position |
|---|
| 8 |
// |
|---|
| 9 |
// I've left comments in the script on how to use this, so if you're not script-experienced, you can probably still use this, though, |
|---|
| 10 |
// if you don't know scripting, this probably isn't of much interest to you, since you're probably not making HUDs. |
|---|
| 11 |
// |
|---|
| 12 |
// @todo if rezzed from inv, into world, or onto body even? asks to attach to a HUD point. Can even give user a choice via llDialog |
|---|
| 13 |
// @todo make flag for wether Requires HUD Attach point, or is any point allowed? |
|---|
| 14 |
// Use this in products you make, but don't just re-sell this script as-is - thanks. |
|---|
| 15 |
// -max |
|---|
| 16 |
////////////// |
|---|
| 17 |
|
|---|
| 18 |
//Global Vars |
|---|
| 19 |
rotation GR_HUD_ROTATION = <0.000000, -0.000000, -0.000000, 1.000000>; |
|---|
| 20 |
rotation GR_HUD_PREFS = <-0.000000, -0.000000, 1.000000, 0.000000>; |
|---|
| 21 |
//OFFSET - Offset is relative to BOTTOM RIGHT - towards inside of the screen - away from edge |
|---|
| 22 |
vector GV_OFFSET = <-0.087600, 0.329133, 0.142695>; |
|---|
| 23 |
vector GV_HIDE_OFFSET = <-0.087600, -0.319792, 0.142695>; |
|---|
| 24 |
vector GV_USER_OFFSET = <0,0,0>; //For show hide reset |
|---|
| 25 |
|
|---|
| 26 |
//BUTTONS |
|---|
| 27 |
//Set to -1 to turn off. TO activate this functionality, set to the link number you want associted with the function |
|---|
| 28 |
//BUTTONS |
|---|
| 29 |
|
|---|
| 30 |
//To Flip HUD - say, for preferences on the back |
|---|
| 31 |
integer GI_BUTTON_FLIP = -1; //PREFS |
|---|
| 32 |
integer GI_BUTTON_FLIP_B = -1; |
|---|
| 33 |
|
|---|
| 34 |
integer GI_BUTTON_HIDE = -1; |
|---|
| 35 |
integer GI_BUTTON_SHOW = -1; |
|---|
| 36 |
|
|---|
| 37 |
//Set to true if you want kill switch functionality on |
|---|
| 38 |
// probably want this to be false on no copy objects :) |
|---|
| 39 |
integer GI_KILL_SWITCH = TRUE; |
|---|
| 40 |
//How many chances before i auto delete |
|---|
| 41 |
integer GI_KILL_MAX = 7; |
|---|
| 42 |
//For the Kill Switch timer- gets multiplied - so, first wanrning is in TICKS second, then second is in TICKS*2, etc... up to the GI_KILL_MAX |
|---|
| 43 |
float TICKS = 60.0; |
|---|
| 44 |
|
|---|
| 45 |
//LINK CODE |
|---|
| 46 |
//If you are using an external Show Button, this lets others know that SHOW / HIDE button triggered |
|---|
| 47 |
integer SHOW_NUM =-239482; |
|---|
| 48 |
|
|---|
| 49 |
//Start in flipped mode? |
|---|
| 50 |
//Panel View default, TRUE = prefs |
|---|
| 51 |
integer GI_HUD_FLIPPED = FALSE; |
|---|
| 52 |
integer GI_VISIBLE = TRUE; //SHow hide flag |
|---|
| 53 |
|
|---|
| 54 |
//Shouldnt have to mode below here. |
|---|
| 55 |
integer GI_KILL_COUNTER = 0; //Just a global to track it. |
|---|
| 56 |
|
|---|
| 57 |
list GL_HUD_NAMES = ["Center 2","Top Right","Top","Top Left","Center","Bottom Left","Bottom","Bottom Right"]; |
|---|
| 58 |
list GL_HUD_NUMBERS = ["31","32","33","34","35","36","37","38"]; |
|---|
| 59 |
|
|---|
| 60 |
integer LAST_ATTACH_POINT = -1; //This will be used to store users pref |
|---|
| 61 |
|
|---|
| 62 |
integer CH_ATTACH_POINT = -29394; |
|---|
| 63 |
integer GI_ATTACH_HANDLE; |
|---|
| 64 |
|
|---|
| 65 |
integer debug_flag = TRUE; //set to false to turn off debug messages |
|---|
| 66 |
DEBUG(list vars) { llOwnerSay( llList2CSV(vars)); } //We use SAY/DEBUG_CHANNEL because that shows up while we have busy flag on :) |
|---|
| 67 |
|
|---|
| 68 |
//This is for public speech mainly. -1 will give owner say, any other will be channel, but allows for general override |
|---|
| 69 |
SAY(string msg, integer channel) { if(channel == -1) llOwnerSay(msg); else llSay(channel, msg); } |
|---|
| 70 |
|
|---|
| 71 |
integer fn_easyDialog( key id, string message, list buttons, integer channel ) { |
|---|
| 72 |
llDialog( id, message, fn_validateLength(buttons), channel); |
|---|
| 73 |
return llListen(channel, "", id, ""); //now we can just switch it off when done. |
|---|
| 74 |
} |
|---|
| 75 |
|
|---|
| 76 |
//Flip the hud to either prefs or main panel |
|---|
| 77 |
integer fn_flip_hud( integer current ){ |
|---|
| 78 |
if(current == FALSE) { |
|---|
| 79 |
llSetLocalRot(GR_HUD_PREFS); |
|---|
| 80 |
} else { |
|---|
| 81 |
llSetLocalRot(GR_HUD_ROTATION); |
|---|
| 82 |
} |
|---|
| 83 |
return !current; |
|---|
| 84 |
} |
|---|
| 85 |
|
|---|
| 86 |
//Show/Hid the hud |
|---|
| 87 |
integer fn_show_hide_hud( integer current ){ |
|---|
| 88 |
if(current == TRUE) { //so hide it |
|---|
| 89 |
//Using LINK_ALL_OTHERS instead of BUTTON_SHOW for safety while dev'ing. @TODO change later. |
|---|
| 90 |
GV_USER_OFFSET = llGetLocalPos();//get the users last position, to restore later. |
|---|
| 91 |
|
|---|
| 92 |
llSetPos(fn_make_hidePos(llGetAttached(), GV_HIDE_OFFSET)); |
|---|
| 93 |
|
|---|
| 94 |
//Lets any other prim waiting for the hide event trigger |
|---|
| 95 |
llMessageLinked( LINK_ALL_OTHERS , SHOW_NUM, "hide", NULL_KEY ); |
|---|
| 96 |
} else { |
|---|
| 97 |
llSetPos(GV_USER_OFFSET); |
|---|
| 98 |
|
|---|
| 99 |
//Lets any other prim waiting for the show event trigger |
|---|
| 100 |
llMessageLinked( LINK_ALL_OTHERS , SHOW_NUM, "show", NULL_KEY ); |
|---|
| 101 |
} |
|---|
| 102 |
|
|---|
| 103 |
return !current; |
|---|
| 104 |
} |
|---|
| 105 |
|
|---|
| 106 |
|
|---|
| 107 |
integer fn_getIndex(list foo, string name) { |
|---|
| 108 |
return llListFindList(foo, [name] ); |
|---|
| 109 |
} |
|---|
| 110 |
|
|---|
| 111 |
//fn_isHudPoint |
|---|
| 112 |
//Returns either integer # of the attach point if hud, or false if its not |
|---|
| 113 |
integer fn_isHudPoint(integer attach_point) { |
|---|
| 114 |
if(attach_point > 30){ |
|---|
| 115 |
return attach_point; |
|---|
| 116 |
} else { |
|---|
| 117 |
return FALSE; |
|---|
| 118 |
} |
|---|
| 119 |
} |
|---|
| 120 |
|
|---|
| 121 |
integer fn_setHudPos(vector localpos, rotation localrot) { |
|---|
| 122 |
llSetPos(localpos); |
|---|
| 123 |
llSetLocalRot(localrot); |
|---|
| 124 |
return TRUE; |
|---|
| 125 |
} |
|---|
| 126 |
|
|---|
| 127 |
//For buttons |
|---|
| 128 |
list fn_validateLength( list foo) { |
|---|
| 129 |
integer li_return_length = 12; |
|---|
| 130 |
if( llGetListLength(foo) > li_return_length) { |
|---|
| 131 |
return llDeleteSubList( foo, 12, -1); |
|---|
| 132 |
} |
|---|
| 133 |
return foo; |
|---|
| 134 |
} |
|---|
| 135 |
|
|---|
| 136 |
//These seem similar, can probably be combined, but was simpler to keep them seperate. |
|---|
| 137 |
|
|---|
| 138 |
//Takes in the offsets, and the attach point |
|---|
| 139 |
vector fn_makePos(integer attach_point, vector offset) { |
|---|
| 140 |
if ((attach_point == 31) || (attach_point == 35)) { //center 2 & center |
|---|
| 141 |
return <0,0,0>; |
|---|
| 142 |
} else if (attach_point == 32) { // Top right |
|---|
| 143 |
return <offset.x, offset.y, offset.z * -1>; |
|---|
| 144 |
} else if (attach_point == 33) { // Top |
|---|
| 145 |
return <offset.x, 0, offset.z * -1>; |
|---|
| 146 |
} else if (attach_point == 34) { // Top Left |
|---|
| 147 |
return <offset.x, offset.y * -1, offset.z * -1>; |
|---|
| 148 |
} else if (attach_point == 36) { // Bottom Left |
|---|
| 149 |
return <offset.x, offset.y * -1 , offset.z>; |
|---|
| 150 |
} else if (attach_point == 37) { // Bottom |
|---|
| 151 |
return <offset.x, 0, offset.z>; |
|---|
| 152 |
} else if (attach_point == 38) { // Bottom Right - Baseline |
|---|
| 153 |
return offset; |
|---|
| 154 |
} else { //Not a HUD point? Then return it's current pos |
|---|
| 155 |
return llGetLocalPos(); |
|---|
| 156 |
} |
|---|
| 157 |
} |
|---|
| 158 |
|
|---|
| 159 |
//Takes in the offsets, and the attach point |
|---|
| 160 |
vector fn_make_hidePos(integer attach_point, vector offset) { |
|---|
| 161 |
if ((attach_point == 31) || (attach_point == 35)) { //center 2 & center |
|---|
| 162 |
return <0,-1.19,0>; |
|---|
| 163 |
} else if (attach_point == 32) { // Top right |
|---|
| 164 |
return <offset.x, offset.y, offset.z * -1>; |
|---|
| 165 |
} else if (attach_point == 33) { // Top |
|---|
| 166 |
return <offset.x, 0, offset.z>; |
|---|
| 167 |
} else if (attach_point == 34) { // Top Left |
|---|
| 168 |
return <offset.x, offset.y * -1, offset.z * -1>; |
|---|
| 169 |
} else if (attach_point == 36) { // Bottom Left |
|---|
| 170 |
return <offset.x, offset.y * -1 , offset.z>; |
|---|
| 171 |
} else if (attach_point == 37) { // Bottom |
|---|
| 172 |
return <offset.x, 0, offset.z * -1>; |
|---|
| 173 |
} else if (attach_point == 38) { // Bottom Right - Baseline |
|---|
| 174 |
return offset; |
|---|
| 175 |
} else { //Not a HUD point? Then return it's current pos |
|---|
| 176 |
return llGetLocalPos(); |
|---|
| 177 |
} |
|---|
| 178 |
} |
|---|
| 179 |
|
|---|
| 180 |
|
|---|
| 181 |
//Once you have your HUD positions (BOTTOM RIGHT) and Rotated just right, put this script into the root prim. |
|---|
| 182 |
//In the state entry, you will get the position (which is the offset) and rotation. Plug those into the top of your script, and remove the garbage from state_entry |
|---|
| 183 |
default |
|---|
| 184 |
{ |
|---|
| 185 |
state_entry() { |
|---|
| 186 |
//////DELETE ME BEGIN |
|---|
| 187 |
llOwnerSay("Offset Info: "+(string)llGetLocalPos()); |
|---|
| 188 |
llOwnerSay("Rotation Info: "+(string)llGetLocalRot()); |
|---|
| 189 |
//DEBUG([llGetLocalPos(), llGetLocalRot()]); |
|---|
| 190 |
//////DELETE ME END |
|---|
| 191 |
} |
|---|
| 192 |
|
|---|
| 193 |
attach(key attached) { |
|---|
| 194 |
if (attached != NULL_KEY) { |
|---|
| 195 |
//Reset the Kill switch |
|---|
| 196 |
llSetTimerEvent(0.0); |
|---|
| 197 |
GI_KILL_COUNTER = 0; |
|---|
| 198 |
|
|---|
| 199 |
if(LAST_ATTACH_POINT != llGetAttached()){ |
|---|
| 200 |
fn_setHudPos(fn_makePos(llGetAttached(),GV_OFFSET ), GR_HUD_ROTATION ); |
|---|
| 201 |
LAST_ATTACH_POINT = llGetAttached(); |
|---|
| 202 |
// DEBUG(["setting last attach point"]); |
|---|
| 203 |
} |
|---|
| 204 |
|
|---|
| 205 |
//Flip it to front |
|---|
| 206 |
if(GI_HUD_FLIPPED == TRUE) { |
|---|
| 207 |
GI_HUD_FLIPPED=fn_flip_hud(GI_HUD_FLIPPED); |
|---|
| 208 |
} |
|---|
| 209 |
} else { |
|---|
| 210 |
llSetTimerEvent(TICKS); //This will pester owner seconds to come pick up their item, and do kill switch. Clean up your litter kids! |
|---|
| 211 |
} |
|---|
| 212 |
} |
|---|
| 213 |
|
|---|
| 214 |
changed(integer change) |
|---|
| 215 |
{ |
|---|
| 216 |
if (change & CHANGED_OWNER) { |
|---|
| 217 |
llResetScript(); |
|---|
| 218 |
} |
|---|
| 219 |
} |
|---|
| 220 |
|
|---|
| 221 |
listen( integer chan, string name, key id, string msg ) { |
|---|
| 222 |
if(chan == CH_ATTACH_POINT) { |
|---|
| 223 |
|
|---|
| 224 |
//Done with the listen, so let's clean up, shall we? |
|---|
| 225 |
llListenRemove(GI_ATTACH_HANDLE); |
|---|
| 226 |
|
|---|
| 227 |
//DEBUG([llList2Integer(GL_HUD_NUMBERS, fn_getIndex(GL_HUD_NAMES, msg)), msg]); |
|---|
| 228 |
llAttachToAvatar(llList2Integer(GL_HUD_NUMBERS, fn_getIndex(GL_HUD_NAMES, msg))); |
|---|
| 229 |
} |
|---|
| 230 |
} |
|---|
| 231 |
|
|---|
| 232 |
on_rez(integer start_param) { |
|---|
| 233 |
if (!fn_isHudPoint(llGetAttached())){ |
|---|
| 234 |
llOwnerSay("Please! Let me attach to your HUD, won't you?"); |
|---|
| 235 |
llRequestPermissions(llGetOwner(), PERMISSION_ATTACH); |
|---|
| 236 |
llSetTimerEvent(TICKS); |
|---|
| 237 |
} |
|---|
| 238 |
} |
|---|
| 239 |
|
|---|
| 240 |
run_time_permissions(integer perm) { |
|---|
| 241 |
if (perm & PERMISSION_ATTACH) { |
|---|
| 242 |
GI_ATTACH_HANDLE = fn_easyDialog( llGetOwner(), "Pick a HUD Attach Point.", GL_HUD_NAMES, CH_ATTACH_POINT); |
|---|
| 243 |
} else { |
|---|
| 244 |
llOwnerSay("Please let me attach! Attachment is my purpose! My Life!"); |
|---|
| 245 |
} |
|---|
| 246 |
} |
|---|
| 247 |
|
|---|
| 248 |
timer() { |
|---|
| 249 |
//DEBUG([GI_KILL_COUNTER]); |
|---|
| 250 |
GI_KILL_COUNTER++; |
|---|
| 251 |
if(GI_KILL_SWITCH == TRUE) { |
|---|
| 252 |
if(GI_KILL_COUNTER > GI_KILL_MAX){ |
|---|
| 253 |
llInstantMessage(llGetOwner(), "I die now!"); |
|---|
| 254 |
llDie(); |
|---|
| 255 |
} |
|---|
| 256 |
} |
|---|
| 257 |
|
|---|
| 258 |
string message = "Come Get me! I am here. "+ llGetRegionName()+" - "+ (string)llGetPos(); |
|---|
| 259 |
if(GI_KILL_SWITCH == TRUE) { |
|---|
| 260 |
message += " I will clean myself up if you don't pick me up after a while."; |
|---|
| 261 |
} |
|---|
| 262 |
|
|---|
| 263 |
llInstantMessage(llGetOwner(), message); |
|---|
| 264 |
llSetTimerEvent(TICKS * (float)GI_KILL_COUNTER); |
|---|
| 265 |
} |
|---|
| 266 |
|
|---|
| 267 |
touch_start(integer num_detected) { |
|---|
| 268 |
// DEBUG([llDetectedLinkNumber(0)]); |
|---|
| 269 |
if((llDetectedLinkNumber(0) == GI_BUTTON_FLIP) || (llDetectedLinkNumber(0) == GI_BUTTON_FLIP_B)) { |
|---|
| 270 |
GI_HUD_FLIPPED=fn_flip_hud(GI_HUD_FLIPPED); |
|---|
| 271 |
} else if((llDetectedLinkNumber(0) == GI_BUTTON_SHOW) || (llDetectedLinkNumber(0) == GI_BUTTON_HIDE)) { |
|---|
| 272 |
GI_VISIBLE= fn_show_hide_hud(GI_VISIBLE); |
|---|
| 273 |
} |
|---|
| 274 |
} |
|---|
| 275 |
|
|---|
| 276 |
|
|---|
| 277 |
} |
|---|
| 278 |
|
|---|