diff --git a/src/Actor.cpp b/src/Actor.cpp index 25df41bd1c..39fb4ec406 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -193,6 +193,7 @@ Actor::Actor( const Actor &cpy ): #define CPY(x) x = cpy.x CPY( m_sName ); + CPY(alias_); CPY( m_pParent ); CPY( m_FakeParent ); CPY( m_pLuaInstance ); @@ -272,6 +273,7 @@ Actor &Actor::operator=(Actor other) using std::swap; #define SWAP(x) swap(x, other.x) SWAP( m_sName ); + SWAP(alias_); SWAP( m_pParent ); SWAP( m_FakeParent ); SWAP( m_pLuaInstance ); @@ -336,6 +338,14 @@ Actor &Actor::operator=(Actor other) return *this; } + +bool Actor::IsAlias(const std::string& name) { + if (alias_.empty()) { + return false; + } + return name == alias_; +} + /* XXX: This calls InitCommand, which must happen after all other * initialization (eg. ActorFrame loading children). However, it * also loads input variables, which should happen first. The diff --git a/src/Actor.h b/src/Actor.h index 76569ad0ef..66719d2793 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -297,10 +297,16 @@ public: * @brief Retrieve the Actor's name. * @return the Actor's name. */ const RString &GetName() const { return m_sName; } + const std::string& GetAlias() { return alias_; } + + // IsAlias checks first if the Actor's alias isn't empty, and if it isn't, + // does a simple compare against the provided name. + bool IsAlias(const std::string& name); /** * @brief Set the Actor's name to a new one. * @param sName the new name for the Actor. */ virtual void SetName( const RString &sName ) { m_sName = sName; } + virtual void SetAlias(const std::string alias) { alias_ = alias; } /** * @brief Give this Actor a new parent. * @param pParent the new parent Actor. */ @@ -631,6 +637,13 @@ public: protected: /** @brief the name of the Actor. */ RString m_sName; + + // Alias is an alternate name for the actor. The name of the actor is + // allowed to be empty, whereas if the alias is empty, it is ignored. The + // point of the alias is to help maintain backward compatability with lua + // in case an actor name changes + std::string alias_; + /** @brief the current parent of this Actor if it exists. */ Actor *m_pParent; // m_FakeParent exists to provide a way to render the actor inside another's diff --git a/src/ActorFrame.cpp b/src/ActorFrame.cpp index 460332d55b..dc4e5c6c1e 100644 --- a/src/ActorFrame.cpp +++ b/src/ActorFrame.cpp @@ -171,8 +171,9 @@ Actor* ActorFrame::GetChild( const RString &sName ) { for (Actor *a : m_SubActors) { - if( a->GetName() == sName ) + if (a->GetName() == sName || a->IsAlias(sName)) { return a; + } } return nullptr; } @@ -411,7 +412,7 @@ void ActorFrame::PushChildTable(lua_State* L, const RString &sName) int found= 0; for (Actor *a: m_SubActors) { - if(a->GetName() == sName) + if (a->GetName() == sName || a->IsAlias(sName)) { if (found == 0) { diff --git a/src/EditModePlayerManager.cpp b/src/EditModePlayerManager.cpp index 3dc671421e..2c3d905344 100644 --- a/src/EditModePlayerManager.cpp +++ b/src/EditModePlayerManager.cpp @@ -23,6 +23,11 @@ void EditModePlayerManager::AddPlayers(const NoteData& note_data) { player->Init("Player", GAMESTATE->m_pPlayerState[pn], nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); player.Load(note_data); + // We set the actor alias here instead of the name to maintain + // backward compatability with scripted stepcharts that expect + // the Player's actor frame to be unnamed. + player->SetAlias("Player" + PlayerNumberToString(pn)); + player->CacheAllUsedNoteSkins(); GAMESTATE->m_pPlayerState[pn]->m_PlayerController = PC_HUMAN; player->SetY(SCREEN_CENTER_Y);