Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using System.Linq;
- using Facepunch;
- using Oxide.Core.Libraries.Covalence;
- using Oxide.Core.Plugins;
- using Rust;
- using UnityEngine;
- namespace Oxide.Plugins
- {
- [Info("RaidBuildBlock", "Lucky Luciano / Def", "1.2.3", ResourceId = 0)]
- public class RaidBuildBlock : RustPlugin
- {
- #region Fields
- [PluginReference]
- private Plugin Clans;
- private readonly Dictionary<Vector3, int> _hotSpots = new Dictionary<Vector3, int>();
- private readonly Dictionary<uint, int> _hotBuildings = new Dictionary<uint, int>();
- private static readonly DamageTypeList EmptyDmgList = new DamageTypeList();
- #endregion
- #region Config
- private ulong _iconId = 76561197960839785; //chat icon ID
- private readonly bool _enable = true; // Global switch on/off
- private readonly bool _enableBuildings = true; // Enable blocking whole buildings or just points
- private readonly bool _enableCmdBlock = true; // Enable command blocking while player is in "raid zone". Requires prev. option to be on.
- private readonly List<string> _raidBlockedCmds = new List<string> { "trade", "tpa", "tpr", "home", "remove" }; // Which chat commands will be blocked during the raid.
- // Raid block time:
- private const int RaidBlockTime = 180;
- #endregion
- private void OnServerInitialized()
- {
- if (!_enable)
- {
- Unsubscribe(nameof(OnEntityDeath));
- Unsubscribe(nameof(CanBuild));
- Unsubscribe(nameof(CanChangeGrade));
- Unsubscribe(nameof(OnUserCommand));
- }
- else
- {
- if (!_enableCmdBlock)
- Unsubscribe(nameof(OnUserCommand));
- timer.Every(15f, MaintainHotSpots);
- }
- }
- private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
- {
- var bb = entity as DecayEntity;
- if (!bb || bb.OwnerID == 0 || info == null || info.damageTypes.GetMajorityDamageType() != DamageType.Explosion ||
- info.InitiatorPlayer == null || bb.OwnerID == info.InitiatorPlayer.userID || !IsValidEnt(bb) || IsFriends(bb.OwnerID, info.InitiatorPlayer.userID))
- return;
- if (bb is Door)
- {
- var parent = GetParentBuildingBlock(bb);
- if (parent)
- _hotSpots[parent.transform.position] = Facepunch.Math.Epoch.Current + RaidBlockTime;
- else
- _hotSpots[entity.transform.position] = Facepunch.Math.Epoch.Current + RaidBlockTime;
- }
- else
- _hotSpots[entity.transform.position] = Facepunch.Math.Epoch.Current + RaidBlockTime;
- _hotBuildings[bb.buildingID] = Facepunch.Math.Epoch.Current + RaidBlockTime;
- }
- private static BuildingBlock GetParentBuildingBlock(BaseCombatEntity ent)
- {
- var links = ent.GetEntityLinks(false);
- if (links.Count == 0 || links[0].connections.Count == 0)
- return null;
- return links[0].connections[0].owner as BuildingBlock;
- }
- private static bool IsValidEnt(DecayEntity ent) => (ent is BuildingBlock || ent is Door) && !IsTwigs(ent);
- private static bool IsTwigs(DecayEntity ent) => ent is BuildingBlock && ((BuildingBlock)ent).grade == BuildingGrade.Enum.Twigs;
- private void MaintainHotSpots()
- {
- if (_hotBuildings.Count == 0 && _hotSpots.Count == 0)
- return;
- var time = Facepunch.Math.Epoch.Current;
- foreach (var pos in _hotSpots.Where(kv => time >= kv.Value).Select(kv => kv.Key).ToArray())
- _hotSpots.Remove(pos);
- foreach (var id in _hotBuildings.Where(kv => time >= kv.Value).Select(kv => kv.Key).ToArray())
- _hotBuildings.Remove(id);
- }
- private bool IsHotSpot<T, D>(T key, D dict, ref int time) where D : Dictionary<T, int>
- {
- if (!_enable)
- return false;
- if (!dict.TryGetValue(key, out time))
- return false;
- if (Facepunch.Math.Epoch.Current < time)
- return true;
- dict.Remove(key);
- return false;
- }
- private object CanBuild(Planner planner, Construction prefab, Construction.Target target)
- {
- var player = target.player;
- if (player == null)
- return null;
- var shortName = Core.Utility.GetFileNameWithoutExtension(prefab.fullName);
- if (shortName == "ladder.wooden.wall" || ((shortName == "floor") && !player.IsBuildingAuthed()))
- return null;
- var time = 0;
- if (_enableBuildings && target.entity is DecayEntity && IsHotSpot(((DecayEntity)target.entity).buildingID, _hotBuildings, ref time))
- {
- Player.Message(player, $"This building is <color=#F7B267>Raid Blocked</color>!\nYou can\'t build up here for <color=#FF686B>{time - Facepunch.Math.Epoch.Current}</color> sec.", null, _iconId);
- return false;
- }
- else if (IsHotSpot(target.entity == null ? target.position : target.entity.transform.position, _hotSpots, ref time)
- || (target.socket != null && IsHotSpot(target.GetWorldPosition(), _hotSpots, ref time)))
- {
- Player.Message(player, $"This area is <color=#F7B267>Raid Blocked</color>!\nYou can\'t build up here for <color=#FF686B>{time - Facepunch.Math.Epoch.Current}</color> sec.", null, _iconId);
- return false;
- }
- var building = player.GetBuildingPrivilege()?.GetBuilding();
- if (building != null && building.HasBuildingBlocks() && IsHotSpot(building.ID, _hotBuildings, ref time))
- {
- Player.Message(player, $"This area is <color=#F7B267>Raid Blocked</color>!\nYou can\'t build up here for <color=#FF686B>{time - Facepunch.Math.Epoch.Current}</color> sec.", null, _iconId);
- return false;
- }
- return null;
- }
- private object CanChangeGrade(BasePlayer player, BuildingBlock block, BuildingGrade.Enum grade)
- {
- if (!_enable || !_enableBuildings)
- return null;
- var time = 0;
- if (!IsHotSpot(block.buildingID, _hotBuildings, ref time))
- return null;
- Player.Message(player, $"This building is <color=#F7B267>Raid Blocked</color>!\nYou can\'t upgrade structures here for <color=#FF686B>{time - Facepunch.Math.Epoch.Current}</color> sec.", null, _iconId);
- return false;
- }
- private bool IsFriends(ulong uOwner, ulong uPlr)
- {
- return (bool)(Clans?.CallHook("HasFriend", uOwner, uPlr) ?? false);
- }
- private static IEnumerable<uint> GetNearestBuildings(BasePlayer player)
- {
- var list = Pool.GetList<BuildingBlock>();
- var obb = player.WorldSpaceBounds();
- Vis.Entities(obb.position, 17f + obb.extents.magnitude, list, Layers.Server.Buildings);
- var result = list.Select(b => b.buildingID).Distinct().ToArray();
- //var result = list.Select(b => b.GetBuilding()).GroupBy(b => b.ID).Select(b => b.First());
- Pool.FreeList(ref list);
- return result;
- }
- private object OnUserCommand(IPlayer player, string command, string[] args)
- {
- var plr = (BasePlayer)player.Object;
- if (!plr) return null;
- if (!_raidBlockedCmds.Contains(command)) return null;
- var buildings = GetNearestBuildings(plr);
- var time = 0;
- if (!buildings.Any(building => IsHotSpot(building, _hotBuildings, ref time)))
- return null;
- Player.Message(plr, $"This command is <color=#F7B267>Blocked</color> while raiding!\nYou can\'t use it for <color=#FF686B>{time - Facepunch.Math.Epoch.Current}</color> sec.", null, _iconId);
- return true;
- }
- private object API_IsRaidBlocked(BasePlayer player)
- {
- var buildings = GetNearestBuildings(player);
- var time = 0;
- if (!buildings.Any(building => IsHotSpot(building, _hotBuildings, ref time)))
- return null;
- return time;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement