コード例 #1
0
    private static IEnumerator InstantiateComponents(Bomb bomb)
    {
        yield return(new WaitUntil(() => modsLoading == 0 && bombQueue.Count != 0 && bombQueue.Peek() == bomb));

        var bombGenerator = SceneManager.Instance.GameplayState.GetValue <BombGenerator>("bombGenerator");

        bombGenerator.SetValue("bomb", bomb);
        var logger = bombGenerator.GetValue <ILog>("logger");

        // Enable logging again
        ((log4net.Repository.Hierarchy.Logger)logger.Logger).Level = null;

        var validBombFaces = new List <BombFace>(bomb.Faces.Where(face => face.ComponentSpawnPoints.Count != 0));

        bombGenerator.SetValue("validBombFaces", validBombFaces);

        List <KMBombInfo> knownBombInfos = new List <KMBombInfo>();

        foreach (KMBombInfo item in UnityEngine.Object.FindObjectsOfType <KMBombInfo>())
        {
            knownBombInfos.Add(item);
        }

        var bombInfo  = allBombInfo[bomb];
        var timerFace = bombInfo.TimerFace;
        var setting   = bombInfo.Settings;

        bombInfo.EnableOriginal = true;
        bombGenerator.SetValue("rand", bombInfo.Rand);   // Bring back the real Random object.
        UnityEngine.Random.InitState(bomb.Seed);         // Loading AudioClips triggers RNG calls so we need to reset the RNG to before that happened.

        // Emulate logging messages
        logger.InfoFormat("Generating bomb with seed {0}", bomb.Seed);
        logger.InfoFormat("Generator settings: {0}", setting.ToString());

        foreach (var component in bombInfo.Components)
        {
            logger.InfoFormat("Selected {0} ({1})", Modes.GetModuleID(component), component);
        }

        var requiresTimer = bombInfo.Components.Where(component => component.RequiresTimerVisibility).Select(Modes.GetModuleID).ToArray();
        var anyFace       = bombInfo.Components.Where(component => !component.RequiresTimerVisibility).Select(Modes.GetModuleID).ToArray();

        logger.DebugFormat("Bomb component list: RequiresTimerVisibility [{0}], AnyFace: [{1}]", string.Join(", ", requiresTimer), string.Join(", ", anyFace));

        logger.DebugFormat("Instantiating RequiresTimerVisibility components on {0}", timerFace);

        // Spawn components
        bool loggedRemaining = false;

        foreach (var bombComponent in bombInfo.Components.OrderByDescending(component => component.RequiresTimerVisibility))
        {
            BombFace face = null;
            if (bombComponent.RequiresTimerVisibility && timerFace.ComponentSpawnPoints.Count != 0)
            {
                face = timerFace;
            }
            else if (!loggedRemaining)
            {
                logger.Debug("Instantiating remaining components on any valid face.");
                loggedRemaining = true;
            }

            if (face == null && validBombFaces.Count != 0)
            {
                face = validBombFaces[bombInfo.Rand.Next(0, validBombFaces.Count)];
            }

            if (face == null)
            {
                Tweaks.Log("No valid faces remain to instantiate:", bombComponent.name);
                continue;
            }

            bombGenerator.CallMethod("InstantiateComponent", face, bombComponent, setting);
        }

        logger.Debug("Filling remaining spaces with empty components.");
        while (validBombFaces.Count > 0)
        {
            bombGenerator.CallMethod("InstantiateComponent", validBombFaces[0], bombGenerator.emptyComponentPrefab, setting);
        }

        // We need to re-Init() the bomb face selectables so that the components get their correct X and Y positions for Gamepad support.
        foreach (Selectable selectable in bomb.Faces.Select(face => face.GetComponent <Selectable>()))
        {
            selectable.Init();
        }

        logger.Debug("Generating Widgets");

        // To ensure that the widgets get placed in the right position, we need to temporarily revert the bomb's size.
        bomb.visualTransform.localScale = Vector3.one;

        WidgetGenerator generator = bombGenerator.GetComponent <WidgetGenerator>();

        generator.SetValue("zones", bombInfo.WidgetZones);
        generator.GenerateWidgets(bomb.WidgetManager, setting.OptionalWidgetCount);

        bomb.visualTransform.localScale = new Vector3(bomb.Scale, bomb.Scale, bomb.Scale);

        bombInfo.Loaded = true;

        HookUpMultipleBombs(bomb, knownBombInfos);

        bombQueue.Dequeue();

        if (BombsLoaded)
        {
            SceneManager.Instance.GameplayState.Bombs.AddRange(allBombInfo.Keys);
            allBombInfo.Clear();

            // This fixes the bomb not getting picked up correctly if clicked on before loading is finished.
            var holdable = KTInputManager.Instance.SelectableManager.GetCurrentFloatingHoldable();
            if (holdable)
            {
                holdable.Defocus(false, false);
            }
        }

        // Solve any fake modules
        foreach (BombComponent component in bomb.BombComponents)
        {
            if (component.GetComponent <FakeModule>() != null)
            {
                component.IsSolved = true;
                component.Bomb.OnPass(component);
            }
        }
    }
コード例 #2
0
    private static IEnumerator InstantiateComponents(Bomb bomb)
    {
        yield return(new WaitUntil(() => modsLoading == 0));

        var bombGenerator = SceneManager.Instance.GameplayState.GetValue <BombGenerator>("bombGenerator");

        bombGenerator.SetValue("bomb", bomb);

        var validBombFaces = new List <BombFace>(bomb.Faces.Where(face => face.ComponentSpawnPoints.Count != 0));

        bombGenerator.SetValue("validBombFaces", validBombFaces);

        List <KMBombInfo> knownBombInfos = new List <KMBombInfo>();

        foreach (KMBombInfo item in UnityEngine.Object.FindObjectsOfType <KMBombInfo>())
        {
            knownBombInfos.Add(item);
        }

        var bombInfo  = allBombInfo[bomb];
        var timerFace = bombInfo.TimerFace;
        var setting   = bombInfo.Settings;

        bombInfo.EnableOriginal = true;
        bombGenerator.SetValue("rand", bombInfo.Rand);   // Bring back the real Random object.
        UnityEngine.Random.InitState(bomb.Seed);         // Loading AudioClips triggers RNG calls so we need to reset the RNG to before that happened.
        foreach (var bombComponent in bombInfo.Components.OrderByDescending(component => component.RequiresTimerVisibility))
        {
            BombFace face = null;
            if (bombComponent.RequiresTimerVisibility && timerFace.ComponentSpawnPoints.Count != 0)
            {
                face = timerFace;
            }

            if (face == null && validBombFaces.Count != 0)
            {
                face = validBombFaces[bombInfo.Rand.Next(0, validBombFaces.Count)];
            }

            if (face == null)
            {
                Tweaks.Log("No valid faces remain to instantiate:", bombComponent.name);
                continue;
            }

            bombGenerator.CallMethod("InstantiateComponent", face, bombComponent, setting);
        }

        while (validBombFaces.Count > 0)
        {
            bombGenerator.CallMethod("InstantiateComponent", validBombFaces[0], bombGenerator.emptyComponentPrefab, setting);
        }

        // To ensure that the widgets get placed in the right position, we need to temporarily revert the bomb's size.
        bomb.visualTransform.localScale = Vector3.one;

        WidgetGenerator generator = bombGenerator.GetComponent <WidgetGenerator>();

        generator.SetValue("zones", bombInfo.WidgetZones);
        generator.GenerateWidgets(bomb.WidgetManager, setting.OptionalWidgetCount);

        bomb.visualTransform.localScale = new Vector3(bomb.Scale, bomb.Scale, bomb.Scale);

        bombInfo.Loaded = true;

        HookUpMultipleBombs(bomb, knownBombInfos);

        if (BombsLoaded)
        {
            SceneManager.Instance.GameplayState.Bombs.AddRange(allBombInfo.Keys);
            allBombInfo.Clear();

            // This fixes the bomb not getting picked up correctly if clicked on before loading is finished.
            var holdable = KTInputManager.Instance.SelectableManager.GetCurrentFloatingHoldable();
            if (holdable)
            {
                holdable.Defocus(false, false);
            }
        }

        // Solve any fake modules
        foreach (BombComponent component in bomb.BombComponents)
        {
            if (component.GetComponent <FakeModule>() != null)
            {
                component.IsSolved = true;
                component.Bomb.OnPass(component);
            }
        }
    }