C#:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Oxide.Core.Libraries.Covalence;
using ru = Oxide.Game.Rust;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json.Linq;
using UnityEngine;
using Facepunch;
using Rust;
namespace Oxide.Plugins
{
[Info ("CombatBB", "Calytic", "2.1.35")]
[Description ("Prevent commands/actions while raid and/or combat is occuring")]
class CombatBB : RustPlugin
{
[ChatCommand("123")]
void pop(BasePlayer player)
{
StartCombatBlocking(player);
}
#region Setup & Configuration
List<string> blockTypes = new List<string> ()
{
"remove",
"tp",
"bank",
"trade",
"recycle",
"shop",
"bgrade",
"build",
"repair",
"upgrade",
"vend",
"kit",
"assignbed",
"craft",
"mailbox",
"backpack"
};
// COMBAT SETTINGS
bool combatBlock;
static float combatDuration;
bool combatOnHitPlayer;
float combatOnHitPlayerMinCondition;
float combatOnHitPlayerMinDamage;
bool combatOnTakeDamage;
float combatOnTakeDamageMinCondition;
float combatOnTakeDamageMinDamage;
bool combatOnHitNPC;
bool combatOnTakeDamageNPC;
// RAID BLOCK SETTINGS
bool raidBlock;
static float raidDuration;
float raidDistance;
bool blockOnDamage;
float blockOnDamageMinCondition;
bool blockOnDestroy;
// RAID-ONLY SETTINGS
bool ownerCheck;
bool blockUnowned;
bool blockAll;
// IGNORES ALL OTHER CHECKS
bool ownerBlock;
bool cupboardShare;
bool friendShare;
bool clanShare;
bool clanCheck;
bool friendCheck;
bool raiderBlock;
List<string> raidDamageTypes;
List<string> raidDeathTypes;
List<string> combatDamageTypes;
// RAID UNBLOCK SETTINGS
bool raidUnblockOnDeath;
bool raidUnblockOnWakeup;
bool raidUnblockOnRespawn;
// COMBAT UNBLOCK SETTINGS
bool combatUnblockOnDeath;
bool combatUnblockOnWakeup;
bool combatUnblockOnRespawn;
float cacheTimer;
// MESSAGES
bool raidBlockNotify;
bool combatBlockNotify;
bool useZoneManager;
bool zoneEnter;
bool zoneLeave;
bool useRaidableBases;
bool raidableZoneEnter;
bool raidableZoneLeave;
bool sendUINotification;
bool sendChatNotification;
bool sendGUIAnnouncementsNotification;
bool sendLustyMapNotification;
string GUIAnnouncementTintColor = "Red";
string GUIAnnouncementTextColor = "White";
string LustyMapIcon = "special";
float LustyMapDuration = 150f;
Dictionary<string, RaidZone> zones = new Dictionary<string, RaidZone> ();
Dictionary<string, List<string>> memberCache = new Dictionary<string, List<string>> ();
Dictionary<string, string> clanCache = new Dictionary<string, string> ();
Dictionary<string, List<string>> friendCache = new Dictionary<string, List<string>> ();
Dictionary<string, DateTime> lastClanCheck = new Dictionary<string, DateTime> ();
Dictionary<string, DateTime> lastCheck = new Dictionary<string, DateTime> ();
Dictionary<string, DateTime> lastFriendCheck = new Dictionary<string, DateTime> ();
Dictionary<string, bool> prefabBlockCache = new Dictionary<string, bool> ();
internal Dictionary<ulong, BlockBehavior> blockBehaviors = new Dictionary<ulong, BlockBehavior> ();
public static CombatBB plugin;
[PluginReference]
Plugin Clans, Friends, ZoneManager, GUIAnnouncements, LustyMap;
readonly int cupboardMask = LayerMask.GetMask ("Deployed");
readonly int blockLayer = LayerMask.GetMask ("Player (Server)");
Dictionary<string, bool> _cachedExcludedWeapons = new Dictionary<string, bool> ();
List<string> blockedPrefabs = new List<string> ()
{
"door",
"window.bars",
"floor.ladder.hatch",
"floor.frame",
"wall.frame",
"shutter",
"external"
};
List<string> exceptionPrefabs = new List<string> ()
{
"ladder.wooden"
};
List<string> exceptionWeapons = new List<string> ()
{
"torch"
};
private List<string> GetDefaultRaidDamageTypes ()
{
return new List<DamageType> ()
{
DamageType.Bullet,
DamageType.Blunt,
DamageType.Stab,
DamageType.Slash,
DamageType.Explosion,
DamageType.Heat
}.Select (x => x.ToString ()).ToList<string> ();
}
private List<string> GetDefaultCombatDamageTypes ()
{
return new List<DamageType> ()
{
DamageType.Bullet,
DamageType.Arrow,
DamageType.Blunt,
DamageType.Stab,
DamageType.Slash,
DamageType.Explosion,
DamageType.Heat,
DamageType.ElectricShock
}.Select (x => x.ToString ()).ToList<string> ();
}
Dictionary<string, object> blockWhenRaidDamageDefault = new Dictionary<string, object> () {
{"enabled", true},
{"minCondition", 100f},
};
Dictionary<string, object> blockWhenCombatDamageDefault = new Dictionary<string, object> () {
{"enabled", false},
{"minCondition", 100f},
{"minDamage", 1f},
};
static Regex _htmlRegex = new Regex ("<.*?>", RegexOptions.Compiled);
protected override void LoadDefaultConfig ()
{
Config ["VERSION"] = Version.ToString ();
// RAID SETTINGS
Config ["Raid", "Block", "enabled"] = true;
Config ["Raid", "Block", "duration"] = 300f; // 5 minutes
Config ["Raid", "Block", "distance"] = 100f;
Config ["Raid", "Block", "notify"] = true;
Config ["Raid", "Block", "damageTypes"] = GetDefaultRaidDamageTypes ();
Config ["Raid", "Block", "deathTypes"] = GetDefaultRaidDamageTypes();
Config ["Raid", "Block", "includePrefabs"] = blockedPrefabs;
Config ["Raid", "Block", "excludePrefabs"] = exceptionPrefabs;
Config ["Raid", "Block", "excludeWeapons"] = exceptionWeapons;
Config ["Raid", "BlockWhen", "damage"] = blockWhenRaidDamageDefault;
Config ["Raid", "BlockWhen", "destroy"] = true;
Config ["Raid", "BlockWhen", "unowned"] = false;
Config ["Raid", "BlockWho", "everyone"] = true;
Config ["Raid", "BlockWho", "owner"] = false;
Config ["Raid", "BlockWho", "cupboardAuthorized"] = false;
Config ["Raid", "BlockWho", "clan"] = false;
Config ["Raid", "BlockWho", "friends"] = false;
Config ["Raid", "BlockWho", "raider"] = false;
Config ["Raid", "BlockExcept", "owner"] = true;
Config ["Raid", "BlockExcept", "friends"] = false;
Config ["Raid", "BlockExcept", "clan"] = false;
Config ["Raid", "Zone", "enabled"] = false;
Config ["Raid", "Zone", "enter"] = true;
Config ["Raid", "Zone", "leave"] = false;
Config ["Raid", "Map", "enabled"] = false;
Config ["Raid", "Map", "icon"] = "special";
Config ["Raid", "Map", "duration"] = 150f;
Config ["Raid", "UnblockWhen", "death"] = true;
Config ["Raid", "UnblockWhen", "wakeup"] = false;
Config ["Raid", "UnblockWhen", "respawn"] = true;
// COMBAT SETTINGS
Config ["Combat", "Block", "enabled"] = false;
Config ["Combat", "Block", "duration"] = 180f; // 3 minutes
Config ["Combat", "Block", "notify"] = true;
Config ["Combat", "Block", "damageTypes"] = GetDefaultCombatDamageTypes ();
Config ["Combat", "BlockWhen", "giveDamage"] = blockWhenCombatDamageDefault;
Config ["Combat", "BlockWhen", "takeDamage"] = blockWhenCombatDamageDefault;
Config ["Combat", "BlockWhen", "npcGiveDamage"] = false;
Config ["Combat", "BlockWhen", "npcTakeDamage"] = false;
Config ["Combat", "UnblockWhen", "death"] = true;
Config ["Combat", "UnblockWhen", "wakeup"] = false;
Config ["Combat", "UnblockWhen", "respawn"] = true;
Config ["Settings", "cacheMinutes"] = 1f;
Config ["Settings", "Block", "Types"] = blockTypes;
Config ["Notifications", "UI"] = true;
Config ["Notifications", "Chat"] = true;
Config ["Notifications", "GUIAnnouncements", "enabled"] = false;
Config ["Notifications", "GUIAnnouncements", "backgroundColor"] = "Red";
Config ["Notifications", "GUIAnnouncements", "textColor"] = "White";
Config ["VERSION"] = Version.ToString ();
}
void Loaded ()
{
LoadMessages ();
}
void Unload ()
{
if (useZoneManager)
foreach (var zone in zones.ToList ())
EraseZone (zone.Value.zoneid);
var objects = GameObject.FindObjectsOfType (typeof (RaidBlock));
if (objects != null)
foreach (var gameObj in objects)
if (!((RaidBlock)gameObj).Active)
GameObject.Destroy (gameObj);
objects = GameObject.FindObjectsOfType (typeof (CombatBlock));
if (objects != null)
foreach (var gameObj in objects)
if (!((CombatBlock)gameObj).Active)
GameObject.Destroy (gameObj);
}
void LoadMessages ()
{
lang.RegisterMessages (new Dictionary<string, string>
{
{ "Raid Blocked Message", "You may not do that while raid blocked ({time})" },
{ "Combat Blocked Message", "You may do that while a in combat ({time})" },
{ "Raid Block Complete", "You are no longer raid blocked." },
{ "Combat Block Complete", "You are no longer combat blocked." },
{ "Raid Block Notifier", "You are raid blocked for {time}" },
{ "Combat Block Notifier", "You are combat blocked for {time}" },
{ "Combat Block UI Message", "COMBAT BLOCK" },
{ "Raid Block UI Message", "RAID BLOCK" },
{ "Unit Seconds", "second(s)" },
{ "Unit Minutes", "minute(s)" },
{ "Prefix", string.Empty }
}, this);
}
void CheckConfig ()
{
if (Config ["VERSION"] == null) {
// FOR COMPATIBILITY WITH INITIAL VERSIONS WITHOUT VERSIONED CONFIG
ReloadConfig ();
} else if (GetConfig ("VERSION", string.Empty) != Version.ToString ()) {
// ADDS NEW, IF ANY, CONFIGURATION OPTIONS
ReloadConfig ();
}
}
protected void ReloadConfig ()
{
Config ["VERSION"] = Version.ToString ();
// NEW CONFIGURATION OPTIONS HERE
// END NEW CONFIGURATION OPTIONS
PrintToConsole ("Upgrading configuration file");
SaveConfig ();
}
void OnServerInitialized ()
{
CombatBB.plugin = this;
permission.RegisterPermission ("CombatBB.disable", this);
blockTypes = GetConfig ("Settings", "Block", "Types", blockTypes);
foreach (string command in blockTypes) {
permission.RegisterPermission ("CombatBB.raid." + command + "block", this);
permission.RegisterPermission ("CombatBB.combat." + command + "block", this);
}
CheckConfig ();
// RAID SETTINGS
raidBlock = GetConfig ("Raid", "Block", "enabled", true);
raidDuration = GetConfig ("Raid", "Block", "duration", 300f);
raidDistance = GetConfig ("Raid", "Block", "distance", 100f);
raidBlockNotify = GetConfig ("Raid", "Block", "notify", true);
raidDamageTypes = GetConfig ("Raid", "Block", "damageTypes", GetDefaultRaidDamageTypes ());
raidDeathTypes = GetConfig("Raid", "Block", "deathTypes", GetDefaultRaidDamageTypes());
Interface.Oxide.GetLibrary<ru.Libraries.Command>(null).AddConsoleCommand("blockaddcommand.start", this, "StartBlockingBB");
blockedPrefabs = GetConfig ("Raid", "Block", "includePrefabs", blockedPrefabs);
exceptionPrefabs = GetConfig ("Raid", "Block", "excludePrefabs", exceptionPrefabs);
exceptionWeapons = GetConfig ("Raid", "Block", "excludeWeapons", exceptionWeapons);
Dictionary<string, object> blockOnRaidDamageDetails = GetConfig ("Raid", "BlockWhen", "damage", blockWhenRaidDamageDefault);
if (blockOnRaidDamageDetails.ContainsKey ("enabled")) {
blockOnDamage = (bool)blockOnRaidDamageDetails ["enabled"];
} else {
blockOnDamage = true;
}
if (blockOnRaidDamageDetails.ContainsKey ("minCondition")) {
blockOnDamageMinCondition = Convert.ToSingle (blockOnRaidDamageDetails ["minCondition"]);
} else {
blockOnDamageMinCondition = 100f;
}
blockOnDestroy = GetConfig ("Raid", "BlockWhen", "destroy", true);
blockUnowned = GetConfig ("Raid", "BlockWhen", "unowned", false);
blockAll = GetConfig ("Raid", "BlockWho", "everyone", true);
ownerBlock = GetConfig ("Raid", "BlockWho", "owner", false);
friendShare = GetConfig ("Raid", "BlockWho", "friends", false);
clanShare = GetConfig ("Raid", "BlockWho", "clan", false);
cupboardShare = GetConfig ("Raid", "BlockWho", "cupboardAuthorized", false);
raiderBlock = GetConfig ("Raid", "BlockWho", "raider", false);
ownerCheck = GetConfig ("Raid", "BlockExcept", "owner", true);
friendCheck = GetConfig ("Raid", "BlockExcept", "friends", false);
clanCheck = GetConfig ("Raid", "BlockExcept", "clan", false);
useZoneManager = GetConfig ("Raid", "Zone", "enabled", false);
zoneEnter = GetConfig ("Raid", "Zone", "enter", true);
zoneLeave = GetConfig ("Raid", "Zone", "leave", false);
useRaidableBases = GetConfig ("Raid", "RaidableBases", "enabled", false);
raidableZoneEnter = GetConfig ("Raid", "RaidableBases", "enter", true);
raidableZoneLeave = GetConfig ("Raid", "RaidableBases", "leave", false);
sendLustyMapNotification = GetConfig ("Raid", "Map", "enabled", false);
LustyMapIcon = GetConfig ("Raid", "Map", "icon", "special");
LustyMapDuration = GetConfig ("Raid", "Map", "duration", 150f);
raidUnblockOnDeath = GetConfig ("Raid", "UnblockWhen", "death", true);
raidUnblockOnWakeup = GetConfig ("Raid", "UnblockWhen", "wakeup", false);
raidUnblockOnRespawn = GetConfig ("Raid", "UnblockWhen", "respawn", true);
// COMBAT SETTINGS
combatBlock = GetConfig ("Combat", "Block", "enabled", false);
combatDuration = GetConfig ("Combat", "Block", "duration", 180f);
combatBlockNotify = GetConfig ("Combat", "Block", "notify", true);
combatDamageTypes = GetConfig ("Combat", "Block", "damageTypes", GetDefaultCombatDamageTypes ());
//combatOnHitPlayer = GetConfig ("Combat", "BlockWhen", "giveDamage", true);
Dictionary<string, object> blockOnCombatGiveDamageDetails = GetConfig ("Combat", "BlockWhen", "giveDamage", blockWhenCombatDamageDefault);
if (blockOnCombatGiveDamageDetails.ContainsKey ("enabled")) {
combatOnHitPlayer = (bool)blockOnCombatGiveDamageDetails ["enabled"];
} else {
combatOnHitPlayer = false;
}
if (blockOnCombatGiveDamageDetails.ContainsKey ("minCondition")) {
combatOnHitPlayerMinCondition = Convert.ToSingle (blockOnCombatGiveDamageDetails ["minCondition"]);
} else {
combatOnHitPlayerMinCondition = 100f;
}
//combatOnTakeDamage = GetConfig ("Combat", "BlockWhen", "takeDamage", true);
Dictionary<string, object> blockOnCombatTakeDamageDetails = GetConfig ("Combat", "BlockWhen", "takeDamage", blockWhenCombatDamageDefault);
if (blockOnCombatTakeDamageDetails.ContainsKey ("enabled")) {
combatOnTakeDamage = (bool)blockOnCombatTakeDamageDetails ["enabled"];
} else {
combatOnTakeDamage = false;
}
if (blockOnCombatTakeDamageDetails.ContainsKey ("minCondition")) {
combatOnTakeDamageMinCondition = Convert.ToSingle (blockOnCombatTakeDamageDetails ["minCondition"]);
} else {
combatOnTakeDamageMinCondition = 100f;
}
if (blockOnCombatTakeDamageDetails.ContainsKey ("minDamage")) {
combatOnTakeDamageMinDamage = Convert.ToSingle (blockOnCombatTakeDamageDetails ["minDamage"]);
} else {
combatOnTakeDamageMinDamage = 1f;
}
combatOnHitNPC = GetConfig ("Combat", "BlockWhen", "npcGiveDamage", false);
combatOnTakeDamageNPC = GetConfig ("Combat", "BlockWhen", "npcTakeDamage", false);
combatUnblockOnDeath = GetConfig ("Combat", "UnblockWhen", "death", true);
combatUnblockOnWakeup = GetConfig ("Combat", "UnblockWhen", "wakeup", false);
combatUnblockOnRespawn = GetConfig ("Combat", "UnblockWhen", "respawn", true);
cacheTimer = GetConfig ("Settings", "cacheMinutes", 1f);
sendUINotification = GetConfig ("Notifications", "UI", true);
sendChatNotification = GetConfig ("Notifications", "Chat", true);
sendGUIAnnouncementsNotification = GetConfig ("Notifications", "GUIAnnouncements", "enabled", false);
GUIAnnouncementTintColor = GetConfig ("Notifications", "GUIAnnouncements", "backgroundColor", "Red");
GUIAnnouncementTextColor = GetConfig ("Notifications", "GUIAnnouncements", "textColor", "White");
if ((clanShare || clanCheck) && !Clans) {
clanShare = false;
clanCheck = false;
PrintWarning ("Clans not found! All clan options disabled.Cannot use clan options without this plugin.http://oxidemod.org/plugins/clans.2087");
}
if (friendShare && !Friends) {
friendShare = false;
friendCheck = false;
PrintWarning ("Friends not found! All friend options disabled.Cannot use friend options without this plugin.http://oxidemod.org/plugins/friends-api.686");
}
if (useZoneManager && !ZoneManager) {
useZoneManager = false;
PrintWarning ("ZoneManager not found! All zone options disabled.Cannot use zone options without this plugin.http://oxidemod.org/plugins/zones-manager.739");
}
if (sendGUIAnnouncementsNotification && !GUIAnnouncements) {
sendGUIAnnouncementsNotification = false;
PrintWarning ("GUIAnnouncements not found! GUI announcement option disabled.Cannot use gui announcement integration without this plugin.http://oxidemod.org/plugins/gui-announcements.1222");
}
if (sendLustyMapNotification && !LustyMap) {
sendLustyMapNotification = false;
PrintWarning ("LustyMap not found! LustyMap notification option disabled.Cannot use LustyMap integration without this plugin.http://oxidemod.org/plugins/lustymap.1333");
}
if (sendLustyMapNotification && LustyMap && LustyMapDuration <= 0) {
PrintWarning ("LustyMap icon duration is zero, no icon will be displayed");
}
UnsubscribeHooks ();
}
const string ss = "<color=#FB7153>Запрещено использовать эту команду во время коматблока!</color>";
void UnsubscribeHooks ()
{
if (!blockOnDestroy && !raidUnblockOnDeath && !combatUnblockOnDeath)
Unsubscribe ("OnEntityDeath");
if (!raidUnblockOnWakeup && !combatUnblockOnWakeup)
Unsubscribe ("OnPlayerSleepEnded");
if (!combatOnTakeDamage && !combatOnHitPlayer)
Unsubscribe ("OnPlayerAttack");
if (!blockOnDamage)
Unsubscribe ("OnEntityTakeDamage");
if (!blockTypes.Contains ("repair"))
Unsubscribe ("OnStructureRepair");
if (!blockTypes.Contains ("upgrade"))
Unsubscribe ("OnStructureUpgrade");
if (!blockTypes.Contains ("mailbox"))
Unsubscribe ("CanUseMailbox");
if (!blockTypes.Contains ("vend"))
Unsubscribe ("CanUseVending");
if (!blockTypes.Contains ("build"))
Unsubscribe ("CanBuild");
if (!blockTypes.Contains ("assignbed"))
Unsubscribe ("CanAssignBed");
if (!blockTypes.Contains ("craft"))
Unsubscribe ("CanCraft");
if (!blockTypes.Contains ("backpack"))
Unsubscribe ("CanOpenBackpack");
if (!blockTypes.Contains ("kit"))
Unsubscribe ("canRedeemKit");
if(!useZoneManager)
{
Unsubscribe ("OnEnterZone");
Unsubscribe ("OnExitZone");
}
if(!useRaidableBases)
{
Unsubscribe ("OnPlayerEnteredRaidableBase");
Unsubscribe ("OnPlayerExitedRaidableBase");
}
}
object canRedeemKit(BasePlayer player)
{
if(!IsCombatBlocked(player)) return null;
return ss;
}
#endregion
#region Classes
public class RaidZone
{
public string zoneid;
public Vector3 position;
public Timer timer;
public RaidZone (string zoneid, Vector3 position)
{
this.zoneid = zoneid;
this.position = position;
}
public float Distance (RaidZone zone)
{
return Vector3.Distance (position, zone.position);
}
public float Distance (Vector3 pos)
{
return Vector3.Distance (position, pos);
}
public RaidZone ResetTimer ()
{
if (timer is Timer && !timer.Destroyed)
timer.Destroy ();
return this;
}
}
public abstract class BlockBehavior : MonoBehaviour
{
protected BasePlayer player;
public DateTime lastBlock = DateTime.MinValue;
public DateTime lastNotification = DateTime.MinValue;
internal DateTime lastUINotification = DateTime.MinValue;
internal Timer timer;
internal Action notifyCallback;
internal string iconUID;
internal bool moved;
public void CopyFrom (BlockBehavior behavior)
{
lastBlock = behavior.lastBlock;
lastNotification = behavior.lastNotification;
lastUINotification = behavior.lastUINotification;
timer = behavior.timer;
notifyCallback = behavior.notifyCallback;
iconUID = behavior.iconUID;
NotificationWindow = behavior.NotificationWindow;
}
internal abstract float Duration { get; }
internal abstract CuiRectTransformComponent NotificationWindow { get; set; }
internal abstract string notifyMessage { get; }
internal string BlockName {
get {
return GetType ().Name;
}
}
public bool Active {
get {
if (lastBlock > DateTime.MinValue) {
TimeSpan ts = DateTime.Now - lastBlock;
if (ts.TotalSeconds < Duration) {
return true;
}
}
GameObject.Destroy (this);
return false;
}
}
void Awake ()
{
player = GetComponent<BasePlayer> ();
if (plugin.blockBehaviors.ContainsKey (player.userID)) {
plugin.blockBehaviors.Remove (player.userID);
}
plugin.blockBehaviors.Add (player.userID, this);
}
void Destroy ()
{
if (!moved) {
Stop ();
}
CancelInvoke ("Update");
}
void Update ()
{
if (!plugin.sendUINotification)
return;
bool send = false;
if (lastUINotification == DateTime.MinValue) {
lastUINotification = DateTime.Now;
send = true;
} else {
TimeSpan ts = DateTime.Now - lastUINotification;
if (ts.TotalSeconds > 1) {
send = true;
} else {
send = false;
}
}
if (player is BasePlayer && player.IsConnected) {
if (!Active) {
CuiHelper.DestroyUi (player, "MainGUI" + BlockName);
}
if (send && Active) {
lastUINotification = DateTime.Now;
SendGUI ();
}
}
}
public void Stop ()
{
if (notifyCallback is Action)
notifyCallback.Invoke ();
if (timer is Timer && !timer.Destroyed)
timer.Destroy ();
if (plugin.sendUINotification && player is BasePlayer && player.IsConnected)
CuiHelper.DestroyUi (player, "MainGUI" + BlockName);
plugin.blockBehaviors.Remove (player.userID);
GameObject.Destroy (this);
}
public void Notify (Action callback)
{
if (plugin.sendUINotification)
SendGUI ();
notifyCallback = callback;
if (timer is Timer && !timer.Destroyed)
timer.Destroy ();
timer = plugin.timer.In (Duration, callback);
}
private string FormatTime (TimeSpan ts)
{
if (ts.Days > 0)
return string.Format ("{0}D, {1}H", ts.Days, ts.Hours);
if (ts.Hours > 0)
return string.Format ("{0} мин {1} сек.",ts.Minutes, ts.Seconds);
return string.Format ("{1} сек.", ts.Minutes, ts.Seconds);
}
void SendGUI()
{
TimeSpan ts = lastBlock.AddSeconds (Duration) - DateTime.Now;
string countDown = FormatTime (ts);
CuiHelper.DestroyUi (player, "MainGUI" + BlockName);
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0.2745098 0.1921569 0.1921569 0" },
RectTransform ={ AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-39.256 117.37", OffsetMax = "-0.004 145.839" }
},"Hud","MainGUI" + BlockName);
container.Add(new CuiPanel
{
Image = { Color = "0.2745098 0.1921569 0.1921569 1" },
RectTransform ={ AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-126.027 -14.234", OffsetMax = "19.623 14.234" }
},"MainGUI" + BlockName,"Panel");
container.Add(new CuiElement
{
Name = "combattext",
Parent = "Panel",
Components =
{
new CuiTextComponent { Text = $"Комбат блок: <color=#deae00>{countDown}</color>", Font = "robotocondensed-bold.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-66.203 -12.617", OffsetMax = "72.827 7.1" }
}
});
container.Add(new CuiPanel
{
Image = { Color = "0.3960785 0.3960785 0.3764706 1" },
RectTransform ={ AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-126.027 -21.609", OffsetMax = "19.623 -14.234" }
},"MainGUI" + BlockName,"LinePanel");
double timeLines = ((double)ts.Seconds / 15);
container.Add(new CuiPanel
{
Image = { Color = "0.9294118 0.7490196 0 1" },
RectTransform ={ AnchorMin = "0 0", AnchorMax = $"{timeLines} 1",OffsetMin = "0 0", OffsetMax = "0 0" }
},"LinePanel","LinePanel (1)");
CuiHelper.AddUi(player, container);
}
/*void SendGUI ()
{
TimeSpan ts = lastBlock.AddSeconds (Duration) - DateTime.Now;
string countDown = FormatTime (ts);
CuiHelper.DestroyUi (player, "MainGUI" + BlockName);
var elements = new CuiElementContainer ();
var BlockMsg = elements.Add (new CuiPanel {
Image =
{
Color = "0.95 0 0.02 0.67"
},
RectTransform =
{
AnchorMax = NotificationWindow.AnchorMax,
AnchorMin = NotificationWindow.AnchorMin
}
}, "Hud", "BlockMsg" + BlockName);
elements.Add (new CuiElement {
Parent = BlockMsg,
Components =
{
new CuiRawImageComponent
{
Sprite = "assets/icons/explosion.png",
Color = "0.95 0 0.02 0.67"
},
new CuiRectTransformComponent
{
AnchorMin = "0 0",
AnchorMax = "0.13 1"
}
}
});
elements.Add (new CuiLabel {
RectTransform =
{
AnchorMin = "0.15 0",
AnchorMax = "0.82 1"
},
Text =
{
Text = notifyMessage,
FontSize = 11,
Align = TextAnchor.MiddleLeft,
}
}, BlockMsg);
elements.Add (new CuiElement {
Name = "TimerPanel",
Parent = BlockMsg,
Components =
{
new CuiImageComponent
{
Color = "0 0 0 0.64",
ImageType = UnityEngine.UI.Image.Type.Filled
},
new CuiRectTransformComponent
{
AnchorMin = "0.73 0",
AnchorMax = "1 1"
}
}
});
elements.Add (new CuiLabel {
RectTransform =
{
AnchorMin = "0 0",
AnchorMax = "1 1"
},
Text =
{
Text = countDown,
FontSize = 12,
Align = TextAnchor.MiddleCenter,
}
}, "TimerPanel");
CuiHelper.AddUi (player, elements);
}*/
}
public class CombatBlock : BlockBehavior
{
internal override float Duration {
get {
return combatDuration;
}
}
internal override string notifyMessage {
get { return GetMsg ("Combat Block UI Message", player); }
}
CuiRectTransformComponent _notificationWindow = null;
internal override CuiRectTransformComponent NotificationWindow {
get {
if (_notificationWindow != null) {
return _notificationWindow;
}
return _notificationWindow = new CuiRectTransformComponent () {
AnchorMin = "0.44 0.15",
AnchorMax = "0.56 0.18"
};
}
set {
_notificationWindow = value;
}
}
}
public class RaidBlock : BlockBehavior
{
internal override float Duration {
get {
return raidDuration;
}
}
internal override string notifyMessage {
get { return GetMsg ("Raid Block UI Message", player); }
}
private CuiRectTransformComponent _notificationWindow = null;
internal override CuiRectTransformComponent NotificationWindow {
get {
if (_notificationWindow != null) {
return _notificationWindow;
}
return _notificationWindow = new CuiRectTransformComponent () {
AnchorMin = "0.87 0.39",
AnchorMax = "0.99 0.42"
};
}
set {
_notificationWindow = value;
}
}
}
#endregion
#region Oxide Hooks
void OnEntityTakeDamage (BaseCombatEntity entity, HitInfo hitInfo)
{
if (!blockOnDamage || !raidBlock)
return;
if (hitInfo == null || hitInfo.Initiator == null || !IsEntityBlocked (entity) || hitInfo.Initiator.transform == null)
return;
if (!IsRaidDamage (hitInfo.damageTypes))
return;
if (IsExcludedWeapon (hitInfo?.WeaponPrefab?.ShortPrefabName))
return;
if (GetHealthPercent (entity, hitInfo.damageTypes.Total ()) > blockOnDamageMinCondition) {
return;
}
StructureAttack (entity, hitInfo.Initiator, hitInfo?.WeaponPrefab?.ShortPrefabName, hitInfo.HitPositionWorld);
}
void OnPlayerConnected (BasePlayer player)
{
BlockBehavior behavior;
if (blockBehaviors.TryGetValue (player.userID, out behavior)) {
if (behavior is RaidBlock) {
var raidBlockComponent = player.gameObject.AddComponent<RaidBlock> ();
raidBlockComponent.CopyFrom (behavior);
} else if (behavior is CombatBlock) {
var combatBlockComponent = player.gameObject.AddComponent<CombatBlock> ();
combatBlockComponent.CopyFrom (behavior);
}
behavior.moved = true;
GameObject.Destroy (behavior);
}
}
void OnPlayerAttack (BasePlayer attacker, HitInfo hitInfo)
{
if (!combatBlock || !(hitInfo.HitEntity is BasePlayer))
return;
if (!combatOnHitNPC && hitInfo.HitEntity.IsNpc)
return;
if (!combatOnTakeDamageNPC && attacker.IsNpc) {
return;
}
if (!IsCombatDamage (hitInfo.damageTypes))
return;
float totalDamage = hitInfo.damageTypes.Total ();
BasePlayer target = hitInfo.HitEntity as BasePlayer;
if (combatOnTakeDamage) {
if (GetHealthPercent (target, hitInfo.damageTypes.Total ()) > combatOnTakeDamageMinCondition) {
return;
}
if (totalDamage < combatOnTakeDamageMinDamage) {
return;
}
StartCombatBlocking (target);
}
if (combatOnHitPlayer) {
if (GetHealthPercent (attacker, hitInfo.damageTypes.Total ()) > combatOnHitPlayerMinCondition) {
return;
}
if (totalDamage < combatOnHitPlayerMinDamage) {
return;
}
StartCombatBlocking (attacker);
}
}
void OnEntityDeath (BaseCombatEntity entity, HitInfo hitInfo)
{
if (blockOnDestroy && raidBlock) {
if (hitInfo == null || hitInfo.Initiator == null || !IsDeathDamage (hitInfo.damageTypes) || !IsEntityBlocked (entity))
return;
StructureAttack (entity, hitInfo.Initiator, hitInfo?.WeaponPrefab?.ShortPrefabName, hitInfo.HitPositionWorld);
}
if (entity.ToPlayer () == null)
return;
var player = entity.ToPlayer ();
RaidBlock raidBlocker;
if (raidBlock && raidUnblockOnDeath && TryGetBlocker (player, out raidBlocker)) {
timer.In (0.3f, delegate () {
raidBlocker.Stop ();
});
}
CombatBlock combatBlocker;
if (combatBlock && combatUnblockOnDeath && TryGetBlocker (player, out combatBlocker)) {
timer.In (0.3f, delegate () {
combatBlocker.Stop ();
});
}
}
void OnPlayerSleepEnded (BasePlayer player)
{
if (player == null) return;
RaidBlock raidBlocker;
if (raidBlock && raidUnblockOnWakeup && TryGetBlocker (player, out raidBlocker)) {
timer.In (0.3f, delegate () {
raidBlocker.Stop ();
});
}
CombatBlock combatBlocker;
if (combatBlock && combatUnblockOnWakeup && TryGetBlocker (player, out combatBlocker)) {
timer.In (0.3f, delegate () {
combatBlocker.Stop ();
});
}
}
void OnPlayerRespawned (BasePlayer player)
{
if (player == null) return;
RaidBlock raidBlocker;
if (raidBlock && raidUnblockOnRespawn && TryGetBlocker (player, out raidBlocker)) {
timer.In (0.3f, delegate () {
raidBlocker.Stop ();
});
}
CombatBlock combatBlocker;
if (combatBlock && combatUnblockOnRespawn && TryGetBlocker (player, out combatBlocker)) {
timer.In (0.3f, delegate () {
combatBlocker.Stop ();
});
}
}
object CanLootEntity(BasePlayer player, StorageContainer container)
{
if(container?.GetEntity() is Recycler)
{
object reply = CanDo("recycle", player);
if (reply != null && IsBlocked(player))
{
player.ChatMessage((string)reply);
return true;
}
}
return null;
}
#endregion
#region Block Handling
void StructureAttack (BaseEntity targetEntity, BaseEntity sourceEntity, string weapon, Vector3 hitPosition)
{
BasePlayer source = null;
if (sourceEntity.ToPlayer () is BasePlayer)
source = sourceEntity.ToPlayer ();
else {
ulong ownerID = sourceEntity.OwnerID;
if (ownerID.IsSteamId ())
source = BasePlayer.FindByID (ownerID);
else
return;
}
if (source == null)
return;
List<string> sourceMembers = null;
if (targetEntity.OwnerID.IsSteamId () || (blockUnowned && !targetEntity.OwnerID.IsSteamId ())) {
if (clanCheck || friendCheck)
sourceMembers = getFriends (source.UserIDString);
if (blockAll) {
BlockAll (source, targetEntity, sourceMembers);
} else {
if (ownerBlock)
OwnerBlock (source, sourceEntity, targetEntity.OwnerID, targetEntity.transform.position, sourceMembers);
if (raiderBlock)
RaiderBlock (source, targetEntity.OwnerID, targetEntity.transform.position, sourceMembers);
}
}
}
float GetHealthPercent (BaseEntity entity, float damage = 0f)
{
return (entity.Health () - damage) * 100f / entity.MaxHealth ();
}
void BlockAll (BasePlayer source, BaseEntity targetEntity, List<string> sourceMembers = null)
{
if (ShouldBlockEscape (targetEntity.OwnerID, source.userID, sourceMembers)) {
StartRaidBlocking (source, targetEntity.transform.position);
}
var checkSourceMembers = false;
if (targetEntity.OwnerID == source.userID || (sourceMembers is List<string> && sourceMembers.Contains (targetEntity.OwnerID.ToString ()))) {
checkSourceMembers = true;
}
var nearbyTargets = Pool.GetList<BasePlayer> ();
Vis.Entities (targetEntity.transform.position, raidDistance, nearbyTargets, blockLayer);
if (nearbyTargets.Count > 0) {
RaidBlock blocker;
foreach (BasePlayer nearbyTarget in nearbyTargets) {
if (nearbyTarget.IsNpc) continue;
if (nearbyTarget.userID == source.userID) continue;
if (TryGetBlocker (nearbyTarget, out blocker) && blocker.Active) {
StartRaidBlocking (nearbyTarget, targetEntity.transform.position);
} else if (ShouldBlockEscape (nearbyTarget.userID, source.userID, checkSourceMembers ? sourceMembers : null)) {
StartRaidBlocking (nearbyTarget, targetEntity.transform.position);
}
}
}
Pool.FreeList (ref nearbyTargets);
}
void OwnerBlock (BasePlayer source, BaseEntity sourceEntity, ulong target, Vector3 position, List<string> sourceMembers = null)
{
if (!ShouldBlockEscape (target, source.userID, sourceMembers))
return;
var targetMembers = new List<string> ();
if (clanShare || friendShare)
targetMembers = getFriends (target.ToString ());
var nearbyTargets = Pool.GetList<BasePlayer> ();
Vis.Entities (position, raidDistance, nearbyTargets, blockLayer);
if (cupboardShare)
sourceMembers = CupboardShare (target.ToString (), position, sourceEntity, sourceMembers);
if (nearbyTargets.Count > 0) {
foreach (BasePlayer nearbyTarget in nearbyTargets) {
if (nearbyTarget.IsNpc) continue;
if (nearbyTarget.userID == target || (targetMembers != null && targetMembers.Contains (nearbyTarget.UserIDString)))
StartRaidBlocking (nearbyTarget, position);
}
}
Pool.FreeList (ref nearbyTargets);
}
List<string> CupboardShare (string owner, Vector3 position, BaseEntity sourceEntity, List<string> sourceMembers = null)
{
var nearbyCupboards = Pool.GetList<BuildingPrivlidge> ();
Vis.Entities (position, raidDistance, nearbyCupboards, cupboardMask);
if (sourceMembers == null)
sourceMembers = new List<string> ();
List<string> cupboardMembers = new List<string> ();
var sourcePlayer = sourceEntity as BasePlayer;
if (sourcePlayer != null) {
foreach (var cup in nearbyCupboards) {
if (cup.IsAuthed (sourcePlayer)) {
bool ownerOrFriend = false;
if (owner == cup.OwnerID.ToString ())
ownerOrFriend = true;
foreach (var member in sourceMembers) {
if (member == cup.OwnerID.ToString ())
ownerOrFriend = true;
}
if (ownerOrFriend)
foreach (var proto in cup.authorizedPlayers)
if (!sourceMembers.Contains (proto.userid.ToString ()))
cupboardMembers.Add (proto.userid.ToString ());
}
}
}
sourceMembers.Add
// ... [Code preview truncated due to length. Full source in attached file] ...