#include "PapyrusForm.h" #include "GameForms.h" #include "GameObjects.h" #include "GameRTTI.h" #include "PapyrusVM.h" #include "PapyrusEvents.h" #include "PapyrusArgs.h" //#include "GameMenus.h" #include #include namespace papyrusForm { UInt32 GetType(TESForm* thisForm) { return (thisForm) ? thisForm->GetFormType() : 0; } BSFixedString GetName(TESForm* thisForm) { if (!thisForm) return NULL; TESFullName* pFullName = DYNAMIC_CAST(thisForm, TESForm, TESFullName); if (pFullName) return pFullName->name.data; return NULL; } void SetName(TESForm* thisForm, BSFixedString nuName) { TESFullName* pFullName = DYNAMIC_CAST(thisForm, TESForm, TESFullName); // is a const string, so have to just reassign it. if (pFullName) { pFullName->name = nuName; } } float GetWeight(TESForm* thisForm) { if (!thisForm) return 0.0; TESWeightForm* pWeight = DYNAMIC_CAST(thisForm, TESForm, TESWeightForm); if (pWeight) return pWeight->weight; return 0.0; } void SetWeight(TESForm* thisForm, float nuWeight) { if (!thisForm) return; TESWeightForm* pWeight = DYNAMIC_CAST(thisForm, TESForm, TESWeightForm); if (pWeight) pWeight->weight = nuWeight; } UInt32 GetBaseDamage(TESForm* thisForm) { if (!thisForm) return 0; TESAttackDamageForm* pAttack = DYNAMIC_CAST(thisForm, TESForm, TESAttackDamageForm); if (pAttack) return pAttack->GetAttackDamage(); return 0; } UInt32 GetValue(TESForm* thisForm) { if (!thisForm) return 0; TESValueForm* pValue = DYNAMIC_CAST(thisForm, TESForm, TESValueForm); if (pValue) return pValue->value; else { AlchemyItem* alchemyItem = DYNAMIC_CAST(thisForm, TESForm, AlchemyItem); if(alchemyItem && (alchemyItem->itemData.flags & AlchemyItem::kFlag_ManualCalc) == AlchemyItem::kFlag_ManualCalc) return alchemyItem->itemData.value; } return 0; } void SetGoldValue(TESForm* thisForm, UInt32 value) { if (!thisForm) return; TESValueForm* pValue = DYNAMIC_CAST(thisForm, TESForm, TESValueForm); if (pValue) pValue->value = value; else { AlchemyItem* alchemyItem = DYNAMIC_CAST(thisForm, TESForm, AlchemyItem); if(alchemyItem && (alchemyItem->itemData.flags & AlchemyItem::kFlag_ManualCalc) == AlchemyItem::kFlag_ManualCalc) alchemyItem->itemData.value = value; } } UInt32 GetNumKeywords(TESForm* thisForm) { if (!thisForm) return 0; BGSKeywordForm* pKeywords = DYNAMIC_CAST(thisForm, TESForm, BGSKeywordForm); if (pKeywords) return pKeywords->numKeywords; return 0; } BGSKeyword* GetNthKeyword(TESForm* thisForm, UInt32 index) { if (!thisForm) return NULL; BGSKeywordForm* pKeywords = DYNAMIC_CAST(thisForm, TESForm, BGSKeywordForm); if (pKeywords && index < pKeywords->numKeywords) { return pKeywords->keywords[index]; } return NULL; } typedef std::set HandleList; typedef std::map RegisteredKeyMap; VMResultArray GetKeywords(TESForm* thisForm) { VMResultArray result; if (!thisForm) return result; BGSKeywordForm* pKeywords = DYNAMIC_CAST(thisForm, TESForm, BGSKeywordForm); if (pKeywords) { for(UInt32 i = 0; i < pKeywords->numKeywords; i++) { if(pKeywords->keywords[i]) result.push_back(pKeywords->keywords[i]); } } return result; } void SetPlayerKnows(TESForm * thisForm, bool knows) { if(!thisForm) return; knows ? thisForm->flags |= TESForm::kFlagPlayerKnows : thisForm->flags &= ~TESForm::kFlagPlayerKnows; } void RegisterForKey(TESForm * thisForm, UInt32 key) { if(!thisForm) return; g_inputKeyEventRegs.Register(key, thisForm->GetFormType(), thisForm); } void UnregisterForKey(TESForm * thisForm, UInt32 key) { if(!thisForm) return; g_inputKeyEventRegs.Unregister(key, thisForm->GetFormType(), thisForm); } void UnregisterForAllKeys(TESForm * thisForm) { if(!thisForm) return; g_inputKeyEventRegs.UnregisterAll(thisForm->GetFormType(), thisForm); } void RegisterForControl(TESForm * thisForm, BSFixedString control) { if(!thisForm) return; g_inputControlEventRegs.Register(control, thisForm->GetFormType(), thisForm); } void UnregisterForControl(TESForm * thisForm, BSFixedString control) { if(!thisForm) return; g_inputControlEventRegs.Unregister(control, thisForm->GetFormType(), thisForm); } void UnregisterForAllControls(TESForm * thisForm) { if(!thisForm) return; g_inputControlEventRegs.UnregisterAll(thisForm->GetFormType(), thisForm); } #if 0 void UpdateKeys(UInt8 * data) { /*static UInt8 oldState[0x100] = { 0 }; if(!*g_skyrimVM) return; // ### this is off because it's a super temp hack BSFixedString eventName("OnKeyDown"); VMClassRegistry * registry = (*g_skyrimVM)->GetClassRegistry(); for(UInt32 i = 0; i < 0x100; i++) { if(!oldState[i] && data[i]) { RegisteredKeyMap::iterator registeredHandles = g_regKeyMap.find(i); if(registeredHandles != g_regKeyMap.end()) { for(HandleList::iterator iter = registeredHandles->second.begin(); iter != registeredHandles->second.end(); ++iter) { OneIntArg args(i); registry->QueueEvent(*iter, &eventName, &args); } } } oldState[i] = data[i]; }*/ } #endif void RegisterForMenu(TESForm * thisForm, BSFixedString menuName) { if(!thisForm || !menuName.data) return; g_menuOpenCloseRegs.Register(menuName, thisForm->GetFormType(), thisForm); } void UnregisterForMenu(TESForm * thisForm, BSFixedString menuName) { if(!thisForm || !menuName.data) return; g_menuOpenCloseRegs.Unregister(menuName, thisForm->GetFormType(), thisForm); } void UnregisterForAllMenus(TESForm * thisForm) { if(!thisForm) return; g_menuOpenCloseRegs.UnregisterAll(thisForm->GetFormType(), thisForm); } void RegisterForModEvent(TESForm * thisForm, BSFixedString eventName, BSFixedString callbackName) { if(!thisForm || !eventName.data || !callbackName.data) return; ModCallbackParameters params; params.callbackName = callbackName; g_modCallbackRegs.Register(eventName, thisForm->GetFormType(), thisForm, ¶ms); } void UnregisterForModEvent(TESForm * thisForm, BSFixedString eventName) { if(!thisForm || !eventName.data) return; g_modCallbackRegs.Unregister(eventName, thisForm->GetFormType(), thisForm); } void UnregisterForAllModEvents(TESForm * thisForm) { g_modCallbackRegs.UnregisterAll(thisForm->GetFormType(), thisForm); } void SendModEvent(TESForm * thisForm, BSFixedString eventName, BSFixedString strArg, float numArg) { if (!eventName.data) return; SKSEModCallbackEvent evn(eventName, strArg, numArg, thisForm); g_modCallbackEventDispatcher.SendEvent(&evn); } void RegisterForCameraState(TESForm * thisForm) { if(!thisForm) return; g_cameraEventRegs.Register(thisForm->GetFormType(), thisForm); } void UnregisterForCameraState(TESForm * thisForm) { if(!thisForm) return; g_cameraEventRegs.Unregister(thisForm->GetFormType(), thisForm); } void RegisterForCrosshairRef(TESForm * thisForm) { if(!thisForm) return; g_crosshairRefEventRegs.Register(thisForm->GetFormType(), thisForm); } void UnregisterForCrosshairRef(TESForm * thisForm) { if(!thisForm) return; g_crosshairRefEventRegs.Unregister(thisForm->GetFormType(), thisForm); } void RegisterForActorAction(TESForm * thisForm, UInt32 actionType) { if(!thisForm) return; g_actionEventRegs.Register(actionType, thisForm->GetFormType(), thisForm); } void UnregisterForActorAction(TESForm * thisForm, UInt32 actionType) { if(!thisForm) return; g_actionEventRegs.Unregister(actionType, thisForm->GetFormType(), thisForm); } TESForm * TempClone(TESForm * thisForm) { TESForm * result = NULL; if(thisForm) { IFormFactory * factory = IFormFactory::GetFactoryForType(thisForm->formType); if(factory) { result = factory->Create(); if(result) { result->Init(); result->CopyFrom(thisForm); result->CopyFromEx(thisForm); } else { _ERROR("Form::TempClone: factory for type %02X failed", thisForm->formType); } } else { _MESSAGE("Form::TempClone: tried to clone form %08X (type %02X), no factory found", thisForm->formID, thisForm->formType); } } return result; } bool HasWorldModel(TESForm * thisForm) { if(thisForm) { TESModel* pWorldModel = DYNAMIC_CAST(thisForm, TESForm, TESModel); if (pWorldModel) return true; } return false; } BSFixedString GetWorldModelPath(TESForm * thisForm) { if(!thisForm) return NULL; TESModel* pWorldModel = DYNAMIC_CAST(thisForm, TESForm, TESModel); if (!pWorldModel) return NULL; return pWorldModel->GetModelName(); } void SetWorldModelPath(TESForm * thisForm, BSFixedString nuPath) { if(thisForm) { TESModel* pWorldModel = DYNAMIC_CAST(thisForm, TESForm, TESModel); if(pWorldModel) pWorldModel->SetModelName(nuPath.data); } } UInt32 GetWorldModelNumTextureSets(TESForm * thisForm) { if(!thisForm) return 0; TESModelTextureSwap* pTextSwap = DYNAMIC_CAST(thisForm, TESForm, TESModelTextureSwap); if (!pTextSwap) return 0; return pTextSwap->count; } BGSTextureSet* GetWorldModelNthTextureSet(TESForm * thisForm, UInt32 n) { if(!thisForm) return NULL; TESModelTextureSwap* pTextSwap = DYNAMIC_CAST(thisForm, TESForm, TESModelTextureSwap); if (!pTextSwap) return NULL; if(!pTextSwap->swaps || n >= pTextSwap->count) return NULL; return pTextSwap->swaps[n].textureSet; } void SetWorldModelNthTextureSet(TESForm * thisForm, BGSTextureSet* textureSet, UInt32 n) { if(thisForm && thisForm) { TESModelTextureSwap* pTextSwap = DYNAMIC_CAST(thisForm, TESForm, TESModelTextureSwap); if (pTextSwap) { if(pTextSwap->swaps && n < pTextSwap->count) { pTextSwap->swaps[n].textureSet = textureSet; } } } } bool IsPlayable(TESForm * thisForm) { return (thisForm) ? thisForm->IsPlayable() : false; } void RegisterForNiNodeUpdate(TESForm * thisForm) { if(!thisForm) return; g_ninodeUpdateEventRegs.Register(thisForm->GetFormType(), thisForm); } void UnregisterForNiNodeUpdate(TESForm * thisForm) { if(!thisForm) return; g_ninodeUpdateEventRegs.Unregister(thisForm->GetFormType(), thisForm); } } #include "PapyrusVM.h" #include "PapyrusNativeFunctions.h" void papyrusForm::RegisterFuncs(VMClassRegistry* registry) { registry->RegisterFunction( new NativeFunction0 ("GetType", "Form", papyrusForm::GetType, registry)); registry->RegisterFunction( new NativeFunction0 ("GetName", "Form", papyrusForm::GetName, registry)); registry->RegisterFunction( new NativeFunction1 ("SetName", "Form", papyrusForm::SetName, registry)); registry->RegisterFunction( new NativeFunction0 ("GetWeight", "Form", papyrusForm::GetWeight, registry)); registry->RegisterFunction( new NativeFunction1 ("SetWeight", "Form", papyrusForm::SetWeight, registry)); registry->RegisterFunction( new NativeFunction1 ("SetGoldValue", "Form", papyrusForm::SetGoldValue, registry)); registry->RegisterFunction( new NativeFunction0 ("GetNumKeywords", "Form", papyrusForm::GetNumKeywords, registry)); registry->RegisterFunction( new NativeFunction1 ("GetNthKeyword", "Form", papyrusForm::GetNthKeyword, registry)); registry->RegisterFunction( new NativeFunction0 > ("GetKeywords", "Form", papyrusForm::GetKeywords, registry)); registry->RegisterFunction( new NativeFunction1 ("SetPlayerKnows", "Form", papyrusForm::SetPlayerKnows, registry)); registry->RegisterFunction( new NativeFunction1 ("RegisterForKey", "Form", papyrusForm::RegisterForKey, registry)); registry->RegisterFunction( new NativeFunction1 ("UnregisterForKey", "Form", papyrusForm::UnregisterForKey, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForAllKeys", "Form", papyrusForm::UnregisterForAllKeys, registry)); registry->RegisterFunction( new NativeFunction1 ("RegisterForMenu", "Form", papyrusForm::RegisterForMenu, registry)); registry->RegisterFunction( new NativeFunction1 ("UnregisterForMenu", "Form", papyrusForm::UnregisterForMenu, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForAllMenus", "Form", papyrusForm::UnregisterForAllMenus, registry)); registry->RegisterFunction( new NativeFunction2 ("RegisterForModEvent", "Form", papyrusForm::RegisterForModEvent, registry)); registry->RegisterFunction( new NativeFunction3 ("SendModEvent", "Form", papyrusForm::SendModEvent, registry)); registry->RegisterFunction( new NativeFunction1 ("UnregisterForModEvent", "Form", papyrusForm::UnregisterForModEvent, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForAllModEvents", "Form", papyrusForm::UnregisterForAllModEvents, registry)); registry->RegisterFunction( new NativeFunction0 ("TempClone", "Form", papyrusForm::TempClone, registry)); registry->RegisterFunction( new NativeFunction1 ("RegisterForControl", "Form", papyrusForm::RegisterForControl, registry)); registry->RegisterFunction( new NativeFunction1 ("UnregisterForControl", "Form", papyrusForm::UnregisterForControl, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForAllControls", "Form", papyrusForm::UnregisterForAllControls, registry)); registry->RegisterFunction( new NativeFunction0 ("RegisterForCameraState", "Form", papyrusForm::RegisterForCameraState, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForCameraState", "Form", papyrusForm::UnregisterForCameraState, registry)); registry->RegisterFunction( new NativeFunction0 ("RegisterForCrosshairRef", "Form", papyrusForm::RegisterForCrosshairRef, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForCrosshairRef", "Form", papyrusForm::UnregisterForCrosshairRef, registry)); registry->RegisterFunction( new NativeFunction1 ("RegisterForActorAction", "Form", papyrusForm::RegisterForActorAction, registry)); registry->RegisterFunction( new NativeFunction1 ("UnregisterForActorAction", "Form", papyrusForm::UnregisterForActorAction, registry)); registry->RegisterFunction( new NativeFunction0 ("RegisterForNiNodeUpdate", "Form", papyrusForm::RegisterForNiNodeUpdate, registry)); registry->RegisterFunction( new NativeFunction0 ("UnregisterForNiNodeUpdate", "Form", papyrusForm::UnregisterForNiNodeUpdate, registry)); registry->RegisterFunction( new NativeFunction0 ("HasWorldModel", "Form", papyrusForm::HasWorldModel, registry)); registry->RegisterFunction( new NativeFunction0 ("GetWorldModelPath", "Form", papyrusForm::GetWorldModelPath, registry)); registry->RegisterFunction( new NativeFunction1 ("SetWorldModelPath", "Form", papyrusForm::SetWorldModelPath, registry)); registry->RegisterFunction( new NativeFunction0 ("GetWorldModelNumTextureSets", "Form", papyrusForm::GetWorldModelNumTextureSets, registry)); registry->RegisterFunction( new NativeFunction1 ("GetWorldModelNthTextureSet", "Form", papyrusForm::GetWorldModelNthTextureSet, registry)); registry->RegisterFunction( new NativeFunction2 ("SetWorldModelNthTextureSet", "Form", papyrusForm::SetWorldModelNthTextureSet, registry)); registry->RegisterFunction( new NativeFunction0 ("IsPlayable", "Form", papyrusForm::IsPlayable, registry)); registry->SetFunctionFlags("Form", "SetPlayerKnows", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForKey", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForKey", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForAllKeys", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForMenu", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForMenu", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForAllMenus", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForModEvent", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "SendModEvent", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForAllModEvents", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForControl", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForControl", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForAllControls", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForCameraState", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForCameraState", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForCrosshairRef", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForCrosshairRef", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "RegisterForActorAction", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "UnregisterForActorAction", VMClassRegistry::kFunctionFlag_NoWait); registry->SetFunctionFlags("Form", "HasWorldModel", VMClassRegistry::kFunctionFlag_NoWait); }