#ifndef CNODECOPYMIMEDATA #define CNODECOPYMIMEDATA #include #include #include #include #include #include "Editor/CSelectionIterator.h" #include "Editor/WorldEditor/CWorldEditor.h" #include class CNodeCopyMimeData : public QMimeData { Q_OBJECT public: struct SCopiedNode { ENodeType Type; TString Name; CVector3f Position; CQuaternion Rotation; CVector3f Scale; uint32 OriginalInstanceID; std::vector InstanceData; }; private: CWorldEditor *mpEditor; CAssetID mAreaID; QVector mCopiedNodes; EGame mGame; public: CNodeCopyMimeData(const CNodeCopyMimeData& rkSrc) : mpEditor(rkSrc.mpEditor) , mAreaID(rkSrc.mAreaID) , mCopiedNodes(rkSrc.mCopiedNodes) , mGame(rkSrc.mGame) { } CNodeCopyMimeData(CWorldEditor *pEditor) : mpEditor(pEditor) , mAreaID(pEditor->ActiveArea()->ID()) , mGame(pEditor->CurrentGame()) { CNodeSelection *pSelection = pEditor->Selection(); mCopiedNodes.resize(pSelection->Size()); uint32 NodeIndex = 0; CVector3f FirstNodePos; bool SetFirstNodePos = false; for (CSelectionIterator It(pEditor->Selection()); It; ++It) { SCopiedNode& rNode = mCopiedNodes[NodeIndex]; rNode.Type = It->NodeType(); rNode.Name = It->Name(); rNode.Position = It->LocalPosition(); rNode.Rotation = It->LocalRotation(); rNode.Scale = It->LocalScale(); if (rNode.Type == ENodeType::Script) { CScriptObject *pInst = static_cast(*It)->Instance(); rNode.OriginalInstanceID = pInst->InstanceID(); CVectorOutStream Out(&rNode.InstanceData, EEndian::BigEndian); CScriptCooker Cooker(mGame); Cooker.WriteInstance(Out, static_cast(*It)->Instance()); // Replace instance ID with 0xFFFFFFFF to force it to generate a new one. Out.Seek(mGame <= EGame::Prime ? 0x5 : 0x6, SEEK_SET); Out.WriteLong(0xFFFFFFFF); if (!SetFirstNodePos) { FirstNodePos = rNode.Position; SetFirstNodePos = true; } rNode.Position -= FirstNodePos; } NodeIndex++; } } int IndexOfInstanceID(uint32 InstanceID) const { for (int iNode = 0; iNode < mCopiedNodes.size(); iNode++) { if (mCopiedNodes[iNode].OriginalInstanceID == InstanceID) return iNode; } return -1; } CAssetID AreaID() const { return mAreaID; } EGame Game() const { return mGame; } const QVector& CopiedNodes() const { return mCopiedNodes; } }; #endif // CNODECOPYMIMEDATA