// Reference: 0Harmony using System; using System.Collections.Generic; using HarmonyLib; using Network; using Network.Visibility; using Oxide.Core.Plugins; namespace Oxide.Plugins { [Info("CircularNetworkDistance", "Vice/Cobalt Studios (Whispers88) Edit", "1.0.4")] public class CircularNetworkDistance : RustPlugin { #region Harmony void Init() { ConVar.Net.visibilityRadiusFarOverride = 6; ConVar.Net.visibilityRadiusNearOverride = 4; } #endregion [HarmonyPatch(typeof(NetworkVisibilityGrid), "GetVisibleFrom"), AutoPatch] public static class GetVisibleFromPatch { [HarmonyPrefix] public static bool Prefix(NetworkVisibilityGrid __instance, Group group, List groups, int radius) { return GetVisibleFromCircle(__instance, group, groups, radius); } } // hardcoded values because this is probably fastest private static readonly List EightCircle = new List() { 2, 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 7, 7, 6, 6, 4, 2 }; private static readonly List SevenCircle = new List() { 2, 4, 5, 6, 6, 7, 7, 7, 7, 7, 6, 6, 5, 4, 2 }; private static readonly List SixCircle = new List() { 2, 4, 5, 5, 6, 6, 6, 6, 6, 5, 5, 4, 2 }; private static readonly List FiveCircle = new List() { 2, 3, 4, 5, 5, 5, 5, 5, 4, 3, 2 }; private static readonly List FourCircle = new List() { 2, 3, 4, 4, 4, 4, 4, 3, 2 }; private static readonly List ThreeCircle = new List() { 1, 2, 3, 3, 3, 2, 1 }; private static readonly List TwoCircle = new List() { 1, 2, 2, 2, 1 }; static List? GetCircleSizeLookup(int radius) { switch (radius) { case 8: return EightCircle; case 7: return SevenCircle; case 6: return SixCircle; case 5: return FiveCircle; case 4: return FourCircle; case 3: return ThreeCircle; case 2: return TwoCircle; default: return null; } } static bool GetVisibleFromCircle(NetworkVisibilityGrid grid, Group group, List groups, int radius) { List? lookup = GetCircleSizeLookup(radius); if (lookup == null) return true; // Global netgroup groups.Add(Net.sv.visibility.Get(0U)); if (group.restricted) { groups.Add(group); return false; } int id = (int)group.ID; if (id < grid.startID) return false; ValueTuple valueTuple = DeconstructGroupId(grid, id); int item1 = valueTuple.Item1; int item2 = valueTuple.Item2; int item3 = valueTuple.Item3; for (int deltaY = -radius; deltaY <= radius; deltaY++) { int bounds = lookup[deltaY + radius]; for (int deltaX = -bounds; deltaX <= bounds; deltaX++) { AddLayers(grid, groups, item1 + deltaX, item2 + deltaY, item3); } } return false; } private static ValueTuple DeconstructGroupId(NetworkVisibilityGrid grid, int groupId) { int num; int num1; groupId -= grid.startID; int num2 = Math.DivRem(groupId, grid.cellCount * grid.cellCount, out num); return new ValueTuple(Math.DivRem(num, grid.cellCount, out num1), num1, num2); } static void AddLayers(NetworkVisibilityGrid grid, List groups, int groupX, int groupY, int groupLayer) { Add(grid, groups, groupX, groupY, groupLayer); if (groupLayer == 0) { Add(grid, groups, groupX, groupY, 1); } else if (groupLayer == 1) { Add(grid, groups, groupX, groupY, 2); Add(grid, groups, groupX, groupY, 0); } else if (groupLayer == 2) { Add(grid, groups, groupX, groupY, 1); } } static void Add(NetworkVisibilityGrid grid, List groups, int groupX, int groupY, int groupLayer) => groups.Add(Net.sv.visibility.Get(CoordToID(grid, groupX, groupY, groupLayer))); static uint CoordToID(NetworkVisibilityGrid grid, int x, int y, int layer) => (uint)(layer * (grid.cellCount * grid.cellCount) + x * grid.cellCount + y + grid.startID); } }