using Oxide.Core.Plugins; using Rust; using UnityEngine; using Oxide.Core.Libraries.Covalence; using System.Collections.Generic; using System; using Newtonsoft.Json; namespace Oxide.Plugins { [Info("MyHorse", "Carl", "1.0.0")] class MyHorse : RustPlugin { #region Commands [ChatCommand("MyHorse")] private void CmdMyHorse(BasePlayer player, string command, string[] args) { string entityType = "horse"; if (HasBuildingWithinRadius(player, configData.radius)) { Print(player, Lang("ForbidByBuilding", player.UserIDString, configData.radius)); return; } BaseEntity closestEntity = FindClosestEntity(player, configData.radius, entityType); if (closestEntity == null) { Print(player, Lang("NotFound", player.UserIDString, configData.radius)); return; } Vector3 destination = player.transform.position + player.transform.forward * 3; closestEntity.transform.position = destination; Print(player, Lang("TpSuccess", player.UserIDString, configData.radius)); } #endregion #region Methods private BaseEntity FindClosestEntity(BasePlayer player, int range, string entityType) { BaseEntity closestEntity = null; float closestDistance = float.MaxValue; foreach (var entity in BaseNetworkable.serverEntities) { if ( entity is BaseEntity && ( ((BaseEntity)entity).PrefabName.ToLower().Contains(entityType) || ((BaseEntity)entity).ShortPrefabName == entityType ) ) { float distanceToPlayer = Vector3.Distance( player.transform.position, entity.transform.position ); if (distanceToPlayer < closestDistance) { closestDistance = distanceToPlayer; closestEntity = (BaseEntity)entity; } } } if (closestDistance < range) { return closestEntity; } else { return null; } } #endregion #region Helper bool HasBuildingWithinRadius(BasePlayer player, float radius) { Vector3 playerPosition = player.transform.position; Collider[] hitColliders = Physics.OverlapSphere(playerPosition, radius); foreach (Collider hitCollider in hitColliders) { string objname = hitCollider.gameObject.ToString(); if (objname.Contains("assets/prefabs/building core/")) { return true; } } return false; } #endregion #region ConfigurationFile private ConfigData configData; private class ConfigData { [JsonProperty(PropertyName = "Player-centered search radius")] public int radius = 10; [JsonProperty(PropertyName = "Chat Prefix")] public string prefix = "[MyHorse]:"; [JsonProperty(PropertyName = "Chat Prefix color")] public string prefixColor = "#00FFFF"; [JsonProperty(PropertyName = "Chat steamID icon")] public ulong steamIDIcon = 0; } protected override void LoadConfig() { base.LoadConfig(); try { configData = Config.ReadObject(); if (configData == null) { LoadDefaultConfig(); } } catch (Exception ex) { PrintError($"The configuration file is corrupted. \n{ex}"); LoadDefaultConfig(); } SaveConfig(); } protected override void LoadDefaultConfig() { PrintWarning("Creating a new configuration file"); configData = new ConfigData { }; } protected override void SaveConfig() { Config.WriteObject(configData); } #endregion ConfigurationFile #region LanguageFile private void PrintAll(string key, params object[] args) { foreach (var player in BasePlayer.activePlayerList) { Print(player, Lang(key, player.UserIDString, args)); } } private void Print(IPlayer iPlayer, string message) { iPlayer?.Reply( message, iPlayer.Id == "server_console" ? $"{configData.prefix}" : $"{configData.prefix}" ); } private void Print(BasePlayer player, string message) { Player.Message( player, message, string.IsNullOrEmpty(configData.prefix) ? string.Empty : $"{configData.prefix}", configData.steamIDIcon ); } private string Lang(string key, string id = null, params object[] args) { try { return string.Format(lang.GetMessage(key, this, id), args); } catch (Exception) { PrintError( $"Error in the language formatting of '{key}'. (userid: {id}. lang: {lang.GetLanguage(id)}. args: {string.Join(" ,", args)})" ); throw; } } protected override void LoadDefaultMessages() { lang.RegisterMessages( new Dictionary { ["NotFound"] = "No horses found within a radius of {0} meters!", ["ForbidByBuilding"] = "There's a building within a radius of {0} meters, you can't use this command!", ["TpSuccess"] = "The horse within a radius of {0} meters has been teleported in front of you!" }, this ); lang.RegisterMessages( new Dictionary { ["NotFound"] = "在半径 {0} 米内找不到马!", ["ForbidByBuilding"] = "你半径 {0} 米内有建筑物,不能使用这个命令!", ["TpSuccess"] = "半径 {0} 米内的马已经被传送到你面前!" }, this, "zh-CN" ); } #endregion LanguageFile } }