Untitled

 avatar
unknown
plain_text
2 months ago
5.5 kB
6
Indexable
using HarmonyLib;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Scripting;

namespace TradersOpenExceptBloodmoon
{
    [HarmonyPatch(typeof(TraderArea), "SetClosed")]
    public class TraderPatch
    {
        static bool Prefix(World _world, bool _bClosed, EntityTrader _trader, bool playSound, ref bool __result)
        {
            // Verificar si es Blood Moon
            if (IsBloodMoonActive())
            {
                Log.Out("[TradersOpenExceptBloodmoon] Blood Moon activa. Los traders permanecerán cerrados.");
                __result = true; // Mantiene el trader cerrado

                // Obtener la hora actual del juego
                float currentHour = GameManager.Instance.World.GetWorldTime() % 24000 / 1000f;

                // Reproducir sonido de advertencia a las 03:30
                if (currentHour >= 3.5f && currentHour < 4.0f)
                {
                    PlayTraderSound(_trader, "Warning");
                }

                // Reproducir sonido de apertura a las 04:00
                if (currentHour >= 4.0f)
                {
                    PlayTraderSound(_trader, "Open");
                }

                return true; // Ejecuta el método original
            }

            // Asegurar que el trader esté SIEMPRE abierto después de la Blood Moon
            _bClosed = false;
            __result = false;

            // Desactivar la protección de la zona del Trader para evitar expulsión y desbloquear puertas
            if (_trader.traderArea != null)
            {
                _trader.traderArea.IsClosed = false; // Evita teletransportación
                UnlockTraderDoors(_world, _trader.traderArea); // Desbloquea las puertas
                Log.Out("[TradersOpenExceptBloodmoon] Se ha deshabilitado la protección del trader y desbloqueado las puertas.");
            }

            return false; // Evita la ejecución del código original
        }

        /// <summary>
        /// Verifica si actualmente es Blood Moon.
        /// </summary>
        private static bool IsBloodMoonActive()
        {
            return GameManager.Instance.World.aiDirector.BloodMoonComponent.BloodMoonActive;
        }

        /// <summary>
        /// Obtiene los días restantes para la próxima Blood Moon.
        /// </summary>
        public static int DaysUntilNextBloodMoon()
        {
            int currentDay = (int)(GameManager.Instance.World.GetWorldTime() / 24000); // Convierte ticks a días
            int bloodMoonFrequency = GamePrefs.GetInt(EnumGamePrefs.BloodMoonFrequency); // Frecuencia de Blood Moon desde configuración
            return bloodMoonFrequency - (currentDay % bloodMoonFrequency);
        }

        /// <summary>
        /// Desbloquea las puertas del Trader después de la Blood Moon.
        /// </summary>
        private static void UnlockTraderDoors(World _world, TraderArea traderArea)
        {
            int startX = World.toChunkXZ(traderArea.Position.x - 1);
            int endX = World.toChunkXZ(traderArea.Position.x + traderArea.PrefabSize.x + 1);
            int startZ = World.toChunkXZ(traderArea.Position.z - 1);
            int endZ = World.toChunkXZ(traderArea.Position.z + traderArea.PrefabSize.z + 1);

            for (int z = startZ; z <= endZ; z++)
            {
                for (int x = startX; x <= endX; x++)
                {
                    Chunk chunk = _world.GetChunkSync(x, z) as Chunk;
                    if (chunk == null) continue;

                    if (chunk.IndexedBlocks.TryGetValue("TraderOnOff", out List<Vector3i> blockPositions))
                    {
                        foreach (Vector3i blockPos in blockPositions)
                        {
                            BlockValue block = chunk.GetBlock(blockPos);
                            if (block.ischild) continue;

                            Vector3i worldPos = chunk.ToWorldPos(blockPos);
                            if (!traderArea.ProtectBounds.Contains(worldPos)) continue;

                            Block blockType = block.Block;
                            if (blockType is BlockDoorSecure secureDoor && secureDoor.IsDoorLocked(_world, worldPos))
                            {
                                Log.Out($"[TradersOpenExceptBloodmoon] Desbloqueando puerta en {worldPos}");
                                blockType.OnBlockActivated("unlock", _world, 0, worldPos, block, null);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Reproduce el sonido del trader.
        /// </summary>
        private static void PlayTraderSound(EntityTrader trader, string soundType)
        {
            Vector3i traderPosition = new Vector3i(trader.position);
            BlockSpeakerTrader speaker = new BlockSpeakerTrader();

            switch (soundType)
            {
                case "Warning":
                    speaker.PlayWarning(traderPosition, trader);
                    break;
                case "Open":
                    speaker.PlayOpen(traderPosition, trader);
                    break;
                case "Close":
                    speaker.PlayClose(traderPosition, trader);
                    break;
            }
        }
    }
}
Editor is loading...
Leave a Comment