C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Rust;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Parachute", "Rustoholics", "0.2.2")]
[Description("Give players a parachute")]
public class Parachute : CovalencePlugin
{
#region Dependencies
[PluginReference] private Plugin Chute;
#endregion
#region Config
private double _fallSpeed = 1d;
private float _fallTimer = 0.2f;
private int _coolDown = 5;
private float _packCheckTimer = 60f;
private string _backpackPrefab = "assets/prefabs/misc/item drop/item_drop_backpack.prefab";
private Dictionary<string, Timer> _fallTimers = new Dictionary<string, Timer>();
private Configuration _config;
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() => _config = new Configuration();
private class Configuration
{
public bool ShowBackpack = true;
public ulong ParachuteSkinId = 1901976770;
public string ParachuteName = "Parachute";
public string ParachuteShortname = "attire.hide.poncho";
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
#endregion
#region Language
private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["InvalidPlayer"] = "Invalid player",
["ParachuteGiveTo"] = "Parachute given to {0}",
}, this);
}
#endregion
# region Hooks
private void OnServerInitialized()
{
permission.RegisterPermission("parachute.admin", this);
foreach (var p in players.Connected)
{
MonitorPlayerFall(p.Object as BasePlayer);
WearSetupAndTimer(p.Object as BasePlayer);
}
}
private void OnPlayerConnected(BasePlayer player)
{
MonitorPlayerFall(player);
WearSetupAndTimer(player);
}
private void WearSetupAndTimer(BasePlayer player)
{
WearParachutePack(player);
}
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
if (info != null && info.HitEntity != null && info.HitEntity.ToPlayer() != null && info.HitEntity.ToPlayer().userID.IsSteamId())
{
if (info.damageTypes.Has(DamageType.Fall) && IsWearingParachute(info.HitEntity.ToPlayer()))
{
return true;
}
}
return null;
}
private void OnItemAddedToContainer(ItemContainer container, Item item)
{
DoPackWearing(container.playerOwner, item);
}
private void OnItemRemovedFromContainer(ItemContainer container, Item item)
{
DoPackWearing(container.playerOwner, item);
}
#endregion
#region Functions
private void MonitorPlayerFall(BasePlayer player)
{
if (Chute == null || !Chute.IsLoaded) return;
if (_fallTimers.ContainsKey(player.UserIDString))
{
_fallTimers[player.UserIDString].Destroy();
}
var d = 0d;
DateTime lastChute = default(DateTime);
_fallTimers[player.UserIDString] = timer.Every(_fallTimer, () =>
{
if (d > 0 && !player.IsFlying && d - player.transform.position.y > _fallSpeed)
{
if (IsWearingParachute(player)
&& !player.isMounted
&& (default(DateTime) == lastChute || lastChute.AddSeconds(_coolDown) < DateTime.Now)
&& !Chute.Call<bool>("ActiveChutePlayerList", player)
&& Chute.Call<bool>("IsAboveGround", player))
{
Chute.Call("ExternalAddPlayerChute", player, "");
lastChute = DateTime.Now;
}
}
d = player.transform.position.y;
});
}
private bool IsWearingParachute(BasePlayer player)
{
foreach (var item in player.inventory.containerWear.itemList)
{
if (ItemIsParachute(item)) return true;
}
return false;
}
private bool ItemIsParachute(Item item)
{
if (item == null) return false;
return item.info.shortname == _config.ParachuteShortname && item.skin == _config.ParachuteSkinId;
}
private void WearParachutePack(BasePlayer player)
{
if (!_config.ShowBackpack || !IsWearingParachute(player)) return;
UnwearParachutePack(player);
var parachute = GameManager.server.CreateEntity(_backpackPrefab, new Vector3(), new Quaternion(-3f, 0f, 3f, 1f), false) ;
parachute.SetParent(player, "spine3");
parachute?.Spawn();
}
private void UnwearParachutePack(BasePlayer player)
{
for (var x = player.children.Count-1; x >= 0;x--)
{
if (player.children[x].PrefabName == _backpackPrefab)
{
player.children[x].parentBone = 0;
player.children[x].Kill();
}
}
}
private bool? OnEntityKill(BaseNetworkable entity)
{
if (entity != null && entity.PrefabName != null && entity.PrefabName == _backpackPrefab)
{
var e = (entity as BaseEntity);
if (e != null && e.parentBone > 0)
{
return false;
}
}
return null;
}
private void DoPackWearing(BasePlayer player, Item item)
{
if (!_config.ShowBackpack) return;
if (!ItemIsParachute(item) || player == null || !player.userID.IsSteamId()) return;
if (IsWearingParachute(player))
{
WearParachutePack(player);
}
else
{
UnwearParachutePack(player);
if (player.isMounted && Chute != null && Chute.IsLoaded)
{
player.GetMounted().Kill();
Chute.Call("RemovePlayerID", player);
}
}
}
private void GiveParachute(BasePlayer player)
{
var itemDefinition = ItemManager.FindItemDefinition(_config.ParachuteShortname);
if (itemDefinition == null) return;
var item = ItemManager.Create(itemDefinition, 1, _config.ParachuteSkinId);
item.name = _config.ParachuteName;
var wearAvailable = player.inventory.containerWear.capacity - player.inventory.containerWear.itemList.Count;
var beltAvailable = player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count;
if (wearAvailable > 0)
{
item.MoveToContainer(player.inventory.containerWear);
return;
}
if (beltAvailable > 0)
{
item.MoveToContainer(player.inventory.containerBelt);
return;
}
player.inventory.GiveItem(item);
}
#endregion
#region Commands
[Command("parachute.give"), Permission("parachute.admin")]
private void GivePackCommand(IPlayer iplayer, string command, string[] args)
{
BasePlayer player;
if (args == null || args.Length == 0)
{
player = iplayer.Object as BasePlayer;
}
else
{
ulong playerid;
if (UInt64.TryParse(args[0], out playerid)){
player = BasePlayer.FindByID(playerid);
}
else
{
player = null;
}
}
if (player == null)
{
iplayer.Reply(Lang("InvalidPlayer", iplayer.Id));
return;
}
GiveParachute(player);
iplayer.Reply(Lang("ParachuteGiveTo", iplayer.Id, player.displayName));
}
#endregion
}
}