diff --git a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp index 85390771..d74605bb 100644 --- a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp +++ b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp @@ -499,6 +499,22 @@ void plVirtualCam1::SetCutNextTrans() #endif } +void plVirtualCam1::SetCutNext() +{ + plCameraModifier1* cam = GetCurrentCamera(); + if (cam && cam->GetBrain()) { + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPosOnce); + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPOAOnce); + } + + SetFlags(kCutNextTrans); + SetRender(true); + +#ifdef STATUS_LOG + camLog->AddLineF("Set Camera to cut on next frame"); +#endif +} + void plVirtualCam1::SetRender(hsBool render) { fFlags.SetBit(kRender,render); diff --git a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h index 0f4ebf07..6649eabc 100644 --- a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h +++ b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h @@ -85,6 +85,7 @@ public: enum flags { kSetFOV, + /** Forces the next camera transition to be cut. */ kCutNextTrans, kRender, kRegionIgnore, @@ -145,6 +146,7 @@ public: hsPoint3 GetCameraPOA() { return fOutputPOA; } hsVector3 GetCameraUp() { return fOutputUp; } void SetCutNextTrans(); // used when player warps into a new camera region + void SetCutNext(); const hsMatrix44 GetCurrentMatrix() { return fMatrix; } static plVirtualCam1* Instance() { return fInstance; } diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp index cd5d123e..2c7d61da 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.cpp @@ -1978,3 +1978,12 @@ hsBool cyAvatar::IsCurrentBrainHuman() } return false; } + +void cyAvatar::SetDontPanicLink(bool value) +{ + if ( fRecvr.Count() > 0 ) { + plArmatureMod* mod = plAvatarMgr::FindAvatar(fRecvr[0]); + if (mod) + mod->SetDontPanicLinkFlag(value); + } +} diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h index e21a8929..168c748b 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h +++ b/Sources/Plasma/FeatureLib/pfPython/cyAvatar.h @@ -566,6 +566,14 @@ public: static hsBool IsCurrentBrainHuman(); + ///////////////////////////////////////////////////////////////////////////// + // + // Function : SetDontPanicLink + // PARAMETERS : value + // + // PURPOSE : Disables panic linking to Personal Age (warps the avatar back to the start instead) + // + void SetDontPanicLink(bool value); }; #endif // cyAvatar_h diff --git a/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp b/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp index 8a538415..96b39c2c 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyAvatarGlue.cpp @@ -597,6 +597,18 @@ PYTHON_METHOD_DEFINITION(ptAvatar, playSimpleAnimation, args) PYTHON_RETURN_NONE; } +PYTHON_METHOD_DEFINITION(ptAvatar, setDontPanicLink, args) +{ + bool value; + if (!PyArg_ParseTuple(args, "b", &value)) { + PyErr_SetString(PyExc_TypeError, "setDontPanicLink expects a boolean"); + PYTHON_RETURN_ERROR; + } + + self->fThis->SetDontPanicLink(value); + PYTHON_RETURN_NONE; +} + PYTHON_START_METHODS_TABLE(ptAvatar) PYTHON_METHOD(ptAvatar, netForce, "Params: forceFlag\nSpecify whether this object needs to use messages that are forced to the network\n" "- This is to be used if your Python program is running on only one client\n" @@ -651,6 +663,8 @@ PYTHON_START_METHODS_TABLE(ptAvatar) PYTHON_METHOD(ptAvatar, unRegisterForBehaviorNotify, "Params: selfKey\nThis will unregister behavior notifications"), PYTHON_METHOD(ptAvatar, playSimpleAnimation, "Params: animName\nPlay simple animation on avatar"), + + PYTHON_METHOD(ptAvatar, setDontPanicLink, "Params: value\nDisables panic linking to Personal Age (warps the avatar back to the start instead)"), PYTHON_END_METHODS_TABLE; PYTHON_GLOBAL_METHOD_DEFINITION(PtSetBehaviorLoopCount, args, "Params: behaviorKey,stage,loopCount,netForce\nThis will set the loop count for a particular stage in a multistage behavior") diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp index 9e384b3a..61556375 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue3.cpp @@ -606,12 +606,12 @@ PYTHON_GLOBAL_METHOD_DEFINITION_WKEY(PtWearDefaultClothingType, args, kw, "Param bool broadcast = false; if (!PyArg_ParseTupleAndKeywords(args, kw, "Ol|b", kwlist, &keyObj, &type, &broadcast)) { - PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothingType expects a ptKey and an unsigned long"); + PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothingType expects a ptKey, an unsigned long, and an optional bool"); PYTHON_RETURN_ERROR; } if (!pyKey::Check(keyObj)) { - PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothingType expects a ptKey and an unsigned long"); + PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothingType expects a ptKey, an unsigned long, and an optional bool"); PYTHON_RETURN_ERROR; } pyKey* key = pyKey::ConvertFrom(keyObj); diff --git a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue4.cpp b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue4.cpp index e5e9f772..0a30675c 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue4.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyMiscGlue4.cpp @@ -536,12 +536,12 @@ PYTHON_GLOBAL_METHOD_DEFINITION_WKEY(PtWearDefaultClothing, args, kw, "Params: k bool broadcast = false; if (!PyArg_ParseTupleAndKeywords(args, kw, "O|b", kwlist, &keyObj, &broadcast)) { - PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothing expects a ptKey"); + PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothing expects a ptKey and an optional bool"); PYTHON_RETURN_ERROR; } if (!pyKey::Check(keyObj)) { - PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothing expects a ptKey"); + PyErr_SetString(PyExc_TypeError, "PtWearDefaultClothing expects a ptKey and an optional bool"); PYTHON_RETURN_ERROR; } pyKey* key = pyKey::ConvertFrom(keyObj); diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp index 90fc261c..b3660d6a 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp @@ -865,10 +865,10 @@ void plArmatureMod::SpawnAt(int spawnNum, double time) w2l.RemoveScale(); ci->SetTransform(l2w, w2l); ci->FlushTransform(); - - if (plVirtualCam1::Instance()) - plVirtualCam1::Instance()->SetCutNextTrans(); - + + if (IsLocalAvatar() && plVirtualCam1::Instance()) + plVirtualCam1::Instance()->SetCutNext(); + if (GetFollowerParticleSystemSO()) { // Since particles are in world space, if we've got some surrounding us, we've got to translate them to compensate for our warp. diff --git a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h index b79f2105..77eecb45 100644 --- a/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h +++ b/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h @@ -234,7 +234,9 @@ public: virtual void PanicLink(hsBool playLinkOutAnim = true); virtual void PersonalLink(); - virtual bool ToggleDontPanicLinkFlag() { fDontPanicLink = fDontPanicLink ? false : true; return fDontPanicLink; } + bool ToggleDontPanicLinkFlag() { fDontPanicLink = fDontPanicLink ? false : true; return fDontPanicLink; } + + void SetDontPanicLinkFlag(bool value) { fDontPanicLink = value; } int GetBrainCount(); plArmatureBrain *GetNextBrain(plArmatureBrain *brain); diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp index 90846201..af3f6132 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputDevice.cpp @@ -176,19 +176,16 @@ void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDo if (key == KEY_SHIFT) { fShiftKeyDown = bKeyDown; -// return; } if (key == KEY_CTRL) { fCtrlKeyDown = bKeyDown; -// return; } if (key == KEY_CAPSLOCK) { - // Keyboards toggle the light on key-down, so I'm going with that. - if (bKeyDown && !bKeyRepeat) + if (!bKeyRepeat) { - fCapsLockLock = !fCapsLockLock; + fCapsLockLock = (GetKeyState(KEY_CAPSLOCK) & 1) == 1; plAvatarInputInterface::GetInstance()->ForceAlwaysRun(fCapsLockLock); } } @@ -208,7 +205,8 @@ void plKeyboardDevice::HandleWindowActivate(bool bActive, HWND hWnd) { if (bActive) { - fCtrlKeyDown = false; + // Refresh the caps lock state + HandleKeyEvent(KEYDOWN, KEY_CAPSLOCK, nil, false); } else { @@ -408,7 +406,7 @@ void plMouseDevice::CreateCursor( char* cursor ) fCursor->SetPosition( 0, 0, 0 ); IUpdateCursorSize(); - fCursor->SetVisible( true ); + fCursor->SetVisible(!bCursorHidden); fCursor->SetOpacity( fOpacity ); } @@ -510,9 +508,6 @@ void plMouseDevice::NewCursor(char* cursor) fInstance->CreateCursor(cursor); fInstance->SetCursorX(fInstance->GetCursorX()); fInstance->SetCursorY(fInstance->GetCursorY()); - - if (!plMouseDevice::bCursorHidden) - fInstance->fCursor->SetVisible( true ); } void plMouseDevice::SetCursorOpacity( hsScalar opacity ) diff --git a/Sources/Plasma/PubUtilLib/plInputCore/plInputInterfaceMgr.cpp b/Sources/Plasma/PubUtilLib/plInputCore/plInputInterfaceMgr.cpp index c1077d98..eda837ab 100644 --- a/Sources/Plasma/PubUtilLib/plInputCore/plInputInterfaceMgr.cpp +++ b/Sources/Plasma/PubUtilLib/plInputCore/plInputInterfaceMgr.cpp @@ -253,15 +253,13 @@ void plInputInterfaceMgr::IUpdateCursor( Int32 newCursor ) { char* mouseCursorResID; - - fCurrentCursor = newCursor; - if( fCurrentCursor == plInputInterface::kCursorHidden ) + if (newCursor == plInputInterface::kCursorHidden) { plMouseDevice::HideCursor(); - else - { - plMouseDevice::ShowCursor(); + } else { + if (fCurrentCursor == plInputInterface::kCursorHidden) + plMouseDevice::ShowCursor(); - switch( fCurrentCursor ) + switch(newCursor) { case plInputInterface::kCursorUp: mouseCursorResID = CURSOR_UP; break; case plInputInterface::kCursorLeft: mouseCursorResID = CURSOR_LEFT; break; @@ -286,12 +284,12 @@ void plInputInterfaceMgr::IUpdateCursor( Int32 newCursor ) case plInputInterface::kCursorHand: mouseCursorResID = CURSOR_HAND; break; case plInputInterface::kCursorUpward: mouseCursorResID = CURSOR_UPWARD; break; default: mouseCursorResID = CURSOR_OPEN; break; - } - - plMouseDevice::NewCursor( mouseCursorResID ); + plMouseDevice::NewCursor(mouseCursorResID); } + + fCurrentCursor = newCursor; } //// IEval /////////////////////////////////////////////////////////////////// diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp b/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp index 40abbff0..a43cc5e8 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp +++ b/Sources/Plasma/PubUtilLib/plResMgr/plResManager.cpp @@ -536,7 +536,7 @@ inline plKeyImp* IFindKeyLocalized(const plUoid& uoid, plRegistryPageNode* page) const char* objectName = uoid.GetObjectName(); // If we're running localized, try to find a localized version first - if (plLocalization::IsLocalized()) + if (objectName != nullptr && plLocalization::IsLocalized()) { char localName[256]; if (plLocalization::GetLocalized(objectName, localName))