Alex Jacobson Posted November 17, 2013 Posted November 17, 2013 So, yeah, it's not unconsciousness. If you disable fixation of X/Y rotation in xLoversMainScriptModuleAdjustPosition from Lovers with PK.esp, you can freely look up and down from first person mode, though such change breaks poses where you're oriented differently (e.g. lying on side). You can disable Z rotation fixation as well, but it'll break everything then. Here's a modified Lovers with PK, back up your old Lovers with PK.esp, use at your own risk, etc. I haven't figured out how to edit Lovers with PK Extender.esp without breaking it, so I haven't figured out how to disable third person camera in Lovers, but you can manually press your first-person view key and enter "tfc" in console. Lovers with PK.esp
Alex Jacobson Posted November 17, 2013 Posted November 17, 2013 I don't know, it's a rather old installation so probably not. If the framework hasn't changed much you can do make your own esp in 10 minutes, just comment following lines in xLoversMainScriptModuleAdjustPosition. I'll try to take a look at LAPF today. zme.setAngle x 0 zme.setAngle y 0 ... xme.setAngle x 0 xme.setAngle y 0 EDIT: Edited LAPF esp Lovers with PK.esp
Mailamea Posted November 19, 2013 Posted November 19, 2013 Guys how do you guys make the legs and foot appear? tried this but im just a floating body and hands in first person view.
ger4 Posted November 19, 2013 Posted November 19, 2013 Guys how do you guys make the legs and foot appear? tried this but im just a floating body and hands in first person view. Have you installed this OBSE plugin http://oblivion.nexusmods.com/mods/44337//? ? If not, then install the plugin, start having sex i-game, exit flycam mode by entering tfc into the console and then press the R key to go into first person. That should work.
Mailamea Posted November 20, 2013 Posted November 20, 2013 Thanks it works now, how do i keep animations from playing in third person? lovers animations forces me in third person when i hit to first person i change back to third. Thanks EDIT : was clumsy again, fixed it, so camera rotation on first person while on position is no no yet?
Mailamea Posted November 20, 2013 Posted November 20, 2013 Anyone have any ideas how to modify a .dll file? I'd like to replicate it for fallout if i can lol. Messing with tfc wishing fallout has this.
Happysparkles Posted November 21, 2013 Posted November 21, 2013 Anyone have any ideas how to modify a .dll file? I'd like to replicate it for fallout if i can lol. Messing with tfc wishing fallout has this. 2013-11-20_00009.jpg 2013-11-20_00010.jpg Wow, well you're off to a Great Start Mailamea! None the less please check this link out. http://www.wikihow.com/Edit-DLL-Files It should get you started on modifying those DLL filre PS: Sorry if it does not work, I've never tried it myself . Also for any of you who may still not be sure about downloading this mod, please allow me to give you 2 reasons why you should . Enjoy, -HappySparkles
fejeena Posted November 21, 2013 Posted November 21, 2013 Not working, I have "double melons" = 4 tits in first Person mode. Edit: I also see in the Video 4 tits. The bigger the tits the more clearly you can see the top pair. Hope the modder will fix it.
ger4 Posted November 21, 2013 Posted November 21, 2013 Not working, I have "double melons" = 4 tits in first Person mode. Double melons.jpg Edit: I also see in the Video 4 tits. The bigger the tits the more clearly you can see the top pair. Hope the modder will fix it. To fix the 'double tits' bug you have to go into the OBSE/Plugins folder and open EnhancedCamera.ini . In there set [Main] ; Enables first person during events where the game normally switches to third person bFirstPersonSitting=1 bFirstPersonKnockout=1 bFirstPersonDeath=1 ; Enables first person for mods that switch to third person to play animations bFirstPersonModAnim=1 ; Enables the head node to make hair visible when in first person bEnableHeadFirstPerson=0 ; Enables a visible body while riding a horse in first person bHorseFirstPersonBody=0 ; Enables experimental third person arms when in first person bUseThirdPersonArms=0 bRotateThirdPersonArms=0 to [Main] ; Enables first person during events where the game normally switches to third person bFirstPersonSitting=1 bFirstPersonKnockout=1 bFirstPersonDeath=1 ; Enables first person for mods that switch to third person to play animations bFirstPersonModAnim=1 ; Enables the head node to make hair visible when in first person bEnableHeadFirstPerson=0 ; Enables a visible body while riding a horse in first person bHorseFirstPersonBody=0 ; Enables experimental third person arms when in first person bUseThirdPersonArms=1 bRotateThirdPersonArms=1
DrN Posted November 21, 2013 Posted November 21, 2013 copy paste from posr #10,soz guys, but I guess noone noticed or knows an answer.Might be the one we all are looking for. Actually there is a first person animation... http://up.mnty.net/?...dit&edit=002139 , called benki first person. I asked a long time ago if it is compatible with lovers,got no answer, and guessed either ppl didnt notice it or noone knew.
Ark of Truth Posted November 21, 2013 Posted November 21, 2013 Anyone have any ideas how to modify a .dll file? I'd like to replicate it for fallout if i can lol. Messing with tfc wishing fallout has this. 2013-11-20_00009.jpg 2013-11-20_00010.jpg
Mailamea Posted November 21, 2013 Posted November 21, 2013 Anyone have any ideas how to modify a .dll file? I'd like to replicate it for fallout if i can lol. Messing with tfc wishing fallout has this. 2013-11-20_00009.jpg 2013-11-20_00010.jpg i know right, i just wanted to know how was he able to make the camera use the eye bone using just a single dll
Mailamea Posted November 21, 2013 Posted November 21, 2013 Not working, I have "double melons" = 4 tits in first Person mode. Double melons.jpg Edit: I also see in the Video 4 tits. The bigger the tits the more clearly you can see the top pair. Hope the modder will fix it. read the fix below your post, using dmra as well no problems.
Ark of Truth Posted November 21, 2013 Posted November 21, 2013 -snip- i know right, i just wanted to know how was he able to make the camera use the eye bone using just a single dll I have no idea, its beyond my knowledge.
fejeena Posted November 21, 2013 Posted November 21, 2013 Thanks ger4, works fine now. here only small tits but tested it also with giant boobs. no third and fourth nipple
D_ManXX2 Posted November 21, 2013 Posted November 21, 2013 Anyone have any ideas how to modify a .dll file? I'd like to replicate it for fallout if i can lol. Messing with tfc wishing fallout has this. 2013-11-20_00009.jpg 2013-11-20_00010.jpg you should ask Hydrogen: http://www.loverslab.com/topic/19451-hdt-support-unoff-release-v9-28-minor-v11-16-see-minor-rls-links-for-info-xp32-new-physics-enabled-outfit/ Hydrogen made HDT system for skyrim. maybe he can help you convert it to new Vegas.
Mailamea Posted November 22, 2013 Posted November 22, 2013 Sent Hydrogen a message. Lets hope its not so utterly complicated. LogicDragon personally replied to it and he said he might take a look for fallout if he has some time. I think if already out of their leauge. LOL #include "obse/PluginAPI.h"#include "obse/CommandTable.h"#include "obse/GameAPI.h"#include "obse/GameData.h"#include "obse/GameForms.h"#include "obse/GameMenus.h"#include "obse/GameObjects.h"#include "obse/GameProcess.h"#include "obse/NiAPI.h"#include "obse/NiControllers.h"#include "obse/NiNodes.h"#include "obse/NiObjects.h"#include "obse/NiTypes.h"#include "obse_common/SafeWrite.h"#include "obse/Utilities.h"#include <windows.h>#include "matrix.h"PluginHandle g_pluginHandle = kPluginHandle_Invalid;OBSEScriptInterface * g_scriptInterface = NULL; // make sure you assign to this#define ExtractArgsEx(...) g_scriptInterface->ExtractArgsEx(__VA_ARGS__)IDebugLog gLog("EnhancedCamera.log");char inipath[] = "Data\\obse\\plugins\\EnhancedCamera.ini";// ini settingsstatic int g_bFirstPersonSitting = 0;static int g_bFirstPersonKnockout = 0;static int g_bFirstPersonDeath = 0;static int g_bFirstPersonModAnim = 0;static int g_bEnableHeadFirstPerson = 0;static int g_bHorseFirstPersonBody = 0;static int g_bUseThirdPersonArms = 0;static int g_bRotateThirdPersonArms = 0;// Stores if the game is in 1st or 3rd personstatic int g_isThirdPerson = 0;// This should be set when the game force switches to 3rd person (sitting anim, knockout)// if set the camera should be moved in front of the player's facestatic int g_forceThirdPerson = 0;// Should not enable visible body while riding a horse// (can sometimes see yourself without a head/arms)static int g_horseToggle = 0;// Used to detect when a mod switches to third person to play an animationstatic int g_checkIdle = 0;// Pointer to the First Person camera node stored in Oblivion// See: GameObjects.cpp, g_1stPersonCameraNodestatic NiNode ** g_FirstPersonCameraNode = (NiNode**)0x00B3BB0C;// Calls Oblivion's built-in procedure for scanning nif trees - NiAVObject::Unk_16()NiNode * FindNode(NiNode * node, const char * name) { _asm { mov edx, name mov ecx, node push edx mov eax, dword ptr [ecx] mov edx, dword ptr [eax+0x58] call edx // This automatically sets the return value }}// Returns if an actor is currently vampire feedingbool IsVampireFeeding(Actor * act) { _asm { mov ecx, act mov edx, [ecx] mov eax, [edx+0x358] call eax // HasVampireFeedPackage(), sets return value }}// Applies MagicShaderHitEffect to playerbool ApplyMagicEffectShader(MagicShaderHitEffect * shader) { _asm { mov ecx, shader mov edx, [ecx] mov eax, [edx+0x68] call eax // Applies the shader, sets return value }}// Returns true if dialog menu is openbool InDialogMenu() { InterfaceManager *im = InterfaceManager::GetSingleton(); return (!im->IsGameMode() && (im->MenuModeHasFocus(kMenuType_Dialog) || im->MenuModeHasFocus(kMenuType_Persuasion)));}// Returns true if first person body is visiblebool IsFirstPerson() { return !g_isThirdPerson;}void *idlePlaying = (void *)0x00472EA0;// Returns true if a special idle is playing on the playerbool IsIdlePlaying() { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); ActorAnimData* anim = proc->animData; _asm { mov ecx, anim call idlePlaying not al and al, 0x1 }}// Sets and resets scale of 3rd person skeleton nodes// Must also call ThisStdCall(0x00471F20, anim) to update them properlyvoid UpdateSkeletonNodes(bool toggleNodes) { NiNode * node; if (toggleNodes) { if (g_bUseThirdPersonArms == 0 && ((*g_thePlayer)->horseOrRider == 0 || g_bHorseFirstPersonBody != 1)) { node = FindNode((*g_thePlayer)->niNode, "Bip01 L Clavicle"); node->m_fLocalScale = 1; node = FindNode((*g_thePlayer)->niNode, "Bip01 R Clavicle"); node->m_fLocalScale = 1; } if (g_bEnableHeadFirstPerson == 0 || InDialogMenu()) { node = FindNode((*g_thePlayer)->niNode, "Bip01 Head"); node->m_fLocalScale = 1; } } else { if (g_bUseThirdPersonArms == 0 && ((*g_thePlayer)->horseOrRider == 0 || g_bHorseFirstPersonBody != 1)) { node = FindNode((*g_thePlayer)->niNode, "Bip01 L Clavicle"); node->m_fLocalScale = 0; node = FindNode((*g_thePlayer)->niNode, "Bip01 R Clavicle"); node->m_fLocalScale = 0; } if (g_bEnableHeadFirstPerson == 0 || InDialogMenu()) { node = FindNode((*g_thePlayer)->niNode, "Bip01 Head"); node->m_fLocalScale = 0; } }}// Hooks the code to switch POVstatic void __stdcall HookSwitchPOV(void) { g_isThirdPerson = (*g_thePlayer)->isThirdPerson; NiNode * n; HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int isVanityMode = *(UInt8*)0x00B3BB04; if ((*g_thePlayer)->isThirdPerson == 0 && isVanityMode == 0) { if ((*g_thePlayer)->horseOrRider && g_bHorseFirstPersonBody == 0) { n = (*g_thePlayer)->niNode; n->m_flags = n->m_flags | 0x0001; } else { n = (*g_thePlayer)->niNode; n->m_flags = n->m_flags & 0xfffe; } // Note: Visible first person body while riding a horse results in visual glitches if (g_bUseThirdPersonArms || ((*g_thePlayer)->horseOrRider && g_bHorseFirstPersonBody == 1)) { n = (*g_thePlayer)->firstPersonNiNode; n->m_flags = n->m_flags | 0x0001; } else { n = (*g_thePlayer)->firstPersonNiNode; n->m_flags = n->m_flags & 0xfffe; } if ((*g_thePlayer)->horseOrRider) { g_horseToggle = 1; } // Reset this here, just in case g_forceThirdPerson = 0; g_checkIdle = 0; } else { g_horseToggle = 0; n = (*g_thePlayer)->niNode; n->m_flags = n->m_flags & 0xfffe; n = (*g_thePlayer)->firstPersonNiNode; n->m_flags = n->m_flags | 0x0001; if (g_bFirstPersonModAnim) { g_forceThirdPerson = 2; g_checkIdle = 1; } else { g_forceThirdPerson = 0; g_checkIdle = 0; } }}// Used to rotate a node in the root node's bonespacevoid RotateNode(Actor * act, NiNode * node, float rad) { NiMatrix33 mRootInverse; NiMatrix33 mNodeWorld; NiMatrix33 mParentWorld; NiMatrix33 mParentInverse; NiMatrix33 mRotate1; NiMatrix33 mRotate2; // Call UpdateTransform() to update the node's world rotation matrix. // It seems to not be modified in the animations, so not updating it causes a bug. node->UpdateTransform(); // Calculate the inverse of the root node NiNode * nRoot; nRoot = act->niNode; MatrixInverse(&mRootInverse, &(nRoot->m_worldRotate)); // Calculates the NodeWorldMatrix and ParentWorldMatrix without the root node NiNode * nParent = static_cast<NiNode *>(node->m_parent); MatrixMultiply(&mNodeWorld, &mRootInverse, &(node->m_worldRotate)); MatrixMultiply(&mParentWorld, &mRootInverse, &(nParent->m_worldRotate)); // Calculates the rotation matrix in Z-axis mRotate1.data[0] = 1.0f; mRotate1.data[1] = 0.0f; mRotate1.data[2] = 0.0f; mRotate1.data[3] = 0.0f; mRotate1.data[4] = cos(rad); mRotate1.data[5] = -sin(rad); mRotate1.data[6] = 0.0f; mRotate1.data[7] = sin(rad); mRotate1.data[8] = cos(rad); // Applies rotation to NodeWorldMatrix MatrixMultiply(&mRotate2, &mRotate1, &mNodeWorld); // Applies the ParentWorldMatrix inverse to get the node local matrix MatrixInverse(&mParentInverse, &mParentWorld); MatrixMultiply(&(node->m_localRotate), &mParentInverse, &mRotate2);}// Rotate the arms when the player looks up and downvoid RotateArms() { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); ActorAnimData* animData = proc->animData; float playerAngle = (*g_thePlayer)->rotX; float rotateLClavicle = 0.0f; float rotateRClavicle = 0.0f; // Determines the type of the equipped weapon int weaponType = -1; ExtraContainerChanges::EntryData* weaponData = proc->equippedWeaponData; if (weaponData) { TESForm * form = weaponData->type; if (form && form->typeID == kFormType_Weapon) { TESObjectWEAP * weaponForm = static_cast<TESObjectWEAP *>(form); weaponType = weaponForm->type; } } if (animData && animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastSelf, TESAnimGroup::kAnimGroup_CastTargetAlt)) { if (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouch, TESAnimGroup::kAnimGroup_CastTarget) || animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouchAlt, TESAnimGroup::kAnimGroup_CastTargetAlt)) { rotateLClavicle = playerAngle; rotateRClavicle = playerAngle; } } else if (proc->IsAttacking()) { if (weaponType == TESObjectWEAP::kType_BladeOneHand || weaponType == TESObjectWEAP::kType_BluntOneHand) { rotateRClavicle = playerAngle * 0.35; } else if (weaponType == TESObjectWEAP::kType_Bow) { rotateLClavicle = playerAngle * 0.35; rotateRClavicle = playerAngle * 0.35 * 0.5; } else { rotateLClavicle = playerAngle * 0.35; rotateRClavicle = playerAngle * 0.35; } } else if (proc->IsBlocking()) { if (weaponType == TESObjectWEAP::kType_BladeOneHand || weaponType == TESObjectWEAP::kType_BluntOneHand) { if (proc->GetEquippedAmmoData(1)) { // GetEquippedShieldData() rotateLClavicle = playerAngle * 0.4; } else { rotateRClavicle = playerAngle * 0.4; } } else if (weaponType == TESObjectWEAP::kType_BladeTwoHand || weaponType == TESObjectWEAP::kType_BluntTwoHand) { rotateLClavicle = playerAngle * 0.4; rotateRClavicle = playerAngle * 0.4; } else if (weaponType == TESObjectWEAP::kType_Bow) { rotateLClavicle = playerAngle * 0.4; } else if (weaponType == TESObjectWEAP::kType_Staff) { rotateLClavicle = playerAngle * 0.4; rotateRClavicle = playerAngle * 0.4; } else { // HandToHand rotateLClavicle = playerAngle * 0.4; rotateRClavicle = playerAngle * 0.4; } } else if (proc->GetEquippedWeaponData(1)) { // GetEquippedTorchData() rotateLClavicle = playerAngle * 0.6; } // Fix magicNode position for casting animations if (animData && (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouch, TESAnimGroup::kAnimGroup_CastTarget) || animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouchAlt, TESAnimGroup::kAnimGroup_CastTargetAlt))) { NiNode * nMagicNode; NiNode * nParentNode; NiNode * node; NiVector3 v, v1, v2; nMagicNode = FindNode((*g_thePlayer)->niNode, "magicNode"); nParentNode = static_cast<NiNode *>(nMagicNode->m_parent); if (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouch)) { NiNode *n1, *n2; NiVector3 w1, w2; n1 = FindNode((*g_thePlayer)->niNode, "Bip01 L Hand"); n2 = FindNode((*g_thePlayer)->niNode, "Bip01 R Hand"); v.x = 12.0; v.y = 4.0; v.z = 0.0; MatrixVectorMultiply(&w1, &(n1->m_worldRotate), &v); MatrixVectorMultiply(&w2, &(n2->m_worldRotate), &v); v.x = 0.5 * ((n1->m_worldTranslate).x + w1.x + (n2->m_worldTranslate).x + w2.x); v.y = 0.5 * ((n1->m_worldTranslate).y + w1.y + (n2->m_worldTranslate).y + w2.y); v.z = 0.5 * ((n1->m_worldTranslate).z + w1.z + (n2->m_worldTranslate).z + w2.z); } else if (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTouchAlt)) { node = FindNode((*g_thePlayer)->niNode, "Bip01 R Hand"); v1.x = 6.58; v1.y = 3.05; v1.z = -0.1; MatrixVectorMultiply(&v2, &(node->m_worldRotate), &v1); v.x = (node->m_worldTranslate).x + v2.x; v.y = (node->m_worldTranslate).y + v2.y; v.z = (node->m_worldTranslate).z + v2.z; } else if (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTarget)) { node = FindNode((*g_thePlayer)->niNode, "Bip01 L Hand"); v1.x = 12.2; v1.y = 4.1; v1.z = 0.0; MatrixVectorMultiply(&v2, &(node->m_worldRotate), &v1); v.x = (node->m_worldTranslate).x + v2.x; v.y = (node->m_worldTranslate).y + v2.y; v.z = (node->m_worldTranslate).z + v2.z; } else if (animData->FindAnimInRange(TESAnimGroup::kAnimGroup_CastTargetAlt)) { node = FindNode((*g_thePlayer)->niNode, "Bip01 R Hand"); v1.x = 6.62; v1.y = 3.02; v1.z = -0.075; MatrixVectorMultiply(&v2, &(node->m_worldRotate), &v1); v.x = (node->m_worldTranslate).x + v2.x; v.y = (node->m_worldTranslate).y + v2.y; v.z = (node->m_worldTranslate).z + v2.z; } NiVector3 wTranslate; wTranslate.x = v.x - (nParentNode->m_worldTranslate).x; wTranslate.y = v.y - (nParentNode->m_worldTranslate).y; wTranslate.z = v.z - (nParentNode->m_worldTranslate).z; NiMatrix33 mParentInverse; MatrixInverse(&mParentInverse, &(nParentNode->m_worldRotate)); MatrixVectorMultiply(&(nMagicNode->m_localTranslate), &mParentInverse, &wTranslate); } NiNode * node; node = FindNode((*g_thePlayer)->niNode, "Bip01 L Clavicle"); RotateNode((*g_thePlayer), node, -rotateLClavicle); node = FindNode((*g_thePlayer)->niNode, "Bip01 R Clavicle"); RotateNode((*g_thePlayer), node, -rotateRClavicle);}// This code translates the first person skeleton to the correct position// and allows you to see the hands on the 1st person body while seeing legs from 3rd person bodyvoid TranslateFirstPerson() { // Update the skeleton to get correct world translation values ThisStdCall(0x00471F20, (*g_thePlayer)->firstPersonAnimData); // applies animData to skeleton // Calculate displacement of first person camera NiNode * nRootFirst = (*g_thePlayer)->firstPersonNiNode; NiNode * nCameraFirst = *g_FirstPersonCameraNode; NiVector3 vFirstPerson; NiVector3 vThirdPerson; vFirstPerson.x = nCameraFirst->m_worldTranslate.x - nRootFirst->m_worldTranslate.x; vFirstPerson.y = nCameraFirst->m_worldTranslate.y - nRootFirst->m_worldTranslate.y; vFirstPerson.z = nCameraFirst->m_worldTranslate.z - nRootFirst->m_worldTranslate.z; // Calculate displacement of third person camera NiNode * nRootThird = (*g_thePlayer)->niNode; NiNode * nHead = FindNode((*g_thePlayer)->niNode, "Bip01 Head"); NiVector3 * tHead = &(nHead->m_worldTranslate); NiVector3 v0, v1; v0.x = 0.0; v0.y = 14.0; v0.z = 6.0; MatrixVectorMultiply(&v1, &(nRootThird->m_worldRotate), &v0); vThirdPerson.x = (tHead->x + v1.x) - nRootThird->m_worldTranslate.x; vThirdPerson.y = (tHead->y + v1.y) - nRootThird->m_worldTranslate.y; vThirdPerson.z = (tHead->z + v1.z) - nRootThird->m_worldTranslate.z; // This should give the difference between the root node positions NiVector3 vTranslateRoot; vTranslateRoot.x = nRootThird->m_localTranslate.x - nRootFirst->m_localTranslate.x; vTranslateRoot.y = nRootThird->m_localTranslate.y - nRootFirst->m_localTranslate.y; vTranslateRoot.z = nRootThird->m_localTranslate.z - nRootFirst->m_localTranslate.z; // Translate 1st person root node to new position nRootFirst->m_localTranslate.x += vThirdPerson.x - vFirstPerson.x + vTranslateRoot.x; nRootFirst->m_localTranslate.y += vThirdPerson.y - vFirstPerson.y + vTranslateRoot.y; nRootFirst->m_localTranslate.z += vThirdPerson.z - vFirstPerson.z + vTranslateRoot.z; // Hide 1st person arms when sleeping HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int sitSleepFlag = proc->unk11D; if (sitSleepFlag >= 8) { nRootFirst->m_localTranslate.z -= 100; }}// Runs animation editing code// Note: This function is actually called twice by the game for both 1st/3rd person skeletons// (*g_thePlayer)->isThirdPerson gets set to corresponding valuesvoid UpdateActor(Actor * act) { // type must be npc and not creature if (act->typeID != kFormType_ACHR) { return; } if (act == (*g_thePlayer)) { // Enables body if the horse dies while riding in 1st person if (g_horseToggle && (*g_thePlayer)->horseOrRider == 0) { NiNode * n = (*g_thePlayer)->niNode; n->m_flags = n->m_flags & 0xfffe; if (g_bUseThirdPersonArms) { n = (*g_thePlayer)->firstPersonNiNode; n->m_flags = n->m_flags | 0x0001; } else { n = (*g_thePlayer)->firstPersonNiNode; n->m_flags = n->m_flags & 0xfffe; } g_horseToggle = 0; } // Moves the camera when sleeping/vampire feeding to avoid clipping HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int sitSleepFlag = proc->unk11D; int isVanityMode = *(UInt8*)0x00B3BB04; if (sitSleepFlag >= 8 && isVanityMode == 0) { if (IsFirstPerson() || g_forceThirdPerson) { NiNode * nRoot = (*g_thePlayer)->niNode; if (IsVampireFeeding(*g_thePlayer)) { NiVector3 v0, v1; v0.x = 0.0; v0.y = -16.0; v0.z = 0.0; MatrixVectorMultiply(&v1, &(nRoot->m_worldRotate), &v0); nRoot->m_localTranslate.x += v1.x; nRoot->m_localTranslate.y += v1.y; nRoot->m_localTranslate.z += v1.z + 10; } else { nRoot->m_localTranslate.z += 10; } } } if (IsFirstPerson() && g_forceThirdPerson == 0 && ((*g_thePlayer)->horseOrRider == 0 || g_bHorseFirstPersonBody)) { // Disabled in dialog to avoid zoom glitch if (!InDialogMenu()) { // Disable 3rd person arms so we don't end up with duplicates if ((*g_thePlayer)->isThirdPerson) { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int sitSleepFlag = proc->unk11D; // Move body to prevent seeing into objects if (sitSleepFlag == 0) { NiNode * nRoot = (*g_thePlayer)->niNode; NiVector3 v0, v1; v0.x = 0.0; v0.y = -25.0; v0.z = 0.0; MatrixVectorMultiply(&v1, &(nRoot->m_worldRotate), &v0); nRoot->m_localTranslate.x += v1.x; nRoot->m_localTranslate.y += v1.y; nRoot->m_localTranslate.z += v1.z; } // Rotate Arms if (g_bRotateThirdPersonArms & 1) { RotateArms(); } // Translate 1st person skeleton to correct position } else { TranslateFirstPerson(); } } } else { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int knockedFlag = proc->unk11C; // Translate camera up to avoid clipping // with the ground when getting up after knockout if (knockedFlag == 6 && g_forceThirdPerson) { NiNode * nRoot = (*g_thePlayer)->niNode; nRoot->m_localTranslate.z += 10; } // Rotate Arms if (g_bRotateThirdPersonArms & 2) { RotateArms(); } } }}// Modifies camera positionvoid UpdateCamera(NiNode * nCamera) { g_isThirdPerson = (*g_thePlayer)->isThirdPerson; HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); int isVanityMode = *(UInt8*)0x00B3BB04; int knockedFlag = proc->unk11C; static int sitSleepFlag = 0; if (g_forceThirdPerson == 2) { if (IsIdlePlaying()) { g_forceThirdPerson = 1; g_checkIdle = 0; } else { g_checkIdle--; if (g_checkIdle == 0) { g_forceThirdPerson = 0; } } } // Do not show body if dead or knocked out // (Camera placed inside head to avoid ground clipping) NiNode * nRoot = (*g_thePlayer)->niNode; if (isVanityMode == 0 && g_forceThirdPerson && ((*g_thePlayer)->IsDead() || (knockedFlag != 0 && knockedFlag != 6))) { if ((nRoot->m_flags & 0x0001) == 0) { nRoot->m_flags = nRoot->m_flags | 0x0001; } } else { if ((nRoot->m_flags & 0x0001) == 1) { nRoot->m_flags = nRoot->m_flags & 0xfffe; } } // Set sittingFlag to detect if player is transitioning // into sit state (3), out of sit state (5), or is in a bed state (>=8) // unk11D is SitSleepState if (proc->unk11D == 3 || proc->unk11D == 5 || proc->unk11D >= 8) { sitSleepFlag = 5; // Must wait a few frames after the GetSitting state changes // or the camera does not update properly } else if (sitSleepFlag > 0) { sitSleepFlag -= 1; } // Disabled when in 3rd person if ((*g_thePlayer)->isThirdPerson && g_forceThirdPerson == 0) { return; // Disabled when riding a horse } else if ((*g_thePlayer)->horseOrRider && g_bHorseFirstPersonBody == 0 && proc->unk11D == 4 && sitSleepFlag == 0) { return; // Disabled in dialog to avoid zoom glitch } else if (InDialogMenu() || isVanityMode) { return; } NiNode * nHead = FindNode((*g_thePlayer)->niNode, "Bip01 Head"); NiVector3 * tHead = &(nHead->m_worldTranslate); NiVector3 * tCamera = &(nCamera->m_localTranslate); NiVector3 v0, v1; // Positions camera in front of the head if ((*g_thePlayer)->IsDead() != 0 || knockedFlag != 0 || sitSleepFlag != 0) { if (sitSleepFlag || knockedFlag == 6) { v0.x = 6.0; v0.y = 6.0; v0.z = 0.0; } else { // Dead, knocked out v0.x = 6.0; v0.y = -6.0; v0.z = 0.0; } MatrixVectorMultiply(&v1, &(nHead->m_worldRotate), &v0); tCamera->x = tHead->x + v1.x; tCamera->y = tHead->y + v1.y; tCamera->z = tHead->z + v1.z; // Translate camera up to avoid clipping // with the ground when dead or knocked out if (sitSleepFlag == 0 && knockedFlag != 6) { tCamera->z += 6; } // Rotate camera to face forward NiMatrix33 mCameraRot; mCameraRot.data[0] = 0; mCameraRot.data[1] = 0; mCameraRot.data[2] = 1; mCameraRot.data[3] = 0; mCameraRot.data[4] = 1; mCameraRot.data[5] = 0; mCameraRot.data[6] = -1; mCameraRot.data[7] = 0; mCameraRot.data[8] = 0; MatrixMultiply(&(nCamera->m_localRotate), &(nHead->m_worldRotate), &mCameraRot); } else if (IsIdlePlaying()) { v0.x = 6.0; v0.y = 14.0; v0.z = 0.0; MatrixVectorMultiply(&v1, &(nHead->m_worldRotate), &v0); tCamera->x = tHead->x + v1.x; tCamera->y = tHead->y + v1.y; tCamera->z = tHead->z + v1.z; NiMatrix33 m; NiVector3 v; v.x = -90.0*PI/180; v.y = 90.0*PI/180 - (*g_thePlayer)->rotX; v.z = 90.0*PI/180; //EulerToMatrix(&mCameraRot, &v); m.data[0] = cos(v.y)*cos(v.z); m.data[1] = -cos(v.y)*sin(v.z); m.data[2] = sin(v.y); m.data[3] = cos(v.z)*sin(v.x)*sin(v.y) + cos(v.x)*sin(v.z); m.data[4] = cos(v.x)*cos(v.z) - sin(v.x)*sin(v.y)*sin(v.z); m.data[5] = -cos(v.y)*sin(v.x); m.data[6] = -cos(v.x)*cos(v.z)*sin(v.y) + sin(v.x)*sin(v.z); m.data[7] = cos(v.z)*sin(v.x) + cos(v.x)*sin(v.y)*sin(v.z); m.data[8] = cos(v.x)*cos(v.y); MatrixMultiply(&(nCamera->m_localRotate), &(nHead->m_worldRotate), &m); } else { NiNode * node = (*g_thePlayer)->niNode; v0.x = 0.0; v0.y = 14.0; v0.z = 6.0; MatrixVectorMultiply(&v1, &(node->m_worldRotate), &v0); tCamera->x = tHead->x + v1.x; tCamera->y = tHead->y + v1.y; tCamera->z = tHead->z + v1.z; }}void *cameraReturn = (void *)0x0066BE7C;// Hooks Oblivion's code for updating the camerastatic _declspec(naked) void HookCamera(void){ _asm { push ebx push eax call UpdateCamera add esp, 4 pop ebx jmp cameraReturn }}// Address of function called by overwritten codevoid *applyAnimData = (void *)0x00471F20;void *animationReturn = (void *)0x006043E1;// Hooks Oblivion's animation code in order to edit the animationsstatic _declspec(naked) void HookAnimation(void){ _asm { // Calls my update function on the actor (stored in ebp) pushad push ebp call UpdateActor add esp, 4 popad // overwritten code call applyAnimData jmp animationReturn }}// Checks if head tracking should be disabled on the playerbool CheckDisableHeadtracking(Actor * act) { if (act->typeID == kFormType_ACHR) { if (act == (*g_thePlayer)) { if (IsFirstPerson() || g_forceThirdPerson) { return true; } } } return false;}void *headTrackingReturn01 = (void *)0x00603AB0;void *headTrackingReturn02 = (void *)0x00603BB7;// Hooks Oblivion's head tracking codestatic _declspec(naked) void HookHeadTracking(void){ _asm { // overwritten code jz disable_head_ik // Check if head ik should be disabled on the player push esi call CheckDisableHeadtracking add esp, 4 test al, al jnz disable_head_ik jmp headTrackingReturn01 disable_head_ik: jmp headTrackingReturn02 }}// Fix magic shader not appearing in 1st person// Shader is applied to both 1st and 3rd personbool UpdateMagicShader(MagicShaderHitEffect * shader) { bool retVal; if (shader->target == (*g_thePlayer)) { // Restore nodes to avoid bug with paralysis if ((*g_thePlayer)->GetActorValue(kActorVal_Paralysis) != 0) { UpdateSkeletonNodes(1); HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); ActorAnimData* anim = proc->animData; ThisStdCall(0x00471F20, anim); // applies animData to skeleton } NiNode * n; n = (*g_thePlayer)->niNode; UInt16 flags = n->m_flags; if (g_isThirdPerson || g_bUseThirdPersonArms) { n->m_flags = n->m_flags | 0x0001; ApplyMagicEffectShader(shader); n->m_flags = n->m_flags & 0xfffe; retVal = ApplyMagicEffectShader(shader); } else { n->m_flags = n->m_flags & 0xfffe; ApplyMagicEffectShader(shader); n->m_flags = n->m_flags | 0x0001; retVal = ApplyMagicEffectShader(shader); } n->m_flags = flags; } else { retVal = ApplyMagicEffectShader(shader); } return retVal;}void *fixMagicShader01Return = (void *)0x00657603;// Fix body magic shader 1static _declspec(naked) void HookFixMagicShader01(void){ _asm { push eax call UpdateMagicShader add esp, 4 jmp fixMagicShader01Return }}void *fixMagicShader02Return = (void *)0x0069DB00;// Fix body magic shader 2static _declspec(naked) void HookFixMagicShader02(void){ _asm { // overwritten code mov [esp+0x18], -1 push esi call UpdateMagicShader add esp, 4 jmp fixMagicShader02Return }}void *fixMagicShader03Return = (void *)0x00657764;// Fix weapon magic shader 1static _declspec(naked) void HookFixMagicShader03(void){ _asm { push edi call UpdateMagicShader add esp, 4 jmp fixMagicShader03Return }}void *fixMagicShader04Return = (void *)0x0065777C;// Fix weapon magic shader 2static _declspec(naked) void HookFixMagicShader04(void){ _asm { push eax call UpdateMagicShader add esp, 4 jmp fixMagicShader04Return }}void *fixMagicShader05Return = (void *)0x005060E3;// Fix PMS magic shaderstatic _declspec(naked) void HookFixMagicShader05(void){ _asm { // overwritten code mov [esp+0x20], -1 push esi call UpdateMagicShader add esp, 4 jmp fixMagicShader05Return }}// Returns if the camera should be forced if player is sitting or knocked outvoid CheckForceCamera() { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); //Console_Print("CheckForceCamera, SitSleepFlag: %x, KnockedFlag: %x", proc->unk11D, proc->unk11C); g_forceThirdPerson = ((proc->unk11C == 0) && g_bFirstPersonSitting) || ((proc->unk11C != 0) && g_bFirstPersonKnockout);}void *forcePOVCall = (void *)0x0066C580;void *forcePOV01Return = (void *)0x0066C642;static _declspec(naked) void HookForcePOV01(void){ _asm { // overwritten code, call Oblivion's switch POV call forcePOVCall pushad call CheckForceCamera popad jmp forcePOV01Return }}void *forcePOV02Return = (void *)0x0066CEF3;static _declspec(naked) void HookForcePOV02(void){ _asm { // overwritten code, call Oblivion's switch POV call forcePOVCall mov g_forceThirdPerson, 1 jmp forcePOV02Return }}void *forcePOV03Return = (void *)0x0066CF62;static _declspec(naked) void HookForcePOV03(void){ _asm { // overwritten code, call Oblivion's switch POV call forcePOVCall mov g_forceThirdPerson, 1 jmp forcePOV03Return }}void *forcePOV04Return = (void *)0x0066CCC2;static _declspec(naked) void HookForcePOV04(void){ _asm { // overwritten code, call Oblivion's switch POV call forcePOVCall mov g_forceThirdPerson, 1 jmp forcePOV04Return }}void *forcePOV05Return = (void *)0x00600BD1;static _declspec(naked) void HookForcePOV05(void){ _asm { // overwritten code, call Oblivion's switch POV call forcePOVCall mov g_forceThirdPerson, 1 jmp forcePOV05Return }}// Updates 3rd person nodesvoid update3rdPersonNodes(bool toggleNodes) { NiNode * node; int isVanityMode = *(UInt8*)0x00B3BB04; if ((*g_thePlayer)->isThirdPerson == 0 && isVanityMode == 0) { // Fix Trifle shadows while riding a horse if ((*g_thePlayer)->horseOrRider && g_bHorseFirstPersonBody == 0) { if (toggleNodes) { node = (*g_thePlayer)->niNode; node->m_flags = node->m_flags & 0xfffe; } else { node = (*g_thePlayer)->niNode; node->m_flags = node->m_flags | 0x0001; } } else { if (toggleNodes) { // Restore skeleton when in menu mode to prevent shadow missing head/arms InterfaceManager *im = InterfaceManager::GetSingleton(); if (!im->IsGameMode()) { HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); ActorAnimData* anim = proc->animData; ThisStdCall(0x00471F20, anim); // applies animData to skeleton } } else { // Disables visibility of arms/head nodes UpdateSkeletonNodes(0); HighProcess * proc = static_cast<HighProcess *>((*g_thePlayer)->process); ActorAnimData* anim = proc->animData; ThisStdCall(0x00471F20, anim); // applies animData to skeleton // Resets scale to prevent bug with arms/head disappearing // when equipping items in the inventory menu UpdateSkeletonNodes(1); // Fix bug where game uses 3rd person magicNode causing spells to be // casted from wrong position. Move it to same position as first person node. NiNode * nMagicNodeFirst = FindNode((*g_thePlayer)->firstPersonNiNode, "magicNode"); NiNode * nMagicNodeThird = FindNode((*g_thePlayer)->niNode, "magicNode"); nMagicNodeThird->m_worldTranslate.x = nMagicNodeFirst->m_worldTranslate.x; nMagicNodeThird->m_worldTranslate.y = nMagicNodeFirst->m_worldTranslate.y; nMagicNodeThird->m_worldTranslate.z = nMagicNodeFirst->m_worldTranslate.z; } } }}void *shadowFunction = (void *)0x004073D0;void *fixTrifleShadowsReturn = (void *)0x0040C920;// Fix bug with Trifle's 1st person shadows missing arms/headstatic _declspec(naked) void FixTrifleShadows(void){ _asm { pushad push 1 call update3rdPersonNodes add esp, 4 popad // overwritten code, call Oblivion's shadow function call shadowFunction pushad push 0 call update3rdPersonNodes add esp, 4 popad jmp fixTrifleShadowsReturn }}extern "C" {bool OBSEPlugin_Query(const OBSEInterface * obse, PluginInfo * info){ _MESSAGE("query"); // fill out the info structure info->infoVersion = PluginInfo::kInfoVersion; info->name = "EnhancedCamera"; info->version = 1; // version checks if(!obse->isEditor) { if(obse->obseVersion < OBSE_VERSION_INTEGER) { _ERROR("OBSE version too old (got %08X expected at least %08X)", obse->obseVersion, OBSE_VERSION_INTEGER); return false; } if(obse->oblivionVersion != OBLIVION_VERSION) { _ERROR("incorrect Oblivion version (got %08X need %08X)", obse->oblivionVersion, OBLIVION_VERSION); return false; } } else { //return false; // not using the editor } // version checks pass return true;}OBSEMessagingInterface* g_messageInterface;void MessageHandler(OBSEMessagingInterface::Message* msg){ switch (msg->type) { case OBSEMessagingInterface::kMessage_PostLoad: //_MESSAGE("Received PostLoad mesage"); // Trifle compatibility fix WriteRelJump(0x0040C91B,(UInt32)&FixTrifleShadows); break; }}bool OBSEPlugin_Load(const OBSEInterface * obse){ _MESSAGE("load"); g_pluginHandle = obse->GetPluginHandle(); // Load ini settings char filename[MAX_PATH]; char *pch; GetModuleFileNameA(NULL, filename, MAX_PATH); pch = strrchr(filename, '\\') + 1; strcpy(pch, inipath); //_MESSAGE("filepath:"); //_MESSAGE(filename); g_bFirstPersonSitting = GetPrivateProfileIntA("Main", "bFirstPersonSitting", 1, filename); g_bFirstPersonKnockout = GetPrivateProfileIntA("Main", "bFirstPersonKnockout", 1, filename); g_bFirstPersonDeath = GetPrivateProfileIntA("Main", "bFirstPersonDeath", 1, filename); g_bFirstPersonModAnim = GetPrivateProfileIntA("Main", "bFirstPersonModAnim", 1, filename); g_bEnableHeadFirstPerson = GetPrivateProfileIntA("Main", "bEnableHeadFirstPerson", 0, filename); g_bHorseFirstPersonBody = GetPrivateProfileIntA("Main", "bHorseFirstPersonBody", 0, filename); g_bUseThirdPersonArms = GetPrivateProfileIntA("Main", "bUseThirdPersonArms", 0, filename); g_bRotateThirdPersonArms = GetPrivateProfileIntA("Main", "bRotateThirdPersonArms", 0, filename); if(!obse->isEditor) { // get an OBSEScriptInterface to use for argument extraction g_scriptInterface = (OBSEScriptInterface*)obse->QueryInterface(kInterface_Script); // register to receive messages from OBSE g_messageInterface = (OBSEMessagingInterface*)obse->QueryInterface(kInterface_Messaging); g_messageInterface->RegisterListener(g_pluginHandle, "OBSE", MessageHandler); // Hook the Camera WriteRelJump(0x0066BE6E,(UInt32)&HookCamera); // Hook to somewhere in Oblivion's animation code // This allows you to modify the 1st/3rd person skeleton nodes WriteRelJump(0x006043DC,(UInt32)&HookAnimation); // Hook to Oblivion's head tracking code. It is disabled in 1st person // to prevent strange camera movements when near npcs/dead bodies. WriteRelJump(0x00603AAA,(UInt32)&HookHeadTracking); // Forces game to load 3rd person body when loading save game in 1st person SafeWrite16(0x00664FC6,0x9090); SafeWrite32(0x00664FC8,0x90909090); // Hook to switch POV code in Oblivion WriteRelCall(0x00665008,(UInt32)&HookSwitchPOV); WriteRelJump(0x0066500D,0x00665034); // The switch POV code broke the view switching, this should fix it... SafeWrite16(0x00664FFB,0x9090); SafeWrite32(0x00664FFD,0x90909090); // Fix the bug where magic shaders are only applied in 3rd person WriteRelJump(0x006575FA,(UInt32)&HookFixMagicShader01); // body 1 WriteRelJump(0x0069DAEF,(UInt32)&HookFixMagicShader02); // body 2 WriteRelJump(0x0065775B,(UInt32)&HookFixMagicShader03); // weapon 1 WriteRelJump(0x006576DF,(UInt32)&HookFixMagicShader04); // weapon 2 WriteRelJump(0x005060D2,(UInt32)&HookFixMagicShader05); // PMS // Hooks to where the game force switches to 3rd person, // enables a fake first person. WriteRelJump(0x0066C63D,(UInt32)&HookForcePOV01); // chair, fatigue knockout, paralysis if (g_bFirstPersonSitting) { WriteRelJump(0x0066CEEE,(UInt32)&HookForcePOV02); // mount horse WriteRelJump(0x0066CF5D,(UInt32)&HookForcePOV03); // dismount horse WriteRelJump(0x0066CCBD,(UInt32)&HookForcePOV04); // vampire feed } if (g_bFirstPersonDeath) { WriteRelJump(0x00600BCC,(UInt32)&HookForcePOV05); // death } } return true;}};
Shinobi7 Posted November 22, 2013 Posted November 22, 2013 Would this work with BBB and NoMaam Breathing Idle?
Mailamea Posted November 22, 2013 Posted November 22, 2013 Would this work with BBB and NoMaam Breathing Idle? yes it does
Shinobi7 Posted November 22, 2013 Posted November 22, 2013 Would this work with BBB and NoMaam Breathing Idle? yes it does Thanks, also NoMaam Battle BBB and third person view still available?
Mailamea Posted November 22, 2013 Posted November 22, 2013 Would this work with BBB and NoMaam Breathing Idle? yes it does Thanks, and would you know if it alters third person view? it doesnt, all this mod does is use your eye bone in first person to give you a realistic first person view.
Mailamea Posted November 22, 2013 Posted November 22, 2013 ah ok thanks then! keep in mind there is an ini included, if you get four arms bug, and cant see your hands, read the previous posts to fix it.
DeadSomething Posted November 25, 2013 Posted November 25, 2013 i must say this is an amazing tweak mod and i love it. at first i had some strange issues, but that was due to an experimental skeleton from a previous first-person-mod - also it was solvedby reinstalling the max-compatibility skeleton(s). it works with BBB and doesnt lower the FPS. i havent tried to change LoversPK animations into first person yet, but i hope someone will make a patch soon.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.