Flight Assistant code rewrite + some minor script modifications

Northspring 2014-06-16 01:35:11 +02:00
parent 3d6921153a
commit cd4fd4f68b
2 changed files with 103 additions and 238 deletions

View File

@ -1,4 +1,4 @@
//http bridge script v.2.11
//http bridge script v.2.12
//Firestorm
//Tozh Taurog, Arrehn Oberlander, Tonya Souther
@ -6,20 +6,12 @@
// Global Variables and CONSTANTS
//
// Shared
integer timerMask; // Every function that shares the timer needs a TIMER_ entry below.
float timerInterval; // float, seconds. Always set this when using llSetTimerEvent
float timerElapsed; // floats, seconds since last tick.
integer TIMER_TYPE_NONE = 0;
integer TIMER_TYPE_TP = 1;
integer TIMER_TYPE_FLIGHT = 2;
// Bridge platform
integer FIRESTORM_VIEWER = 0;
integer UNKNOWN_VIEWER = 1;
integer META_CONTROL = 1024; // Control value to do nothing; for no-script sims
string bridgeAuth = "BRIDGEKEY"; // Filled in dynamically
string bridgeVersion = "2.11"; // This should match fslslbridge.cpp
string bridgeVersion = "2.12"; // This should match fslslbridge.cpp
string bridgeURL;
string latestURL;
integer debug = FALSE;
@ -27,7 +19,6 @@
integer keyViewerHandshake;
integer tryHandshakeOnce = TRUE;
key owner;
integer timerType = TIMER_TYPE_NONE;
// Teleport
float TP_TARGET_DISTANCE = 1.0;// Distance to target when move to target should stop
@ -42,27 +33,11 @@
integer relockIsUserMoving = FALSE;
// Flight assist
float MIN_SPEED = 2.0;
float WANT_SPEED = 20.0;
float MAX_SPEED = 25.0;
float MIN_TIME = 1.0;
float DEFAULT_BOOST = 0.5;
float FAST_TICK = 0.1;
float SLOW_TICK = 1.0;
float LONG_TIME = 5.0; // Reset boost if no work in a long time
float MIN_BOOST_HEIGHT = 72.0;
float MIN_BOOST_CLEARANCE = 36.0;
integer useFlightAssist = FALSE;
float last_alt;
float last_time;
float last_move;
float boost;
integer controls;
integer flying = -1;
integer falling = -1;
integer hovering = -1;
float last_boost_height;
float average_boost;
integer isFlyingNow = -1;
float flightAssistPushForce = 3.0;
float flightAirCheckNormal = 0.5;
float flightAirCheckSlow = 5.0;
// OpenCollar/LockMeister AO interface
integer aoChannelOC;
@ -96,6 +71,8 @@
llSetTextureAnim(FALSE, ALL_SIDES, 1, 1, 1.0, 1.0, 1.0);
llAllowInventoryDrop(FALSE);
llStopMoveToTarget();
llSetTorque(ZERO_VECTOR, 0);
flight_hover(FALSE);
// Make bridge inconspicuous
llSetLinkPrimitiveParamsFast(LINK_THIS, [
PRIM_TEXT, "", ZERO_VECTOR, 0.0,
@ -122,7 +99,6 @@
// Disable all secondary stateful services
llSetTimerEvent(0);
llStopMoveToTarget();
flight_set_hover(FALSE);
if (llGetAttached() != 0)
{
@ -135,9 +111,12 @@
// If we were last flying reinitialize ourself
if (useFlightAssist)
{
//debugOutput("Flight assist true, going to flight_init");
flight_init();
}
else
{
flight_hover(FALSE);
}
// Check the state of movelock, relock if needed
if (useMoveLock)
@ -195,24 +174,18 @@
if (cmd == "UseLSLFlightAssist")
{
//debugOutput("Parsing params: " + llList2String(commandList, 1));
integer newstatus = llList2Integer(commandList, 1);
if (newstatus != useFlightAssist)
{
useFlightAssist = newstatus;
if (useFlightAssist)
{
//debugOutput("Flight assist true, going to flight_init");
flight_init();
}
else
{
//debugOutput("Flight assist false, removing flag");
if (timerMask & TIMER_TYPE_FLIGHT)
{
//debugOutput("timerMask & TIMER_FLIGHT");
timerMask = timerMask ^ TIMER_TYPE_FLIGHT; // Remove flight from event counter
}
flight_hover(FALSE);
llSetTimerEvent(0);
}
}
}
@ -245,12 +218,7 @@
startTPTimer = llGetUnixTime();
// TP commands immediately configure a TP timer consumer
timerMask = timerMask | TIMER_TYPE_TP;
if ((timerInterval > TP_TIMER_TICK) || (timerInterval == 0))
{
timerInterval = TP_TIMER_TICK;
llSetTimerEvent(timerInterval);
}
setTimerEvent2(TP_TIMER_TICK);
//llHTTPResponse(httpReqID, httpStatus, "<llsd><string>test response from llMoveToTarget</string></llsd>");
} // "llMoveToTarget"
@ -383,6 +351,18 @@ getScriptInfo(key target)
// Teleport Helper functions
//
setTimerEvent2(float time)
{
if (time <= 0)
{
llSensorRemove();
}
else
{
llSensorRepeat("set-Timer-Event-2", NULL_KEY, AGENT_BY_LEGACY_NAME, 0.001, 0.001, time);
}
}
tpMoveStep()
{
vector loc = llGetPos();
@ -395,7 +375,7 @@ getScriptInfo(key target)
if ((dist < TP_TARGET_DISTANCE) || (llGetUnixTime() - MAX_TIME_TO_TP > startTPTimer) || (mttVector == loc))
{
llStopMoveToTarget();
timerMask = timerMask ^ TIMER_TYPE_TP; // Remove our timer if we finish
setTimerEvent2(0);
if (useMoveLock)
{
movelock_init();
@ -415,160 +395,41 @@ getScriptInfo(key target)
}
}
// If we're not close to target and time is not up yet, check again
if (timerMask & TIMER_TYPE_TP)
{
timerInterval = TP_TIMER_TICK;
llSetTimerEvent(timerInterval);
}
}
//
// Flight Assist Functions
// Movement control permission, shared function
//
flight_set_hover(integer active)
{
//debugOutput("Flight:set_hover " + (string)active);
if (active == hovering) return;
hovering = active;
if (hovering)
llSetForce(<0, 0, 9.8> * llGetMass(), FALSE);
else
llSetForce(<0, 0, 0>, FALSE);
}
flight_set_tick(float tick)
// Positively intializes a spot for us in the eventTimer.
{
//debugOutput("Flight:set_tick " + (string)tick);
timerMask = timerMask | TIMER_TYPE_FLIGHT;
timerInterval = tick;
if (timerMask == TIMER_TYPE_FLIGHT)
{
llSetTimerEvent(timerInterval);
}
else if ((timerInterval > tick) || (timerInterval < 0.1))
{
llSetTimerEvent(timerInterval);
}
}
flight_check_boost()
{
//debugOutput("Flight:check_boost ");
flying = 1;
falling = 0;
integer info = llGetAgentInfo(owner);
// Sleep if not flying
if ((info & AGENT_FLYING) == 0)
{
//debugOutput("not flying");
flight_set_hover(FALSE);
falling = (info & AGENT_IN_AIR) != 0;
flying = 0;
boost = 0;
flight_set_tick(SLOW_TICK);
return;
}
// Sleep if we don't have controls
if (controls <= 0)
{
//debugOutput("no controls");
flight_set_tick(SLOW_TICK);
return;
}
// Otherwise, we may be flying = look up further details
vector pos = llGetPos();
if (pos.z < last_boost_height / 2) // Trim running average of boost if big altitude drop
average_boost = average_boost * (pos.z / last_boost_height)
+ DEFAULT_BOOST * (1.0 - pos.z / last_boost_height);
// Sleep if low to the ground
if (pos.z < MIN_BOOST_HEIGHT || pos.z - llGround(<0,0,0>) < MIN_BOOST_CLEARANCE)
{
flight_set_hover(FALSE);
flight_set_tick(SLOW_TICK);
boost = 0;
return;
}
// Otherwise hover and get even more details
flight_set_hover(TRUE);
vector vel = llGetVel();
float time = llGetTime();
float speed = vel.z;
float target = WANT_SPEED;
float window = WANT_SPEED / 20;
if (speed > 0)
last_move = time;
if (time - last_time >= LONG_TIME)
boost = 0;
else
{
if (speed < target - window)
{
if (boost == 0)
boost = average_boost;
if (time - last_move > MIN_TIME) boost += 0.4;
else if (speed < target * 0.25) boost += 0.2;
else if (speed < target * 0.5 ) boost += 0.1;
else if (speed < target * 0.75) boost += 0.05;
else if (speed < target - window * 4) boost += 0.02;
else boost += 0.01;
}
else if (speed > MAX_SPEED) boost -= 0.5;
else if (speed > target + window * 4) boost -= 0.1;
else if (speed > target + window * 2) boost -= 0.03;
else if (speed > target + window) boost -= 0.01;
if (boost <= 0)
boost = 0;
if (boost > 0)
{
llApplyImpulse(<0,0,boost> * llGetMass(), FALSE);
average_boost = average_boost * 0.9 + boost * 0.1; // 10 sample running average
last_boost_height = pos.z;
}
}
// If we find we need a correction
if (boost)
{
flight_set_tick(FAST_TICK);
}
else
flight_set_tick(SLOW_TICK);
last_alt = pos.z;
last_time = time;
}
request_control_perms()
{
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_UP | CONTROL_DOWN, TRUE, TRUE);
}
//
// Flight Assist
//
flight_init()
{
//debugOutput("Flight:init ");
flight_set_hover(FALSE);
// Initialize flight vars
useFlightAssist = TRUE;
boost = 0;
flying = -1;
falling = -1;
hovering = -1;
llSetTimerEvent(flightAirCheckNormal);
if (llGetAttached())
{
request_control_perms();
flight_set_tick(SLOW_TICK);
}
}
flight_hover(integer yes)
{
if (yes)
{
llSetForce((<0.0, 0.0, 9.8> * llGetMass()), 0);
}
else
{
llSetForce(ZERO_VECTOR, 0);
}
}
//
@ -607,9 +468,11 @@ default
{
// We don't want to be rezzed without being attached. Insure we don't create litter.
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEMP_ON_REZ, TRUE]);
// Force Movelock variable to false here and allow attach() to decide via initBridge(), if we're on Firestorm and login relock can be turned off if needed.
// Force Movelock and Flight assist variables to false here and allow attach() to decide via initBridge(), if we're on Firestorm and login relock / flight assist can be turned off if needed.
// on_rez() will be triggered prior to attach() when attaching from inventory or during login, but not prior to state_entry().
useMoveLock = FALSE;
useFlightAssist = FALSE;
isFlyingNow = -1;
}
attach(key k)
@ -661,13 +524,40 @@ default
}
}
if ((llGetAgentInfo(owner) & AGENT_FLYING) && useFlightAssist)
if (useFlightAssist && isFlyingNow)
{
controls = 0;
if (level & CONTROL_UP) ++controls;
if (level & CONTROL_DOWN) --controls;
if (controls > 0)
flight_check_boost();
if (level & (CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_UP | CONTROL_DOWN))
{
vector pushingForce = ZERO_VECTOR;
// Forward / back
if (level & CONTROL_FWD)
{
pushingForce += <flightAssistPushForce, 0, 0>;
}
else if (level & CONTROL_BACK)
{
pushingForce += <-flightAssistPushForce, 0, 0>;
}
// Left / right
if (level & CONTROL_LEFT)
{
pushingForce += <0, flightAssistPushForce, 0>;
}
else if (level & CONTROL_RIGHT)
{
pushingForce += <0, -flightAssistPushForce, 0>;
}
// Up / down
if (level & CONTROL_UP)
{
pushingForce += <0, 0, flightAssistPushForce>;
}
else if (level & CONTROL_DOWN)
{
pushingForce += <0, 0, -flightAssistPushForce>;
}
llApplyImpulse(pushingForce, 1);
}
}
}
@ -686,36 +576,28 @@ default
timer()
{
//debugOutput("tick. mask = "+(string)timerMask);
// Multiple functions may have to share the timer
// Do not assume you know the timer interval in advance.
// Each consumer will have to check whether the interval that has passed
// since last tick is long enough to trigger functionality.
// Every tick, stop ourself. Consumers are responsible for restarting the timer
// each time they get a tick, if they still need it
llSetTimerEvent(0);
timerInterval = 0;
timerElapsed = llGetAndResetTime();
// All consumers should have an entry here, and must manage their interval.
// Consumers should reset the timer only of they need it faster, otherwise
// leave it as it is. Order this list by fastest timer consumers first.
if (timerMask & TIMER_TYPE_TP)
if (llGetAgentInfo(owner) & AGENT_FLYING)
{
tpMoveStep();
return; // Teleports shortcut other timers
if (isFlyingNow != TRUE)
{
isFlyingNow = TRUE;
flight_hover(TRUE);
llSetTimerEvent(flightAirCheckNormal);
}
}
if (timerMask & TIMER_TYPE_FLIGHT)
else if (isFlyingNow != FALSE)
{
flight_check_boost();
isFlyingNow = FALSE;
flight_hover(FALSE);
llSetTimerEvent(flightAirCheckSlow);
}
}
//<DEBUG>
//debugOutput("memUsage= "+(string)llGetFreeMemory());
//llSetTimerEvent(10);
//</DEBUG>
no_sensor()
{
// Used for TP timer only
// no_sensor() is used as a second timer() along with setTimerEvent2(), because lightweight llSensorRepeat() query is using impossible to meet requirements
tpMoveStep();
}
http_request(key ID, string Method, string Body)
@ -817,20 +699,3 @@ default
} // End listen
}
//
// Flight assist code
//
// Copyright (c) 2005, Argent Stonecutter & player
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions in modifiable form must retain the above copyright notice, this list of conditions and the following disclaimer.
// * Redistributions in non-modifiable form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// * Neither the name of Argent Stonecutter nor his player may be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// END //

View File

@ -67,10 +67,10 @@
const std::string FS_BRIDGE_FOLDER = "#LSL Bridge";
const std::string FS_BRIDGE_CONTAINER_FOLDER = "Landscaping";
const U32 FS_BRIDGE_MAJOR_VERSION = 2;
const U32 FS_BRIDGE_MINOR_VERSION = 11;
const U32 FS_BRIDGE_MINOR_VERSION = 12;
const U32 FS_MAX_MINOR_VERSION = 99;
//current script version is 2.11
//current script version is 2.12
const std::string UPLOAD_SCRIPT_CURRENT = "EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt";
//