Advertisement
expired6978

Latent Attach Wire

Apr 5th, 2017
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.24 KB | None | 0 0
  1. class AttachWireTaskFunctor : public LatentF4SEDelayFunctor
  2.     {
  3.     public:
  4.         explicit AttachWireTaskFunctor(UInt32 stackId, TESObjectREFR* refA, TESObjectREFR* refB, TESForm* baseSpline) : LatentF4SEDelayFunctor( stackId )
  5.         {
  6.             m_ref[0] = GetHandleFromObject(refA, TESObjectREFR::kTypeID);
  7.             m_ref[1] = GetHandleFromObject(refB, TESObjectREFR::kTypeID);
  8.             m_ref[2] = GetHandleFromObject(baseSpline, TESForm::kTypeID);
  9.         }
  10.         explicit AttachWireTaskFunctor(SerializationTag tag) : LatentF4SEDelayFunctor( tag ) {}
  11.  
  12.         virtual const char* ClassName() const       { return "AttachWireTaskFunctor"; }
  13.         virtual UInt32      ClassVersion() const    { return 1; }
  14.  
  15.         virtual bool Save(const F4SESerializationInterface* intfc);
  16.         virtual bool Load(const F4SESerializationInterface* intfc, UInt32 version);
  17.  
  18.         virtual void Run(VMValue& resultValue)
  19.         {
  20.             TESObjectREFR * wireRef = nullptr;
  21.             VirtualMachine* vm = (*g_gameVM)->m_virtualMachine;
  22.  
  23.             TESObjectREFR * refA = (TESObjectREFR*)GetObjectFromHandle(m_ref[0], TESObjectREFR::kTypeID);
  24.             TESObjectREFR * refB = (TESObjectREFR*)GetObjectFromHandle(m_ref[1], TESObjectREFR::kTypeID);
  25.             TESForm * splineForm = (TESForm*)GetObjectFromHandle(m_ref[2], TESForm::kTypeID);
  26.  
  27.             // There's no 3D loaded for these, probably bad news
  28.             if(!splineForm || !refA || !refB || !refA->GetObjectRootNode() || !refB->GetObjectRootNode()) {
  29.                 PackValue(&resultValue, &wireRef, vm);
  30.                 return;
  31.             }
  32.  
  33.             BGSBendableSpline * spline = DYNAMIC_CAST(splineForm, TESForm, BGSBendableSpline);
  34.             BGSBendableSpline * splineA = DYNAMIC_CAST(refA->baseForm, TESForm, BGSBendableSpline);
  35.             BGSBendableSpline * splineB = DYNAMIC_CAST(refB->baseForm, TESForm, BGSBendableSpline);
  36.  
  37.             BGSKeyword * keyword = DYNAMIC_CAST(LookupFormByID(0x00054BA6), TESForm, BGSKeyword);
  38.             // No workshop keyword is bad
  39.             // Connecting a wire to another wire or connecting a non-wire is invalid
  40.             if(!keyword || !spline || splineA || splineB) {
  41.                 PackValue(&resultValue, &wireRef, vm);
  42.                 return;
  43.             }
  44.  
  45.             // Get the workshop by keyword
  46.             TESObjectREFR * workshopRef = GetLinkedRef_Native(refA, keyword);
  47.             if(!workshopRef) {
  48.                 PackValue(&resultValue, &wireRef, vm);
  49.                 return;
  50.             }
  51.  
  52.             // Workshop ref isn't a workshop!
  53.             BSExtraData* extraDataWorkshop = workshopRef->extraDataList->GetByType(ExtraDataType::kExtraData_WorkshopExtraData);
  54.             if(!extraDataWorkshop) {
  55.                 PackValue(&resultValue, &wireRef, vm);
  56.                 return;
  57.             }
  58.  
  59.             // Create our wire instance
  60.             wireRef = PlaceAtMe_Native(vm, stackId_, &refA, spline, 1, false, false, false);
  61.             if(!wireRef) {
  62.                 PackValue(&resultValue, &wireRef, vm);
  63.                 return;
  64.             }
  65.  
  66.             // Set the wire's linked ref to the workshop
  67.             SetLinkedRef_Native(wireRef, workshopRef, keyword);
  68.  
  69.             LocationData locData(*g_player);
  70.             FinalizeWireLink(&locData, wireRef, refB, 0, refA, 0);
  71.             SetWireEndpoints_Internal(refA, 0, refB, 0, wireRef);
  72.            
  73.  
  74.             ExtraBendableSplineParams * splineParams = (ExtraBendableSplineParams*)wireRef->extraDataList->GetByType(kExtraData_BendableSplineParams);
  75.             if(splineParams) {
  76.                 splineParams->thickness = 1.5f;
  77.             }
  78.  
  79.             LinkPower_Internal(extraDataWorkshop, refA, refB, wireRef);
  80.  
  81.             PackValue(&resultValue, &wireRef, vm);
  82.         }
  83.  
  84.     private:
  85.         UInt64 m_ref[3];
  86.     };
  87.  
  88.     bool AttachWireTaskFunctor::Save(const F4SESerializationInterface* intfc)
  89.     {
  90.         using namespace Serialization;
  91.  
  92.         if (! LatentF4SEDelayFunctor::Save(intfc))
  93.             return false;
  94.  
  95.         for(UInt32 i = 0; i < 3; i++)
  96.         {
  97.             if(!WriteData(intfc, &m_ref[i]))
  98.                 return false;
  99.         }
  100.  
  101.         return true;
  102.     }
  103.  
  104.     bool AttachWireTaskFunctor::Load(const F4SESerializationInterface* intfc, UInt32 version)
  105.     {
  106.         using namespace Serialization;
  107.  
  108.         if (! LatentF4SEDelayFunctor::Load(intfc, version))
  109.             return false;
  110.  
  111.         for(UInt32 i = 0; i < 3; i++)
  112.         {
  113.             if (! ReadData(intfc, &m_ref[i]))
  114.                 return false;
  115.  
  116.             if (! intfc->ResolveHandle(m_ref[i], &m_ref[i]))
  117.                 return false;
  118.         }
  119.  
  120.         return true;
  121.     }
  122.  
  123.     bool AttachWire(VirtualMachine * vm, UInt32 stackId, TESObjectREFR* refA, TESObjectREFR* refB, TESForm* baseSpline)
  124.     {
  125.         if(!baseSpline || !refA || !refB)
  126.             return false;
  127.  
  128.         F4SEDelayFunctorManagerInstance().Enqueue(new AttachWireTaskFunctor(stackId, refA, refB, baseSpline));
  129.         return true;
  130.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement