From 3209507b6c03cc58eee055f02d45e0dd786ba6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Liru=20F=C3=A6rs?= Date: Fri, 10 Jan 2020 16:57:25 -0500 Subject: [PATCH] [Follow] Sit if target is sitting, stand when they stand Does object and ground sitting. May fly to sitting target if they're in air Ground sits as close as it can get if cannot reach ground sitting target Optimizes following when within desired range of target Moves sitting/standing autopilot cancels to more proper places --- indra/newview/llagent.cpp | 68 ++++++++++++++++++++++++++++++++-- indra/newview/llviewermenu.cpp | 6 +-- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 1a384b8f2..76f984c46 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1730,6 +1730,15 @@ void LLAgent::stopAutoPilot(BOOL user_cancel) mAutoPilotFinishedCallback(!user_cancel && dist_vec_squared(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < (mAutoPilotStopDistance * mAutoPilotStopDistance), mAutoPilotCallbackData); mAutoPilotFinishedCallback = NULL; } + + // Sit response during follow pilot, now complete, resume follow + if (!user_cancel && mAutoPilotBehaviorName == "Sit" && mLeaderID.notNull()) + { + mAutoPilotBehaviorName = "Follow"; + mAutoPilot = true; + return; + } + mLeaderID = LLUUID::null; mAutoPilotNoProgressFrameCount = 0; @@ -1758,14 +1767,54 @@ void LLAgent::autoPilot(F32 *delta_yaw) { if (mAutoPilot && isAgentAvatarValid()) { - bool follow = !mLeaderID.isNull(); //mAutoPilotBehaviorName == "Follow"; + U8 follow = mLeaderID.notNull(); //mAutoPilotBehaviorName == "Follow"; if (follow) { if (auto object = gObjectList.findObject(mLeaderID)) { mAutoPilotTargetGlobal = object->getPositionGlobal(); if (const auto& av = object->asAvatar()) // Fly if avatar target is flying + { setFlying(av->mInAir); + if (av->isSitting()) + { + if (!rlv_handler_t::isEnabled() || !gRlvHandler.hasBehaviour(RLV_BHVR_SIT)) + { + if (auto seat = av->getParent()) + { + mAutoPilotNoProgressFrameCount = 0; // Ground Sit may have incremented this, reset it + if (gAgentAvatarp->getParent() != seat) + { + void handle_object_sit(LLViewerObject*, const LLVector3&); + handle_object_sit(static_cast(seat), LLVector3::zero); + } + return; // If sitting, we won't be moving, exit here + } + else // Ground sit, but only if near enough + { + if (dist_vec(av->getPositionAgent(), getPositionAgent()) <= mAutoPilotStopDistance) // We're close enough, sit. + { + if (!gAgentAvatarp->isSittingAvatarOnGround()) + setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + mAutoPilotNoProgressFrameCount = 0; // Ground Sit may have incremented this, reset it now + return; // We're already sitting on the ground, we have nothing to do + } + else // We're not close enough yet + { + if (/*!gAgentAvatarp->isSitting() && */ // RLV takes care of sitting check for us inside standUp + mAutoPilotNoProgressFrameCount <= AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped) // Only stand up if we haven't exhausted our no progress frames + standUp(); // Unsit if need be, so we can move + follow = 2; // Indicate we want to groundsit + } + } + } + } + else if (gAgentAvatarp->isSitting()) // Leader isn't sitting, standUp if needed + { + standUp(); + mAutoPilotNoProgressFrameCount = 0; // Ground Sit may have incremented this, reset it + } + } } else // We might still have a valid avatar pos { @@ -1777,12 +1826,19 @@ void LLAgent::autoPilot(F32 *delta_yaw) stopAutoPilot(); return; } + standUp(); // Leader not rendered, we mustn't be sitting + mAutoPilotNoProgressFrameCount = 0; // Ground Sit may have incremented this, reset it mAutoPilotTargetGlobal = pos; // Should we fly if the height difference is great enough here? Altitude is often invalid... } + + if (dist_vec(mAutoPilotTargetGlobal, getPositionGlobal()) <= mAutoPilotStopDistance) + { + follow = 3; // We're close enough, indicate no walking + } } - if (!follow && gAgentAvatarp->mInAir && mAutoPilotAllowFlying) + if (follow % 2 == 0 && gAgentAvatarp->mInAir && mAutoPilotAllowFlying) { setFlying(TRUE); } @@ -1794,12 +1850,15 @@ void LLAgent::autoPilot(F32 *delta_yaw) F32 target_dist = direction.magVec(); - if (!follow && target_dist >= mAutoPilotTargetDist) + if (follow % 2 == 0 && target_dist >= mAutoPilotTargetDist) { mAutoPilotNoProgressFrameCount++; if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped) { - stopAutoPilot(); + if (follow) // Well, we tried to reach them, let's just ground sit for now. + setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + else + stopAutoPilot(); return; } } @@ -1841,6 +1900,7 @@ void LLAgent::autoPilot(F32 *delta_yaw) } *delta_yaw = yaw; + if (follow == 3) return; // We're close enough, all we need to do is turn // Compute when to start slowing down F32 slow_distance; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f2dac54af..667f35583 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3897,8 +3897,6 @@ void handle_object_sit(LLViewerObject* object, const LLVector3& offset = LLVecto } // [/RLVa:KB] - gAgent.stopAutoPilot(true); - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); @@ -3921,9 +3919,10 @@ void handle_object_sit_or_stand() return; } + gAgent.stopAutoPilot(true); + if (sitting_on_selection()) { - gAgent.stopAutoPilot(true); gAgent.standUp(); return; } @@ -9649,6 +9648,7 @@ class ListObjectSit : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { + gAgent.stopAutoPilot(true); handle_object_sit(gObjectList.findObject(LFIDBearer::getActiveSelectedID())); return true; }