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

FREE PumpkinHead : 1.1.3 1.1.3

Нет прав для скачивания
C#:
using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using Oxide.Core;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Facepunch;
using Rust;
using Rust.Ai;

namespace Oxide.Plugins
{
    [Info("PumpkinHead", "Krungh Crow", "1.1.3", ResourceId = 1442)]
    [Description("When picking up wild pumpkins or Corn (Pumpkin/Corn)Head can appear")]

    #region Changelogs and ToDo
    /**********************************************************************
     * 1.0.0    :   -   Initial release By request [The Friendly Chap]
     * 1.0.1    :   -   Optimisations and minor Cleanup (thx to the Codefling Team)
     * 1.0.2    :   -   Wrapped corpse injection in a slight delay
     * 1.0.3    :   -   Removed Wounded state to avoid npc looting before it is killed.*          :   -   Npc now spawns in a small radius around the pumpkin.* 1.0.4    :   -   Added various FX through cfg
     * 1.1.0    :   -   Added CornHead npc and appropriate cfg settings and checks
     * 1.1.1    :   -   Fix for kits not aplying
     * 1.1.2    :   -   Patched for December 2nd rust update
     *              -   Removed murderer which is removed by Facepunch
     *              -   NPC are now scientists (working on mellee part)
     * 1.1.3    :   -   Fixed oxide mixing up HumanNPC plugin(same name) and npc type
     * 
     **********************************************************************/
    #endregion

    class PumpkinHead : RustPlugin
    {
        [PluginReference] Plugin Kits;

        public static Dictionary<BasePlayer, Zombies> SpawnedZombies { get; set; } = new Dictionary<BasePlayer, Zombies>();

        #region Mono
        public static PumpkinHead instance;

        void OnServerInitialized()
        {
            instance = this;
        }

        void Unload()
        {
            if (SpawnedZombies != null)
            {
                foreach (var zombie in SpawnedZombies)
                    if (zombie.Key != null && !zombie.Key.IsDead())
                        UnityEngine.Object.Destroy(zombie.Value);
            }
        }

        public class Zombies : MonoBehaviour
        {
            public global::HumanNPC npc;
            public bool ReturningToHome = false;
            public Vector3 SpawnPoint;
            public bool ignoreSafeZonePlayers = true;

            void Start()
            {
                npc = GetComponent<global::HumanNPC>();

                InvokeRepeating("GoHome", 1f, 1f);
            }
            public void Init()
            {
                npc.Brain.Navigator.Agent.agentTypeID = -1372625422;
                npc.Brain.Navigator.DefaultArea = "Walkable";
                npc.Brain.Navigator.Init(npc, npc.Brain.Navigator.Agent);
                npc.Brain.ForceSetAge(0);
                npc.Brain.TargetLostRange = 30f;
                npc.Brain.HostileTargetsOnly = false;
                npc.Brain.Navigator.BestCoverPointMaxDistance = 20f;//0
                npc.Brain.Navigator.BestRoamPointMaxDistance = 20f;//0
                npc.Brain.Navigator.MaxRoamDistanceFromHome = instance.configData.NPCData.NPCRoam;
                npc.SetDestination(SpawnPoint);
                npc.Brain.Senses.Init(npc, 5f, 60f, 140f, -1f, true, false, true, 60f, false, false, false, EntityType.Player, false);
            }

            void GoHome()
            {
                if (npc == null || npc.IsDestroyed || npc.isMounted)
                    return;

                if (!npc.HasBrain)
                    return;

                if (npc.Distance(SpawnPoint) >= instance.configData.NPCData.NPCRoam)
                {
                    npc.Brain.Senses.Memory.Targets.Clear();
                    npc.Brain.Senses.Memory.Threats.Clear();
                }

                if (npc.Brain.Senses.Memory.Targets.Count != 0)
                    return;

                if (npc.Brain.Navigator.Agent == null || !npc.Brain.Navigator.Agent.isOnNavMesh)
                {
                    npc.Brain.Navigator.Destination = SpawnPoint;
                    npc.SetDestination(SpawnPoint);
                }
                else
                    npc.Brain.Navigator.SetDestination(SpawnPoint);
            }

            void OnDestroy()
            {
                if (npc != null && !npc.IsDestroyed)
                {
                    npc.Kill();
                }
                CancelInvoke();
            }
        }
        #endregion

        #region Variables

        const string Use_Perm = "pumpkinhead.use";
        private readonly List<ulong> _Pin = new List<ulong>();

        private bool Debug;
        bool IsSpawned;
        bool IsSeed = false;
        const string zombie = "assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_junkpile_pistol.prefab";
        const ulong chaticon = 0;
        private Dictionary<string, List<ulong>> Skins { get; set; } = new Dictionary<string, List<ulong>>();
        string _Node;
        bool CanGive = false;
        bool KitIsValid;
        bool IsPumpkin;
        bool IsCorn;

        #endregion

        #region Configuration
        void Init()
        {
            if (!LoadConfigVariables())
            {
                Puts("Config file issue detected.Please delete file, or check syntax and fix.");
                return;
            }
            Debug = configData.UseDebug;
            permission.RegisterPermission(Use_Perm, this);
            if (Debug) Puts($"[Debug] Debug is active");
        }

        private ConfigData configData;

        class ConfigData
        {
            [JsonProperty(PropertyName = "Use Debug")]
            public bool UseDebug = false;
            [JsonProperty(PropertyName = "PumpkinHead triggers")]
            public Pickup PickupData = new Pickup();
            [JsonProperty(PropertyName = "NPC Settings")]
            public SettingsNPC NPCData = new SettingsNPC();
        }

        class Pickup
        {
            [JsonProperty(PropertyName = "Wild Pumpkins")]
            public Pumpkins DataPumpkins = new Pumpkins();
            [JsonProperty(PropertyName = "Wild Corn")]
            public Corn DataCorn = new Corn();
        }

        class Pumpkins
        {
            [JsonProperty(PropertyName = "Can spawn from wild Pumpkins")]
            public bool TriggerPumpkin = true;
            [JsonProperty(PropertyName = "Spawn chance (1-100%)")]
            public float NPCSpawnratePumpkin = 10f;
            [JsonProperty(PropertyName = "Sound and visual FX")]
            public Effects FXData = new Effects();
        }

        class Corn
        {
            [JsonProperty(PropertyName = "Can spawn from wild Corn")]
            public bool TriggerCorn = true;
            [JsonProperty(PropertyName = "Spawn chance (1-100%)")]
            public float NPCSpawnrateCorn = 10f;
            [JsonProperty(PropertyName = "Sound and visual FX")]
            public Effects FXData = new Effects();
        }

        class Effects
        {
            [JsonProperty(PropertyName = "FX used when npc spawns (at npc position)")]
            public string SpawnFX = "assets/bundled/prefabs/fx/explosions/water_bomb.prefab";
            [JsonProperty(PropertyName = "Spawn soundeffect (at player position)")]
            public string SpawnFXspawnsound = "assets/bundled/prefabs/fx/player/howl.prefab";
            [JsonProperty(PropertyName = "FX used when npc dies (at npc position)")]
            public string SpawnFXdie = "assets/bundled/prefabs/fx/explosions/water_bomb.prefab";
            [JsonProperty(PropertyName = "Death soundeffect (npc deathsound)")]
            public string SpawnFXdeathsound = "assets/prefabs/npc/murderer/sound/death.prefab";
        }

        class SettingsNPC
        {
            [JsonProperty(PropertyName = "Spawn Amount")]
            public int NPCAmount = 1;
            [JsonProperty(PropertyName = "Health")]
            public int NPCHealth = 250;
            [JsonProperty(PropertyName = "Max Roam Distance")]
            public int NPCRoam = 20;
            [JsonProperty(PropertyName = "Damage multiplier")]
            public float NPCDamageScale = 0.6f;
            [JsonProperty(PropertyName = "Lifetime (minutes)")]
            public float NPCLife = 10f;
            [JsonProperty(PropertyName = "Use kit (clothing)")]
            public bool UseKit = false;
            [JsonProperty(PropertyName = "Kit ID PumpkinHead")]
            public List<string> KitName = new List<string>();
            [JsonProperty(PropertyName = "Kit ID CornHead")]
            public List<string> KitName2 = new List<string>();
            [JsonProperty(PropertyName = "Show messages")]
            public bool ShowMsg = true;
            [JsonProperty(PropertyName = "NPC drop a Backpack with loot")]
            public bool UseLoot = false;
            [JsonProperty(PropertyName = "Use Random Skins")]
            public bool RandomSkins { get; set; } = true;
            [JsonProperty(PropertyName = "Spawn Min Amount Items")]
            public int MinAmount { get; set; } = 2;
            [JsonProperty(PropertyName = "Spawn Max Amount Items")]
            public int MaxAmount { get; set; } = 6;
            [JsonProperty(PropertyName = "Loot Table", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<LootItem> Loot { get; set; } = DefaultLoot;
        }

        private bool LoadConfigVariables()
        {
            try
            {
                configData = Config.ReadObject<ConfigData>();
            }
            catch
            {
                return false;
            }
            SaveConf();
            return true;
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Fresh install detected Creating a new config file.");
            configData = new ConfigData();
            SaveConf();
        }

        void SaveConf() => Config.WriteObject(configData, true);
        #endregion

        #region LanguageAPI
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["CornHead_Spawn"] = "My Coooorn",
                ["CornHead_Spawn_Backpack"] = "A Backpack dropped!",
                ["PumpkinHead_Spawn"] = "My Pumpkiiiin",
                ["PumpkinHead_Spawn_Backpack"] = "A Backpack dropped!",
                ["Prefix"] = "[<color=green>PumpkinHead</color>] : ",
                ["info"] = "\nGathering the wild pumpkins or corn outside you could be jumped by PumpkinHead or his twin CornHead.",
            }, this);
        }

        #endregion

        #region Commands

        [ChatCommand("phinfo")]
        void cmdphinfo(BasePlayer player, string cmd, string[] args)
        {
            string prefix = lang.GetMessage("Prefix", this);
            {
                Player.Message(player, prefix + string.Format(msg("Current Version v", player.UserIDString)) + this.Version.ToString() + " By : " + this.Author.ToString() + msg("info"), chaticon);
            }
        }

        #endregion

        #region Hooks

        object OnNpcKits(BasePlayer player)
        {
            if (_Pin.Contains(player.userID))
                return true;
            return null;
        }

        object OnCollectiblePickup(Item item, BasePlayer player, CollectibleEntity entity)
        {
            IsPumpkin = false;
            IsCorn = false;
            if (item == null || player == null || entity == null) return null;
            if (!permission.UserHasPermission(player.UserIDString, Use_Perm)) return null;
            if (item.info.shortname == "pumpkin" && !CheckSeed(item) && UnityEngine.Random.Range(0f, 1f) <= configData.PickupData.DataPumpkins.NPCSpawnratePumpkin / 100)
            {
                if (Debug) Puts($"{player} picked up Pumpkins");
                CanGive = true;
                IsPumpkin = true;
            }
            if (item.info.shortname == "corn" && !CheckSeed(item) && UnityEngine.Random.Range(0f, 1f) <= configData.PickupData.DataCorn.NPCSpawnrateCorn / 100)
            {
                if (Debug) Puts($"{player} picked up Corn");
                CanGive = true;
                IsCorn = true;
            }
            if (CanGive == true && !CheckSeed(item))
            {
                if (item != null)
                {
                    for (int i = 0; i < configData.NPCData.NPCAmount; i++)
                    {
                        Spawnnpc(entity.transform.position);
                    }
                    CanGive = false;
                    if (configData.NPCData.ShowMsg && IsSpawned == true)
                    {
                        string prefix = lang.GetMessage("Prefix", this);
                        if (IsPumpkin)
                        {
                            Player.Message(player, prefix + string.Format(msg("PumpkinHead_Spawn", player.UserIDString)), chaticon);
                        }
                        else if (IsCorn)
                        {
                            Player.Message(player, prefix + string.Format(msg("CornHead_Spawn", player.UserIDString)), chaticon);
                        }
                    }
                    if (IsPumpkin && configData.PickupData.DataPumpkins.FXData.SpawnFXspawnsound != null)
                    {
                        Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFXspawnsound, player.transform.position);
                    }
                    if (IsCorn && configData.PickupData.DataCorn.FXData.SpawnFXspawnsound != null)
                    {
                        Effect.server.Run(configData.PickupData.DataCorn.FXData.SpawnFXspawnsound, player.transform.position);
                    }
                }
            }
            return null;
        }

        void OnEntityDeath(global::HumanNPC zombie, HitInfo info)
        {
            if (zombie == null || info?.Initiator == null) return;

            if (_Pin.Contains(zombie.userID))
            {
                BasePlayer player = info.InitiatorPlayer;
                if (player == null || !player.IsValid()) return;

                if (!info.InitiatorPlayer.userID.IsSteamId())
                {
                    return;
                }

                if (configData.NPCData.UseLoot == true)
                {
                    if (configData.NPCData.ShowMsg)
                    {
                        string prefix = lang.GetMessage("Prefix", this);
                        Player.Message(player, prefix + string.Format(msg("PumpkinHead_Spawn_Backpack", player.UserIDString)), chaticon);
                    }
                    SpawnLoot(zombie.transform.position + new Vector3(0f, 0.5f, 0f), zombie.transform.rotation);
                }
                _Pin.Remove(zombie.userID);
            }
        }

        private object OnNpcTarget(BasePlayer attacker, BasePlayer target)
        {
            if (attacker != null && (attacker.displayName == "PumpkinHead" || attacker.displayName == "CornHead"))
            {
                if ( target.IsSleeping () || !target.userID.IsSteamId () )
                    return true;
            }
            return null;
        }

        void OnEntitySpawned ( NPCPlayerCorpse corpse )
        {
            if ( corpse == null || corpse.IsDestroyed ) return;

            ulong id = corpse.playerSteamID;

            if (corpse._playerName.Contains("PumpkinHead") || corpse._playerName.Contains("CornHead"))
            {
                try
                {
                    if (corpse._playerName.Contains("PumpkinHead") && configData.PickupData.DataPumpkins.FXData.SpawnFXdie != null)
                    {
                        Vector3 pos = corpse.transform.position;
                        pos.y = TerrainMeta.HeightMap.GetHeight(pos);
                        CheckPos(pos);
                        if (pos != Vector3.zero)
                        {
                            Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFXdie, pos);
                        }
                        Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFXdeathsound, pos);
                    }

                    if (corpse._playerName.Contains("CornHead") && configData.PickupData.DataCorn.FXData.SpawnFXdie != null)
                    {
                        Vector3 pos = corpse.transform.position;
                        pos.y = TerrainMeta.HeightMap.GetHeight(pos);
                        CheckPos(pos);
                        if (pos != Vector3.zero)
                        {
                            Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFXdie, pos);
                        }
                        Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFXdeathsound, pos);
                    }

                    if (Debug && corpse._playerName.Contains("PumpkinHead")) Puts($"[Debug] NPC is PumpkinHead[{id}] so corpse injection is possible");
                    if (Debug && corpse._playerName.Contains("CornHead")) Puts($"[Debug] NPC is CornHead[{id}] so corpse injection is possible");
                    NextTick(() =>
                    {
                        Item PHCorn = ItemManager.CreateByName("corn", 1, 0);

                        if (corpse._playerName.Contains("PumpkinHead"))
                        {
                            PHCorn = ItemManager.CreateByName("corn", 1, 0);
                        }
                        if (corpse._playerName.Contains("CornHead"))
                        {
                            PHCorn = ItemManager.CreateByName("pumpkin", 1, 0);
                        }

                        ItemAmount NPCCorn = new ItemAmount() { itemDef = PHCorn.info, amount = 1, startAmount = 1 };
                        Item PHFiber = ItemManager.CreateByName("plantfiber", 1, 0);
                        ItemAmount NPCFiber = new ItemAmount() { itemDef = PHFiber.info, amount = 6, startAmount = 1 };

                        var dispenser = corpse.GetComponent<ResourceDispenser>();
                        if (dispenser != null)
                        {
                            dispenser.containedItems.Add(NPCCorn);
                            dispenser.containedItems.Add(NPCFiber);
                            dispenser.Initialize();
                            if (Debug && corpse._playerName.Contains("PumpkinHead")) Puts($"[Debug] PumpkinHead[{id}] Corpse was injected with [Corn & Plant fibers]");
                            if (Debug && corpse._playerName.Contains("CornHead")) Puts($"[Debug] CornHead[{id}] Corpse was injected with [Pumpkin & Plant fibers]");
                        }
                    });
                }
                catch
                {
                }
            }
            return;
        }

        #endregion

        #region Event Helpers
        private bool CheckSeed ( Item item )
        {
            if ( item.ToString ().ToLower ().Contains ( "seed" ) )
            {
                IsSeed = true;
            }
            else return false;
            return IsSeed;
        }

        public static Vector3 CheckPos(Vector3 pos)
        {
            NavMeshHit navMeshHit;

            if (!NavMesh.SamplePosition(pos, out navMeshHit, 1, 1))
                pos = Vector3.zero;
            else if (WaterLevel.GetWaterDepth(pos, true) > 0.6f)
                pos = Vector3.zero;
            else if (Physics.RaycastAll(navMeshHit.position + new Vector3(0, 100, 0), Vector3.down, 99f, 1235288065).Any())
                pos = Vector3.zero;
            else
                pos = new Vector3(navMeshHit.position.x, TerrainMeta.HeightMap.GetHeight(navMeshHit.position), navMeshHit.position.z);
            return pos;
        }

        private void Spawnnpc ( Vector3 position )
        {
            int radius = 3;
            Vector3 pos = position + UnityEngine.Random.onUnitSphere * radius;
            pos.y = TerrainMeta.HeightMap.GetHeight(pos);
            CheckPos(pos);
            if (pos == Vector3.zero)
            {
                return;
            }
            global::HumanNPC npc = (global::HumanNPC)GameManager.server.CreateEntity(zombie, pos, new Quaternion(), true);

            npc.Spawn ();
            if (IsPumpkin)
            {
                npc.displayName = "PumpkinHead";
            }
            if (IsCorn)
            {
                npc.displayName = "CornHead";
            }
            NextTick( () =>
              {
                  if ( npc == null )
                      return;

                  var mono = npc.gameObject.AddComponent<Zombies> ();
                  mono.SpawnPoint = pos;
                  SpawnedZombies.Add ( npc, mono );

                  npc.startHealth = configData.NPCData.NPCHealth;
                  npc.InitializeHealth ( configData.NPCData.NPCHealth, configData.NPCData.NPCHealth );
                  KitIsValid = false;
                  npc.damageScale = configData.NPCData.NPCDamageScale;

                  if ((npc.displayName == "PumpkinHead") && configData.NPCData.UseKit && configData.NPCData.KitName.Count > 0 )
                  {
                      object checkKit = Kits?.CallHook ( "GetKitInfo", configData.NPCData.KitName [ new System.Random ().Next ( configData.NPCData.KitName.Count () ) ] );
                      if ( checkKit != null )
                      {
                          npc.inventory.Strip ();
                          Kits?.Call ( $"GiveKit", npc, configData.NPCData.KitName [ new System.Random ().Next ( configData.NPCData.KitName.Count () ) ] );
                          KitIsValid = true;
                      }
                  }

                  if ((npc.displayName == "CornHead") && configData.NPCData.UseKit && configData.NPCData.KitName2.Count > 0)
                  {
                      object checkKit = Kits?.CallHook("GetKitInfo", configData.NPCData.KitName2[new System.Random().Next(configData.NPCData.KitName2.Count())]);
                      if (checkKit != null)
                      {
                          npc.inventory.Strip();
                          Kits?.Call($"GiveKit", npc, configData.NPCData.KitName2[new System.Random().Next(configData.NPCData.KitName2.Count())]);
                          KitIsValid = true;
                      }
                  }
                  (npc as ScientistNPC).radioChatterType = ScientistNPC.RadioChatterType.NONE;

                  if ( !KitIsValid || !configData.NPCData.UseKit )
                  {
                      var inv_belt = npc.inventory.containerBelt;
                      var inv_wear = npc.inventory.containerWear;

                      npc.inventory.Strip ();
                      if(npc.displayName.Contains("PumpkinHead"))
                      {
                          ItemManager.CreateByName("pumpkin", 1, 0).MoveToContainer(inv_wear, 0);
                      }
                      if (npc.displayName.Contains("CornHead"))
                      {
                          ItemManager.CreateByName("metal.facemask", 1, 1670059636UL).MoveToContainer(inv_wear, 0);
                      }

                      Item eyes = ItemManager.CreateByName ( "gloweyes", 1, 0 );
                      Item boots = ItemManager.CreateByName ( "shoes.boots", 1, 0 );
                      Item gloves = ItemManager.CreateByName ( "burlap.gloves.new", 1, 0 );
                      Item chest = ItemManager.CreateByName ( "burlap.shirt", 1, 0 );
                      Item pants = ItemManager.CreateByName ( "burlap.trousers", 1, 0 );
                      Item woodpants = ItemManager.CreateByName ( "wood.armor.pants", 1, 0 );

                      switch ( UnityEngine.Random.Range ( 0, 4 ) )
                      {
                          case 0:
                              ItemManager.CreateByName ( "shotgun.waterpipe", 1, 0 ).MoveToContainer ( inv_belt, 0 );
                              break;
                          case 1:
                              ItemManager.CreateByName ("shotgun.double", 1, 0 ).MoveToContainer ( inv_belt, 0 );
                              break;
                          case 2:
                              ItemManager.CreateByName ("shotgun.pump", 1, 0 ).MoveToContainer ( inv_belt, 0 );
                              break;
                          default:
                              ItemManager.CreateByName ("shotgun.spas12", 1, 0 ).MoveToContainer ( inv_belt, 0 );
                              break;
                      }
                      if ( eyes != null ) eyes.MoveToContainer ( inv_wear );
                      if ( boots != null ) boots.MoveToContainer ( inv_wear );
                      if ( gloves != null ) gloves.MoveToContainer ( inv_wear );
                      if ( chest != null ) chest.MoveToContainer ( inv_wear );
                      if ( pants != null ) pants.MoveToContainer ( inv_wear );
                      if ( woodpants != null ) woodpants.MoveToContainer ( inv_wear );
                      if ( Debug ) PrintWarning ( $"{npc} has a default outfit assigned." );

                  }
              } );

            if (npc.IsHeadUnderwater())
            {
                npc.Kill();
                if (IsPumpkin) Puts("PumpkinHead[" + npc.userID + "] skipped its spawn (spawned under water)");
                if (IsCorn) Puts("CornHead[" + npc.userID + "] skipped its spawn (spawned under water)");
                IsSpawned = false;
                return;
            }
            if (!npc.IsOutside())
            {
                npc.Kill();
                if (IsPumpkin) Puts("PumpkinHead[" + npc.userID + "] skipped its spawn (No valid spawnpoint)");
                if (IsCorn) Puts("CornHead[" + npc.userID + "] skipped its spawn (No valid spawnpoint)");
                IsSpawned = false;
                return;
            }
            IsSpawned = true;

            var id = npc.userID;
            if (IsPumpkin) Puts($"PumpkinHead[" + id + "] spawned");
            if (IsCorn) Puts($"CornHead[" + id + "] spawned");
            _Pin.Add(npc.userID);
            if (IsPumpkin && configData.PickupData.DataPumpkins.FXData.SpawnFX != null)
            {
                Effect.server.Run(configData.PickupData.DataPumpkins.FXData.SpawnFX, npc.transform.position);
            }
            if (IsCorn && configData.PickupData.DataCorn.FXData.SpawnFX != null)
            {
                Effect.server.Run(configData.PickupData.DataCorn.FXData.SpawnFX, npc.transform.position);
            }
            timer.Once(configData.NPCData.NPCLife * 60, () =>
            {
                if (npc != null)
                {
                    _Pin.Remove(npc.userID);
                    npc.Kill();
                    if (IsPumpkin) Puts("PumpkinHead[" + id + "] Died of natural causes!!!");
                    if (IsCorn) Puts("CornHead[" + id + "] Died of natural causes!!!");
                    return;
                }
                if (Debug && IsPumpkin) Puts("[Debug] PumpkinHead[" + id + "] was killed before ending of timer");
                if (Debug && IsCorn) Puts("[Debug] CornHead[" + id + "] was killed before ending of timer");
                return;
            });
        }

        #endregion

        #region Loot System

        private static List<LootItem> DefaultLoot
        {
            get
            {
                return new List<LootItem>
                {
                    new LootItem { shortname = "ammo.pistol", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.pistol.fire", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.pistol.hv", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.rifle", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.rifle.explosive", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.rifle.hv", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.rifle.incendiary", amount = 5, skin = 0, amountMin = 5 },
                    new LootItem { shortname = "ammo.shotgun", amount = 12, skin = 0, amountMin = 8 },
                    new LootItem { shortname = "explosive.timed", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "explosives", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "pistol.m92", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "shotgun.spas12", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "pickaxe", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "hatchet", amount = 1, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "can.beans", amount = 3, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "can.tuna", amount = 3, skin = 0, amountMin = 1 },
                    new LootItem { shortname = "black.raspberries", amount = 5, skin = 0, amountMin = 3 },
                };
            }
        }

        public class LootItem
        {
            public string shortname { get; set; }
            public int amount { get; set; }
            public ulong skin { get; set; }
            public int amountMin { get; set; }
        }

        private void SpawnLoot ( Vector3 pos, Quaternion rot )
        {
            var backpack = GameManager.server.CreateEntity ( StringPool.Get ( 1519640547 ), pos, rot, true ) as DroppedItemContainer;

            if ( backpack == null ) return;

            backpack.inventory = new ItemContainer ();
            backpack.inventory.ServerInitialize ( null, 36 );
            backpack.inventory.GiveUID ();
            backpack.inventory.entityOwner = backpack;
            backpack.inventory.SetFlag ( ItemContainer.Flag.NoItemInput, true );
            backpack.Spawn ();
            backpack.playerName = "PumpkinHead Backpack";
            SpawnLoot ( backpack.inventory, configData.NPCData.Loot.ToList () );
        }

        private void SpawnLoot ( ItemContainer container, List<LootItem> loot )
        {
            int total = UnityEngine.Random.Range ( Math.Min ( loot.Count, configData.NPCData.MinAmount ), Math.Min ( loot.Count, configData.NPCData.MaxAmount ) );

            if ( total == 0 || loot.Count == 0 )
            {
                return;
            }

            container.capacity = total;
            ItemDefinition def;
            List<ulong> skins;
            LootItem lootItem;

            for ( int j = 0; j < total; j++ )
            {
                if ( loot.Count == 0 )
                {
                    break;
                }

                lootItem = loot.GetRandom ();

                loot.Remove ( lootItem );

                if ( lootItem.amount <= 0 )
                {
                    continue;
                }

                string shortname = lootItem.shortname;
                bool isBlueprint = shortname.EndsWith ( ".bp" );

                if ( isBlueprint )
                {
                    shortname = shortname.Replace ( ".bp", string.Empty );
                }

                def = ItemManager.FindItemDefinition ( shortname );

                if ( def == null )
                {
                    Puts ( "Invalid shortname: {0}", lootItem.shortname );
                    continue;
                }

                ulong skin = lootItem.skin;

                if ( configData.NPCData.RandomSkins && skin == 0 )
                {
                    skins = GetItemSkins ( def );

                    if ( skins.Count > 0 )
                    {
                        skin = skins.GetRandom ();
                    }
                }

                int amount = lootItem.amount;

                if ( amount <= 0 )
                {
                    continue;
                }

                if ( lootItem.amountMin > 0 && lootItem.amountMin < lootItem.amount )
                {
                    amount = UnityEngine.Random.Range ( lootItem.amountMin, lootItem.amount );
                }

                Item item;

                if ( isBlueprint )
                {
                    item = ItemManager.CreateByItemID ( -996920608, 1, 0 );

                    if ( item == null ) continue;

                    item.blueprintTarget = def.itemid;
                    item.amount = amount;
                }
                else item = ItemManager.Create ( def, amount, skin );

                if ( !item.MoveToContainer ( container, -1, false ) )
                {
                    item.Remove ();
                }
            }
        }

        private List<ulong> GetItemSkins ( ItemDefinition def )
        {
            List<ulong> skins;
            if ( !Skins.TryGetValue ( def.shortname, out skins ) )
            {
                Skins [ def.shortname ] = skins = ExtractItemSkins ( def, skins );
            }

            return skins;
        }

        private List<ulong> ExtractItemSkins ( ItemDefinition def, List<ulong> skins )
        {
            skins = new List<ulong> ();

            foreach ( var skin in def.skins )
            {
                skins.Add ( Convert.ToUInt64 ( skin.id ) );
            }
            foreach ( var asi in Rust.Workshop.Approved.All.Values )
            {
                if ( !string.IsNullOrEmpty ( asi.Skinnable.ItemName ) && asi.Skinnable.ItemName == def.shortname )
                {
                    skins.Add ( Convert.ToUInt64 ( asi.WorkshopdId ) );
                }
            }

            return skins;
        }

        #endregion

        #region Message helper

        private string msg ( string key, string id = null ) => lang.GetMessage ( key, this, id );

        #endregion
    }
}

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