C#:
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<ConfigData>();
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}"
: $"<color={configData.prefixColor}>{configData.prefix}</color>"
);
}
private void Print(BasePlayer player, string message)
{
Player.Message(
player,
message,
string.IsNullOrEmpty(configData.prefix)
? string.Empty
: $"<color={configData.prefixColor}>{configData.prefix}</color>",
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<string, string>
{
["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<string, string>
{
["NotFound"] = "在半径 {0} 米内找不到马!",
["ForbidByBuilding"] = "你半径 {0} 米内有建筑物,不能使用这个命令!",
["TpSuccess"] = "半径 {0} 米内的马已经被传送到你面前!"
},
this,
"zh-CN"
);
}
#endregion LanguageFile
}
}