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

FREE PersonalAnimal : 1.3.7 1.3.7

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using System.Collections.Generic;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System;
using Oxide.Core.Plugins;
using System.Collections;
using Oxide.Core;
namespace Oxide.Plugins {
    [Info("PersonalAnimal", "walkinrey", "1.3.7")]
    public class PersonalAnimal : RustPlugin {
        public static PersonalAnimal Instance;
        [PluginReference]
        private Plugin ImageLibrary, PersonalNPC, Friends, Clans;
        private Dictionary<ulong, PlayerAnimalController> _existsControllers = new Dictionary<ulong, PlayerAnimalController>();
        private Dictionary<ulong, AnimalOwnerComponent> _existsOwnerComponents = new Dictionary<ulong, AnimalOwnerComponent>();
        private List<string> _permissionKeys = new List<string>();
        private Dictionary<ulong, DateTime> _cooldownInfo = new Dictionary<ulong, DateTime>();
        private BUTTON controlButton = BUTTON.FIRE_THIRD, inventoryButton = BUTTON.RELOAD, mountButton = BUTTON.USE;
#region Config
        private Configuration _config;
        public class Configuration {
            [JsonProperty("Controls setup")]
            public ControlsSetup controlsSetup = new ControlsSetup();
            [JsonProperty("GUI setup")]
            public GUISetup gui = new GUISetup();
            [JsonProperty("Protect from Rust anti-cheat kick when player riding an animal")]
            public ProtectInfo protect = new ProtectInfo();
            [JsonProperty("Spawn settings")]
            public SpawnInfo spawnInfo = new SpawnInfo();
            [JsonProperty("How frequent animal will update the information? (affects the performance and operation of the animal)")]
            public float mainProcessTimer = 0.01f;
            [JsonProperty("Setting up personal animals by permission")]
            public Dictionary<string, AnimalInfo> animalInfoPerm = new Dictionary<string, AnimalInfo>();
            [JsonProperty("Damage scale from animals to other entities")]
            public Dictionary<string, float> damageScale = new Dictionary<string, float>();
            [JsonProperty("Animal install by item")]
            public List<ItemInfo> installItem = new List<ItemInfo>();
            [JsonProperty("List of prefabs that the animal can loot (useful if the animal attacks loot instead of looting it)")]
            public List<string> lootEntities = new List<string>();
            public class SpawnInfo {
                [JsonProperty("Can player spawn animal in cupboard range?")]
                public bool canSpawnInCupboard = true;
                [JsonProperty("Can player spawn animal on construction? (foundations, floors, walls, etc.)")]
                public bool canSpawnOnConstruction = false;
                [JsonProperty("Can player spawn animal on deployed entities? (wood boxes, tables, workbenches, etc.)")]
                public bool canSpawnOnDeployed = false;
            }
            public class ProtectInfo {
                [JsonProperty("Kick if detected noclip?")]
                public bool noClip = true;
                [JsonProperty("Kick if detected speedhack?")]
                public bool speedHack = true;
                [JsonProperty("Kick if detected flyhack?")]
                public bool flyHack = true;
                [JsonProperty("Kick if detected insideterrain?")]
                public bool insideTerrain = true;
            }
            public struct ItemInfo {
                [JsonProperty("Item name")]
                public string name;
                [JsonProperty("Item shortname")]
                public string shortname;
                [JsonProperty("Item skin")]
                public ulong skin;
                [JsonProperty("Return item back if player have despawned the animal via command or GUI?")]
                public bool returnDespawn;
                [JsonProperty("Bot info")]
                public AnimalInfo animal;
            }
            public class GUISetup {
                [JsonProperty("How many seconds to update the GUI?")]
                public int refreshTime = 6;
                [JsonProperty("Panel layer (Hud, Overlay, Overall, Hud.Menu, Under)")]
                public string layer = "Overlay";
                [JsonProperty("Panel position")]
                public CuiRectTransformComponent panelPosition = new CuiRectTransformComponent();
                [JsonProperty("Second position of the panel (used if the player has a personal bot)")]
                public CuiRectTransformComponent secondPanelPosition = new CuiRectTransformComponent();
                [JsonProperty("1 panel color")]
                public string panelColor1 = "#7f8c8d";
                [JsonProperty("2 panel color")]
                public string panelColor2 = "#bdc3c7";
                [JsonProperty("Health bar color")]
                public string panelHealthColor = "#2ecc71";
                [JsonProperty("Shortcut buttons")]
                public List<AccessButton> accessButtons = new List<AccessButton>();
                public class AccessButton {
                    [JsonProperty("Text on button")]
                    public string text = "";
                    [JsonProperty("Executable chat commands")]
                    public string[] commands = new string[] {
                    }
                    ;
                    public AccessButton(string btnText, string[] btnCommand) {
                        text = btnText;
                        commands = btnCommand;
                    }
                }
            }
            public class ControlsSetup {
                [JsonProperty("Which button will assign tasks to the animal, attack / collect, etc.(MIDDLE_MOUSE, SECOND_MOUSE, E, RELOAD, SPRINT)")]
                public string key = "MIDDLE_MOUSE";
                [JsonProperty("Button to open animal inventory (MIDDLE_MOUSE, SECOND_MOUSE, E, RELOAD, SPRINT)")]
                public string inventoryKey = "RELOAD";
                [JsonProperty("Button to mount animal (MIDDLE_MOUSE, SECOND_MOUSE, E, RELOAD, SPRINT)")]
                public string mountKey = "E";
                [JsonProperty("Range of action of the assignment button")]
                public float rayLength = 25f;
                [JsonProperty("Input tick (affects performance and feedback of the inputs, 0.1 for best performance, 0.01 for best feedback)")]
                public float inputTick = 0.05f;
                [JsonProperty("Display 3D arrows over a target?")]
                public bool showArrow = true;
                [JsonProperty("Arrow display duration")]
                public int arrowDuration = 2;
                [JsonProperty("Distance between player and animal to move animal into idle state")]
                public float idleDistance = 1f;
                [JsonProperty("Control animal by mouse direction (true) of by WASD buttons (false) when mounted?")]
                public bool byDirection = true;
            }
            public class AnimalInfo {
                [JsonProperty("The name of the animal to be selected through the command when spawning")]
                public string spawnName = "wolf1";
                [JsonProperty("Animal type (bear, boar, chicken, stag, wolf, polar-bear)")]
                public string type = "wolf";
                [JsonProperty("Animal speed (slowest, slow, normal, fast)")]
                public string speed = "normal";
                [JsonProperty("Maximum health")]
                public int maxHealth = 200;
                [JsonProperty("Animal spawn cooldown")]
                public float cooldown = 300f;
                [JsonProperty("AI Stopping Distance")]
                public float stoppingDistance = 0.1f;
                [JsonProperty("Addons setup")]
                public AddonsSetup addonsSetup = new AddonsSetup();
                [JsonProperty("Functions setup")]
                public FunctionsSetup functionsSetup = new FunctionsSetup();
                [JsonProperty("Damage, interactions and loot setup")]
                public InteractionSetup interactionSetup = new InteractionSetup();
                [JsonProperty("Death Marker (marker will be only visible for owner)")]
                public DeathMarkerSetup deathMarker = new DeathMarkerSetup();
                [JsonProperty("Nutrition setup")]
                public FoodSetup nutritionSetup = new FoodSetup();
                public class DeathMarkerSetup {
                    [JsonProperty("Show marker on bot's death position?")]
                    public bool enableMarker = false;
                    [JsonProperty("Display name on map")]
                    public string displayName = "Bot's death marker";
                    [JsonProperty("Marker radius")]
                    public float radius = 0.35f;
                    [JsonProperty("Outline color (hex)")]
                    public string outline = "00FFFFFF";
                    [JsonProperty("Main color (hex)")]
                    public string main = "00FFFF";
                    [JsonProperty("Alpha")]
                    public float alpha = 0.5f;
                    [JsonProperty("Duration")]
                    public int duration = 20;
                }
                public class FoodSetup {
                    [JsonProperty("Turn on the animal feeding system?")]
                    public bool enableFeeding = true;
                    [JsonProperty("Setting health for food eaten")]
                    public Dictionary<string, float> foodInfo = new Dictionary<string, float>();
                }
                public class AddonsSetup {
                    [JsonProperty("Enable the ability to ride an animal?")]
                    public bool needChair = false;
                    [JsonProperty("Dismount owner when entering RaidableBase?")]
                    public bool dismountOnRaidableBase = false;
                    [JsonProperty("Add a bag to an animal to store resources?")]
                    public bool needBag = true;
                    [JsonProperty("Number of available slots in the bag (maximum 36)")]
                    public int slotsAmount = 12;
                }
                public class InteractionSetup {
                    [JsonProperty("Animal damage rate")]
                    public float botDamageRate = 2f;
                    [JsonProperty("Damage rate receive for an animal")]
                    public float botReceiveDamageRate = 1f;
                    [JsonProperty("Can the animal damage players?")]
                    public bool canDamagePlayers = true;
                    [JsonProperty("Can players damage the animal?")]
                    public bool canBeDamagedByPlayers = true;
                    [JsonProperty("Despawn animal corpse after death?")]
                    public bool despawnCorpse = false;
                    [JsonProperty("Distance between animal and loot entity (collectible resources, loot boxes etc.)")]
                    public float collectibleDistance = 3f;
                    [JsonProperty("Distance between animal and enemy")]
                    public float enemyDistance = 5f;
                    [JsonProperty("Setting up resource pickup rates")]
                    public Dictionary<string, float> collectRates = new Dictionary<string, float>();
                    [JsonProperty("Setting up loot rates")]
                    public Dictionary<string, float> lootRates = new Dictionary<string, float>();
                    [JsonProperty("Black list of items that cannot be put in the bag")]
                    public List<string> bagBlacklist = new List<string>();
                }
                public class FunctionsSetup {
                    [JsonProperty("Can the animal attack objects?")]
                    public bool canAttackEntities = true;
                    [JsonProperty("Can the animal attack players?")]
                    public bool canAttackPlayers = true;
                    [JsonProperty("Can the animal attack NPCs?")]
                    public bool canAttackNPC = true;
                    [JsonProperty("Can an animal loot boxes?")]
                    public bool canLootBoxes = true;
                    [JsonProperty("Can the animal pick up resources?")]
                    public bool canCollectResources = true;
                    [JsonProperty("Does the animal have to defend itself?")]
                    public bool canProtectSelf = true;
                    [JsonProperty("Should the animal protect the owner?")]
                    public bool canProtectOwner = true;
                    [JsonProperty("Can an animal collect resources within a specified radius? (/panimal auto-collect)")]
                    public bool canAutoCollect = false;
                    [JsonProperty("Collect resources radius (/panimal auto-collect)")]
                    public float collectRadius = 50f;
                    [JsonProperty("Only owner can open animal's bag after death?")]
                    public bool onlyOwnerLootDeadBag = true;
                    [JsonProperty("Can attack team/clan members or friends?")]
                    public bool canAttackTeam = true;
                }
                public string TypeToEntity() {
                    switch(type) {
                        case "bear" : return "assets/rust.ai/agents/bear/bear.prefab";
                        case "boar" : return "assets/rust.ai/agents/boar/boar.prefab";
                        case "chicken" : return "assets/rust.ai/agents/chicken/chicken.prefab";
                        case "stag" : return "assets/rust.ai/agents/stag/stag.prefab";
                        case "wolf" : return "assets/rust.ai/agents/wolf/wolf.prefab";
                        case "polar-bear" : return "assets/rust.ai/agents/bear/polarbear.prefab";
                        default : return string.Empty;
                    }
                }
                public Vector3 GetChairOffset() {
                    switch(type) {
                        case "bear" : return new Vector3(0, 0.65f, 0);
                        case "boar" : return new Vector3(0, 0.35f, 0);
                        case "stag" : return new Vector3(0, 0.5f, 0);
                        case "polar-bear" : return new Vector3(0, 0.7f, 0);
                        default : return Vector3.zero;
                    }
                }
                public Vector3 GetFeedingOffset() {
                    switch(type) {
                        case "wolf" : return new Vector3(0, 0.15f, 0.9f);
                        case "bear" : return new Vector3(0, 0.15f, 1.25f);
                        case "boar" : return new Vector3(0, 0.15f, 1.1f);
                        case "stag" : return new Vector3(0, 0.15f, 1f);
                        case "polar-bear" : return new Vector3(0, 0.15f, 1.3f);
                        case "chicken" : return new Vector3(0, 0.2f, 0.5f);
                        default : return Vector3.zero;
                    }
                }
            }
        }
        protected override void LoadDefaultConfig() {
            _config = new Configuration();
            _config.gui.panelPosition = new CuiRectTransformComponent {
                AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-170 -104", OffsetMax = "-10 -10"
            }
            ;
            _config.gui.secondPanelPosition = new CuiRectTransformComponent {
                AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-360 -104", OffsetMax = "-200 -10"
            }
            ;
            _config.damageScale.Add("bradleyapc", 0f);
            _config.damageScale.Add("bradley", 0f);
            _config.animalInfoPerm.Add("personalanimal.wolf", new Configuration.AnimalInfo {
                interactionSetup = new Configuration.AnimalInfo.InteractionSetup {
                    collectRates = new Dictionary<string, float> {
                        ["stones"]
                        = 5f
                    }
                    , bagBlacklist = new List<string> {
                        "rocket.launcher"
                    }
                }
                , nutritionSetup = new Configuration.AnimalInfo.FoodSetup() {
                    foodInfo = new Dictionary<string, float> {
                        ["pumpkin"]
                        = 10f, ["corn"] = 5f, ["apple"] = 5f,
                    }
                }
            }
            );
            _config.installItem.Add(new Configuration.ItemInfo {
                name = "Wolf", skin = 1234, shortname = "furnace", animal = new Configuration.AnimalInfo {
                    interactionSetup = new Configuration.AnimalInfo.InteractionSetup {
                        collectRates = new Dictionary<string, float> {
                            ["stones"]
                            = 5f
                        }
                        , bagBlacklist = new List<string> {
                            "rocket.launcher"
                        }
                    }
                    , nutritionSetup = new Configuration.AnimalInfo.FoodSetup() {
                        foodInfo = new Dictionary<string, float> {
                            ["pumpkin"]
                            = 10f, ["corn"] = 5f, ["apple"] = 5f,
                        }
                    }
                }
            }
            );
            _config.gui.accessButtons.Add(new Configuration.GUISetup.AccessButton("Stay on Position", new string[] {
                "panimal idle"
            }
            ));
            _config.lootEntities.Add("foodbox");
            _config.lootEntities.Add("vehicle_parts");
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
                SaveConfig();
            }
            catch (Exception ex) {
                PrintError("{0}", ex);
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Loc
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["ChatCommand_Success_Despawn"]
                = "Your personal animal has been successfully despawned!", ["ChatCommand_Success_Spawn"] = "Your personal animal has been successfully spawned!", ["ChatCommand_Notice_Cooldown"] = "You need to wait {0} seconds before re-spawning the animal!", ["ChatCommand_Notice_Location"] = "Your animal is in the grid: {0}, distance to it: {1}", ["ChatCommand_Notice_Health"] = "Your animal's health: {0}/{1}", ["ChatCommand_Notice_Follow"] = "The animal is now following you!", ["ChatCommand_Notice_AvailableBots"] = "<size=16>Available animals:</size>\n{BOTS}\n\nEnter /panimal [short name of the animal], to spawn!", ["ChatCommand_Error_AutoPickup"] = "<size=16>Auto-pickup resources</size>\n\nThe animal will begin to collect all resources within a radius of 50 meters from its original point.\n\nAvailable mods: all, wood, stone, metal, sulfur\nDisable - /panimal auto-pickup disable", ["ChatCommand_Error_NoPermission"] = "You do not have permission to spawn a personal animal", ["ChatCommand_Error_CannotUse"] = "Your animal does not have this function, you cannot use it!", ["ChatCommand_Error_NoBot"] = "You don't have a personal animal!", ["ChatCommand_Error_NotFounded"] = "Animal not found!", ["ChatCommand_Error_Blacklist"] = "This item has been blacklisted, you cannot give it to an animal!", ["ChatCommand_Error_CannotSpawn"] = "You can't spawn a personal animal here!", ["ChatCommand_Notice_AutoPickup_Status"] = "Auto-pickup resources: {0}\nResources to collect: {1}", ["ChatCommand_AutoMode_Resources_All"] = "all", ["ChatCommand_AutoMode_Resources_Wood"] = "wood", ["ChatCommand_AutoMode_Resources_Stone"] = "stone", ["ChatCommand_AutoMode_Resources_Sulfur"] = "sulfur", ["ChatCommand_AutoMode_Resources_Metal"] = "metal", ["ChatCommand_AutoMode_Resources_Hemp"] = "hemp", ["ChatCommand_AutoMode_Resources_Berries"] = "berries", ["ChatCommand_AutoMode_Resources_Corn"] = "corn", ["ChatCommand_AutoMode_Resources_Mushroom"] = "mushroom", ["ChatCommand_AutoMode_Resources_Pumpkin"] = "pumpkin", ["ChatCommand_AutoMode_Status_Disabled"] = "disabled", ["ChatCommand_AutoMode_Status_Enabled"] = "enabled", ["Bot_Notice_MissionCompleted"] = "Mission completed, backing to you!", ["Bot_Notice_GoingCollect"] = "Going to collect the resource!", ["Bot_Notice_GoingLootBox"] = "Going to loot the box!", ["Bot_Notice_Following"] = "Following you!", ["Bot_Notice_Staying"] = "Staying on the position.", ["Bot_Notice_StartedAttack"] = "Starting attack!", ["Bot_Notice_GoingPosition"] = "Going to the position.", ["Bot_Error_NoResourcesAround"] = "No resources around!", ["Bot_Error_Dead_NotOwner"] = "You can't loot this bag because you aren't the owner!", ["GUI_Header"] = "Animal Control", ["GUI_Follow"] = "Follow", ["GUI_Kill"] = "Kill", ["Text_Inventory"] = "Open Inventory - R", ["Text_Drive"] = "Saddle the animal - E"
            }
            , this, "en");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["ChatCommand_Success_Despawn"]
                = "Ваше персональное животное успешно задеспавнено!", ["ChatCommand_Success_Spawn"] = "Ваше персональное животное успешно заспавнено!", ["ChatCommand_Notice_Cooldown"] = "Вам нужно подождать {0} секунд, прежде чем повторно заспавнить животное!", ["ChatCommand_Notice_Location"] = "Ваше животное находится в квадрате: {0}, расстояние до него: {1}", ["ChatCommand_Notice_Health"] = "Здоровье вашего животного: {0}/{1}", ["ChatCommand_Notice_Follow"] = "Животное теперь следует за вами!", ["ChatCommand_Notice_AvailableBots"] = "<size=16>Доступные животные:</size>\n{BOTS}\n\nВведите /panimal [короткое название животного], чтобы заспавнить!", ["ChatCommand_Error_AutoPickup"] = "<size=16>Авто-подбор ресурсов</size>\n\nЖивотное начнет собирать все ресурсы в радиусе 50 метров от его первоначальной точки.\n\nДоступные режимы: all, wood, stone, metal, sulfur\nОтключить - /panimal auto-pickup disable", ["ChatCommand_Error_NoPermission"] = "У вас нет разрешения на спавн персонального животного", ["ChatCommand_Error_CannotUse"] = "Ваше животное не обладает такой функцией, вы не можете ее использовать!", ["ChatCommand_Error_NoBot"] = "У вас нет персонального животного!", ["ChatCommand_Error_NotFounded"] = "Животное не найдено!", ["ChatCommand_Error_Blacklist"] = "Этот предмет добавлен в черный список, вы не можете дать его животному!", ["ChatCommand_Error_CannotSpawn"] = "Вы не можете заспавнить персональное животное здесь!", ["ChatCommand_Notice_AutoPickup_Status"] = "Авто-подбор ресурсов: {0}\nРесурсы для сбора: {1}", ["ChatCommand_AutoMode_Resources_All"] = "все", ["ChatCommand_AutoMode_Resources_Wood"] = "дерево", ["ChatCommand_AutoMode_Resources_Stone"] = "камень", ["ChatCommand_AutoMode_Resources_Sulfur"] = "сера", ["ChatCommand_AutoMode_Resources_Metal"] = "металл", ["ChatCommand_AutoMode_Resources_Hemp"] = "ткань", ["ChatCommand_AutoMode_Resources_Berries"] = "ягоды", ["ChatCommand_AutoMode_Resources_Corn"] = "кукуруза", ["ChatCommand_AutoMode_Resources_Mushroom"] = "гриб", ["ChatCommand_AutoMode_Resources_Pumpkin"] = "тыква", ["ChatCommand_AutoMode_Status_Disabled"] = "отключён", ["ChatCommand_AutoMode_Status_Enabled"] = "включён", ["Bot_Notice_MissionCompleted"] = "Цель выполнена, возвращаюсь к вам!", ["Bot_Notice_GoingCollect"] = "Иду собирать ресурс!", ["Bot_Notice_GoingLootBox"] = "Иду лутать ящик!", ["Bot_Notice_Following"] = "Следую за вами!", ["Bot_Notice_Staying"] = "Стою на позиции.", ["Bot_Notice_StartedAttack"] = "Начинаю атаку!", ["Bot_Notice_GoingPosition"] = "Иду на позицию.", ["Bot_Error_NoResourcesAround"] = "Нет ресурсов поблизости!", ["Bot_Error_Dead_NotOwner"] = "Вы не можете залутать эту сумку потому что вы не ее владелец!", ["GUI_Header"] = "Управление животным", ["GUI_Follow"] = "Следовать", ["GUI_Kill"] = "Убить", ["Text_Inventory"] = "Открыть инвентарь - R", ["Text_Drive"] = "Оседлать животное - E"
            }
            , this, "ru");
        }
#endregion
#region Hooks
        private void OnServerInitialized() {
            if(ImageLibrary == null) {
                PrintError("Install ImageLibrary / Установите ImageLibrary!");
                NextTick(() => Interface.Oxide.UnloadPlugin(Title));
                return;
            }
            ImageLibrary.CallHook("AddImage", "https://api.rustyplugin.ru/pnpc/arrow.png", "PersonalAnimal_Close");
            ImageLibrary.CallHook("AddImage", "https://api.rustyplugin.ru/pnpc/arrow2.png", "PersonalAnimal_Open");
            switch(_config.controlsSetup.key) {
                case "E" : controlButton = BUTTON.USE;
                break;
                case "MIDDLE_MOUSE" : controlButton = BUTTON.FIRE_THIRD;
                break;
                case "RELOAD" : controlButton = BUTTON.RELOAD;
                break;
                case "SPRINT" : controlButton = BUTTON.SPRINT;
                break;
                case "SECOND_MOUSE" : controlButton = BUTTON.FIRE_SECONDARY;
                break;
            }
            switch(_config.controlsSetup.inventoryKey) {
                case "E" : inventoryButton = BUTTON.USE;
                break;
                case "MIDDLE_MOUSE" : inventoryButton = BUTTON.FIRE_THIRD;
                break;
                case "RELOAD" : inventoryButton = BUTTON.RELOAD;
                break;
                case "SPRINT" : inventoryButton = BUTTON.SPRINT;
                break;
                case "SECOND_MOUSE" : inventoryButton = BUTTON.FIRE_SECONDARY;
                break;
            }
            switch(_config.controlsSetup.mountKey) {
                case "E" : mountButton = BUTTON.USE;
                break;
                case "MIDDLE_MOUSE" : mountButton = BUTTON.FIRE_THIRD;
                break;
                case "RELOAD" : mountButton = BUTTON.RELOAD;
                break;
                case "SPRINT" : mountButton = BUTTON.SPRINT;
                break;
                case "SECOND_MOUSE" : mountButton = BUTTON.FIRE_SECONDARY;
                break;
            }
        }
        private object OnPlayerWantsMount(BasePlayer player, BaseMountable entity) {
            if(entity == null || player == null) return null;
            if(!_existsOwnerComponents.ContainsKey(entity.net.ID.Value)) return null;
            AnimalOwnerComponent ownerComponent = _existsOwnerComponents[entity.net.ID.Value];
            if(ownerComponent == null) {
                _existsOwnerComponents.Remove(entity.net.ID.Value);
                return null;
            }
            if(ownerComponent.controller == null) return null;
            entity.AttemptMount(player, false);
            ownerComponent.controller.IsDriving = true;
            return false;
        }
        private object OnNpcTarget(BaseEntity npc, BaseEntity entity) {
            if(entity == null || npc == null) return null;
            if(!_existsOwnerComponents.ContainsKey(npc.net.ID.Value)) return null;
            AnimalOwnerComponent ownerComponent = _existsOwnerComponents[npc.net.ID.Value];
            if(ownerComponent == null) {
                _existsOwnerComponents.Remove(npc.net.ID.Value);
                return null;
            }
            if(entity == ownerComponent.controller.owner) return false;
            return null;
        }
        private void OnEntityDeath(BaseAnimalNPC entity, HitInfo info) {
            if(entity == null) return;
            var ownerComponent = entity.GetComponent<AnimalOwnerComponent>();
            if(ownerComponent) {
                _existsOwnerComponents.Remove(entity.net.ID.Value);
                if(ownerComponent.controller && !ownerComponent.isLootSpawned) {
                    var controller = ownerComponent.controller;
                    var source = controller.owner.inventory.loot.entitySource;
                    _existsControllers.Remove(controller.GetComponent<BaseNetworkable>().net.ID.Value);
                    if(source != null) {
                        var storage = source as StorageContainer;
                        if(storage) {
                            if(storage.name == $"panimal_{controller.owner.userID}") {
                                controller.owner.EndLooting();
                            }
                        }
                    }
                    if(controller.bagItems.Count != 0) {
                        var backpack = GameManager.server.CreateEntity("assets/prefabs/misc/item drop/item_drop_backpack.prefab", entity.transform.position, Quaternion.identity) as DroppedItemContainer;
                        backpack.inventory = new ItemContainer();
                        backpack.inventory.ServerInitialize((Item) null, controller.bagItems.Count);
                        backpack.inventory.GiveUID();
                        backpack.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
                        foreach(var bagItem in controller.bagItems) {
                            var obj = bagItem.ToItem();
                            if (!obj.MoveToContainer(backpack.inventory)) obj.DropAndTossUpwards(backpack.transform.position);
                        }
                        backpack.ResetRemovalTime();
                        backpack.Spawn();
                        if(controller.animalSetup.functionsSetup.onlyOwnerLootDeadBag) {
                            backpack.name = $"panimal_{controller.owner.userID}";
                            backpack.OwnerID = controller.owner.userID;
                        }
                    }
                }
                if(ownerComponent.controller != null) {
                    if(ownerComponent.controller.animalSetup.interactionSetup.despawnCorpse) {
                        entity.transform.position = new Vector3(0, -1000, 0);
                    }
                }
                if(ownerComponent.controller) UnityEngine.Object.Destroy(ownerComponent.controller);
                ownerComponent.isLootSpawned = true;
            }
        }
        private object OnPlayerViolation(BasePlayer player, AntiHackType type, float amount) {
            if(player == null || type == AntiHackType.None) return null;
            if(!_existsControllers.ContainsKey(player.net.ID.Value)) return null;
            var controller = _existsControllers[player.net.ID.Value];
            if(controller == null) {
                _existsControllers.Remove(player.net.ID.Value);
                return null;
            }
            if(controller.IsDriving) {
                if(!_config.protect.flyHack && type == AntiHackType.FlyHack) return false;
                if(!_config.protect.insideTerrain && type == AntiHackType.InsideTerrain) return false;
                if(!_config.protect.noClip && type == AntiHackType.NoClip) return false;
                if(!_config.protect.speedHack && type == AntiHackType.SpeedHack) return false;
            }
            return null;
        }
        private void OnLootEntity(BasePlayer player, BaseEntity entity) {
            if(player == null || entity == null) return;
            if(entity is DroppedItemContainer || entity is LootableCorpse) {
                if(entity.name.Contains("panimal")) {
                    if(entity.OwnerID != player.userID) {
                        player.ChatMessage(GetMsg("Bot_Error_Dead_NotOwner", player.UserIDString));
                        NextTick(() => player.EndLooting());
                        return;
                    }
                }
            }
        }
        private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
            if(entity == null || info == null || info?.Initiator == null || entity.net == null || info?.Initiator?.net == null) return null;
            BaseEntity target = info.Initiator;
            if(!(target is BaseCombatEntity)) return null;
            if(_existsOwnerComponents.ContainsKey(target.net.ID.Value)) {
                var initiatorBotOwner = _existsOwnerComponents[target.net.ID.Value];
                if(initiatorBotOwner != null && initiatorBotOwner?.controller != null) {
                    info.damageTypes.ScaleAll(initiatorBotOwner.controller.animalSetup.interactionSetup.botDamageRate);
                    if(_config.damageScale.ContainsKey(entity.ShortPrefabName)) info.damageTypes.ScaleAll(_config.damageScale[entity.ShortPrefabName]);
                    if(!initiatorBotOwner.controller.animalSetup.interactionSetup.canDamagePlayers) {
                        var victim = entity.ToPlayer();
                        if(victim != null) {
                            if(!victim.IsNpc && victim.userID.IsSteamId()) {
                                return false;
                            }
                        }
                    }
                }
            }
            if(_existsControllers.ContainsKey(entity.net.ID.Value)) {
                var controller = _existsControllers[entity.net.ID.Value];
                if(controller != null) {
                    if(target == controller?.bot) return false;
                    controller.OnAttacked(target, info, true);
                }
                return null;
            }
            if(_existsOwnerComponents.ContainsKey(entity.net.ID.Value)) {
                var ownerComponent = _existsOwnerComponents[entity.net.ID.Value];
                if(ownerComponent != null && ownerComponent?.controller != null) {
                    if(entity == ownerComponent.controller?.owner) return false;
                    info.damageTypes?.ScaleAll(ownerComponent.controller.animalSetup.interactionSetup.botReceiveDamageRate);
                    if(!ownerComponent.controller.animalSetup.interactionSetup.canBeDamagedByPlayers) {
                        var player = target.ToPlayer();
                        if(player != null) {
                            if(player.IsNpc == false && player.userID.IsSteamId()) {
                                return false;
                            }
                        }
                    }
                    ownerComponent.controller.OnAttacked(target, info);
                }
            }
            return null;
        }
        private void Unload() {
            var finded = _existsControllers;
            for (int i = finded.Count - 1; i >= 0; i--) {
                var obj = new List<PlayerAnimalController>(_existsControllers.Values)[i];
                if(obj.bot != null) obj.bot.Kill();
                if(obj) UnityEngine.Object.Destroy(obj);
            }
            var cachedPlayers = Facepunch.Pool.GetList<BasePlayer>();
            cachedPlayers.AddRange(BasePlayer.activePlayerList);
            cachedPlayers.ForEach(x => CuiHelper.DestroyUi(x, "PersonalAnimal_ControlPanel"));
            Facepunch.Pool.FreeList(ref cachedPlayers);
        }
        private object CanAcceptItem(ItemContainer container, Item item, int targetPos) {
            var player = item?.GetOwnerPlayer();
            if(player == null) return null;
            if(!_existsControllers.ContainsKey(player.net.ID.Value)) return null;
            var controller = _existsControllers[player.net.ID.Value];
            if(controller != null) {
                var owner = container.GetEntityOwner();
                if(owner == null) return null;
                if(controller.IsBlacklisted(item) && owner.name == $"panimal_{player.userID}") {
                    SendMsg(player, "ChatCommand_Error_Blacklist");
                    return ItemContainer.CanAcceptResult.CannotAcceptRightNow;
                }
            }
            else {
                _existsControllers.Remove(player.net.ID.Value);
            }
            return null;
        }
        private void Loaded() {
            Instance = this;
            _permissionKeys = new List<string>(_config.animalInfoPerm.Keys);
            _permissionKeys.ForEach(x => permission.RegisterPermission(x, this));
        }
        private void OnLootEntityEnd(BasePlayer player, BaseCombatEntity entity) {
            if(!_existsControllers.ContainsKey(player.net.ID.Value)) return;
            var controller = _existsControllers[player.net.ID.Value];
            if(controller == null) {
                _existsControllers.Remove(player.net.ID.Value);
                return;
            }
            if(!controller.animalSetup.addonsSetup.needBag) return;
            var storage = entity as StorageContainer;
            if(storage == null) return;
            if(storage.name != $"panimal_{player.userID}") return;
            controller.UpdateItems(storage.inventory);
        }
        private void OnEntityBuilt(Planner plan, GameObject go) {
            if(_config.installItem.Count == 0) return;
            var player = plan.GetOwnerPlayer();
            if(player == null) return;
            var item = player.GetActiveItem();
            if(item == null) return;
            foreach(var loopInfo in _config.installItem) {
                if(loopInfo.skin == item.skin) {
                    PlayerAnimalController comp;
                    if(player.TryGetComponent<PlayerAnimalController>(out comp)) {
                        if(comp.ItemInfo.returnDespawn) {
                            Item panimal = ItemManager.CreateByName(comp.ItemInfo.shortname, 1, comp.ItemInfo.skin);
                            if(!string.IsNullOrEmpty(comp.ItemInfo.name)) panimal.name = comp.ItemInfo.name;
                            player.GiveItem(panimal);
                        }
                        comp.bot.Kill();
                        //OnEntityDeath(comp.bot, null);
                    }
                    NextTick(() => {
                        var controller = player.gameObject.AddComponent<PlayerAnimalController>();
                        controller.bot = CreateBot(player, loopInfo.animal, go.transform.position);
                        controller.owner = player;
                        controller.mountButton = mountButton;
                        controller.controlButton = controlButton;
                        controller.inventoryButton = inventoryButton;
                        controller.ItemInfo = loopInfo;
                        _existsControllers.Remove(player.net.ID.Value);
                        _existsControllers.Add(player.net.ID.Value, controller);
                        SendMsg(player, "ChatCommand_Success_Spawn");
                        go.ToBaseEntity().Kill();
                    }
                    );
                    break;
                }
            }
        }
#endregion
#region Methods
        [ChatCommand("panimal")]
        private void chatCommand(BasePlayer player, string command, string[] args) {
            if(args == null || args?.Length == 0) {
                PlayerAnimalController playerAnimalController;
                if(player.TryGetComponent<PlayerAnimalController>(out playerAnimalController)) {
                    if(playerAnimalController.ItemInfo.returnDespawn) {
                        Item panimal = ItemManager.CreateByName(playerAnimalController.ItemInfo.shortname, 1, playerAnimalController.ItemInfo.skin);
                        if(!string.IsNullOrEmpty(playerAnimalController.ItemInfo.name)) panimal.name = playerAnimalController.ItemInfo.name;
                        player.GiveItem(panimal);
                    }
                    if(playerAnimalController.bot) {
                        player.EndLooting();
                        playerAnimalController.bot.Kill();
                    }
                    SendMsg(player, "ChatCommand_Success_Despawn");
                }
                else {
                    var botSetup = GetBotSetup(player);
                    if(botSetup != null) {
                        if(botSetup.Count == 0) SendMsg(player, "ChatCommand_Error_NoPermission");
                        else {
                            if(botSetup.Count == 1) {
                                chatCommand(player, command, new string[] {
                                    botSetup[0].spawnName
                                }
                                );
                                return;
                            }
                            string msg = lang.GetMessage("ChatCommand_Notice_AvailableBots", this, player.UserIDString);
                            string availableBots = "";
                            foreach(var bot in botSetup) {
                                availableBots = availableBots + $"\n{botSetup.IndexOf(bot) + 1}.{bot.spawnName}";
                            }
                            msg = msg.Replace("{BOTS}", availableBots);
                            player.ChatMessage(msg);
                        }
                    }
                }
                return;
            }
            if(args[0] == "idle") {
                var controller = player.GetComponent<PlayerAnimalController>();
                if(controller == null) {
                    SendMsg(player, "ChatCommand_Error_NoBot");
                    return;
                }
                else {
                    controller.Idle();
                    SendMsg(player, "Bot_Notice_Staying");
                    return;
                }
            }
            if(args[0] == "where") {
                var controller = player.GetComponent<PlayerAnimalController>();
                if(controller == null) {
                    SendMsg(player, "ChatCommand_Error_NoBot");
                    return;
                }
                else {
                    SendMsg(player, "ChatCommand_Notice_Location", new string[] {
                        PersonalAnimal.GetGrid(controller.bot.transform.position), Vector3.Distance(controller.bot.transform.position, player.transform.position).ToString()
                    }
                    );
                    return;
                }
            }
            if(args[0] == "health") {
                var controller = player.GetComponent<PlayerAnimalController>();
                if(controller == null) {
                    SendMsg(player, "ChatCommand_Error_NoBot");
                    return;
                }
                else {
                    SendMsg(player, "ChatCommand_Notice_Health", new string[] {
                        Mathf.RoundToInt(controller.bot.Health()).ToString(), Mathf.RoundToInt(controller.bot.MaxHealth()).ToString()
                    }
                    );
                    return;
                }
            }
            if(args[0] == "follow") {
                var controller = player.GetComponent<PlayerAnimalController>();
                if(controller == null) {
                    SendMsg(player, "ChatCommand_Error_NoBot");
                    return;
                }
                else {
                    controller.FollowPlayer();
                    SendMsg(player, "Bot_Notice_Following");
                    return;
                }
            }
            if(args[0] == "auto-pickup") {
                if(args.Length == 1) {
                    SendMsg(player, "ChatCommand_Error_AutoPickup");
                    return;
                }
                else {
                    var controller = player.GetComponent<PlayerAnimalController>();
                    if(controller == null) {
                        SendMsg(player, "ChatCommand_Error_NoBot");
                        return;
                    }
                    var compMode = controller.mode;
                    if(compMode == null) {
                        SendMsg(player, "ChatCommand_Error_CannotUse");
                        return;
                    }
                    else if(!controller.animalSetup.functionsSetup.canAutoCollect) {
                        SendMsg(player, "ChatCommand_Error_CannotUse");
                        return;
                    }
                    if(args[1] == "disable") {
                        compMode.Disable();
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "enable") {
                        compMode.SetMode(AnimalAutoMode.AutoMode.Pickup);
                        compMode.EnableMode();
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "all") {
                        compMode.AddResource(AnimalAutoMode.Resources.All);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "stone") {
                        compMode.AddResource(AnimalAutoMode.Resources.Stone);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "metal") {
                        compMode.AddResource(AnimalAutoMode.Resources.Metal);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "sulfur") {
                        compMode.AddResource(AnimalAutoMode.Resources.Sulfur);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "wood") {
                        compMode.AddResource(AnimalAutoMode.Resources.Wood);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "hemp") {
                        compMode.AddResource(AnimalAutoMode.Resources.Hemp);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "corn") {
                        compMode.AddResource(AnimalAutoMode.Resources.Corn);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "mushroom") {
                        compMode.AddResource(AnimalAutoMode.Resources.Mushroom);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "pumpkin") {
                        compMode.AddResource(AnimalAutoMode.Resources.Pumpkin);
                        SendMsg(player, "ChatCommand_Notice_AutoPickup_Status");
                        return;
                    }
                    if(args[1] == "berries") {
                        compMode.AddResource(AnimalAutoMode.Resources.Berries);
                        SendMsg(player, 
// ... [Code preview truncated due to length. Full source in attached file] ...

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