public void LateUpdate()
        {
            CustomBeatmapData beatmapData = this.beatmapData as CustomBeatmapData;

            if (beatmapData == null)
            {
                return;
            }
            foreach (var pair in beatmapData.customEventData)
            {
                if (!callbackDatas.ContainsKey(pair.Key))
                {
                    continue;
                }
                foreach (var callbackData in callbackDatas[pair.Key])
                {
                    while (callbackData.nextEventIndex < pair.Value.Count)
                    {
                        CustomEventData eventData = pair.Value[callbackData.nextEventIndex];
                        if (eventData.time - callbackData.aheadTime >= audioTimeSyncController.songTime)
                        {
                            break;
                        }
                        if (eventData.time >= spawningStartTime || callbackData.callIfBeforeStartTime) // skip events before song start
                        {
                            callbackData.callback(eventData);
                        }
                        callbackData.nextEventIndex++;
                    }
                }
            }
        }
예제 #2
0
        internal static void Init(CustomBeatmapData customBeatmap)
        {
            IEnumerable <string>?objectsToKill = customBeatmap.beatmapCustomData.Get <List <object> >(ENVIRONMENTREMOVAL)?.Cast <string>();

            if (objectsToKill != null)
            {
                Plugin.Logger.Log("Legacy Environment Removal Detected...", IPA.Logging.Logger.Level.Warning);
                Plugin.Logger.Log("Please do not use Legacy Environment Removal for new maps as it is deprecated and its functionality in future versions of Chroma cannot be guaranteed", IPA.Logging.Logger.Level.Warning);

                IEnumerable <GameObject> gameObjects = Resources.FindObjectsOfTypeAll <GameObject>();
                foreach (string s in objectsToKill)
                {
                    if (s == "TrackLaneRing" || s == "BigTrackLaneRing")
                    {
                        foreach (GameObject n in gameObjects.Where(obj => obj.name.Contains(s)))
                        {
                            if (s == "TrackLaneRing" && n.name.Contains("Big"))
                            {
                                continue;
                            }

                            n.SetActive(false);
                        }
                    }
                    else
                    {
                        foreach (GameObject n in gameObjects
                                 .Where(obj => obj.name.Contains(s) && (obj.scene.name?.Contains("Environment") ?? false) && (!obj.scene.name?.Contains("Menu") ?? false)))
                        {
                            n.SetActive(false);
                        }
                    }
                }
            }
        }
예제 #3
0
        static bool Prefix(BeatmapData beatmapData, ref BeatmapData __result)
        {
            BeatmapEventData[]      beatmapEventData = beatmapData.beatmapEventData;
            List <BeatmapEventData> list             = new List <BeatmapEventData>(beatmapEventData.Length);

            list.Add(new BeatmapEventData(0f, BeatmapEventType.Event0, 1));
            list.Add(new BeatmapEventData(0f, BeatmapEventType.Event4, 1));
            foreach (BeatmapEventData beatmapEventData2 in beatmapEventData)
            {
                if (beatmapEventData2.type.IsRotationEvent())
                {
                    list.Add(beatmapEventData2);
                }
            }

            if (beatmapData is CustomBeatmapData customBeatmap)
            {
                __result = new CustomBeatmapData(beatmapData.GetBeatmapLineDataCopy(), list.ToArray(), customBeatmap.customEventData, customBeatmap.beatmapCustomData, customBeatmap.levelCustomData);
            }
            else
            {
                __result = new BeatmapData(beatmapData.GetBeatmapLineDataCopy(), list.ToArray());
            }
            return(false);
        }
 internal static void PostfixHelper(ref IReadonlyBeatmapData __result, BeatmapData beatmapData)
 {
     if (beatmapData is CustomBeatmapData customBeatmapData)
     {
         __result = new CustomBeatmapData(beatmapData,
                                          customBeatmapData.customEventData, customBeatmapData.customData, customBeatmapData.beatmapCustomData, customBeatmapData.levelCustomData);
     }
 }
예제 #5
0
        private static IReadonlyBeatmapData ReorderLineData(IReadonlyBeatmapData beatmapData)
        {
            if (beatmapData is CustomBeatmapData)
            {
                CustomBeatmapData customBeatmapData = (CustomBeatmapData)beatmapData.GetCopy();

                // there is some ambiguity with these variables but who frikkin cares
                float startHalfJumpDurationInBeats = 4;
                float maxHalfJumpDistance          = 18;
                float moveDuration = 0.5f;

                for (int i = 0; i < customBeatmapData.beatmapLinesData.Count; i++)
                {
                    BeatmapLineData beatmapLineData = customBeatmapData.beatmapLinesData[i] as BeatmapLineData;
                    foreach (BeatmapObjectData beatmapObjectData in beatmapLineData.beatmapObjectsData)
                    {
                        dynamic customData;
                        if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData || beatmapObjectData is CustomWaypointData)
                        {
                            customData = beatmapObjectData;
                        }
                        else
                        {
                            NoodleLogger.Log("beatmapObjectData was not CustomObstacleData, CustomNoteData, or CustomWaypointData");
                            continue;
                        }

                        dynamic dynData = customData.customData;
                        float   noteJumpMovementSpeed   = (float?)Trees.at(dynData, NOTEJUMPSPEED) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpMovementSpeed;
                        float   noteJumpStartBeatOffset = (float?)Trees.at(dynData, NOTESPAWNOFFSET) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpStartBeatOffset;

                        // how do i not repeat this in a reasonable way
                        float num  = 60f / (float)Trees.at(dynData, "bpm");
                        float num2 = startHalfJumpDurationInBeats;
                        while (noteJumpMovementSpeed * num * num2 > maxHalfJumpDistance)
                        {
                            num2 /= 2f;
                        }

                        num2 += noteJumpStartBeatOffset;
                        if (num2 < 1f)
                        {
                            num2 = 1f;
                        }

                        float jumpDuration = num * num2 * 2f;
                        dynData.aheadTime = moveDuration + (jumpDuration * 0.5f);
                    }

                    _beatmapObjectsDataAccessor(ref beatmapLineData) = beatmapLineData.beatmapObjectsData.OrderBy(n => n.time - (float)((dynamic)n).customData.aheadTime).ToList();
                }

                return(customBeatmapData);
            }

            NoodleLogger.Log("beatmapData was not CustomBeatmapData", IPA.Logging.Logger.Level.Error);
            return(beatmapData);
        }
예제 #6
0
 public ModBeatmapData(CustomBeatmapData from)
 {
     this.from = from;
     foreach (BeatmapObjectData d in from.beatmapObjectsData)
     {
         objects.Add(d);
     }
     foreach (BeatmapEventData e in from.beatmapEventsData)
     {
         events.Add(e);
     }
 }
예제 #7
0
 private static void Postfix(ref BeatmapData __result, string difficultyFileName, StandardLevelInfoSaveData standardLevelInfoSaveData)
 {
     if (__result != null && __result is CustomBeatmapData customBeatmapData && standardLevelInfoSaveData is CustomLevelInfoSaveData lisd)
     {
         __result = new CustomBeatmapData(
             __result,
             customBeatmapData.customEventData,
             customBeatmapData.customData,
             at(lisd.beatmapCustomDatasByFilename, difficultyFileName) ?? Tree(),
             lisd.customData ?? Tree());
     }
 }
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
        private static void Postfix(CustomBeatmapData __instance)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
        {
            IEnumerable <string> requirements = ((List <object>)Trees.at(__instance.beatmapCustomData, "_requirements"))?.Cast <string>();
            bool noodleRequirement            = requirements?.Contains(CAPABILITY) ?? false;

            if (noodleRequirement)
            {
                // Recount for fake notes
                int notesCount     = 0;
                int obstaclesCount = 0;
                int bombsCount     = 0;
                BeatmapLineData[] beatmapLinesData = __instance.beatmapLinesData;
                for (int i = 0; i < beatmapLinesData.Length; i++)
                {
                    foreach (BeatmapObjectData beatmapObjectData in beatmapLinesData[i].beatmapObjectsData)
                    {
                        if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData)
                        {
                            dynamic customObjectData = beatmapObjectData;
                            dynamic dynData          = customObjectData.customData;
                            bool?   fake             = Trees.at(dynData, FAKENOTE);
                            if (fake.HasValue && fake.Value)
                            {
                                continue;
                            }
                        }

                        if (beatmapObjectData.beatmapObjectType == BeatmapObjectType.Note)
                        {
                            NoteType noteType = ((NoteData)beatmapObjectData).noteType;
                            if (noteType == NoteType.NoteA || noteType == NoteType.NoteB)
                            {
                                notesCount++;
                            }
                            else if (noteType == NoteType.Bomb)
                            {
                                bombsCount++;
                            }
                        }
                        else if (beatmapObjectData.beatmapObjectType == BeatmapObjectType.Obstacle)
                        {
                            obstaclesCount++;
                        }
                    }
                }

                BeatmapData beatmapData = __instance as BeatmapData;
                _notesCountSetter(ref beatmapData, notesCount);
                _obstaclesCountSetter(ref beatmapData, obstaclesCount);
                _bombsCountSetter(ref beatmapData, bombsCount);
            }
        }
예제 #9
0
 internal static void OnTrackManagerCreated(object trackManager, CustomBeatmapData customBeatmapData)
 {
     CustomEventData[] customEventDatas = customBeatmapData.customEventData;
     foreach (CustomEventData customEventData in customEventDatas)
     {
         if (customEventData.type == "AssignPlayerToTrack")
         {
             string trackName = Trees.at(customEventData.data, TRACK);
             ((TrackManager)trackManager).AddTrack(trackName);
         }
     }
 }
        internal static void OnCustomBeatmapDataCreated(CustomBeatmapData customBeatmapData)
        {
            IEnumerable <string> requirements = ((List <object>)Trees.at(customBeatmapData.beatmapCustomData, "_requirements"))?.Cast <string>();
            bool noodleRequirement            = requirements?.Contains(CAPABILITY) ?? false;

            if (noodleRequirement)
            {
                // Recount for fake notes
                int notesCount     = 0;
                int obstaclesCount = 0;
                int bombsCount     = 0;
                IReadOnlyList <IReadonlyBeatmapLineData> beatmapLinesData = customBeatmapData.beatmapLinesData;
                for (int i = 0; i < beatmapLinesData.Count; i++)
                {
                    foreach (BeatmapObjectData beatmapObjectData in beatmapLinesData[i].beatmapObjectsData)
                    {
                        if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData)
                        {
                            dynamic customObjectData = beatmapObjectData;
                            dynamic dynData          = customObjectData.customData;
                            bool?   fake             = Trees.at(dynData, FAKENOTE);
                            if (fake.HasValue && fake.Value)
                            {
                                continue;
                            }
                        }

                        if (beatmapObjectData.beatmapObjectType == BeatmapObjectType.Note)
                        {
                            ColorType noteType = ((NoteData)beatmapObjectData).colorType;
                            if (noteType == ColorType.ColorA || noteType == ColorType.ColorB)
                            {
                                notesCount++;
                            }
                            else if (noteType == ColorType.None)
                            {
                                bombsCount++;
                            }
                        }
                        else if (beatmapObjectData.beatmapObjectType == BeatmapObjectType.Obstacle)
                        {
                            obstaclesCount++;
                        }
                    }
                }

                BeatmapData beatmapData = customBeatmapData as BeatmapData;
                _cuttableNotesTypeSetter(ref beatmapData, notesCount);
                _obstaclesCountSetter(ref beatmapData, obstaclesCount);
                _bombsCountSetter(ref beatmapData, bombsCount);
            }
        }
예제 #11
0
        internal static void OnTrackManagerCreated(object trackManager, CustomBeatmapData customBeatmapData)
        {
            List <CustomEventData> customEventsData = customBeatmapData.customEventsData;

            foreach (CustomEventData customEventData in customEventsData)
            {
                if (customEventData.type == "AssignTrackParent")
                {
                    string trackName = Trees.at(customEventData.data, "_parentTrack");
                    ((TrackManager)trackManager).AddTrack(trackName);
                }
            }
        }
        internal static void OnTrackManagerCreated(object trackManager, CustomBeatmapData customBeatmapData)
        {
            List <CustomEventData> customEventsData = customBeatmapData.customEventsData;

            foreach (CustomEventData customEventData in customEventsData)
            {
                if (customEventData.type == ASSIGNPLAYERTOTRACK)
                {
                    string trackName = Trees.at(customEventData.data, TRACK);
                    ((TrackManager)trackManager).AddTrack(trackName);
                }
            }
        }
예제 #13
0
        private static IReadonlyBeatmapData ReorderLineData(IReadonlyBeatmapData beatmapData)
        {
            if (beatmapData is CustomBeatmapData)
            {
                CustomBeatmapData customBeatmapData = (CustomBeatmapData)beatmapData.GetCopy();

                // there is some ambiguity with these variables but who frikkin cares
                float startHalfJumpDurationInBeats = 4;
                float maxHalfJumpDistance          = 18;
                float moveDuration = 0.5f;

                for (int i = 0; i < customBeatmapData.beatmapLinesData.Count; i++)
                {
                    BeatmapLineData beatmapLineData = (BeatmapLineData)customBeatmapData.beatmapLinesData[i];
                    foreach (BeatmapObjectData beatmapObjectData in beatmapLineData.beatmapObjectsData)
                    {
                        Dictionary <string, object?> dynData = beatmapObjectData.GetDataForObject();

                        float noteJumpMovementSpeed   = dynData.Get <float?>(NOTEJUMPSPEED) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpMovementSpeed;
                        float noteJumpStartBeatOffset = dynData.Get <float?>(NOTESPAWNOFFSET) ?? GameplayCoreInstallerInstallBindings.CachedNoteJumpStartBeatOffset;

                        // how do i not repeat this in a reasonable way
                        float num  = 60f / dynData.Get <float>("bpm");
                        float num2 = startHalfJumpDurationInBeats;
                        while (noteJumpMovementSpeed * num * num2 > maxHalfJumpDistance)
                        {
                            num2 /= 2f;
                        }

                        num2 += noteJumpStartBeatOffset;
                        if (num2 < 1f)
                        {
                            num2 = 1f;
                        }

                        float jumpDuration = num * num2 * 2f;
                        dynData["aheadTime"] = moveDuration + (jumpDuration * 0.5f);
                    }

                    _beatmapObjectsDataAccessor(ref beatmapLineData) = beatmapLineData.beatmapObjectsData
                                                                       .OrderBy(n => n.time - (float)(n.GetDataForObject()["aheadTime"] ?? throw new System.InvalidOperationException($"Could not get aheadTime for [{n.GetType().FullName}] at time [{n.time}].")))
                                                                       .ToList();
                }

                return(customBeatmapData);
            }

            Logger.Log("beatmapData was not CustomBeatmapData", IPA.Logging.Logger.Level.Error);
            return(beatmapData);
        }
예제 #14
0
        internal static void OnTrackManagerCreated(TrackBuilder trackManager, CustomBeatmapData customBeatmapData)
        {
            List <CustomEventData> customEventsData = customBeatmapData.customEventsData;

            foreach (CustomEventData customEventData in customEventsData)
            {
                if (customEventData.type == ASSIGNPLAYERTOTRACK)
                {
                    string?trackName = customEventData.data.Get <string>(TRACK);
                    if (trackName != null)
                    {
                        trackManager.AddTrack(trackName);
                    }
                }
            }
        }
        internal static void CreateEnvironmentTracks(TrackBuilder trackManager, CustomBeatmapData customBeatmapData)
        {
            IEnumerable <Dictionary <string, object?> >?environmentData = customBeatmapData.customData.Get <List <object> >(ENVIRONMENT)?.Cast <Dictionary <string, object?> >();

            if (environmentData != null)
            {
                foreach (Dictionary <string, object?> gameObjectData in environmentData)
                {
                    string?trackName = gameObjectData.Get <string>("_track");
                    if (trackName != null)
                    {
                        trackManager.AddTrack(trackName);
                    }
                }
            }
        }
예제 #16
0
        internal static void CreateEnvironmentTracks(object trackManager, CustomBeatmapData customBeatmapData)
        {
            List <dynamic> environmentData = Trees.at(customBeatmapData.customData, ENVIRONMENT);

            if (environmentData != null)
            {
                foreach (dynamic gameObjectData in environmentData)
                {
                    string trackName = Trees.at(gameObjectData, "_track");
                    if (trackName != null)
                    {
                        ((TrackManager)trackManager).AddTrack(trackName);
                    }
                }
            }
        }
예제 #17
0
        public CustomBeatmapData ToBeatmap()
        {
            CustomBeatmapData bm = new CustomBeatmapData(from.numberOfLines, from.customEventsData, from.customData, from.beatmapCustomData, from.levelCustomData);

            foreach (BeatmapObjectData o in objects.OrderBy((e) => e.time))
            {
                if (!(o is ObstacleData ob && ob.duration == 0f) && o.time > 0f)
                {
                    bm.AddBeatmapObjectData(o);
                }
            }
            foreach (BeatmapEventData o in events.OrderBy((e) => e.time))
            {
                bm.AddBeatmapEventData(o);
            }
            CustomBeatmapData.CopyAvailableSpecialEventsPerKeywordDictionary(this.from, bm);
            return(bm);
        }
예제 #18
0
        public static bool Prefix(string json, float beatsPerMinute, float shuffle, float shufflePeriod, ref BeatmapData __result)
        {
            CustomBeatmapSaveData saveData = CustomBeatmapSaveData.DeserializeFromJSONString(json);

            if (saveData == null)
            {
                return(true);
            }

            __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(saveData.notes, saveData.obstacles, saveData.events, beatsPerMinute, shuffle, shufflePeriod, saveData.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), Tree(), Tree());
            if (!(__result is CustomBeatmapData))
            {
                return(true);
            }

            CustomBeatmapData beatmapData = __result as CustomBeatmapData;

            return(false);
        }
        private static bool BasicPatch(CustomBeatmapData customBeatmapData)
        {
            IEnumerable <string> requirements = ((List <object>)Trees.at(customBeatmapData.beatmapCustomData, "_requirements"))?.Cast <string>();
            IEnumerable <string> suggestions  = ((List <object>)Trees.at(customBeatmapData.beatmapCustomData, "_suggestions"))?.Cast <string>();
            bool chromaRequirement            = (requirements?.Contains(Chroma.Plugin.REQUIREMENTNAME) ?? false) || (suggestions?.Contains(Chroma.Plugin.REQUIREMENTNAME) ?? false);

            // please let me remove this shit
            bool legacyOverride = customBeatmapData.beatmapEventsData.Any(n => n.value >= LegacyLightHelper.RGB_INT_OFFSET);

            if (legacyOverride)
            {
                ChromaLogger.Log("Legacy Chroma Detected...", IPA.Logging.Logger.Level.Warning);
                ChromaLogger.Log("Please do not use Legacy Chroma for new maps as it is deprecated and its functionality in future versions of Chroma cannot be guaranteed", IPA.Logging.Logger.Level.Warning);
            }

            ChromaController.ToggleChromaPatches((chromaRequirement || legacyOverride) && ChromaConfig.Instance.CustomColorEventsEnabled);
            ChromaController.DoColorizerSabers = chromaRequirement && ChromaConfig.Instance.CustomColorEventsEnabled;

            return(chromaRequirement);
        }
        public static bool Prefix(BeatmapDataLoader __instance, string json, float startBPM, float shuffle, float shufflePeriod, ref BeatmapData __result)
        {
            //Plugin.logger.Debug("In GetBeatmapDataFromJson");

            CustomBeatmapSaveData saveData = CustomBeatmapSaveData.DeserializeFromJSONString(json);

            if (saveData == null)
            {
                return(true);
            }

            __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(saveData.notes, saveData.obstacles, saveData.events, startBPM, shuffle, shufflePeriod, saveData.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), Tree(), Tree(), __instance);
            if (!(__result is CustomBeatmapData))
            {
                return(true);
            }

            CustomBeatmapData beatmapData = __result as CustomBeatmapData;

            return(false);
        }
예제 #21
0
        private static bool BasicPatch(IDifficultyBeatmap difficultyBeatmap, CustomBeatmapData customBeatmapData)
        {
            IEnumerable <string>?requirements = customBeatmapData.beatmapCustomData.Get <List <object> >("_requirements")?.Cast <string>();
            IEnumerable <string>?suggestions  = customBeatmapData.beatmapCustomData.Get <List <object> >("_suggestions")?.Cast <string>();
            bool chromaRequirement            = (requirements?.Contains(Plugin.REQUIREMENTNAME) ?? false) || (suggestions?.Contains(Plugin.REQUIREMENTNAME) ?? false);

            // please let me remove this shit
            bool legacyOverride = customBeatmapData.beatmapEventsData.Any(n => n.value >= LegacyLightHelper.RGB_INT_OFFSET);

            if (legacyOverride)
            {
                Plugin.Logger.Log("Legacy Chroma Detected...", IPA.Logging.Logger.Level.Warning);
                Plugin.Logger.Log("Please do not use Legacy Chroma Lights for new maps as it is deprecated and its functionality in future versions of Chroma cannot be guaranteed", IPA.Logging.Logger.Level.Warning);
            }

            ChromaController.ToggleChromaPatches((chromaRequirement || legacyOverride) && ChromaConfig.Instance !.CustomColorEventsEnabled);
            ChromaController.DoColorizerSabers = chromaRequirement && ChromaConfig.Instance !.CustomColorEventsEnabled;

            LightIDTableManager.SetEnvironment(difficultyBeatmap.GetEnvironmentInfo().serializedName);

            return(chromaRequirement);
        }
예제 #22
0
 internal TrackManager(CustomBeatmapData beatmapData)
 {
     TrackManagerCreated?.Invoke(this, beatmapData);
 }
예제 #23
0
        internal static void Init(CustomBeatmapData customBeatmapData, float noteLinesDistance)
        {
            List <dynamic> environmentData = Trees.at(customBeatmapData.customData, ENVIRONMENT);

            GetAllGameObjects();
            if (environmentData != null)
            {
                RingRotationOffsets.Clear();
                ParametricBoxControllerParameters.TransformParameters.Clear();

                if (Settings.ChromaConfig.Instance.PrintEnvironmentEnhancementDebug)
                {
                    ChromaLogger.Log($"=====================================");
                }

                foreach (dynamic gameObjectData in environmentData)
                {
                    string id = Trees.at(gameObjectData, ID);

                    string       lookupString = Trees.at(gameObjectData, LOOKUPMETHOD);
                    LookupMethod lookupMethod = (LookupMethod)Enum.Parse(typeof(LookupMethod), lookupString);

                    int?dupeAmount = (int?)Trees.at(gameObjectData, DUPLICATIONAMOUNT);

                    bool?active = (bool?)Trees.at(gameObjectData, ACTIVE);

                    Vector3?scale         = GetVectorData(gameObjectData, SCALE);
                    Vector3?position      = GetVectorData(gameObjectData, POSITION);
                    Vector3?rotation      = GetVectorData(gameObjectData, OBJECTROTATION);
                    Vector3?localPosition = GetVectorData(gameObjectData, LOCALPOSITION);
                    Vector3?localRotation = GetVectorData(gameObjectData, LOCALROTATION);

                    List <GameObjectInfo> foundObjects = LookupID(id, lookupMethod);
                    if (Settings.ChromaConfig.Instance.PrintEnvironmentEnhancementDebug)
                    {
                        ChromaLogger.Log($"ID [\"{id}\"] using method [{lookupMethod:G}] found:");
                        foundObjects.ForEach(n => ChromaLogger.Log(n.FullID));
                    }

                    List <GameObjectInfo> gameObjectInfos;

                    if (dupeAmount.HasValue)
                    {
                        gameObjectInfos = new List <GameObjectInfo>();
                        foreach (GameObjectInfo gameObjectInfo in foundObjects)
                        {
                            if (Settings.ChromaConfig.Instance.PrintEnvironmentEnhancementDebug)
                            {
                                ChromaLogger.Log($"Duplicating [{gameObjectInfo.FullID}]:");
                            }

                            GameObject gameObject = gameObjectInfo.GameObject;
                            Transform  parent     = gameObject.transform.parent;
                            Scene      scene      = gameObject.scene;

                            for (int i = 0; i < dupeAmount.Value; i++)
                            {
                                List <IComponentData> componentDatas = new List <IComponentData>();
                                ComponentInitializer.PrefillComponentsData(gameObject.transform, componentDatas);
                                GameObject newGameObject = UnityEngine.Object.Instantiate(gameObject);
                                ComponentInitializer.PostfillComponentsData(newGameObject.transform, gameObject.transform, componentDatas);
                                SceneManager.MoveGameObjectToScene(newGameObject, scene);
                                newGameObject.transform.SetParent(parent, true);
                                ComponentInitializer.InitializeComponents(newGameObject.transform, gameObject.transform, _gameObjectInfos, componentDatas);
                                gameObjectInfos.AddRange(_gameObjectInfos.Where(n => n.GameObject == newGameObject));
                            }
                        }
                    }
                    else
                    {
                        gameObjectInfos = foundObjects;
                    }

                    foreach (GameObjectInfo gameObjectInfo in gameObjectInfos)
                    {
                        GameObject gameObject = gameObjectInfo.GameObject;

                        if (active.HasValue)
                        {
                            gameObjectInfo.GameObject.SetActive(active.Value);
                        }

                        Transform transform = gameObject.transform;

                        if (scale.HasValue)
                        {
                            transform.localScale = scale.Value;
                        }

                        if (position.HasValue)
                        {
                            transform.position = position.Value * noteLinesDistance;
                        }

                        if (rotation.HasValue)
                        {
                            transform.eulerAngles = rotation.Value;
                        }

                        if (localPosition.HasValue)
                        {
                            transform.localPosition = localPosition.Value * noteLinesDistance;
                        }

                        if (localRotation.HasValue)
                        {
                            transform.localEulerAngles = localRotation.Value;
                        }

                        // Handle TrackLaneRing
                        TrackLaneRing trackLaneRing = gameObject.GetComponent <TrackLaneRing>();
                        if (trackLaneRing != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                _positionOffsetAccessor(ref trackLaneRing) = transform.localPosition;
                                _posZAccessor(ref trackLaneRing) = 0;
                            }

                            if (rotation.HasValue || localRotation.HasValue)
                            {
                                RingRotationOffsets[trackLaneRing] = transform.localRotation;
                                _rotZAccessor(ref trackLaneRing) = 0;
                            }
                        }

                        // Handle ParametricBoxController
                        ParametricBoxController parametricBoxController = gameObject.GetComponent <ParametricBoxController>();
                        if (parametricBoxController != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                ParametricBoxControllerParameters.SetTransformPosition(parametricBoxController, transform.localPosition);
                            }

                            if (scale.HasValue)
                            {
                                ParametricBoxControllerParameters.SetTransformScale(parametricBoxController, transform.localScale);
                            }
                        }

                        if (NoodleExtensionsInstalled)
                        {
                            GameObjectTrackController.HandleTrackData(gameObject, gameObjectData, customBeatmapData, noteLinesDistance, trackLaneRing, parametricBoxController);
                        }
                    }

                    if (Settings.ChromaConfig.Instance.PrintEnvironmentEnhancementDebug)
                    {
                        ChromaLogger.Log($"=====================================");
                    }
                }
            }

            LegacyEnvironmentRemoval.Init(customBeatmapData);
        }
예제 #24
0
        internal static void OnDeserializeBeatmapData(CustomDataDeserializer.DeserializeBeatmapEventArgs eventArgs)
        {
            if (eventArgs.IsMultiplayer)
            {
                return;
            }

            CustomBeatmapData beatmapData = eventArgs.BeatmapData;

            _noodleObjectDatas = new Dictionary <BeatmapObjectData, IBeatmapObjectDataCustomData>();
            Dictionary <string, PointDefinition> pointDefinitions = beatmapData.GetBeatmapPointDefinitions();
            Dictionary <string, Track>           beatmapTracks    = beatmapData.GetBeatmapTracks();

            foreach (BeatmapObjectData beatmapObjectData in eventArgs.BeatmapObjectDatas)
            {
                try
                {
                    NoodleObjectData noodleObjectData;

                    Dictionary <string, object?> customData;

                    switch (beatmapObjectData)
                    {
                    case CustomObstacleData customObstacleData:
                        customData       = customObstacleData.customData;
                        noodleObjectData = ProcessCustomObstacle(customData);
                        break;

                    case CustomNoteData customNoteData:
                        customData       = customNoteData.customData;
                        noodleObjectData = ProcessCustomNote(customData);
                        break;

                    case CustomWaypointData customWaypointData:
                        customData       = customWaypointData.customData;
                        noodleObjectData = new NoodleObjectData();
                        break;

                    default:
                        continue;
                    }

                    FinalizeCustomObject(customData, noodleObjectData, pointDefinitions, beatmapTracks);
                    _noodleObjectDatas.Add(beatmapObjectData, noodleObjectData);
                }
                catch (Exception e)
                {
                    CustomDataDeserializer.LogFailure(Plugin.Logger, e, beatmapObjectData);
                }
            }

            _noodleEventDatas = new Dictionary <CustomEventData, ICustomEventCustomData>();
            foreach (CustomEventData customEventData in eventArgs.CustomEventDatas)
            {
                try
                {
                    ICustomEventCustomData noodleEventData;

                    Dictionary <string, object?> data = customEventData.data;
                    switch (customEventData.type)
                    {
                    case ASSIGNPLAYERTOTRACK:
                        noodleEventData = new NoodlePlayerTrackEventData(GetTrack(customEventData.data, beatmapTracks) ?? throw new InvalidOperationException("Track was not defined."));
                        break;

                    case ASSIGNTRACKPARENT:
                        noodleEventData = ProcessParentTrackEvent(data, beatmapTracks);
                        break;

                    default:
                        continue;
                    }

                    _noodleEventDatas.Add(customEventData, noodleEventData);
                }
                catch (Exception e)
                {
                    CustomDataDeserializer.LogFailure(Plugin.Logger, e, customEventData);
                }
            }
        }
        static bool Prefix(BeatmapData beatmapData, ref BeatmapData __result)
        {
            MethodInfo MirrorTransformBeatmapObjects = typeof(BeatDataMirrorTransform).GetMethod("MirrorTransformBeatmapObjects", BindingFlags.Static | BindingFlags.NonPublic);

            BeatmapLineData[] beatmapLinesData = beatmapData.beatmapLinesData;
            int[]             array            = new int[beatmapLinesData.Length];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = 0;
            }
            int num = 0;

            for (int j = 0; j < beatmapLinesData.Length; j++)
            {
                num += beatmapLinesData[j].beatmapObjectsData.Length;
            }
            List <BeatmapObjectData> list = new List <BeatmapObjectData>(num);
            bool flag;

            do
            {
                flag = false;
                float num2 = 999999f;
                int   num3 = 0;
                for (int k = 0; k < beatmapLinesData.Length; k++)
                {
                    BeatmapObjectData[] beatmapObjectsData = beatmapLinesData[k].beatmapObjectsData;
                    int num4 = array[k];
                    if (num4 < beatmapObjectsData.Length)
                    {
                        flag = true;
                        float time = beatmapObjectsData[num4].time;
                        if (time < num2)
                        {
                            num2 = time;
                            num3 = k;
                        }
                    }
                }
                if (flag)
                {
                    list.Add(beatmapLinesData[num3].beatmapObjectsData[array[num3]].GetCopy());
                    array[num3]++;
                }
            }while (flag);
            MirrorTransformBeatmapObjects.Invoke(null, new object[] { list, beatmapData.beatmapLinesData.Length });
            int[] array2 = new int[beatmapLinesData.Length];
            for (int l = 0; l < list.Count; l++)
            {
                BeatmapObjectData beatmapObjectData = list[l];
                array2[beatmapObjectData.lineIndex]++;
            }
            BeatmapLineData[] array3 = new BeatmapLineData[beatmapLinesData.Length];
            for (int m = 0; m < beatmapLinesData.Length; m++)
            {
                array3[m] = new BeatmapLineData();
                array3[m].beatmapObjectsData = new BeatmapObjectData[array2[m]];
                array[m] = 0;
            }
            for (int n = 0; n < list.Count; n++)
            {
                BeatmapObjectData beatmapObjectData2 = list[n];
                int lineIndex = beatmapObjectData2.lineIndex;
                array3[lineIndex].beatmapObjectsData[array[lineIndex]] = beatmapObjectData2;
                array[lineIndex]++;
            }
            CustomBeatmapEventData[] array4 = new CustomBeatmapEventData[beatmapData.beatmapEventData.Length];
            for (int num5 = 0; num5 < beatmapData.beatmapEventData.Length; num5++)
            {
                CustomBeatmapEventData beatmapEventData = beatmapData.beatmapEventData[num5] as CustomBeatmapEventData;
                if (beatmapEventData == null)
                {
                    continue;
                }
                if (beatmapEventData.type.IsRotationEvent())
                {
                    int value = 7 - beatmapEventData.value;
                    array4[num5] = new CustomBeatmapEventData(beatmapEventData.time, beatmapEventData.type, value, beatmapEventData.customData ?? Tree());
                }
                else
                {
                    array4[num5] = beatmapEventData;
                }
            }

            if (beatmapData is CustomBeatmapData customBeatmap)
            {
                __result = new CustomBeatmapData(array3, array4, customBeatmap.customEventData, customBeatmap.beatmapCustomData, customBeatmap.levelCustomData);
            }
            else
            {
                __result = new BeatmapData(array3, array4);
            }
            return(false);
        }
        internal static void Init(CustomBeatmapData customBeatmapData, float noteLinesDistance)
        {
            List <dynamic> environmentData = Trees.at(customBeatmapData.customData, "_environment");

            GetAllGameObjects();
            if (environmentData != null)
            {
                SkipRingUpdate = new Dictionary <TrackLaneRing, bool>();

                foreach (dynamic gameObjectData in environmentData)
                {
                    string id = Trees.at(gameObjectData, "_id");

                    string       lookupString = Trees.at(gameObjectData, "_lookupMethod");
                    LookupMethod lookupMethod = (LookupMethod)Enum.Parse(typeof(LookupMethod), lookupString);

                    bool hide = ((bool?)Trees.at(gameObjectData, "_hide")).GetValueOrDefault(false);

                    Vector3?scale         = GetVectorData(gameObjectData, "_scale");
                    Vector3?position      = GetVectorData(gameObjectData, "_position");
                    Vector3?rotation      = GetVectorData(gameObjectData, "_rotation");
                    Vector3?localPosition = GetVectorData(gameObjectData, "_localPosition");
                    Vector3?localRotation = GetVectorData(gameObjectData, "_localRotation");

                    List <GameObjectInfo> foundObjects = LookupID(id, lookupMethod);
                    foreach (GameObjectInfo gameObjectInfo in foundObjects)
                    {
                        GameObject gameObject = gameObjectInfo.GameObject;

                        if (hide)
                        {
                            gameObjectInfo.GameObject.SetActive(false);
                        }

                        Transform transform = gameObject.transform;

                        if (scale.HasValue)
                        {
                            transform.localScale = scale.Value;
                        }

                        if (position.HasValue)
                        {
                            transform.position = position.Value * noteLinesDistance;
                        }

                        if (rotation.HasValue)
                        {
                            transform.eulerAngles = rotation.Value;
                        }

                        if (localPosition.HasValue)
                        {
                            transform.localPosition = localPosition.Value * noteLinesDistance;
                        }

                        if (localRotation.HasValue)
                        {
                            transform.localEulerAngles = localRotation.Value;
                        }

                        // Handle TrackLaneRing
                        TrackLaneRing trackLaneRing = gameObject.GetComponent <TrackLaneRing>();
                        if (trackLaneRing != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                _positionOffsetAccessor(ref trackLaneRing) = transform.position;
                                float zPosition = transform.position.z;
                                _prevPosZAccessor(ref trackLaneRing) = zPosition;
                                _posZAccessor(ref trackLaneRing)     = zPosition;
                            }

                            if (rotation.HasValue || localRotation.HasValue)
                            {
                                float zRotation = transform.rotation.z;
                                _prevRotZAccessor(ref trackLaneRing) = zRotation;
                                _rotZAccessor(ref trackLaneRing)     = zRotation;
                            }
                        }

                        if (Plugin.NoodleExtensionsInstalled && NoodleController.NoodleExtensionsActive)
                        {
                            GameObjectTrackController.HandleTrackData(gameObject, gameObjectData, customBeatmapData, noteLinesDistance, trackLaneRing);
                        }
                    }

                    if (Settings.ChromaConfig.Instance.PrintEnvironmentEnhancementDebug)
                    {
                        ChromaLogger.Log($"ID [\"{id}\"] using method [{lookupMethod.ToString("G")}] found:");
                        foundObjects.ForEach(n => ChromaLogger.Log(n.FullID));
                        ChromaLogger.Log($"=====================================");
                    }
                }
            }

            LegacyEnvironmentRemoval.Init(customBeatmapData);
        }
        internal static void Init(CustomBeatmapData customBeatmapData, float noteLinesDistance)
        {
            IEnumerable <Dictionary <string, object?> >?environmentData = customBeatmapData.customData.Get <List <object> >(ENVIRONMENT)?.Cast <Dictionary <string, object?> >();

            GetAllGameObjects();

            RingRotationOffsets = new Dictionary <TrackLaneRing, Quaternion>();
            AvoidancePosition   = new Dictionary <BeatmapObjectsAvoidance, Vector3>();
            AvoidanceRotation   = new Dictionary <BeatmapObjectsAvoidance, Quaternion>();
            ParametricBoxControllerParameters.TransformParameters = new Dictionary <ParametricBoxController, ParametricBoxControllerParameters>();

            if (environmentData != null)
            {
                RingRotationOffsets.Clear();
                ParametricBoxControllerParameters.TransformParameters.Clear();

                if (Settings.ChromaConfig.Instance !.PrintEnvironmentEnhancementDebug)
                {
                    Plugin.Logger.Log($"=====================================");
                }

                foreach (Dictionary <string, object?> gameObjectData in environmentData)
                {
                    string id = gameObjectData.Get <string>(ID) ?? throw new InvalidOperationException("Id was not defined.");

                    string       lookupString = gameObjectData.Get <string>(LOOKUPMETHOD) ?? throw new InvalidOperationException("Lookup method was not defined.");
                    LookupMethod lookupMethod = (LookupMethod)Enum.Parse(typeof(LookupMethod), lookupString);

                    int?dupeAmount = gameObjectData.Get <int?>(DUPLICATIONAMOUNT);

                    bool?active = gameObjectData.Get <bool?>(ACTIVE);

                    Vector3?scale         = GetVectorData(gameObjectData, SCALE);
                    Vector3?position      = GetVectorData(gameObjectData, POSITION);
                    Vector3?rotation      = GetVectorData(gameObjectData, OBJECTROTATION);
                    Vector3?localPosition = GetVectorData(gameObjectData, LOCALPOSITION);
                    Vector3?localRotation = GetVectorData(gameObjectData, LOCALROTATION);

                    int?lightID = gameObjectData.Get <int?>(LIGHTID);

                    List <GameObjectInfo> foundObjects = LookupID(id, lookupMethod);
                    if (Settings.ChromaConfig.Instance !.PrintEnvironmentEnhancementDebug)
                    {
                        if (foundObjects.Count > 0)
                        {
                            Plugin.Logger.Log($"ID [\"{id}\"] using method [{lookupMethod:G}] found:");
                            foundObjects.ForEach(n => Plugin.Logger.Log(n.FullID));
                        }
                        else
                        {
                            Plugin.Logger.Log($"ID [\"{id}\"] using method [{lookupMethod:G}] found nothing.", IPA.Logging.Logger.Level.Error);
                        }
                    }

                    List <GameObjectInfo> gameObjectInfos;

                    if (dupeAmount.HasValue)
                    {
                        gameObjectInfos = new List <GameObjectInfo>();
                        foreach (GameObjectInfo gameObjectInfo in foundObjects)
                        {
                            if (Settings.ChromaConfig.Instance !.PrintEnvironmentEnhancementDebug)
                            {
                                Plugin.Logger.Log($"Duplicating [{gameObjectInfo.FullID}]:");
                            }

                            GameObject gameObject = gameObjectInfo.GameObject;
                            Transform  parent     = gameObject.transform.parent;
                            Scene      scene      = gameObject.scene;

                            for (int i = 0; i < dupeAmount.Value; i++)
                            {
                                List <IComponentData> componentDatas = new List <IComponentData>();
                                ComponentInitializer.PrefillComponentsData(gameObject.transform, componentDatas);
                                GameObject newGameObject = UnityEngine.Object.Instantiate(gameObject);
                                ComponentInitializer.PostfillComponentsData(newGameObject.transform, gameObject.transform, componentDatas);
                                SceneManager.MoveGameObjectToScene(newGameObject, scene);
                                newGameObject.transform.SetParent(parent, true);
                                ComponentInitializer.InitializeComponents(newGameObject.transform, gameObject.transform, _gameObjectInfos, componentDatas, lightID);

                                List <GameObjectInfo> gameObjects = _gameObjectInfos.Where(n => n.GameObject == newGameObject).ToList();
                                gameObjectInfos.AddRange(gameObjects);

                                if (Settings.ChromaConfig.Instance !.PrintEnvironmentEnhancementDebug)
                                {
                                    gameObjects.ForEach(n => Plugin.Logger.Log(n.FullID));
                                }
                            }
                        }
                    }
                    else
                    {
                        if (lightID.HasValue)
                        {
                            Plugin.Logger.Log($"LightID requested but no duplicated object to apply to.", IPA.Logging.Logger.Level.Error);
                        }

                        gameObjectInfos = foundObjects;
                    }

                    foreach (GameObjectInfo gameObjectInfo in gameObjectInfos)
                    {
                        GameObject gameObject = gameObjectInfo.GameObject;

                        if (active.HasValue)
                        {
                            gameObjectInfo.GameObject.SetActive(active.Value);
                        }

                        Transform transform = gameObject.transform;

                        if (scale.HasValue)
                        {
                            transform.localScale = scale.Value;
                        }

                        if (position.HasValue)
                        {
                            transform.position = position.Value * noteLinesDistance;
                        }

                        if (rotation.HasValue)
                        {
                            transform.eulerAngles = rotation.Value;
                        }

                        if (localPosition.HasValue)
                        {
                            transform.localPosition = localPosition.Value * noteLinesDistance;
                        }

                        if (localRotation.HasValue)
                        {
                            transform.localEulerAngles = localRotation.Value;
                        }

                        // Handle TrackLaneRing
                        TrackLaneRing trackLaneRing = gameObject.GetComponent <TrackLaneRing>();
                        if (trackLaneRing != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                _positionOffsetAccessor(ref trackLaneRing) = transform.localPosition;
                                _posZAccessor(ref trackLaneRing) = 0;
                            }

                            if (rotation.HasValue || localRotation.HasValue)
                            {
                                RingRotationOffsets[trackLaneRing] = transform.localRotation;
                                _rotZAccessor(ref trackLaneRing) = 0;
                            }
                        }

                        // Handle ParametricBoxController
                        ParametricBoxController parametricBoxController = gameObject.GetComponent <ParametricBoxController>();
                        if (parametricBoxController != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                ParametricBoxControllerParameters.SetTransformPosition(parametricBoxController, transform.localPosition);
                            }

                            if (scale.HasValue)
                            {
                                ParametricBoxControllerParameters.SetTransformScale(parametricBoxController, transform.localScale);
                            }
                        }

                        // Handle BeatmapObjectsAvoidance
                        BeatmapObjectsAvoidance beatmapObjectsAvoidance = gameObject.GetComponent <BeatmapObjectsAvoidance>();
                        if (beatmapObjectsAvoidance != null)
                        {
                            if (position.HasValue || localPosition.HasValue)
                            {
                                AvoidancePosition[beatmapObjectsAvoidance] = transform.localPosition;
                            }

                            if (rotation.HasValue || localRotation.HasValue)
                            {
                                AvoidanceRotation[beatmapObjectsAvoidance] = transform.localRotation;
                            }
                        }

                        GameObjectTrackController.HandleTrackData(gameObject, gameObjectData, customBeatmapData, noteLinesDistance, trackLaneRing, parametricBoxController, beatmapObjectsAvoidance);
                    }

                    if (Settings.ChromaConfig.Instance !.PrintEnvironmentEnhancementDebug)
                    {
                        Plugin.Logger.Log($"=====================================");
                    }
                }
            }

            try
            {
                LegacyEnvironmentRemoval.Init(customBeatmapData);
            }
            catch (Exception e)
            {
                Plugin.Logger.Log("Could not run Legacy Enviroment Removal");
                Plugin.Logger.Log(e);
            }
        }
예제 #28
0
        static bool Prefix(BeatmapData beatmapData, GameplayModifiers.EnabledObstacleType enabledObstaclesType, bool noBombs, ref BeatmapData __result)
        {
            MethodInfo ShouldUseBeatmapObject = typeof(BeatmapDataObstaclesAndBombsTransform).GetMethod("ShouldUseBeatmapObject", BindingFlags.Static | BindingFlags.NonPublic);

            BeatmapLineData[] beatmapLinesData = beatmapData.beatmapLinesData;
            int[]             array            = new int[beatmapLinesData.Length];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = 0;
            }
            int num = 0;

            for (int j = 0; j < beatmapLinesData.Length; j++)
            {
                num += beatmapLinesData[j].beatmapObjectsData.Length;
            }
            List <BeatmapObjectData> list = new List <BeatmapObjectData>(num);
            bool flag;

            do
            {
                flag = false;
                float num2 = 999999f;
                int   num3 = 0;
                for (int k = 0; k < beatmapLinesData.Length; k++)
                {
                    BeatmapObjectData[] beatmapObjectsData = beatmapLinesData[k].beatmapObjectsData;
                    int num4 = array[k];
                    if (num4 < beatmapObjectsData.Length)
                    {
                        flag = true;
                        float time = beatmapObjectsData[num4].time;
                        if (time < num2)
                        {
                            num2 = time;
                            num3 = k;
                        }
                    }
                }
                if (flag)
                {
                    if (Convert.ToBoolean(ShouldUseBeatmapObject.Invoke(null, new object[] { beatmapLinesData[num3].beatmapObjectsData[array[num3]], enabledObstaclesType, noBombs })))
                    {
                        list.Add(beatmapLinesData[num3].beatmapObjectsData[array[num3]].GetCopy());
                    }
                    array[num3]++;
                }
            }while (flag);
            int[] array2 = new int[beatmapLinesData.Length];
            for (int l = 0; l < list.Count; l++)
            {
                BeatmapObjectData beatmapObjectData = list[l];
                array2[beatmapObjectData.lineIndex]++;
            }
            BeatmapLineData[] array3 = new BeatmapLineData[beatmapLinesData.Length];
            for (int m = 0; m < beatmapLinesData.Length; m++)
            {
                array3[m] = new BeatmapLineData();
                array3[m].beatmapObjectsData = new BeatmapObjectData[array2[m]];
                array[m] = 0;
            }
            for (int n = 0; n < list.Count; n++)
            {
                BeatmapObjectData beatmapObjectData2 = list[n];
                int lineIndex = beatmapObjectData2.lineIndex;
                array3[lineIndex].beatmapObjectsData[array[lineIndex]] = beatmapObjectData2;
                array[lineIndex]++;
            }
            CustomBeatmapEventData[] array4 = new CustomBeatmapEventData[beatmapData.beatmapEventData.Length];
            for (int num5 = 0; num5 < beatmapData.beatmapEventData.Length; num5++)
            {
                CustomBeatmapEventData beatmapEventData = beatmapData.beatmapEventData[num5] as CustomBeatmapEventData;
                if (beatmapEventData == null)
                {
                    continue;
                }
                array4[num5] = beatmapEventData;
            }

            if (beatmapData is CustomBeatmapData customBeatmap)
            {
                __result = new CustomBeatmapData(array3, array4, customBeatmap.customEventData, customBeatmap.beatmapCustomData, customBeatmap.levelCustomData);
            }
            else
            {
                __result = new BeatmapData(array3, array4);
            }
            return(false);
        }