@@ -54,25 +54,39 @@ void spawnToyota() {
5454 toyotaGO->get_transform ()->set_localScale (::UnityEngine::Vector3 (0.4 , 0.4 , 0.4 ));
5555}
5656
57- void spawnTeapotOnNotes () {
57+ UnityW<UnityEngine::GameObject> getTeapotGO () {
5858 static UnityW<UnityEngine::GameObject> teapotGO;
59+
5960 if (!teapotGO) {
6061 teapotGO = Flair::Assets::loadModel (" /storage/emulated/0/ModData/com.beatgames.beatsaber/Mods/Flair/teapot.glb" );
61- if (!teapotGO) return ;
62+ if (!teapotGO) return nullptr ;
6263 teapotGO->set_name (" Teapot" );
6364 teapotGO->SetActive (false );
6465 UnityEngine::GameObject::DontDestroyOnLoad (teapotGO);
6566 }
66-
67+
68+ return teapotGO;
69+ }
70+
71+ void spawnTeapotOnGameObject (UnityEngine::GameObject* go) {
72+ UnityW<UnityEngine::GameObject> teapotGO = getTeapotGO ();
73+ if (!teapotGO) return ;
74+
75+ if (go->get_transform ()->Find (" Teapot(Clone)" )) return ;
76+
77+ PaperLogger.info (" Instantiating teapot on '{}'" , go->get_name ());
78+ UnityW<UnityEngine::GameObject> teapotCloneGO = UnityEngine::GameObject::Instantiate (teapotGO, go->get_transform (), false );
79+ if (!teapotCloneGO) {PaperLogger.error (" Failed instantiating teapot" ); return ;}
80+ teapotCloneGO->SetActive (true );
81+ }
82+
83+ void spawnTeapotOnNotes () {
6784 float startTime = UnityEngine::Time::get_realtimeSinceStartup ();
6885
6986 ArrayW<UnityEngine::GameObject*> everyGO = UnityEngine::GameObject::FindObjectsOfType<UnityEngine::GameObject*>();
7087 for (UnityEngine::GameObject* go : everyGO) {
7188 if (!(go->get_name ()->StartsWith (" Note " ) || go->get_name () == " NoteCube" )) continue ;
72- if (go->get_transform ()->Find (" Teapot(Clone)" )) continue ;
73- PaperLogger.info (" Instancing teapot onto '{}'" , go->get_name ());
74- UnityEngine::GameObject* teapotCloneGO = UnityEngine::GameObject::Instantiate (teapotGO, go->get_transform (), false );
75- teapotCloneGO->SetActive (true );
89+ spawnTeapotOnGameObject (go);
7690 }
7791
7892 float endTime = UnityEngine::Time::get_realtimeSinceStartup ();
@@ -156,6 +170,17 @@ MAKE_HOOK_MATCH(SillyHook, &UnityEngine::GameObject::set_name, void, UnityEngine
156170 PaperLogger.info (" Set GameObject name to '{}'" , string);
157171}
158172
173+ MAKE_HOOK_NO_CATCH (AwakeFromLoad_Hook, 0x0 , void ,
174+ void * GameObjectPtr_this, uint32_t AwakeFromLoadMode_param_1
175+ ) {
176+ AwakeFromLoad_Hook (GameObjectPtr_this, AwakeFromLoadMode_param_1);
177+ UnityEngine::GameObject* self = (UnityEngine::GameObject*)UnityEngine::Object::FindObjectFromInstanceID (*(int *)( (char *)GameObjectPtr_this + 8 )).ptr ();
178+
179+ if (UnityEngine::Object::IsPersistent (self)) return ; // Can't instantiate on Unity prefabs
180+ if (!(self->get_name ()->StartsWith (" Note " ) || self->get_name () == " NoteCube" )) return ;
181+ BSML::MainThreadScheduler::ScheduleAfterTime (1 , [self](){spawnTeapotOnGameObject (self);}); // Game doesn't really like it when you start doing complicated things in the AwakeFromLoad method
182+ }
183+
159184// Called at the early stages of game loading
160185MOD_EXTERN_FUNC void setup (CModInfo *info) noexcept {
161186 *info = modInfo.to_c ();
@@ -183,5 +208,13 @@ MOD_EXTERN_FUNC void late_load() noexcept {
183208 INSTALL_HOOK (PaperLogger, AssimpTestHook);
184209 INSTALL_HOOK (PaperLogger, SillyHook);
185210
211+ uintptr_t libunity = baseAddr (" libunity.so" );
212+ PaperLogger.info (" Found libunity: {}" , libunity);
213+ if (!libunity) {PaperLogger.error (" Could not find libunity" ); return ;}
214+ uintptr_t AwakeFromLoad = findPattern (libunity, " fe 0f 1e f8 f4 4f 01 a9 f4 03 01 2a 3f 0c 00 71 f3 03 00 aa 61 00 00 54 e8 1f 80 52 68 de 01 39 e0 03 13 aa 0f 00 00 94 e0 03 13 aa 2b 00 00 94 9f 0e 00 71 00 01 00 54 e8 9c 00 f0 01 9d 44 f9" );
215+ PaperLogger.info (" Found AwakeFromLoad: {}" , AwakeFromLoad);
216+ if (!AwakeFromLoad) {PaperLogger.error (" Could not find AwakeFromLoad" ); return ;}
217+ INSTALL_HOOK_DIRECT (PaperLogger, AwakeFromLoad_Hook, reinterpret_cast <void *>(AwakeFromLoad));
218+
186219 PaperLogger.info (" Installed all hooks!" );
187220}
0 commit comments