C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core.Plugins;
namespace Oxide.Plugins
{
[Info("Item Void", "Default", "1.0.3")]
[Description("Transport items to a chest via the void")]
class ItemVoid : RustPlugin
{
#region Declarations
private static ItemVoid instance;
private const string permissionName = "itemvoid.use";
private Dictionary<string, ItemContainer> voidList = new Dictionary<string, ItemContainer>();
//private static Dictionary<ulong, ItemVoid> _itemVoid = new Dictionary<ulong, ItemVoid>();
private bool pluginready = false;
[PluginReference] private Plugin Economics;
#endregion
#region Oxide Hooks
private void Init()
{
instance = this;
permission.RegisterPermission(permissionName, this);
cmd.AddChatCommand(_config.linkCommand, this, nameof(LinkChestCMD));
cmd.AddChatCommand(_config.voidCommand, this, nameof(CreateVoidTeleportCMD));
}
void OnServerInitialized()
{
if (_config.eco.economicsSupport && Economics == null)
{
PrintWarning("You have Economics enabled in the configuration but Economics plugin is missing.Please load Economics and reload this plugin.");
return;
}
if (_config.eco.economicsSupport && Economics.IsLoaded && Economics != null)
{
PrintWarning("Economic support loaded.");
pluginready = true;
return;
}
pluginready = true;
}
void Unload()
{
instance = null;
var gameObjects = UnityEngine.Object.FindObjectsOfType<TeleportVoid>();
if (gameObjects.Length > 0)
{
foreach (var objects in gameObjects)
{
objects.entity.Kill(BaseNetworkable.DestroyMode.None);
UnityEngine.Object.Destroy(objects);
}
}
}
void OnEntityKill(StorageContainer container)
{
BasePlayer owner = FindPlayer(container.OwnerID);
if (owner != null && voidList.ContainsKey(owner.UserIDString))
{
voidList.Remove(owner.UserIDString);
PrintToChat(owner, lang.GetMessage("Destroyed", this, owner.UserIDString));
return;
}
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoPermission"] = "You don't have permission to use this command.",
["Linked"] = "This chest has been linked",
["Invalid"] = "This is either not a box, or a box not owned by you!",
["NotFound"] = "No box was found, please look at a box.",
["Created"] = "You have created a void!",
["NotReady"] = "The plugin is not currently fully loaded.Please check your console for more information.",
["Destroyed"] = "Your linked chest has been destroyed!",
["NoVoid"] = "You currently do not have a linked chest.Use {0} to link one."
//["PaidTransport"] = "You have teleported {0}x {1} for a cost of ${2}",
//["NoMoney"] = "You lack the required money to transport {0}\nYou Require ${1}"
}, this);
}
#endregion
#region Chat commands
//[ChatCommand("void")]
private void CreateVoidTeleportCMD(BasePlayer player, string command, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, permissionName))
{
PrintToChat(player, lang.GetMessage("NoPermission", this, player.UserIDString));
return;
}
if (!voidList.ContainsKey(player.UserIDString))
{
PrintToChat(player, string.Format(lang.GetMessage("NoVoid", this, player.UserIDString), _config.linkCommand));
return;
}
/*if (!pluginready)
{
PrintToChat(player, lang.GetMessage("NotReady", this, player.UserIDString));
return;
}*/
CreateVoid(player);
PrintToChat(player, lang.GetMessage("Created", this, player.UserIDString));
}
//[ChatCommand("linkchest")]
private void LinkChestCMD(BasePlayer player, string command, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, permissionName))
{
PrintToChat(player, lang.GetMessage("NoPermission", this, player.UserIDString));
return;
}
/*if (!pluginready)
{
PrintToChat(player, lang.GetMessage("NotReady", this, player.UserIDString));
return;
}*/
RaycastHit RayHit;
var flag1 = Physics.Raycast(player.eyes.HeadRay(), out RayHit, 20f);
BaseEntity hitEntity = flag1 ? RayHit.GetEntity() : null;
if (hitEntity == null)
{
PrintToChat(player, lang.GetMessage("NotFound", this, player.UserIDString));
return;
}
StorageContainer storageContainer = hitEntity.GetComponent<StorageContainer>();
if (storageContainer == null || hitEntity.OwnerID != player.userID)
{
PrintToChat(player, lang.GetMessage("Invalid", this, player.UserIDString));
return;
}
ItemContainer container = storageContainer.inventory;
if (voidList.ContainsKey(player.UserIDString))
voidList[player.UserIDString] = container;
else
voidList.Add(player.UserIDString, container);
PrintToChat(player, lang.GetMessage("Linked", this, player.UserIDString));
}
#endregion
#region Void handling
private BaseEntity CreateVoid(BasePlayer player)
{
BaseEntity ent = GameManager.server.CreateEntity("assets/prefabs/deployable/rug/rug.deployed.prefab", player.transform.position);
if (ent == null)
{
PrintWarning("Error when creating a void.Please contact the plugin author.");
return null;
}
ent.skinID = _config.skin; // 1277571149 my portal - 1277211259
ent.Spawn();
ent.gameObject.AddComponent<TeleportVoid>().ownerPlayer = player;
return ent;
}
public class TeleportVoid : MonoBehaviour
{
private ItemContainer linkedContainer;
public BaseEntity entity;
private BoxCollider collider;
public BasePlayer ownerPlayer;
private float initTime;
private float destroyTime;
private string t;
private void Awake()
{
entity = GetComponent<BaseEntity>();
collider = entity.GetComponent<BoxCollider>();
collider.isTrigger = true;
initTime = Time.time;
destroyTime = initTime + instance._config.voidLifeLength;
instance.NextTick(() =>
{
linkedContainer = instance.voidList[ownerPlayer.UserIDString];
});
}
private void Update()
{
if (Time.time >= destroyTime)
{
entity.Kill(BaseNetworkable.DestroyMode.None);
Destroy(this);
}
transform.Rotate(0, 0.2f, 0);
entity.SendNetworkUpdateImmediate();
}
private void OnTriggerEnter(Collider col)
{
DroppedItem droppedItem = col.GetComponentInParent<DroppedItem>();
if (droppedItem == null)
return;
if (linkedContainer != null)
if (ContainerHasSpace(linkedContainer))
TransportThroughVoid(droppedItem);
}
private void TransportThroughVoid(DroppedItem droppedItem)
{
int itemamount = droppedItem.item.amount;
string itemname = droppedItem.item.info.shortname;
if (instance._config.eco.economicsSupport && instance._config.eco.itemTable.ContainsKey(itemname))
{
double itemcost = instance._config.eco.itemTable[itemname] * itemamount;
if (instance.EnoughMoney(droppedItem.OwnerID.ToString(), itemcost))
{
instance.Withdraw(droppedItem.OwnerID.ToString(), itemcost);
droppedItem.item.MoveToContainer(linkedContainer);
DoVanishEffect(droppedItem.transform.position);
return;
}
}
droppedItem.item.MoveToContainer(linkedContainer);
DoVanishEffect(droppedItem.transform.position);
//removalItems.Add(droppedItem);
}
private void DoVanishEffect(Vector3 pos)
{
t = instance._config.effectUsed;
Effect.server.Run(t, pos, gameObject.transform.position.normalized);
}
private bool ContainerHasSpace(ItemContainer container)
{
if (container.itemList.Count < container.capacity)
return true;
return false;
}
}
#endregion
#region Config handling
public ConfigFile _config;
public class ConfigFile
{
[JsonProperty("Time until the void despawns")]
public float voidLifeLength = 300.0f;
[JsonProperty("Skin to use for the void (Default skin is: 1277211259")]
public ulong skin = 1277211259;
[JsonProperty("Effect to use when an item is transferred to a linked container")]
public string effectUsed = "assets/bundled/prefabs/fx/water/playerjumpinwater.prefab";
[JsonProperty("Command to create a void")]
public string voidCommand = "void";
[JsonProperty("Command to link a chest")]
public string linkCommand = "linkchest";
[JsonProperty("Economics")]
public ItemVoidEconomics eco = new ItemVoidEconomics();
}
protected override void LoadConfig()
{
base.LoadConfig();
_config = Config.ReadObject<ConfigFile>();
if (_config == null)
{
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig()
{
_config = new ConfigFile();
PrintWarning("Default configuration has been loaded.");
}
protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Economics handling
public class ItemVoidEconomics
{
[JsonProperty("Enable economics support?")]
public bool economicsSupport = false;
[JsonProperty("Cost to link a container")]
public double linkCost = 500;
[JsonProperty("Cost to create a void")]
public double voidCost = 1000;
[JsonProperty("Item ID and costs")]
public Dictionary<string, double> itemTable = new Dictionary<string, double>
{
{"stones", 100 },
{"wood", 50 }
};
}
#endregion
#region Helpers
private void Withdraw(string playerId, double amount)
{
Economics?.Call("Withdraw", playerId, amount);
}
private bool EnoughMoney(string playerId, double requiredAmount)
{
double playerBalance = (double)(Economics?.Call("Balance", playerId));
if (playerBalance >= requiredAmount)
return true;
return false;
}
public static BasePlayer FindPlayer(ulong userId)
{
foreach (var activePlayer in BasePlayer.activePlayerList)
{
if (activePlayer.userID == userId)
return activePlayer;
}
foreach (var sleepingPlayer in BasePlayer.sleepingPlayerList)
{
if (sleepingPlayer.userID == userId)
return sleepingPlayer;
}
return null;
}
#endregion
}
}