bool plPXPhysical::Should_I_Trigger(bool enter, hsPoint3& pos) { // see if we are inside the detector hull, if so, then don't trigger bool trigger = false; bool inside = IsObjectInsideHull(pos); if ( !inside) { trigger = true; fInsideConvexHull = enter; } else { // catch those rare cases on slow machines that miss the collision before avatar penetrated the face if (enter && !fInsideConvexHull) { #ifdef PHYSX_SAVE_TRIGGERS_WORKAROUND trigger = true; fInsideConvexHull = enter; DetectorLogSpecial("**>Saved a missing enter collision: %s",GetObjectKey()->GetName().c_str()); #else DetectorLogSpecial("**>Could have saved a missing enter collision: %s",GetObjectKey()->GetName().c_str()); #endif PHYSX_SAVE_TRIGGERS_WORKAROUND } } return trigger; }
/////////////////////////////////// /////////////////////////////////// /// plPanicLinkDetector /////////////////////////////////// bool plPanicLinkRegion::MsgReceive(plMessage* msg) { if (plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg)) { if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey) return true; if (pCollMsg->fEntering) { plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey); if (avMod) { if (avMod->IsLinkedIn()) { hsPoint3 pos; if (avMod->GetController()) { avMod->GetController()->GetPositionSim(pos); DetectorLogSpecial("Avatar is panic linking. Position %f,%f,%f and is %s", pos.fX, pos.fY, pos.fZ, avMod->GetController()->IsEnabled() ? "enabled" : "disabled"); } avMod->PanicLink(fPlayLinkOutAnim); } else DetectorLogRed("PANIC LINK %s before we actually linked in!", GetKey()->GetName().c_str()); } } return true; } return plCollisionDetector::MsgReceive(msg); }
bool plExcludeRegionModifier::MsgReceive(plMessage* msg) { plExcludeRegionMsg *exclMsg = plExcludeRegionMsg::ConvertNoRef(msg); if (exclMsg) { if (exclMsg->GetCmd() == plExcludeRegionMsg::kClear) { DetectorLogSpecial("Clearing exclude region %s", GetKeyName().c_str()); IMoveAvatars(); fContainedAvatars.Reset(); ISetPhysicalState(true); } else if (exclMsg->GetCmd() == plExcludeRegionMsg::kRelease) { DetectorLogSpecial("Releasing exclude region %s", GetKeyName().c_str()); ISetPhysicalState(false); } GetTarget()->DirtySynchState(kSDLXRegion, exclMsg->fSynchFlags); return true; } // Avatar entering or exiting our volume. Only the owner of the SO logs this since // it does all the moving at clear time. plCollideMsg *collideMsg = plCollideMsg::ConvertNoRef(msg); if (collideMsg) { if (collideMsg->fEntering) { //DetectorLogSpecial("Avatar enter exclude region %s",GetKeyName().c_str()); fContainedAvatars.Append(collideMsg->fOtherKey); } else { //DetectorLogSpecial("Avatar exit exclude region %s",GetKeyName().c_str()); int idx = fContainedAvatars.Find(collideMsg->fOtherKey); if (idx != fContainedAvatars.kMissingIndex) fContainedAvatars.Remove(idx); } return true; } return plSingleModifier::MsgReceive(msg); }
bool plSubworldRegionDetector::MsgReceive(plMessage* msg) { plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg); if (pCollMsg) { if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey) return true; plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey); if (avMod) { DetectorLog("%s subworld detector %s", pCollMsg->fEntering ? "Entering" : "Exiting", GetKeyName().c_str()); if ((pCollMsg->fEntering && !fOnExit) || (!pCollMsg->fEntering && fOnExit)) { if (fSub) { plSceneObject* SO = plSceneObject::ConvertNoRef(fSub->ObjectIsLoaded()); if (SO) { DetectorLogSpecial("Switching to subworld %s", fSub->GetName().c_str()); plKey nilKey; plSubWorldMsg* msg = new plSubWorldMsg(GetKey(), avMod->GetKey(), fSub); msg->Send(); } } else { DetectorLogSpecial("Switching to main subworld"); plSubWorldMsg* msg = new plSubWorldMsg(GetKey(), avMod->GetKey(), nil); msg->Send(); } } } return true; } return plCollisionDetector::MsgReceive(msg); }
void plExcludeRegionSDLModifier::ISetCurrentStateFrom(const plStateDataRecord* srcState) { plSimpleStateVariable* var = srcState->FindVar(kXRegionSDLCleared); if (var) { bool cleared; var->Get(&cleared); DetectorLogSpecial("SDL %s exclude region %s", cleared ? "clearing" : "releasing", fXRegion->GetKeyName().c_str()); fXRegion->ISetPhysicalState(cleared); } }
hsBool plSceneInputInterface::MsgReceive( plMessage *msg ) { plLOSHitMsg *pLOSMsg = plLOSHitMsg::ConvertNoRef( msg ); if( pLOSMsg ) { if( pLOSMsg->fRequestID == ID_FIND_CLICKABLE ) { hsBool clearCursor = false; if (!fClickability) return true; if( pLOSMsg->fObj ) { // is this object clickable? plSceneObject *pObj = plSceneObject::ConvertNoRef( pLOSMsg->fObj->ObjectIsLoaded() ); if( pObj ) { if (fShowLOS) { if (pLOSMsg->fNoHit) DetectorLogSpecial("%s: LOS miss", pObj->GetKeyName().c_str()); else DetectorLogSpecial("%s: LOS hit", pObj->GetKeyName().c_str()); } int i; const plInterfaceInfoModifier* pMod = 0; for( i = 0; i < pObj->GetNumModifiers(); i++ ) { if (fBookMode == kNotOffering) // when sharing a book we don't care about other clickables { pMod = plInterfaceInfoModifier::ConvertNoRef( pObj->GetModifier(i) ); if (pMod) // we found our list, stop here { plLogicModBase* pLogicMod = (plLogicModBase*)pObj->GetModifierByType(plLogicModBase::Index()); if (!pLogicMod) return true; if (fCurrentClickable != pObj->GetKey()) { // is it the current clickable already? ClearClickableMap(); fCurrentCursor = SetCurrentCursorID(kNullCursor); fCurrentClickable = pObj->GetKey(); fCurrentClickableLogicMod = pLogicMod->GetKey(); fCurrentClickPoint = pLOSMsg->fHitPoint; for (int x = 0; x < pMod->GetNumReferencedKeys(); x++) fClickableMap.Append( new clickableTest(pMod->GetReferencedKey(x))); } else { // even if this is still the same clickable object, the cursor could be // ...at a different spot on the clickable, so save that fCurrentClickPoint = pLOSMsg->fHitPoint; } fCurrClickIsAvatar = false; return true; } } // see if it is an avatar plArmatureMod* armMod = (plArmatureMod*)plArmatureMod::ConvertNoRef( pObj->GetModifier(i)); if (armMod) { if (armMod->IsMidLink()) return true; // okay, are we a CCR? hsBool amCCR = plNetClientMgr::GetInstance()->GetCCRLevel(); // is this person a NPC or CCR? int mbrIdx=plNetClientMgr::GetInstance()->TransportMgr().FindMember(pObj->GetKey()); plNetTransportMember* pMbr = plNetClientMgr::GetInstance()->TransportMgr().GetMember(mbrIdx); if (!pMbr) // whoops - it's a freakin' NPC ! return true; if (pMbr->IsCCR()) { if (amCCR) { // we can click on them plMouseDevice::AddCCRToCursor(); } else { // nope return true; } } // now, if I am a CCR, let me click on anyone at any time if (amCCR) { ClearClickableMap(); fCurrentClickable = pObj->GetKey(); fCurrentClickableLogicMod = nil; fCurrClickIsAvatar = true; fCurrentCursor = SetCurrentCursorID(kCursorPoised); // not sure why we need to point on the avatar... // ...but maybe something in the future will need this fCurrentClickPoint = pLOSMsg->fHitPoint; plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(fCurrentClickable)); // also add their player ID to the cursor plMouseDevice::AddIDNumToCursor(pMbr->GetPlayerID()); return true; } // otherwise, cull people as necessary // also make sure that they are not in our ignore list else if (VaultAmIgnoringPlayer( pMbr->GetPlayerID())) return true; // further, if we are offering a book, only allow clicks on the person // whom we've already offered it to (to cancel it) else if (fBookMode == kBookOffered && pObj->GetKey() != fOffereeKey) return true; // within distance // also... make sure they aren't off climbing a ladder or looking at their KI else if (fBookMode == kOfferBook) { plArmatureBrain* curBrain = armMod->GetCurrentBrain(); if (curBrain) { if (curBrain->IsRunningTask()) { fCurrentCursor = SetCurrentCursorID(kCursorClickDisabled); plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(pObj->GetKey())); return true; } } plAvatarMgr* aMgr = plAvatarMgr::GetInstance(); if (aMgr) { if (aMgr->IsACoopRunning()) { fCurrentCursor = SetCurrentCursorID(kCursorClickDisabled); plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(pObj->GetKey())); return true; } } plSceneObject* locPlayer = (plSceneObject*)plNetClientMgr::GetInstance()->GetLocalPlayer(); // make sure that they are facing each other if ( locPlayer ) { hsVector3 ourView = locPlayer->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView); hsVector3 theirView = pObj->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView); float viewdot = ourView * theirView; hsVector3 towards(locPlayer->GetCoordinateInterface()->GetLocalToWorld().GetTranslate() - pObj->GetCoordinateInterface()->GetLocalToWorld().GetTranslate()); towards.Normalize(); float towardsdot = ourView * towards; if (viewdot > SHARE_FACING_TOLERANCE || towardsdot > SHARE_FACING_TOLERANCE ) { ResetClickableState(); return true; // not facing enough... reject } } //otherwise make sure that they are close enough to click on if (locPlayer) { hsPoint3 avPt = locPlayer->GetCoordinateInterface()->GetLocalToWorld().GetTranslate(); hsPoint3 objPt = pObj->GetCoordinateInterface()->GetLocalToWorld().GetTranslate(); hsVector3 dist(avPt - objPt); if ( dist.MagnitudeSquared() >= 16.0f ) // you are too far away { ResetClickableState(); return true; } if (hsABS(avPt.fZ - objPt.fZ) > 1.0f) // you need to also be in the same plane (some books are on top of rocks you need to jump onto) { ResetClickableState(); return true; } } } // finally - make sure this guy is not in our ignore lists. int x; for (x = 0; x < fIgnoredAvatars.Count(); x++) { if (fIgnoredAvatars[x] == pObj->GetKey()) { fCurrentCursor = SetCurrentCursorID(kCursorClickDisabled); plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(pObj->GetKey())); return true; } } for (x = 0; x < fGUIIgnoredAvatars.Count(); x++) { if (fGUIIgnoredAvatars[x] == pObj->GetKey()) { fCurrentCursor = SetCurrentCursorID(kCursorClickDisabled); plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(pObj->GetKey())); return true; } } ClearClickableMap(); fCurrentClickable = pObj->GetKey(); fCurrentClickableLogicMod = nil; fCurrClickIsAvatar = true; fCurrentCursor = SetCurrentCursorID(kCursorPoised); // not sure why we need to point on the avatar... // ...but maybe something in the future will need this fCurrentClickPoint = pLOSMsg->fHitPoint; plMouseDevice::AddNameToCursor(plNetClientMgr::GetInstance()->GetPlayerName(fCurrentClickable)); return true; } } // here! it's an object which is not clickable // no object, or not clickable or avatar fCurrentClickPoint = pLOSMsg->fHitPoint; ResetClickableState(); return false; } } // no object, or not clickable or avatar ResetClickableState(); } else if( pLOSMsg->fRequestID == ID_FIND_LOCALPLAYER ) { bool result = false; if( pLOSMsg->fObj ) { // is this object clickable? plSceneObject *pObj = plSceneObject::ConvertNoRef( pLOSMsg->fObj->ObjectIsLoaded() ); if( pObj ) { if (pObj == plNetClientMgr::GetInstance()->GetLocalPlayer()) result = true; } } if (result && !fFadedLocalAvatar) { IHalfFadeAvatar(true); return true; } else if (!result && fFadedLocalAvatar) { IHalfFadeAvatar(false); return true; } } if( pLOSMsg->fRequestID == ID_FIND_WALKABLE_GROUND ) { if (!pLOSMsg->fNoHit) { plAvatarMgr::GetInstance()->GetLocalAvatar()->TurnToPoint(pLOSMsg->fHitPoint); } return true; } return true; } plCursorChangeMsg *fakeReplyMsg = plCursorChangeMsg::ConvertNoRef( msg ); if( fakeReplyMsg != nil ) { hsBool deniedCurrent = false; plKey key = fakeReplyMsg->GetSender(); for (int i = 0; i < fClickableMap.Count(); i++) { if (fClickableMap[i]->key == key) { if( fakeReplyMsg->fType == plCursorChangeMsg::kNullCursor ) { // Means not clickable--gotta fix this someday fClickableMap[i]->val = false; if (fClickableMap[i]->key == fCurrentClickableLogicMod) { deniedCurrent = true; break; } } else { // And fix this... fClickableMap[i]->val = true; } } } if (deniedCurrent) ResetClickableState(); return true; } plRenderMsg *rMsg = plRenderMsg::ConvertNoRef( msg ); if( rMsg != nil ) { fPipe = rMsg->Pipeline(); plgDispatch::Dispatch()->UnRegisterForExactType( plRenderMsg::Index(), fManager->GetKey() ); return true; } // reply from coop share book multistage plNotifyMsg* pNMsg = plNotifyMsg::ConvertNoRef(msg); if (pNMsg) { for(int x=0; x < pNMsg->GetEventCount();x++) { proEventData* pED = pNMsg->GetEventRecord(0); if ( pED->fEventType == proEventData::kMultiStage ) { proMultiStageEventData* pMS = (proMultiStageEventData*)pED; if (pMS->fAvatar == fOffereeKey) // mojo has linked { // do something - they linked out but we are still in the multistage fOffereeKey = nil; } else if (pMS->fAvatar == plNetClientMgr::GetInstance()->GetLocalPlayerKey()) { // do something else if (fBookMode = kNotOffering && fPendingLink == false) // we just linked out { // make me clickable again ISendAvatarDisabledNotification(true); } else // we put the book back after our target linked out { fBookMode = kNotOffering; fPendingLink = false; // make ME clickable again ISendAvatarDisabledNotification(true); } } return true; } } return false; } // if someone pages out / in, remove them from our ignore list or notify them to ignore us plPlayerPageMsg* pPlayerMsg = plPlayerPageMsg::ConvertNoRef(msg); if (pPlayerMsg) { if (pPlayerMsg->fUnload) { int x; // first, remove this avatar from my list of avatars I ingore for clickable griefing (when the 'ignore avatars' key is pressed) for(x = 0; x < fLocalIgnoredAvatars.Count(); x++) { if (fLocalIgnoredAvatars[x] == pPlayerMsg->fPlayer) fLocalIgnoredAvatars.RemoveItem(pPlayerMsg->fPlayer); } // now deal with avatars we are always ignoring because of their current activity for(x = 0; x < fIgnoredAvatars.Count(); x++) { if (fIgnoredAvatars[x] == pPlayerMsg->fPlayer) fIgnoredAvatars.RemoveItem(pPlayerMsg->fPlayer); } for(x = 0; x < fGUIIgnoredAvatars.Count(); x++) { if (fGUIIgnoredAvatars[x] == pPlayerMsg->fPlayer) fGUIIgnoredAvatars.RemoveItem(pPlayerMsg->fPlayer); } if (fOffereeKey == pPlayerMsg->fPlayer) { if (fBookMode == kBookOffered) { // and put our own dialog back up... plKey avKey = plNetClientMgr::GetInstance()->GetLocalPlayerKey(); ISendOfferNotification(avKey, 0, false); //IManageIgnoredAvatars(fOffereeKey, false); fOffereeKey = nil; fBookMode = kNotOffering; ISendAvatarDisabledNotification(true); } } } else { // add them to the list we keep of everyone here: // but DO NOT add the local avatar if (pPlayerMsg->fPlayer != plNetClientMgr::GetInstance()->GetLocalPlayerKey()) fLocalIgnoredAvatars.Append(pPlayerMsg->fPlayer); if (fBookMode != kNotOffering) { // tell them to ignore us plInputIfaceMgrMsg* pMsg = new plInputIfaceMgrMsg(plInputIfaceMgrMsg::kDisableAvatarClickable); plKey avKey = plNetClientMgr::GetInstance()->GetLocalPlayerKey(); pMsg->SetAvKey(avKey); pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); pMsg->SetBCastFlag(plMessage::kLocalPropagate, false); pMsg->AddNetReceiver( pPlayerMsg->fClientID ); pMsg->Send(); // and tell them to ignore our victim //plInputIfaceMgrMsg* pMsg2 = new plInputIfaceMgrMsg(plInputIfaceMgrMsg::kDisableAvatarClickable); //pMsg2->SetAvKey(fOffereeKey); //pMsg2->SetBCastFlag(plMessage::kNetPropagate); //pMsg2->SetBCastFlag(plMessage::kNetForce); //pMsg2->SetBCastFlag(plMessage::kLocalPropagate, false); //pMsg2->AddNetReceiver( pPlayerMsg->fClientID ); //pMsg2->Send(); } // tell them to ingore us if we are looking at a GUI for(int x = 0; x < fGUIIgnoredAvatars.Count(); x++) { if (fGUIIgnoredAvatars[x] == plNetClientMgr::GetInstance()->GetLocalPlayerKey()) { plInputIfaceMgrMsg* pMsg3 = new plInputIfaceMgrMsg(plInputIfaceMgrMsg::kGUIDisableAvatarClickable); pMsg3->SetAvKey(fGUIIgnoredAvatars[x]); pMsg3->SetBCastFlag(plMessage::kNetPropagate); pMsg3->SetBCastFlag(plMessage::kNetForce); pMsg3->SetBCastFlag(plMessage::kLocalPropagate, false); pMsg3->AddNetReceiver( pPlayerMsg->fClientID ); pMsg3->Send(); return true; } } } } plInputIfaceMgrMsg *mgrMsg = plInputIfaceMgrMsg::ConvertNoRef( msg ); if( mgrMsg != nil ) { if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kDisableAvatarClickable ) { // ignore if already in list or this is who WE are offering the book to... if (mgrMsg->GetAvKey() == fOffereeKey) return true; for(int x = 0; x < fIgnoredAvatars.Count(); x++) { if (fIgnoredAvatars[x] == mgrMsg->GetAvKey()) return true; } fIgnoredAvatars.Append(mgrMsg->GetAvKey()); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kEnableAvatarClickable ) { for(int x = 0; x < fIgnoredAvatars.Count(); x++) { if (fIgnoredAvatars[x] == mgrMsg->GetAvKey()) fIgnoredAvatars.RemoveItem(mgrMsg->GetAvKey()); } } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kGUIDisableAvatarClickable ) { // ignore if already in list or this is who WE are offering the book to... if (mgrMsg->GetAvKey() == fOffereeKey) return true; for(int x = 0; x < fGUIIgnoredAvatars.Count(); x++) { if (fGUIIgnoredAvatars[x] == mgrMsg->GetAvKey()) return true; } fGUIIgnoredAvatars.Append(mgrMsg->GetAvKey()); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kGUIEnableAvatarClickable ) { for(int x = 0; x < fGUIIgnoredAvatars.Count(); x++) { if (fGUIIgnoredAvatars[x] == mgrMsg->GetAvKey()) fGUIIgnoredAvatars.RemoveItem(mgrMsg->GetAvKey()); } } else if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kEnableClickables ) { fClickability = true; return true; } else if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kDisableClickables ) { fClickability = false; ResetClickableState(); return true; } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kSetOfferBookMode ) { fBookMode = kOfferBook; fOffereeKey = nil; fBookKey = mgrMsg->GetSender(); fOfferedAgeInstance = mgrMsg->GetAgeName(); fOfferedAgeFile = mgrMsg->GetAgeFileName(); ISendAvatarDisabledNotification(false); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kClearOfferBookMode ) { if (fBookMode == kOfferAccepted || fBookMode == kOfferLinkPending) { fPendingLink = true; } else if (fOffereeKey != nil) { // notify any offeree that the offer is rescinded ISendOfferNotification(fOffereeKey, -999, true); //IManageIgnoredAvatars(fOffereeKey, false); fOffereeKey = nil; } // shut down offer book mode fBookMode = kNotOffering; ISendAvatarDisabledNotification(true); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kNotifyOfferRejected) { if (fBookMode == kBookOffered) { // and put our own dialog back up... plKey avKey = plNetClientMgr::GetInstance()->GetLocalPlayerKey(); ISendOfferNotification(avKey, 0, false); //IManageIgnoredAvatars(fOffereeKey, false); fBookMode = kOfferBook; fOffereeKey = nil; } else if (mgrMsg->GetSender() == plNetClientMgr::GetInstance()->GetLocalPlayerKey()) { fBookMode = kNotOffering; ISendAvatarDisabledNotification(true); } } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kNotifyOfferAccepted && fBookMode == kBookOffered) { fBookMode = kOfferAccepted; } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kNotifyOfferCompleted ) { // must have actually offered the book... if (!fPendingLink) { if (fBookMode == kOfferBook || fBookMode == kBookOffered) return true; } if (!plNetClientMgr::GetInstance()) return true; fOffereeID = mgrMsg->GetPageID(); ILinkOffereeToAge(); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kSetShareSpawnPoint ) { fSpawnPoint = mgrMsg->GetSpawnPoint(); } else if ( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kSetShareAgeInstanceGuid ) { fAgeInstanceGuid = plUUID(mgrMsg->GetAgeInstanceGuid()); } } plVaultNotifyMsg* pVaultMsg = plVaultNotifyMsg::ConvertNoRef(msg); if (pVaultMsg && pVaultMsg->GetType()==plNetCommon::VaultTasks::kRegisterOwnedAge ) { //sanity check - if (fBookMode != kOfferLinkPending && fPendingLink == false) return true; // stop looking for this message and reset interface to 'offer book' mode again plgDispatch::Dispatch()->UnRegisterForExactType(plVaultNotifyMsg::Index(), fManager->GetKey()); ILinkOffereeToAge(); return true; } return false; }