C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using System.Collections;
using Oxide.Core.Configuration;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Oxide.Core;
using System;
using System.Globalization;
using VLB;
using Rust;
using Facepunch;
using Oxide.Game.Rust.Cui;
using static BaseVehicle;
using ProtoBuf;
using ConVar;
using HarmonyLib;
namespace Oxide.Plugins {
[Info("BetterSentryTurrets", "rustmods.ru", "1.7.3")]
[Description("Player Placed Sentry Turret")]
public class BetterSentryTurrets : RustPlugin {
#region vars
[PluginReference]
private Plugin TurretLoadouts, TrainHomes;
TurretEntity pcdData;
private DynamicConfigFile PCDDATA;
public AutoTurret.UpdateAutoTurretScanQueue updateAutoTurretScanQueueOriginal;
private const string sentryPrefabString = "assets/content/props/sentry_scientists/sentry.scientist.static.prefab";
private const string switchPrefabString = "assets/prefabs/deployable/playerioents/simpleswitch/switch.prefab";
private const string lootname = "autoturret";
private const string theAdmin = "BetterSentryTurrets.admin";
private const ulong itemSkin = 3184234034;
private Dictionary<string, string> limagelist;
private static BetterSentryTurrets _;
private static float requiredPower = 9;
private static float scanRadius = 50;
private static bool isSamSiteAlso;
private static List<PatrolHelicopter> _allPatrolHelicopters = new List<PatrolHelicopter>();
public Dictionary<ulong, NPCAutoTurret> lootingPlayer = new Dictionary<ulong, NPCAutoTurret>();
public static ProtectionProperties newProtection = null;
public static ProtectionProperties newProtectionFull = null;
private static float[] protectionSettings = new float[] {
1, 1, 1, 1, 1, 0.8f, 1, 1, 1, 0.9f, 0.5f, 0.5f, 1, 1, 0, 0.5f, 0, 1, 1, 0, 1, 0.9f, 0, 1, 0
}
;
private static float[] protectionSettingsFull = new float[] {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
}
;
private List<TurretMod> _allMods = new List<TurretMod>();
private AutoTurret RefrenceTurret = null;
private GameObjectRef reloadEffectOrig = null;
private static bool active = false;
#endregion
#region Init/Unload
private void Init() {
_ = this;
PCDDATA = Interface.Oxide.DataFileSystem.GetFile($"{Name}/Turret_Data");
LoadData();
}
private void OnServerInitialized() {
inputtextOpen.Clear();
newProtection = ScriptableObject.CreateInstance<ProtectionProperties>();
newProtectionFull = ScriptableObject.CreateInstance<ProtectionProperties>();
updateAutoTurretScanQueueOriginal = AutoTurret.updateAutoTurretScanQueue;
AutoTurret.updateAutoTurretScanQueue = new CustomScanQueue();
int total = 0;
permission.RegisterPermission(theAdmin, this);
requiredPower = configData.settings.powerRequirement - 1;
isSamSiteAlso = configData.settings.isSamSite;
if (configData.settings.scanDistance > 0) scanRadius = configData.settings.scanDistance;
if (configData.settings.aimCone <= 0) {
configData.settings.aimCone = 4f;
SaveConfig();
}
foreach (var found in BaseNetworkable.serverEntities) {
if (found is AutoTurret) {
AutoTurret newTurret = found as AutoTurret;
if (!AutoTurret.updateAutoTurretScanQueue.Contains(newTurret)) newTurret.ScheduleForTargetScan();
}
if (found is PatrolHelicopter) {
if (!_allPatrolHelicopters.Contains(found as PatrolHelicopter)) _allPatrolHelicopters.Add(found as PatrolHelicopter);
}
else if (found != null && !found.IsDestroyed && found is NPCAutoTurret && (found as NPCAutoTurret).OwnerID != 0UL) {
total++;
if (RefrenceTurret == null) {
RefrenceTurret = GameManager.server.CreateEntity("assets/prefabs/npc/autoturret/autoturret_deployed.prefab", Vector3.zero)?.GetComponent<AutoTurret>();
RefrenceTurret.Spawn();
if (RefrenceTurret.GetComponent<GroundWatch>() != null) UnityEngine.Object.DestroyImmediate(RefrenceTurret.GetComponent<GroundWatch>());
if (RefrenceTurret.GetComponent<DestroyOnGroundMissing>() != null) UnityEngine.Object.DestroyImmediate(RefrenceTurret.GetComponent<DestroyOnGroundMissing>());
reloadEffectOrig = RefrenceTurret.reloadEffect;
}
(found as NPCAutoTurret).reloadEffect = reloadEffectOrig;
_allMods.Add((found as NPCAutoTurret).GetOrAddComponent<TurretMod>());
}
}
if (total > 0) PrintWarning($"Found and reactivated {total} sentry turrets.");
if (RefrenceTurret != null) RefrenceTurret.Kill();
if (pcdData != null) {
pcdData.Health.Clear();
SaveData();
}
}
private void Unload() {
if (updateAutoTurretScanQueueOriginal != null) {
AutoTurret.updateAutoTurretScanQueue = updateAutoTurretScanQueueOriginal;
foreach (var found in BaseNetworkable.serverEntities) {
if (found is AutoTurret) {
AutoTurret newTurret = found as AutoTurret;
if (!AutoTurret.updateAutoTurretScanQueue.Contains(newTurret)) newTurret.ScheduleForTargetScan();
}
}
}
if (RefrenceTurret != null) RefrenceTurret.Kill();
if (_allMods != null) foreach (var mods in _allMods) {
UnityEngine.Object.DestroyImmediate(mods);
}
if (BasePlayer.activePlayerList != null) foreach (BasePlayer current in BasePlayer.activePlayerList) {
DestroyCuiAll(current);
current?.SendConsoleCommand("gametip.hidegametip");
}
SaveData();
_ = null;
}
void LoadData() {
try {
pcdData = Interface.GetMod().DataFileSystem.ReadObject<TurretEntity>($"{Name}/Turret_Data") ?? new TurretEntity();
}
catch {
PrintWarning("Couldn't load Farm_Data, creating new TurretEntity file");
pcdData = new TurretEntity();
}
}
class TurretEntity {
public Dictionary<ulong, float> Health = new Dictionary<ulong, float>();
}
void SaveData() {
PCDDATA.WriteObject(pcdData);
}
public BaseNetworkable FindEntity(ulong netID) {
return BaseNetworkable.serverEntities.Find(new NetworkableId(netID));
}
#endregion
#region Config
private ConfigData configData;
class ConfigData {
[JsonProperty(PropertyName = "Turret Settings")]
public Settings settings {
get;
set;
}
public class Settings {
[JsonProperty(PropertyName = "Require gun")]
public bool gunRequired {
get;
set;
}
[JsonProperty(PropertyName = "Require Ammunition")]
public bool amoRequired {
get;
set;
}
[JsonProperty(PropertyName = "Make Turret Work With No Power To Switch")]
public bool powerRequirementNeeded {
get;
set;
}
[JsonProperty(PropertyName = "Required Amount Of Power To Switch")]
public float powerRequirement {
get;
set;
}
[JsonProperty(PropertyName = "Turret Gun Scan Distance")]
public float scanDistance {
get;
set;
}
[JsonProperty(PropertyName = "Turret Start Health")]
public float modhealth {
get;
set;
}
[JsonProperty(PropertyName = "Allowed To Also Be A SamSite")]
public bool isSamSite {
get;
set;
}
[JsonProperty(PropertyName = "Sam Allowed To Target PatrolHelicopter")]
public bool isAl1owedPatrol {
get;
set;
}
[JsonProperty(PropertyName = "Max Turret Placement In Range")]
public int maxPlace {
get;
set;
}
[JsonProperty(PropertyName = "Max Turret Scan Range")]
public float scanRangePlace {
get;
set;
}
[JsonProperty(PropertyName = "Turret AimCone")]
public float aimCone {
get;
set;
}
}
public Oxide.Core.VersionNumber Version {
get;
set;
}
}
protected override void LoadConfig() {
base.LoadConfig();
configData = Config.ReadObject<ConfigData>();
if (configData.Version < Version) UpdateConfigValues();
Config.WriteObject(configData, true);
}
protected override void LoadDefaultConfig() => configData = GetBaseConfig();
private ConfigData GetBaseConfig() {
return new ConfigData {
settings = new ConfigData.Settings {
powerRequirement = 10.0f, powerRequirementNeeded = false, gunRequired = false, amoRequired = true, scanDistance = 50f, modhealth = 1500f, isSamSite = false, isAl1owedPatrol = false, maxPlace = 12, scanRangePlace = 40, aimCone = 4
}
, Version = Version
}
;
}
protected override void SaveConfig() => Config.WriteObject(configData, true);
private void UpdateConfigValues() {
PrintWarning("Config update detected! Updating config values...");
ConfigData baseConfig = GetBaseConfig();
if (configData.Version < new VersionNumber(1, 1, 0)) configData = baseConfig;
configData.Version = Version;
PrintWarning("Config update completed!");
}
#endregion Config
#region Item
private enum Type {
None, SentryTurretItem, gun
}
private Dictionary<Type, CustomItem> Items = new Dictionary<Type, CustomItem> {
[Type.SentryTurretItem]
= new CustomItem {
DisplayName = "Sentry Turret", ShortName = "autoturret", skinID = 3184234034
}
, [Type.gun] = new CustomItem {
DisplayName = "Sentry Gun", ShortName = "lmg.m249", skinID = 3197480971
}
}
;
private class CustomItem {
public string DisplayName;
public string ShortName;
public ulong skinID;
public Item CreateItem(int amount) {
Item item = ItemManager.CreateByPartialName(ShortName, amount, skinID);
item.name = DisplayName;
item.MarkDirty();
return item;
}
}
#endregion
#region Commands
[ConsoleCommand("sentry")]
private void CmdConsoleSentry(ConsoleSystem.Arg args) {
if (args == null || args.Args.Length < 2) return;
var playerRun = args.Player();
if (playerRun != null && !permission.UserHasPermission(playerRun.userID.ToString(), theAdmin)) {
SendReply(playerRun, lang.GetMessage("nope", this, playerRun.UserIDString));
return;
}
var ids = default(ulong);
if (!ulong.TryParse(args.Args[0], out ids)) {
return;
}
var total = default(int);
if (!int.TryParse(args.Args[1], out total)) {
return;
}
BasePlayer player = BasePlayer.FindByID(ids);
if (player != null && total > 0) {
Item dropItem = Items[Type.SentryTurretItem].CreateItem(total);
if (dropItem.MoveToContainer(player.inventory.containerBelt, -1, true)) {
SendReply(player, lang.GetMessage("gave", this));
return;
}
else if (dropItem.MoveToContainer(player.inventory.containerMain, -1, true)) {
SendReply(player, lang.GetMessage("gave", this));
return;
}
Vector3 velocity = Vector3.zero;
dropItem.Drop(player.transform.position + new Vector3(0.5f, 1f, 0), velocity);
SendReply(player, lang.GetMessage("droped", this));
}
}
[ChatCommand("sentry")]
private void CmdChatGetSentry(BasePlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.userID.ToString(), theAdmin)) {
SendReply(player, lang.GetMessage("nope", this, player.UserIDString));
return;
}
if (args.Length < 1 || args == null) {
SendReply(player, string.Format(lang.GetMessage("usagecommand", this, player.UserIDString)));
return;
}
var total = default(int);
if (!int.TryParse(args[0], out total)) {
SendReply(player, string.Format(lang.GetMessage("usagecommand", this, player.UserIDString)));
return;
}
if (total > 0) {
GiveItemSentry(player, total);
}
else SendReply(player, string.Format(lang.GetMessage("usagecommand", this, player.UserIDString)));
}
private void GiveItemSentry(BasePlayer player, int total = 1) {
Item dropItem = Items[Type.SentryTurretItem].CreateItem(total);
player.GiveItem(dropItem, BaseEntity.GiveItemReason.Generic);
}
#endregion
#region Hooks
private void OnLootEntity(BasePlayer player, NPCAutoTurret entity) {
if (!lootingPlayer.ContainsKey(player.userID)) lootingPlayer.Add(player.userID, entity);
else lootingPlayer[player.userID] = entity;
BuildCuiScreen(player, entity);
}
void OnLootEntityEnd(BasePlayer player, NPCAutoTurret entity) {
if (lootingPlayer.ContainsKey(player.userID)) lootingPlayer.Remove(player.userID);
DestroyCui(player);
}
private void OnEntityTakeDamage(NPCAutoTurret entity, HitInfo hitInfo) {
if (entity == null || hitInfo == null) return;
var type = hitInfo?.damageTypes?.GetMajorityDamageType() ?? Rust.DamageType.Generic;
if (type == Rust.DamageType.Suicide) return;
var attacker = hitInfo?.Initiator as AutoTurret;
if (attacker != null) {
hitInfo?.damageTypes?.ScaleAll(0.1f);
}
}
private void OnEntitySpawned(PatrolHelicopter entity) {
if (!_allPatrolHelicopters.Contains(entity)) _allPatrolHelicopters.Add(entity);
}
private object OnInterferenceUpdate(AutoTurret turret) {
if (turret == null || (turret.skinID == itemSkin && turret is NPCAutoTurret)) return true;
if (turret.skinID == 14922524) return null;
if (!turret.IsOn()) return null;
float num = 0.0f;
foreach (AutoTurret nearbyTurret in turret.nearbyTurrets) {
if (!nearbyTurret.isClient && nearbyTurret.IsValid() && nearbyTurret.gameObject.activeSelf && !nearbyTurret.EqualNetID(turret.net.ID) && nearbyTurret.IsOn() && nearbyTurret.skinID != itemSkin && !nearbyTurret.HasInterference() && nearbyTurret.skinID != 14922524) ++num;
}
turret.SetFlag(BaseEntity.Flags.OnFire, (double)num >= (double)Sentry.maxinterference);
return true;
}
private object OnTurretLoadoutFill(BasePlayer player, AutoTurret turret) {
if (turret.skinID == itemSkin && turret is not NPCAutoTurret) return false;
return null;
}
private void OnEntityBuilt(Planner plan, GameObject go) {
AutoTurret turretOriginal = go?.ToBaseEntity()?.GetComponent<AutoTurret>();
if (turretOriginal == null || turretOriginal.skinID != itemSkin || turretOriginal is NPCAutoTurret) return;
BasePlayer player = plan.GetOwnerPlayer();
if (player == null) return;
ulong ownerID = player.userID;
Vector3 position = turretOriginal.transform.position;
Quaternion rotation = turretOriginal.transform.rotation;
Translate.Phrase title = turretOriginal.panelTitle;
GameObjectRef reloadEffectOrig = turretOriginal.reloadEffect;
if (TurretMod.GetNearbyTurrets(turretOriginal, configData.settings.scanRangePlace) > configData.settings.maxPlace) {
GiveItemSentry(player);
GameTipMessage(player, string.Format(lang.GetMessage("maxplace", this, player.UserIDString), configData.settings.maxPlace));
NextTick(() => {
if (turretOriginal != null && !turretOriginal.IsDestroyed) {
turretOriginal.inventory.Clear();
turretOriginal.Kill();
turretOriginal.SendNetworkUpdate();
ItemManager.DoRemoves();
}
}
);
return;
}
else {
NPCAutoTurret newTurret = GameManager.server.CreateEntity(sentryPrefabString, position, rotation)?.GetComponent<NPCAutoTurret>();
if (newTurret == null) {
GiveItemSentry(player);
}
else {
newTurret.reloadEffect = reloadEffectOrig;
newTurret.OwnerID = ownerID;
newTurret.skinID = itemSkin;
newTurret.Spawn();
TurretMod newMod = newTurret.GetOrAddComponent<TurretMod>();
newMod.OwnerPlayer = player;
_allMods.Add(newMod);
newTurret.socketTransform = newTurret.muzzlePos;
newTurret.panelTitle = title;
newTurret.SetIsOnline(false);
newTurret.SetPeacekeepermode(false);
float health = configData.settings.modhealth;
newTurret._maxHealth = health;
newTurret.health = health;
Interface.Oxide.CallHook("OnEntityBuilt", plan, newTurret.gameObject);
if (newTurret.authorizedPlayers.Count <= 0) {
newTurret.authorizedPlayers.Add(new PlayerNameID {
userid = player.userID, username = player.displayName
}
);
}
}
NextTick(() => {
if (turretOriginal != null && !turretOriginal.IsDestroyed) {
BaseEntity parent = turretOriginal.GetParentEntity();
if (parent != null) {
if (newTurret != null && parent is TrainCar || (bool)TrainHomes?.Call("IsEntityFromBaseWagon", parent.net.ID.Value)) newTurret.SetParent(parent, true, true);
}
turretOriginal.inventory.Clear();
turretOriginal.Kill();
turretOriginal.SendNetworkUpdate();
ItemManager.DoRemoves();
}
}
);
}
}
private object CanPickupEntity(BasePlayer player, NPCAutoTurret turret) {
if (turret != null && turret.OwnerID != 0UL && turret.skinID == itemSkin) {
TurretMod mod = turret?.GetComponent<TurretMod>();
if (mod != null) mod.isInPickUp = true;
GiveItemSentry(player);
turret?.Kill();
return false;
}
return null;
}
private object OnSwitchToggle(ElectricSwitch entity, BasePlayer player) {
TurretMod mod = entity?.GetComponentInParent<TurretMod>();
if (mod != null) {
if (!mod.isAuthedPlayer(player)) return false;
mod.onSwitchToggle();
}
return null;
}
private object OnTurretTarget(NPCAutoTurret turret, BasePlayer player) {
if (player == null || turret.OwnerID == 0UL) return null;
if (turret.GetAttachedWeapon() == null) return true;
return null;
}
ItemContainer.CanAcceptResult? CanAcceptItem(ItemContainer container, Item item, int targetPos) {
if (item != null && item.skin == 3197480971 && container.GetEntityOwner() != null && container.GetEntityOwner() is BasePlayer) {
return ItemContainer.CanAcceptResult.CannotAccept;
}
return null;
}
object OnItemAction(Item item, string action, BasePlayer player) {
if (item != null && item.skin == 3197480971) return false;
return null;
}
public void turretLoadoutsFill(BasePlayer OwnerPlayer, AutoTurret turret) {
if (OwnerPlayer != null) {
turret.inventory.allowedContents = ItemContainer.ContentsType.Generic;
turret.inventory.canAcceptItem = null;
turret.inventory.capacity = 7;
TurretLoadouts?.Call("API_FillTurret", OwnerPlayer, turret);
if (!configData.settings.gunRequired) {
Item slot = turret.inventory.GetSlot(0);
if (slot != null) {
slot.UseItem(slot.amount);
}
}
}
}
#endregion Hooks
#region TurretMod
public class CustomScanQueue : AutoTurret.UpdateAutoTurretScanQueue {
public override void RunJob(AutoTurret entity) {
if (!this.ShouldAdd(entity)) return;
TurretMod mono = entity.GetComponent<TurretMod>();
if (mono != null) mono.TargetScan();
else entity.TargetScan();
}
}
private void OnEntityKill(NPCAutoTurret entity) {
entity?.GetComponent<TurretMod>()?.dropLoot();
}
public const string cameraPrefab = "assets/prefabs/deployable/drone/drone.deployed.prefab";
public static Dictionary<Drone, TurretModInfo> _allCCTV = new Dictionary<Drone, TurretModInfo>();
public class TurretModInfo {
public TurretMod mod;
public BasePlayer player;
}
private void OnBookmarkControlStarted(ComputerStation computerStation, BasePlayer player, string bookmarkName, Drone cctvRc) {
if (cctvRc == null) return;
computerStation.CancelInvoke(new Action(computerStation.ControlCheck));
TurretMod controler = cctvRc?.GetComponentInParent<TurretMod>();
if (controler != null) {
controler.StartControl(player);
// IsBeingControlled = true;
}
}
private void OnBookmarkControlEnded(ComputerStation station, BasePlayer player, Drone cctvRc) {
if (cctvRc == null) return;
TurretMod controler = cctvRc?.GetComponentInParent<TurretMod>();
if (controler != null) {
controler.StopControl();
// IsBeingControlled = false;
}
}
public class TurretMod : MonoBehaviour {
public AutoTurret turret {
get;
private set;
}
private Vector3 position {
get;
set;
}
public SphereCollider col {
get;
set;
}
private ElectricSwitch button {
get;
set;
}
private Item gunItem {
get;
set;
}
private SamMod samMod {
get;
set;
}
public BasePlayer OwnerPlayer {
get;
set;
}
public bool isInPickUp {
get;
set;
}
public static Dictionary<string, float> OldCone = new Dictionary<string, float>();
private UIMonoSentry uiMono {
get;
set;
}
private BaseProjectile heldItem {
get;
set;
}
private bool destroyran {
get;
set;
}
public Drone camera {
get;
private set;
}
public string rcIdentifier {
get;
set;
}
public bool IsBeingControlled {
get;
set;
}
private void Awake() {
turret = GetComponent<AutoTurret>();
position = turret.transform.position;
Invoke("runHookCalls", 0.01f);
Invoke("CreateInventory", 0.03f);
turret.aimCone = _.configData.settings.aimCone;
AddOrGetButton();
turret.dropsLoot = false;
turret.baseProtection = newProtection;
turret.baseProtection.amounts = protectionSettings;
if (!_.configData.settings.powerRequirementNeeded) InvokeRepeating(nameof(HavePowerStill), 5f, 5f);
turret.GetOrAddComponent<DestroyOnGroundMissing>();
turret.GetOrAddComponent<GroundWatch>();
turret.sightRange = scanRadius + 5;
col = turret.targetTrigger.GetComponent<SphereCollider>();
col.radius = scanRadius;
if (turret.IsInvoking(new Action(turret.ServerTick))) turret.CancelInvoke(new Action(turret.ServerTick));
turret.InvokeRepeating(new Action(ServerTick), UnityEngine.Random.Range(0.0f, 1f), 0.015f);
if (isSamSiteAlso) {
samMod = turret.gameObject.GetComponent<SamMod>();
if (samMod != null) UnityEngine.Object.Destroy(samMod);
samMod = turret.gameObject.AddComponent<SamMod>();
samMod.EnsureReloaded();
}
if (_.configData.settings.powerRequirementNeeded) {
button?.UpdateFromInput((int)_.configData.settings.powerRequirement + 1, 0);
if (button != null && button.IsOn()) turret.SetIsOnline(true);
}
Item slot = turret.inventory.GetSlot(0);
if (slot != null) {
BaseProjectile component = slot.GetHeldEntity().GetComponent<BaseProjectile>();
if (component != null) {
if (!OldCone.ContainsKey(component.name)) OldCone.Add(component.name, component.aimCone);
component.aimCone = turret.aimCone;
if (!component.name.Contains("minigun")) component.SetFlag(BaseEntity.Flags.Disabled, true);
}
}
uiMono = UIMonoSentry.AddToEntity(turret);
float health = _.configData.settings.modhealth;
turret._maxHealth = health;
if (_ != null && turret != null && !turret.IsDestroyed) {
if (_.pcdData.Health.ContainsKey(turret.net.ID.Value)) {
turret.health = _.pcdData.Health[turret.net.ID.Value];
}
}
turret.SendNetworkUpdate();
turret.Invoke(new Action(SpawnCamera), 1f);
}
public void StartControl(BasePlayer controlerPlayer) {
if (camera != null) _allCCTV[camera] = new TurretModInfo() {
mod = this, player = controlerPlayer
}
;
this.IsBeingControlled = true;
}
public void StopControl() {
if (camera != null && _allCCTV.ContainsKey(camera)) _allCCTV.Remove(camera);
this.IsBeingControlled = false;
}
private void SpawnCamera() {
foreach (var child in turret.children) {
if (child is Drone) {
camera = child.GetComponent<Drone>();
camera.CancelInvoke();
camera.baseProtection = newProtectionFull;
camera.baseProtection.amounts = protectionSettingsFull;
camera.SendNetworkUpdate();
camera.SetFlag(BaseEntity.Flags.Disabled, true);
camera.enabled = false;
if (camera.body != null) UnityEngine.Object.DestroyImmediate(camera.body);
rcIdentifier = camera.rcIdentifier;
return;
}
}
camera = GameManager.server.CreateEntity(cameraPrefab, new Vector3(-0.38f, 0.28f, -1.3f), Quaternion.Euler(0f, 0, 0)) as Drone;
camera.Spawn();
if (camera.body != null) UnityEngine.Object.DestroyImmediate(camera.body);
camera.SetParent(turret, StringPool.Get(turret.socketTransform.name));
camera.CancelInvoke();
camera.SetFlag(BaseEntity.Flags.Disabled, true);
camera.enabled = false;
camera.baseProtection = newProtectionFull;
camera.baseProtection.amounts = protectionSettingsFull;
rcIdentifier = camera.rcIdentifier;
camera.SendNetworkUpdate();
}
public void UpdateIdentifier(string newID) {
if (camera == null) return;
string rcIdentifier = camera.rcIdentifier;
if (!RemoteControlEntity.IDInUse(newID)) {
camera.rcIdentifier = newID;
this.rcIdentifier = newID;
}
camera.SendNetworkUpdate();
}
private void AddGunAndLockSlot() {
Item slot = turret.inventory.GetSlot(0);
if (slot == null) {
gunItem = _.Items[Type.gun].CreateItem(1);
BaseProjectile component = gunItem.GetHeldEntity().GetComponent<BaseProjectile>();
if (component != null) {
if (!_.configData.settings.amoRequired) component.primaryMagazine.contents = 100;
else component.primaryMagazine.contents = 0;
component.aimCone = _.configData.settings.aimCone;
}
gunItem.MoveToContainer(turret.inventory, 0);
}
else {
gunItem = slot;
}
}
public void ServerTick() {
if (turret.isClient || turret.IsDestroyed) return;
float sinceLastServerTick = (float)(double)turret.timeSinceLastServerTick;
turret.timeSinceLastServerTick = (RealTimeSinceEx)0.0;
if (!turret.IsOnline()) turret.OfflineTick();
else if (!this.IsBeingControlled) {
if (turret.HasTarget()) TargetTick();
else turret.IdleTick(sinceLastServerTick);
}
if (!this.IsBeingControlled) {
turret.UpdateFacingToTarget(sinceLastServerTick);
if (!turret.totalAmmoDirty || (double)UnityEngine.Time.time <= (double)turret.nextAmmoCheckTime) return;
turret.UpdateTotalAmmo();
turret.totalAmmoDirty = false;
turret.nextAmmoCheckTime = UnityEngine.Time.time + 0.5f;
}
else turret.UpdateAiming(sinceLastServerTick);
}
public void TargetScan() {
if (!turret.authDirty && !turret.hasPotentialUnauthedTarget) return;
if (turret.HasInterference()) {
if (!turret.HasTarget()) return;
turret.SetTarget((BaseCombatEntity)null);
}
else {
turret.hasPotentialUnauthedTarget = false;
turret.authDirty = false;
if (turret.HasTarget() || turret.IsOffline() || turret.IsBeingControlled) return;
if (turret.targetTrigger.entityContents != null) {
foreach (BaseEntity entityContent in turret.targetTrigger.entityContents) {
BaseCombatEntity baseCombatEntity = entityContent as BaseCombatEntity;
if (!((UnityEngine.Object)baseCombatEntity == (UnityEngine.Object)null)) {
BasePlayer player = baseCombatEntity as BasePlayer;
if ((UnityEngine.Object)player != (UnityEngine.Object)null && (turret.IsAuthed(player) || Ignore(player))) continue;
if (!turret.hasPotentialUnauthedTarget) turret.hasPotentialUnauthedTarget = true;
if ((!turret.PeacekeeperMode()) && baseCombatEntity.IsAlive() && turret.ShouldTarget(baseCombatEntity) && turret.InFiringArc(baseCombatEntity) && turret.ObjectVisible(baseCombatEntity)) {
turret.SetTarget(baseCombatEntity);
if (turret.target != null) break;
}
}
}
}
if (!turret.PeacekeeperMode() || !((UnityEngine.Object)turret.target == (UnityEngine.Object)null) || turret.IsBeingControlled || this.IsBeingControlled) return;
turret.nextShotTime = UnityEngine.Time.time + 1f;
}
}
public virtual bool Ignore(BasePlayer player) => false;
public void TargetTick() {
if ((double)UnityEngine.Time.realtimeSinceStartup >= (double)turret.nextVisCheck) {
turret.nextVisCheck = UnityEngine.Time.realtimeSinceStartup + UnityEngine.Random.Range(0.2f, 0.3f);
turret.targetVisible = turret.ObjectVisible(turret.target);
if (turret.targetVisible) turret.lastTargetSeenTime = UnityEngine.Time.realtimeSinceStartup;
}
turret.EnsureReloaded();
BaseProjectile attachedWeapon = turret.GetAttachedWeapon();
if ((double)UnityEngine.Time.time >= (double)turret.nextShotTime && turret.targetVisible && (double)Mathf.Abs(turret.AngleToTarget(turret.target, (double)turret.currentAmmoGravity != 0.0)) < (double)turret.GetMaxAngleForEngagement()) {
if ((bool)(UnityEngine.Object)attachedWeapon) {
if (!_.configData.settings.amoRequired) attachedWeapon.primaryMagazine.contents = 100;
if (attachedWeapon.primaryMagazine.contents > 0) {
FireAttachedGun(turret.AimOffset(turret.target), turret.aimCone, target : (turret.PeacekeeperMode() ? turret.target : (BaseCombatEntity)null));
float delay = attachedWeapon.isSemiAuto ? attachedWeapon.repeatDelay * 1.5f : attachedWeapon.repeatDelay;
turret.nextShotTime = UnityEngine.Time.time + attachedWeapon.ScaleRepeatDelay(delay);
}
else turret.nextShotTime = UnityEngine.Time.time + 5f;
}
}
if (!((UnityEngine.Object)turret.target == (UnityEngine.Object)null) && !turret.target.IsDead() && ((double)UnityEngine.Time.realtimeSinceStartup - (double)turret.lastTargetSeenTime <= 3.0 && (double)Vector3.Distance(turret.transform.position, turret.target.transform.position) <= (double)turret.sightRange) && (!turret.PeacekeeperMode() || turret.IsEntityHostile(turret.target))) return;
turret.SetTarget((BaseCombatEntity)null);
}
public void FireAttachedGun(Vector3 targetPos, float aimCone, Transform muzzleToUse = null, BaseCombatEntity target = null) {
BaseProjectile attachedWeapon = turret.GetAttachedWeapon();
if ((UnityEngine.Object)attachedWeapon == (UnityEngine.Object)null || turret.IsOffline()) return;
Transform pitch = turret.gun_pitch;
attachedWeapon.aiAimCone = 0f;
attachedWeapon.ServerUse(1f, 1f, turret.IsBeingControlled ? turret.RCEyes : pitch);
if (!attachedWeapon.name.Contains("minigun")) turret.ClientRPC<uint, Vector3>((Network.Connection)null, "CLIENT_FireGun", StringPool.Get(turret.muzzlePos.gameObject.name), targetPos);
}
public bool isAuthedPlayer(BasePlayer player) => turret.IsAuthed(player);
public bool HasInterference() => turret.IsOnFire();
private void HavePowerStill() {
bool online = turret.IsOnline();
float enegry = button.GetCurrentEnergy();
if (enegry < requiredPower && online || online && !button.IsOn()) {
turret.SetIsOnline(false);
Effect.server.Run(turret.offlineSound.resourcePath, (BaseEntity)turret, 0U, Vector3.zero, Vector3.zero);
}
else if (enegry >= requiredPower && !online && button.IsOn()) {
turret.SetIsOnline(true);
Effect.server.Run(turret.onlineSound.resourcePath, (BaseEntity)turret, 0U, Vector3.zero, Vector3.zero);
}
}
public static int GetNearbyTurrets(AutoTurret newTurret, float radius = 40) {
List<NPCAutoTurret> list = Facepunch.Pool.Get<List<NPCAutoTurret>>();
Vis.Entities<NPCAutoTurret>(newTurret.transform.position, radius, list, 256, QueryTriggerInteraction.Ignore);
int count = list.Count;
Facepunch.Pool.FreeUnmanaged<NPCAutoTurret>(ref list);
return count;
}
private void runHookCalls() {
if (OwnerPlayer != null) {
_.turretLoadoutsFill(OwnerPlayer, turret);
}
}
public void CreateInventory() {
if (turret.socketTransform == null) turret.socketTransform = turret.muzzlePos;
turret.inventory.entityOwner = (BaseEntity)turret;
turret.inventory.capacity = 7;
turret.inventory.canAcceptItem += new Func<Item, int, bool>(CanAcceptItem);
turret.inventory.onItemAddedRemoved = new Action<Item, bool>(OnItemAddedOrRemoved);
turret.dropsLoot = false;
turret.lootPanelName = lootname;
turret.baseProtection = newProtection;
turret.baseProtection.amounts = protectionSettings;
if (!_.configData.settings.gunRequired) Invoke("AddGunAndLockSlot", 1.1f);
if (!_.configData.settings.gunRequired && !_.configData.settings.amoRequired) turret.inventory.SetLocked(true);
}
public bool CanAcceptItem(Item item, int targetSlot) {
Item slot = turret.inventory.GetSlot(0);
if (turret.IsValidWeapon(item) && targetSlot == 0) return true;
if (turret.IsValidWeapon(item) && targetSlot == 0) return true;
if (isSamSiteAlso && item.info.itemid == -384243979 && targetSlot != 0) return true;
if (item.info.category != ItemCategory.Ammunition) return false;
ItemModProjectile component = item.info.GetComponent<ItemModProjectile>();
BaseProjectile attachedWeapon = turret.GetAttachedWeapon();
return slot != null && !((UnityEngine.Object)attachedWeapon == (UnityEngine.Object)null) && (!((UnityEngine.Object)component == (UnityEngine.Object)null) && (attachedWeapon.primaryMagazine.definition.ammoTypes & component.ammoType) != (AmmoTypes)0) && targetSlot != 0;
}
public void OnItemAddedOrRemoved(Item item, bool added) {
if (!added) {
BaseProjectile attachedWeapon = item.GetHeldEntity() as BaseProjectile;
if (attachedWeapon != null) {
if (!attachedWeapon.name.Contains("minigun")) attachedWeapon.SetFlag(BaseEntity.Flags.Disabled, false);
heldItem = attachedWeapon;
}
}
if (samMod != null) samMod.EnsureReloaded();
if (!(bool)(UnityEngine.Object)item.info.GetComponent<ItemModEntity>()) return;
if (turret.IsInvoking(new Action(UpdateAttachedWeapon))) UpdateAttachedWeapon();
turret.Invoke(new Action(UpdateAttachedWeapon), 0.5f);
}
public void UpdateAttachedWeapon() {
HeldEntity turretNew = TryAddWeaponToTurret(turret.inventory.GetSlot(0), turret.socketTransform, (BaseEntity)turret, turret.attachedWeaponZOffsetScale);
bool b = (UnityEngine.Object)turretNew != (UnityEngine.Object)null;
turret.SetFlag(BaseEntity.Flags.Reserved3, b);
if (b) {
BaseProjectile attachedWeaponMod = turret.GetAttachedWeapon();
turret.AttachedWeapon = turretNew;
turret.totalAmmoDirty = true;
turret.Reload();
turret.UpdateTotalAmmo();
if (attachedWeaponMod != null) {
if (!OldCone.ContainsKey(attachedWeaponMod.name)) OldCone.Add(attachedWeaponMod.name, attachedWeaponMod.aimCone);
attachedWeaponMod.aimCone = _.configData.settings.aimCone;
}
if (!turret.IsOffline()) return;
turretNew.SetLightsOn(false);
}
else {
BaseProjectile attachedWeapon = turret.GetAttachedWeapon();
if ((UnityEngine.Object)attachedWeapon != (UnityEngine.Object)null) {
attachedWeapon.SetGenericVisible(false);
attachedWeapon.SetLightsOn(false);
if (!OldCone.ContainsKey(attachedWeapon.name)) OldCone.Add(attachedWeapon.name, attachedWeapon.aimCone);
attachedWeapon.aimCone = _.configData.settings.aimCone;
}
turret.AttachedWeapon = (HeldEntity)null;
}
}
public static HeldEntity TryAddWeaponToTurret(Item weaponItem, Transform parent, BaseEntity entityParent, float zOffsetScale) {
Vector3 gunOffset = new Vector3(-0.0f, -0.036f, -0.30f);
HeldEntity heldEntity1 = (HeldEntity)null;
if (weaponItem != null && (weaponItem.info.category == ItemCategory.Weapon || weaponItem.info.category == ItemCategory.Fun)) {
BaseEntity heldEntity2 = weaponItem.GetHeldEntity();
if ((UnityEngine.Object)heldEntity2 != (UnityEngine.Object)null) {
HeldEntity component = heldEntity2.GetComponent<HeldEntity>();
if ((UnityEngine.Object)component != (UnityEngine.Object)null && component.IsUsableByTurret) heldEntity1 = component;
}
}
if ((UnityEngine.Object)heldEntity1 == (UnityEngine.Object)null) return (HeldEntity)null;
Transform transform = heldEntity1.transform;
Transform muzzleTransform = heldEntity1.MuzzleTransform;
heldEntity1.SetParent((BaseEntity)null);
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
Quaternion quaternion = transform.rotation * Quaternion.Inverse(muzzleTransform.rotation);
heldEntity1.limitNetworking = false;
if (!heldEntity1.name.Contains("minigun")) heldEntity1.SetFlag(BaseEntity.Flags.Disabled, false);
heldEntity1.SetParent(entityParent, StringPool.Get(parent.name));
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.rotation *= quaternion;
Vector3 vector3 = parent.InverseTransformPoint(muzzleTransform.position);
transform.localPosition = Vector3.left * vector3.x;
float num = Vector3.Distance(muzzleTransform.position, transform.position);
transform.localPosition += (Vector3.forward * num * zOffsetScale) + gunOffset;
heldEntity1.SetGenericVisible(true);
heldEntity1.SetLightsOn(true);
if (!heldEntity1.name.Contains("minigun")) heldEntity1.SetFlag(BaseEntity.Flags.Disabled, true);
if (_ != null) {
_.NextTick(() => {
if (heldEntity1 != null && !heldEntity1.name.Contains("minigun")) heldEntity1.SetFlag(BaseEntity.Flags.Disabled, true);
heldEntity1?.SendNetworkUpdate();
}
);
}
return heldEntity1;
}
private ElectricSwitch AddOrGetButton() {
ElectricSwitch buttonFind = turret.GetComponentInChildren<ElectricSwitch>();
if (buttonFind == null) {
ElectricSwitch buttonNew = GameManager.server.CreateEntity(switchPrefabString, position) as ElectricSwitch;
if (buttonNew == null) return null;
buttonNew.Spawn();
buttonNew.SetParent(turret, true);
button = buttonNew;
}
else {
// ... [Code preview truncated due to length. Full source in attached file] ...