summary refs log blame commit diff stats
path: root/Requirements.cs
blob: 1613a47ac474209e2d98275aa97530adbe97c654 (plain) (tree)


















































                                                                     





                            
                                                        
                                         














                                                             
                                        
         









                                                        




















                                                                                                   
                                        
         









                                                        

















                                                                                                  
                                        
         
                                                                                             

















                                                 
                                        
         
                                                                                                   


















                                                           
                                        
         






                                                                                      


















                                                           
                                        
         






                                                                                      


















                                                     
                                        
         






                                                                                


















                                                                   
                                        
         






                                                                                              


















                                                           
                                        
         






                                                                                      






                                         











                                                                                                     









                                                           
                                        
         












                                                   






                                          
using System.Collections.Generic;
using System.Linq;

namespace ManifoldGardenArchipelago
{
    public struct RequirementReferences
    {
        public RequirementReferences() { }

        public readonly HashSet<string> scenes = [];
        public readonly HashSet<SceneItemReference> buttons = [];
        public readonly HashSet<SceneItemReference> sockets = [];
        public readonly HashSet<SceneItemReference> pads = [];
        public readonly HashSet<SceneItemReference> waterwheels = [];
        public readonly HashSet<SceneItemReference> spheres = [];
        public readonly HashSet<string> items = [];

        public void Merge(RequirementReferences other)
        {
            foreach (var item in other.scenes)
            {
                scenes.Add(item);
            }
            foreach (var item in other.buttons)
            {
                buttons.Add(item);
            }
            foreach (var item in other.sockets)
            {
                sockets.Add(item);
            }
            foreach (var item in other.pads)
            {
                pads.Add(item);
            }
            foreach (var item in other.waterwheels)
            {
                waterwheels.Add(item);
            }
            foreach (var item in other.spheres)
            {
                spheres.Add(item);
            }
            foreach (var item in other.items)
            {
                items.Add(item);
            }
        }
    }

    public abstract class Requirement
    {
        public enum Decision
        {
            Maybe,
            No,
            Yes,
        }

        public RequirementReferences references = new();

        public abstract Decision Check();
    }

    public class AndRequirement : Requirement
    {
        private readonly List<Requirement> _requirements;

        public AndRequirement(List<Requirement> requirements)
        {
            _requirements = requirements;

            foreach (var subreq in _requirements)
            {
                references.Merge(subreq.references);
            }
        }

        public override Decision Check()
        {
            foreach (var requirement in _requirements)
            {
                Decision decision = requirement.Check();

                if (decision != Decision.Yes)
                {
                    return decision;
                }
            }

            return Decision.Yes;
        }

        public override string ToString()
        {
            return "And(" + string.Join(", ", _requirements.Select((req) => req.ToString())) + ")";
        }
    }

    public class OrRequirement : Requirement
    {
        private readonly List<Requirement> _requirements;

        public OrRequirement(List<Requirement> requirements)
        {
            _requirements = requirements;

            foreach (var subreq in _requirements)
            {
                references.Merge(subreq.references);
            }
        }

        public override Decision Check()
        {
            foreach (var requirement in _requirements)
            {
                Decision decision = requirement.Check();

                if (decision != Decision.No)
                {
                    return decision;
                }
            }

            return Decision.No;
        }

        public override string ToString()
        {
            return "Or(" + string.Join(", ", _requirements.Select((req) => req.ToString())) + ")";
        }
    }

    public class ItemRequirement : Requirement
    {
        private readonly string _itemName;

        public ItemRequirement(string itemName)
        {
            _itemName = itemName;

            references.items.Add(itemName);
        }

        public override Decision Check()
        {
            return Plugin.archipelagoManager.HasItem(_itemName) ? Decision.Yes : Decision.No;
        }

        public override string ToString()
        {
            return $"Item({_itemName})";
        }
    }

    public class EntryRequirement : Requirement
    {
        private readonly string _sceneName;

        public EntryRequirement(string sceneName)
        {
            _sceneName = sceneName;

            references.scenes.Add(sceneName);
        }

        public override Decision Check()
        {
            return Plugin.slotSave.VisitedScenes.Contains(_sceneName) ? Decision.Yes : Decision.No;
        }

        public override string ToString()
        {
            return $"Entry({_sceneName})";
        }
    }

    public class ButtonRequirement : Requirement
    {
        private readonly SceneItemReference _button;

        public ButtonRequirement(SceneItemReference button)
        {
            _button = button;

            references.scenes.Add(button.scene);
            references.buttons.Add(button);
        }

        public override Decision Check()
        {
            if (Plugin.slotSave.ActivatedButtons.TryGetValue(_button, out bool value))
            {
                return value ? Decision.Yes : Decision.No;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Button{_button}";
        }
    }

    public class SocketRequirement : Requirement
    {
        private readonly SceneItemReference _socket;

        public SocketRequirement(SceneItemReference socket)
        {
            _socket = socket;

            references.scenes.Add(socket.scene);
            references.sockets.Add(socket);
        }

        public override Decision Check()
        {
            if (Plugin.slotSave.ActivatedSockets.TryGetValue(_socket, out bool value))
            {
                return value ? Decision.Yes : Decision.No;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Socket{_socket}";
        }
    }

    public class PadRequirement : Requirement
    {
        private readonly SceneItemReference _pad;

        public PadRequirement(SceneItemReference pad)
        {
            _pad = pad;

            references.scenes.Add(pad.scene);
            references.pads.Add(pad);
        }

        public override Decision Check()
        {
            if (Plugin.slotSave.ActivatedPads.TryGetValue(_pad, out bool value))
            {
                return value ? Decision.Yes : Decision.No;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Pad{_pad}";
        }
    }

    public class WaterwheelRequirement : Requirement
    {
        private readonly SceneItemReference _waterwheel;

        public WaterwheelRequirement(SceneItemReference waterwheel)
        {
            _waterwheel = waterwheel;

            references.scenes.Add(waterwheel.scene);
            references.waterwheels.Add(waterwheel);
        }

        public override Decision Check()
        {
            if (Plugin.slotSave.ActivatedWaterwheels.TryGetValue(_waterwheel, out bool value))
            {
                return value ? Decision.Yes : Decision.No;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Waterwheel{_waterwheel}";
        }
    }

    public class SphereRequirement : Requirement
    {
        private readonly SceneItemReference _sphere;

        public SphereRequirement(SceneItemReference sphere)
        {
            _sphere = sphere;

            references.scenes.Add(sphere.scene);
            references.spheres.Add(sphere);
        }

        public override Decision Check()
        {
            if (Plugin.slotSave.ActivatedSpheres.TryGetValue(_sphere, out bool value))
            {
                return value ? Decision.Yes : Decision.No;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Sphere{_sphere}";
        }
    }

    public class FullGardenRequirement : Requirement
    {
        public override Decision Check()
        {
            return GameManager.MandalaManager.PlacedGodCubes.Count == 6 ? Decision.Yes : Decision.No;
        }

        public override string ToString()
        {
            return "FullGarden";
        }
    }

    public class InvertedRequirement : Requirement
    {
        private readonly Requirement _requirement;

        public InvertedRequirement(Requirement requirement)
        {
            _requirement = requirement;

            references = requirement.references;
        }

        public override Decision Check()
        {
            Decision subdec = _requirement.Check();

            if (subdec == Decision.Yes)
            {
                return Decision.No;
            }
            else if (subdec == Decision.No)
            {
                return Decision.Yes;
            }
            else
            {
                return Decision.Maybe;
            }
        }

        public override string ToString()
        {
            return $"Not({_requirement})";
        }
    }
}