C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins
{
[Info("Mushroom Effects", "supreme", "1.1.2")]
[Description("Make mushroom eating fun and add effects")]
public class MushroomEffects : RustPlugin
{
#region Class Fields
private PluginConfig _pluginConfig;
private readonly Hash<string, Effect> _cachedEffects = new Hash<string, Effect>();
private readonly Hash<ulong, List<Timer>> _cachedTimers = new Hash<ulong, List<Timer>>();
private readonly Hash<ulong, int> _cachedUsedMushrooms = new Hash<ulong, int>();
private readonly System.Random _random = new System.Random();
private const string UiBlur = "MushroomEffects_UiBlur";
private const string UiEffects = "MushroomEffects_UiEffects";
private const string HardShakeEffectPrefab = "assets/bundled/prefabs/fx/screen_land.prefab";
private const string SoftShakeEffectPrefab = "assets/bundled/prefabs/fx/takedamage_generic.prefab";
private const string VomitEffetPrefab = "assets/bundled/prefabs/fx/gestures/drink_vomit.prefab";
private const string BreatheEffectPrefab = "assets/prefabs/npc/bear/sound/breathe.prefab";
private const string UsePermission = "mushroomeffects.use";
private const int MushroomItemId = -1962971928;
private string _cachedUi;
#endregion
#region Hooks
private void Init()
{
permission.RegisterPermission(UsePermission, this);
}
private void OnServerInitialized()
{
CacheUiBlur();
}
private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
DestroyMushroomEffects(player);
}
}
private void OnItemUse(Item item, int amount)
{
if (item.info.itemid != MushroomItemId)
{
return;
}
BasePlayer player = item.GetOwnerPlayer();
if (!player || !permission.UserHasPermission(player.UserIDString, UsePermission))
{
return;
}
ulong playerId = player.userID;
_cachedUsedMushrooms[playerId]++;
if (_cachedUsedMushrooms[playerId] < _random.Next(_pluginConfig.MinUsed, _pluginConfig.MaxUsed))
{
return;
}
List<Timer> cachedTimers = GetCachedTimers(playerId);
int times = 0;
// No point in implementing a proper system for such a simple plugin
cachedTimers.Add(timer.Every(0.25f, () =>
{
if (_pluginConfig.EnableShakeEffect)
{
SendEffectTo(HardShakeEffectPrefab, player);
SendEffectTo(SoftShakeEffectPrefab, player);
}
// instead of instantiating more timers
if (times % 16 == 0 && _pluginConfig.EnableVomitEffect)
{
SendEffectTo(VomitEffetPrefab, player);
}
if (times % 4 == 0 && _pluginConfig.EnableBreathEffect)
{
SendEffectTo(BreatheEffectPrefab, player);
}
DisplayUiEffects(player);
times++;
}));
DisplayUiBlur(player);
_cachedUsedMushrooms[playerId] = 0;
cachedTimers.Add(timer.Once(_pluginConfig.EffectsDuration, () => DestroyMushroomEffects(player)));
}
private void OnPlayerDeath(BasePlayer player, HitInfo hitInfo)
{
DestroyMushroomEffects(player);
}
private void OnPlayerDisconnected(BasePlayer player)
{
DestroyMushroomEffects(player);
_cachedUsedMushrooms.Remove(player.userID);
_cachedTimers.Remove(player.userID);
}
#endregion
#region Core Methods
private void DisplayUiBlur(BasePlayer player)
{
if (!player)
{
return;
}
CuiHelper.DestroyUi(player, UiBlur);
CuiHelper.AddUi(player, _cachedUi);
}
private void DisplayUiEffects(BasePlayer player)
{
if (!player)
{
return;
}
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
Image = { Color = $"{GetRandomColor()}" }
}, "Overlay", UiEffects);
CuiHelper.DestroyUi(player, UiEffects);
CuiHelper.AddUi(player, container);
}
#endregion
#region Helper Methods
private List<Timer> GetCachedTimers(ulong playerId)
{
return _cachedTimers[playerId] ?? (_cachedTimers[playerId] = new List<Timer>());
}
private void CacheUiBlur()
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = false,
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
Image = { Color = "0 0 0 0.65", Material = "assets/content/ui/uibackgroundblur.mat" },
}, "Overlay", UiBlur);
_cachedUi = container.ToJson();
}
private void SendEffectTo(string effectPrefab, BasePlayer player)
{
Effect effect = _cachedEffects[effectPrefab];
if (effect == null)
{
effect = new Effect(effectPrefab, Vector3.zero, Vector3.zero)
{
attached = true
};
_cachedEffects[effectPrefab] = effect;
}
effect.entity = player.net.ID;
EffectNetwork.Send(effect, player.net.connection);
}
private void DestroyMushroomEffects(BasePlayer player)
{
CuiHelper.DestroyUi(player, UiEffects);
CuiHelper.DestroyUi(player, UiBlur);
DestroyTimers(player.userID);
}
private void DestroyTimers(ulong playerId)
{
List<Timer> timers = _cachedTimers[playerId];
if (timers == null)
{
return;
}
foreach (Timer cachedTimer in timers)
{
cachedTimer?.Destroy();
}
}
private string GetRandomColor()
{
return $"{_random.NextDouble()} {_random.NextDouble()} {_random.NextDouble()} {_pluginConfig.ColorOpacity}";
}
#endregion
#region Configuration
private class PluginConfig
{
[JsonProperty(PropertyName = "Duration of the effects")]
public float EffectsDuration { get; set; } = 10f;
[JsonProperty(PropertyName = "Minimum Amount Of Mushrooms required to trigger the effect")]
public int MinUsed { get; set; } = 1;
[JsonProperty(PropertyName = "Maximum Amount Of Mushrooms required to trigger the effect")]
public int MaxUsed { get; set; } = 5;
[JsonProperty(PropertyName = "Opacity of the colors")]
public float ColorOpacity { get; set; } = 0.3f;
[JsonProperty(PropertyName = "Enable vomit effect")]
public bool EnableVomitEffect { get; set; } = true;
[JsonProperty(PropertyName = "Enable breath effect")]
public bool EnableBreathEffect { get; set; } = true;
[JsonProperty(PropertyName = "Enable shake effect")]
public bool EnableShakeEffect { get; set; } = true;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_pluginConfig = Config.ReadObject<PluginConfig>();
if (_pluginConfig == null)
{
throw new Exception();
}
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() => Config.WriteObject(_pluginConfig);
protected override void LoadDefaultConfig() => _pluginConfig = new PluginConfig();
#endregion
}
}