diff --git a/stepmania/src/ActorUtil.cpp b/stepmania/src/ActorUtil.cpp index 736f161923..320cdcaf55 100644 --- a/stepmania/src/ActorUtil.cpp +++ b/stepmania/src/ActorUtil.cpp @@ -316,6 +316,24 @@ static void MergeActorXML( XNode *pChild, const XNode *pParent ) namespace { + void AnnotateXMLTree( XNode *pNode, const RString &sFile ) + { + RString sDir = Dirname( sFile ); + + vector queue; + queue.push_back( pNode ); + while( !queue.empty() ) + { + pNode = queue.back(); + queue.pop_back(); + FOREACH_Child( pNode, pChild ) + queue.push_back( pChild ); + + pNode->AppendAttr( "_Dir", sDir ); + } + + } + XNode *LoadXNodeFromLuaShowErrors( const RString &sFile ) { RString sScript; @@ -401,6 +419,7 @@ Actor* ActorUtil::MakeActor( const RString &sPath_, const XNode *pParent, Actor } XmlFileUtil::CompileXNodeTree( &xml, sPath ); + AnnotateXMLTree( &xml, sPath ); MergeActorXML( &xml, pParent ); return ActorUtil::LoadFromNode( sDir, &xml ); } @@ -440,6 +459,26 @@ Actor* ActorUtil::MakeActor( const RString &sPath_, const XNode *pParent, Actor } } +bool ActorUtil::GetAttrPath( const XNode *pNode, const RString &sName, RString &sOut ) +{ + if( !pNode->GetAttrValue(sName, sOut) ) + return false; + + bool bIsRelativePath = sOut.Left(1) != "/"; + if( bIsRelativePath ) + { + RString sDir; + if( !pNode->GetAttrValue("_Dir", sDir) ) + { + LOG->Warn( "Relative path \"%s\", but path is unknown", sOut.c_str() ); + return false; + } + sOut = sDir+sOut; + } + + return true; +} + apActorCommands ActorUtil::ParseActorCommands( const RString &sCommands, const RString &sName ) { Lua *L = LUA->Get(); diff --git a/stepmania/src/ActorUtil.h b/stepmania/src/ActorUtil.h index 81f0bb48de..90789270c0 100644 --- a/stepmania/src/ActorUtil.h +++ b/stepmania/src/ActorUtil.h @@ -71,6 +71,7 @@ namespace ActorUtil // Return a Sprite, BitmapText, or Model depending on the file type Actor* LoadFromNode( const RString& sAniDir, const XNode* pNode, Actor *pParentActor = NULL ); Actor* MakeActor( const RString &sPath, const XNode *pParent = NULL, Actor *pParentActor = NULL ); + bool GetAttrPath( const XNode *pNode, const RString &sName, RString &sOut ); void ResolvePath( RString &sPath, const RString &sName );