2015-07-26 21:39:49 +00:00
# include "CScriptTemplate.h"
# include "CScriptObject.h"
# include "CMasterTemplate.h"
# include <iostream>
# include <string>
# include <Core/Log.h>
# include <Core/CResCache.h>
2015-09-18 05:53:53 +00:00
# include <Resource/CAnimSet.h>
2015-07-26 21:39:49 +00:00
2015-09-18 05:53:53 +00:00
CScriptTemplate : : CScriptTemplate ( CMasterTemplate * pMaster )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
mpMaster = pMaster ;
mVisible = true ;
2015-11-29 11:28:10 +00:00
mPreviewScale = 1.f ;
2015-09-18 05:53:53 +00:00
mVolumeShape = eNoShape ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CScriptTemplate : : ~ CScriptTemplate ( )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
for ( u32 iSet = 0 ; iSet < mPropertySets . size ( ) ; iSet + + )
delete mPropertySets [ iSet ] . pBaseStruct ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CMasterTemplate * CScriptTemplate : : MasterTemplate ( )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mpMaster ;
2015-07-26 21:39:49 +00:00
}
2015-11-27 18:49:20 +00:00
EGame CScriptTemplate : : Game ( )
{
return mpMaster - > GetGame ( ) ;
}
2015-11-24 06:08:31 +00:00
TString CScriptTemplate : : TemplateName ( s32 propCount ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
// Return original name if there is only one property set
// or if caller doesn't want to distinguish between sets
if ( ( NumPropertySets ( ) = = 1 ) | | ( propCount = = - 1 ) )
return mTemplateName ;
// Otherwise we return the template name with the set name appended
for ( auto it = mPropertySets . begin ( ) ; it ! = mPropertySets . end ( ) ; it + + )
if ( it - > pBaseStruct - > Count ( ) = = propCount )
return mTemplateName + " ( " + it - > SetName + " ) " ;
return mTemplateName + " (Invalid) " ;
2015-07-26 21:39:49 +00:00
}
2015-11-24 06:08:31 +00:00
TString CScriptTemplate : : PropertySetNameByCount ( s32 propCount ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
for ( auto it = mPropertySets . begin ( ) ; it ! = mPropertySets . end ( ) ; it + + )
if ( it - > pBaseStruct - > Count ( ) = = propCount )
return it - > SetName ;
return " " ;
2015-07-26 21:39:49 +00:00
}
2015-11-24 06:08:31 +00:00
TString CScriptTemplate : : PropertySetNameByIndex ( u32 index ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
if ( index < NumPropertySets ( ) )
return mPropertySets [ index ] . SetName ;
else
return " " ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
u32 CScriptTemplate : : NumPropertySets ( ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mPropertySets . size ( ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CScriptTemplate : : ERotationType CScriptTemplate : : RotationType ( ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mRotationType ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CScriptTemplate : : EScaleType CScriptTemplate : : ScaleType ( ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mScaleType ;
2015-07-26 21:39:49 +00:00
}
2015-11-29 11:28:10 +00:00
float CScriptTemplate : : PreviewScale ( ) const
{
return mPreviewScale ;
}
2015-09-18 05:53:53 +00:00
u32 CScriptTemplate : : ObjectID ( ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mObjectID ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
void CScriptTemplate : : SetVisible ( bool visible )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
mVisible = visible ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
bool CScriptTemplate : : IsVisible ( ) const
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return mVisible ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
void CScriptTemplate : : DebugPrintProperties ( int propCount )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
CStructTemplate * pTemp = BaseStructByCount ( propCount ) ;
if ( pTemp ) pTemp - > DebugPrintProperties ( " " ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
// ************ PROPERTY FETCHING ************
template < typename t , EPropertyType propType >
t TFetchProperty ( CPropertyStruct * pProperties , const TIDString & ID )
2015-07-26 21:39:49 +00:00
{
2015-11-24 06:08:31 +00:00
if ( ID . IsEmpty ( ) ) return nullptr ;
2015-09-18 05:53:53 +00:00
CPropertyBase * pProp = pProperties - > PropertyByIDString ( ID ) ;
2015-07-26 21:39:49 +00:00
2015-09-18 05:53:53 +00:00
if ( pProp & & ( pProp - > Type ( ) = = propType ) )
return static_cast < t > ( pProp ) ;
2015-07-26 21:39:49 +00:00
else
return nullptr ;
}
2015-09-18 05:53:53 +00:00
CStructTemplate * CScriptTemplate : : BaseStructByCount ( s32 propCount )
2015-07-26 21:39:49 +00:00
{
2015-09-21 10:30:24 +00:00
if ( mPropertySets . size ( ) = = 1 ) return mPropertySets [ 0 ] . pBaseStruct ;
2015-09-18 05:53:53 +00:00
for ( u32 iSet = 0 ; iSet < mPropertySets . size ( ) ; iSet + + )
if ( mPropertySets [ iSet ] . pBaseStruct - > Count ( ) = = propCount )
return mPropertySets [ iSet ] . pBaseStruct ;
2015-07-26 21:39:49 +00:00
2015-09-18 05:53:53 +00:00
return nullptr ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CStructTemplate * CScriptTemplate : : BaseStructByIndex ( u32 index )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
if ( index < NumPropertySets ( ) )
return mPropertySets [ index ] . pBaseStruct ;
2015-07-26 21:39:49 +00:00
else
return nullptr ;
}
2015-09-18 05:53:53 +00:00
EVolumeShape CScriptTemplate : : VolumeShape ( CScriptObject * pObj )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
if ( pObj - > Template ( ) ! = this )
{
Log : : Error ( pObj - > Template ( ) - > TemplateName ( ) + " instance somehow called VolumeShape() on " + TemplateName ( ) + " template " ) ;
return eInvalidShape ;
}
if ( mVolumeShape = = eConditionalShape )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
CPropertyBase * pProp = pObj - > Properties ( ) - > PropertyByIDString ( mVolumeConditionIDString ) ;
// Get value of the condition test property (only boolean, integral, and enum types supported)
int v ;
switch ( pProp - > Type ( ) )
{
case eBoolProperty :
v = ( static_cast < CBoolProperty * > ( pProp ) - > Get ( ) ? 1 : 0 ) ;
break ;
case eByteProperty :
v = ( int ) static_cast < CByteProperty * > ( pProp ) - > Get ( ) ;
break ;
case eShortProperty :
v = ( int ) static_cast < CShortProperty * > ( pProp ) - > Get ( ) ;
break ;
case eLongProperty :
v = ( int ) static_cast < CLongProperty * > ( pProp ) - > Get ( ) ;
break ;
2015-10-25 22:44:25 +00:00
case eEnumProperty : {
CEnumProperty * pEnumCast = static_cast < CEnumProperty * > ( pProp ) ;
CEnumTemplate * pEnumTemp = static_cast < CEnumTemplate * > ( pEnumCast - > Template ( ) ) ;
int index = static_cast < CEnumProperty * > ( pProp ) - > Get ( ) ;
v = pEnumTemp - > EnumeratorID ( index ) ;
break ;
}
2015-09-18 05:53:53 +00:00
}
// Test and check whether any of the conditions are true
for ( auto it = mVolumeConditions . begin ( ) ; it ! = mVolumeConditions . end ( ) ; it + + )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
if ( it - > Value = = v )
return it - > Shape ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
2015-11-24 06:08:31 +00:00
Log : : Error ( TemplateName ( ) + " instance " + TString : : HexString ( pObj - > InstanceID ( ) , true , true , 8 ) + " has unexpected volume shape value of " + TString : : HexString ( ( u32 ) v , true , true ) ) ;
2015-09-18 05:53:53 +00:00
return eInvalidShape ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
else return mVolumeShape ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CStringProperty * CScriptTemplate : : FindInstanceName ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CStringProperty * , eStringProperty > ( pProperties , mNameIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CVector3Property * CScriptTemplate : : FindPosition ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CVector3Property * , eVector3Property > ( pProperties , mPositionIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CVector3Property * CScriptTemplate : : FindRotation ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CVector3Property * , eVector3Property > ( pProperties , mRotationIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CVector3Property * CScriptTemplate : : FindScale ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CVector3Property * , eVector3Property > ( pProperties , mScaleIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CBoolProperty * CScriptTemplate : : FindActive ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CBoolProperty * , eBoolProperty > ( pProperties , mActiveIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
CPropertyStruct * CScriptTemplate : : FindLightParameters ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
return TFetchProperty < CPropertyStruct * , eStructProperty > ( pProperties , mLightParametersIDString ) ;
2015-07-26 21:39:49 +00:00
}
2015-11-26 09:05:26 +00:00
// todo: merge these four functions, they have near-identical code
2015-09-18 05:53:53 +00:00
CModel * CScriptTemplate : : FindDisplayModel ( CPropertyStruct * pProperties )
2015-07-26 21:39:49 +00:00
{
2015-09-18 05:53:53 +00:00
for ( auto it = mAssets . begin ( ) ; it ! = mAssets . end ( ) ; it + + )
{
2015-11-24 15:43:26 +00:00
if ( ( it - > AssetType ! = SEditorAsset : : eModel ) & & ( it - > AssetType ! = SEditorAsset : : eAnimParams ) ) continue ;
2015-09-18 05:53:53 +00:00
CResource * pRes = nullptr ;
// File
if ( it - > AssetSource = = SEditorAsset : : eFile )
{
2015-11-24 06:08:31 +00:00
TString path = " ../resources/ " + it - > AssetLocation ;
2015-09-18 05:53:53 +00:00
pRes = gResCache . GetResource ( path ) ;
}
// Property
else
{
CPropertyBase * pProp = pProperties - > PropertyByIDString ( it - > AssetLocation ) ;
if ( pProp - > Type ( ) = = eFileProperty )
{
CFileProperty * pFile = static_cast < CFileProperty * > ( pProp ) ;
pRes = pFile - > Get ( ) ;
}
2015-09-21 10:30:24 +00:00
else if ( pProp - > Type ( ) = = eAnimParamsProperty )
2015-09-18 05:53:53 +00:00
{
2015-09-21 10:30:24 +00:00
CAnimParamsProperty * pParams = static_cast < CAnimParamsProperty * > ( pProp ) ;
pRes = pParams - > Get ( ) . GetCurrentModel ( it - > ForceNodeIndex ) ;
2015-09-18 05:53:53 +00:00
}
}
// Verify resource exists + is correct type
2015-09-21 10:30:24 +00:00
if ( pRes & & ( pRes - > Type ( ) = = eModel ) )
return static_cast < CModel * > ( pRes ) ;
2015-09-18 05:53:53 +00:00
}
return nullptr ;
2015-07-26 21:39:49 +00:00
}
2015-11-24 15:43:26 +00:00
CTexture * CScriptTemplate : : FindBillboardTexture ( CPropertyStruct * pProperties )
{
for ( auto it = mAssets . begin ( ) ; it ! = mAssets . end ( ) ; it + + )
{
if ( it - > AssetType ! = SEditorAsset : : eBillboard ) continue ;
CResource * pRes = nullptr ;
// File
if ( it - > AssetSource = = SEditorAsset : : eFile )
{
TString path = " ../resources/ " + it - > AssetLocation ;
pRes = gResCache . GetResource ( path ) ;
}
// Property
else
{
CPropertyBase * pProp = pProperties - > PropertyByIDString ( it - > AssetLocation ) ;
if ( pProp - > Type ( ) = = eFileProperty )
{
CFileProperty * pFile = static_cast < CFileProperty * > ( pProp ) ;
pRes = pFile - > Get ( ) ;
}
}
// Verify resource exists + is correct type
if ( pRes & & ( pRes - > Type ( ) = = eTexture ) )
return static_cast < CTexture * > ( pRes ) ;
}
return nullptr ;
}
2015-09-26 22:55:14 +00:00
CCollisionMeshGroup * CScriptTemplate : : FindCollision ( CPropertyStruct * pProperties )
{
for ( auto it = mAssets . begin ( ) ; it ! = mAssets . end ( ) ; it + + )
{
2015-11-24 15:43:26 +00:00
if ( it - > AssetType ! = SEditorAsset : : eCollision ) continue ;
2015-09-26 22:55:14 +00:00
CResource * pRes = nullptr ;
// File
if ( it - > AssetSource = = SEditorAsset : : eFile )
{
2015-11-24 06:08:31 +00:00
TString path = " ../resources/ " + it - > AssetLocation ;
2015-09-26 22:55:14 +00:00
pRes = gResCache . GetResource ( path ) ;
}
// Property
else
{
CPropertyBase * pProp = pProperties - > PropertyByIDString ( it - > AssetLocation ) ;
if ( pProp - > Type ( ) = = eFileProperty )
{
CFileProperty * pFile = static_cast < CFileProperty * > ( pProp ) ;
pRes = pFile - > Get ( ) ;
}
}
// Verify resource exists + is correct type
if ( pRes & & ( pRes - > Type ( ) = = eCollisionMeshGroup ) )
return static_cast < CCollisionMeshGroup * > ( pRes ) ;
}
return nullptr ;
}
2015-11-26 09:05:26 +00:00
bool CScriptTemplate : : HasInGameModel ( CPropertyStruct * pProperties )
{
for ( auto it = mAssets . begin ( ) ; it ! = mAssets . end ( ) ; it + + )
{
if ( ( it - > AssetType ! = SEditorAsset : : eModel ) & & ( it - > AssetType ! = SEditorAsset : : eAnimParams ) ) continue ;
if ( it - > AssetSource = = SEditorAsset : : eFile ) continue ;
CResource * pRes = nullptr ;
CPropertyBase * pProp = pProperties - > PropertyByIDString ( it - > AssetLocation ) ;
if ( pProp - > Type ( ) = = eFileProperty )
{
CFileProperty * pFile = static_cast < CFileProperty * > ( pProp ) ;
pRes = pFile - > Get ( ) ;
}
else if ( pProp - > Type ( ) = = eAnimParamsProperty )
{
CAnimParamsProperty * pParams = static_cast < CAnimParamsProperty * > ( pProp ) ;
pRes = pParams - > Get ( ) . GetCurrentModel ( it - > ForceNodeIndex ) ;
}
// Verify resource exists + is correct type
if ( pRes & & ( pRes - > Type ( ) = = eModel ) )
return true ;
}
return false ;
}
2015-09-18 05:53:53 +00:00
bool CScriptTemplate : : HasPosition ( )
2015-07-26 21:39:49 +00:00
{
2015-11-24 06:08:31 +00:00
return ( ! mPositionIDString . IsEmpty ( ) ) ;
2015-07-26 21:39:49 +00:00
}
2015-09-18 05:53:53 +00:00
// ************ OBJECT TRACKING ************
2015-07-26 21:39:49 +00:00
u32 CScriptTemplate : : NumObjects ( ) const
{
return mObjectList . size ( ) ;
}
const std : : list < CScriptObject * > & CScriptTemplate : : ObjectList ( ) const
{
return mObjectList ;
}
void CScriptTemplate : : AddObject ( CScriptObject * pObject )
{
mObjectList . push_back ( pObject ) ;
}
void CScriptTemplate : : RemoveObject ( CScriptObject * pObject )
{
for ( auto it = mObjectList . begin ( ) ; it ! = mObjectList . end ( ) ; it + + )
{
if ( * it = = pObject )
{
mObjectList . erase ( it ) ;
break ;
}
}
}
void CScriptTemplate : : SortObjects ( )
{
// todo: make this function take layer names into account
mObjectList . sort ( [ ] ( CScriptObject * pA , CScriptObject * pB ) - > bool {
return ( pA - > InstanceID ( ) < pB - > InstanceID ( ) ) ;
} ) ;
}