YaK:: Bedstraw Locomotive 202 notes [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   
[mega_changes]
[photos]

Bedstraw Locomotive 202 notes

Bedstraw Locomotive 202:
// Train 201.  (C) Strick Unknown.  Bedstraw(128,128).
integer Physical;
integer gAngularControls;
integer gLinearControls;
integer Speed;
integer TTL;
integer WasSatOn;
integer UnixTimeLinked;
vector Corner;
vector Bedstraw;
vector Prev;
float Meters;
float VERTICAL_PRESSURE = -0.2;
integer TICK = 2;
integer MAX_IDLE = 900; // 15 min

Init() {
    llSetVehicleType(VEHICLE_TYPE_CAR);
    llSetVehicleFlags( VEHICLE_FLAG_NO_DEFLECTION_UP );

    llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0,1,1>);
    llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <3,1,1>);

    llSitTarget( <-1.8,0,1.5>, ZERO_ROTATION );
    llSetSitText("Ride");
    llSetCameraEyeOffset(<-3, 0, 3>);
    llSetCameraAtOffset(<2.5, 0, 1>);

    Phys(FALSE);

    // define these here for convenience later
    gAngularControls = CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT ;
    gLinearControls = CONTROL_UP | CONTROL_DOWN | CONTROL_BACK | CONTROL_FWD;
    Bedstraw = <1011,1023,0>;
}

Phys(integer how) {llSetStatus(STATUS_PHYSICS, how); Physical= how;}

UnPhys(integer verbose) {
    if (Physical) {
        ReSpeed(0);
        Phys(FALSE);
        if (verbose) llWhisper(0,
          "Physics OFF.  (Hit PAGE DOWN to restore.)");
    }
}
RePhys(integer verbose) {
    if (!Physical) {
        Phys(TRUE);
        ReSpeed(0);
        llWhisper(0,
          "Physics ON.  (Hit SHIFT LEFT or SHIFT RIGHT to side out & freeze.)");
    }
}
ReSpeed(integer s) {
    llSetVehicleVectorParam(
      VEHICLE_LINEAR_MOTOR_DIRECTION, <s, 0, VERTICAL_PRESSURE>);
    if (Speed != s) {
        llWhisper(0, HowFar() + "Speed: "+(string)s);
        Speed = s;
    }
}

RotImp(integer k) {
    llApplyRotationalImpulse(<0, 0, k>, TRUE);
}
SideOutLeft(float y) {
    llSetPos(llGetPos() + y*llRot2Left(llGetRot()));
}
SideOutFwd(float x) {
    llSetPos(llGetPos() + x*llRot2Fwd(llGetRot()));
}
string HowFar() {
    integer ut = llGetUnixTime();
    integer im = (integer)Meters;
    return  "{"+ (string)im+"m "+(string)(ut-UnixTimeLinked)+"s} ... ";
}

default {
    on_rez(integer a) {
        TTL = -1;
    }
    state_entry() {
        Init();
        if (TTL >= 0) TTL = 0;
        Corner = llGetRegionCorner();
        Prev = Corner + llGetPos();
        llSetTimerEvent(TICK);
    }
    changed(integer change) {
        if (change & CHANGED_LINK) {
            key agent = llAvatarOnSitTarget();
            llOwnerSay("llAvatarOnSitTarget() " + (string)agent);
            if (agent) {
                llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
                TTL = 300;
                WasSatOn = TRUE;
                UnixTimeLinked = llGetUnixTime();
                Corner = llGetRegionCorner();
                Prev = Corner + llGetPos();
                llSetTimerEvent(2);
            } else if (WasSatOn) {
                // driver is getting up
                llReleaseControls();
                llStopAnimation("sit");
                llSleep( 1.0 );
                Phys(FALSE);
                WasSatOn = FALSE;
                state limbo;
            } else {
                llSay(0, "Stray UNLINK Event!");
            }
        }
    }
    run_time_permissions(integer perm)
    {
        if (perm)
        {
            llStartAnimation("sit");
            llTakeControls(gAngularControls | gLinearControls, TRUE, FALSE);
            RePhys(0);
            llWhisper(0, "###### Important Hints:");
            llWhisper(0, "###### Use PAGE UP to move to nearest rails.");
            llWhisper(0, "###### Use PAGE DOWN to reverse direction (180 degrees).");
            llWhisper(0, "###### SHIFT LEFT, SHIFT RIGHT to side out & stop Physics.");
            llWhisper(0, "###### FWD, BACK, LEFT, RIGHT drive as normal.");
        }
    }
    control(key id, integer level, integer edge)
    {
        TTL = 0;
        if (level & edge & CONTROL_FWD ) {
            if (Physical) ReSpeed(Speed + 2); else SideOutFwd(4);
        } else if (level & edge & CONTROL_BACK ) {
            if (Physical) ReSpeed(Speed - 2); else SideOutFwd(-4);
        } else if (level & CONTROL_ROT_LEFT ) {
            if (Physical) RotImp(100); else SideOutLeft(4);
        } else if (level & CONTROL_ROT_RIGHT ) {
            if (Physical) RotImp(-100); else SideOutLeft(-4);
        } else if (level & CONTROL_LEFT ) {
            UnPhys(1);
            SideOutLeft(4);
        } else if (level & CONTROL_RIGHT ) {
            UnPhys(1);
            SideOutLeft(-4);
        } else if (level & edge & CONTROL_UP ) {
            llSensor("Guide", NULL_KEY, PASSIVE, 96, PI);
        } else if (level & edge & CONTROL_DOWN ) {
            if (Physical) {
                UnPhys(0);
                llSetRot(llEuler2Rot(<0,0,PI> + llRot2Euler(llGetRot())));
                RePhys(0);
            } else {
                RePhys(1);
                // llWhisper(0,"## Hit PAGE DOWN again to flip 180 degrees.");
            }
        }
    }
    timer() {
        if (TTL >= 0) {
            TTL += TICK;
            if (TTL > MAX_IDLE) llDie();
            if (Physical) {
                vector c = llGetRegionCorner();
                vector here = c + llGetPos();
                Meters += llVecDist(Prev, here);
                if (c != Corner) {
                    integer dx = (integer)(c.x/256 - Bedstraw.x);
                    integer dy = (integer)(c.y/256 - Bedstraw.y);
                    string s = HowFar() + "Bedstraw + ("+(string)dx+", "+(string)dy;
                    s += ") == \"" + llGetRegionName() + "\"";
                    llWhisper(0, s);
                    Corner = c;
                }
                Prev = here;
            }
        }
    }
    sensor(integer n) {
        integer i;
        vector pos = llDetectedPos(0);
        rotation rot = llDetectedRot(0);
        llWhisper(0, "Detected track: "+ (string)pos);

        // Mark places with footballs
        /*for (i=0; i<n; ++i) {
            vector p = llDetectedPos(i);
            integer xxx = (integer)p.x;
            integer yyy = (integer)p.y;
            integer zzz = (integer)p.z;
            integer param = ((i*10+1)<<24) | ((xxx&255)<<16) |
               ((yyy&255)<<8) | (zzz&255);
           llRezObject("Football Place Marker (temp)",
                llGetPos()+<0,0,9>, ZERO_VECTOR,  ZERO_ROTATION, param);
        }*/

        Speed = 0;
        llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,-0.1>);
        Phys(FALSE);

        rotation myRot = llGetRot();
        vector myFwd = llRot2Fwd(myRot);
        vector left = llRot2Left(rot);
        vector cross = myFwd % left;
        if (cross.z < 0) {
            rot = rot * llEuler2Rot(<0,0,PI>);
        }
        llSetRot(rot);
        for (i=0; i<12; ++i) {
            llSetPos(pos + <0,0,1>);
        }
        RePhys(1);
    }
}
state limbo {
    state_entry() {
        llSetTimerEvent(3);
    }
    touch_start(integer i) {
        state default;
    }
    timer() {
        llDie();
    }
}
(unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
(last modified 2011-01-31)       [Login]
(No back references.)