Pour pallier à certains carences du premier script (absence de rotations verticales) et introduire une architecture plus pro. Je vous présente le :
et à compiler comme dab.
La box sera transformée ...en tapis volant équipé d'un petit moteur de... F16 (bridé à cause M Lag).
Sous l'aspect fun c'est un produit sérieux, sous l'aspect sérieux c'est un produit ludique..
Just enjoy it and have fun...
// _________________________________________________
//
// Record & Travel
//
// Record your avatar pos & rot and replay them
//
// By Sebastien Pfalz on September 2009
//
//
// _________________________________________________
// .: Constants :.//
string PRODUCT = "Record & Travel";
string VERSION = "V1.1";
string SCRIPT_NAME = "Recording & Traveling";
integer MAX_RECORDS = 1200;
integer WAITING = 0;
integer RECORDING = 1;
integer TRAVELING = 2;
integer SETTINGS = 3;
integer PLAYING = 4;
integer PLAY_LOW = 2;
integer REC_LOW = 2;
integer PLAY_NORMAL = 3;
integer REC_NORMAL = 3;
integer PLAY_HIGH = 5;
integer REC_HIGH = 5;
vector CAM_OFFSET = <-5.0, 0.0, 2.0>;
vector CAM_ANG = <0.0, 0.0, 2.0>;
vector GREEN = < 0.0, 1.0, 0.0 >;
vector RED = < 1.0, 0.0, 0.4 >;
vector WHITE = < 1.0, 1.0, 1.0 >;
float ALPHA = 1;
float ROT_RAD = 0;
list SIT_PARAMS = [<-0.2,0.0,0.8>, <0.0, 0.0, 0.0>];
// .: Variables :.//
vector Size = <2.2,1.2,0.01>;
vector Repeats = < 1.0, 0.9, 1.0 >;
vector Offsets = ZERO_VECTOR;
key Rug_Texture = "22aca67a-946a-fae7-448c-8da90265b34a";
key Avatar_Siting;
integer Listen_Handle;
integer Channel1;
integer Dialog_Channel;
key Owner;
integer Status;
string Number_Records;
list Pos_Rot;
vector Origin_Pos;
list Travels = ["Tour 1"];
string Desc_Travels = "1. Visit of the region";
string Menu_Selected;
// Parameters record & play
float Record_PosBySeconds = 3;
float Play_PosBySeconds = 3;
// variable Motor
float X_THRUST = 20;
float Z_THRUST = 15;
float xMotor;
float zMotor;
integer Sit;
// .: Functions :.//
Play()
{ // move across the land with the pos & rot recorded before
integer i;
vector pos;
rotation rot;
llSetStatus(STATUS_PHYSICS, TRUE); // set the object physical
Hover_Text ( " Travelling..", GREEN );
for ( i = 0; i < llGetListLength(Pos_Rot); i = i +2 )
{ // move to pos and do the rotate
pos = (vector)llList2String(Pos_Rot,i);
rot = (rotation)llList2String(Pos_Rot,i+1);
llMoveToTarget(pos,1);
llRotLookAt( rot , 1, 1 );
llSleep (1.0/Play_PosBySeconds); // same that the recording but can be different too
}
llSetStatus(STATUS_PHYSICS, FALSE); // remove the status physical
llSetRot( ZERO_ROTATION); // remove the last rotation
Hover_Text ( " End of the travel..", GREEN );
}
Record_Proc()
{
Pos_Rot = [];
Origin_Pos = llGetPos();
llSetTimerEvent ( 1/Record_PosBySeconds );
}
integer Channel(key uuid) // Retourne un channel (integer)
{
return (integer)("0x"+ llGetSubString((string)uuid,-8,-1)) + 5478; // UUID + secure number
}
Warp_Pos( vector destpos)
{
// Compute the number of jumps necessary
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
// Try and avoid stack/heap collisions
if (jumps > 100 )
jumps = 100; // 1km should be plenty
list rules = [ PRIM_POSITION, destpos ]; //The start for the rules list
integer count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
}
Hover_Text ( string text , vector color )
{
llSetText ( text ,color,1.0 ); // show the recording
}
Init()
{
Owner = llGetOwner();
llSetTimerEvent(0);
llSetSitText("Sit");
llSetStatus(STATUS_PHYSICS, FALSE);
llSitTarget(llList2Vector(SIT_PARAMS,0),llList2Rot(SIT_PARAMS,1));
Status = WAITING;
Hover_Text ( "Click to get the menu...", GREEN );
}
Build_Rug ()
{
llSetPrimitiveParams([ PRIM_SIZE, Size,
PRIM_FULLBRIGHT, ALL_SIDES, TRUE,
PRIM_TEXTURE, ALL_SIDES, Rug_Texture, Repeats, Offsets, ROT_RAD,
PRIM_COLOR, ALL_SIDES, WHITE, ALPHA
]);
llSetObjectName ( PRODUCT + " " + VERSION );
llSetObjectDesc ( "For JOL");
if ( llGetScriptName() != SCRIPT_NAME )
llOwnerSay ( "Please the script the script inside " + PRODUCT + " " + VERSION + " \n\t> " + SCRIPT_NAME + " <");
}
default
{
on_rez(integer params)
{
Build_Rug (); // noone knows...
Init();
}
state_entry()
{
if ( llGetObjectName () != (PRODUCT + " " + VERSION) )
Build_Rug();
Init();
Dialog_Channel = Channel(llGetKey());
Listen_Handle = llListen(Dialog_Channel ,"", "","");
}
touch_start(integer total_number)
{
llListen(Dialog_Channel,"",llGetOwner(),"");
if ( llDetectedKey(0) == Owner)
{
list buttons = ["Play","Record","Travel","Settings"];
llDialog( llGetOwner(),"Please select...\n\n ",buttons, Dialog_Channel);
}
else
{ Menu_Selected = "Travel";
llDialog( llGetOwner(),"Please select... your travel\n\n" + Desc_Travels, Travels, Dialog_Channel);
}
}
listen( integer channel, string name, key id, string message )
{
if (channel == Dialog_Channel )
{
if ( message == "Play" )
{
Status = PLAYING;
state Record;
}
if ( message == "Record" )
{
Menu_Selected = "Record";
llDialog( llGetOwner(),"Please select... the travel\n\n ",Travels, Dialog_Channel);
}
else if ( message == "Settings" )
{
Status = SETTINGS;
state Settings;
}
else if ( message == "Travel" )
{
Menu_Selected = "Travel";
llDialog( llGetOwner(),"Please select... the travel\n\n ",Travels, Dialog_Channel);
}
else if ( !llListFindList( Travels, [message] ) && Menu_Selected == "Record")
{
Status = RECORDING;
state Record;
}
else if ( !llListFindList( Travels, [message] ) && Menu_Selected == "Travel")
{
Status = TRAVELING;
state Travel;
}
}
}
}
state Travel
{
on_rez(integer params)
{
state default;
}
state_entry()
{
Hover_Text ( " Sit to travel...", RED );
llSetSitText("Travel");
llSetCameraEyeOffset(CAM_OFFSET);
llSetCameraAtOffset(CAM_ANG);
Dialog_Channel = Channel(llGetKey());
Listen_Handle = llListen(Dialog_Channel ,"", "","");
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
Avatar_Siting = llAvatarOnSitTarget();
if (llAvatarOnSitTarget() != NULL_KEY)
llRequestPermissions(Avatar_Siting,PERMISSION_TRIGGER_ANIMATION );
}
}
run_time_permissions(integer perms)
{
if(perms)
{
llStopAnimation("sit");
llStartAnimation("sit_ground");
Play();
llOwnerSay ( "End of the travel...");
llSleep(4);
llUnSit(Avatar_Siting);
state default;
}
else
llUnSit(Avatar_Siting);
}
}
state Settings
{
on_rez(integer params)
{
state default;
}
state_entry()
{
Init();
llListen(Dialog_Channel,"",llGetOwner(),"");
list buttons = ["Low","Normal","High","OK"];
llDialog( llGetOwner(),"Modify the parameters \n of resolution\n \nLow = 2 Positions/Second \nNormal = 3 Positions/Second \nHight = 5 Positions/Second ",buttons, Dialog_Channel);
}
listen( integer channel, string name, key id, string message )
{
if (channel == Dialog_Channel )
{
if ( message == "Low" )
{
Play_PosBySeconds = PLAY_LOW;
Record_PosBySeconds = REC_LOW;
}
else if ( message == "Normal" )
{
Play_PosBySeconds = PLAY_NORMAL;
Record_PosBySeconds = REC_NORMAL;
}
else if (message == "High" )
{
Play_PosBySeconds = PLAY_HIGH;
Record_PosBySeconds =REC_HIGH;
}
else if ( message == "OK" )
state default;
list buttons = ["Low","Normal","High","OK"];
llDialog( llGetOwner(),"Modify the parameters \n of resolution\n \nLow = 2 Positions/Second \nNormal = 3 Positions/Second
\nHigh = 5 Positions/Second ",buttons, Dialog_Channel);
}
}
}
state Record
{
on_rez(integer params)
{
state default;
}
state_entry()
{
if ( Status == PLAYING)
{
Origin_Pos = llGetPos();
llSetSitText("Play!");
Hover_Text ( " Sit to start playing...", RED );
}
else
{
llSetSitText("Record");
Hover_Text ( " Sit to start recording...", RED );
}
llListen(Dialog_Channel,"",llGetOwner(),"");
llSetCameraEyeOffset(CAM_OFFSET);
llSetCameraAtOffset(CAM_ANG);
//SET VEHICLE PARAMETERS
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, <200, 20, 20> );
// uniform angular friction
llSetVehicleFloatParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, 2 );
// linear motor
llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, 2 );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 120 );
// agular motor
llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0 );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, .4);
// hover
llSetVehicleFloatParam( VEHICLE_HOVER_HEIGHT, 2 );
llSetVehicleFloatParam( VEHICLE_HOVER_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_HOVER_TIMESCALE, 10000 );
llSetVehicleFloatParam( VEHICLE_BUOYANCY, 0.977 );
// no linear deflection
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 5 );
// no angular deflection
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0);
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 5);
// no vertical attractor
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 1 );
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1 );
// banking
llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 1);
llSetVehicleFloatParam( VEHICLE_BANKING_MIX, .5);
llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 0.01);
// default rotation of local frame
llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME, <0,0,0,1>);
// remove these flags
llRemoveVehicleFlags( VEHICLE_FLAG_NO_DEFLECTION_UP
| VEHICLE_FLAG_HOVER_WATER_ONLY
| VEHICLE_FLAG_LIMIT_ROLL_ONLY
| VEHICLE_FLAG_HOVER_TERRAIN_ONLY
| VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT
| VEHICLE_FLAG_HOVER_UP_ONLY
| VEHICLE_FLAG_LIMIT_MOTOR_UP );
}
touch_start(integer total_number)
{
llDialog( llGetOwner(),"\n Stop the recording...",["STOP"], Dialog_Channel);
}
listen( integer channel, string name, key id, string message )
{
if (channel == Dialog_Channel && message == "STOP" )
{
llSetTimerEvent (0);
if ( Status == PLAYING)
Hover_Text ( ";-) It was fun thanks!", GREEN );
else
Hover_Text ( " Stopped " + Number_Records + " positions recorded ", RED );
llSleep (5);
state default;
}
}
// DETECT AV SITTING/UNSITTING AND GIVE PERMISSIONS
changed(integer change)
{
Avatar_Siting = llAvatarOnSitTarget();
if(change & CHANGED_LINK)
{
if((Avatar_Siting == NULL_KEY) && (Sit))
{// Avatar gets off vehicle
llSetStatus(STATUS_PHYSICS, FALSE);
Warp_Pos(Origin_Pos); // long deplacement.....
llStopAnimation("sit_ground");
llReleaseControls();
Sit = FALSE;
llSetTimerEvent (0);
Hover_Text ( " Stopped " + Number_Records + " positions recorded ", RED );
state default;
}
else if ((Avatar_Siting == Owner) && (!Sit))
{ // Avatar gets on vehicle
llSetStatus(STATUS_PHYSICS, TRUE);
Sit = TRUE;
llRequestPermissions(Avatar_Siting, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
}
else if (Avatar_Siting != Owner)
llUnSit(Avatar_Siting);
}
}
//CHECK PERMISSIONS AND TAKE CONTROLS
run_time_permissions(integer perm)
{
if ( Status == RECORDING)
Record_Proc();
else
Hover_Text ( " To stop... Click and STOP. ", RED );
if (perm & (PERMISSION_TAKE_CONTROLS))
{
llTakeControls( CONTROL_UP|CONTROL_DOWN|CONTROL_FWD|CONTROL_BACK|CONTROL_RIGHT|
CONTROL_LEFT|CONTROL_ROT_RIGHT|CONTROL_ROT_LEFT,
TRUE,FALSE);
}
if (perm & PERMISSION_TRIGGER_ANIMATION)
{
// Admittedly, animations are bugged. I'll let you figure it out. :) -CT
llStartAnimation("sit_ground");
llStopAnimation("sit");
}
}
//FLIGHT CONTROLS
control(key id, integer level, integer edge)
{
vector angular_motor;
integer motor_changed;
if ((level & CONTROL_FWD) || (level & CONTROL_BACK))
{
if (edge & CONTROL_FWD) xMotor = X_THRUST;
if (edge & CONTROL_BACK) xMotor = -X_THRUST;
}
else
xMotor = 0;
if ((level & CONTROL_UP) || (level & CONTROL_DOWN))
{
if (level & CONTROL_UP)
zMotor = Z_THRUST;
else if (level & CONTROL_DOWN)
zMotor = -Z_THRUST;
}
else
zMotor = 0;
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <xMotor,0,zMotor>);
if (level & CONTROL_RIGHT){
angular_motor.x = 3*PI;
angular_motor.y /= 8;
}
else if (level & CONTROL_LEFT) {
angular_motor.x = -3*PI;
angular_motor.y /= 8;
}
else if (level & CONTROL_ROT_RIGHT) {
angular_motor.x = TWO_PI;
angular_motor.y /= 8;
}
else if (level & CONTROL_ROT_LEFT) {
angular_motor.x = -TWO_PI;
angular_motor.y /= 8;
}
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);
}
timer()
{
integer list_length = llGetListLength(Pos_Rot);
if ( llGetFreeMemory() < 500 || list_length == MAX_RECORDS )
{
llOwnerSay ( "The memory of this script is almost full...We must stop the recording and come back!");
llSetStatus(STATUS_PHYSICS,FALSE);
Warp_Pos(Origin_Pos); // long deplacement.....
state default;
}
Pos_Rot += llGetObjectDetails(Owner, [ OBJECT_POS, OBJECT_ROT]);
Number_Records = (string) list_length;
integer memory_used = llRound((list_length*1.0/MAX_RECORDS)*100);
if ( memory_used < 90 )
Hover_Text ( Number_Records + " positions stored in list\n" + (string) memory_used + "% memory used", GREEN );
else
Hover_Text ( Number_Records + " positions stored in list\n" + (string) memory_used + "% memory used", RED );
}
}