Improved DKCR game mode + a few other assorted fixes

This commit is contained in:
parax0 2016-02-17 01:55:19 -07:00
parent 9eaf537611
commit c36c09a674
10 changed files with 90 additions and 10 deletions

View File

@ -233,7 +233,7 @@ namespace CompressionUtil
TotalOut = Size; TotalOut = Size;
} }
// If it's not smaller, write the compressed data // If it IS smaller, write the compressed data
else else
{ {
// Write new compressed size + data to destination // Write new compressed size + data to destination

View File

@ -33,6 +33,7 @@ bool CAreaAttributes::IsSkyEnabled() const
case eEchoes: case eEchoes:
case eCorruptionProto: case eCorruptionProto:
case eCorruption: case eCorruption:
case eReturns:
return static_cast<TBoolProperty*>(pBaseStruct->PropertyByIndex(1))->Get(); return static_cast<TBoolProperty*>(pBaseStruct->PropertyByIndex(1))->Get();
default: default:
return false; return false;
@ -51,6 +52,7 @@ CModel* CAreaAttributes::SkyModel() const
case eEchoes: case eEchoes:
case eCorruptionProto: case eCorruptionProto:
case eCorruption: case eCorruption:
case eReturns:
return (CModel*) static_cast<TFileProperty*>(pBaseStruct->PropertyByID(0xD208C9FA))->Get().Load(); return (CModel*) static_cast<TFileProperty*>(pBaseStruct->PropertyByID(0xD208C9FA))->Get().Load();
default: default:
return nullptr; return nullptr;

View File

@ -165,7 +165,9 @@ IPropertyTemplate* CTemplateLoader::LoadProperty(XMLElement *pElem, CScriptTempl
LoadProperties(pProperties, pScript, pStruct, rkTemplateName); LoadProperties(pProperties, pScript, pStruct, rkTemplateName);
} }
if (IsNewProperty)
CMasterTemplate::AddProperty(pProp, mMasterDir + rkTemplateName); CMasterTemplate::AddProperty(pProp, mMasterDir + rkTemplateName);
return pProp; return pProp;
} }

View File

@ -80,6 +80,54 @@ void CScriptObject::SetLayer(CScriptLayer *pLayer)
} }
} }
bool CScriptObject::HasNearVisibleActivation() const
{
/* This function is used to check whether an inactive DKCR object should render in game mode. DKCR deactivates a lot of
* decorative actors when the player isn't close to them as an optimization. This means a lot of them are inactive by
* default but should render in game mode anyway. To get around this, we'll check the links to find out whether this
* instance has a "Near Visible" activation, which is typically done via a trigger that activates the object on
* InternalState04 (usually through a relay). */
std::list<CScriptObject*> Relays;
for (u32 iLink = 0; iLink < mInConnections.size(); iLink++)
{
const SLink& rkLink = mInConnections[iLink];
// Check for trigger activation
if (rkLink.State == 0x49533034) // "IS04"
{
if ( (rkLink.Message == 0x41435456) || // "ACTV"
(ObjectTypeID() == 0x53524C59 && rkLink.Message == 0x4143544E) ) // If type is "SRLY" and message is "ACTN"
{
CScriptObject *pObj = mpArea->GetInstanceByID(rkLink.ObjectID);
if (pObj->ObjectTypeID() == 0x54524752) // "TRGR"
return true;
}
}
// Check for relay activation
else if (rkLink.State == 0x524C4159) // "RLAY"
{
if ( (rkLink.Message == 0x41435456) || // "ACTV"
(ObjectTypeID() == 0x53524C59 && rkLink.Message == 0x4143544E) ) // If type is "SRLY" and message is "ACTN"
{
CScriptObject *pObj = mpArea->GetInstanceByID(rkLink.ObjectID);
if (pObj->ObjectTypeID() == 0x53524C59) // "SRLY"
Relays.push_back(pObj);
}
}
}
// Check whether any of the relays have a near visible activation
for (auto it = Relays.begin(); it != Relays.end(); it++)
if ((*it)->HasNearVisibleActivation())
return true;
return false;
}
// ************ GETTERS ************ // ************ GETTERS ************
IProperty* CScriptObject::PropertyByIndex(u32 index) const IProperty* CScriptObject::PropertyByIndex(u32 index) const
{ {

View File

@ -51,6 +51,7 @@ public:
void EvaluateVolume(); void EvaluateVolume();
bool IsEditorProperty(IProperty *pProp); bool IsEditorProperty(IProperty *pProp);
void SetLayer(CScriptLayer *pLayer); void SetLayer(CScriptLayer *pLayer);
bool HasNearVisibleActivation() const;
CScriptTemplate* Template() const; CScriptTemplate* Template() const;
CMasterTemplate* MasterTemplate() const; CMasterTemplate* MasterTemplate() const;

View File

@ -12,6 +12,7 @@
CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pObject) CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pObject)
: CSceneNode(pScene, pParent) : CSceneNode(pScene, pParent)
, mGameModeVisibility(eUntested)
{ {
mpVolumePreviewNode = nullptr; mpVolumePreviewNode = nullptr;
mHasVolumePreview = false; mHasVolumePreview = false;
@ -113,7 +114,10 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
// If we're in game mode, then override other visibility settings. // If we're in game mode, then override other visibility settings.
if (ViewInfo.GameMode) if (ViewInfo.GameMode)
{ {
if ( (!mpInstance->IsActive() && Template()->Game() != eReturns) || !mpInstance->HasInGameModel()) if (mGameModeVisibility == eUntested)
TestGameModeVisibility();
if (mGameModeVisibility != eVisible)
return; return;
} }
@ -568,6 +572,17 @@ void CScriptNode::GeneratePosition()
} }
} }
void CScriptNode::TestGameModeVisibility()
{
// Don't render if we don't have an ingame model, or if this is the Prime series and the instance is not active.
if ((Template()->Game() < eReturns && !mpInstance->IsActive()) || !mpInstance->HasInGameModel())
mGameModeVisibility = eNotVisible;
// If this is Returns, only render if the instance is active OR if it has a near visible activation.
else
mGameModeVisibility = (mpInstance->IsActive() || mpInstance->HasNearVisibleActivation()) ? eVisible : eNotVisible;
}
CColor CScriptNode::WireframeColor() const CColor CScriptNode::WireframeColor() const
{ {
return CColor::Integral(12, 135, 194); return CColor::Integral(12, 135, 194);

View File

@ -24,6 +24,11 @@ class CScriptNode : public CSceneNode
CLightParameters *mpLightParameters; CLightParameters *mpLightParameters;
enum EGameModeVisibility
{
eVisible, eNotVisible, eUntested
} mGameModeVisibility;
public: public:
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0); CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
ENodeType NodeType(); ENodeType NodeType();
@ -43,6 +48,7 @@ public:
void PropertyModified(IProperty *pProp); void PropertyModified(IProperty *pProp);
void UpdatePreviewVolume(); void UpdatePreviewVolume();
void GeneratePosition(); void GeneratePosition();
void TestGameModeVisibility();
CScriptObject* Object() const; CScriptObject* Object() const;
CScriptTemplate* Template() const; CScriptTemplate* Template() const;
CScriptExtra* Extra() const; CScriptExtra* Extra() const;

View File

@ -185,6 +185,8 @@ void CStartWindow::on_LaunchWorldEditorButton_clicked()
{ {
mpWorld->SetAreaLayerInfo(pArea, mSelectedAreaIndex); mpWorld->SetAreaLayerInfo(pArea, mSelectedAreaIndex);
mpWorldEditor->SetArea(mpWorld, pArea, mSelectedAreaIndex); mpWorldEditor->SetArea(mpWorld, pArea, mSelectedAreaIndex);
gResCache.Clean();
mpWorldEditor->setWindowModality(Qt::WindowModal); mpWorldEditor->setWindowModality(Qt::WindowModal);
mpWorldEditor->showMaximized(); mpWorldEditor->showMaximized();
@ -194,8 +196,6 @@ void CStartWindow::on_LaunchWorldEditorButton_clicked()
if (HasErrors) if (HasErrors)
ErrorDialog.exec(); ErrorDialog.exec();
gResCache.Clean();
} }
} }
} }

View File

@ -624,7 +624,7 @@
<property ID="0x0F37E756" name="Unknown"/> <property ID="0x0F37E756" name="Unknown"/>
<property ID="0x0F3E29EB" name="Unknown"/> <property ID="0x0F3E29EB" name="Unknown"/>
<property ID="0x0F4CB02A" name="Unknown"/> <property ID="0x0F4CB02A" name="Unknown"/>
<property ID="0x0F4D73B7" name="Unknown"/> <property ID="0x0F4D73B7" name="DigitalGuardianHeadData"/>
<property ID="0x0F52074C" name="Unknown"/> <property ID="0x0F52074C" name="Unknown"/>
<property ID="0x0F5765C9" name="Unknown"/> <property ID="0x0F5765C9" name="Unknown"/>
<property ID="0x0F598739" name="Radius?"/> <property ID="0x0F598739" name="Radius?"/>

View File

@ -3,10 +3,16 @@
<name>Timer</name> <name>Timer</name>
<properties> <properties>
<property ID="0x00" name="Name" type="string"/> <property ID="0x00" name="Name" type="string"/>
<property ID="0x01" name="Start time" type="float"/> <property ID="0x01" name="Start Time" type="float"/>
<property ID="0x02" name="Max random addition" type="float"/> <property ID="0x02" name="Max Random Delay" type="float">
<property ID="0x03" name="Reset on Zero" type="bool"/> <description>A random value between 0 and this number will be added to the timer's start time.</description>
<property ID="0x04" name="Start immediately" type="bool"/> </property>
<property ID="0x03" name="Loop" type="bool">
<description>When the timer reaches 0, it will reset back to its start time and start ticking again.</description>
</property>
<property ID="0x04" name="Auto-Start" type="bool">
<description>The timer will start ticking immediately on load, without waiting for a script message to start it.</description>
</property>
<property ID="0x05" name="Active" type="bool"/> <property ID="0x05" name="Active" type="bool"/>
</properties> </properties>
<states/> <states/>