BSFixedString InputManager::GetMappedControl(UInt32 buttonID, UInt32 deviceType, UInt32 contextIdx) { ASSERT(contextIdx < kContextCount); // 0xFF == unbound if (buttonID == 0xFF) return BSFixedString(); tArray<InputContext::Mapping> * mappings; if (deviceType == kDeviceType_Mouse) mappings = &context[contextIdx]->mouseMap; else if (deviceType == kDeviceType_Gamepad) mappings = &context[contextIdx]->gamepadMap; else mappings = &context[contextIdx]->keyboardMap; for (UInt32 i=0; i < mappings->count; i++) { InputContext::Mapping m; if (!mappings->GetNthItem(i, m)) break; if (m.buttonID == buttonID) return m.name; } return BSFixedString(); }
EventResult MenuEventHandler::ReceiveEvent(MenuOpenCloseEvent * evn, EventDispatcher<MenuOpenCloseEvent> * dispatcher) { BSFixedString eventName = evn->opening ? BSFixedString("OnMenuOpen") : BSFixedString("OnMenuClose"); g_menuOpenCloseRegs.ForEach( evn->menuName, EventQueueFunctor1<BSFixedString>(eventName, evn->menuName) ); return kEvent_Continue; }
TESQuest* GetQuest(StaticFunctionTag*, BSFixedString editorID) { s_questCacheLock.Enter(); if(g_invalidateQuestCache == 1) { g_invalidateQuestCache = 0; s_questCache.clear(); } if (s_questCache.empty()) { DataHandler* pDataHandler = DataHandler::GetSingleton(); tArray<TESQuest*>& quests = pDataHandler->quests; for (UInt32 n = 0; n < quests.count; n++) { TESQuest* pQuest = NULL; quests.GetNthItem(n, pQuest); if (pQuest) { s_questCache.insert(QuestCache::value_type(BSFixedString(pQuest->questID.Get()), pQuest)); } } } s_questCacheLock.Leave(); QuestCache::iterator it = s_questCache.find(editorID); TESQuest* pQuest = (it != s_questCache.end()) ? it->second : NULL; return pQuest; }
EventResult NiNodeUpdateEventHandler::ReceiveEvent(SKSENiNodeUpdateEvent * evn, EventDispatcher<SKSENiNodeUpdateEvent> * dispatcher) { g_ninodeUpdateEventRegs.ForEach( EventQueueFunctor1<TESObjectREFR*>(BSFixedString("OnNiNodeUpdate"), evn->reference) ); return kEvent_Continue; }
EventResult CrosshairRefEventHandler::ReceiveEvent(SKSECrosshairRefEvent * evn, EventDispatcher<SKSECrosshairRefEvent> * dispatcher) { g_crosshairRefEventRegs.ForEach( EventQueueFunctor1<TESObjectREFR*>(BSFixedString("OnCrosshairRefChange"), evn->crosshairRef) ); return kEvent_Continue; }
EventResult ActionEventHandler::ReceiveEvent(SKSEActionEvent * evn, EventDispatcher<SKSEActionEvent> * dispatcher) { g_actionEventRegs.ForEach( evn->type, EventQueueFunctor4<SInt32, Actor*, TESForm*, UInt32>(BSFixedString("OnActorAction"), evn->type, evn->actor, evn->sourceForm, evn->slot) ); return kEvent_Continue; }
NiTriBasedGeom * GetTriBasedGeomByHeadPart(BSFaceGenNiNode * faceNode, BGSHeadPart * headPart) { for (UInt32 p = 0; p < faceNode->m_children.m_size; p++) { NiAVObject * object = faceNode->m_children.m_data[p]; if (object && BSFixedString(object->m_name) == headPart->partName) { NiTriBasedGeom * geometry = object->GetAsNiTriBasedGeom(); if (geometry) { return geometry; } } } return NULL; }
EventResult CameraEventHandler::ReceiveEvent(SKSECameraEvent * evn, EventDispatcher<SKSECameraEvent> * dispatcher) { SInt32 oldState = -1; SInt32 newState = -1; PlayerCamera * playerCamera = PlayerCamera::GetSingleton(); if(playerCamera) { for(int i = 0; i < PlayerCamera::kNumCameraStates; i++) { if(evn->oldState == playerCamera->cameraStates[i]) oldState = i; if(evn->newState == playerCamera->cameraStates[i]) newState = i; } } g_cameraEventRegs.ForEach( EventQueueFunctor2<SInt32, SInt32>(BSFixedString("OnPlayerCameraState"), oldState, newState) ); return kEvent_Continue; }
NiTransform GetGeometryTransform(NiGeometry * geometry) { NiTransform transform = geometry->m_localTransform; NiSkinInstance * dstSkin = niptr_cast<NiSkinInstance>(geometry->m_spSkinInstance); if (dstSkin) { NiSkinData * skinData = dstSkin->m_spSkinData; if (skinData) { transform = transform * skinData->m_kRootParentToSkin; for (UInt32 i = 0; i < skinData->m_uiBones; i++) { NiAVObject * bone = dstSkin->m_ppkBones[i]; if (bone->m_name == BSFixedString("NPC Head [Head]").data) { transform = transform * skinData->m_pkBoneData[i].m_kSkinToBone; break; } } } } return transform; }
BGSHeadPart* GetHeadPart(StaticFunctionTag*, BSFixedString editorID) { s_headPartCacheLock.Enter(); if (s_headPartCache.empty()) { DataHandler* pDataHandler = DataHandler::GetSingleton(); tArray<BGSHeadPart*>& headParts = pDataHandler->headParts; for (UInt32 n = 0; n < headParts.count; n++) { BGSHeadPart* pHeadPart = NULL; headParts.GetNthItem(n, pHeadPart); if (pHeadPart) { s_headPartCache.insert(HeadPartCache::value_type(BSFixedString(pHeadPart->partName), pHeadPart)); } } } s_headPartCacheLock.Leave(); HeadPartCache::iterator it = s_headPartCache.find(editorID); BGSHeadPart* pHeadPart = (it != s_headPartCache.end()) ? it->second : NULL; return pHeadPart; }
EventResult InputEventHandler::ReceiveEvent(InputEvent ** evns, InputEventDispatcher * dispatcher) { // Function is called periodically, if no buttons pressed/held *evns == NULL if (! *evns) return kEvent_Continue; for (InputEvent * e = *evns; e; e = e->next) { switch(e->eventType) { case InputEvent::kEventType_Button: { ButtonEvent * t = DYNAMIC_CAST(e, InputEvent, ButtonEvent); UInt32 keyCode; UInt32 deviceType = t->deviceType; UInt32 keyMask = t->keyMask; // Mouse if (deviceType == kDeviceType_Mouse) keyCode = InputMap::kMacro_MouseButtonOffset + keyMask; // Gamepad else if (deviceType == kDeviceType_Gamepad) keyCode = InputMap::GamepadMaskToKeycode(keyMask); // Keyboard else keyCode = keyMask; // Valid scancode? if (keyCode >= InputMap::kMaxMacros) continue; BSFixedString control = *t->GetControlID(); float timer = t->timer; bool isDown = t->flags != 0 && timer == 0.0; bool isUp = t->flags == 0 && timer != 0; if (isDown) { // Used by scaleform skse.GetLastControl SetLastControlDown(control.data, keyCode); g_inputKeyEventRegs.ForEach( keyCode, EventQueueFunctor1<SInt32>(BSFixedString("OnKeyDown"), (SInt32)keyCode) ); g_inputControlEventRegs.ForEach( control, EventQueueFunctor1<BSFixedString>(BSFixedString("OnControlDown"), control) ); } else if (isUp) { SetLastControlUp(control.data, keyCode); g_inputKeyEventRegs.ForEach( keyCode, EventQueueFunctor2<SInt32, float>(BSFixedString("OnKeyUp"), (SInt32)keyCode, timer) ); g_inputControlEventRegs.ForEach( control, EventQueueFunctor2<BSFixedString, float>(BSFixedString("OnControlUp"), control, timer) ); } } break; /*case InputEvent::kEventType_Thumbstick: { ThumbstickEvent * t = DYNAMIC_CAST(e, InputEvent, ThumbstickEvent); _MESSAGE("Moved %s Stick X: %f Y: %f", t->keyMask == 0x0B ? "Left" : "Right", t->x, t->y); } break;*/ } } return kEvent_Continue; }
void SKSETaskExportHead::Run() { if (!m_formId) return; TESForm * form = LookupFormByID(m_formId); Actor * actor = DYNAMIC_CAST(form, TESForm, Actor); if (!actor) return; BSFaceGenNiNode * faceNode = actor->GetFaceGenNiNode(); TESNPC * actorBase = DYNAMIC_CAST(actor->baseForm, TESForm, TESNPC); if (!actorBase || !faceNode) return; BSFaceGenAnimationData * animationData = actor->GetFaceGenAnimationData(); if (animationData) { FaceGen::GetSingleton()->isReset = 0; for (UInt32 t = BSFaceGenAnimationData::kKeyframeType_Expression; t <= BSFaceGenAnimationData::kKeyframeType_Phoneme; t++) { BSFaceGenKeyframeMultiple * keyframe = &animationData->keyFrames[t]; for (UInt32 i = 0; i < keyframe->count; i++) keyframe->values[i] = 0.0; keyframe->isUpdated = 0; } UpdateModelFace(faceNode); } IFileStream::MakeAllDirs(m_nifPath.data); BSFadeNode * rootNode = BSFadeNode::Create(); rootNode->IncRef(); NiNode * skinnedNode = NiNode::Create(0); skinnedNode->m_name = BSFixedString("BSFaceGenNiNodeSkinned").data; std::map<NiAVObject*, NiAVObject*> boneMap; for (UInt32 i = 0; i < faceNode->m_children.m_size; i++) { NiAVObject * object = faceNode->m_children.m_data[i]; if (!object) continue; if (NiGeometry * geometry = object->GetAsNiGeometry()) { NiGeometryData * geometryData = niptr_cast<NiGeometryData>(geometry->m_spModelData); NiGeometryData * newGeometryData = NULL; if (geometryData) CALL_MEMBER_FN(geometryData, DeepCopy)((NiObject **)&newGeometryData); NiProperty * trishapeEffect = niptr_cast<NiProperty>(geometry->m_spEffectState); NiProperty * newTrishapeEffect = NULL; if (trishapeEffect) CALL_MEMBER_FN(trishapeEffect, DeepCopy)((NiObject **)&newTrishapeEffect); NiProperty * trishapeProperty = niptr_cast<NiProperty>(geometry->m_spPropertyState); NiProperty * newTrishapeProperty = NULL; if (trishapeProperty) CALL_MEMBER_FN(trishapeProperty, DeepCopy)((NiObject **)&newTrishapeProperty); NiSkinInstance * skinInstance = niptr_cast<NiSkinInstance>(geometry->m_spSkinInstance); NiSkinInstance * newSkinInstance = NULL; if (skinInstance) { newSkinInstance = skinInstance->Clone(false); newSkinInstance->m_pkRootParent = skinnedNode; UInt32 numBones = 0; NiSkinData * skinData = niptr_cast<NiSkinData>(skinInstance->m_spSkinData); NiSkinData * newSkinData = NULL; if (skinData) { numBones = skinData->m_uiBones; CALL_MEMBER_FN(skinData, DeepCopy)((NiObject **)&newSkinData); } NiSkinPartition * skinPartition = niptr_cast<NiSkinPartition>(skinInstance->m_spSkinPartition); NiSkinPartition * newSkinPartition = NULL; if (skinPartition) CALL_MEMBER_FN(skinPartition, DeepCopy)((NiObject **)&newSkinPartition); newSkinInstance->m_spSkinData = newSkinData; newSkinData->DecRef(); newSkinInstance->m_spSkinPartition = newSkinPartition; newSkinPartition->DecRef(); // Remap the bones to new NiNode instances if (numBones > 0) { newSkinInstance->m_ppkBones = (NiAVObject**)NiAllocate(numBones * sizeof(NiAVObject*)); for (UInt32 i = 0; i < numBones; i++) { NiAVObject * bone = skinInstance->m_ppkBones[i]; if (bone) { auto it = boneMap.find(bone); if (it == boneMap.end()) { NiNode * newBone = NiNode::Create(); newBone->m_name = bone->m_name; newBone->m_flags = bone->m_flags; boneMap.insert(std::make_pair(bone, newBone)); newSkinInstance->m_ppkBones[i] = newBone; } else newSkinInstance->m_ppkBones[i] = it->second; } else { newSkinInstance->m_ppkBones[i] = nullptr; } } } } NiGeometry * newGeometry = NULL; if (NiTriShape * trishape = geometry->GetAsNiTriShape()) { NiTriShape * newTrishape = NiTriShape::Create(static_cast<NiTriShapeData*>(newGeometryData)); newGeometryData->DecRef(); newTrishape->m_localTransform = geometry->m_localTransform; newTrishape->m_name = geometry->m_name; memcpy(&newTrishape->unk88, &geometry->unk88, 0x1F); newTrishape->m_spEffectState = newTrishapeEffect; newTrishape->m_spPropertyState = newTrishapeProperty; newTrishape->m_spSkinInstance = newSkinInstance; newGeometry = newTrishape; } else if (NiTriStrips * tristrips = geometry->GetAsNiTriStrips()) { NiTriStrips * newTristrips = NiTriStrips::Create(static_cast<NiTriStripsData*>(newGeometryData)); newGeometryData->DecRef(); newTristrips->m_localTransform = geometry->m_localTransform; newTristrips->m_name = geometry->m_name; memcpy(&newTristrips->unk88, &geometry->unk88, 0x1F); newTristrips->m_spEffectState = newTrishapeEffect; newTristrips->m_spPropertyState = newTrishapeProperty; newTristrips->m_spSkinInstance = newSkinInstance; newGeometry = newTristrips; } if (newGeometry) { auto textureData = GetTextureSetForPartByName(actorBase, newGeometry->m_name); if (textureData.first && textureData.second) { BSShaderProperty * shaderProperty = niptr_cast<BSShaderProperty>(newGeometry->m_spEffectState); if (shaderProperty) { if (shaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) { BSLightingShaderProperty * lightingShader = static_cast<BSLightingShaderProperty *>(shaderProperty); BSLightingShaderMaterial * material = static_cast<BSLightingShaderMaterial *>(shaderProperty->material); if (material && material->textureSet) { for (UInt32 i = 0; i < BGSTextureSet::kNumTextures; i++) material->textureSet->SetTexturePath(i, textureData.first->textureSet.GetTexturePath(i)); if (textureData.second->type == BGSHeadPart::kTypeFace) material->textureSet->SetTexturePath(6, m_ddsPath.data); } } } // Save the previous tint mask BSShaderProperty * originalShaderProperty = niptr_cast<BSShaderProperty>(geometry->m_spEffectState); if (originalShaderProperty) { if (originalShaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) { BSLightingShaderProperty * lightingShader = static_cast<BSLightingShaderProperty *>(originalShaderProperty); BSLightingShaderMaterial * material = static_cast<BSLightingShaderMaterial *>(originalShaderProperty->material); if (material) { if (material->GetShaderType() == BSShaderMaterial::kShaderType_FaceGen) { BSMaskedShaderMaterial * maskedMaterial = static_cast<BSMaskedShaderMaterial *>(material); SaveRenderedDDS(niptr_cast<NiRenderedTexture>(maskedMaterial->renderedTexture), m_ddsPath.data); } } } } } skinnedNode->AttachChild(newGeometry, true); } } } for (auto & bones : boneMap) rootNode->AttachChild(bones.second, true); rootNode->AttachChild(skinnedNode, true); UInt8 niStreamMemory[0x5B4]; memset(niStreamMemory, 0, 0x5B4); NiStream * niStream = (NiStream *)niStreamMemory; CALL_MEMBER_FN(niStream, ctor)(); CALL_MEMBER_FN(niStream, AddObject)(rootNode); niStream->SavePath(m_nifPath.data); CALL_MEMBER_FN(niStream, dtor)(); rootNode->DecRef(); if (animationData) { animationData->overrideFlag = 0; CALL_MEMBER_FN(animationData, Reset)(1.0, 1, 1, 0, 0); FaceGen::GetSingleton()->isReset = 1; UpdateModelFace(faceNode); } }