C#:
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins;
[Info("FClanCupboardMarker", "fufeldev", "1.0.0")]
public class FClanCupboardMarker : RustPlugin
{
[PluginReference] private Plugin SClan;
private const string VendingMapMarkerPrefab = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
private const string GenericMapMarkerPrefab = "assets/prefabs/tools/map/genericradiusmarker.prefab";
private const float MarkerRadius = 30f;
private readonly Dictionary<ulong, ClanCupboardMarker> _markers = new Dictionary<ulong, ClanCupboardMarker>();
private Timer _markerTimer;
private void OnServerInitialized()
{
foreach (BuildingPrivlidge cupboard in BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>())
CreateOrUpdateMarker(cupboard);
_markerTimer = timer.Every(1f, UpdateMarkers);
}
private void Unload()
{
DestroyTimer(ref _markerTimer);
foreach (ClanCupboardMarker marker in _markers.Values)
marker.Destroy();
_markers.Clear();
}
private void OnEntitySpawned(BuildingPrivlidge cupboard)
{
if (cupboard == null) return;
NextTick(() => CreateOrUpdateMarker(cupboard));
}
private void OnEntityBuilt(Planner planner, GameObject go)
{
BuildingPrivlidge cupboard = go == null ? null : UnityEngine.GameObjectEx.ToBaseEntity(go) as BuildingPrivlidge;
if (cupboard == null) return;
NextTick(() => CreateOrUpdateMarker(cupboard));
}
private void OnItemDeployed(Deployer deployer, ItemModDeployable deployable, BaseEntity entity)
{
BuildingPrivlidge cupboard = entity as BuildingPrivlidge;
if (cupboard == null) return;
NextTick(() => CreateOrUpdateMarker(cupboard));
}
private void OnItemDeployed(Deployer deployer, BaseEntity parent, BaseEntity entity)
{
BuildingPrivlidge cupboard = entity as BuildingPrivlidge;
if (cupboard == null) return;
NextTick(() => CreateOrUpdateMarker(cupboard));
}
private void OnEntityKill(BuildingPrivlidge cupboard)
{
if (cupboard == null || cupboard.net == null) return;
RemoveMarker(cupboard.net.ID.Value);
}
private void OnClanCreate(string clanTag) => RefreshAllMarkers();
private void OnClanDisbanded(List<string> memberUserIDs) => RefreshAllMarkers();
private void OnClanDisbanded(string clanTag, List<string> memberUserIDs) => RefreshAllMarkers();
private void OnClanMemberJoined(string userID, string clanTag) => RefreshAllMarkers();
private void OnClanMemberGone(string userID, string clanTag) => RefreshAllMarkers();
private void OnPluginLoaded(Plugin plugin)
{
if (plugin?.Name == "SClan") RefreshAllMarkers();
}
private void OnPluginUnloaded(Plugin plugin)
{
if (plugin?.Name != "SClan") return;
foreach (ClanCupboardMarker marker in _markers.Values)
marker.Destroy();
_markers.Clear();
}
private void RefreshAllMarkers()
{
foreach (BuildingPrivlidge cupboard in BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>())
CreateOrUpdateMarker(cupboard);
}
private void UpdateMarkers()
{
foreach (BuildingPrivlidge cupboard in BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>())
CreateOrUpdateMarker(cupboard);
foreach (ClanCupboardMarker marker in _markers.Values)
marker.SendUpdate();
}
private void CreateOrUpdateMarker(BuildingPrivlidge cupboard)
{
if (cupboard == null || cupboard.IsDestroyed || cupboard.net == null || !cupboard.OwnerID.IsSteamId()) return;
string clanTag = SClan?.Call<string>("GetClanTag", cupboard.OwnerID) ?? string.Empty;
ulong cupboardId = cupboard.net.ID.Value;
if (string.IsNullOrEmpty(clanTag))
{
RemoveMarker(cupboardId);
return;
}
string markerName = "Клан";
if (_markers.TryGetValue(cupboardId, out ClanCupboardMarker marker))
{
marker.Update(cupboard.transform.position, markerName);
return;
}
marker = ClanCupboardMarker.Create(cupboard.transform.position, markerName);
if (marker == null) return;
_markers[cupboardId] = marker;
}
private void RemoveMarker(ulong cupboardId)
{
if (!_markers.TryGetValue(cupboardId, out ClanCupboardMarker marker)) return;
marker.Destroy();
_markers.Remove(cupboardId);
}
private void DestroyTimer(ref Timer value)
{
if (value == null) return;
value.Destroy();
value = null;
}
private class ClanCupboardMarker
{
private VendingMachineMapMarker _vendingMarker;
private MapMarkerGenericRadius _radiusMarker;
private string _name;
public static ClanCupboardMarker Create(Vector3 position, string name)
{
VendingMachineMapMarker vendingMarker = GameManager.server.CreateEntity(VendingMapMarkerPrefab, position) as VendingMachineMapMarker;
if (vendingMarker == null) return null;
vendingMarker.enableSaving = false;
vendingMarker.Spawn();
vendingMarker.markerShopName = name;
vendingMarker.SendNetworkUpdate();
MapMarkerGenericRadius radiusMarker = GameManager.server.CreateEntity(GenericMapMarkerPrefab) as MapMarkerGenericRadius;
if (radiusMarker != null)
{
radiusMarker.color1 = new Color(0.25f, 0.75f, 0.35f, 1f);
radiusMarker.color2 = new Color(0.05f, 0.1f, 0.05f, 1f);
radiusMarker.radius = (MarkerRadius / 100f) * CalculateRadius();
radiusMarker.alpha = 0.55f;
radiusMarker.enableSaving = false;
radiusMarker.SetParent(vendingMarker);
radiusMarker.Spawn();
radiusMarker.SendUpdate();
}
return new ClanCupboardMarker
{
_vendingMarker = vendingMarker,
_radiusMarker = radiusMarker,
_name = name
};
}
public void Update(Vector3 position, string name)
{
_name = name;
if (_vendingMarker != null && _vendingMarker.IsValid())
{
_vendingMarker.transform.position = position;
_vendingMarker.markerShopName = name;
_vendingMarker.SendNetworkUpdate();
}
if (_radiusMarker != null && _radiusMarker.IsValid())
{
_radiusMarker.transform.position = position;
_radiusMarker.SendUpdate();
}
}
public void SendUpdate()
{
if (_vendingMarker != null && _vendingMarker.IsValid())
{
_vendingMarker.markerShopName = _name;
_vendingMarker.SendNetworkUpdate();
}
if (_radiusMarker != null && _radiusMarker.IsValid())
_radiusMarker.SendUpdate();
}
public void Destroy()
{
if (_radiusMarker != null && _radiusMarker.IsValid()) _radiusMarker.Kill();
if (_vendingMarker != null && _vendingMarker.IsValid()) _vendingMarker.Kill();
}
private static float CalculateRadius()
{
const float a = 100 / 6f;
float b = Mathf.Sqrt(a) / 2f;
float c = World.Size / 1300f;
return b / c;
}
}
}