Иконка ресурса

FREE MiningOutpostQuarries : 1.0.4 1.0.4

Нет прав для скачивания
C#:
#region License (GPL v2)
/*
    Mining Outpost Quarries
    Copyright (c) 2023 RFC1920 <desolationoutpostpve@gmail.com>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License v2.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

    Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v2)
using Facepunch.Extend;
using Oxide.Core;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("MiningOutpostQuarries", "RFC1920", "1.0.4")]
    [Description("Spawn quarries next to MiningOutposts just like the good old days")]
    internal class MiningOutpostQuarries : RustPlugin
    {
        private ConfigData configData;
        public static MiningOutpostQuarries Instance;
        private static SortedDictionary<string, Vector3> monPos = new();
        private static SortedDictionary<string, Quaternion> monRot = new();
        private static SortedDictionary<string, Vector3> monSize = new();
        private static Dictionary<uint, Quarry> Quarries = new();

        private const string quarryprefab = "assets/prefabs/deployable/quarry/mining_quarry.prefab";
        private const string permUse = "miningoutpostquarries.use";
        private bool newsave;

        private class Quarry
        {
            public Vector3 position;
            public Quaternion rotation;
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["notauthorized"] = "You don't have permission to do that !!"
            }, this);
        }

        private void OnServerInitialized()
        {
            permission.RegisterPermission(permUse, this);
            LoadConfigVariables();

            if (newsave)
            {
                Quarries = new Dictionary<uint, Quarry>();
                SaveData();
                newsave = false;
            }
            LoadData();

            Instance = this;

            FindMonuments();
            BuildQuarries();
        }

        private void OnNewSave()
        {
            newsave = true;
        }

        private void DoLog(string message)
        {
            if (configData.debug) Interface.GetMod().LogInfo(message);
        }

        private void Unload()
        {
            foreach (KeyValuePair<uint, Quarry> quarry in Quarries)
            {
                BaseNetworkable quarryObj = BaseNetworkable.serverEntities.Find(new NetworkableId(quarry.Key));
                if (quarryObj == null) continue;
                Vector3 loc = quarryObj.transform.position;
                UnityEngine.Object.DestroyImmediate(quarryObj, true);
                List<MiningQuarry> oldmq = new();
                Vis.Entities(loc, 50f, oldmq);
                foreach (MiningQuarry mq in oldmq)
                {
                    UnityEngine.Object.DestroyImmediate(mq, true);
                }
            }
        }

        private class ConfigData
        {
            public Options Options;
            public bool debug;
            public VersionNumber Version;
        }

        public class Options
        {
            public int maxQuarries;
        }

        private void LoadConfigVariables()
        {
            configData = Config.ReadObject<ConfigData>();
            if (configData.Options == null) configData.Options = new Options();
            if (configData.Options.maxQuarries == 0) configData.Options.maxQuarries = 3;
            configData.Version = Version;
            SaveConfig(configData);
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Creating new config file.");
            ConfigData config = new()
            {
                debug = false,
                Options = new Options()
                {
                    maxQuarries = 3
                }
            };

            SaveConfig(config);
        }

        private void SaveConfig(ConfigData config)
        {
            Config.WriteObject(config, true);
        }

        private void LoadData()
        {
            Quarries = Interface.GetMod().DataFileSystem.ReadObject<Dictionary<uint, Quarry>>(Name + "/quarries");
        }

        private void SaveData()
        {
            Interface.GetMod().DataFileSystem.WriteObject(Name + "/quarries", Quarries);
        }

        private bool BadLocation(Vector3 loc)
        {
            // Avoid placing in a rock or foundation, water, etc.
            int layerMask = LayerMask.GetMask("Construction", "World", "Water", "Road");
            RaycastHit hit;
            foreach (Vector3 location in new List<Vector3>() { loc, loc + new Vector3(5, 0, 0), loc + new Vector3(0, 0, 5) })
            {
                if (Physics.Raycast(new Ray(location, Vector3.down), out hit, 6f, layerMask))
                {
                    if (!hit.GetCollider().material.name.Contains("Grass"))
                    {
                        DoLog($"Found {hit.GetCollider().material.name} {hit.distance}f below this location");
                        return true;
                    }
                }
                else if (Physics.Raycast(new Ray(location, Vector3.up), out hit, 6f, layerMask))
                {
                    DoLog($"Found {hit.GetCollider().material.name} {hit.distance}f above this location");
                    return true;
                }
                else if (Physics.Raycast(new Ray(location, Vector3.forward), out hit, 15f, layerMask))
                {
                    DoLog($"Found {hit.GetCollider().material.name} at {hit.distance}f next to this location");
                    return true;
                }
            }
            return false;
        }

        private void BuildQuarries()
        {
            int spawned = 0;
            if (Quarries.Count > 0)
            {
                DoLog("Spawning quarries from memory.");
                foreach (KeyValuePair<uint, Quarry> quarry in Quarries)
                {
                    BaseEntity quarryEnt = GameManager.server.CreateEntity(quarryprefab, quarry.Value.position, quarry.Value.rotation, true);
                    quarryEnt.Spawn();
                    MiningQuarry mq = quarryEnt as MiningQuarry;
                    mq.canExtractLiquid = true;
                    mq.canExtractSolid = true;

                    if (quarryEnt == null)
                    {
                        DoLog($"Unable to spawn quarry at {quarry.Value.position}");
                        continue;
                    }
                    spawned++;
                }
                DoLog($"Spawned {spawned} quarries!");
                return;
            }

            foreach (KeyValuePair<string, Vector3> warehouse in monPos)
            {
                if (spawned > configData.Options.maxQuarries) break;
                DoLog($"Attemping placement near {warehouse.Key} at {warehouse.Value}");
                string whseName = warehouse.Key;
                const float radius = 30f;// monSize[whseName].magnitude / 2;
                for (int i = 0; i < 16; i++)
                {
                    float angle = i * Mathf.PI * 2f / 16;
                    Vector3 newPos = new(Mathf.Cos(angle) * radius, monSize[whseName].y, Mathf.Sin(angle) * radius);

                    newPos += warehouse.Value;
                    newPos.y = TerrainMeta.HeightMap.GetHeight(newPos);

                    DoLog($"Checking location {newPos} size {radius}");
                    if (BadLocation(newPos)) continue;

                    DoLog("Good choice, spawning quarry...");
                    Quaternion newRot = monRot[whseName] *= Quaternion.Euler(0, 90, 0);
                    BaseEntity quarryEnt = GameManager.server.CreateEntity(quarryprefab, newPos, newRot, true);
                    quarryEnt.Spawn();
                    MiningQuarry mq = quarryEnt as MiningQuarry;
                    mq.canExtractLiquid = true;
                    mq.canExtractSolid = true;

                    if (quarryEnt == null)
                    {
                        DoLog($"Unable to spawn quarry at {newPos}");
                        continue;
                    }
                    //quarry.FindSuitableParent();
                    DoLog("Adding to list");
                    Quarries.Add((uint)quarryEnt.net.ID.Value, new Quarry()
                    {
                        position = newPos,
                        rotation = newRot
                    });
                    spawned++;
                    break;
                }
            }
            SaveData();
            DoLog($"Spawned {spawned} quarries!");
        }

        private void FindMonuments()
        {
            Vector3 extents = Vector3.zero;
            float realWidth = 0f;
            string name = null;

            foreach (MonumentInfo monument in UnityEngine.Object.FindObjectsByType(typeof(MonumentInfo), FindObjectsSortMode.None).Cast<MonumentInfo>())
            {
                realWidth = 20f;
                name = Regex.Match(monument.name, @"\w{6}\/(.+\/)(.+)\.(.+)").Groups[2].Value.Replace("_", " ").Replace(" 1", "").Titleize();

                int i = 0;
                string newname = name + i.ToString();
                while (monPos.ContainsKey(newname))
                {
                    i++;
                    newname = name + i.ToString();
                }
                name = newname;
                DoLog($"Found {name}");

                extents = monument.Bounds.extents;
                DoLog($"Size: {extents.z}");
                if (realWidth > 0f)
                {
                    extents.z = realWidth;
                }

                if (extents.z < 1)
                {
                    extents.z = 50f;
                }
                monPos.Add(name, monument.transform.position);
                monSize.Add(name, extents);
                monRot.Add(name, monument.transform.rotation);
            }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху