Example #1
0
        IEnumerator LoopRoutine()
        {
            MopSettings.IsModActive = true;

            FramerateRecorder rec = gameObject.AddComponent <FramerateRecorder>();

            rec.Initialize();

            while (MopSettings.IsModActive)
            {
                // Ticks make sure that MOP is still up and running.
                // If the ticks didn't update, that means this routine stopped.
                ++ticks;

                if (!itemInitializationDelayDone)
                {
                    // We are slightly delaying the initialization, so all items have chance to set in place, because f**k MSC and its physics.
                    waitTime++;
                    if (waitTime >= WaitDone)
                    {
                        FinishLoading();
                    }
                }

                isPlayerAtYard = MOP.ActiveDistance.Value == 0 ? Vector3.Distance(player.position, placeManager[0].transform.position) < 100
                    : Vector3.Distance(player.position, placeManager[0].transform.position) < 100 * MopSettings.ActiveDistanceMultiplicationValue;

                // When player is in any of the sectors, MOP will act like the player is at yard.
                if (SectorManager.Instance.IsPlayerInSector())
                {
                    inSectorMode   = true;
                    isPlayerAtYard = true;
                }
                else
                {
                    inSectorMode = false;
                }

                yield return(null);

                int  i;
                long half = worldObjectManager.Count >> 1;
                // World Objects.
                for (i = 0; i < worldObjectManager.Count; ++i)
                {
                    if (i == half)
                    {
                        yield return(null);
                    }

                    try
                    {
                        GenericObject worldObject = worldObjectManager[i];

                        // Check if object was destroyed (mostly intended for AI pedastrians).
                        if (worldObject.GameObject == null)
                        {
                            worldObjectManager.Remove(worldObject);
                            continue;
                        }

                        if (SectorManager.Instance.IsPlayerInSector() && SectorManager.Instance.SectorRulesContains(worldObject.GameObject.name))
                        {
                            worldObject.GameObject.SetActive(true);
                            continue;
                        }

                        // Should the object be disabled when the player leaves the house?
                        if (worldObject.DisableOn.HasFlag(DisableOn.PlayerAwayFromHome) || worldObject.DisableOn.HasFlag(DisableOn.PlayerInHome))
                        {
                            if (worldObject.GameObject.name == "NPC_CARS" && inSectorMode)
                            {
                                continue;
                            }

                            if (worldObject.GameObject.name == "COMPUTER" && worldObject.GameObject.transform.Find("SYSTEM").gameObject.activeSelf)
                            {
                                continue;
                            }

                            worldObject.Toggle(worldObject.DisableOn.HasFlag(DisableOn.PlayerAwayFromHome) ? isPlayerAtYard : !isPlayerAtYard);
                        }
                        else if (worldObject.DisableOn.HasFlag(DisableOn.Distance))
                        {
                            // The object will be disabled, if the player is in the range of that object.
                            worldObject.Toggle(IsEnabled(worldObject.transform, worldObject.Distance));
                        }
                    }
                    catch (Exception ex)
                    {
                        ExceptionManager.New(ex, false, "WORLD_OBJECT_TOGGLE_ERROR");
                    }
                }

                // Safe mode prevents toggling elemenets that MAY case some issues (vehicles, items, etc.)
                if (MopSettings.Mode == PerformanceMode.Safe)
                {
                    yield return(new WaitForSeconds(.7f));

                    continue;
                }

                // So we create two separate lists - one is meant to enable, and second is ment to disable them,
                // Why?
                // If we enable items before enabling vehicle inside of which these items are supposed to be, they'll fall through to ground.
                // And the opposite happens if we disable vehicles before disabling items.
                // So if we are disabling items, we need to do that BEFORE we disable vehicles.
                // And we need to enable items AFTER we enable vehicles.
                itemsToEnable.Clear();
                itemsToDisable.Clear();
                half = ItemsManager.Instance.Count >> 1;
                for (i = 0; i < ItemsManager.Instance.Count; ++i)
                {
                    if (i == half)
                    {
                        yield return(null);
                    }

                    // Safe check if somehow the i gets bigger than array length.
                    if (i >= ItemsManager.Instance.Count)
                    {
                        break;
                    }

                    try
                    {
                        ItemBehaviour item = ItemsManager.Instance[i];

                        if (item == null || item.gameObject == null)
                        {
                            itemsToRemove.Add(item);
                            continue;
                        }

                        // Check the mode in what MOP is supposed to run and adjust to it.
                        bool toEnable = true;
                        if (MopSettings.Mode == 0)
                        {
                            toEnable = IsEnabled(item.transform, FsmManager.IsPlayerInCar() && !isPlayerAtYard ? 20 : 150);
                        }
                        else
                        {
                            toEnable = IsEnabled(item.transform, 150);
                        }

                        if (toEnable)
                        {
                            item.ToggleChangeFix();
                            if (item.ActiveSelf)
                            {
                                continue;
                            }
                            itemsToEnable.Add(item);
                        }
                        else
                        {
                            if (!item.ActiveSelf)
                            {
                                continue;
                            }
                            itemsToDisable.Add(item);
                        }

                        if (item.rb != null && item.rb.IsSleeping())
                        {
                            if (item.IsPartMagnetAttached())
                            {
                                continue;
                            }
                            if (CompatibilityManager.IsInBackpack(item))
                            {
                                continue;
                            }
                            item.rb.isKinematic = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        ExceptionManager.New(ex, false, "ITEM_TOGGLE_GATHER_ERROR");
                    }
                }

                // Items To Disable
                int full = itemsToDisable.Count;
                if (full > 0)
                {
                    half = itemsToDisable.Count >> 1;
                    for (i = 0; i < full; ++i)
                    {
                        if (half != 0 && i == half)
                        {
                            yield return(null);
                        }

                        try
                        {
                            itemsToDisable[i].Toggle(false);
                        }
                        catch (Exception ex)
                        {
                            ExceptionManager.New(ex, false, "ITEM_TOGGLE_DISABLE_ERROR - " + itemsToDisable[i] != null ? itemsToDisable[i].gameObject.name : "null");
                        }
                    }
                }

                // Vehicles (new)
                half = vehicleManager.Count >> 1;
                for (i = 0; i < vehicleManager.Count; ++i)
                {
                    if (half != 0 && i == half)
                    {
                        yield return(null);
                    }

                    try
                    {
                        if (vehicleManager[i] == null)
                        {
                            vehicleManager.RemoveAt(i);
                            continue;
                        }

                        float distance       = Vector3.Distance(player.transform.position, vehicleManager[i].transform.position);
                        float toggleDistance = MOP.ActiveDistance.Value == 0
                            ? MopSettings.UnityCarActiveDistance : MopSettings.UnityCarActiveDistance * MopSettings.ActiveDistanceMultiplicationValue;

                        switch (vehicleManager[i].VehicleType)
                        {
                        case VehiclesTypes.Satsuma:
                            Satsuma.Instance.ToggleElements(distance);
                            vehicleManager[i].ToggleEventSounds(distance < 3);
                            break;

                        case VehiclesTypes.Jonnez:
                            vehicleManager[i].ToggleEventSounds(distance < 2);
                            break;
                        }

                        vehicleManager[i].ToggleUnityCar(IsVehiclePhysicsEnabled(distance, toggleDistance));
                        vehicleManager[i].Toggle(IsVehicleEnabled(distance));
                    }
                    catch (Exception ex)
                    {
                        ExceptionManager.New(ex, false, $"VEHICLE_TOGGLE_ERROR_{i}");
                    }
                }

                // Items To Enable
                full = itemsToEnable.Count;
                if (full > 0)
                {
                    half = full >> 1;
                    for (i = 0; i < full; ++i)
                    {
                        if (half != 0 && i == half)
                        {
                            yield return(null);
                        }

                        try
                        {
                            itemsToEnable[i].Toggle(true);
                        }
                        catch (Exception ex)
                        {
                            ExceptionManager.New(ex, false, "ITEM_TOGGLE_ENABLE_ERROR - " + itemsToEnable[i] != null ? itemsToDisable[i].gameObject.name : "null");
                        }
                    }
                }

                // Places (New)
                full = placeManager.Count;
                half = full >> 1;
                for (i = 0; i < full; ++i)
                {
                    if (i == half)
                    {
                        yield return(null);
                    }

                    try
                    {
                        if (SectorManager.Instance.IsPlayerInSector() && SectorManager.Instance.SectorRulesContains(placeManager[i].GetName()))
                        {
                            continue;
                        }

                        placeManager[i].ToggleActive(IsPlaceEnabled(placeManager[i].transform, placeManager[i].GetToggleDistance()));
                    }
                    catch (Exception ex)
                    {
                        ExceptionManager.New(ex, false, $"PLACE_TOGGLE_ERROR_{i}");
                    }
                }

                // Remove items that don't exist anymore.
                if (itemsToRemove.Count > 0)
                {
                    for (i = itemsToRemove.Count - 1; i >= 0; --i)
                    {
                        ItemsManager.Instance.RemoveAt(i);
                    }

                    itemsToRemove.Clear();
                }

                yield return(new WaitForSeconds(.7f));

                if (retries > 0 && !restartSucceedMessaged)
                {
                    restartSucceedMessaged = true;
                    ModConsole.Log("<color=green>[MOP] Restart succeeded!</color>");
                }
            }
        }
Example #2
0
        /// <summary>
        /// Toggles some of the elements of that car, depneding on the of player to Satsuma.
        /// </summary>
        /// <param name="distance"></param>
        public void ToggleElements(float distance)
        {
            if (Toggle == IgnoreToggle)
            {
                distance = 0;
            }

            try
            {
                bool onEngine = distance < 2;
                bool onClose  = distance <= 10 * MopSettings.ActiveDistanceMultiplicationValue;
                bool onFar    = distance <= 20 * MopSettings.ActiveDistanceMultiplicationValue;

                if (IsKeyInserted() || IsSatsumaInInspectionArea || IsMoving())
                {
                    onEngine = true;
                    onClose  = true;
                    onFar    = true;
                }

                for (int i = 0; i < onEngineOffToggle.Count; i++)
                {
                    onEngineOffToggle[i].SetActive(onEngine);
                }

                for (int i = 0; i < onCloseToggle.Count; i++)
                {
                    onCloseToggle[i].SetActive(onClose);
                }

                for (int i = 0; i < onCloseTogglePlayMaker.Count; i++)
                {
                    onCloseTogglePlayMaker[i].enabled = onClose;
                }

                for (int i = 0; i < onFarToggle.Count; i++)
                {
                    onFarToggle[i].SetActive(onFar);
                }

                // This script fixes the issue with bolts staying unbolted, with parts internally being fully bolted.
                if (onEngine && maskedFixStages < 2)
                {
                    switch (maskedFixStages)
                    {
                    case 0:
                        for (int i = 0; i < maskedElements.Count; i++)
                        {
                            maskedElements.ElementAt(i).Key.SetActive(true);
                        }
                        break;

                    case 1:
                        for (int i = 0; i < maskedElements.Count; i++)
                        {
                            maskedElements.ElementAt(i).Key.SetActive(maskedElements.ElementAt(i).Value);
                        }
                        break;
                    }
                    maskedFixStages++;
                }
            }
            catch (System.Exception ex)
            {
                ExceptionManager.New(ex, "SATSUMA_TOGGLE_ELEMENTS_ERROR");
            }
        }
Example #3
0
        /// <summary>
        /// Looks for gamobject named SAVEGAME, and hooks PreSaveGame into them.
        /// </summary>
        void HookPreSaveGame()
        {
            try
            {
                GameObject[] saveGames = Resources.FindObjectsOfTypeAll <GameObject>()
                                         .Where(obj => obj.name.Contains("SAVEGAME")).ToArray();

                int i = 0;
                for (; i < saveGames.Length; i++)
                {
                    bool useInnactiveFix = false;
                    bool isJail          = false;

                    if (!saveGames[i].activeSelf)
                    {
                        useInnactiveFix = true;
                        saveGames[i].SetActive(true);
                    }

                    if (saveGames[i].transform.parent != null && saveGames[i].transform.parent.name == "JAIL" && saveGames[i].transform.parent.gameObject.activeSelf == false)
                    {
                        useInnactiveFix = true;
                        isJail          = true;
                        saveGames[i].transform.parent.gameObject.SetActive(true);
                    }

                    FsmHook.FsmInject(saveGames[i], "Mute audio", PreSaveGame);

                    if (useInnactiveFix)
                    {
                        if (isJail)
                        {
                            saveGames[i].transform.parent.gameObject.SetActive(false);
                            continue;
                        }

                        saveGames[i].SetActive(false);
                    }
                }

                // Hooking up on death save.
                GameObject onDeathSaveObject = new GameObject("MOP_OnDeathSave");
                onDeathSaveObject.transform.parent = GameObject.Find("Systems").transform.Find("Death/GameOverScreen");
                OnDeathBehaviour behaviour = onDeathSaveObject.AddComponent <OnDeathBehaviour>();
                behaviour.Initialize(PreSaveGame);
                i++;

                // Adding custom action to state that will trigger PreSaveGame, if the player picks up the phone with large Suski.
                PlayMakerFSM          useHandleFSM     = GameObject.Find("Telephone").transform.Find("Logic/UseHandle").GetComponent <PlayMakerFSM>();
                FsmState              phoneFlip        = useHandleFSM.GetState("Pick phone");
                List <FsmStateAction> phoneFlipActions = phoneFlip.Actions.ToList();
                phoneFlipActions.Insert(0, new CustomSuskiLargeFlip());
                phoneFlip.Actions = phoneFlipActions.ToArray();
                i++;

                ModConsole.Log($"[MOP] Hooked {i} save points!");
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, true, "SAVE_HOOK_ERROR");
            }
        }
Example #4
0
        /// <summary>
        /// Toggles on all objects.
        /// </summary>
        public void ToggleAll(bool enabled, ToggleAllMode mode = ToggleAllMode.Default)
        {
            // World objects
            for (int i = 0; i < worldObjectManager.Count; i++)
            {
                try
                {
                    worldObjectManager[i].Toggle(enabled);
                }
                catch (Exception ex)
                {
                    ExceptionManager.New(ex, false, "TOGGLE_ALL_WORLD_OBJECTS_ERROR");
                }
            }

            if (MopSettings.Mode == PerformanceMode.Safe)
            {
                return;
            }

            // Items
            for (int i = 0; i < ItemsManager.Instance.Count; i++)
            {
                try
                {
                    ItemBehaviour item = ItemsManager.Instance[i];
                    item.Toggle(enabled);

                    // We're freezing the object on save, so it won't move at all.
                    if (mode == ToggleAllMode.OnSave)
                    {
                        item.gameObject.SetActive(true);
                        item.Freeze();
                        item.SaveGame();
                    }
                }
                catch (Exception ex)
                {
                    ExceptionManager.New(ex, false, "TOGGLE_ALL_ITEMS_ERROR");
                }
            }

            // Find all kilju, emptyca, empty juice container, and force empty them if applicable
            try
            {
                IEnumerable <GameObject> bottles = Resources.FindObjectsOfTypeAll <GameObject>().Where(g => g.name.ContainsAny("kilju", "emptyca", "empty plastic can"));
                foreach (GameObject bottle in bottles)
                {
                    bottle.GetComponent <ItemBehaviour>()?.ResetKiljuContainer();
                    if (mode == ToggleAllMode.OnSave)
                    {
                        bottle.SetActive(true);
                        bottle.GetComponent <ItemBehaviour>()?.SaveGame();
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "KILJU_RESET_FORCE_ERROR");
            }

            // Vehicles
            for (int i = 0; i < vehicleManager.Count; i++)
            {
                try
                {
                    vehicleManager[i].Toggle(enabled);

                    if (mode == ToggleAllMode.OnLoad)
                    {
                        vehicleManager[i].ForceToggleUnityCar(false);
                    }
                    else if (mode == ToggleAllMode.OnSave)
                    {
                        vehicleManager[i].ToggleUnityCar(enabled);
                        vehicleManager[i].Freeze();
                    }
                }
                catch (Exception ex)
                {
                    ExceptionManager.New(ex, false, $"TOGGLE_ALL_VEHICLE_ERROR_{i}");
                }
            }


            // Places
            for (int i = 0; i < placeManager.Count; i++)
            {
                try
                {
                    placeManager[i].ToggleActive(enabled);
                }
                catch (Exception ex)
                {
                    ExceptionManager.New(ex, false, $"TOGGLE_ALL_PLACES_{i}");
                }
            }

            // Force teleport kilju bottles.
            try
            {
                if (mode == ToggleAllMode.OnSave)
                {
                    GameObject canTrigger = ItemsManager.Instance.GetCanTrigger();
                    if (canTrigger)
                    {
                        if (!canTrigger.transform.parent.gameObject.activeSelf)
                        {
                            canTrigger.transform.parent.gameObject.SetActive(true);
                        }
                        canTrigger.GetComponent <PlayMakerFSM>().SendEvent("STOP");
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "TOGGLE_ALL_JOBS_DRUNK");
            }

            // ToggleElements class of Satsuma.
            try
            {
                Satsuma.Instance.ToggleElements((mode == ToggleAllMode.OnSave) ? 0 : (enabled ? 0 : 10000));
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "TOGGLE_ALL_SATSUMA_TOGGLE_ELEMENTS");
            }
        }
Example #5
0
        void Initialize()
        {
            instance = this;

            ModConsole.Log("[MOP] Loading MOP...");

            // Initialize the worldObjectManager list
            worldObjectManager = new WorldObjectManager();

            // Looking for player and yard
            player = GameObject.Find("PLAYER").transform;

            // Add GameFixes MonoBehaviour.
            try
            {
                gameObject.AddComponent <GameFixes>();
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, $"GAME_FIXES_INITIALIZAITON | {ex}");
            }

            // Loading vehicles
            vehicleManager = new VehicleManager();

            // World Objects
            try
            {
                worldObjectManager.Add("CABIN", DisableOn.Distance | DisableOn.IgnoreInQualityMode);
                worldObjectManager.Add("COTTAGE", DisableOn.Distance, 400);
                worldObjectManager.Add("DANCEHALL", DisableOn.Distance, 500);
                worldObjectManager.Add("PERAJARVI", DisableOn.Distance | DisableOn.IgnoreInQualityMode, 400);
                worldObjectManager.Add("SOCCER", DisableOn.Distance);
                worldObjectManager.Add("WATERFACILITY", DisableOn.Distance, 300);
                worldObjectManager.Add("DRAGRACE", DisableOn.Distance, 1100);
                worldObjectManager.Add("StrawberryField", DisableOn.Distance, 400);
                worldObjectManager.Add("MAP/Buildings/DINGONBIISI", DisableOn.Distance, 400);
                worldObjectManager.Add("RALLY/PartsSalesman", DisableOn.Distance, 400);
                worldObjectManager.Add("LakeSmallBottom1", DisableOn.Distance, 500);
                worldObjectManager.Add("machine", DisableOn.Distance, 200, silent: true);

                ModConsole.Log("[MOP] World objects (1) loaded");
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "WORLD_OBJECTS_1_INITIALIZAITON_FAIL");
            }

            // Initialize places.
            placeManager = new PlaceManager();

            // Fixes
            GameFixes.Instance.MainFixes();

            //Things that should be enabled when out of proximity of the house
            try
            {
                worldObjectManager.Add("NPC_CARS", DisableOn.PlayerInHome);
                worldObjectManager.Add("TRAFFIC", DisableOn.PlayerInHome);
                worldObjectManager.Add("TRAIN", DisableOn.PlayerInHome | DisableOn.IgnoreInQualityMode);
                worldObjectManager.Add("Buildings", DisableOn.PlayerInHome);
                worldObjectManager.Add("TrafficSigns", DisableOn.PlayerInHome);
                worldObjectManager.Add("StreetLights", DisableOn.PlayerInHome);
                worldObjectManager.Add("HUMANS", DisableOn.PlayerInHome);
                worldObjectManager.Add("TRACKFIELD", DisableOn.PlayerInHome);
                worldObjectManager.Add("SkijumpHill", DisableOn.PlayerInHome | DisableOn.IgnoreInQualityMode);
                worldObjectManager.Add("Factory", DisableOn.PlayerInHome);
                worldObjectManager.Add("WHEAT", DisableOn.PlayerInHome);
                worldObjectManager.Add("RAILROAD", DisableOn.PlayerInHome);
                worldObjectManager.Add("AIRPORT", DisableOn.PlayerInHome);
                worldObjectManager.Add("RAILROAD_TUNNEL", DisableOn.PlayerInHome);
                worldObjectManager.Add("PierDancehall", DisableOn.PlayerInHome);
                worldObjectManager.Add("PierRiver", DisableOn.PlayerInHome);
                worldObjectManager.Add("PierStore", DisableOn.PlayerInHome);
                worldObjectManager.Add("BRIDGE_dirt", DisableOn.PlayerInHome);
                worldObjectManager.Add("BRIDGE_highway", DisableOn.PlayerInHome);
                worldObjectManager.Add("BirdTower", DisableOn.Distance, 400);
                worldObjectManager.Add("RYKIPOHJA", DisableOn.PlayerInHome);
                worldObjectManager.Add("COMPUTER", DisableOn.PlayerAwayFromHome);

                ModConsole.Log("[MOP] World objects (2) loaded");
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "WORLD_OBJECTS_2_INITIALIZAITON_FAIL");
            }

            // Adding area check if Satsuma is in the inspection's area
            try
            {
                SatsumaInArea inspectionArea = GameObject.Find("INSPECTION").AddComponent <SatsumaInArea>();
                inspectionArea.Initialize(new Vector3(20, 20, 20));
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "SATSUMA_AREA_CHECK_INSPECTION_FAIL");
            }

            // Check for when Satsuma is on the lifter
            try
            {
                SatsumaInArea lifterArea = GameObject.Find("REPAIRSHOP/Lifter/Platform").AddComponent <SatsumaInArea>();
                lifterArea.Initialize(new Vector3(5, 5, 5));
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "SATSUMA_AREA_CHECK_REPAIRSHOP_FAIL");
            }

            // Area for the parc ferme.
            try
            {
                GameObject parcFermeTrigger = new GameObject("MOP_ParcFermeTrigger");
                parcFermeTrigger.transform.parent   = GameObject.Find("RALLY").transform.Find("Scenery");
                parcFermeTrigger.transform.position = new Vector3(-1383f, 3f, 1260f);
                SatsumaInArea parcFerme = parcFermeTrigger.AddComponent <SatsumaInArea>();
                parcFerme.Initialize(new Vector3(41, 12, 35));
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "PARC_FERME_TRIGGER_FAIL");
            }

            ModConsole.Log("[MOP] Satsuma triggers loaded");

            // Jokke's furnitures.
            // Only renderers are going to be toggled.
            try
            {
                if (GameObject.Find("tv(Clo01)"))
                {
                    string[] furnitures = { "tv(Clo01)",    "chair(Clo02)", "chair(Clo05)", "bench(Clo01)",
                                            "bench(Clo02)", "table(Clo02)", "table(Clo03)", "table(Clo04)",
                                            "table(Clo05)", "desk(Clo01)",  "arm chair(Clo01)" };

                    foreach (string furniture in furnitures)
                    {
                        GameObject g = GameObject.Find(furniture);
                        if (g)
                        {
                            g.transform.parent = null;
                            worldObjectManager.Add(g, DisableOn.Distance, 100, ToggleModes.Renderer);
                        }
                    }

                    ModConsole.Log("[MOP] Jokke's furnitures found and loaded");
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "JOKKE_FURNITURE_ERROR");
            }

            // Haybales.
            // First we null out the prevent it from reloading the position of haybales.
            try
            {
                GameObject haybalesParent = GameObject.Find("JOBS/HayBales");
                if (haybalesParent != null)
                {
                    haybalesParent.GetComponent <PlayMakerFSM>().Fsm.RestartOnEnable = false;
                    // And now we add all child haybale to world objects.
                    foreach (Transform haybale in haybalesParent.transform.GetComponentInChildren <Transform>())
                    {
                        worldObjectManager.Add(haybale.gameObject.name, DisableOn.Distance | DisableOn.IgnoreInQualityMode, 120);
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "HAYBALES_FIX_ERROR");
            }

            // Logwalls
            try
            {
                foreach (GameObject wall in Resources.FindObjectsOfTypeAll <GameObject>().Where(g => g.name == "LogwallLarge"))
                {
                    worldObjectManager.Add(wall, DisableOn.Distance, 300);
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "LOGWALL_LOAD_ERROR");
            }

            // Perajarvi Church.
            try
            {
                if (MopSettings.Mode != PerformanceMode.Performance)
                {
                    GameObject church = GameObject.Find("PERAJARVI").transform.Find("CHURCH").gameObject;
                    church.transform.parent = null;
                    GameObject churchLOD = church.transform.Find("LOD").gameObject;
                    church.GetComponent <PlayMakerFSM>().enabled = false;
                    worldObjectManager.Add(churchLOD, DisableOn.Distance, 300);
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "CHURCH_LOD_ERROR");
            }

            // Lake houses.
            try
            {
                if (MopSettings.Mode == PerformanceMode.Quality)
                {
                    GameObject.Find("PERAJARVI").transform.Find("TerraceHouse").transform.parent = null;
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "LAKE_HOUSE_ERROR");
            }

            // VehiclesHighway renderers.
            try
            {
                Transform vehiclesHighway = GameObject.Find("TRAFFIC").transform.Find("VehiclesHighway");
                foreach (var f in vehiclesHighway.GetComponentsInChildren <Transform>(true).Where(f => f.parent == vehiclesHighway))
                {
                    worldObjectManager.Add(f.gameObject, DisableOn.Distance, 600, ToggleModes.MultipleRenderers);
                }

                // Also we gonna fix the lag on initial traffic load.
                vehiclesHighway.gameObject.SetActive(true);
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "TRAFFIC_VEHICLES_ERROR");
            }

            // FITTAN renderers.
            try
            {
                worldObjectManager.Add(GameObject.Find("TRAFFIC").transform.Find("VehiclesDirtRoad/Rally/FITTAN").gameObject, DisableOn.Distance, 600, ToggleModes.MultipleRenderers);
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "FITTAN_RENDERERS_ERROR");
            }

            // Initialize Items class
            try
            {
                new ItemsManager();
                ItemsManager.Instance.Initialize();
                ModConsole.Log("[MOP] Items class initialized");
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, true, "ITEMS_CLASS_ERROR");
            }

            try
            {
                DateTime now = DateTime.Now;
                if (now.Day == 1 && now.Month == 4)
                {
                    GameObject     fpsObject = GameObject.Find("GUI").transform.Find("HUD/FPS/HUDValue").gameObject;
                    PlayMakerFSM[] fsms      = fpsObject.GetComponents <PlayMakerFSM>();
                    foreach (var fsm in fsms)
                    {
                        fsm.enabled = false;
                    }
                    fpsObject.GetComponent <TextMesh>().text = "99999999 :)";
                    fpsObject.transform.Find("HUDValueShadow").GetComponent <TextMesh>().text = "99999999 :)";
                }
            }
            catch { }

            HookPreSaveGame();

            ModConsole.Log("[MOP] Loading rules...");
            foreach (ToggleRule v in RulesManager.Instance.ToggleRules)
            {
                try
                {
                    switch (v.ToggleMode)
                    {
                    default:
                        ModConsole.LogError($"[MOP] Unrecognized toggle mode for {v.ObjectName}: {v.ToggleMode}.");
                        break;

                    case ToggleModes.Simple:
                        if (GameObject.Find(v.ObjectName) == null)
                        {
                            ModConsole.LogError($"[MOP] Couldn't find world object {v.ObjectName}");
                            continue;
                        }

                        worldObjectManager.Add(v.ObjectName, DisableOn.Distance);
                        break;

                    case ToggleModes.Renderer:
                        if (GameObject.Find(v.ObjectName) == null)
                        {
                            ModConsole.LogError($"[MOP] Couldn't find world object {v.ObjectName}");
                            continue;
                        }

                        worldObjectManager.Add(v.ObjectName, DisableOn.Distance, 200, ToggleModes.Renderer);
                        break;

                    case ToggleModes.Item:
                        GameObject g = GameObject.Find(v.ObjectName);

                        if (g == null)
                        {
                            ModConsole.LogError($"[MOP] Couldn't find item {v.ObjectName}");
                            continue;
                        }

                        if (g.GetComponent <ItemBehaviour>() == null)
                        {
                            g.AddComponent <ItemBehaviour>();
                        }
                        break;

                    case ToggleModes.Vehicle:
                        if (RulesManager.Instance.SpecialRules.IgnoreModVehicles)
                        {
                            continue;
                        }

                        if (GameObject.Find(v.ObjectName) == null)
                        {
                            ModConsole.LogError($"[MOP] Couldn't find vehicle {v.ObjectName}");
                            continue;
                        }

                        vehicleManager.Add(new Vehicle(v.ObjectName));
                        break;

                    case ToggleModes.VehiclePhysics:
                        if (RulesManager.Instance.SpecialRules.IgnoreModVehicles)
                        {
                            continue;
                        }

                        if (GameObject.Find(v.ObjectName) == null)
                        {
                            ModConsole.LogError($"[MOP] Couldn't find vehicle {v.ObjectName}");
                            continue;
                        }
                        vehicleManager.Add(new Vehicle(v.ObjectName));
                        Vehicle veh = vehicleManager[vehicleManager.Count - 1];
                        veh.Toggle = veh.ToggleUnityCar;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    ExceptionManager.New(ex, false, "TOGGLE_RULES_LOAD_ERROR");
                }
            }

            ModConsole.Log("[MOP] Rules loading complete!");

            // Initialzie sector manager
            try
            {
                gameObject.AddComponent <SectorManager>();
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, true, "SECTOR_MANAGER_ERROR");
            }

            // Add DynamicDrawDistance component.
            try
            {
                gameObject.AddComponent <DynamicDrawDistance>();
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, false, "DYNAMIC_DRAW_DISTANCE_ERROR");
            }

            try
            {
                if (MopSettings.Mode != PerformanceMode.Safe)
                {
                    ToggleAll(false, ToggleAllMode.OnLoad);
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.New(ex, true, "TOGGLE_ALL_ERROR");
            }

            // Initialize the coroutines.
            currentLoop = LoopRoutine();
            StartCoroutine(currentLoop);
            currentControlCoroutine = ControlCoroutine();
            StartCoroutine(currentControlCoroutine);

            ModConsole.Log("<color=green>[MOP] MOD LOADED SUCCESFULLY!</color>");
            Resources.UnloadUnusedAssets();
            GC.Collect();

            // If generate-list command is set to true, generate the list of items that are disabled by MOP.
            if (MopSettings.GenerateToggledItemsListDebug)
            {
                if (System.IO.File.Exists("world.txt"))
                {
                    System.IO.File.Delete("world.txt");
                }
                string world = "";
                foreach (var w in worldObjectManager.GetList())
                {
                    if (world.Contains(w.GetName()))
                    {
                        continue;
                    }
                    world += w.GetName() + ", ";
                }
                System.IO.File.WriteAllText("world.txt", world);
                System.Diagnostics.Process.Start("world.txt");

                if (System.IO.File.Exists("vehicle.txt"))
                {
                    System.IO.File.Delete("vehicle.txt");
                }
                string vehiclez = "";
                foreach (var w in vehicleManager.List())
                {
                    vehiclez += w.gameObject.name + ", ";
                }
                System.IO.File.WriteAllText("vehicle.txt", vehiclez);
                System.Diagnostics.Process.Start("vehicle.txt");

                if (System.IO.File.Exists("items.txt"))
                {
                    System.IO.File.Delete("items.txt");
                }
                string items = "";
                foreach (var w in ItemsManager.Instance.All())
                {
                    if (items.Contains(w.gameObject.name))
                    {
                        continue;
                    }
                    items += w.gameObject.name + ", ";
                }
                System.IO.File.WriteAllText("items.txt", items);
                System.Diagnostics.Process.Start("items.txt");

                if (System.IO.File.Exists("place.txt"))
                {
                    System.IO.File.Delete("place.txt");
                }
                string place = "";
                foreach (var w in placeManager.GetList())
                {
                    place += w.GetName() + ": ";
                    foreach (var f in w.GetDisableableChilds())
                    {
                        if (place.Contains(f.gameObject.name))
                        {
                            continue;
                        }
                        place += f.gameObject.name + ", ";
                    }

                    place += "\n\n";
                }
                System.IO.File.WriteAllText("place.txt", place);
                System.Diagnostics.Process.Start("place.txt");
            }
        }
Example #6
0
        public SectorManager()
        {
            instance = this;

            ModConsole.Print("[MOP] Loading sectors...");
            activeSectors = new List <Sector>();

            DisabledObjects = new List <GameObject>
            {
                GameObject.Find("ELEC_POLES"),
                GameObject.Find("ELEC_POLES_COLL"),
                GameObject.Find("TREES_MEDIUM3"),
                GameObject.Find("TREES_SMALL1"),
                GameObject.Find("TREES1_COLL"),
                GameObject.Find("TREES2_COLL"),
                GameObject.Find("TREES3_COLL"),
                GameObject.Find("BUSHES3"),
                GameObject.Find("BUSHES6"),
                GameObject.Find("BUSHES7"),
                GameObject.Find("BusStop"),
                GameObject.Find("BusStop 1"),
                GameObject.Find("MachineHall"),
                GameObject.Find("YARD/UNCLE/Shed"),
                GameObject.Find("YARD/UNCLE/Greenhouse"),
                GameObject.Find("YARD/UNCLE/LOD"),
                GameObject.Find("YARD/UNCLE/Home"),
                GameObject.Find("YARD/UNCLE/Building"),
                GameObject.Find("MAP/RadioMast"),
                GameObject.Find("MAP/PierHome"),
                GameObject.Find("MAP/MESH/FOLIAGE/LAKE_VEGETATION")
            };

            GameObject lakeSimpleTile = GameObject.Find("MAP/LakeSimple/Tile");

            if (lakeSimpleTile != null)
            {
                DisabledObjects.Add(lakeSimpleTile);
            }

            GameObject lakeNice = GameObject.Find("MAP/LakeNice");

            if (lakeNice != null)
            {
                DisabledObjects.Add(lakeNice);
            }

            sectors = new List <GameObject>();

            // Load rule files
            if (Rules.instance.IgnoreRules.Count > 0)
            {
                List <GameObject> newList = new List <GameObject>();
                foreach (GameObject obj in DisabledObjects)
                {
                    try
                    {
                        if (obj == null)
                        {
                            continue;
                        }

                        if (!Rules.instance.IgnoreRules.Any(f => f.ObjectName == obj.name))
                        {
                            newList.Add(obj);
                        }
                    }
                    catch (System.Exception ex)
                    {
                        ExceptionManager.New(ex, "SECTOR_RULES_LOAD_ERROR");
                    }
                }
                DisabledObjects = newList;
            }

            // Garage
            CreateNewSector(new Vector3(-16.77627f, -0.5062422f, 1.559867f), new Vector3(5, 5, 9), "PierHome");
            // Teimo
            CreateNewSector(new Vector3(-1547.3f, 4, 1183.35f), new Vector3(9.6f, 5, 5.5f), new Vector3(0, 328, 0),
                            "StreetLights", "HUMANS", "TRAFFIC", "NPC_CARS", "PERAJARVI", "TrafficSigns", "StreetLights", "ELEC_POLES", "TREES_SMALL1");
            CreateNewSector(new Vector3(-1551.7f, 4, 1185.8f), new Vector3(4.6f, 5, 2.5f), new Vector3(0, 328, 0),
                            "StreetLights", "HUMANS", "TRAFFIC", "NPC_CARS", "PERAJARVI", "TrafficSigns", "StreetLights", "ELEC_POLES", "TREES_SMALL1");
            // Repair shop
            CreateNewSector(new Vector3(1562.49f, 4.8f, 733.8835f), new Vector3(15, 5, 20), new Vector3(0, 335, 0), "TRAFFIC", "ELEC_POLES", "Buildings",
                            "HUMANS", "TrafficSigns", "StreetLights");
            // Yard Machine Hall
            CreateNewSector(new Vector3(54.7f, -0.5062422f, -73.9f), new Vector3(6, 5, 5.2f), "YARD", "MachineHall", "BUSHES3", "BUSHES6", "TREES_SMALL1");
            // Home
            CreateNewSector(new Vector3(-7.2f, -0.5062422f, 9.9f), new Vector3(11, 5, 9.5f), "PierHome", "TREES_SMALL1", "BUSHES7", "Building");    // Living room, kitchen, bedrooms.
            CreateNewSector(new Vector3(-12.5f, -0.5062422f, 1), new Vector3(3, 5, 7.7f), "PierHome", "TREES_SMALL1", "BUSHES7", "Building");       // Sauna, bathroom.
            CreateNewSector(new Vector3(-13.5f, -0.5062422f, 6.4f), new Vector3(1.3f, 5, 1.7f), "PierHome", "TREES_SMALL1", "BUSHES7", "Building"); // Storage room (kitchen).
            // Jail
            CreateNewSector(new Vector3(-655, 5, -1156), new Vector3(5, 5, 9f));
            // Cottage
            CreateNewSector(new Vector3(-848.2f, -2, 505.6f), new Vector3(5, 3, 5.2f), new Vector3(0, 342, -1.07f), "BUSHES7", "TREES_SMALL4", "TREES_MEDIUM3", "LakeNice", "TRAFFIC", "Tile");
            // Cabin
            CreateNewSector(new Vector3(-165.55f, -3.7f, 1020.7f), new Vector3(5, 4, 3.5f), "LakeNice", "Tile", "BUSHES7", "TREES_SMALL1");

            // Driveway sector
            if (Rules.instance.SpecialRules.DrivewaySector)
            {
                CreateNewSector(new Vector3(-18.5f, -0.5062422f, 11.9f), new Vector3(11f, 5, 9.5f),
                                "PierHome", "TREES_SMALL1", "BUSHES7", "BUSHES3", "BUSHES6", "TREES_MEDIUM3", "YARD", "LakeNice", "Tile");
            }

            // Generating sectors from rule files.
            if (Rules.instance.NewSectors.Count > 0)
            {
                foreach (NewSector sector in Rules.instance.NewSectors)
                {
                    CreateNewSector(sector.Position, sector.Scale, sector.Rotation, sector.Whitelist);
                }
            }

            ModConsole.Print($"[MOP] Loaded {loadedSectors} sectors");
        }
Example #7
0
        /// <summary>
        /// Lists all the game objects in the game's world and that are on the whitelist,
        /// then it adds ObjectHook to them
        /// </summary>
        void InitializeList()
        {
            // Get all minor objects from the game world (like beer cases, sausages)
            // Only items that are in the listOfMinorObjects list, and also contain "(itemx)" in their name will be loaded
            GameObject[] items = Object.FindObjectsOfType <GameObject>()
                                 .Where(gm => gm.name.ContainsAny(BlackList) && gm.name.ContainsAny("(itemx)", "(Clone)") && gm.activeSelf).ToArray();

            for (int i = 0; i < items.Length; i++)
            {
                try
                {
                    items[i].AddComponent <ItemHook>();

                    // Hook the TriggerMinorObjectRefresh to Confirm and Spawn all actions
                    if (items[i].name.Equals("shopping bag(itemx)"))
                    {
                        FsmHook.FsmInject(items[i], "Confirm", cashRegisterHook.TriggerMinorObjectRefresh);
                        FsmHook.FsmInject(items[i], "Spawn all", cashRegisterHook.TriggerMinorObjectRefresh);
                    }
                    else if (items[i].name.EqualsAny("spark plug box(Clone)", "car light bulb box(Clone)"))
                    {
                        FsmHook.FsmInject(items[i], "Create Plug", cashRegisterHook.WipeUseLoadOnSparkPlugs);
                    }
                    else if (items[i].name.EqualsAny("alternator belt(Clone)", "oil filter(Clone)", "battery(Clone)"))
                    {
                        PlayMakerFSM          fanbeltUse   = items[i].GetPlayMakerByName("Use");
                        FsmState              loadFanbelt  = fanbeltUse.FindFsmState("Load");
                        List <FsmStateAction> emptyActions = new List <FsmStateAction> {
                            new CustomNullState()
                        };
                        loadFanbelt.Actions = emptyActions.ToArray();
                        loadFanbelt.SaveActions();
                    }
                }
                catch (System.Exception ex)
                {
                    ExceptionManager.New(ex, "ITEM_LIST_LOAD_ERROR");
                }
            }
            cashRegisterHook.WipeUseLoadOnSparkPlugs();

            // CD Player Enhanced compatibility
            if (ModLoader.IsModPresent("CDPlayer"))
            {
                GameObject[] cdEnchancedObjects = Object.FindObjectsOfType <GameObject>()
                                                  .Where(gm => gm.name.ContainsAny("cd case(itemy)", "CD Rack(itemy)", "cd(itemy)") && gm.activeSelf).ToArray();

                for (int i = 0; i < cdEnchancedObjects.Length; i++)
                {
                    cdEnchancedObjects[i].AddComponent <ItemHook>();
                }

                // Create shop table check, for when the CDs are bought
                GameObject itemCheck = new GameObject("MOP_ItemAreaCheck");
                itemCheck.transform.position = GameObject.Find("SpawnItemStore").transform.position;
                itemCheck.AddComponent <ShopModItemSpawnCheck>();
            }
            else
            {
                GameObject[] cdItems = Resources.FindObjectsOfTypeAll <GameObject>().Where(g => g.name.ContainsAny("cd case(item", "cd(item")).ToArray();
                foreach (GameObject cd in cdItems)
                {
                    cd.AddComponent <ItemHook>();
                }
            }

            // Get items from ITEMS object.
            GameObject itemsObject = GameObject.Find("ITEMS");

            for (int i = 0; i < itemsObject.transform.childCount; i++)
            {
                GameObject item = itemsObject.transform.GetChild(i).gameObject;
                if (item.name == "CDs")
                {
                    continue;
                }

                try
                {
                    if (item.GetComponent <ItemHook>() != null)
                    {
                        continue;
                    }

                    item.AddComponent <ItemHook>();
                }
                catch (System.Exception ex)
                {
                    ExceptionManager.New(ex, "ITEM_LIST_AT_ITEMS_LOAD_ERROR");
                }
            }

            // Also disable the restart for that sunnuva bitch.
            itemsObject.GetComponent <PlayMakerFSM>().Fsm.RestartOnEnable = false;

            // F*****g wheels.
            GameObject[] wheels = Object.FindObjectsOfType <GameObject>().
                                  Where(gm => gm.name.EqualsAny("wheel_regula", "wheel_offset") && gm.activeSelf).ToArray();
            foreach (GameObject wheel in wheels)
            {
                wheel.AddComponent <ItemHook>();
            }

            // Tires trigger at Fleetari's.
            GameObject wheelTrigger = new GameObject("MOP_WheelTrigger");

            wheelTrigger.transform.localPosition    = new Vector3(1555.49f, 4.8f, 737);
            wheelTrigger.transform.localEulerAngles = new Vector3(1.16f, 335, 1.16f);
            wheelTrigger.AddComponent <WheelRepairJobTrigger>();

            // Hook up the envelope.
            GameObject[] envelopes = Resources.FindObjectsOfTypeAll <GameObject>().Where(g => g.name.EqualsAny("envelope(xxxxx)", "lottery ticket(xxxxx)")).ToArray();
            foreach (var g in envelopes)
            {
                g.AddComponent <ItemHook>();
            }

            // Unparent all childs of CDs object.
            Transform cds = GameObject.Find("ITEMS").transform.Find("CDs");

            if (cds != null)
            {
                for (int i = 0; i < cds.childCount; i++)
                {
                    cds.GetChild(i).parent = null;
                }
            }
        }