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

FREE HumanNPC : 0.1.18 0.1.18

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Reflection;
using Oxide.Core;
using Oxide.Core.Plugins;
using Rust;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("HumanNPC", "Reneb", "0.1.18", ResourceId = 856)]
    class HumanNPC : RustPlugin {
        //////////////////////////////////////////////////////
        ///  Fields
        //////////////////////////////////////////////////////
        private static FieldInfo serverinput;
        private static FieldInfo viewangles;
        public static FieldInfo lastPositionValue;
        public static FieldInfo displayname;
        private static int playerLayer;
        private DamageTypeList emptyDamage;
        private List<Oxide.Plugins.Timer> TimersList;
        private static Vector3 Vector3Down;
        private static Vector3 Vector3Forward;
        private static Vector3 jumpPosition;
        private static int groundLayer;
        private static int blockshootLayer;
        StoredData storedData;
        Hash<string, HumanNPCInfo> humannpcs = new Hash<string, HumanNPCInfo>();
        [PluginReference]
        Plugin Kits;
        [PluginReference]
        Plugin Waypoints;
        [PluginReference]
        public static Plugin PathFinding;
        //////////////////////////////////////////////////////
        ///  Cached Fields
        //////////////////////////////////////////////////////
        private Quaternion currentRot;
        private Vector3 closestHitpoint;
        private static Vector3 eyesPosition;
        private static RaycastHit hitinfo;
        private object closestEnt;
        //////////////////////////////////////////////////////
        ///  class WaypointInfo
        ///  Waypoint information, position & speed
        ///  public => will be saved in the data file
        ///  non public => won't be saved in the data file
        //////////////////////////////////////////////////////
        class WaypointInfo {
            public string x;
            public string y;
            public string z;
            public string s;
            Vector3 position;
            float speed;
            public WaypointInfo(Vector3 position, float speed) {
                x = position.x.ToString();
                y = position.y.ToString();
                z = position.z.ToString();
                s = speed.ToString();
                this.position = position;
                this.speed = speed;
            }
            public Vector3 GetPosition() {
                if (position == Vector3.zero) position = new Vector3(float.Parse(x), float.Parse(y), float.Parse(z));
                return position;
            }
            public float GetSpeed() {
                speed = Convert.ToSingle(s);
                return speed;
            }
        }
        //////////////////////////////////////////////////////
        ///  class SpawnInfo
        ///  Spawn information, position & rotation
        ///  public => will be saved in the data file
        ///  non public => won't be saved in the data file
        //////////////////////////////////////////////////////
        class SpawnInfo {
            public string x;
            public string y;
            public string z;
            public string rx;
            public string ry;
            public string rz;
            public string rw;
            Vector3 position;
            Quaternion rotation;
            public SpawnInfo(Vector3 position, Quaternion rotation) {
                x = position.x.ToString();
                y = position.y.ToString();
                z = position.z.ToString();
                rx = rotation.x.ToString();
                ry = rotation.y.ToString();
                rz = rotation.z.ToString();
                rw = rotation.w.ToString();
                this.position = position;
                this.rotation = rotation;
            }
            public Vector3 GetPosition() {
                if (position == Vector3.zero) position = new Vector3(float.Parse(x), float.Parse(y), float.Parse(z));
                return position;
            }
            public Quaternion GetRotation() {
                if (rotation.x == 0f) rotation = new Quaternion(Convert.ToSingle(rx), Convert.ToSingle(ry), Convert.ToSingle(rz), Convert.ToSingle(rw));
                return rotation;
            }
            public string String() {
                return string.Format("Pos({0},{1},{2}) - Rot({3},{4},{5},{6})", x, y, z, rx, ry, rz, rw);
            }
            public string ShortString() {
                return string.Format("Pos({0},{1},{2})", Math.Ceiling(position.x).ToString(), Math.Ceiling(position.y).ToString(), Math.Ceiling(position.z).ToString());
            }
            public SpawnInfo Clone() {
                var clone = (SpawnInfo)MemberwiseClone();
                return clone;
            }
        }
        //////////////////////////////////////////////////////
        ///  class HumanTrigger
        /// MonoBehaviour: managed by UnityEngine
        ///  This takes care of all collisions and area management of humanNPCs
        //////////////////////////////////////////////////////
        class HumanTrigger : MonoBehaviour {
            HumanPlayer npc;
            Collider[] colliderArray;
            List<BasePlayer> collidePlayers = new List<BasePlayer>();
            List<BasePlayer> triggerPlayers = new List<BasePlayer>();
            List<BasePlayer> removePlayers = new List<BasePlayer>();
            BasePlayer cachedPlayer;
            public float collisionRadius;
            void Awake() {
                npc = GetComponent<HumanPlayer>();
                collisionRadius = float.Parse(npc.info.collisionRadius);
                InvokeRepeating("UpdateTriggerArea", 2, 2);
            }
            void UpdateTriggerArea() {
                colliderArray = Physics.OverlapSphere(npc.player.transform.position, collisionRadius, playerLayer);
                foreach (Collider collider in colliderArray) {
                    cachedPlayer = collider.GetComponentInParent<BasePlayer>();
                    if (cachedPlayer == null) continue;
                    if (cachedPlayer == npc.player) continue;
                    collidePlayers.Add(cachedPlayer);
                    if (!triggerPlayers.Contains(cachedPlayer)) OnEnterCollision(cachedPlayer);
                }
                foreach (BasePlayer player in triggerPlayers) {
                    if (!collidePlayers.Contains(player)) removePlayers.Add(player);
                }
                foreach (BasePlayer player in removePlayers) {
                    OnLeaveCollision(player);
                }
                collidePlayers.Clear();
                removePlayers.Clear();
            }
            void OnEnterCollision(BasePlayer targetplayer) {
                triggerPlayers.Add(targetplayer);
                Interface.CallHook("OnEnterNPC", npc.player, targetplayer);
            }
            void OnLeaveCollision(BasePlayer targetplayer) {
                triggerPlayers.Remove(targetplayer);
                Interface.CallHook("OnLeaveNPC", npc.player, targetplayer);
            }
        }
        //////////////////////////////////////////////////////
        ///  class HumanLocomotion
        /// MonoBehaviour: managed by UnityEngine
        ///  This takes care of all movements and attacks of HumanNPCs
        //////////////////////////////////////////////////////
        class HumanLocomotion : MonoBehaviour {
            public HumanPlayer npc;
            public Vector3 StartPos = new Vector3(0f, 0f, 0f);
            public Vector3 EndPos = new Vector3(0f, 0f, 0f);
            public Vector3 LastPos = new Vector3(0f, 0f, 0f);
            public Vector3 nextPos = new Vector3(0f, 0f, 0f);
            public float waypointDone = 0f;
            public float secondsTaken = 0f;
            public float secondsToTake = 0f;
            public List<WaypointInfo> cachedWaypoints;
            public int currentWaypoint = -1;
            public float c_attackDistance = 0f;
            public float attackDistance = 0f;
            public float maxDistance = 0f;
            public float damageDistance = 0f;
            public float damageInterval = 0f;
            public float damageAmount = 0f;
            public float lastHit = 0f;
            public float speed = 4f;
            public int noPath = 0;
            public bool shouldMove = true;
            public BaseEntity attackEntity = null;
            public List<Vector3> pathFinding;
            public List<Vector3> temppathFinding;
            void Awake() {
                npc = GetComponent<HumanPlayer>();
                var cwaypoints = Interface.CallHook("GetWaypointsList", npc.info.waypoint);
                if (cwaypoints == null) cachedWaypoints = null;
                else {
                    cachedWaypoints = new List<WaypointInfo>();
                    foreach (var cwaypoint in (List<object>)cwaypoints) {
                        foreach (KeyValuePair<Vector3, float> pair in (Dictionary<Vector3, float>)cwaypoint) {
                            cachedWaypoints.Add(new WaypointInfo(pair.Key, pair.Value));
                        }
                    }
                }
                attackDistance = float.Parse(npc.info.attackDistance);
                maxDistance = float.Parse(npc.info.maxDistance);
                damageDistance = float.Parse(npc.info.damageDistance);
                damageInterval = float.Parse(npc.info.damageInterval);
                damageAmount = float.Parse(npc.info.damageAmount);
                speed = float.Parse(npc.info.speed);
            }
            void FixedUpdate() {
                TryToMove();
            }
            void TryToMove() {
                if (npc.player.IsWounded()) return;
                if (attackEntity != null) MoveOrAttack(attackEntity);
                else if (secondsTaken == 0f) GetNextPath();
                if (StartPos != EndPos) Execute_Move();
                if (waypointDone >= 1f) secondsTaken = 0f;
            }
            void Execute_Move() {
                if (!shouldMove) return;
                secondsTaken += Time.deltaTime;
                waypointDone = Mathf.InverseLerp(0f, secondsToTake, secondsTaken);
                nextPos = Vector3.Lerp(StartPos, EndPos, waypointDone);
                npc.player.transform.position = nextPos;
                npc.player.TransformChanged();
            }
            void GetNextPath() {
                if (npc == null) npc = GetComponent<HumanPlayer>();
                LastPos = Vector3.zero;
                shouldMove = true;
                if (cachedWaypoints == null) {
                    shouldMove = false;
                    return;
                }
                Interface.CallHook("OnNPCPosition", npc.player, npc.player.transform.position);
                if (currentWaypoint + 1 >= cachedWaypoints.Count) currentWaypoint = -1;
                currentWaypoint++;
                SetMovementPoint(npc.player.transform.position, cachedWaypoints[currentWaypoint].GetPosition(), cachedWaypoints[currentWaypoint].GetSpeed());
                if (npc.player.transform.position == cachedWaypoints[currentWaypoint].GetPosition()) {
                    npc.DisableMove();
                    npc.Invoke("AllowMove", cachedWaypoints[currentWaypoint].GetSpeed());
                    return;
                }
            }
            public void SetMovementPoint(Vector3 startpos, Vector3 endpos, float s) {
                StartPos = startpos;
                EndPos = endpos;
                if (StartPos != EndPos) secondsToTake = Vector3.Distance(EndPos, StartPos) / s;
                LookTowards(npc.player, EndPos);
                secondsTaken = 0f;
                waypointDone = 0f;
            }
            void MoveOrAttack(BaseEntity entity) {
                c_attackDistance = Vector3.Distance(entity.transform.position, npc.player.transform.position);
                shouldMove = false;
                if (((BaseCombatEntity)entity).IsAlive() && c_attackDistance < attackDistance && Vector3.Distance(LastPos, npc.player.transform.position) < maxDistance && noPath < 5) {
                    if (waypointDone >= 1f) {
                        if (pathFinding != null && pathFinding.Count > 0) pathFinding.RemoveAt(0);
                        waypointDone = 0f;
                    }
                    if (c_attackDistance < damageDistance && CanSee(npc.player, entity)) {
                        if (Time.realtimeSinceStartup > lastHit + damageInterval) DoHit(this, (BaseCombatEntity)entity);
                        return;
                    }
                    if (pathFinding == null || pathFinding.Count < 1) return;
                    shouldMove = true;
                    if (waypointDone == 0f) SetMovementPoint(npc.player.transform.position, pathFinding[0], speed * 2);
                }
                else npc.EndAttackingEntity();
            }
            public void PathFinding() {
                if (IsInvoking("PathFinding")) {
                    CancelInvoke("PathFinding");
                }
                temppathFinding = (List<Vector3>)Interface.CallHook("FindBestPath", npc.player.transform.position, attackEntity.transform.position);
                if (temppathFinding == null) {
                    if (pathFinding == null || pathFinding.Count == 0) noPath++;
                    else noPath = 0;
                    Invoke("PathFinding", 2);
                }
                else {
                    noPath = 0;
                    pathFinding = temppathFinding;
                    waypointDone = 0f;
                    Invoke("PathFinding", pathFinding.Count / speed);
                }
            }
            public void GetBackToLastPos() {
                if (npc.player.transform.position != LastPos) {
                    SetMovementPoint(npc.player.transform.position, LastPos, 7f);
                    secondsTaken = 0.01f;
                }
            }
            public void Enable() {
                this.enabled = true;
            }
            public void Disable() {
                this.enabled = false;
            }
        }
        //////////////////////////////////////////////////////
        ///  class HumanPlayer : MonoBehaviour
        ///  MonoBehaviour: managed by UnityEngine
        /// Takes care of all the sub categories of the HumanNPCs
        //////////////////////////////////////////////////////
        class HumanPlayer : MonoBehaviour {
            public HumanNPCInfo info;
            public HumanLocomotion locomotion;
            public HumanTrigger trigger;
            public BasePlayer player;
            public bool hostile;
            public bool invulnerability;
            public bool stopandtalk;
            public float stopandtalkSeconds;
            public float lastMessage;
            public List<TuneNote> tunetoplay = new List<TuneNote>();
            public int currentnote = 0;
            Effect effectP = new Effect("assets/bundled/prefabs/fx/gestures/guitarpluck.prefab", new Vector3(0, 0, 0), Vector3.forward);
            Effect effectS = new Effect("assets/bundled/prefabs/fx/gestures/guitarpluck.prefab", new Vector3(0, 0, 0), Vector3.forward);
            void Awake() {
                player = GetComponent<BasePlayer>();
            }
            public void SetInfo(HumanNPCInfo info) {
                this.info = info;
                if (info == null) return;
                player.userID = ulong.Parse(info.userid);
                displayname.SetValue(player, info.displayName);
                invulnerability = bool.Parse(info.invulnerability);
                stopandtalk = bool.Parse(info.stopandtalk);
                hostile = bool.Parse(info.hostile);
                stopandtalkSeconds = float.Parse(info.stopandtalkSeconds);
                player.InitializeHealth(float.Parse(info.health), float.Parse(info.health));
                player.syncPosition = true;
                player.transform.position = info.spawnInfo.GetPosition();
                lastPositionValue.SetValue(player, player.transform.position);
                player.TransformChanged();
                SetViewAngle(player, info.spawnInfo.GetRotation());
                player.EndSleeping();
                player.UpdateNetworkGroup();
                Interface.CallHook("OnNPCRespawn", player);
                if (info.minstrel != null) PlayTune();
                locomotion = player.gameObject.AddComponent<HumanLocomotion>();
                trigger = player.gameObject.AddComponent<HumanTrigger>();
                enabled = true;
                lastMessage = Time.realtimeSinceStartup;
            }
            public void AllowMove() {
                locomotion.Enable();
            }
            public void DisableMove() {
                locomotion.Disable();
            }
            public void TemporaryDisableMove(float thetime = -1f) {
                if (thetime == -1f) thetime = stopandtalkSeconds;
                DisableMove();
                if (IsInvoking("AllowMove")) CancelInvoke("AllowMove");
                Invoke("AllowMove", thetime);
            }
            public void EndAttackingEntity() {
                if (locomotion.IsInvoking("PathFinding")) locomotion.CancelInvoke("PathFinding");
                locomotion.noPath = 0;
                locomotion.shouldMove = true;
                Interface.CallHook("OnNPCStopTarget", player, locomotion.attackEntity);
                locomotion.attackEntity = null;
                player.health = float.Parse(info.health);
                locomotion.GetBackToLastPos();
            }
            public void PlayTune() {
                if (info.minstrel == null) return;
                if (tunetoplay.Count == 0) GetTune(this);
                if (tunetoplay.Count == 0) return;
                Invoke("PlayNote", 1);
            }
            public void PlayNote() {
                if (tunetoplay[currentnote].Pluck) {
                    effectP.worldPos = player.transform.position;
                    effectP.origin = player.transform.position;
                    effectP.scale = tunetoplay[currentnote].NoteScale;
                    EffectNetwork.Send(effectP);
                }
                else {
                    effectS.worldPos = player.transform.position;
                    effectS.origin = player.transform.position;
                    effectS.scale = tunetoplay[currentnote].NoteScale;
                    EffectNetwork.Send(effectS);
                }
                currentnote++;
                if (currentnote >= tunetoplay.Count) currentnote = 0;
                Invoke("PlayNote", tunetoplay[currentnote].Delay);
            }
            public void StartAttackingEntity(BaseEntity entity) {
                if (Interface.CallHook("OnNPCStartTarget", player, entity) == null) {
                    locomotion.attackEntity = entity;
                    locomotion.pathFinding = null;
                    locomotion.temppathFinding = null;
                    if (locomotion.LastPos == Vector3.zero) locomotion.LastPos = player.transform.position;
                    if (IsInvoking("AllowMove")) {
                        CancelInvoke("AllowMove");
                        AllowMove();
                    }
                    locomotion.Invoke("PathFinding", 0);
                }
            }
            void OnDestroy() {
                GameObject.Destroy(locomotion);
                GameObject.Destroy(trigger);
            }
        }
        //////////////////////////////////////////////////////
        ///  class HumanNPCInfo
        ///  NPC information that will be saved inside the datafile
        ///  public => will be saved in the data file
        ///  non public => won't be saved in the data file
        //////////////////////////////////////////////////////
        class HumanNPCInfo {
            public string userid;
            public string displayName;
            public string invulnerability;
            public string health;
            public string respawn;
            public string respawnSeconds;
            public SpawnInfo spawnInfo;
            public string waypoint;
            public string collisionRadius;
            public string spawnkit;
            public string damageAmount;
            public string damageDistance;
            public string damageInterval;
            public string attackDistance;
            public string maxDistance;
            public string minstrel;
            public string hostile;
            public string speed;
            public string stopandtalk;
            public string stopandtalkSeconds;
            public string enable;
            public string lootable;
            public List<string> message_hello;
            public List<string> message_bye;
            public List<string> message_use;
            public List<string> message_hurt;
            public List<string> message_kill;
            public HumanNPCInfo(ulong userid, Vector3 position, Quaternion rotation) {
                this.userid = userid.ToString();
                displayName = "NPC";
                invulnerability = "true";
                health = "50";
                hostile = "false";
                respawn = "true";
                respawnSeconds = "60";
                spawnInfo = new SpawnInfo(position, rotation);
                collisionRadius = "10";
                damageDistance = "3";
                damageAmount = "10";
                attackDistance = "100";
                maxDistance = "200";
                speed = "3";
                stopandtalk = "true";
                stopandtalkSeconds = "3";
                enable = "true";
                lootable = "true";
                damageInterval = "2";
            }
            public HumanNPCInfo Clone(ulong userid) {
                var clone = new HumanNPCInfo(userid, this.spawnInfo.GetPosition(), this.spawnInfo.GetRotation());
                clone.userid = userid.ToString();
                clone.displayName = this.displayName;
                clone.invulnerability = this.invulnerability;
                clone.health = this.health;
                clone.respawn = this.respawn;
                clone.respawnSeconds = this.respawnSeconds;
                clone.waypoint = this.waypoint;
                clone.collisionRadius = this.collisionRadius;
                clone.spawnkit = this.spawnkit;
                clone.damageAmount = this.damageAmount;
                clone.damageDistance = this.damageDistance;
                clone.attackDistance = this.attackDistance;
                clone.maxDistance = this.maxDistance;
                clone.hostile = this.hostile;
                clone.speed = this.speed;
                clone.stopandtalk = this.stopandtalk;
                clone.stopandtalkSeconds = this.stopandtalkSeconds;
                clone.lootable = this.lootable;
                clone.damageInterval = this.damageInterval;
                clone.minstrel = this.minstrel;
                clone.message_hello = this.message_hello;
                clone.message_bye = this.message_bye;
                clone.message_use = this.message_use;
                clone.message_hurt = this.message_hurt;
                clone.message_kill = this.message_kill;
                return clone;
            }
        }
        class NPCEditor : MonoBehaviour {
            public BasePlayer player;
            public HumanPlayer targetNPC;
            void Awake() {
                player = GetComponent<BasePlayer>();
            }
        }
        class StoredData {
            public HashSet<HumanNPCInfo> HumanNPCs = new HashSet<HumanNPCInfo>();
            public StoredData() {
            }
        }
        private static Dictionary<string, object> weaponToFX = DefaultWeaponToFx();
        void LoadDefaultConfig() {
        }
        private void CheckCfg<T>(string Key, ref T var) {
            if (Config[Key] is T) var = (T)Config[Key];
            else Config[Key] = var;
        }
        void Init() {
            CheckCfg<Dictionary<string, object>>("Weapon To FX", ref weaponToFX);
            SaveConfig();
        }
        static Dictionary<string, object> DefaultWeaponToFx() {
            var defaultfx = new Dictionary<string, object>();
            defaultfx.Add("shotgun_waterpipe", "assets/blunded/prefabs/fx/weapons/vm_waterpipe_shotgun/attack.prefab");
            defaultfx.Add("shotgun_pump", "assets/blunded/prefabs/fx/weapons/vm_waterpipe_shotgun/attack.prefab");
            defaultfx.Add("smg_thompson", "assets/blunded/prefabs/fx/weapons/vm_thompson/attack.prefab");
            defaultfx.Add("rifle_ak", "assets/blunded/prefabs/fx/weapons/vm_ak47u/attack.prefab");
            defaultfx.Add("rifle_bolt", "assets/blunded/prefabs/fx/weapons/vm_bolt_rifle/attack.prefab");
            defaultfx.Add("pistol_revolver", "assets/blunded/prefabs/fx/weapons/vm_revolver/attack.prefab");
            defaultfx.Add("pistol_eoka", "assets/blunded/prefabs/fx/weapons/vm_eoka_pistol/attack.prefab");
            defaultfx.Add("unarmed", "assets/blunded/prefabs/fx/weapons/vm_unarmed/uppercut.prefab");
            defaultfx.Add("torch", "assets/blunded/prefabs/fx/weapons/vm_torch/attack.prefab");
            return defaultfx;
        }
        static float GetGroundY(Vector3 position) {
            position = position + jumpPosition;
            if (Physics.Raycast(position, Vector3Down, out hitinfo, 1.5f, groundLayer)) {
                return hitinfo.point.y;
            }
            return position.y - 1.5f;
        }
        void Loaded() {
            LoadData();
            serverinput = typeof(BasePlayer).GetField("serverInput", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic));
            viewangles = typeof(BasePlayer).GetField("viewAngles", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic));
            displayname = typeof(BasePlayer).GetField("_displayName", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic));
            lastPositionValue = typeof(BasePlayer).GetField("lastPositionValue", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic));
            TimersList = new List<Oxide.Plugins.Timer>();
            eyesPosition = new Vector3(0f, 0.5f, 0f);
            jumpPosition = new Vector3(0f, 1f, 0f);
            Vector3Down = new Vector3(0f, -1f, 0f);
            Vector3Forward = new Vector3(0f, 0f, 1f);
            foreach(BasePlayer player in BasePlayer.activePlayerList) {
                Network.SendInfo sendInfo = new Network.SendInfo(player.net.group) {
                    method = Network.SendMethod.Unreliable
                }
                ;
                player.ClientRPCEx(sendInfo, null, "SignalFromServer", new object[] {
                    (int)BaseEntity.Signal.Attack, string.Empty
                }
                );
            }
        }
        void Unloaded() {
            SaveData();
        }
        void Unload() {
            var objects = GameObject.FindObjectsOfType(typeof(HumanPlayer));
            if (objects != null) foreach (var gameObj in objects) GameObject.Destroy(gameObj);
            objects = GameObject.FindObjectsOfType(typeof(NPCEditor));
            if (objects != null) foreach (var gameObj in objects) GameObject.Destroy(gameObj);
            foreach (Oxide.Plugins.Timer timers in TimersList) timers.Destroy();
            TimersList.Clear();
        }
        void SaveData() {
            Interface.GetMod().DataFileSystem.WriteObject("HumanNPC", storedData);
        }
        void LoadData() {
            humannpcs.Clear();
            try {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("HumanNPC");
            }
            catch {
                storedData = new StoredData();
            }
            foreach (var thenpc in storedData.HumanNPCs) humannpcs[thenpc.userid] = thenpc;
        }
        public class TuneNote {
            public float NoteScale, Delay;
            public bool Pluck;
            public TuneNote() {
            }
        }
        static void GetTune(HumanPlayer hp) {
            var tune = Interface.CallHook("getTune", hp.info.minstrel);
            if (tune == null) {
                hp.CancelInvoke("PlayTune");
                return;
            }
            var newtune = new List<TuneNote>();
            foreach (var note in (List<object>)tune) {
                var newnote = new TuneNote();
                foreach (KeyValuePair<string, object> pair in (Dictionary<string, object>)note) {
                    if (pair.Key == "NoteScale") newnote.NoteScale = Convert.ToSingle(pair.Value);
                    if (pair.Key == "Delay") newnote.Delay = Convert.ToSingle(pair.Value);
                    if (pair.Key == "Pluck") newnote.Pluck = Convert.ToBoolean(pair.Value);
                }
                newtune.Add(newnote);
            }
            hp.tunetoplay = newtune;
        }
        //////////////////////////////////////////////////////
        ///  Oxide Hooks
        //////////////////////////////////////////////////////
        //////////////////////////////////////////////////////
        ///  OnServerInitialized()
        ///  called when the server is done being initialized
        //////////////////////////////////////////////////////
        void OnServerInitialized() {
            playerLayer = UnityEngine.LayerMask.GetMask(new string[] {
                "Player (Server)"
            }
            );
            groundLayer = UnityEngine.LayerMask.GetMask(new string[] {
                "Construction", "Terrain", "World"
            }
            );
            blockshootLayer = UnityEngine.LayerMask.GetMask(new string[] {
                "Construction", "Terrain", "World"
            }
            );
            RefreshAllNPC();
            emptyDamage = new DamageTypeList();
        }
        //////////////////////////////////////////////////////
        ///  OnServerSave()
        ///  called when a server performs a save
        //////////////////////////////////////////////////////
        void OnServerSave() {
            SaveData();
        }
        //////////////////////////////////////////////////////
        /// OnPlayerInput(BasePlayer player, InputState input)
        /// Called when a plugin presses a button
        //////////////////////////////////////////////////////
        void OnPlayerInput(BasePlayer player, InputState input) {
            if (input.WasJustPressed(BUTTON.USE)) {
                TryGetPlayerView(player, out currentRot);
                if (Physics.Raycast(new Ray(player.transform.position + eyesPosition, currentRot * Vector3.forward), out hitinfo, 5f, playerLayer)) if (hitinfo.collider.GetComponentInParent<HumanPlayer>() != null) Interface.CallHook("OnUseNPC", hitinfo.collider.GetComponentInParent<BasePlayer>(), player);
            }
        }
        //////////////////////////////////////////////////////
        /// OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitinfo)
        /// Called when an entity gets attacked (can be anything, building, animal, player..)
        //////////////////////////////////////////////////////
        void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitinfo) {
            if (entity.GetComponent<HumanPlayer>() != null) {
                Interface.CallHook("OnHitNPC", entity.GetComponent<BaseCombatEntity>(), hitinfo);
                if (entity.GetComponent<HumanPlayer>().invulnerability) {
                    hitinfo.damageTypes = emptyDamage;
                    hitinfo.HitMaterial = 0;
                }
            }
        }
        //////////////////////////////////////////////////////
        /// OnEntityDeath(BaseEntity entity, HitInfo hitinfo)
        /// Called when an entity gets killed (can be anything, building, animal, player..)
        //////////////////////////////////////////////////////
        void OnEntityDeath(BaseEntity entity, HitInfo hitinfo) {
            if (entity.GetComponent<HumanPlayer>() != null) {
                Interface.CallHook("OnKillNPC", entity.GetComponent<BasePlayer>(), hitinfo);
                if (entity.GetComponent<HumanPlayer>().info.respawn == "true") {
                    var userid = entity.GetComponent<HumanPlayer>().info.userid;
                    TimersList.Add(timer.Once(float.Parse(entity.GetComponent<HumanPlayer>().info.respawnSeconds), () => SpawnOrRefresh(userid, false)));
                }
            }
        }
        void OnPlayerLoot(PlayerLoot loot, BaseEntity target) {
            var userid = GetIDFromLoot(target);
            if (userid != 0L && humannpcs[userid.ToString()] != null) {
                Interface.CallHook("OnLootNPC", loot, target, userid.ToString());
            }
        }
        //////////////////////////////////////////////////////
        /// End of Oxide Hooks
        //////////////////////////////////////////////////////
        ulong GetIDFromLoot(BaseEntity target) {
            if (target is PlayerCorpse) return (target as PlayerCorpse).playerSteamID;
            if (target is BasePlayer) return (target as BasePlayer).userID;
            return 0L;
        }
        HumanPlayer FindHumanPlayerByID(ulong userid) {
            var allBasePlayer = UnityEngine.Resources.FindObjectsOfTypeAll<HumanPlayer>();
            foreach (HumanPlayer humanplayer in allBasePlayer) {
                if (humanplayer.player.userID == userid) return humanplayer;
            }
            return null;
        }
        BasePlayer FindPlayerByID(ulong userid) {
            var allBasePlayer = UnityEngine.Resources.FindObjectsOfTypeAll<BasePlayer>();
            foreach (BasePlayer player in allBasePlayer) {
                if (player.userID == userid) return player;
            }
            return null;
        }
        static void DoHit(HumanLocomotion loc, BaseCombatEntity target) {
            loc.lastHit = Time.realtimeSinceStartup;
            HitInfo info = new HitInfo(loc.npc.player, DamageType.Stab, loc.damageAmount, target.transform.position) {
                PointStart = loc.npc.player.transform.position, PointEnd = target.transform.position
            }
            ;
            target.SendMessage("OnAttacked", info, SendMessageOptions.DontRequireReceiver);
            ForceSignalBroadcast(loc.npc.GetComponent<BasePlayer>());
            var activeitem = loc.npc.player.inventory.containerBelt.GetSlot(0);
            //PlayAttack(activeitem, loc.npc.player.transform.position, (target.transform.position - loc.npc.player.transform.position));
        }
        static void ForceSignalBroadcast(BasePlayer entity) {
            entity.SignalBroadcast(BaseEntity.Signal.Gesture, "pickup_item", null);
            //Network.SendInfo sendInfo = new Network.SendInfo(entity.net.group) { method = Network.SendMethod.Unreliable };
            //entity.ClientRPCEx(sendInfo, null, "SignalFromServer", new object[] { (int)BaseEntity.Signal.Gesture, "item_drop" });
        }
        /*
        void OnClientRPCEx(BaseEntity entity, Network.SendInfo sendinfo, Network.Connection source, string funcname, object[] args)
        {
            Debug.Log(string.Format("{0} : {1} - {2}", entity.ToString(), source == null ? "null" : source.ToString(), funcname));
            foreach(object arg in args)
            {
                Debug.Log(arg == string.Empty ? "EMPTY":arg.ToString());
            }
        }*/
        static void PlayAttack(Item attackitem, Vector3 source, Vector3 dir) {
            if (attackitem != null) {
                if (weaponToFX.ContainsKey(attackitem.info.shortname)) {
                    Effect effect = new Effect();
                    effect.Init(Effect.Type.Projectile, source, dir.normalized, null);
                    effect.scale = dir.magnitude;
                    effect.pooledString = (string)weaponToFX[attackitem.info.shortname];
                    effect.number = 0;
                    EffectNetwork.Send(effect);
                }
            }
        }
        static void SetViewAngle(BasePlayer player, Quaternion ViewAngles) {
            viewangles.SetValue(player, ViewAngles);
            player.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
        }
        void RefreshAllNPC() {
            List<string> npcspawned = new List<string>();
            foreach (KeyValuePair<string, HumanNPCInfo> pair in humannpcs) {
                if (pair.Value.enable == "true") {
                    npcspawned.Add(pair.Key);
                    SpawnOrRefresh(pair.Key, false);
                }
            }
            foreach (BasePlayer player in UnityEngine.Resources.FindObjectsOfTypeAll<BasePlayer>()) {
                if (player.userID < 76560000000000000L && player.userID > 0L) if (!npcspawned.Contains(player.userID.ToString())) {
                    player.KillMessage();
                    Puts(string.Format("Detected a HumanNPC with no data or disabled, deleting him: {0} {1}", player.userID.ToString(), player.displayName));
                }
            }
        }
        void SpawnOrRefresh(string userid, bool isediting ) {
            BasePlayer findplayer = FindPlayerByID(Convert.ToUInt64(userid));
            if (findplayer == null) SpawnNPC(userid, false);
            else RefreshNPC(findplayer, false);
        }
        void SpawnNPC(string userid, bool isediting) {
            if (humannpcs[userid] == null) return;
            if (!isediting && humannpcs[userid].enable == "false") return;
            var newplayer = GameManager.server.CreateEntity("assets/bundled/prefabs/player/player.prefab", humannpcs[userid].spawnInfo.GetPosition(), humannpcs[userid].spawnInfo.GetRotation()).ToPlayer();
            newplayer.userID = Convert.ToUInt64(userid);
            var humanplayer = newplayer.gameObject.AddComponent<HumanPlayer>();
            displayname.SetValue(newplayer, (humannpcs[userid]).displayName);
            newplayer.Spawn(true);
            humanplayer.SetInfo(humannpcs[userid]);
            Puts("Spawned NPC: " + userid);
        }
        void RefreshNPC(BasePlayer player, bool isediting) {
            if (player.GetComponent<HumanPlayer>() != null) GameObject.Destroy(player.GetComponent<HumanPlayer>());
            var humanplayer = player.gameObject.AddComponent<HumanPlayer>();
            humanplayer.SetInfo(humannpcs[player.userID.ToString()]);
            if (humannpcs[player.userID.ToString()].enable == "false" && !isediting) {
                player.KillMessage();
                Puts("NPC was refreshed and Killed because he is disabled: " + player.userID.ToString());
                return;
            }
            Puts("Refreshed NPC: " + player.userID.ToString());
        }
        bool hasAccess(BasePlayer player) {
            if (player.net.connection.authLevel < 1) {
                SendReply(player, "You don't have access to this command");
                return false;
            }
            return true;
        }
        bool hasNoArguments(BasePlayer player, string[] args, int Number) {
            if (args.Length < Number) {
                SendReply(player, "Not enough Arguments");
                return true;
            }
            return false;
        }
        bool TryGetPlayerView(BasePlayer player, out Quaternion viewAngle) {
            viewAngle = new Quaternion(0f, 0f, 0f, 0f);
            var input = serverinput.GetValue(player) as InputState;
            if (input == null) return false;
            if (input.current == null) return false;
            viewAngle = Quaternion.Euler(input.current.aimAngles);
            return true;
        }
        bool TryGetClosestRayPoint(Vector3 sourcePos, Quaternion sourceDir, out object closestEnt, out Vector3 closestHitpoint) {
            Vector3 sourceEye = sourcePos + new Vector3(0f, 1.5f, 0f);
            UnityEngine.Ray ray = new UnityEngine.Ray(sourceEye, sourceDir * Vector3.forward);
            var hits = UnityEngine.Physics.RaycastAll(ray);
            float closestdist = 999999f;
            closestHitpoint = sourcePos;
            closestEnt = false;
            foreach (var hit in hits) if (hit.collider.GetComponentInParent<TriggerBase>() == null) if (hit.distance < closestdist) {
                closestdist = hit.distance;
                closestEnt = hit.collider;
                closestHitpoint = hit.point;
            }
            if (closestEnt is bool) return false;
            return true;
        }
        static bool CanSee(BasePlayer source, BaseEntity target) {
            if (UnityEngine.Physics.Linecast(source.transform.position + jumpPosition, target.transform.position + jumpPosition, blockshootLayer)) return false;
            return true;
        }
        string GetRandomMessage(List<string> messagelist) {
            return messagelist[GetRandom(0, messagelist.Count)];
        }
        int GetRandom(int min, int max) {
            return UnityEngine.Random.Range(min, max);
        }
        List<string> ListFromArgs(string[] args, int from) {
            var newlist = new List<string>();
            for (var i = from; i < args.Length; i++) {
                newlist.Add(args[i]);
            }
            return newlist;
        }
        public static void LookTowards(BasePlayer player, Vector3 pos) {
            if (pos != player.transform.position) SetViewAngle(player, Quaternion.LookRotation(pos - player.transform.position));
        }
        //////////////////////////////////////////////////////////////////////////////
        /// Chat Commands
        //////////////////////////////////////////////////////////////////////////////
        [ChatCommand("npc_add")]
        void cmdChatNPCAdd(BasePlayer player, string command, string[] args) {
            if (!hasAccess(player)) return;
            if (player.GetComponent<NPCEditor>() != null) {
                SendReply(player, "NPC Editor: Already editing an NPC, say /npc_end first");
                return;
            }
            if (!TryGetPlayerView(player, out currentRot)) return;
            var newplayer = GameManager.server.CreateEntity("assets/bundled/prefabs/player/player.prefab", player.transform.position, currentRot).ToPlayer();
            displayname.SetValue(newplayer, "NPC");
            newplayer.Spawn(true);
            var humannpcinfo = new HumanNPCInfo(newplayer.userID, player.transform.position, currentRot);
            var humanplayer = newplayer.gameObject.AddComponent<HumanPlayer>();
            if (args.Length > 0) {
                if (humannpcs[args[0]] != null) {
                    humannpcinfo = humannpcs[args[0]].Clone(newplayer.userID);
                    humannpcinfo.userid = newplayer.userID.ToString();
                    humannpcinfo.spawnInfo = new SpawnInfo(player.transform.position, currentRot);
                    humanplayer.SetInfo(humannpcinfo);
                }
            }
            else {
                humanplayer.SetInfo(humannpcinfo);
            }
            var npceditor = player.gameObject.AddComponent<NPCEditor>();
            npceditor.targetNPC = humanplayer;
            if (humannpcs[newplayer.userID.ToString()] != null) storedData.HumanNPCs.Remove(humannpcs[newplayer.userID.ToString()]);
            humannpcs[newplayer.userID.ToString()] = humannpcinfo;
            storedData.HumanNPCs.Add(humannpcs[newplayer.userID.ToString()]);
            SaveData();
        }
        [ChatCommand("npc_edit")]
        void cmdChatNPCEdit(BasePlayer player, string command, string[] args) {
            if (!hasAccess(player)) return;
            if (player.GetComponent<NPCEditor>() != null) {
                SendReply(player, "NPC Editor: Already editing an NPC, say /npc_end first");
                return;
            }
            HumanPlayer targetnpc;
            ulong userid;
            if (args.Length == 0) {
                if (!TryGetPlayerView(player, out currentRot)) return;
                if (!TryGetClosestRayPoint(player.transform.position, currentRot, out closestEnt, out closestHitpoint)) return;
                if (((Collider)closestEnt).GetComponentInParent<HumanPlayer>() == null) {
                    SendReply(player, "This is not an NPC");
                    return;
                }
                targetnpc = ((Collider)closestEnt).GetComponentInParent<HumanPlayer>();
            }
            else if (humannpcs[args[0]] != null) {
                if (!ulong.TryParse(args[0], out userid)) {
                    SendReply(player, "/npc_edit TARGETID");
                    return;
                }
                targetnpc = FindHumanPlayerByID(userid);
                if (targetnpc == null) {
                    SpawnNPC(args[0], true);
                }
                targetnpc = FindHumanPlayerByID(userid);
                if (targetnpc == null) {
                    SendReply(player, "Couldn't Spawn the NPC");
                    return;
                }
            }
            else {
                SendReply(player, "You are not looking at an NPC or this userid doesn't exist");
                return;
            }
            var npceditor = player.gameObject.AddComponent<NPCEditor>();
            npceditor.targetNPC = targetnpc;
            SendReply(player, string.Format("NPC Editor: Start Editing {0} - {1}", npceditor.targetNPC.player.displayName, npceditor.targetNPC.player.userID.ToString()));
        }
        [ChatCommand("npc_list")]
        void cmdChatNPCList(BasePlayer player, string command, string[] args) {
            if (!hasAccess(player)) return;
            if (humannpcs.Count == 0) {
                SendReply(player, "No NPC created yet");
                return;
            }
            SendReply(player, "==== NPCs ====");
            foreach (KeyValuePair<string, HumanNPCInfo> pair in humannpcs) SendReply(player, string.Format("{0} - {1} - {2} {3}", pair.Key, pair.Value.displayName, pair.Value.spawnInfo.ShortString(), pair.Value.enable == "true" ? "" : "- Disabled"));
        }
        [ChatCommand("npc")]
        void cmdChatNPC(BasePlayer player, string command, string[] args) {
            if (!hasAccess(player)) return;
            if (player.GetComponent<NPCEditor>() == null) {
                SendReply(player, "NPC Editor: You need to be editing an NPC, say /npc_add or /npc_edit");
                return;
            }
            var npceditor = player.GetComponent<NPCEditor>();
            if (args.Length == 0) {
                SendReply(player, "<color=#81F781>/npc attackdistance</color><color=#F2F5A9> XXX </color>=> <color=#D8D8D8>Distance between him and the target needed for the NPC to ignore the targ
// ... [Code preview truncated due to length. Full source in attached file] ...

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