/////////////////////////////////////////////////////////// // // Car Engine v2.3.3 by Fumi.Iseki // // /868 start // /868 stop // /868 delete // // /868 reset // vector sit_position = <0.0, 0.0, 0.01>; string sit_anim_name = "drive"; float camera_pitch = 15.0; integer debug_mode = FALSE; integer race_mode = FALSE; integer meter_mode = FALSE; integer stop_flag = FALSE; // Env Parameter integer sim_num = 3; // float boundary_max = 2550.0; float boundary_min = 0.0; float boundary_err = 5.0; float limit_ground = 3.0; // Engine float maxSpeed = 30.0; float backSpeed = 10.0; // maxSpeed/3.0; float accel_rate = 0.5; integer turn_max = 50; float turn_rate = 3.0; float turn_div = 0.6; // turn_rate/turn_max*10.0; integer use_stabilizer = FALSE; float stop_speed = 0.4; float dfltdtime = 0.5; // // Note Card string notecard_name = "car.conf"; key notecard_key = NULL_KEY; integer notecard_line = 0; // Channel integer speed_channel = 858; integer starter_channel = 868; // Work integer listen_starter = 0; integer ride_on = FALSE; integer start_on = FALSE; integer turn_direct = 0; // forward integer turn_rcount = 0; integer turn_lcount = 0; key driver = NULL_KEY; key engine = NULL_KEY; //integer inObjCollision = FALSE; //integer inGrdCollision = FALSE; //integer falling_max = 3; //integer falling_count = 0; //// float speed = 0.0; float acceler = 0.0; vector motor = <0.0, 0.0, 0.0>; ///////////////////////////////////////////////////////////////////////// // Setting of Physical Parameters init_physical_param() { llSetVehicleType(VEHICLE_TYPE_CAR); //car llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.01); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.2); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.5); llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <50.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <10.0, 10.0, 1000.0>); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 1.0); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1.0); llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 1.0); llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.1); llSetTimerEvent(dfltdtime); } reset_physical_param() { llSetTimerEvent(0.0); llSetVehicleType(VEHICLE_TYPE_NONE); // stop the motors llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0.0, 0.0, 0.0>); llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <0.0, 0.0, 0.0>); llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, 0.0); llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 0.0); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.0); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.0); llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.0); llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.0); llSetVehicleType(VEHICLE_TYPE_NONE); } ///////////////////////////////////////////////////////////////////////// // Setting of Initail Parameter and Configuration Faile init_params() { speed = 0.0; acceler = 0.0; motor = <0.0, 0.0, 0.0>; // show_text(""); } normalize_params() { backSpeed = maxSpeed/3.0; boundary_min = boundary_err; boundary_max = 255.0*sim_num - boundary_err; if (debug_mode) { llSay(0, "Boundary Min is "+(string)boundary_min + " m"); llSay(0, "Boundary Max is "+(string)boundary_max + " m"); llSay(0, "Boundary Err is "+(string)boundary_err + " m"); } } // ノートカードの読み込み read_conf() { llResetTime(); notecard_line = 0; if (llGetInventoryType(notecard_name)==INVENTORY_NOTECARD) { notecard_key = llGetNotecardLine(notecard_name, 0); } else { normalize_params(); } } // ノートカードからの読み込みデータの解釈 parse_conf_file(string str, integer say) { list items = llParseString2List(str,["=", ",", " ", "\n"], []); string name = llList2String(items,0); string value = llList2String(items,1); if (name == "debug_mode") { integer flg = (integer)value; if (flg>0) { debug_mode = TRUE; llSay(0, "Debug Mode ON"); } } else if (name == "race_mode") { integer flg = (integer)value; if (flg>0) { race_mode = TRUE; if (say) llSay(0, "Racing Mode ON"); } } else if (name == "meter_mode") { integer flg = (integer)value; if (flg>0) { meter_mode = TRUE; if (say) llSay(0, "Speed Meter Mode ON"); } } else if (name == "sim_num") { sim_num = (integer)value; if (say) llSay(0, "Number of SIM is " + value); } else if (name == "sit_pos_x") { sit_position.x = (float)value; llSitTarget(sit_position, ZERO_ROTATION); if (say) llSay(0, "Sit Pos X is " + value + " m"); } else if (name == "sit_pos_y") { sit_position.y = (float)value; llSitTarget(sit_position, ZERO_ROTATION); if (say) llSay(0, "Sit Pos Y is " + value + " m"); } else if (name == "sit_pos_z") { sit_position.z = (float)value; llSitTarget(sit_position, ZERO_ROTATION); if (say) llSay(0, "Sit Pos Z is " + value + " m"); } else if (name == "maxSpeed") { maxSpeed = (float)value; backSpeed = maxSpeed/3.0; if (say) llSay(0, "Max Speed is " + value + " m/s"); } else if (name == "turn_max") { turn_max = (integer)value; turn_div = turn_rate/turn_max*10.0; if (say) llSay(0, "Turn Max is " + value); } else if (name == "turn_rate") { turn_rate = (float)value; turn_div = turn_rate/turn_max*10.0; if (say) llSay(0, "Turn Rate is " + value); } else if (name == "accel_rate") { accel_rate = (float)value; if (say) llSay(0, "Accel Rate is " + value); } else if (name == "boundary") { boundary_err = (float)value; if (say) llSay(0, "Boundary is " + value + " m"); } // else if (name == "stabilizer") { integer flg = (integer)value; if (flg>0) { use_stabilizer = TRUE; if (say) llSay(0, "Stabilizer ON"); } } return; } ///////////////////////////////////////////////////////////////////////// // Debug and HUD support show_text(string str) { vector col = <0.1, 1.0, 1.0>; llSetText(str + "\n \n \n" , col, 2.0); } send_speed_meter(float speed) { llSay(speed_channel, "DATA " + (string)driver + " " + (string)speed); } ///////////////////////////////////////////////////////////////////////// // Boundary and Over Run check_over_run(vector pos) { if (pos.xboundary_max || pos.yboundary_max) { llSay(0, "領域オーバー!"); crash_car(0.0); } else if (pos.xboundary_max-boundary_err || pos.yboundary_max-boundary_err) { llSay(0, "注意:境界近し!!"); } } explosion() { llSay(0,"コースアウト!"); crash_car(3.0); } crash_car(float wait) { if (meter_mode) llShout(speed_channel, "RESET " + (string)driver); llMessageLinked(LINK_THIS, 4, "Explosion", NULL_KEY); if (listen_starter!=0) llListenRemove(listen_starter); listen_starter = 0; llReleaseControls(); init_params(); reset_physical_param(); llSleep(wait); llStopAnimation(sit_anim_name); llDie(); } ///////////////////////////////////////////////////////////////////////// // Engine Control stop_car() { llReleaseControls(); // init_params(); reset_physical_param(); llSetStatus(STATUS_PHYSICS, FALSE); if (meter_mode) llSay(speed_channel, "RESET " + (string)driver); llMessageLinked(LINK_ALL_CHILDREN, 3, "MOTEROFF", ""); llMessageLinked(LINK_ALL_CHILDREN, 9, "STOP", ""); llMessageLinked(LINK_ALL_CHILDREN, 3, "JETOFF", ""); } ///////////////////////////////////////////////////////////////////////// // Control stabilizer(float ratex) { rotation rot = llGetRot(); vector vcty = llRot2Left(rot); float dot = vcty.x*vcty.x + vcty.y*vcty.y; if (dot<1.0 && dot>-1.0) { float th = llAcos(dot); if (th>ratex) { if (vcty.z>0) th = -th; vector vctx = llRot2Fwd(rot); llSetRot(rot*llAxisAngle2Rot(vctx, th/2.0)); } } } float get_fwd_speed_vel(vector vel) { vector fwd = llRot2Fwd(llGetRot()); float xspeed = vel.x*fwd.x + vel.y*fwd.y; return xspeed; } check_ground(vector pos) { if ((!debug_mode) && start_on && race_mode) { float carz = pos.z - llGround(<0.0, 0.0, 0.0>); if (carz<=limit_ground) explosion(); } } check_status() { vector pos = llGetPos(); if (race_mode) check_ground(pos); check_over_run(pos); //if ((!inObjCollision) && (!inGrdCollision)) falling_count++; // vector vel = llGetVel(); speed = get_fwd_speed_vel(vel); if (speed>stop_speed) { llMessageLinked(LINK_ALL_CHILDREN, 3, "JETON", ""); } else { llMessageLinked(LINK_ALL_CHILDREN, 3, "JETOFF", ""); } // if (meter_mode) { send_speed_meter(speed); } else { float disp = (integer)((speed*3.6)*100)/100.0; show_text((string)disp); } return; } control_key_handle(integer level, integer edge) { /* if (falling_count>=falling_max) { //llSay(0, "落下中! count = "+(string)falling_count); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, ); // turn_rcount = 0; turn_lcount = 0; return; }*/ // integer angule_acl = FALSE; integer linear_acl = FALSE; integer handle_turn = 0; // forward float grv_accel = 0.0; speed = get_fwd_speed_vel(llGetVel()); //llSay(0, "SPEED = "+(string)speed); if (level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) { angule_acl = TRUE; handle_turn = 1; // right turn_lcount = 0; if (turn_rcount=0.0) motor.z = -turn_div*turn_rcount/(llSqrt( speed+maxSpeed)); else motor.z = turn_div*turn_rcount/(llSqrt(-speed+maxSpeed)); //llSay(0, "Right "+(string)motor.z+" "+(string)turn_rcount); } else if (level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) { angule_acl = TRUE; handle_turn = 2; // left turn_rcount = 0; if (turn_lcount=0.0) motor.z = turn_div*turn_lcount/(llSqrt( speed+maxSpeed)); else motor.z = -turn_div*turn_lcount/(llSqrt(-speed+maxSpeed)); //llSay(0, "Left "+(string)motor.z+" "+(string)turn_lcount); } else { if (turn_rcount>0) turn_rcount--; if (turn_lcount>0) turn_lcount--; } if (level & CONTROL_FWD) { linear_acl = TRUE; if (speed>=-backSpeed && speed0) grv_accel = -acceler/3.0; llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, ); } if (angule_acl) { //llSay(0, "ROT "+(string)motor.z); llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, motor); } } get_key_control() { integer anglControls = CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT; integer lineControls = CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP; llTakeControls(anglControls | lineControls, TRUE, FALSE); //llWhisper(0, "Get Key Control"); } ///////////////////////////////////////////////////////////////////////// // default State default { // ノートカードが一行読まれる度に発生するイベント dataserver(key requested_key, string data) { if (requested_key == notecard_key ){ notecard_key = NULL_KEY; if (data != EOF){ parse_conf_file(data, debug_mode); notecard_line++; notecard_key = llGetNotecardLine(notecard_name, notecard_line); } else { normalize_params(); } } } state_entry() { llSetSitText("Ride"); llCollisionSound("", 0.0); llSitTarget(sit_position, ZERO_ROTATION); llSetStatus(STATUS_DIE_AT_EDGE, TRUE); llSetStatus(STATUS_PHYSICS, FALSE); read_conf(); init_params(); // if (listen_starter!=0) llListenRemove(listen_starter); listen_starter = llListen(starter_channel, "", "", ""); if (listen_starter<0) { llShout(0, "ERROR: LISTEN CHANNEL is "+(string)listen_starter); } } on_rez(integer param) { llResetScript(); llSetStatus(STATUS_PHYSICS, FALSE); } timer() { check_status(); // if (stop_flag) { stop_car(); stop_flag = FALSE; } } changed(integer change) { if (change & CHANGED_LINK) { key agent = llAvatarOnSitTarget(); if (agent!=NULL_KEY) { driver = agent; engine = llGetLinkKey(1); llMessageLinked(LINK_ALL_CHILDREN, 1, "DRIVER", driver); llMessageLinked(LINK_ALL_CHILDREN, 2, "CORE", llGetKey()); llMessageLinked(LINK_ALL_CHILDREN, 3, "MOTERON", ""); if (meter_mode) { llSay(speed_channel, "START " + (string)driver + " " + (string)maxSpeed + " "); if (debug_mode) llSay(0, "START " + (string)driver + " " + (string)maxSpeed + " "); } llSetStatus(STATUS_PHYSICS, TRUE); llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]); init_physical_param(); llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA); get_key_control(); llStopAnimation("sit"); llStartAnimation(sit_anim_name); llSay(0, "Ride ON!!"); ride_on = TRUE; if ((!race_mode)) { llSay(0, "Engine Start!!"); start_on = TRUE; llMessageLinked(LINK_ALL_CHILDREN, 9, "START", ""); } // if (use_stabilizer) stabilizer(0.0); // llMessageLinked(LINK_ALL_CHILDREN, 3, "JETON", ""); llSleep(0.3); llMessageLinked(LINK_ALL_CHILDREN, 3, "JETOFF", ""); } else { stop_car(); llSay(0, "Ride OFF!!"); ride_on = FALSE; llStopAnimation(sit_anim_name); if ((!debug_mode) && start_on && race_mode) { llSleep(3.0); llDie(); } } } // else { llResetScript(); } } run_time_permissions(integer perm) { if (perm!=0) { llClearCameraParams(); llSetCameraParams([ CAMERA_ACTIVE, 1, // 1 は有効, 0 は無効 CAMERA_BEHINDNESS_ANGLE, 30.0, // (0 〜 180) 度 CAMERA_BEHINDNESS_LAG, 0.0, // (0 〜 3) 秒 CAMERA_DISTANCE, 8.0, // ( 0.5 〜 10) メートル CAMERA_FOCUS_LAG, 0.0 , // (0 〜 3) 秒 CAMERA_FOCUS_LOCKED, FALSE, // (TRUE または FALSE) CAMERA_FOCUS_THRESHOLD, 0.0, // (0 〜 4) メートル CAMERA_PITCH, camera_pitch, // (-45 〜 80) 度 CAMERA_POSITION_LAG, 0.0, // (0 〜 3) 秒 CAMERA_POSITION_LOCKED, FALSE, // (TRUE または FALSE) CAMERA_POSITION_THRESHOLD, 0.0, // (0 〜 4) メートル CAMERA_FOCUS_OFFSET, <2.0, 0.0, 0.0> // <-10,-10,-10> 〜 <10,10,10> メートル ]); } } control(key id, integer level, integer edge) { if (start_on) control_key_handle(level, edge); if (use_stabilizer) stabilizer(0.174); } /* collision(integer num_detected){ //llSay(0, "COLLISION ING"); inObjCollision = TRUE; falling_count = 0; } collision_start(integer num_detected){ //llSay(0, "COLLISION SRT"); inObjCollision = TRUE; falling_count = 0; } collision_end(integer num_detected) { //llSay(0, "COLLISION OFF"); inObjCollision = FALSE; } land_collision(vector pos) { inGrdCollision = TRUE; falling_count = 0; } land_collision_start(vector pos) { inGrdCollision = TRUE; falling_count = 0; } land_collision_end(vector pos) { inGrdCollision = FALSE; }*/ listen(integer ch, string name, key id, string mesg) { if (ch==starter_channel) { // list items = llParseString2List(mesg,[" "],[]); string cmd = llList2String(items,0); string uid = llList2String(items,1); // if (llToLower(cmd)=="start") { if (ride_on) { start_on = TRUE; llMessageLinked(LINK_ALL_CHILDREN, 9, "START", ""); } } // else if (llToLower(cmd)=="stop") { if (ride_on && race_mode) { if (uid==(string)engine) { llSetTimerEvent(0.0); llResetTime(); llSetTimerEvent(3.0); llResetTime(); stop_flag = TRUE; } } } // else if (llToLower(cmd)=="reset") { llResetScript(); read_conf(); init_params(); llSetStatus(STATUS_PHYSICS, FALSE); } // // else if (llToLower(cmd)=="delete") { if ((!ride_on) && race_mode) { llListenRemove(listen_starter); listen_starter = 0; llDie(); } } // else if (llToLower(cmd)=="forcedel") { if (race_mode) { llListenRemove(listen_starter); listen_starter = 0; llDie(); } } } } }