Progress Bar

This is a script to create very useful and realistic looking progress or health bars. They are suitable for creating quick, direct and visual feedback to a user without resorting to exotic dedicated prim displays.
== Non-License ==
//===================================================//
// Progress Bar v1 //
// "September 24 2009", "04:24:00 GMT-0" //
// By Nexii Malthus //
// Public Domain //
//===================================================//
== Function ==
Progress Bars Function
string Bars( float Cur, integer Bars, list Charset ){
 // Input = 0.0 to 1.0
 // Bars = char length of progress bar
 // Charset = [Blank,<Shades>,Solid];
 integer Shades = llGetListLength(Charset)-1;
 Cur *= Bars;
 integer Solids = llFloor( Cur );
 integer Shade = llRound( (Cur-Solids)*Shades );
 integer Blanks = Bars - Solids - 1;
 string str;
 while( Solids-- >0 ) str += llList2String( Charset, -1 );
 if( Blanks >= 0 ) str += llList2String( Charset, Shade );
 while( Blanks-- >0 ) str += llList2String( Charset, 0 );
 return str; }
== Character Sets ==
These are various characters in Unicode/UTF that may be of use with the progress bar function or for other creative visual indication purposes in hovertext or chat.
// Bars
list Charset_Shade = [" ","░","▒","▓","█"];// Too rough
list Charset_LeftRight = [" ","▏","▎","▍","▌","▋","▊","▉","█"];// Works Best
list Charset_UpDown = [" ","▁","▂","▃","▄","▅","▆","▇","█"];// Good as single-bar progress bar
list Charset_Central = [" ","❘","❙","❚","█"];// Too steppy
list Charset_Braille = ["⠀","⠁","⠃","⠇","⠏","⠟","⠿"];
// Random Single-char
list Charset_Box = ["□","▧","▨","▩","■"];
list Charset_Circle = ["○","◔","◑","◕","●"];
list Charset_Boxes = [" ","▝","▐","▟","█"];
list Charset_Dice = ["⚀","⚁","⚂","⚃","⚄","⚅"];// Hard to perceive detail
list Charset_Tone = ["˩","˨","˧","˦","˥"];
list Charset_Num1 = ["⒈","⒉","⒊","⒋","⒌","⒍","⒎","⒏","⒐","⒑",
 "⒒","⒓","⒔","⒕","⒖","⒗","⒘","⒙","⒚","⒛"];
list Charset_Num2 = ["⑴","⑵","⑶","⑷","⑸","⑹","⑺","⑻","⑼","⑽",
 "⑾","⑿","⒀","⒁","⒂","⒃","⒄","⒅","⒆","⒇"];
list Charset_Num3 = ["①","②","③","④","⑤","⑥","⑦","⑧","⑨","⑩"];
list Charset_Num4 = ["❶","❷","❸","❹","❺","❻","❼","❽","❾","❿"];
list Charset_Num5 = ["➊","➋","➌","➍","➎","➏","➐","➑","➒","➓"];
list Chars_Fill = ["䷁","䷖","䷇","䷏","䷎","䷆","䷗","䷚","䷂","䷲","䷣","䷒","䷨","䷻","䷵","䷊","䷙","䷄","䷡","䷍","䷪","䷀"];
list Chars_Elevator = ["䷗","䷆","䷎","䷏","䷇","䷖"];
// Directional
list Charset_Arrow1 = ["↑","↗","→","↘","↓","↙","←","↖"];
list Charset_Arrow2 = ["⇑","⇗","⇒","⇘","⇓","⇙","⇐","⇖"];
list Charset_Arrow3 = ["⬆","⬈","➨","⬊","⬇","⬋","⬅","⬉"];
// Other character sets I find possibly useful for some application out there
list Charset_Layers = ["⿰","⿱","⿲","⿲","⿳","⿴","⿵","⿶","⿷","⿸","⿹","⿺","⿻"];
== Simple Test ==
list Charset_LeftRight = [" ","▏","▎","▍","▌","▋","▊","▉","█"];
string Bars( float Cur, integer Bars, list Charset ){
 // Input = 0.0 to 1.0
 // Bars = char length of progress bar
 // Charset = [Blank,<Shades>,Solid];
 integer Shades = llGetListLength(Charset)-1;
 Cur *= Bars;
 integer Solids = llFloor( Cur );
 integer Shade = llRound( (Cur-Solids)*Shades );
 integer Blanks = Bars - Solids - 1;
 string str;
 while( Solids-- >0 ) str += llList2String( Charset, -1 );
 if( Blanks >= 0 ) str += llList2String( Charset, Shade );
 while( Blanks-- >0 ) str += llList2String( Charset, 0 );
 return str; }
default {
 touch_start( integer d ){
 float Input;
 integer Length = 10;
 
 for( Input = 0.0; Input < 1.0; Input += 0.02 ){
 string Text = "▕"+Bars( Input, Length, Charset_LeftRight )+"▏";
 llSetText( Text, <0,0,0>, 1.0 );
 llSleep( 0.1 );
 }
 }
}
== Full Test Script ==
string cleanF( float F ){// Clean a float for debug output
 string S = (string)F;
 while( llGetSubString( S, -1, -1 ) == "0" )// Clear zeroes
 S = llGetSubString( S, 0, -2 );
 if( llGetSubString( S, -1, -1 ) == "." )// Cut dot if lone
 S = llGetSubString( S, 0, -2 ); 
 return S; }
float fCub_I( float t, float b, float c, float d ){
 return c * llPow( t/d, 3 ) + b;}
float fCirc_I( float t, float b, float c, float d ){
 return c * ( 1 - llSqrt( 1 - ( t /= d ) * t ) ) + b;}
float fExpo_IO( float t, float b, float c, float d ){
 if( ( t /= d / 2 ) < 1 )
 return c / 2 * llPow( 2, 10 * ( t - 1 ) ) + b;
 return c / 2 * ( -llPow( 2 , -10 * --t ) + 2 ) + b;}
list Charset_Shade = [" ","░","▒","▓","█"];
list Charset_LeftRight = [" ","▏","▎","▍","▌","▋","▊","▉","█"];
list Charset_UpDown = [" ","▁","▂","▃","▄","▅","▆","▇","█"];
list Charset_Central = [" ","❘","❙","❚","█"];
list Charset_Box = ["□","▧","▨","▩","■"];
list Charset_Circle = ["○","◔","◑","◕","●"];
list Charset_Boxes = [" ","▝","▐","▟","█"];
list Charset_Dice = ["⚀","⚁","⚂","⚃","⚄","⚅"];
list Charset_Braille = ["⠀","⠁","⠃","⠇","⠏","⠟","⠿"];
string Bars( float Cur, integer Bars, list Charset ){
 // Input = 0.0 to 1.0
 // Bars = char length of progress bar
 // Charset = [Blank,<Shades>,Solid];
 integer Shades = llGetListLength(Charset)-1;
 Cur *= Bars;
 integer Solids = llFloor( Cur );
 integer Shade = llRound( (Cur-Solids)*Shades );
 integer Blanks = Bars - Solids - 1;
 string str;
 while( Solids-- >0 ) str += llList2String( Charset, -1 );
 if( Blanks >= 0 ) str += llList2String( Charset, Shade );
 while( Blanks-- >0 ) str += llList2String( Charset, 0 );
 return str; }
float Energy = 40.0;
float EnergyCap = 100.0;
float Dir = 1;
default {
 state_entry(){
 llSetText("", <.0,.5,1.>, 1 );
 llSetTimerEvent( 0.1 );
 }
 
 timer(){
 Energy += 2 * Dir;
 if( Energy > EnergyCap ){
 Energy = EnergyCap; Dir = -Dir;
 } else if( Energy < 0 ){
 Energy = 0; Dir = -Dir;
 }
 
 float t = Energy / EnergyCap;
 
 float Bar1 = t;
 float Bar2 = fCirc_I(t,0,1,1);
 float Bar3 = fExpo_IO(1-t,0,1,1);
 float Bar4 = t;
 
 string Text;
 if( Dir == TRUE ) Text += "⟾ ";
 else Text += "⟸ ";
 Text += Bars( Bar1, 10, Charset_LeftRight )+"\n";
 Text += Bars( Bar2, 8, Charset_UpDown )+"\n";
 Text += Bars( Bar2, 8, Charset_Braille )+"\n";
 Text += Bars( Bar3, 8, Charset_Shade )+"\n⟦ ";
 if( Dir == TRUE ) Text += "► ";
 else Text += "◄ ";
 Text += Bars( Bar4, 1, Charset_LeftRight )+" | ";
 if( Dir == TRUE ) Text += "▲ ";
 else Text += "▼ ";
 Text += Bars( Bar4, 1, Charset_UpDown )+" | ";
 Text += Bars( Bar4, 1, Charset_Central )+" ⟧\n⟦ ";
 Text += Bars( Bar4, 1, Charset_Box )+" | ";
 if( Dir == TRUE ) Text += "⟳ ";
 else Text += "⟲ ";
 Text += Bars( Bar4, 1, Charset_Circle )+" ";
 Text += Bars( Bar4, 1, Charset_Boxes )+" ⟧\n";
 Text += "\n"+cleanF(Energy)+" / "+cleanF(EnergyCap);
 
 vector Color = llVecNorm(<1-t,t,0>);
 llSetText(Text,Color,1);
 }
}