From 641cf81dd849dca865c2a6cf753def1f8a87c439 Mon Sep 17 00:00:00 2001 From: Aruki Date: Mon, 9 Jul 2018 03:54:19 -0600 Subject: [PATCH] Fixed array property display on UI (they still can't be resized) --- src/Core/Resource/Cooker/CScriptCooker.cpp | 2 +- src/Core/Resource/Factory/CScriptLoader.cpp | 4 +- src/Core/Resource/Factory/CTemplateLoader.cpp | 16 ++-- src/Core/Resource/Script/IPropertyNew.cpp | 6 +- src/Core/Resource/Script/IPropertyNew.h | 9 ++ .../Script/Property/CAnimationSetProperty.h | 5 ++ .../Resource/Script/Property/CArrayProperty.h | 15 +++- .../Resource/Script/Property/CByteProperty.h | 2 +- .../Resource/Script/Property/CShortProperty.h | 2 +- .../Script/Property/CStructProperty.h | 6 +- src/Editor/PropertyEdit/CPropertyDelegate.cpp | 12 +-- src/Editor/PropertyEdit/CPropertyModel.cpp | 86 +++++++++++++++---- src/Editor/PropertyEdit/CPropertyModel.h | 2 +- templates/mp2/Script/SequenceTimer.xml | 1 + 14 files changed, 123 insertions(+), 45 deletions(-) diff --git a/src/Core/Resource/Cooker/CScriptCooker.cpp b/src/Core/Resource/Cooker/CScriptCooker.cpp index 88d53740..9ee00e8e 100644 --- a/src/Core/Resource/Cooker/CScriptCooker.cpp +++ b/src/Core/Resource/Cooker/CScriptCooker.cpp @@ -213,7 +213,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IPropertyNew* pProperty, for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(pData); ElementIdx++) { mpArrayItemData = pArray->ItemPointer(pData, ElementIdx); - WriteProperty(rOut, pArray->ArchetypeProperty(), true); + WriteProperty(rOut, pArray->ItemArchetype(), true); } mpArrayItemData = pOldItemData; diff --git a/src/Core/Resource/Factory/CScriptLoader.cpp b/src/Core/Resource/Factory/CScriptLoader.cpp index 8e9bfa38..7324a20c 100644 --- a/src/Core/Resource/Factory/CScriptLoader.cpp +++ b/src/Core/Resource/Factory/CScriptLoader.cpp @@ -219,7 +219,7 @@ void CScriptLoader::ReadProperty(IPropertyNew *pProp, u32 Size, IInputStream& rS // Make sure the array archetype is atomic... non-atomic array archetypes is not supported // because arrays can only have one possible archetype so having property IDs here wouldn't make sense - ASSERT(pArray->ArchetypeProperty()->IsAtomic()); + ASSERT(pArray->ItemArchetype()->IsAtomic()); for (int ElementIdx = 0; ElementIdx < Count; ElementIdx++) { @@ -236,7 +236,7 @@ void CScriptLoader::ReadProperty(IPropertyNew *pProp, u32 Size, IInputStream& rS * things to make this cleaner */ mpArrayItemData = pArray->ItemPointer(pData, ElementIdx); - ReadProperty(pArray->ArchetypeProperty(), 0, rSCLY); + ReadProperty(pArray->ItemArchetype(), 0, rSCLY); } mpArrayItemData = pOldArrayItemData; diff --git a/src/Core/Resource/Factory/CTemplateLoader.cpp b/src/Core/Resource/Factory/CTemplateLoader.cpp index 1f22698a..ab4aec14 100644 --- a/src/Core/Resource/Factory/CTemplateLoader.cpp +++ b/src/Core/Resource/Factory/CTemplateLoader.cpp @@ -333,18 +333,22 @@ IPropertyNew* CTemplateLoader::LoadProperty(XMLElement* pElem, CScriptTemplate* { CArrayProperty* pArray = TPropCast(pProp); - if (pArray->mpArchetype != nullptr) + if (pArray->mpItemArchetype != nullptr) { - ASSERT(pArray->mpArchetype->Type() == EPropertyTypeNew::Struct); - pStruct = TPropCast(pArray->mpArchetype); + ASSERT(pArray->mpItemArchetype->Type() == EPropertyTypeNew::Struct); + pStruct = TPropCast(pArray->mpItemArchetype); } else { - pArray->mpArchetype = IPropertyNew::Create(EPropertyTypeNew::Struct, pArray, mpMaster, pScript, false); - pStruct = TPropCast(pArray->mpArchetype); + pArray->mpItemArchetype = IPropertyNew::Create(EPropertyTypeNew::Struct, pArray, mpMaster, pScript, false); + pStruct = TPropCast(pArray->mpItemArchetype); pStruct->mFlags = EPropertyFlag::IsAtomic | EPropertyFlag::IsArrayArchetype; } - pStruct = TPropCast(pArray->mpArchetype); + + XMLElement* pItemNameElem = pElem->FirstChildElement("element_name"); + + if (pItemNameElem) + pStruct->mName = pItemNameElem->GetText(); } // Load parameter overrides diff --git a/src/Core/Resource/Script/IPropertyNew.cpp b/src/Core/Resource/Script/IPropertyNew.cpp index 40250b41..5aaec92e 100644 --- a/src/Core/Resource/Script/IPropertyNew.cpp +++ b/src/Core/Resource/Script/IPropertyNew.cpp @@ -152,10 +152,8 @@ TString IPropertyNew::GetTemplateFileName() void* IPropertyNew::RawValuePtr(void* pData) const { // For array archetypes, the caller needs to provide the pointer to the correct array item - if (IsArrayArchetype()) - return pData; - - void* pBasePtr = (mpPointerParent ? mpPointerParent->GetChildDataPointer(pData) : pData); + // Array archetypes can't store their index in the array so it's impossible to determine the correct pointer. + void* pBasePtr = (mpPointerParent && !IsArrayArchetype() ? mpPointerParent->GetChildDataPointer(pData) : pData); void* pValuePtr = ((char*)pBasePtr + mOffset); return pValuePtr; } diff --git a/src/Core/Resource/Script/IPropertyNew.h b/src/Core/Resource/Script/IPropertyNew.h index 5f332611..944b5ce0 100644 --- a/src/Core/Resource/Script/IPropertyNew.h +++ b/src/Core/Resource/Script/IPropertyNew.h @@ -72,6 +72,7 @@ inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type) { switch (Type) { + // these names are required to generate accurate property ID hashes case EPropertyTypeNew::Bool: return "bool"; case EPropertyTypeNew::Int: return "int"; case EPropertyTypeNew::Float: return "float"; @@ -85,6 +86,14 @@ inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type) case EPropertyTypeNew::Sound: return "sound"; case EPropertyTypeNew::Spline: return "spline"; case EPropertyTypeNew::Guid: return "guid"; + // unknown hashable types - used in hashes but these names are inaccurate + case EPropertyTypeNew::Animation: return "animation"; // hashable but real name unknown + case EPropertyTypeNew::Sequence: return "sequence"; + // non hashable types - not used in ID hashes but still displayed on the UI + case EPropertyTypeNew::Byte: return "byte"; + case EPropertyTypeNew::Short: return "short"; + case EPropertyTypeNew::Array: return "array"; + // fallback default: return ""; } } diff --git a/src/Core/Resource/Script/Property/CAnimationSetProperty.h b/src/Core/Resource/Script/Property/CAnimationSetProperty.h index 3778a12d..30c786d9 100644 --- a/src/Core/Resource/Script/Property/CAnimationSetProperty.h +++ b/src/Core/Resource/Script/Property/CAnimationSetProperty.h @@ -17,6 +17,11 @@ public: { Value(pData).Serialize(Arc); } + + virtual const char* HashableTypeName() const + { + return (Game() <= eEchoes ? "AnimationSet" : "CharacterAnimationSet"); + } }; #endif // CANIMATIONSETPROPERTY_H diff --git a/src/Core/Resource/Script/Property/CArrayProperty.h b/src/Core/Resource/Script/Property/CArrayProperty.h index 2a5b2bd9..d0fda7c8 100644 --- a/src/Core/Resource/Script/Property/CArrayProperty.h +++ b/src/Core/Resource/Script/Property/CArrayProperty.h @@ -22,7 +22,9 @@ struct SScriptArray /** @todo proper support of default values for arrays (this would be used for prefabs) */ class CArrayProperty : public TTypedPropertyNew { + friend class IPropertyNew; friend class CTemplateLoader; + /** This class inherits from TTypedPropertyNew in order to expose the array * count value (the first member of SScriptArray). Outside users can edit this * value and we respond by updating the allocated space, handling item destruction @@ -42,6 +44,12 @@ class CArrayProperty : public TTypedPropertyNew return rArray.size() / ItemSize(); } +protected: + CArrayProperty() + : TTypedPropertyNew() + , mpItemArchetype(nullptr) + {} + public: virtual u32 DataSize() const { @@ -110,7 +118,7 @@ public: if (Arc.ParamBegin("ArrayElement")) { void* pItemData = ItemPointer(pData, ItemIdx); - mpArchetype->SerializeValue(pItemData, Arc); + mpItemArchetype->SerializeValue(pItemData, Arc); Arc.ParamEnd(); } } @@ -148,6 +156,7 @@ public: u32 NewSize = NewCount * ItemSize(); rArray.Array.resize(NewSize); + rArray.Count = NewCount; // Handle construction of new elements if (NewCount > OldCount) @@ -163,7 +172,7 @@ public: void* ItemPointer(void* pPropertyData, u32 ItemIndex) const { - ASSERT(ArrayCount(pPropertyData) > ItemIndex); + ASSERT(_InternalArrayCount(pPropertyData) > ItemIndex); std::vector& rArray = _GetInternalArray(pPropertyData).Array; u32 MyItemSize = ItemSize(); ASSERT(rArray.size() >= (MyItemSize * (ItemIndex+1))); @@ -178,7 +187,7 @@ public: } /** Accessors */ - IPropertyNew* ArchetypeProperty() const { return mpArchetype; } + IPropertyNew* ItemArchetype() const { return mpItemArchetype; } }; #endif // CARRAYPROPERTY_H diff --git a/src/Core/Resource/Script/Property/CByteProperty.h b/src/Core/Resource/Script/Property/CByteProperty.h index 2f6403cc..a0dbbe74 100644 --- a/src/Core/Resource/Script/Property/CByteProperty.h +++ b/src/Core/Resource/Script/Property/CByteProperty.h @@ -18,7 +18,7 @@ public: Arc.SerializePrimitive( (u8&) ValueRef(pData) ); } - virtual TString ValueAsString(void* pData) + virtual TString ValueAsString(void* pData) const { return TString::FromInt32( (s32) Value(pData), 0, 10 ); } diff --git a/src/Core/Resource/Script/Property/CShortProperty.h b/src/Core/Resource/Script/Property/CShortProperty.h index 759f866b..f1e1c8c6 100644 --- a/src/Core/Resource/Script/Property/CShortProperty.h +++ b/src/Core/Resource/Script/Property/CShortProperty.h @@ -18,7 +18,7 @@ public: Arc.SerializePrimitive( (u16&) ValueRef(pData) ); } - virtual TString ValueAsString(void* pData) + virtual TString ValueAsString(void* pData) const { return TString::FromInt32( (s32) Value(pData), 0, 10 ); } diff --git a/src/Core/Resource/Script/Property/CStructProperty.h b/src/Core/Resource/Script/Property/CStructProperty.h index 442582cf..831d131c 100644 --- a/src/Core/Resource/Script/Property/CStructProperty.h +++ b/src/Core/Resource/Script/Property/CStructProperty.h @@ -81,12 +81,10 @@ public: virtual const char* HashableTypeName() const { - ASSERT(IsArchetype() || mpArchetype != nullptr); - - if (IsArchetype()) + if (IsArchetype() || !mpArchetype) return *mName; else - return *mpArchetype->Name(); + return mpArchetype->HashableTypeName(); } #if 0 diff --git a/src/Editor/PropertyEdit/CPropertyDelegate.cpp b/src/Editor/PropertyEdit/CPropertyDelegate.cpp index 4405b244..43990ff7 100644 --- a/src/Editor/PropertyEdit/CPropertyDelegate.cpp +++ b/src/Editor/PropertyEdit/CPropertyDelegate.cpp @@ -201,7 +201,7 @@ void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkInd { // Set editor data for regular property IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, false); - void* pData = mpModel->GetPropertyData(); + void* pData = mpModel->DataPointerForIndex(rkIndex); if (pProp) { @@ -356,7 +356,7 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo IEditPropertyCommand* pCommand = nullptr; IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, true); - void* pData = mpModel->GetPropertyData(); + void* pData = mpModel->DataPointerForIndex(rkIndex); if (pProp) { @@ -540,7 +540,7 @@ bool CPropertyDelegate::eventFilter(QObject *pObject, QEvent *pEvent) QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModelIndex& rkIndex) const { CAnimationSetProperty* pAnimSetProp = TPropCast(mpModel->PropertyForIndex(rkIndex, true)); - CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData()); + CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex)); // Determine property type EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex); @@ -588,7 +588,7 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelIndex& rkIndex) const { CAnimationSetProperty* pAnimSetProp = TPropCast(mpModel->PropertyForIndex(rkIndex, true)); - CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData()); + CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex)); EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex); if (Type == EPropertyTypeNew::Asset) @@ -612,7 +612,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelIndex& rkIndex) const { CAnimationSetProperty* pAnimSetProp = TPropCast(mpModel->PropertyForIndex(rkIndex, true)); - CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData()); + CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex)); EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex); if (Type == EPropertyTypeNew::Asset) @@ -632,7 +632,7 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde Params.SetUnknown(UnkIndex, static_cast(pEditor)->value() ); } - pAnimSetProp->ValueRef(mpModel->GetPropertyData()) = Params; + pAnimSetProp->ValueRef(mpModel->DataPointerForIndex(rkIndex)) = Params; // If we just updated the resource, make sure all the sub-properties of the character are flagged as changed. // We want to do this -after- updating the anim params on the property, which is why we have a second type check. diff --git a/src/Editor/PropertyEdit/CPropertyModel.cpp b/src/Editor/PropertyEdit/CPropertyModel.cpp index 0582a00b..c55b0694 100644 --- a/src/Editor/PropertyEdit/CPropertyModel.cpp +++ b/src/Editor/PropertyEdit/CPropertyModel.cpp @@ -30,12 +30,17 @@ int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID) if (pProperty->Type() == EPropertyTypeNew::Array) { CArrayProperty* pArray = TPropCast(pProperty); + u32 ArrayCount = pArray->ArrayCount(mpPropertyData); + void* pOldData = mpPropertyData; - for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(mpPropertyData); ElementIdx++) + for (u32 ElementIdx = 0; ElementIdx < ArrayCount; ElementIdx++) { - int NewChildID = RecursiveBuildArrays( pArray->Archetype(), MyID ); + mpPropertyData = pArray->ItemPointer(pOldData, ElementIdx); + int NewChildID = RecursiveBuildArrays( pArray->ItemArchetype(), MyID ); mProperties[MyID].ChildIDs.push_back(NewChildID); } + + mpPropertyData = pOldData; } else { @@ -115,6 +120,50 @@ QModelIndex CPropertyModel::IndexForProperty(IPropertyNew *pProp) const return mProperties[ID].Index; } +void* CPropertyModel::DataPointerForIndex(const QModelIndex& rkIndex) const +{ + // Going to be the base pointer in 99% of cases, but we need to account for arrays in some cases + int ID = rkIndex.internalId(); + + if (!mProperties[ID].pProperty->IsArrayArchetype()) + return mpPropertyData; + + // Head up the hierarchy until we find a non-array property, keeping track of array indices along the way + // Static arrays to avoid memory allocations, we never have more than 2 nested arrays + CArrayProperty* ArrayProperties[2]; + int ArrayIndices[2]; + int MaxIndex = -1; + + IPropertyNew* pProperty = mProperties[ID].pProperty; + + while (pProperty->IsArrayArchetype()) + { + CArrayProperty* pArray = TPropCast(pProperty->Parent()); + + if (pArray) + { + MaxIndex++; + ArrayProperties[MaxIndex] = pArray; + ArrayIndices[MaxIndex] = mProperties[ID].Index.row(); + } + + ID = mProperties[ID].ParentID; + pProperty = pProperty->Parent(); + } + + // Now fetch the correct pointer from the array properties + void* pOutData = mpPropertyData; + + for (int i = MaxIndex; i >= 0; i--) + { + CArrayProperty* pArray = ArrayProperties[i]; + int ArrayIndex = ArrayIndices[i]; + pOutData = pArray->ItemPointer(pOutData, ArrayIndex); + } + + return pOutData; +} + int CPropertyModel::columnCount(const QModelIndex& /*rkParent*/) const { return 2; @@ -128,7 +177,7 @@ int CPropertyModel::rowCount(const QModelIndex& rkParent) const if (rkParent.internalId() & 0x80000000) return 0; IPropertyNew *pProp = PropertyForIndex(rkParent, false); - int ID = mPropertyToIDMap[pProp]; + int ID = rkParent.internalId(); switch (pProp->Type()) { @@ -137,7 +186,8 @@ int CPropertyModel::rowCount(const QModelIndex& rkParent) const case EPropertyTypeNew::AnimationSet: { - CAnimationParameters Params = TPropCast(pProp)->Value(mpPropertyData); + void* pData = DataPointerForIndex(rkParent); + CAnimationParameters Params = TPropCast(pProp)->Value(pData); if (Params.Version() <= eEchoes) return 3; if (Params.Version() <= eCorruption) return 2; @@ -183,14 +233,15 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const if (Role == Qt::DisplayRole) return ""; else - return TO_QSTRING(TString::HexString( pFlags->FlagMask(rkIndex.row()))); + return TO_QSTRING(TString::HexString( pFlags->FlagMask(rkIndex.row()) )); } } else if (Type == EPropertyTypeNew::AnimationSet) { + void* pData = DataPointerForIndex(rkIndex); CAnimationSetProperty* pAnimSet = TPropCast(pProp); - CAnimationParameters Params = pAnimSet->Value(mpPropertyData); + CAnimationParameters Params = pAnimSet->Value(pData); // There are three different layouts for this property - one for MP1/2, one for MP3, and one for DKCR if (Params.Version() <= eEchoes) @@ -247,7 +298,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const if (pParent && pParent->Type() == EPropertyTypeNew::Array) { // For direct array sub-properties, display the element index after the name - TString ElementName = pParent->Name(); + TString ElementName = pProp->Name(); return QString("%1 %2").arg( TO_QSTRING(ElementName) ).arg(rkIndex.row() + 1); } @@ -257,12 +308,14 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const if (rkIndex.column() == 1) { + void* pData = DataPointerForIndex(rkIndex); + switch (pProp->Type()) { // Enclose vector property text in parentheses case EPropertyTypeNew::Vector: { - CVector3f Value = TPropCast(pProp)->Value(mpPropertyData); + CVector3f Value = TPropCast(pProp)->Value(pData); return TO_QSTRING("(" + Value.ToString() + ")"); } @@ -270,7 +323,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const case EPropertyTypeNew::Sound: { CSoundProperty* pSound = TPropCast(pProp); - u32 SoundID = pSound->Value(mpPropertyData); + u32 SoundID = pSound->Value(pData); if (SoundID == -1) return "[None]"; SSoundInfo SoundInfo = mpProject->AudioManager()->GetSoundInfo(SoundID); @@ -294,7 +347,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const // Display character name for characters case EPropertyTypeNew::AnimationSet: - return TO_QSTRING(TPropCast(pProp)->Value(mpPropertyData).GetCurrentCharacterName()); + return TO_QSTRING(TPropCast(pProp)->Value(pData).GetCurrentCharacterName()); // Display enumerator name for enums (but only on ToolTipRole) case EPropertyTypeNew::Choice: @@ -302,7 +355,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const if (Role == Qt::ToolTipRole) { CEnumProperty *pEnum = TPropCast(pProp); - u32 ValueID = pEnum->Value(mpPropertyData); + u32 ValueID = pEnum->Value(pData); u32 ValueIndex = pEnum->ValueIndex(ValueID); return TO_QSTRING( pEnum->ValueName(ValueIndex) ); } @@ -311,7 +364,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const // Display the element count for arrays case EPropertyTypeNew::Array: { - u32 Count = TPropCast(pProp)->Value(mpPropertyData); + u32 Count = TPropCast(pProp)->Value(pData); return QString("%1 element%2").arg(Count).arg(Count != 1 ? "s" : ""); } @@ -328,7 +381,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const // fall through // Display property value to string for everything else default: - return TO_QSTRING(pProp->ValueAsString(mpPropertyData) + pProp->Suffix()); + return TO_QSTRING(pProp->ValueAsString(pData) + pProp->Suffix()); } } } @@ -341,7 +394,8 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const // Add name IPropertyNew *pProp = PropertyForIndex(rkIndex, false); QString DisplayText = data(rkIndex, Qt::DisplayRole).toString(); - QString Text = QString("%1 (%2)").arg(DisplayText).arg(pProp->HashableTypeName()); + QString TypeName = pProp->HashableTypeName(); + QString Text = QString("%1 (%2)").arg(DisplayText).arg(TypeName); // Add uncooked notification if (pProp->CookPreference() == ECookPreferenceNew::Never) @@ -392,7 +446,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const IPropertyNew *pProp = PropertyForIndex(rkIndex, true); // Don't highlight the name of the root property - if (pProp && pProp->Parent() != nullptr && !pProp->IsArrayArchetype()) + if (pProp && pProp->Parent() != nullptr) { static const QColor skRightColor = QColor(128, 255, 128); static const QColor skWrongColor = QColor(255, 128, 128); @@ -413,7 +467,7 @@ QModelIndex CPropertyModel::index(int Row, int Column, const QModelIndex& rkPare // Check property for children IPropertyNew* pParent = (rkParent.isValid() ? PropertyForIndex(rkParent, false) : mpRootProperty); EPropertyTypeNew ParentType = pParent->Type(); - int ParentID = mPropertyToIDMap[pParent]; + int ParentID = rkParent.internalId(); if (ParentType == EPropertyTypeNew::Flags || ParentType == EPropertyTypeNew::AnimationSet) { diff --git a/src/Editor/PropertyEdit/CPropertyModel.h b/src/Editor/PropertyEdit/CPropertyModel.h index 8f7e50b5..52893b03 100644 --- a/src/Editor/PropertyEdit/CPropertyModel.h +++ b/src/Editor/PropertyEdit/CPropertyModel.h @@ -36,6 +36,7 @@ public: void ConfigureScript(CGameProject* pProject, IPropertyNew* pRootProperty, CScriptObject* pObject); IPropertyNew* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedIndices) const; QModelIndex IndexForProperty(IPropertyNew *pProp) const; + void* DataPointerForIndex(const QModelIndex& rkIndex) const; int columnCount(const QModelIndex& rkParent) const; int rowCount(const QModelIndex& rkParent) const; @@ -53,7 +54,6 @@ public: inline void SetFont(QFont Font) { mFont = Font; } inline void SetBoldModifiedProperties(bool Enable) { mBoldModifiedProperties = Enable; } - inline void* GetPropertyData() const { return mpPropertyData; } inline CScriptObject* GetScriptObject() const { return mpObject; } public slots: diff --git a/templates/mp2/Script/SequenceTimer.xml b/templates/mp2/Script/SequenceTimer.xml index bc8c4368..b791e434 100644 --- a/templates/mp2/Script/SequenceTimer.xml +++ b/templates/mp2/Script/SequenceTimer.xml @@ -10,6 +10,7 @@ 0 + Activation Time 0.0