Various crash fixes
This commit is contained in:
parent
4e1560a99c
commit
0827c05802
|
@ -29,6 +29,7 @@ CRenderer::CRenderer()
|
||||||
CRenderer::~CRenderer()
|
CRenderer::~CRenderer()
|
||||||
{
|
{
|
||||||
sNumRenderers--;
|
sNumRenderers--;
|
||||||
|
CGraphics::ReleaseContext(mContextIndex);
|
||||||
|
|
||||||
if (sNumRenderers == 0)
|
if (sNumRenderers == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,9 @@ void CCollisionRenderData::BuildRenderData(const SCollisionIndexData& kIndexData
|
||||||
mWireframeIndexBuffer.SetPrimitiveType(GL_LINES);
|
mWireframeIndexBuffer.SetPrimitiveType(GL_LINES);
|
||||||
|
|
||||||
// Build list of triangle indices sorted by material index
|
// Build list of triangle indices sorted by material index
|
||||||
std::vector<uint16> SortedTris(kIndexData.TriangleMaterialIndices.size(), 0);
|
// Apparently some collision meshes have more triangle indices than actual triangles
|
||||||
|
uint NumTris = Math::Min(kIndexData.TriangleIndices.size() / 3, kIndexData.TriangleMaterialIndices.size());
|
||||||
|
std::vector<uint16> SortedTris(NumTris, 0);
|
||||||
|
|
||||||
for (uint16 i=0; i<SortedTris.size(); i++)
|
for (uint16 i=0; i<SortedTris.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -156,6 +156,7 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG)
|
||||||
uint TotalSize;
|
uint TotalSize;
|
||||||
};
|
};
|
||||||
std::vector<SCookedLanguageData> CookedLanguageData( mpStringTable->NumLanguages() );
|
std::vector<SCookedLanguageData> CookedLanguageData( mpStringTable->NumLanguages() );
|
||||||
|
int EnglishIdx = -1;
|
||||||
|
|
||||||
for (uint LanguageIdx = 0; LanguageIdx < mpStringTable->NumLanguages(); LanguageIdx++)
|
for (uint LanguageIdx = 0; LanguageIdx < mpStringTable->NumLanguages(); LanguageIdx++)
|
||||||
{
|
{
|
||||||
|
@ -165,6 +166,11 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG)
|
||||||
CookedData.Language = kLanguageData.Language;
|
CookedData.Language = kLanguageData.Language;
|
||||||
CookedData.StringOffsets.resize( mpStringTable->NumStrings() );
|
CookedData.StringOffsets.resize( mpStringTable->NumStrings() );
|
||||||
CookedData.TotalSize = 0;
|
CookedData.TotalSize = 0;
|
||||||
|
|
||||||
|
if (CookedData.Language == ELanguage::English)
|
||||||
|
{
|
||||||
|
EnglishIdx = (int) LanguageIdx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Language IDs
|
// Language IDs
|
||||||
|
@ -185,9 +191,6 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG)
|
||||||
STRG.WriteLong( 0 );
|
STRG.WriteLong( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some of the following code assumes that language 0 is English.
|
|
||||||
ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English );
|
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
uint StringsStart = STRG.Tell();
|
uint StringsStart = STRG.Tell();
|
||||||
|
|
||||||
|
@ -201,7 +204,7 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG)
|
||||||
|
|
||||||
// If the "localized" flag is disabled, then we will not write this string. Instead, it will
|
// If the "localized" flag is disabled, then we will not write this string. Instead, it will
|
||||||
// reuse the offset for the English text.
|
// reuse the offset for the English text.
|
||||||
if (LanguageIdx == 0 || kStringData.IsLocalized)
|
if (LanguageIdx == EnglishIdx || kStringData.IsLocalized)
|
||||||
{
|
{
|
||||||
CookedData.StringOffsets[StringIdx] = STRG.Tell() - StringsStart;
|
CookedData.StringOffsets[StringIdx] = STRG.Tell() - StringsStart;
|
||||||
CookedData.TotalSize += kStringData.String.Size() + 1; // +1 for terminating zero
|
CookedData.TotalSize += kStringData.String.Size() + 1; // +1 for terminating zero
|
||||||
|
@ -210,8 +213,8 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CookedData.StringOffsets[StringIdx] = CookedLanguageData[0].StringOffsets[StringIdx];
|
CookedData.StringOffsets[StringIdx] = CookedLanguageData[EnglishIdx].StringOffsets[StringIdx];
|
||||||
CookedData.TotalSize += mpStringTable->mLanguages[0].Strings[StringIdx].String.Size() + 1; // +1 for terminating zero
|
CookedData.TotalSize += mpStringTable->mLanguages[EnglishIdx].Strings[StringIdx].String.Size() + 1; // +1 for terminating zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG)
|
||||||
// Language definitions
|
// Language definitions
|
||||||
mpStringTable->mLanguages.resize(NumLanguages);
|
mpStringTable->mLanguages.resize(NumLanguages);
|
||||||
std::vector<uint> LanguageOffsets(NumLanguages);
|
std::vector<uint> LanguageOffsets(NumLanguages);
|
||||||
|
int EnglishIdx = -1;
|
||||||
|
|
||||||
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
||||||
{
|
{
|
||||||
|
@ -49,10 +50,13 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG)
|
||||||
{
|
{
|
||||||
STRG.Skip(4);
|
STRG.Skip(4);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Some of the following code assumes that language 0 is English
|
if (mpStringTable->mLanguages[LanguageIdx].Language == ELanguage::English)
|
||||||
ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English );
|
{
|
||||||
|
EnglishIdx = (int) LanguageIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(EnglishIdx != -1);
|
||||||
|
|
||||||
// String names
|
// String names
|
||||||
if (mVersion >= EGame::EchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
|
@ -89,16 +93,24 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG)
|
||||||
{
|
{
|
||||||
STRG.GoTo( StringOffsets[StringIdx] );
|
STRG.GoTo( StringOffsets[StringIdx] );
|
||||||
TString String = STRG.Read16String().ToUTF8();
|
TString String = STRG.Read16String().ToUTF8();
|
||||||
|
Language.Strings[StringIdx].String = String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set "localized" flags on strings
|
||||||
|
const CStringTable::SLanguageData& kEnglishData = mpStringTable->mLanguages[EnglishIdx];
|
||||||
|
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
||||||
|
{
|
||||||
|
CStringTable::SLanguageData& LanguageData = mpStringTable->mLanguages[LanguageIdx];
|
||||||
|
|
||||||
|
for (uint StringIdx = 0; StringIdx < NumStrings; StringIdx++)
|
||||||
|
{
|
||||||
// Flag the string as localized if it is different than the English
|
// Flag the string as localized if it is different than the English
|
||||||
// version of the same string.
|
// version of the same string.
|
||||||
const TString& kEnglishString = (StringIdx == 0 ? String :
|
const TString& kLocalString = LanguageData.Strings[StringIdx].String;
|
||||||
mpStringTable->mLanguages[0].Strings[StringIdx].String);
|
const TString& kEnglishString = kEnglishData.Strings[StringIdx].String;
|
||||||
|
LanguageData.Strings[StringIdx].IsLocalized = (LanguageIdx == EnglishIdx || kLocalString != kEnglishString);
|
||||||
bool IsLocalized = (LanguageIdx == 0 || String != kEnglishString);
|
|
||||||
|
|
||||||
Language.Strings[StringIdx].String = String;
|
|
||||||
Language.Strings[StringIdx].IsLocalized = IsLocalized;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,11 +128,18 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG)
|
||||||
// Language definitions
|
// Language definitions
|
||||||
mpStringTable->mLanguages.resize(NumLanguages);
|
mpStringTable->mLanguages.resize(NumLanguages);
|
||||||
std::vector< std::vector<uint> > LanguageOffsets(NumLanguages);
|
std::vector< std::vector<uint> > LanguageOffsets(NumLanguages);
|
||||||
|
int EnglishIdx = -1;
|
||||||
|
|
||||||
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
||||||
{
|
{
|
||||||
mpStringTable->mLanguages[LanguageIdx].Language = (ELanguage) STRG.ReadFourCC();
|
mpStringTable->mLanguages[LanguageIdx].Language = (ELanguage) STRG.ReadFourCC();
|
||||||
|
|
||||||
|
if (mpStringTable->mLanguages[LanguageIdx].Language == ELanguage::English)
|
||||||
|
{
|
||||||
|
EnglishIdx = (int) LanguageIdx;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
ASSERT(EnglishIdx != -1);
|
||||||
|
|
||||||
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
||||||
{
|
{
|
||||||
|
@ -133,9 +152,6 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some of the following code assumes that language 0 is English
|
|
||||||
ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English );
|
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
uint StringsStart = STRG.Tell();
|
uint StringsStart = STRG.Tell();
|
||||||
|
|
||||||
|
@ -151,8 +167,8 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG)
|
||||||
Language.Strings[StringIdx].String = STRG.ReadString();
|
Language.Strings[StringIdx].String = STRG.ReadString();
|
||||||
|
|
||||||
// Flag the string as localized if it has a different offset than the English string
|
// Flag the string as localized if it has a different offset than the English string
|
||||||
Language.Strings[StringIdx].IsLocalized = (LanguageIdx == 0 ||
|
Language.Strings[StringIdx].IsLocalized = (LanguageIdx == EnglishIdx ||
|
||||||
LanguageOffsets[LanguageIdx][StringIdx] != LanguageOffsets[0][StringIdx]);
|
LanguageOffsets[LanguageIdx][StringIdx] != LanguageOffsets[EnglishIdx][StringIdx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,12 +96,13 @@ TString CStringTable::GetString(ELanguage Language, uint StringIndex) const
|
||||||
void CStringTable::SetString(ELanguage Language, uint StringIndex, const TString& kNewString)
|
void CStringTable::SetString(ELanguage Language, uint StringIndex, const TString& kNewString)
|
||||||
{
|
{
|
||||||
int LanguageIdx = FindLanguageIndex(this, Language);
|
int LanguageIdx = FindLanguageIndex(this, Language);
|
||||||
|
int EnglishIdx = FindLanguageIndex(this, ELanguage::English);
|
||||||
|
|
||||||
if (LanguageIdx >= 0 && mLanguages[LanguageIdx].Strings.size() > StringIndex)
|
if (LanguageIdx >= 0 && mLanguages[LanguageIdx].Strings.size() > StringIndex)
|
||||||
{
|
{
|
||||||
mLanguages[LanguageIdx].Strings[StringIndex].String = kNewString;
|
mLanguages[LanguageIdx].Strings[StringIndex].String = kNewString;
|
||||||
mLanguages[LanguageIdx].Strings[StringIndex].IsLocalized =
|
mLanguages[LanguageIdx].Strings[StringIndex].IsLocalized =
|
||||||
(LanguageIdx == 0 || kNewString != mLanguages[0].Strings[StringIndex].String);
|
(LanguageIdx == EnglishIdx || kNewString != mLanguages[EnglishIdx].Strings[StringIndex].String);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,14 +32,42 @@ void CTweakManager::LoadTweaks()
|
||||||
// MP2+ - Load tweaks from Standard.ntwk
|
// MP2+ - Load tweaks from Standard.ntwk
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TString FilePath = mpProject->DiscFilesystemRoot(false) + "Standard.ntwk";
|
if (!mpProject->IsWiiBuild())
|
||||||
CFileInStream StandardNTWK(FilePath, EEndian::BigEndian);
|
{
|
||||||
|
mStandardFilePath = mpProject->DiscFilesystemRoot(false) / "Standard.ntwk";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For Wii builds, there is another game-dependent subfolder.
|
||||||
|
EGame Game = mpProject->Game();
|
||||||
|
TString GameName = (Game == EGame::Prime ? "MP1" :
|
||||||
|
Game == EGame::Echoes ? "MP2" :
|
||||||
|
"MP3");
|
||||||
|
mStandardFilePath = mpProject->DiscFilesystemRoot(false) / GameName / "Standard.ntwk";
|
||||||
|
|
||||||
|
// MP3 might actually be FrontEnd
|
||||||
|
if (Game == EGame::Corruption && !FileUtil::Exists(mStandardFilePath))
|
||||||
|
{
|
||||||
|
mStandardFilePath = mpProject->DiscFilesystemRoot(false) / "fe/Standard.ntwk";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileUtil::Exists(mStandardFilePath))
|
||||||
|
{
|
||||||
|
CFileInStream StandardNTWK(mStandardFilePath, EEndian::BigEndian);
|
||||||
CTweakLoader::LoadNTWK(StandardNTWK, mpProject->Game(), mTweakObjects);
|
CTweakLoader::LoadNTWK(StandardNTWK, mpProject->Game(), mTweakObjects);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTweakManager::SaveTweaks()
|
bool CTweakManager::SaveTweaks()
|
||||||
{
|
{
|
||||||
|
// If we don't have any tweaks loaded, nothing to do
|
||||||
|
if (mTweakObjects.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// MP1 - Save all tweak assets
|
// MP1 - Save all tweak assets
|
||||||
if (mpProject->Game() <= EGame::Prime)
|
if (mpProject->Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
|
@ -67,8 +95,7 @@ bool CTweakManager::SaveTweaks()
|
||||||
// MP2+ - Save tweaks to Standard.ntwk
|
// MP2+ - Save tweaks to Standard.ntwk
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TString FilePath = mpProject->DiscFilesystemRoot(false) + "Standard.ntwk";
|
CFileOutStream StandardNTWK(mStandardFilePath, EEndian::BigEndian);
|
||||||
CFileOutStream StandardNTWK(FilePath, EEndian::BigEndian);
|
|
||||||
return CTweakCooker::CookNTWK(mTweakObjects, StandardNTWK);
|
return CTweakCooker::CookNTWK(mTweakObjects, StandardNTWK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ class CTweakManager
|
||||||
/** All tweak resources in the current game */
|
/** All tweak resources in the current game */
|
||||||
std::vector< CTweakData* > mTweakObjects;
|
std::vector< CTweakData* > mTweakObjects;
|
||||||
|
|
||||||
|
/** For MP2+, the path to Standard.ntwk */
|
||||||
|
TString mStandardFilePath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTweakManager(CGameProject* pInProject);
|
CTweakManager(CGameProject* pInProject);
|
||||||
~CTweakManager();
|
~CTweakManager();
|
||||||
|
|
|
@ -34,6 +34,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
||||||
, mpInspectedEntry(nullptr)
|
, mpInspectedEntry(nullptr)
|
||||||
{
|
{
|
||||||
mpUI->setupUi(this);
|
mpUI->setupUi(this);
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
// Hide sorting combo box for now. The size isn't displayed on the UI so this isn't really useful for the end user.
|
// Hide sorting combo box for now. The size isn't displayed on the UI so this isn't really useful for the end user.
|
||||||
mpUI->SortComboBox->hide();
|
mpUI->SortComboBox->hide();
|
||||||
|
@ -896,6 +897,7 @@ void CResourceBrowser::UpdateStore()
|
||||||
// Refresh project-specific UI
|
// Refresh project-specific UI
|
||||||
CreateAddMenu();
|
CreateAddMenu();
|
||||||
CreateFilterCheckboxes();
|
CreateFilterCheckboxes();
|
||||||
|
setEnabled(mpStore != nullptr);
|
||||||
|
|
||||||
// Refresh directory tree
|
// Refresh directory tree
|
||||||
mpDirectoryModel->SetRoot(mpStore ? mpStore->RootDirectory() : nullptr);
|
mpDirectoryModel->SetRoot(mpStore ? mpStore->RootDirectory() : nullptr);
|
||||||
|
|
|
@ -229,6 +229,7 @@ bool CWorldEditor::CloseWorld()
|
||||||
|
|
||||||
ui->ActionSave->setEnabled(false);
|
ui->ActionSave->setEnabled(false);
|
||||||
ui->ActionSaveAndRepack->setEnabled(false);
|
ui->ActionSaveAndRepack->setEnabled(false);
|
||||||
|
ui->ActionEditLayers->setEnabled(false);
|
||||||
emit MapChanged(mpWorld, mpArea);
|
emit MapChanged(mpWorld, mpArea);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -287,6 +288,7 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
|
||||||
// Update toolbar actions
|
// Update toolbar actions
|
||||||
ui->ActionSave->setEnabled(true);
|
ui->ActionSave->setEnabled(true);
|
||||||
ui->ActionSaveAndRepack->setEnabled(true);
|
ui->ActionSaveAndRepack->setEnabled(true);
|
||||||
|
ui->ActionEditLayers->setEnabled(true);
|
||||||
|
|
||||||
// Emit signals
|
// Emit signals
|
||||||
emit MapChanged(mpWorld, mpArea);
|
emit MapChanged(mpWorld, mpArea);
|
||||||
|
|
|
@ -568,6 +568,9 @@
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionEditLayers">
|
<action name="ActionEditLayers">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Edit Layers</string>
|
<string>Edit Layers</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -30,6 +30,8 @@ bool WCreateTab::eventFilter(QObject *pObj, QEvent *pEvent)
|
||||||
if (pObj == mpEditor->Viewport())
|
if (pObj == mpEditor->Viewport())
|
||||||
{
|
{
|
||||||
if (pEvent->type() == QEvent::DragEnter)
|
if (pEvent->type() == QEvent::DragEnter)
|
||||||
|
{
|
||||||
|
if (mpEditor->ActiveArea() != nullptr)
|
||||||
{
|
{
|
||||||
QDragEnterEvent *pDragEvent = static_cast<QDragEnterEvent*>(pEvent);
|
QDragEnterEvent *pDragEvent = static_cast<QDragEnterEvent*>(pEvent);
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ bool WCreateTab::eventFilter(QObject *pObj, QEvent *pEvent)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (pEvent->type() == QEvent::Drop)
|
else if (pEvent->type() == QEvent::Drop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7927,7 +7927,7 @@
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x2BD13AB3" Type="string"/>
|
<Key ID="0x2BD13AB3" Type="string"/>
|
||||||
<Value Name="Unknown"/>
|
<Value Name="PakFile"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x2BD1C15B" Type="float"/>
|
<Key ID="0x2BD1C15B" Type="float"/>
|
||||||
|
@ -13561,10 +13561,6 @@
|
||||||
<Key ID="0x4A1E493B" Type="EmperorIngStage1Data"/>
|
<Key ID="0x4A1E493B" Type="EmperorIngStage1Data"/>
|
||||||
<Value Name="Data"/>
|
<Value Name="Data"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
|
||||||
<Key ID="0x4A1E493B" Type="UnknownStruct25"/>
|
|
||||||
<Value Name="Data"/>
|
|
||||||
</Element>
|
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x4A1E8961" Type="float"/>
|
<Key ID="0x4A1E8961" Type="float"/>
|
||||||
<Value Name="Unknown"/>
|
<Value Name="Unknown"/>
|
||||||
|
@ -14913,10 +14909,6 @@
|
||||||
<Key ID="0x5105FA2D" Type="EmperorIngStage2TentacleData"/>
|
<Key ID="0x5105FA2D" Type="EmperorIngStage2TentacleData"/>
|
||||||
<Value Name="Data"/>
|
<Value Name="Data"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
|
||||||
<Key ID="0x5105FA2D" Type="UnknownStruct18"/>
|
|
||||||
<Value Name="Data"/>
|
|
||||||
</Element>
|
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x5106FEB9" Type="bool"/>
|
<Key ID="0x5106FEB9" Type="bool"/>
|
||||||
<Value Name="Unknown"/>
|
<Value Name="Unknown"/>
|
||||||
|
@ -16003,7 +15995,7 @@
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x56E3CEEF" Type="float"/>
|
<Key ID="0x56E3CEEF" Type="float"/>
|
||||||
<Value Name="Fade Length"/>
|
<Value Name="Fadetime"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0x56EB17BB" Type="GenericCreatureStructE"/>
|
<Key ID="0x56EB17BB" Type="GenericCreatureStructE"/>
|
||||||
|
@ -32865,10 +32857,6 @@
|
||||||
<Key ID="0xB3C6398F" Type="EmperorIngStage1TentacleData"/>
|
<Key ID="0xB3C6398F" Type="EmperorIngStage1TentacleData"/>
|
||||||
<Value Name="Tentacle"/>
|
<Value Name="Tentacle"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
|
||||||
<Key ID="0xB3C6398F" Type="UnknownStruct19"/>
|
|
||||||
<Value Name="Tentacle"/>
|
|
||||||
</Element>
|
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0xB3DABF84" Type="DamageInfo"/>
|
<Key ID="0xB3DABF84" Type="DamageInfo"/>
|
||||||
<Value Name="HyperDamage"/>
|
<Value Name="HyperDamage"/>
|
||||||
|
@ -36643,7 +36631,7 @@
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0xC80FC827" Type="float"/>
|
<Key ID="0xC80FC827" Type="float"/>
|
||||||
<Value Name="Time"/>
|
<Value Name="PickupEffectLifetime"/>
|
||||||
</Element>
|
</Element>
|
||||||
<Element>
|
<Element>
|
||||||
<Key ID="0xC81690CB" Type="string"/>
|
<Key ID="0xC81690CB" Type="string"/>
|
||||||
|
|
Loading…
Reference in New Issue