C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
TODO:
- Add option to steal random item from victim's inventory
- Add option for a cooldown
- Add option to exclude admin
- Add support for Rust:IO Clans to exclude clan members
- Look into Failed to call hook 'OnEntityDeath' with NRE
*/
using System;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core.Plugins;
namespace Oxide.Plugins
{
[Info("Robbery", "Wulf/lukespragg", "2.4.1", ResourceId = 736)]
[Description("Players can steal Economics money from other players")]
class Robbery : RustPlugin
{
// Do NOT edit this file, instead edit Robbery.json in oxide/config and Robbery.en.json in the oxide/lang directory,
// or create a new language file for another language using the 'en' file as a default
#region Initialization
[PluginReference] Plugin Economics;
[PluginReference] Plugin ServerRewards;
[PluginReference] Plugin EventManager;
[PluginReference] Plugin ZoneManager;
void Init()
{
LoadDefaultConfig();
LoadDefaultMessages();
permission.RegisterPermission(permRobbery, this);
}
void Loaded()
{
if (!Economics && !ServerRewards) PrintWarning("No economy plugin loaded, plugin disabled!");
}
#endregion
#region Configuration
const string permRobbery = "robbery.allowed";
bool allowMugging;
bool allowPickpocket;
bool economics;
float percentAwake;
float percentSleeping;
bool rewards;
protected override void LoadDefaultConfig()
{
Config["AllowMugging"] = allowMugging = GetConfig("AllowMugging", true);
Config["AllowPickpocket"] = allowPickpocket = GetConfig("AllowPickpocket", true);
Config["PercentAwake"] = percentAwake = GetConfig("PercentAwake", 25f);
Config["PercentSleeping"] = percentSleeping = GetConfig("PercentSleeping", 50f);
Config["Economics"] = economics = GetConfig("Economics", true);
Config["ServerRewards"] = rewards = GetConfig("ServerRewards", true);
SaveConfig();
}
#endregion
#region Localization
void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["StoleMoney"] = "You stole ${0} from {1}!",
["StoleNothing"] = "You stole pocket lint from {0}!",
["StolePoints"] = "You stole {0} points from {1}!"
}, this);
}
#endregion
#region Money Transfer
void Transfer(BasePlayer victim, BasePlayer attacker)
{
// Check if player is in event with no looting
var inEvent = EventManager?.Call("isPlaying", victim);
if (inEvent != null && (bool)inEvent) return;
// Check if player is in zone with no looting
if (ZoneManager)
{
var noLooting = Enum.Parse(ZoneManager.GetType().GetNestedType("ZoneFlags"), "noplayerloot", true);
if ((bool)ZoneManager.CallHook("HasPlayerFlag", victim, noLooting)) return;
}
// Economics plugin support
var money = 0d;
if (Economics && economics)
{
// Check if victim's balance is greater than 0
var balance = (double)Economics.Call("GetPlayerMoney", victim.userID);
// Calculate amount based on victim's balance
money = victim.IsSleeping() ? Math.Floor(balance * (percentSleeping / 100)) : Math.Floor(balance * (percentAwake / 100));
if (money > 0)
{
// Transfer money from victim to attacker
Economics.Call("Transfer", victim.userID, attacker.userID, money);
}
}
// ServerRewards plugin support
var points = 0d;
if (ServerRewards && rewards)
{
// Check if victim's balance is greater than 0
var balance = (int)ServerRewards.Call("CheckPoints", victim.userID);
// Calculate amount based on victim's balance
points = victim.IsSleeping() ? Math.Floor(balance * (percentSleeping / 100)) : Math.Floor(balance * (percentAwake / 100));
if (points > 0)
{
// Transfer points from victim to attacker
ServerRewards.Call("TakePoints", victim.userID, points);
ServerRewards.Call("AddPoints", attacker.userID, points);
}
}
// Notify attacker
if (money > 0) PrintToChat(attacker, Lang("StoleMoney", attacker.UserIDString, money, victim.displayName));
if (points > 0) PrintToChat(attacker, Lang("StolePoints", attacker.UserIDString, points, victim.displayName));
if (money <= 0 && points <= 0) PrintToChat(attacker, Lang("StoleNothing", attacker.UserIDString, victim.displayName));
}
#endregion
#region Mugging
void OnEntityDeath(BaseEntity entity, HitInfo info)
{
if (!allowMugging) return;
// Check for for valid players
var victim = entity as BasePlayer;
var attacker = info?.Initiator as BasePlayer;
if (victim == null || attacker == null) return;
if (victim == attacker) return;
// Transfer the moola
Transfer(victim, attacker);
}
#endregion
#region Pickpocketing
void OnPlayerInput(BasePlayer attacker, InputState input)
{
if (!allowPickpocket || !Economics) return;
if (!input.WasJustPressed(BUTTON.USE) && !input.WasJustPressed(BUTTON.FIRE_PRIMARY)) return;
// Get target victim
var ray = new Ray(attacker.eyes.position, attacker.eyes.HeadForward());
var entity = FindObject(ray, 1);
var victim = entity as BasePlayer;
if (victim == null) return;
// Make sure victim isn't looking
var victimToAttacker = (attacker.transform.position - victim.transform.position).normalized;
if (Vector3.Dot(victimToAttacker, victim.eyes.HeadForward().normalized) > 0) return;
// Make sure attacker isn't holding an item
if (attacker.GetActiveItem()?.GetHeldEntity() != null) return;
// Steal the money
Transfer(victim, attacker);
}
#endregion
#region Helpers
T GetConfig<T>(string name, T defaultValue)
{
if (Config[name] == null) return defaultValue;
return (T) Convert.ChangeType(Config[name], typeof(T));
}
bool IsAllowed(string id, string perm) => permission.UserHasPermission(id, perm);
string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
static BaseEntity FindObject(Ray ray, float distance)
{
RaycastHit hit;
return !Physics.Raycast(ray, out hit, distance) ? null : hit.GetEntity();
}
#endregion
}
}