workaround coarseoffset positions, initial implementation
parent
be1360c90a
commit
e258982857
|
|
@ -1,4 +1,4 @@
|
|||
//http bridge script v.1.9
|
||||
//http bridge script v.2.0
|
||||
//Firestorm
|
||||
//Tozh Taurog, Arrehn Oberlander
|
||||
|
||||
|
|
@ -8,9 +8,9 @@
|
|||
// 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;
|
||||
float timerElapsed; // floats, seconds since last tick.
|
||||
integer TIMER_TYPE_NONE = 0;
|
||||
integer TIMER_TYPE_TP = 1;
|
||||
integer TIMER_TYPE_FLIGHT = 2;
|
||||
|
||||
|
||||
|
|
@ -20,10 +20,8 @@
|
|||
integer META_CONTROL = 1024; //control value to do nothing; for no-script sims
|
||||
string bridgeURL;
|
||||
string latestURL;
|
||||
integer channel = 99;
|
||||
integer debug = FALSE;
|
||||
integer httpStatus = 200;
|
||||
//key httpReqID;
|
||||
integer keyViewerHandshake;
|
||||
integer tryHandshakeOnce = TRUE;
|
||||
key owner;
|
||||
|
|
@ -32,15 +30,9 @@
|
|||
// Teleport
|
||||
integer MAX_TIME_TO_TP = 10; // (seconds) should be set to 10 for normal use
|
||||
float TP_TIMER_TICK = 0.05;
|
||||
|
||||
vector mttVector; // target for llMoveToTarget() teleport
|
||||
integer startTPTimer;
|
||||
|
||||
// Object details (improved radar)
|
||||
vector opVector; // object position for llGetobjectDetails()
|
||||
key opUUID; // key for llGetobjectDetails()
|
||||
list opObjDetails; // result for llGetobjectDetails()
|
||||
|
||||
// Flight assist
|
||||
float MIN_SPEED = 2.0;
|
||||
float WANT_SPEED = 20.0;
|
||||
|
|
@ -53,7 +45,6 @@
|
|||
float MIN_BOOST_HEIGHT = 72.0;
|
||||
float MIN_BOOST_CLEARANCE = 36.0;
|
||||
integer useFlightAssist = FALSE;
|
||||
integer pendingFlightFeather = 0;
|
||||
float last_alt;
|
||||
float last_time;
|
||||
float last_move;
|
||||
|
|
@ -62,7 +53,6 @@
|
|||
integer flying = -1;
|
||||
integer falling = -1;
|
||||
integer hovering = -1;
|
||||
integer dimmed = -1;
|
||||
float last_boost_height;
|
||||
float average_boost;
|
||||
|
||||
|
|
@ -103,7 +93,7 @@
|
|||
initBridge()
|
||||
{
|
||||
llRequestURL();
|
||||
debugOutput("rezzed");
|
||||
//debugOutput("rezzed");
|
||||
owner = llGetOwner();
|
||||
|
||||
// Disable all secondary stateful services
|
||||
|
|
@ -122,7 +112,7 @@
|
|||
// if we were last flying reinitialize ourself
|
||||
if (useFlightAssist)
|
||||
{
|
||||
debugOutput("Flight assist true, going to flight_init");
|
||||
//debugOutput("Flight assist true, going to flight_init");
|
||||
flight_init();
|
||||
}
|
||||
}
|
||||
|
|
@ -134,23 +124,16 @@
|
|||
|
||||
parseCommand(key httpReqID, string msg)
|
||||
{
|
||||
debugOutput("Parsing original input: " + msg);
|
||||
//remove the <llsd> </llsd> wrapper
|
||||
integer end = llStringLength(msg) - llStringLength("</llsd>") -1;
|
||||
string inner = llGetSubString(msg, 6, end - 1);
|
||||
|
||||
debugOutput("Parsing inner string: " + inner);
|
||||
//remove the <string> </string> wrapper
|
||||
end = llStringLength(inner) - llStringLength("</string>") -1;
|
||||
string msgClean = llGetSubString(inner, 8, end);
|
||||
|
||||
debugOutput("Parsing final string: " + msgClean);
|
||||
list commandList = llParseString2List(msgClean,["|"],[]);
|
||||
//get command name
|
||||
//debugOutput("Parsing original input: " + msg);
|
||||
//remove the <llsd><string> ... </string></llsd> wrapper
|
||||
integer end = llStringLength(msg) - 18;
|
||||
integer start = 14;
|
||||
//debugOutput("Parsing inner string: " + llGetSubString(msg, start, end));
|
||||
list commandList = llParseString2List(llGetSubString(msg,start,end),["|"],[]);
|
||||
//debugOutput("Parsing command list: " + (string)commandList);
|
||||
string cmd = llList2String(commandList,0);
|
||||
|
||||
debugOutput("Parsing command: " + cmd);
|
||||
|
||||
//debugOutput("Parsing command: " + cmd);
|
||||
//Large If statement for command processing. Shame on you, LSL!
|
||||
if (cmd == "URL Confirmed")
|
||||
{
|
||||
|
|
@ -161,36 +144,34 @@
|
|||
|
||||
if (cmd == "UseLSLFlightAssist")
|
||||
{
|
||||
string params = "<" + llList2String(commandList,1) + ">";
|
||||
debugOutput("Parsing params: " + params);
|
||||
//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
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (cmd == "llMoveToTarget")
|
||||
{
|
||||
// Get parameters
|
||||
string params = "<" + llList2String(commandList,1) + ">";
|
||||
debugOutput("Parsing params: " + params);
|
||||
mttVector=(vector)params;
|
||||
debugOutput("Parsing vector: " + (string)mttVector);
|
||||
//debugOutput("Parsing vector: " + (string)mttVector);
|
||||
startTPTimer = llGetUnixTime();
|
||||
|
||||
// tp commands immediately configure a TP timer consumer
|
||||
|
|
@ -204,22 +185,33 @@
|
|||
//llHTTPResponse(httpReqID, httpStatus, "<llsd><string>test response from llMoveToTarget</string></llsd>");
|
||||
}// "llMoveToTarget"
|
||||
|
||||
else if (cmd == "llGetObjectDetails")
|
||||
else if (cmd == "getZOffsets")
|
||||
// Radar-specific command to get high-rez altitude data.
|
||||
// Input is list of UUIDs to query
|
||||
// Output is list of UUID:Altitude pairs
|
||||
{
|
||||
// Get parameters
|
||||
opUUID = (key)llList2String(commandList, 1);
|
||||
|
||||
//string opV = "<" + llList2String(commandList,2) + ">";
|
||||
//debugOutput("Parsing params: " + opV);
|
||||
|
||||
//opVector=(vector)opV;
|
||||
//debugOutput("Parsing vector: " + (string)opVector);
|
||||
|
||||
opObjDetails = llGetObjectDetails(opUUID, ([OBJECT_POS]));
|
||||
string body = "<llsd><string>" + llList2String(opObjDetails,0) + "</string></llsd>";
|
||||
list tUUIDs = llCSV2List(llList2String(commandList, 1));
|
||||
commandList=[]; // free memory
|
||||
integer tLength = llGetListLength(tUUIDs);
|
||||
key tUUID; // key for llGetobjectDetails()
|
||||
vector tPos;
|
||||
integer i = 0;
|
||||
list responses;
|
||||
|
||||
for (i = 0; i < tLength; ++i)
|
||||
{
|
||||
tUUID = (key)llList2String(tUUIDs,i);
|
||||
tPos = llList2Vector(llGetObjectDetails(tUUID, ([OBJECT_POS])),0);
|
||||
if (tPos.z > 1023) // we only care about results at higher altitudes.
|
||||
responses = (responses=[]) + responses + tUUID + tPos.z; //LSO memhack
|
||||
}
|
||||
tUUIDs=[]; // free memory
|
||||
string body = "<llsd><string>" +llList2CSV(responses) + "</string></llsd>";
|
||||
responses=[]; // free memory
|
||||
llHTTPResponse(httpReqID, httpStatus, body);
|
||||
|
||||
}// "llGetObjectDetails"
|
||||
}// "getZOffsets"
|
||||
|
||||
else if ( cmd == "getScriptInfo")
|
||||
{
|
||||
|
|
@ -257,12 +249,11 @@
|
|||
|
||||
tpMoveStep()
|
||||
{
|
||||
vector loc = llGetPos(); // current position
|
||||
vector loc = llGetPos();
|
||||
vector targ = mttVector - loc;
|
||||
//has to be less than 65m
|
||||
float dist = llVecMag(targ);
|
||||
|
||||
debugOutput("current: " + (string)loc + " target: " + (string)targ + " tp distance: " + (string)dist);
|
||||
//debugOutput("current: " + (string)loc + " target: " + (string)targ + " tp distance: " + (string)dist);
|
||||
|
||||
//if we are out of time or distance - stop
|
||||
if((dist < 2.0) || (llGetUnixTime() - MAX_TIME_TO_TP > startTPTimer) || (mttVector == loc))
|
||||
|
|
@ -274,12 +265,12 @@
|
|||
{
|
||||
if (dist < 65)
|
||||
{
|
||||
debugOutput("One jump to :" + (string)mttVector);
|
||||
//debugOutput("One jump to :" + (string)mttVector);
|
||||
llMoveToTarget(mttVector, TP_TIMER_TICK);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugOutput("Multiple jump to :" + (string)(loc+llVecNorm(targ)*60));
|
||||
//debugOutput("Multiple jump to :" + (string)(loc+llVecNorm(targ)*60));
|
||||
llMoveToTarget(loc+llVecNorm(targ)*60, TP_TIMER_TICK);
|
||||
}
|
||||
}
|
||||
|
|
@ -303,7 +294,7 @@
|
|||
|
||||
flight_set_hover(integer active)
|
||||
{
|
||||
debugOutput("Flight:set_hover " + (string)active);
|
||||
//debugOutput("Flight:set_hover " + (string)active);
|
||||
|
||||
if(active == hovering) return;
|
||||
hovering = active;
|
||||
|
|
@ -316,7 +307,7 @@
|
|||
flight_set_tick(float tick)
|
||||
// positively intializes a spot for us in the eventTimer.
|
||||
{
|
||||
debugOutput("Flight:set_tick " + (string)tick);
|
||||
//debugOutput("Flight:set_tick " + (string)tick);
|
||||
|
||||
timerMask = timerMask | TIMER_TYPE_FLIGHT;
|
||||
timerInterval = tick;
|
||||
|
|
@ -332,8 +323,7 @@
|
|||
|
||||
flight_check_boost()
|
||||
{
|
||||
debugOutput("Flight:check_boost ");
|
||||
|
||||
//debugOutput("Flight:check_boost ");
|
||||
|
||||
flying = 1;
|
||||
falling = 0;
|
||||
|
|
@ -342,7 +332,7 @@
|
|||
// Sleep if not flying
|
||||
if((info & AGENT_FLYING) == 0)
|
||||
{
|
||||
debugOutput("not flying");
|
||||
//debugOutput("not flying");
|
||||
flight_set_hover(FALSE);
|
||||
falling = (info & AGENT_IN_AIR) != 0;
|
||||
flying = 0;
|
||||
|
|
@ -354,7 +344,7 @@
|
|||
// Sleep if we don't have controls
|
||||
if(controls <= 0)
|
||||
{
|
||||
debugOutput("no controls");
|
||||
//debugOutput("no controls");
|
||||
flight_set_tick(SLOW_TICK);
|
||||
return;
|
||||
}
|
||||
|
|
@ -437,7 +427,7 @@
|
|||
|
||||
flight_init()
|
||||
{
|
||||
debugOutput("Flight:init ");
|
||||
//debugOutput("Flight:init ");
|
||||
flight_set_hover(FALSE);
|
||||
|
||||
// initialize flight vars
|
||||
|
|
@ -461,7 +451,7 @@ default
|
|||
{
|
||||
makeSane();
|
||||
initBridge();
|
||||
|
||||
//llOwnerSay((string)llGetFreeMemory());
|
||||
}
|
||||
|
||||
on_rez(integer i)
|
||||
|
|
@ -480,11 +470,6 @@ default
|
|||
}
|
||||
}
|
||||
|
||||
touch_start(integer total_number)
|
||||
{
|
||||
debugOutput("touched");
|
||||
}
|
||||
|
||||
run_time_permissions(integer i)
|
||||
{
|
||||
if (i)
|
||||
|
|
@ -516,7 +501,7 @@ default
|
|||
if (change & CHANGED_REGION)
|
||||
{
|
||||
llRequestURL();
|
||||
debugOutput("The region the bridge is in has changed.");
|
||||
//debugOutput("The region the bridge is in has changed.");
|
||||
}
|
||||
if (change & CHANGED_INVENTORY)
|
||||
{
|
||||
|
|
@ -526,7 +511,7 @@ default
|
|||
|
||||
timer()
|
||||
{
|
||||
debugOutput("tick. mask = "+(string)timerMask);
|
||||
//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
|
||||
|
|
@ -556,18 +541,18 @@ default
|
|||
http_request(key ID, string Method, string Body)
|
||||
{
|
||||
//httpReqID = ID;
|
||||
debugOutput("Received HTTP " + Method + " message. Command body: " + Body);
|
||||
//debugOutput("Received HTTP " + Method + " message. Command body: " + Body);
|
||||
|
||||
if (Method == URL_REQUEST_GRANTED)
|
||||
{
|
||||
saveNewURL(Body);
|
||||
|
||||
debugOutput ("keyViewerHandshake " + (string)keyViewerHandshake + " tryHandshakeOnce " + (string)tryHandshakeOnce);
|
||||
//debugOutput ("keyViewerHandshake " + (string)keyViewerHandshake + " tryHandshakeOnce " + (string)tryHandshakeOnce);
|
||||
//Saying URL to owner
|
||||
if (keyViewerHandshake == FIRESTORM_VIEWER || tryHandshakeOnce == 1)
|
||||
{
|
||||
debugOutput ("Firestorm viewer and handshake");
|
||||
llOwnerSay("<bridgeURL>" + latestURL+ "</bridgeURL>");
|
||||
//debugOutput ("Firestorm viewer and handshake");
|
||||
llOwnerSay("<bridgeURL>" + latestURL+ "</bridgeURL>");
|
||||
tryHandshakeOnce = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -580,7 +565,7 @@ default
|
|||
{
|
||||
saveNewURL("");
|
||||
|
||||
debugOutput("No URLs free !");
|
||||
//debugOutput("No URLs free !");
|
||||
//keep trying?
|
||||
llRequestURL();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@
|
|||
//#define ROOT_FIRESTORM_FOLDER "#Firestorm" //moved to llinventoryfunctions to synch with the AO object
|
||||
#define FS_BRIDGE_FOLDER "#LSL Bridge"
|
||||
#define FS_BRIDGE_NAME "#Firestorm LSL Bridge v"
|
||||
#define FS_BRIDGE_MAJOR_VERSION 1
|
||||
#define FS_BRIDGE_MINOR_VERSION 9
|
||||
#define FS_BRIDGE_MAJOR_VERSION 2
|
||||
#define FS_BRIDGE_MINOR_VERSION 0
|
||||
|
||||
//current script version is 1.9
|
||||
//current script version is 2.0
|
||||
const std::string UPLOAD_SCRIPT_CURRENT = "EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt";
|
||||
|
||||
//
|
||||
|
|
@ -819,4 +819,4 @@ void FSLSLBridge :: detachOtherBridges()
|
|||
LLVOAvatarSelf::detachAttachmentIntoInventory(itemp->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@
|
|||
#include "fslslbridge.h"
|
||||
#include "llagent.h" // for gAgent
|
||||
#include "llhttpclient.h"
|
||||
#include <string>
|
||||
#include <boost/tokenizer.hpp> // for radar
|
||||
#include "llpanel.h"
|
||||
#include "llpanelpeople.h"
|
||||
#include "llavatarlist.h"
|
||||
#include "llavatarlistitem.h"
|
||||
#include "llsidetray.h"
|
||||
|
||||
#ifdef LL_STANDALONE
|
||||
#include <expat.h>
|
||||
|
|
@ -81,4 +88,40 @@ void FSLSLBridgeRequestResponder::error(U32 status, const std::string& reason)
|
|||
}
|
||||
|
||||
|
||||
// AO: The below handler is used to parse return data from the bridge, requesting bulk ZOffset updates.
|
||||
FSLSLBridgeRequestRadarPosResponder::FSLSLBridgeRequestRadarPosResponder()
|
||||
{
|
||||
}
|
||||
void FSLSLBridgeRequestRadarPosResponder::result(const LLSD& content)
|
||||
{
|
||||
LLPanel* panel_people = LLSideTray::getInstance()->getPanel("panel_people");
|
||||
if (panel_people)
|
||||
{
|
||||
LLAvatarList* nearbyList = ((LLPanelPeople*)panel_people)->getNearbyList();
|
||||
|
||||
std::string strContent = content.asString();
|
||||
//llinfos << "Got info: " << strContent << llendl;
|
||||
// AO: parse content into pairs of [agent UUID,agent zHeight] , update our peoplepanel radar for each one
|
||||
|
||||
LLUUID targetAv;
|
||||
F32 targetZ;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep(", ");
|
||||
tokenizer tokens(strContent,sep);
|
||||
for (tokenizer::iterator tok_iter=tokens.begin(); tok_iter != tokens.end();++tok_iter)
|
||||
{
|
||||
targetAv = LLUUID(*(tok_iter++));
|
||||
targetZ = (F32)::atof((*tok_iter).c_str());
|
||||
|
||||
LLAvatarListItem* avListItem = nearbyList->getAvatarListItem(targetAv);
|
||||
if (avListItem != NULL)
|
||||
{
|
||||
avListItem->setZOffset((F32)(targetZ));
|
||||
//llinfos << targetAv << " ::: " << targetZ << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,4 +60,19 @@ public:
|
|||
virtual void error(U32 status, const std::string& reason);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Responder used by radar for position lookups
|
||||
//
|
||||
|
||||
class FSLSLBridgeRequestRadarPosResponder : public FSLSLBridgeRequestResponder
|
||||
{
|
||||
public:
|
||||
FSLSLBridgeRequestRadarPosResponder();
|
||||
//If we get back a normal response, handle it here
|
||||
void result(const LLSD& content);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // FS_LSLBRIDGEREQUEST_H
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
|
|||
mShowDisplayName(true),
|
||||
mShowUsername(true),
|
||||
mFirstSeen(time(NULL)),
|
||||
mLastZOffsetTime(time(NULL)),
|
||||
mZOffset(0),
|
||||
mAvStatus(0),
|
||||
mAvPosition(LLVector3d(0.0f,0.0f,0.0f)),
|
||||
mShowFirstSeen(false),
|
||||
|
|
@ -488,6 +490,26 @@ void LLAvatarListItem::setFirstSeen(time_t seentime)
|
|||
mFirstSeen = seentime;
|
||||
}
|
||||
|
||||
time_t LLAvatarListItem::getLastZOffsetTime()
|
||||
{
|
||||
return mLastZOffsetTime;
|
||||
}
|
||||
|
||||
void LLAvatarListItem::setLastZOffsetTime(time_t oTime)
|
||||
{
|
||||
mLastZOffsetTime = oTime;
|
||||
}
|
||||
|
||||
F32 LLAvatarListItem::getZOffset()
|
||||
{
|
||||
return mZOffset;
|
||||
}
|
||||
|
||||
void LLAvatarListItem::setZOffset(F32 offset)
|
||||
{
|
||||
mZOffset = offset;
|
||||
}
|
||||
|
||||
void LLAvatarListItem::setAvatarIconVisible(bool visible)
|
||||
{
|
||||
// Already done? Then do nothing.
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ public:
|
|||
S32 getAvStatus();
|
||||
void setFirstSeen(time_t seenTime);
|
||||
time_t getFirstSeen();
|
||||
void setLastZOffsetTime(time_t oTime);
|
||||
time_t getLastZOffsetTime();
|
||||
void setZOffset(F32 offset);
|
||||
F32 getZOffset();
|
||||
void showDisplayName(bool show);
|
||||
void showFirstSeen(bool show);
|
||||
void showStatusFlags(bool show);
|
||||
|
|
@ -268,10 +272,12 @@ private:
|
|||
|
||||
LLUUID mAvatarId;
|
||||
time_t mFirstSeen;
|
||||
time_t mLastZOffsetTime;
|
||||
F32 mZOffset;
|
||||
S32 mAvStatus;
|
||||
LLVector3d mAvPosition;
|
||||
S32 mAvatarAge;
|
||||
F32 mDistance;
|
||||
F32 mDistance;
|
||||
|
||||
std::string mHighlihtSubstring; // substring to highlight
|
||||
EOnlineStatus mOnlineStatus;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include "llcontrol.h"
|
||||
#include "lggcontactsets.h"
|
||||
#include "fslslbridge.h"
|
||||
#include "fslslbridgerequest.h"
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
|
|
@ -546,9 +548,6 @@ LLPanelPeople::~LLPanelPeople()
|
|||
delete mNearbyListUpdater;
|
||||
delete mFriendListUpdater;
|
||||
delete mRecentListUpdater;
|
||||
lastRadarSweep.clear();
|
||||
mRadarEnterAlerts.clear();
|
||||
mRadarLeaveAlerts.clear();
|
||||
|
||||
if(LLVoiceClient::instanceExists())
|
||||
{
|
||||
|
|
@ -602,22 +601,18 @@ BOOL LLPanelPeople::postBuild()
|
|||
|
||||
LLPanel* nearby_tab = getChild<LLPanel>(NEARBY_TAB_NAME);
|
||||
nearby_tab->getChildView("NearMeRange")->setVisible(gSavedSettings.getBOOL("LimitRadarByRange"));
|
||||
// AO: radarlist takes over for nearbylist. It's a scroll list vs. avatarlist.
|
||||
|
||||
// AO: radarlist takes over for nearbylist for presentation.
|
||||
mRadarList = nearby_tab->getChild<LLRadarListCtrl>("radar_list");
|
||||
mRadarList->sortByColumn("range",TRUE); // sort by range
|
||||
mRadarFrameCount = 0;
|
||||
mRadarAlertRequest = false;
|
||||
mRadarLastBulkOffsetRequestTime = 0;
|
||||
|
||||
// AO: mNearbyList is preserved as a data structure model for radar
|
||||
mNearbyList = nearby_tab->getChild<LLAvatarList>("avatar_list");
|
||||
mNearbyListUpdater->setActive(true); // AO: always keep radar active, for chat and channel integration
|
||||
//nearby_tab->setVisibleCallback(boost::bind(&Updater::setActive, mNearbyListUpdater, _2));
|
||||
// AO: Much of the below presentation options are now deprecated.
|
||||
mNearbyList->setNoItemsCommentText(getString("no_one_near"));
|
||||
mNearbyList->setNoItemsMsg(getString("no_one_near"));
|
||||
mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near"));
|
||||
mNearbyList->showUsername(false);
|
||||
mNearbyList->showMiniProfileIcons(false);
|
||||
mNearbyList->showPermissions(false);
|
||||
// [RLVa:KB] - Checked: 2010-04-05 (RLVa-1.2.2a) | Added: RLVa-1.2.0d
|
||||
mNearbyList->setRlvCheckShowNames(true);
|
||||
// [/RLVa:KB]
|
||||
|
|
@ -641,7 +636,6 @@ BOOL LLPanelPeople::postBuild()
|
|||
mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
|
||||
|
||||
mRadarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
|
||||
mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
|
||||
mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
|
||||
mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
|
||||
mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
|
||||
|
|
@ -661,7 +655,6 @@ BOOL LLPanelPeople::postBuild()
|
|||
|
||||
mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
|
||||
mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
|
||||
mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onNearbyListDoubleClicked, this, _1));
|
||||
mRecentList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
|
||||
mRadarList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onRadarListDoubleClicked, this));
|
||||
|
||||
|
|
@ -673,7 +666,6 @@ BOOL LLPanelPeople::postBuild()
|
|||
// Set openning IM as default on return action for avatar lists
|
||||
mOnlineFriendList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
|
||||
mAllFriendList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
|
||||
mNearbyList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
|
||||
mRecentList->setReturnCallback(boost::bind(&LLPanelPeople::onImButtonClicked, this));
|
||||
|
||||
mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
|
||||
|
|
@ -881,24 +873,23 @@ void LLPanelPeople::updateNearbyList()
|
|||
//AO : Warning, reworked heavily for Firestorm. Do not merge into here without understanding what it's doing.
|
||||
|
||||
if (!mNearbyList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Configuration
|
||||
F32 drawRadius = gSavedSettings.getF32("RenderFarClip");
|
||||
BOOL limitRange = gSavedSettings.getBOOL("LimitRadarByRange");
|
||||
static LLCachedControl<bool> sUseLSLBridge(gSavedSettings, "UseLSLBridge");
|
||||
const LLVector3d& posSelf = gAgent.getPositionGlobal();
|
||||
LLViewerRegion* reg = gAgent.getRegion();
|
||||
LLUUID regionSelf;
|
||||
if (reg)
|
||||
regionSelf = reg->getRegionID();
|
||||
bool alertScripts = mRadarAlertRequest; // assign this at the beginning of the call to resist race conditions
|
||||
|
||||
//const LLUUID regionSelf = gAgent.getRegion()->getRegionID();
|
||||
bool alertScripts = mRadarAlertRequest; // save the current value, so it doesn't get changed out from under us by another thread
|
||||
std::vector<LLPanel*> items;
|
||||
LLWorld* world = LLWorld::getInstance();
|
||||
time_t now = time(NULL);
|
||||
|
||||
//STEP 0: Clear data, saving pieces as needed.
|
||||
//STEP 0: Clear model data, saving pieces as needed.
|
||||
LLScrollListItem* lastRadarSelectedItem = mRadarList->getFirstSelected();
|
||||
LLUUID selected_id;
|
||||
S32 lastScroll = mRadarList->getScrollPos();
|
||||
|
|
@ -909,8 +900,10 @@ void LLPanelPeople::updateNearbyList()
|
|||
mRadarList->clearRows();
|
||||
mRadarEnterAlerts.clear();
|
||||
mRadarLeaveAlerts.clear();
|
||||
mRadarOffsetRequests.clear();
|
||||
|
||||
//STEP 1:Detect Avatars & Positions in our defined range, dump them into avatarList
|
||||
|
||||
//STEP 1: Update our basic data model: detect Avatars & Positions in our defined range
|
||||
std::vector<LLVector3d> positions;
|
||||
std::vector<LLUUID> avatar_ids;
|
||||
if (limitRange)
|
||||
|
|
@ -921,28 +914,29 @@ void LLPanelPeople::updateNearbyList()
|
|||
mNearbyList->setDirty(true,true); // AO: These optional arguements force updating even when we're not a visible window.
|
||||
mNearbyList->getItems(items);
|
||||
|
||||
//STEP 2: Transform detected list data into more flexible multimap;
|
||||
//STEP 2: Transform detected model list data into more flexible multimap data structure;
|
||||
std::vector<LLVector3d>::const_iterator
|
||||
pos_it = positions.begin(),
|
||||
pos_end = positions.end();
|
||||
std::vector<LLUUID>::const_iterator
|
||||
item_it = avatar_ids.begin(),
|
||||
item_end = avatar_ids.end();
|
||||
|
||||
for (;pos_it != pos_end && item_it != item_end; ++pos_it, ++item_it )
|
||||
{
|
||||
//2a. gather necessary model data
|
||||
//
|
||||
//2a. For each detected av, gather up all data we would want to display or use to drive alerts
|
||||
//
|
||||
|
||||
LLUUID avId = static_cast<LLUUID>(*item_it);
|
||||
LLVector3d avPos = static_cast<LLVector3d>(*pos_it);
|
||||
LLAvatarListItem* av = mNearbyList->getAvatarListItem(avId);
|
||||
F32 avRange = dist_vec(avPos, posSelf);
|
||||
LLVector3d avPos = static_cast<LLVector3d>(*pos_it);
|
||||
S32 seentime = 0;
|
||||
LLUUID avRegion;
|
||||
|
||||
// Skip modelling this avatar if its basic data is either inaccessible, or it's a dummy placeholder
|
||||
LLViewerRegion *reg = world->getRegionFromPosGlobal(avPos);
|
||||
if ((!reg) || (!av)) // don't update this radar listing if data is inaccessible
|
||||
continue;
|
||||
|
||||
// WS: If we have a dummy avatar. Then Don't display it in th
|
||||
static LLUICachedControl<bool> showdummyav("FSShowDummyAVsinRadar");
|
||||
if(!showdummyav){
|
||||
LLVOAvatar* voav = (LLVOAvatar*)gObjectList.findObject(avId);
|
||||
|
|
@ -957,11 +951,12 @@ void LLPanelPeople::updateNearbyList()
|
|||
for (multimap<LLUUID,radarFields>::iterator it2 = dupeAvs.first; it2 != dupeAvs.second; ++it2)
|
||||
{
|
||||
if (it2->second.lastRegion == avRegion)
|
||||
seentime = (S32)difftime(time(NULL),it2->second.firstSeen);
|
||||
seentime = (S32)difftime(now,it2->second.firstSeen);
|
||||
}
|
||||
}
|
||||
else
|
||||
seentime = (S32)difftime(time(NULL),av->getFirstSeen());
|
||||
seentime = (S32)difftime(now,av->getFirstSeen());
|
||||
//av->setFirstSeen(now - (time_t)seentime); // maintain compatibility with underlying list, deprecated
|
||||
S32 hours = (S32)(seentime / 3600);
|
||||
S32 mins = (S32)((seentime - hours * 3600) / 60);
|
||||
S32 secs = (S32)((seentime - hours * 3600 - mins * 60));
|
||||
|
|
@ -972,32 +967,43 @@ void LLPanelPeople::updateNearbyList()
|
|||
avFlagStr += "$";
|
||||
std::string avAgeStr = av->getAvatarAge();
|
||||
std::string avName = getRadarName(avId);
|
||||
|
||||
//llinfos << "Processing " << avName << " range: " << avRange << " key: " << avId << llendl;
|
||||
|
||||
//2b. ensure compatibility with avlist, should deprecate
|
||||
av->setRange(avRange);
|
||||
av->setPosition(avPos);
|
||||
av->setFirstSeen(time(NULL) - (time_t)seentime);
|
||||
av->setAvatarName(avName);
|
||||
|
||||
|
||||
//2c Report all detected to scripts if we were asked for an update
|
||||
if (alertScripts)
|
||||
av->setAvatarName(avName); // maintain compatibility with underlying list, deprecated
|
||||
U32 lastZOffsetTime = av->getLastZOffsetTime();
|
||||
F32 avZOffset = av->getZOffset();
|
||||
if (avPos[2] < 0.1) // if our official z position is 0.0, we need a correction.
|
||||
{
|
||||
mRadarEnterAlerts.push_back(avId);
|
||||
}
|
||||
// set correction if we have it
|
||||
if (avZOffset > 0.1)
|
||||
avPos[2] = avZOffset;
|
||||
else
|
||||
{
|
||||
avPos[2] = 9999; // placeholder value, better than "0", until we get real data.
|
||||
}
|
||||
|
||||
//schedule offset requests, if needed
|
||||
if (sUseLSLBridge && (now > (mRadarLastBulkOffsetRequestTime + COARSE_OFFSET_INTERVAL)) && (now > lastZOffsetTime + COARSE_OFFSET_INTERVAL))
|
||||
{
|
||||
mRadarOffsetRequests.push_back(avId);
|
||||
av->setLastZOffsetTime(now);
|
||||
}
|
||||
}
|
||||
F32 avRange = dist_vec(avPos, posSelf);
|
||||
av->setRange(avRange); // maintain compatibility with underlying list, deprecated
|
||||
av->setPosition(avPos); // maintain compatibility with underlying list, deprecated
|
||||
|
||||
//2d. Report on net-new entries.
|
||||
//
|
||||
//2b. Process newly detected avatars
|
||||
//
|
||||
if (lastRadarSweep.count(avId) == 0)
|
||||
{
|
||||
// chat alerts
|
||||
if (gSavedSettings.getBOOL("RadarReportChatRange") && (avRange <= CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered chat range (%3.2f m).",avRange)));
|
||||
if (gSavedSettings.getBOOL("RadarReportDrawRange") && (avRange <= drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered draw distance (%3.2f m).",avRange)));
|
||||
if (gSavedSettings.getBOOL("RadarReportSimRange") && (avRegion == regionSelf))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered the region (%3.2f m).",avRange)));
|
||||
if (gSavedSettings.getBOOL("RadarEnterChannelAlert") && (!mRadarAlertRequest))
|
||||
if (gSavedSettings.getBOOL("RadarEnterChannelAlert") || (alertScripts))
|
||||
{
|
||||
// Autodetect Phoenix chat UUID compatibility.
|
||||
// If Leave channel alerts are not set, restrict reports to same-sim only.
|
||||
|
|
@ -1010,9 +1016,84 @@ void LLPanelPeople::updateNearbyList()
|
|||
mRadarEnterAlerts.push_back(avId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//2e. Build out scrollist-style view
|
||||
//
|
||||
// 2c. Process previously detected avatars
|
||||
//
|
||||
else
|
||||
{
|
||||
radarFields rf; // will hold the newest version
|
||||
// Check for range crossing alert threshholds, being careful to handle double-listings
|
||||
if (lastRadarSweep.count(avId) == 1) // normal case, check from last position
|
||||
{
|
||||
rf = lastRadarSweep.find(avId)->second;
|
||||
if (gSavedSettings.getBOOL("RadarReportChatRange"))
|
||||
{
|
||||
if ((avRange <= CHAT_NORMAL_RADIUS) && (rf.lastDistance > CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered chat range (%3.2f m).",avRange)));
|
||||
else if ((avRange > CHAT_NORMAL_RADIUS) && (rf.lastDistance <= CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left chat range."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportDrawRange"))
|
||||
{
|
||||
if ((avRange <= drawRadius) && (rf.lastDistance > drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered draw distance (%3.2f m).",avRange)));
|
||||
else if ((avRange > drawRadius) && (rf.lastDistance <= drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left draw distance."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportSimRange"))
|
||||
{
|
||||
if ((avRegion == regionSelf) && (avRegion != rf.lastRegion))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered the region (%3.2f m).",avRange)));
|
||||
else if ((rf.lastRegion == regionSelf) && (avRegion != regionSelf))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left the region."));
|
||||
}
|
||||
}
|
||||
else if (lastRadarSweep.count(avId) > 1) // handle duplicates, from sim crossing oddness
|
||||
{
|
||||
// iterate through all the duplicates found, searching for the newest.
|
||||
rf.firstSeen=0;
|
||||
pair<multimap<LLUUID,radarFields>::iterator,multimap<LLUUID,radarFields>::iterator> dupeAvs;
|
||||
dupeAvs = lastRadarSweep.equal_range(avId);
|
||||
for (multimap<LLUUID,radarFields>::iterator it2 = dupeAvs.first; it2 != dupeAvs.second; ++it2)
|
||||
{
|
||||
if (it2->second.firstSeen > rf.firstSeen)
|
||||
rf = it2->second;
|
||||
}
|
||||
llinfos << "AO: Duplicates detected for " << avName <<" , most recent is " << rf.firstSeen << llendl;
|
||||
|
||||
if (gSavedSettings.getBOOL("RadarReportChatRange"))
|
||||
{
|
||||
if ((avRange <= CHAT_NORMAL_RADIUS) && (rf.lastDistance > CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered chat range (%3.2f m).",avRange)));
|
||||
else if ((avRange > CHAT_NORMAL_RADIUS) && (rf.lastDistance <= CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left chat range."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportDrawRange"))
|
||||
{
|
||||
if ((avRange <= drawRadius) && (rf.lastDistance > drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered draw distance (%3.2f m).",avRange)));
|
||||
else if ((avRange > drawRadius) && (rf.lastDistance <= drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left draw distance."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportSimRange"))
|
||||
{
|
||||
if ((avRegion == regionSelf) && (avRegion != rf.lastRegion))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered the region (%3.2f m).",avRange)));
|
||||
else if ((rf.lastRegion == regionSelf) && (avRegion != regionSelf))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left the region."));
|
||||
}
|
||||
}
|
||||
//If we were manually asked to update an external source for all existing avatars, add them to the queue.
|
||||
if (alertScripts)
|
||||
{
|
||||
mRadarEnterAlerts.push_back(avId);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//2d. Build out scrollist-style presentation view for this avatar row
|
||||
//
|
||||
LLSD row;
|
||||
row["value"] = avId;
|
||||
row["columns"][0]["column"] = "name";
|
||||
|
|
@ -1048,88 +1129,69 @@ void LLPanelPeople::updateNearbyList()
|
|||
radarNameCell->setFontStyle(LLFontGL::BOLD);
|
||||
else
|
||||
radarNameCell->setFontStyle(LLFontGL::NORMAL);
|
||||
|
||||
|
||||
if(LGGContactSets::getInstance()->hasFriendColorThatShouldShow(avId,FALSE,FALSE,TRUE))
|
||||
{
|
||||
radarNameCell->setColor(LGGContactSets::getInstance()->getFriendColor(avId));
|
||||
}
|
||||
//AO: Preserve selection
|
||||
if (lastRadarSelectedItem)
|
||||
{
|
||||
if (avId == selected_id)
|
||||
{
|
||||
mRadarList->selectByID(avId);
|
||||
updateButtons(); // TODO: only update on change, instead of every tick
|
||||
}
|
||||
|
||||
//2f. Check for range crossing alert threshholds, being careful to handle double-listings
|
||||
if (lastRadarSweep.count(avId) == 1) // normal case, check from last position
|
||||
{
|
||||
radarFields rf = lastRadarSweep.find(avId)->second;
|
||||
if (gSavedSettings.getBOOL("RadarReportChatRange"))
|
||||
{
|
||||
if ((avRange <= CHAT_NORMAL_RADIUS) && (rf.lastDistance > CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered chat range (%3.2f m).",avRange)));
|
||||
else if ((avRange > CHAT_NORMAL_RADIUS) && (rf.lastDistance <= CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left chat range."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportDrawRange"))
|
||||
{
|
||||
if ((avRange <= drawRadius) && (rf.lastDistance > drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered draw distance (%3.2f m).",avRange)));
|
||||
else if ((avRange > drawRadius) && (rf.lastDistance <= drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left draw distance."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportSimRange"))
|
||||
{
|
||||
if ((avRegion == regionSelf) && (avRegion != rf.lastRegion))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered the region (%3.2f m).",avRange)));
|
||||
else if ((rf.lastRegion == regionSelf) && (avRegion != regionSelf))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left the region."));
|
||||
}
|
||||
}
|
||||
else if (lastRadarSweep.count(avId) > 1) // handle duplicates, from sim crossing oddness
|
||||
{
|
||||
// iterate through all the duplicates found, searching for the newest.
|
||||
radarFields rf; // will hold the newest version
|
||||
rf.firstSeen=0;
|
||||
pair<multimap<LLUUID,radarFields>::iterator,multimap<LLUUID,radarFields>::iterator> dupeAvs;
|
||||
dupeAvs = lastRadarSweep.equal_range(avId);
|
||||
for (multimap<LLUUID,radarFields>::iterator it2 = dupeAvs.first; it2 != dupeAvs.second; ++it2)
|
||||
{
|
||||
if (it2->second.firstSeen > rf.firstSeen)
|
||||
rf = it2->second;
|
||||
}
|
||||
llinfos << "AO: Duplicates detected for " << avName <<" , most recent is " << rf.firstSeen << llendl;
|
||||
|
||||
if (gSavedSettings.getBOOL("RadarReportChatRange"))
|
||||
{
|
||||
if ((avRange <= CHAT_NORMAL_RADIUS) && (rf.lastDistance > CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered chat range (%3.2f m).",avRange)));
|
||||
else if ((avRange > CHAT_NORMAL_RADIUS) && (rf.lastDistance <= CHAT_NORMAL_RADIUS))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left chat range."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportDrawRange"))
|
||||
{
|
||||
if ((avRange <= drawRadius) && (rf.lastDistance > drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered draw distance (%3.2f m).",avRange)));
|
||||
else if ((avRange > drawRadius) && (rf.lastDistance <= drawRadius))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left draw distance."));
|
||||
}
|
||||
if (gSavedSettings.getBOOL("RadarReportSimRange"))
|
||||
{
|
||||
if ((avRegion == regionSelf) && (avRegion != rf.lastRegion))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, llformat(" entered the region (%3.2f m).",avRange)));
|
||||
else if ((rf.lastRegion == regionSelf) && (avRegion != regionSelf))
|
||||
LLAvatarNameCache::get(avId,boost::bind(&LLPanelPeople::radarAlertMsg, this, _1, _2, " left the region."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//STEP 3.0
|
||||
} // End STEP 2, all model/presentation row processing complete.
|
||||
//Reset scroll position
|
||||
mRadarList->setScrollPos(lastScroll);
|
||||
|
||||
//STEP 3: Handle any avatars that dropped off the detected list since last time.
|
||||
//
|
||||
//STEP 3 , process any bulk actions that require the whole model to be known first
|
||||
//
|
||||
|
||||
//
|
||||
//3a. dispatch requests for ZOffset updates, working around minimap's inaccurate height
|
||||
//
|
||||
if (mRadarOffsetRequests.size() > 0)
|
||||
{
|
||||
std::string prefix = "getZOffsets|";
|
||||
std::string msg = "";
|
||||
U32 updatesPerRequest=0;
|
||||
while(mRadarOffsetRequests.size() > 0)
|
||||
{
|
||||
LLUUID avId = mRadarOffsetRequests.back();
|
||||
mRadarOffsetRequests.pop_back();
|
||||
msg = llformat("%s%s,",msg.c_str(),avId.asString().c_str());
|
||||
if (++updatesPerRequest > MAX_OFFSET_REQUESTS)
|
||||
{
|
||||
msg = msg.substr(0,msg.size()-1);
|
||||
FSLSLBridgeRequestResponder* responder = new FSLSLBridgeRequestRadarPosResponder();
|
||||
FSLSLBridge::instance().viewerToLSL(prefix+msg,responder);
|
||||
//llinfos << " OFFSET REQUEST SEGMENT"<< prefix << msg << llendl;
|
||||
msg="";
|
||||
updatesPerRequest = 0;
|
||||
}
|
||||
}
|
||||
if (updatesPerRequest > 0)
|
||||
{
|
||||
msg = msg.substr(0,msg.size()-1);
|
||||
FSLSLBridgeRequestResponder* responder = new FSLSLBridgeRequestRadarPosResponder();
|
||||
FSLSLBridge::instance().viewerToLSL(prefix+msg,responder);
|
||||
//llinfos << " OFFSET REQUEST FINAL " << prefix << msg << llendl;
|
||||
}
|
||||
|
||||
// clear out the dispatch queue
|
||||
mRadarOffsetRequests.clear();
|
||||
mRadarLastBulkOffsetRequestTime = now;
|
||||
}
|
||||
|
||||
//
|
||||
//3b: process alerts for avatars that where here last frame, but gone this frame (ie, they left)
|
||||
// as well as dispatch all earlier detected alerts for crossing range thresholds.
|
||||
//
|
||||
|
||||
for (std::multimap <LLUUID, radarFields>::const_iterator i = lastRadarSweep.begin(); i != lastRadarSweep.end(); ++i)
|
||||
{
|
||||
LLUUID prevId = i->first;
|
||||
|
|
@ -1147,31 +1209,6 @@ void LLPanelPeople::updateNearbyList()
|
|||
mRadarLeaveAlerts.push_back(prevId);
|
||||
}
|
||||
}
|
||||
|
||||
//STEP 4: Update out local radar data cache, for faster tracking of changes
|
||||
lastRadarSweep.clear();
|
||||
for (std::vector<LLPanel*>::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem)
|
||||
{
|
||||
LLAvatarListItem* av = static_cast<LLAvatarListItem*>(*itItem);
|
||||
radarFields rf;
|
||||
rf.avName = av->getAvatarName();
|
||||
rf.lastDistance = av->getRange();
|
||||
rf.firstSeen = av->getFirstSeen();
|
||||
rf.lastStatus = av->getAvStatus();
|
||||
rf.lastGlobalPos = av->getPosition();
|
||||
if (rf.lastGlobalPos != LLVector3d(0.0f,0.0f,0.0f))
|
||||
{
|
||||
LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(rf.lastGlobalPos);
|
||||
if (lastRegion)
|
||||
rf.lastRegion = lastRegion->getRegionID();
|
||||
}
|
||||
else
|
||||
rf.lastRegion = LLUUID(0);
|
||||
|
||||
lastRadarSweep.insert(pair<LLUUID,radarFields>(av->getAvatarId(),rf));
|
||||
}
|
||||
|
||||
//STEP 5: Send out Chat alerts on events
|
||||
if (mRadarEnterAlerts.size() > 0)
|
||||
{
|
||||
mRadarFrameCount++;
|
||||
|
|
@ -1223,16 +1260,50 @@ void LLPanelPeople::updateNearbyList()
|
|||
msgs->addString("ButtonLabel", msg.c_str());
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
|
||||
//STEP 6: Update GUI text of number of total users
|
||||
mRadarList->setColumnLabel("name",llformat("NAME [%d]",lastRadarSweep.size()));
|
||||
|
||||
}
|
||||
// reset any active alert requests
|
||||
if (alertScripts)
|
||||
mRadarAlertRequest = false;
|
||||
|
||||
//
|
||||
//STEP 4: Cache our current model data, so we can compare it with the next fresh group of model data for fast change detection.
|
||||
//
|
||||
|
||||
//minimap updates
|
||||
lastRadarSweep.clear();
|
||||
for (std::vector<LLPanel*>::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem)
|
||||
{
|
||||
LLAvatarListItem* av = static_cast<LLAvatarListItem*>(*itItem);
|
||||
radarFields rf;
|
||||
rf.avName = av->getAvatarName();
|
||||
rf.lastDistance = av->getRange();
|
||||
rf.firstSeen = av->getFirstSeen();
|
||||
rf.lastStatus = av->getAvStatus();
|
||||
rf.ZOffset = av->getZOffset();
|
||||
rf.lastGlobalPos = av->getPosition();
|
||||
if ((rf.ZOffset > 0) && (rf.lastGlobalPos[2] < 1024)) // if our position may need an offset correction, see if we have one to apply
|
||||
{
|
||||
rf.lastGlobalPos[2] = rf.lastGlobalPos[2] + (1024 * rf.ZOffset);
|
||||
}
|
||||
//rf.lastZOffsetTime = av->getLastZOffsetTime();
|
||||
if (rf.lastGlobalPos != LLVector3d(0.0f,0.0f,0.0f))
|
||||
{
|
||||
LLViewerRegion* lastRegion = world->getRegionFromPosGlobal(rf.lastGlobalPos);
|
||||
if (lastRegion)
|
||||
rf.lastRegion = lastRegion->getRegionID();
|
||||
}
|
||||
else
|
||||
rf.lastRegion = LLUUID(0);
|
||||
|
||||
lastRadarSweep.insert(pair<LLUUID,radarFields>(av->getAvatarId(),rf));
|
||||
}
|
||||
|
||||
//
|
||||
//STEP 5: Final presentation updates
|
||||
//
|
||||
|
||||
// update header w/number of avs detected in this sweep
|
||||
mRadarList->setColumnLabel("name",llformat("NAME [%d]",lastRadarSweep.size()));
|
||||
// update minimap with selected avatars
|
||||
uuid_vec_t selected_uuids;
|
||||
LLUUID sVal = mRadarList->getSelectedValue().asUUID();
|
||||
if (sVal != LLUUID::null)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ class LLMenuButton;
|
|||
class LLMenuGL;
|
||||
|
||||
const U32 MAX_AVATARS_PER_ALERT = 7; // maximum number of UUIDs we can cram into a single channel radar alert message
|
||||
const U32 COARSE_OFFSET_INTERVAL = 31; // seconds after which we query the bridge for a coarse location adjustment
|
||||
const U32 COARSE_OFFSET_INTERVAL = 7; // seconds after which we query the bridge for a coarse location adjustment
|
||||
const U32 MAX_OFFSET_REQUESTS = 60; // 2048 / UUID size, leaving overhead space
|
||||
const U32 NAMEFORMAT_DISPLAYNAME = 0;
|
||||
const U32 RADAR_CHAT_MIN_SPACING = 6; //minimum delay between radar chat messages
|
||||
|
||||
|
|
@ -179,7 +180,7 @@ private:
|
|||
LLAvatarList* mRecentList;
|
||||
LLGroupList* mGroupList;
|
||||
LLRadarListCtrl* mRadarList;
|
||||
LLNetMap* mMiniMap;
|
||||
LLNetMap* mMiniMap;
|
||||
|
||||
LLHandle<LLView> mGroupPlusMenuHandle;
|
||||
LLHandle<LLView> mNearbyViewSortMenuHandle;
|
||||
|
|
@ -208,19 +209,23 @@ private:
|
|||
{
|
||||
std::string avName;
|
||||
F32 lastDistance;
|
||||
LLVector3d lastGlobalPos;
|
||||
LLUUID lastRegion;
|
||||
time_t firstSeen;
|
||||
LLVector3d lastGlobalPos;
|
||||
LLUUID lastRegion;
|
||||
time_t firstSeen;
|
||||
S32 lastStatus;
|
||||
S32 coarseOffset;
|
||||
U32 ZOffset;
|
||||
time_t lastZOffsetTime;
|
||||
|
||||
};
|
||||
std::multimap < LLUUID, radarFields > lastRadarSweep;
|
||||
std::vector <LLUUID> mRadarEnterAlerts;
|
||||
std::vector <LLUUID> mRadarLeaveAlerts;
|
||||
std::vector <LLUUID> mRadarOffsetRequests;
|
||||
|
||||
S32 mRadarFrameCount;
|
||||
bool mRadarAlertRequest;
|
||||
F32 mRadarLastRequestTime;
|
||||
U32 mRadarLastBulkOffsetRequestTime;
|
||||
};
|
||||
|
||||
#endif //LL_LLPANELPEOPLE_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue