1
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

597 lines
18 KiB

#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 <map>
#include <set>
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 <UInt64> HandleList;
typedef std::map <UInt32, HandleList> RegisteredKeyMap;
VMResultArray<BGSKeyword*> GetKeywords(TESForm* thisForm)
{
VMResultArray<BGSKeyword*> 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<TESForm>(key, thisForm->GetFormType(), thisForm);
}
void UnregisterForKey(TESForm * thisForm, UInt32 key)
{
if(!thisForm)
return;
g_inputKeyEventRegs.Unregister<TESForm>(key, thisForm->GetFormType(), thisForm);
}
void UnregisterForAllKeys(TESForm * thisForm)
{
if(!thisForm)
return;
g_inputKeyEventRegs.UnregisterAll<TESForm>(thisForm->GetFormType(), thisForm);
}
void RegisterForControl(TESForm * thisForm, BSFixedString control)
{
if(!thisForm)
return;
g_inputControlEventRegs.Register<TESForm>(control, thisForm->GetFormType(), thisForm);
}
void UnregisterForControl(TESForm * thisForm, BSFixedString control)
{
if(!thisForm)
return;
g_inputControlEventRegs.Unregister<TESForm>(control, thisForm->GetFormType(), thisForm);
}
void UnregisterForAllControls(TESForm * thisForm)
{
if(!thisForm)
return;
g_inputControlEventRegs.UnregisterAll<TESForm>(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<TESForm>(menuName, thisForm->GetFormType(), thisForm);
}
void UnregisterForMenu(TESForm * thisForm, BSFixedString menuName)
{
if(!thisForm || !menuName.data)
return;
g_menuOpenCloseRegs.Unregister<TESForm>(menuName, thisForm->GetFormType(), thisForm);
}
void UnregisterForAllMenus(TESForm * thisForm)
{
if(!thisForm)
return;
g_menuOpenCloseRegs.UnregisterAll<TESForm>(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<TESForm>(eventName, thisForm->GetFormType(), thisForm, &params);
}
void UnregisterForModEvent(TESForm * thisForm, BSFixedString eventName)
{
if(!thisForm || !eventName.data)
return;
g_modCallbackRegs.Unregister<TESForm>(eventName, thisForm->GetFormType(), thisForm);
}
void UnregisterForAllModEvents(TESForm * thisForm)
{
g_modCallbackRegs.UnregisterAll<TESForm>(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<TESForm>(thisForm->GetFormType(), thisForm);
}
void UnregisterForCameraState(TESForm * thisForm)
{
if(!thisForm)
return;
g_cameraEventRegs.Unregister<TESForm>(thisForm->GetFormType(), thisForm);
}
void RegisterForCrosshairRef(TESForm * thisForm)
{
if(!thisForm)
return;
g_crosshairRefEventRegs.Register<TESForm>(thisForm->GetFormType(), thisForm);
}
void UnregisterForCrosshairRef(TESForm * thisForm)
{
if(!thisForm)
return;
g_crosshairRefEventRegs.Unregister<TESForm>(thisForm->GetFormType(), thisForm);
}
void RegisterForActorAction(TESForm * thisForm, UInt32 actionType)
{
if(!thisForm)
return;
g_actionEventRegs.Register<TESForm>(actionType, thisForm->GetFormType(), thisForm);
}
void UnregisterForActorAction(TESForm * thisForm, UInt32 actionType)
{
if(!thisForm)
return;
g_actionEventRegs.Unregister<TESForm>(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<TESForm>(thisForm->GetFormType(), thisForm);
}
void UnregisterForNiNodeUpdate(TESForm * thisForm)
{
if(!thisForm)
return;
g_ninodeUpdateEventRegs.Unregister<TESForm>(thisForm->GetFormType(), thisForm);
}
}
#include "PapyrusVM.h"
#include "PapyrusNativeFunctions.h"
void papyrusForm::RegisterFuncs(VMClassRegistry* registry)
{
registry->RegisterFunction(
new NativeFunction0 <TESForm, UInt32> ("GetType", "Form", papyrusForm::GetType, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, BSFixedString> ("GetName", "Form", papyrusForm::GetName, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("SetName", "Form", papyrusForm::SetName, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, float> ("GetWeight", "Form", papyrusForm::GetWeight, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, float> ("SetWeight", "Form", papyrusForm::SetWeight, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, UInt32> ("SetGoldValue", "Form", papyrusForm::SetGoldValue, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, UInt32> ("GetNumKeywords", "Form", papyrusForm::GetNumKeywords, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, BGSKeyword *, UInt32> ("GetNthKeyword", "Form", papyrusForm::GetNthKeyword, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, VMResultArray<BGSKeyword*>> ("GetKeywords", "Form", papyrusForm::GetKeywords, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, bool> ("SetPlayerKnows", "Form", papyrusForm::SetPlayerKnows, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, UInt32> ("RegisterForKey", "Form", papyrusForm::RegisterForKey, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, UInt32> ("UnregisterForKey", "Form", papyrusForm::UnregisterForKey, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForAllKeys", "Form", papyrusForm::UnregisterForAllKeys, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("RegisterForMenu", "Form", papyrusForm::RegisterForMenu, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("UnregisterForMenu", "Form", papyrusForm::UnregisterForMenu, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForAllMenus", "Form", papyrusForm::UnregisterForAllMenus, registry));
registry->RegisterFunction(
new NativeFunction2 <TESForm, void, BSFixedString, BSFixedString> ("RegisterForModEvent", "Form", papyrusForm::RegisterForModEvent, registry));
registry->RegisterFunction(
new NativeFunction3 <TESForm, void, BSFixedString, BSFixedString, float> ("SendModEvent", "Form", papyrusForm::SendModEvent, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("UnregisterForModEvent", "Form", papyrusForm::UnregisterForModEvent, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForAllModEvents", "Form", papyrusForm::UnregisterForAllModEvents, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, TESForm *> ("TempClone", "Form", papyrusForm::TempClone, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("RegisterForControl", "Form", papyrusForm::RegisterForControl, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("UnregisterForControl", "Form", papyrusForm::UnregisterForControl, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForAllControls", "Form", papyrusForm::UnregisterForAllControls, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("RegisterForCameraState", "Form", papyrusForm::RegisterForCameraState, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForCameraState", "Form", papyrusForm::UnregisterForCameraState, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("RegisterForCrosshairRef", "Form", papyrusForm::RegisterForCrosshairRef, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForCrosshairRef", "Form", papyrusForm::UnregisterForCrosshairRef, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, UInt32> ("RegisterForActorAction", "Form", papyrusForm::RegisterForActorAction, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, UInt32> ("UnregisterForActorAction", "Form", papyrusForm::UnregisterForActorAction, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("RegisterForNiNodeUpdate", "Form", papyrusForm::RegisterForNiNodeUpdate, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, void> ("UnregisterForNiNodeUpdate", "Form", papyrusForm::UnregisterForNiNodeUpdate, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, bool> ("HasWorldModel", "Form", papyrusForm::HasWorldModel, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, BSFixedString> ("GetWorldModelPath", "Form", papyrusForm::GetWorldModelPath, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, void, BSFixedString> ("SetWorldModelPath", "Form", papyrusForm::SetWorldModelPath, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, UInt32> ("GetWorldModelNumTextureSets", "Form", papyrusForm::GetWorldModelNumTextureSets, registry));
registry->RegisterFunction(
new NativeFunction1 <TESForm, BGSTextureSet*, UInt32> ("GetWorldModelNthTextureSet", "Form", papyrusForm::GetWorldModelNthTextureSet, registry));
registry->RegisterFunction(
new NativeFunction2 <TESForm, void, BGSTextureSet*, UInt32> ("SetWorldModelNthTextureSet", "Form", papyrusForm::SetWorldModelNthTextureSet, registry));
registry->RegisterFunction(
new NativeFunction0 <TESForm, bool> ("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);
}