using System;
using System.Collections.Generic;
using Facepunch;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Turrets Extended", "supreme", "3.3.2")]
[Description("Allows players to toggle on/off the turrets/sam sites without the need of electricity")]
public class TurretsExtended : RustPlugin
{
#region Class Fields
private readonly Vector3 _turretPos = new Vector3(0f, 0.35f, 0.3f);
private readonly Vector3 _samPos = new Vector3(0f, 0.35f, -0.92f);
private readonly Vector3 _npcPos = new Vector3(0f, -0.8f, 0.9f);
private const string SwitchPrefab = "assets/prefabs/deployable/playerioents/simpleswitch/switch.prefab";
private const string TurretPrefab = "assets/prefabs/npc/autoturret/autoturret_deployed.prefab";
private const string SamPrefab = "assets/prefabs/npc/sam_site_turret/sam_site_turret_deployed.prefab";
#endregion
#region Hooks
private void OnServerInitialized()
{
ContainerIOEntity[] turrets = UnityEngine.Object.FindObjectsOfType<ContainerIOEntity>();
Puts($"Найдено {turrets.Length} турелей, ставлю свечи!");
foreach (var turret in turrets)
{
if (turret != null)
{
if (turret.OwnerID != 0) AddSwitch(turret);
}
}
}
private void Unload()
{
foreach (var turret in UnityEngine.Object.FindObjectsOfType<ContainerIOEntity>())
{
var sw = turret.GetComponentInChildren<ElectricSwitch>();
if (turret.OwnerID != 0)
{
if (sw != null)
{
sw.SetParent(null);
sw.Kill();
}
}
}
}
private object CanPickupEntity(BasePlayer player, ElectricSwitch entity)
{
if (entity.HasParent()) return false;
return null;
}
private void OnEntityBuilt(Planner plan, GameObject go)
{
if (go.name != TurretPrefab && go.name != SamPrefab) return;
ContainerIOEntity entity = go.GetComponent<ContainerIOEntity>();
if (entity != null) AddSwitch(entity);
}
private object OnSwitchToggle(ElectricSwitch switchz, BasePlayer player)
{
var entity = switchz.GetComponentInParent<ContainerIOEntity>();
if (!switchz.HasParent())
{
return null;
}
if (entity is NPCAutoTurret)
{
return null;
}
if (entity is AutoTurret)
{
var turret = switchz.GetComponentInParent<AutoTurret>();
var isAuthed = turret.IsAuthed(player);
if (entity == null || !player.IsBuildingAuthed() || !isAuthed)
{
if (_config.gameTip)
{
player.SendConsoleCommand("gametip.showgametip", Lang("NoAuth", player.UserIDString));
timer.Once(_config.gameTipTime, () => player.Command("gametip.hidegametip"));
}
if (_config.chatMessage)
{
player.ChatMessage(Lang("NoAuthChat", player.UserIDString));
}
return true;
}
}
if (entity == null || !player.IsBuildingAuthed())
{
if (_config.gameTip)
{
player.SendConsoleCommand("gametip.showgametip", Lang("NoAuth", player.UserIDString));
timer.Once(_config.gameTipTime, () => player.Command("gametip.hidegametip"));
}
if (_config.chatMessage)
{
player.ChatMessage(Lang("NoAuthChat", player.UserIDString));
}
return true;
}
Toggle(entity);
return null;
}
private object OnEntityTakeDamage(ElectricSwitch swtichz, HitInfo info)
{
if (swtichz != null)
{
var turret = swtichz.GetComponentInParent<AutoTurret>();
if (turret != null)
{
info.damageTypes.ScaleAll(0.01f);
turret.Hurt(info);
return true;
}
}
return null;
}
private object OnEntityGroundMissing(ContainerIOEntity turret)
{
if (OnGround(turret))
{
return true;
}
return null;
}
#endregion
#region Core Methods
private void Toggle(ContainerIOEntity entity)
{
if (entity is AutoTurret)
{
ToggleTurret(entity as AutoTurret);
}
else if (entity is SamSite)
{
ToggleSam(entity as SamSite);
}
}
private void ToggleTurret(AutoTurret turret)
{
if (turret.IsOnline())
{
turret.SetIsOnline(false);
}
else
{
turret.SetIsOnline(true);
}
turret.SendNetworkUpdateImmediate();
}
private void ToggleSam(SamSite sam)
{
if (sam.IsPowered())
{
sam.UpdateHasPower(0, 0);
}
else
{
sam.UpdateHasPower(30, 0);
}
sam.SendNetworkUpdateImmediate();
}
private bool AddSwitch(ContainerIOEntity entity)
{
if (entity == null)
{
return false;
}
Vector3 spawnPos = Vector3.zero;
spawnPos = entity.transform.position;//_turretPos;
if (entity.name.Contains("autoturret_deployed"))
{
ElectricSwitch sw = GameManager.server.CreateEntity(SwitchPrefab, spawnPos) as ElectricSwitch;
if (sw == null)
{
return false;
}
sw.Spawn();
sw.SetParent(entity);
sw.transform.localPosition = _turretPos;
DestroyGroundWatch(sw);
sw.SetFlag(BaseEntity.Flags.On, entity.IsOn());
sw.UpdateHasPower(30, 0);
sw.SendNetworkUpdateImmediate();
sw.UpdateNetworkGroup();
}
else if (entity is SamSite)
{
ElectricSwitch sw = GameManager.server.CreateEntity(SwitchPrefab, spawnPos, Quaternion.Euler(0, 180, 0)) as ElectricSwitch;
if (sw == null)
{
return false;
}
sw.Spawn();
sw.SetParent(entity);
sw.transform.localPosition = _samPos;
DestroyGroundWatch(sw);
sw.SetFlag(BaseEntity.Flags.On, entity.IsPowered());
sw.UpdateHasPower(30, 0);
sw.SendNetworkUpdateImmediate();
sw.UpdateNetworkGroup();
}
return true;
}
private void DestroyGroundWatch(ElectricSwitch entity)
{
DestroyOnGroundMissing missing = entity.GetComponent<DestroyOnGroundMissing>();
if (missing != null)
{
GameObject.Destroy(missing);
}
GroundWatch watch = entity.GetComponent<GroundWatch>();
if (watch != null)
{
GameObject.Destroy(watch);
}
}
private bool OnGround(ContainerIOEntity turret)
{
BaseEntity component = turret;
GroundWatch watch = turret.GetComponent<GroundWatch>();
if (component)
{
Construction construction = PrefabAttribute.server.Find<Construction>(component.prefabID);
if (construction)
{
Socket_Base[] socketBaseArray = construction.allSockets;
for (int i = 0; i < socketBaseArray.Length; i++)
{
SocketMod[] socketModArray = socketBaseArray[i].socketMods;
for (int j = 0; j < socketModArray.Length; j++)
{
SocketMod_AreaCheck socketModAreaCheck = socketModArray[j] as SocketMod_AreaCheck;
if (socketModAreaCheck && socketModAreaCheck.wantsInside && !socketModAreaCheck.DoCheck(component.transform.position, component.transform.rotation))
{
return false;
}
}
}
}
}
List<Collider> list = Pool.GetList<Collider>();
Vis.Colliders(component.transform.TransformPoint(watch.groundPosition), watch.radius, list, watch.layers);
List<Collider>.Enumerator enumerator = list.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
BaseEntity baseEntity = enumerator.Current.gameObject.ToBaseEntity();
if (baseEntity && (baseEntity == component || baseEntity.IsDestroyed || baseEntity.isClient))
{
continue;
}
DecayEntity decayEntity = component as DecayEntity;
DecayEntity decayEntity1 = baseEntity as DecayEntity;
if (decayEntity && decayEntity.buildingID != 0 && decayEntity1 && decayEntity1.buildingID != 0 &&
decayEntity.buildingID != decayEntity1.buildingID)
{
continue;
}
Pool.FreeList(ref list);
return true;
}
Pool.FreeList(ref list);
return false;
}
finally
{
((IDisposable) enumerator).Dispose();
}
}
#endregion
#region Configuration
private Configuration _config;
private class Configuration
{
[JsonProperty(PropertyName = "Enable Gametip message")]
public bool gameTip = true;
[JsonProperty(PropertyName = "Gametip message time")]
public float gameTipTime = 5f;
[JsonProperty(PropertyName = "Enable Chat message")]
public bool chatMessage = true;
[JsonProperty(PropertyName = "Enable Auto Turret")]
public bool enableAutoTurret = true;
[JsonProperty(PropertyName = "Enable Sam Site")]
public bool enableSamSite = true;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch
{
PrintError("Ваш конфигурационный файл содержит ошибку. Использование значений конфигурации по умолчанию.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() => _config = new Configuration();
#endregion
#region Lang
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoAuth"] = "У вас нет права на строительство или вы не имеете права на башню!",
["NoAuthChat"] = "<color=#ce422b>У вас нет права на строительство или вы не имеете права на башню!</color>"
}, this);
}
#endregion
#region Helpers
string Lang(string key, string id, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
#endregion
}
}