diff --git a/resources/VolumeCylinderLarge.cmdl b/resources/VolumeCylinderLarge.cmdl deleted file mode 100644 index 1955b3e4..00000000 Binary files a/resources/VolumeCylinderLarge.cmdl and /dev/null differ diff --git a/src/Common/TString.h b/src/Common/TString.h index 5ff5ed4f..93c776cd 100644 --- a/src/Common/TString.h +++ b/src/Common/TString.h @@ -319,6 +319,11 @@ public: memcpy(pOut + 8, &part2, 8); } + inline float ToFloat() const + { + return std::stof(mInternalString, nullptr); + } + inline _TStdString ToStdString() const { return mInternalString; diff --git a/src/Core/Resource/Cooker/CTemplateWriter.cpp b/src/Core/Resource/Cooker/CTemplateWriter.cpp index 26081dda..ea9f75cd 100644 --- a/src/Core/Resource/Cooker/CTemplateWriter.cpp +++ b/src/Core/Resource/Cooker/CTemplateWriter.cpp @@ -320,7 +320,6 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString& case eAxisAlignedBoxShape: return "AxisAlignedBox"; case eEllipsoidShape: return "Ellipsoid"; case eCylinderShape: return "Cylinder"; - case eCylinderLargeShape: return "CylinderLarge"; case eConditionalShape: return "Conditional"; default: return "INVALID"; } @@ -328,6 +327,9 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString& pVolume->SetAttribute("shape", *GetVolumeString(pTemp->mVolumeShape)); + if (pTemp->mVolumeScale != 1.f) + pVolume->SetAttribute("scale", pTemp->mVolumeScale); + if (pTemp->mVolumeShape == eConditionalShape) { pVolume->SetAttribute("propertyID", *pTemp->mVolumeConditionIDString); @@ -355,6 +357,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString& XMLElement *pCondition = scriptXML.NewElement("condition"); pCondition->SetAttribute("value", *strVal); pCondition->SetAttribute("shape", *GetVolumeString(it->Shape)); + if (it->Scale != 1.f) pCondition->SetAttribute("scale", it->Scale); pVolume->LinkEndChild(pCondition); } } diff --git a/src/Core/Resource/Factory/CTemplateLoader.cpp b/src/Core/Resource/Factory/CTemplateLoader.cpp index cb2caf99..8b207637 100644 --- a/src/Core/Resource/Factory/CTemplateLoader.cpp +++ b/src/Core/Resource/Factory/CTemplateLoader.cpp @@ -437,7 +437,6 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(tinyxml2::XMLDocument *pDoc if (strcmp(kpType, "AxisAlignedBox") == 0) return eAxisAlignedBoxShape; if (strcmp(kpType, "Ellipsoid") == 0) return eEllipsoidShape; if (strcmp(kpType, "Cylinder") == 0) return eCylinderShape; - if (strcmp(kpType, "CylinderLarge") == 0) return eCylinderLargeShape; if (strcmp(kpType, "Conditional") == 0) return eConditionalShape; return eInvalidShape; }; @@ -447,6 +446,11 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(tinyxml2::XMLDocument *pDoc if (kpShape) pScript->mVolumeShape = GetVolumeType(kpShape); + const char *kpScale = pVolume->Attribute("scale"); + + if (kpScale) + pScript->mVolumeScale = TString(kpScale).ToFloat(); + // Conditional if (pScript->mVolumeShape == eConditionalShape) { @@ -474,6 +478,12 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(tinyxml2::XMLDocument *pDoc else condition.Value = TString(kpConditionValue).ToInt32(); + const char *kpConditionScale = pCondition->Attribute("scale"); + if (kpConditionScale) + condition.Scale = TString(kpConditionScale).ToFloat(); + else + condition.Scale = 1.f; + pScript->mVolumeConditions.push_back(condition); } diff --git a/src/Core/Resource/Script/CScriptObject.cpp b/src/Core/Resource/Script/CScriptObject.cpp index ceef3ba0..b6b0746d 100644 --- a/src/Core/Resource/Script/CScriptObject.cpp +++ b/src/Core/Resource/Script/CScriptObject.cpp @@ -39,6 +39,7 @@ void CScriptObject::EvaluateProperties() mpLightParameters = mpTemplate->FindLightParameters(mpProperties); mHasInGameModel = mpTemplate->HasInGameModel(mpProperties); mVolumeShape = mpTemplate->VolumeShape(this); + mVolumeScale = mpTemplate->VolumeScale(this); EvaluateDisplayModel(); EvaluateBillboard(); EvaluateCollisionModel(); @@ -224,3 +225,8 @@ EVolumeShape CScriptObject::VolumeShape() const { return mVolumeShape; } + +float CScriptObject::VolumeScale() const +{ + return mVolumeScale; +} diff --git a/src/Core/Resource/Script/CScriptObject.h b/src/Core/Resource/Script/CScriptObject.h index 98dc195d..ce75dda0 100644 --- a/src/Core/Resource/Script/CScriptObject.h +++ b/src/Core/Resource/Script/CScriptObject.h @@ -37,6 +37,7 @@ class CScriptObject bool mHasInGameModel; EVolumeShape mVolumeShape; + float mVolumeScale; public: CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate); @@ -79,6 +80,7 @@ public: CTexture* GetBillboard() const; CCollisionMeshGroup* GetCollision() const; EVolumeShape VolumeShape() const; + float VolumeScale() const; }; #endif // CSCRIPTOBJECT_H diff --git a/src/Core/Resource/Script/CScriptTemplate.cpp b/src/Core/Resource/Script/CScriptTemplate.cpp index 31c7926f..77ae04ad 100644 --- a/src/Core/Resource/Script/CScriptTemplate.cpp +++ b/src/Core/Resource/Script/CScriptTemplate.cpp @@ -13,6 +13,7 @@ CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster) mpMaster = pMaster; mVisible = true; mPreviewScale = 1.f; + mVolumeScale = 1.f; mVolumeShape = eNoShape; } @@ -145,6 +146,35 @@ EVolumeShape CScriptTemplate::VolumeShape(CScriptObject *pObj) return eInvalidShape; } + if (mVolumeShape == eConditionalShape) + { + s32 index = CheckVolumeConditions(pObj, true); + if (index == -1) return eInvalidShape; + else return mVolumeConditions[index].Shape; + } + else return mVolumeShape; +} + +float CScriptTemplate::VolumeScale(CScriptObject *pObj) +{ + if (pObj->Template() != this) + { + Log::Error(pObj->Template()->TemplateName() + " instance somehow called VolumeScale() on " + TemplateName() + " template"); + return -1; + } + + if (mVolumeShape == eConditionalShape) + { + s32 index = CheckVolumeConditions(pObj, false); + if (index == -1) return mVolumeScale; + else return mVolumeConditions[index].Scale; + } + else return mVolumeScale; +} + +s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors) +{ + // Private function if (mVolumeShape == eConditionalShape) { CPropertyBase *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString); @@ -179,17 +209,17 @@ EVolumeShape CScriptTemplate::VolumeShape(CScriptObject *pObj) } // Test and check whether any of the conditions are true - for (auto it = mVolumeConditions.begin(); it != mVolumeConditions.end(); it++) + for (u32 iCon = 0; iCon < mVolumeConditions.size(); iCon++) { - if (it->Value == v) - return it->Shape; + if (mVolumeConditions[iCon].Value == v) + return iCon; } - Log::Error(TemplateName() + " instance " + TString::HexString(pObj->InstanceID(), true, true, 8) + " has unexpected volume shape value of " + TString::HexString((u32) v, true, true)); - return eInvalidShape; + if (LogErrors) + Log::Error(pObj->Template()->TemplateName() + " instance " + TString::HexString(pObj->InstanceID(), true, true, 8) + " has unexpected volume shape value of " + TString::HexString((u32) v, true, true)); } - else return mVolumeShape; + return -1; } CStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties) diff --git a/src/Core/Resource/Script/CScriptTemplate.h b/src/Core/Resource/Script/CScriptTemplate.h index a57d0d04..8eece8a7 100644 --- a/src/Core/Resource/Script/CScriptTemplate.h +++ b/src/Core/Resource/Script/CScriptTemplate.h @@ -81,11 +81,13 @@ private: // Preview Volume EVolumeShape mVolumeShape; + float mVolumeScale; TIDString mVolumeConditionIDString; struct SVolumeCondition { int Value; EVolumeShape Shape; + float Scale; }; std::vector mVolumeConditions; @@ -111,6 +113,7 @@ public: CStructTemplate* BaseStructByCount(s32 propCount); CStructTemplate* BaseStructByIndex(u32 index); EVolumeShape VolumeShape(CScriptObject *pObj); + float VolumeScale(CScriptObject *pObj); CStringProperty* FindInstanceName(CPropertyStruct *pProperties); CVector3Property* FindPosition(CPropertyStruct *pProperties); CVector3Property* FindRotation(CPropertyStruct *pProperties); @@ -129,6 +132,9 @@ public: void AddObject(CScriptObject *pObject); void RemoveObject(CScriptObject *pObject); void SortObjects(); + +private: + s32 CheckVolumeConditions(CScriptObject *pObj, bool LogErrors); }; #endif // CSCRIPTTEMPLATE_H diff --git a/src/Core/Resource/Script/EVolumeShape.h b/src/Core/Resource/Script/EVolumeShape.h index a5e187c0..8eda784c 100644 --- a/src/Core/Resource/Script/EVolumeShape.h +++ b/src/Core/Resource/Script/EVolumeShape.h @@ -8,7 +8,6 @@ enum EVolumeShape eBoxShape, eEllipsoidShape, eCylinderShape, - eCylinderLargeShape, eConditionalShape, eInvalidShape }; diff --git a/src/Core/Scene/CScriptNode.cpp b/src/Core/Scene/CScriptNode.cpp index 2f24cb47..5c21d26b 100644 --- a/src/Core/Scene/CScriptNode.cpp +++ b/src/Core/Scene/CScriptNode.cpp @@ -14,6 +14,7 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje : CSceneNode(pScene, pParent) { mpVolumePreviewNode = nullptr; + mHasVolumePreview = false; // Evaluate instance mpInstance = pObject; @@ -42,29 +43,35 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje // Create preview volume node mHasValidPosition = pTemp->HasPosition(); - mHasVolumePreview = (pTemp->ScaleType() == CScriptTemplate::eScaleVolume); - if (mHasVolumePreview) + if (pTemp->ScaleType() == CScriptTemplate::eScaleVolume) { EVolumeShape shape = mpInstance->VolumeShape(); TResPtr pVolumeModel = nullptr; - if ((shape == eAxisAlignedBoxShape) || (shape == eBoxShape)) + switch (shape) + { + case eAxisAlignedBoxShape: + case eBoxShape: pVolumeModel = gResCache.GetResource("../resources/VolumeBox.cmdl"); + break; - else if (shape == eEllipsoidShape) + case eEllipsoidShape: pVolumeModel = gResCache.GetResource("../resources/VolumeSphere.cmdl"); + break; - else if (shape == eCylinderShape) + case eCylinderShape: pVolumeModel = gResCache.GetResource("../resources/VolumeCylinder.cmdl"); + break; + } - else if (shape == eCylinderLargeShape) - pVolumeModel = gResCache.GetResource("../resources/VolumeCylinderLarge.cmdl"); + mHasVolumePreview = (pVolumeModel != nullptr); - if (pVolumeModel) + if (mHasVolumePreview) { mpVolumePreviewNode = new CModelNode(pScene, this, pVolumeModel); mpVolumePreviewNode->SetInheritance(true, (shape != eAxisAlignedBoxShape), true); + mpVolumePreviewNode->SetScale(mpInstance->VolumeScale()); mpVolumePreviewNode->ForceAlphaEnabled(true); } } diff --git a/templates/mp2/Script/SafeZone.xml b/templates/mp2/Script/SafeZone.xml index 967cde12..290d8e59 100644 --- a/templates/mp2/Script/SafeZone.xml +++ b/templates/mp2/Script/SafeZone.xml @@ -171,7 +171,7 @@ volume - +