C#:
// Plugin formatted by redBDGR's Plugin Formatting Tool
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
[Info("RocketTurrets", "redBDGR", "1.3.15")]
[Description("Create rocket shooting turrets")]
class RocketTurrets : RustPlugin {
private bool changed;
private List<AutoTurret> rocketTurrets = new List<AutoTurret>();
private List<AutoTurret> antiairTurrets = new List<AutoTurret>();
private List<AutoTurret> javelinTurrets = new List<AutoTurret>();
private Dictionary<string, PlayerData> turretNumbers = new Dictionary<string, PlayerData>();
private List<ulong> turretIDs = new List<ulong>();
private List<ulong> antiAirIDs = new List<ulong>();
private List<ulong> javelinIDs = new List<ulong>();
private static RocketTurrets plugin;
[PluginReference]
Plugin RemoteTurrets;
public static LayerMask collLayers = LayerMask.GetMask("Construction", "Deployed", "Tree", "Terrain", "Resource", "World", "Water", "Default", "AI");
private float rocketFireRate = 1.2f;
private float rocketLockonTime = 5f;
private float minHitDistance = 10f;
private float rocketLockonRadius = 40f;
private float rocketSpeed = 20f;
private uint rocketLauncherSkin;
private float explosionRadius = 4f;
private bool explodeAtTarget = true;
private int lockonSoundEveryxUpdate = 100;
private bool requiresAmmo = true;
private int maxNumberAllowed = 5;
private bool rocketHeatSeeking;
private bool customRocketTrail = false;
private float aaFireRate = 1.2f;
private float aaLockonTime = 5f;
private float aaminHitDistance = 5f;
private float aaLockonRadius = 150f;
private float aarocketSpeed = 40f;
private uint aaLauncherSkin;
private float aaexplosionRadius = 4f;
private int aalockonSoundEveryxUpdate = 100;
private float damageToHeli = 500f;
private bool aaRequiresAmmo = true;
private int aaMaxNumberAllowed = 5;
private bool aaRequireBuildingRightsToAccessInventory = true;
private bool aaCustomRocketTrail = true;
private float jrocketFireRate = 1.2f;
private float jrocketLockonTime = 5f;
private float jminHitDistance = 10f;
private float jrocketLockonRadius = 40f;
private float jrocketSpeed = 20f;
private uint jrocketLauncherSkin;
private float jexplosionRadius = 4f;
private int jlockonSoundEveryxUpdate = 100;
private bool jrequiresAmmo = true;
private int jmaxNumberAllowed = 5;
private bool jSeekTarget = true;
private float jHeightBeforeCurve = 40f;
private bool jCustomRocketTrail = true;
private bool returnCostOnPickup;
private bool returnCostOnDowngrade;
private static Dictionary<string, object> RocketUpgradeCost() {
var at = new Dictionary<string, object> {
{
"rocket.launcher", 1
}
}
;
return at;
}
private static Dictionary<string, object> AntiAirUpgradeCost() {
var at = new Dictionary<string, object> {
{
"targeting.computer", 1
}
, {
"cctv.camera", 2
}
, {
"rocket.launcher", 1
}
}
;
return at;
}
private static Dictionary<string, object> JavelinUpgradeCost() {
var at = new Dictionary<string, object> {
{
"rocket.launcher", 1
}
}
;
return at;
}
private Dictionary<string, object> rocketUpgradeCost;
private Dictionary<string, object> antiAirUpgradeCost;
private Dictionary<string, object> javelinUpgradeCost;
private const string permissionName = "rocketturrets.use";
private const string permissionNameROCKET = "rocketturrets.rocket";
private const string permissionNameANTIAIR = "rocketturrets.antiair";
private const string permissionNameJAVELIN = "rocketturrets.javelin";
private const string permissionNameUNLIMITED = "rocketturrets.unlimited";
private const string permissionNameAMMOUNLIMITED = "rocketturrets.unlimitedammo";
private class StoredData {
public List<ulong> turretIDs = new List<ulong>();
public List<ulong> antiAirIDs = new List<ulong>();
public List<ulong> javelinIDs = new List<ulong>();
}
private class StoredData2 {
public Dictionary<string, PlayerData> turretNumbers = new Dictionary<string, PlayerData>();
}
private class PlayerData {
public int RocketTurrets;
public int AntiAirTurrets;
public int JavelinTurrets;
}
private DynamicConfigFile data;
private DynamicConfigFile data2;
private StoredData storedData;
private StoredData2 storedData2;
private void OnServerSave() => SaveData();
private void SaveData() {
storedData.turretIDs = turretIDs;
storedData.antiAirIDs = antiAirIDs;
storedData.javelinIDs = javelinIDs;
storedData2.turretNumbers = turretNumbers;
data.WriteObject(storedData);
data2.WriteObject(storedData2);
}
private void LoadData() {
try {
storedData = data.ReadObject<StoredData>();
storedData2 = data2.ReadObject<StoredData2>();
turretNumbers = storedData2.turretNumbers;
turretIDs = storedData.turretIDs;
antiAirIDs = storedData.antiAirIDs;
javelinIDs = storedData.javelinIDs;
}
catch {
Puts("Failed to load data, creating new file");
storedData = new StoredData();
}
}
protected override void LoadDefaultConfig() {
Config.Clear();
LoadVariables();
}
private void LoadVariables() {
rocketFireRate = Convert.ToSingle(GetConfig("Turret Settings", "Rocket fire rate", 2f));
rocketLockonTime = Convert.ToSingle(GetConfig("Turret Settings", "Lockon length", 5f));
minHitDistance = Convert.ToSingle(GetConfig("Turret Settings", "Min shoot distance", 4f));
rocketLockonRadius = Convert.ToSingle(GetConfig("Turret Settings", "Rocket lockon radius", 40f));
rocketSpeed = Convert.ToSingle(GetConfig("Turret Settings", "Rocket speed", 20f));
rocketLauncherSkin = Convert.ToUInt32(GetConfig("Turret Settings", "Default rocket model skin", 0));
explosionRadius = Convert.ToSingle(GetConfig("Turret Settings", "Explosion radius", 4f));
explodeAtTarget = Convert.ToBoolean(GetConfig("Turret Settings", "Explode at target pos", true));
lockonSoundEveryxUpdate = Convert.ToInt32(GetConfig("Turret Settings", "Lockon sound every x updates", 100));
requiresAmmo = Convert.ToBoolean(GetConfig("Turret Settings", "Requires Ammo", true));
maxNumberAllowed = Convert.ToInt16(GetConfig("Turret Settings", "Maximum Allowed Per Player", 5));
rocketHeatSeeking = Convert.ToBoolean(GetConfig("Turret Settings", "Heatseeking Rockets", false));
customRocketTrail = Convert.ToBoolean(GetConfig("Turret Settings", "Custom Rocket Trail", false));
aaFireRate = Convert.ToSingle(GetConfig("AntiAir Settings", "Rocket fire rate", 2f));
aaLockonTime = Convert.ToSingle(GetConfig("AntiAir Settings", "Lockon length", 5f));
aaminHitDistance = Convert.ToSingle(GetConfig("AntiAir Settings", "Min shoot distance", 4f));
aaLockonRadius = Convert.ToSingle(GetConfig("AntiAir Settings", "Lockon radius", 80f));
aarocketSpeed = Convert.ToSingle(GetConfig("AntiAir Settings", "Rocket speed", 30f));
aaLauncherSkin = Convert.ToUInt32(GetConfig("AntiAir Settings", "Default rocket model skin", 0));
aaexplosionRadius = Convert.ToSingle(GetConfig("AntiAir Settings", "Explosion radius", 4f));
aalockonSoundEveryxUpdate = Convert.ToInt32(GetConfig("AntiAir Settings", "Lockon sound every x updates", 100));
damageToHeli = Convert.ToSingle(GetConfig("AntiAir Settings", "Damage to heli", 500f));
aaRequiresAmmo = Convert.ToBoolean(GetConfig("AntiAir Settings", "Requires Ammo", true));
aaMaxNumberAllowed = Convert.ToInt16(GetConfig("AntiAir Settings", "Maximum Allowed Per Player", 5));
aaRequireBuildingRightsToAccessInventory = Convert.ToBoolean(GetConfig("AntiAir Settings", "Require Build Acces to Loot", true));
aaCustomRocketTrail = Convert.ToBoolean(GetConfig("AntiAir Settings", "Custom Rocket Trail", true));
jrocketFireRate = Convert.ToSingle(GetConfig("Javelin Settings", "Rocket fire rate", 2f));
jrocketLockonTime = Convert.ToSingle(GetConfig("Javelin Settings", "Lockon Length", 5f));
jminHitDistance = Convert.ToSingle(GetConfig("Javelin Settings", "Min lockon distance", 10f));
jrocketLockonRadius = Convert.ToSingle(GetConfig("Javelin Settings", "Lockon radius", 80f));
jrocketSpeed = Convert.ToSingle(GetConfig("Javelin Settings", "Rocket speed", 15f));
jrocketLauncherSkin = Convert.ToUInt32(GetConfig("Javelin Settings", "Default rocket model skin", 0));
jexplosionRadius = Convert.ToSingle(GetConfig("Javelin Settings", "Explosion radius", 4f));
jlockonSoundEveryxUpdate = Convert.ToInt16(GetConfig("Javelin Settings", "Lockon sound every x updates", 100));
jrequiresAmmo = Convert.ToBoolean(GetConfig("Javelin Settings", "Requires ammo", true));
jmaxNumberAllowed = Convert.ToInt16(GetConfig("Javelin Settings", "Max number allowed per player", 5));
jSeekTarget = Convert.ToBoolean(GetConfig("Javelin Settings", "Seek target", true));
jHeightBeforeCurve = Convert.ToSingle(GetConfig("Javelin Settings", "Height before curve starts", 40f));
jCustomRocketTrail = Convert.ToBoolean(GetConfig("Javelin Settings", "Custom Rocket Trail", true));
rocketUpgradeCost = (Dictionary<string, object>)GetConfig("Turret Settings", "[ Cost to upgrade - Rocket tier ]", RocketUpgradeCost());
antiAirUpgradeCost = (Dictionary<string, object>)GetConfig("AntiAir Settings", "[Cost to Upgrade - AntiAir Tier ]", AntiAirUpgradeCost());
javelinUpgradeCost = (Dictionary<string, object>)GetConfig("Javelin Settings", "[ Cost to upgrade - Javelin Tier ]", JavelinUpgradeCost());
returnCostOnPickup = Convert.ToBoolean(GetConfig("General Settings", "Return upgrade cost on turret pickup", false));
returnCostOnDowngrade = Convert.ToBoolean(GetConfig("General Settings", "Return upgrade cost on turret downgrade", false));
if (!changed) return;
SaveConfig();
changed = false;
}
private bool IsRocketTurret(AutoTurret turret) {
if (turret.GetComponent<RocketTurret>() || turret.GetComponent<JavelinTurret>() || turret.GetComponent<AntiAirTurret>()) return true;
return false;
}
private void ToggleTurretAutomation(AutoTurret turret, bool enabled) {
if (turret.GetComponent<RocketTurret>()) turret.GetComponent<RocketTurret>().enabled = true;
else if (turret.GetComponent<AntiAirTurret>()) turret.GetComponent<AntiAirTurret>().enabled = true;
else if (turret.GetComponent<JavelinTurret>()) turret.GetComponent<JavelinTurret>().enabled = true;
}
private void TryFireRocket(AutoTurret turret) {
if (turret.GetComponent<RocketTurret>()) turret.GetComponent<RocketTurret>().TryFireRocket();
else if (turret.GetComponent<AntiAirTurret>()) turret.GetComponent<AntiAirTurret>().TryFireRocket();
else if (turret.GetComponent<JavelinTurret>()) turret.GetComponent<JavelinTurret>().TryFireRocket();
}
private class RocketTurret : MonoBehaviour {
private float aimRadius = plugin.rocketLockonRadius;
private float fireRate = plugin.rocketFireRate;
private float rocketSpeed = plugin.rocketSpeed;
private float minHitDistance = plugin.minHitDistance;
private float lockonTime = plugin.rocketLockonTime;
private uint rocketLauncherSkin = plugin.rocketLauncherSkin;
private float explosionRadius = plugin.explosionRadius;
private bool explodeOnTargetPos = plugin.explodeAtTarget;
private int soundEveryxUpdates = plugin.lockonSoundEveryxUpdate;
private bool requiresAmmo = plugin.requiresAmmo;
private bool heatSeek = plugin.rocketHeatSeeking;
private int updateCounter;
private bool isLockedOn;
private bool isLockingOn;
private float lockonFinish;
private float nextShoot;
private AutoTurret turret;
private BaseCombatEntity target;
private DroppedItem launcher_1;
private DroppedItem rocket_1;
private DroppedItem rocket_2;
private DestroyOnGroundMissing desGround;
private GroundWatch groundWatch;
private void Awake() {
turret = gameObject.GetComponent<AutoTurret>();
InitAesthetics();
if (!plugin.rocketTurrets.Contains(turret)) plugin.rocketTurrets.Add(turret);
turret.sightRange = aimRadius;
if (!plugin.turretIDs.Contains(turret.net.ID)) plugin.turretIDs.Add(turret.net.ID);
desGround = GetComponent<DestroyOnGroundMissing>();
if (!desGround) gameObject.AddComponent<DestroyOnGroundMissing>();
groundWatch = GetComponent<GroundWatch>();
if (!groundWatch) gameObject.AddComponent<GroundWatch>();
groundWatch.CancelInvoke("OnPhysicsNeighbourChanged");
groundWatch.InvokeRepeating("OnPhysicsNeighbourChanged", 0, 0.5f);
}
private void Update() {
if (!turret.HasTarget()) {
if (isLockedOn) isLockedOn = false;
if (isLockingOn) isLockingOn = false;
return;
}
if (!isLockedOn) {
if (!isLockingOn) {
lockonFinish = Time.time + lockonTime;
isLockingOn = true;
}
else if (isLockingOn && Time.time > lockonFinish) LockToTarget(turret.target);
else if (isLockingOn) {
if (updateCounter == soundEveryxUpdates) {
Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
updateCounter = 0;
return;
}
updateCounter++;
}
}
else {
if (Time.time < nextShoot) return;
if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance) return;
var rocketItem = HasAmmo();
if (rocketItem == null) return;
FireRocket(rocketItem);
nextShoot = Time.time + fireRate;
}
}
private void OnDestroy() {
if (!launcher_1.IsDestroyed) launcher_1.Kill();
if (!rocket_1.IsDestroyed) rocket_1.Kill();
if (!rocket_2.IsDestroyed) rocket_2.Kill();
}
public void Destroy() {
if (plugin.rocketTurrets.Contains(turret)) plugin.rocketTurrets.Remove(turret);
if (plugin.turretIDs.Contains(turret.net.ID)) plugin.turretIDs.Remove(turret.net.ID);
OnDestroy();
if (this) Destroy(this);
}
private void DestroyTurret() {
if (turret != null) turret.Kill(BaseNetworkable.DestroyMode.Gib);
}
public void UnloadDestroy() {
if (plugin.rocketTurrets.Contains(turret)) plugin.rocketTurrets.Remove(turret);
OnDestroy();
Destroy(this);
}
private Item HasAmmo() {
if (plugin.permission.UserHasPermission(turret.OwnerID.ToString(), permissionNameAMMOUNLIMITED)) return ItemManager.CreateByName("ammo.rocket.basic");
return !requiresAmmo ? ItemManager.CreateByName("ammo.rocket.basic") : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
}
private void LockToTarget(BaseCombatEntity entity) {
isLockedOn = true;
isLockingOn = false;
nextShoot = Time.time + 0.3f;
target = entity;
}
private void InitAesthetics() {
launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
launcher_1.GetComponent<Rigidbody>().isKinematic = true;
launcher_1.GetComponent<Rigidbody>().useGravity = false;
launcher_1.allowPickup = false;
launcher_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), launcher_1, "IdleDestroy"));
rocket_1 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_1.GetComponent<Rigidbody>().isKinematic = true;
rocket_1.GetComponent<Rigidbody>().useGravity = false;
rocket_1.allowPickup = false;
rocket_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_1, "IdleDestroy"));
rocket_2 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_2.GetComponent<Rigidbody>().isKinematic = true;
rocket_2.GetComponent<Rigidbody>().useGravity = false;
rocket_2.allowPickup = false;
rocket_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_2, "IdleDestroy"));
var launcherRot = new Vector3();
var rocketRot = new Vector3();
foreach (var entry in turret.gameObject.transform.GetAllChildren()) {
if (entry.name != "weapon_socket") continue;
launcherRot = entry.gameObject.transform.localRotation.eulerAngles;
launcherRot = new Vector3(launcherRot.x, launcherRot.y + 180, launcherRot.z);
rocketRot = entry.gameObject.transform.localRotation.eulerAngles;
rocketRot = new Vector3(rocketRot.x, rocketRot.y + 270, rocketRot.z);
}
launcher_1.SetParent(turret, "weapon_socket");
launcher_1.transform.localPosition = new Vector3(0, 0, 0);
launcher_1.transform.localRotation = Quaternion.Euler(launcherRot);
rocket_1.SetParent(turret, "weapon_socket");
rocket_1.transform.localPosition = new Vector3(0, -0.05f, 0.17f);
rocket_1.transform.localRotation = Quaternion.Euler(rocketRot);
rocket_2.SetParent(turret, "weapon_socket");
rocket_2.transform.localPosition = new Vector3(0, -0.05f, -0.17f);
rocket_2.transform.localRotation = Quaternion.Euler(rocketRot);
}
public void TryFireRocket() {
if (Time.time < nextShoot) return;
var rocketItem = HasAmmo();
if (rocketItem == null) return;
FireRocket(rocketItem);
nextShoot = Time.time + fireRate;
}
private void FireRocket(Item rocketItem) {
ServerProjectile rocket = CreateRocket(turret.muzzlePos.transform.position, rocketItem);
if (rocket == null) return;
TimedExplosive expl = rocket.gameObject.GetComponent<TimedExplosive>();
if (enabled && explodeOnTargetPos && target) {
float dist = Vector3.Distance(turret.muzzlePos.position, turret.target.transform.position);
float time = dist / rocketSpeed;
expl.SetFuse(time);
}
else expl.SetFuse(float.PositiveInfinity);
expl.explosionRadius = explosionRadius;
rocket.gravityModifier = 0f;
rocket.speed = rocketSpeed;
rocket.InitializeVelocity(turret.aimDir);
Effect.server.Run("assets/prefabs/npc/patrol helicopter/effects/rocket_fire.prefab", turret.muzzlePos.position);
if (plugin.customRocketTrail) {
BaseEntity trail = GameManager.server.CreateEntity("assets/bundled/prefabs/oilfireballsmall.prefab");
trail.SetParent(rocket.GetComponent<BaseEntity>());
trail.Spawn();
}
if (heatSeek) if (this.target != null) rocket.gameObject.AddComponent<HeatRocket>().target = target;
}
private ServerProjectile CreateRocket(Vector3 launchPos, Item rocketItem) {
if (requiresAmmo) {
if (rocketItem == null) return null;
if (rocketItem.amount == 1) rocketItem.RemoveFromContainer();
else rocketItem.UseItem();
}
else rocketItem.RemoveFromContainer();
BaseEntity rocket;
switch (rocketItem.info.shortname) {
case "ammo.rocket.basic" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_basic.prefab", launchPos);
break;
case "ammo.rocket.fire" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_fire.prefab", launchPos);
break;
case "ammo.rocket.hv" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_hv.prefab", launchPos);
break;
default : return null;
}
if (rocket == null) return null;
rocket.creatorEntity = turret;
rocket.Spawn();
if (target != null) {
rocket.transform.LookAt(target.transform);
rocket.GetComponent<ServerProjectile>()?.InitializeVelocity(target.transform.position);
}
else {
rocket.transform.LookAt(turret.muzzlePos.position + turret.muzzlePos.forward.normalized * 10);
rocket.GetComponent<ServerProjectile>()?.InitializeVelocity(turret.muzzlePos.position + turret.muzzlePos.forward * 10);
}
return rocket.GetComponent<ServerProjectile>();
}
}
private class AntiAirTurret : MonoBehaviour {
private float aimRadius = plugin.aaLockonRadius;
private float fireRate = plugin.aaFireRate;
private float rocketSpeed = plugin.aarocketSpeed;
private float minHitDistance = plugin.aaminHitDistance;
private float lockonTime = plugin.aaLockonTime;
private uint rocketLauncherSkin = plugin.aaLauncherSkin;
private float explosionRadius = plugin.aaexplosionRadius;
private int soundEveryxUpdates = plugin.aalockonSoundEveryxUpdate;
private float damage = plugin.damageToHeli;
private bool requiresAmmo = plugin.aaRequiresAmmo;
private int updateCounter;
private bool isLockedOn;
private bool isLockingOn;
private float lockonFinish;
private float nextShoot;
private AutoTurret turret;
private BaseEntity entity;
private BaseCombatEntity target;
private SphereCollider sCol;
private DroppedItem launcher_1;
private DroppedItem rocket_1;
private DroppedItem rocket_2;
private DroppedItem computer;
private DroppedItem camera_1;
private DroppedItem camera_2;
private void Awake() {
turret = gameObject.GetComponent<AutoTurret>();
InitAesthetics();
turret.SetIsOnline(false);
if (!plugin.antiairTurrets.Contains(turret)) plugin.antiairTurrets.Add(turret);
turret.sightRange = 0.1f;
if (!plugin.antiAirIDs.Contains(turret.net.ID)) plugin.antiAirIDs.Add(turret.net.ID);
entity = gameObject.GetComponent<BaseEntity>();
sCol = entity.gameObject.AddComponent<SphereCollider>();
sCol.gameObject.layer = (int)Layer.Reserved1;
sCol.radius = aimRadius;
sCol.isTrigger = true;
}
private void Update() {
if (target == null) {
if (isLockedOn) isLockedOn = false;
if (isLockingOn) isLockingOn = false;
return;
}
if (!isLockedOn) {
turret.target = target;
turret.UpdateFacingToTarget();
if (!isLockingOn) {
lockonFinish = Time.time + lockonTime;
isLockingOn = true;
}
else if (isLockingOn && Time.time > lockonFinish) LockToTarget(turret.target);
else if (isLockingOn) {
if (updateCounter == soundEveryxUpdates) {
Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
updateCounter = 0;
return;
}
updateCounter++;
}
}
else {
TryFireRocket();
}
}
private void OnTriggerEnter(Collider col) {
BaseHelicopter heli = col.GetComponentInParent<BaseHelicopter>();
CH47Helicopter chin = col.GetComponentInParent<CH47Helicopter>();
if (heli != null) target = heli;
else if (chin != null) target = chin;
}
private void OnTriggerExit(Collider col) {
if (col.GetComponentInParent<BaseHelicopter>() == null && col.GetComponentInParent<CH47Helicopter>() == null) return;
if (col.GetComponentInParent<BaseCombatEntity>() != target) return;
turret.target = null;
turret.SetTarget(null);
target = null;
}
private void OnDestroy() {
if (!launcher_1.IsDestroyed) launcher_1.Kill();
if (!rocket_1.IsDestroyed) rocket_1.Kill();
if (!rocket_2.IsDestroyed) rocket_2.Kill();
if (!computer.IsDestroyed) computer.Kill();
if (!camera_1.IsDestroyed) camera_1.Kill();
if (!camera_2.IsDestroyed) camera_2.Kill();
if (sCol) Destroy(sCol);
}
public void Destroy() {
if (plugin.antiairTurrets.Contains(turret)) plugin.antiairTurrets.Remove(turret);
if (plugin.turretIDs.Contains(turret.net.ID)) plugin.turretIDs.Remove(turret.net.ID);
OnDestroy();
Destroy(this);
}
private void DestroyTurret() {
if (turret != null) turret.Kill(BaseNetworkable.DestroyMode.Gib);
}
public void UnloadDestroy() {
if (plugin.antiairTurrets.Contains(turret)) plugin.antiairTurrets.Remove(turret);
OnDestroy();
Destroy(this);
}
private Item HasAmmo() {
if (plugin.permission.UserHasPermission(turret.OwnerID.ToString(), permissionNameAMMOUNLIMITED)) return ItemManager.CreateByName("ammo.rocket.basic");
return !requiresAmmo ? ItemManager.CreateByName("ammo.rocket.basic") : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
}
private void LockToTarget(BaseCombatEntity _entity) {
isLockedOn = true;
isLockingOn = false;
nextShoot = Time.time + 0.3f;
target = _entity;
}
private void InitAesthetics() {
launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
launcher_1.GetComponent<Rigidbody>().isKinematic = true;
launcher_1.GetComponent<Rigidbody>().useGravity = false;
launcher_1.allowPickup = false;
launcher_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), launcher_1, "IdleDestroy"));
rocket_1 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_1.GetComponent<Rigidbody>().isKinematic = true;
rocket_1.GetComponent<Rigidbody>().useGravity = false;
rocket_1.allowPickup = false;
rocket_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_1, "IdleDestroy"));
rocket_2 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_2.GetComponent<Rigidbody>().isKinematic = true;
rocket_2.GetComponent<Rigidbody>().useGravity = false;
rocket_2.allowPickup = false;
rocket_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_2, "IdleDestroy"));
computer = ItemManager.CreateByItemID(1523195708).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
computer.GetComponent<Rigidbody>().isKinematic = true;
computer.GetComponent<Rigidbody>().useGravity = false;
computer.allowPickup = false;
computer.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), computer, "IdleDestroy"));
camera_1 = ItemManager.CreateByItemID(634478325).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
camera_1.GetComponent<Rigidbody>().isKinematic = true;
camera_1.GetComponent<Rigidbody>().useGravity = false;
camera_1.allowPickup = false;
camera_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), camera_1, "IdleDestroy"));
camera_2 = ItemManager.CreateByItemID(634478325).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
camera_2.GetComponent<Rigidbody>().isKinematic = true;
camera_2.GetComponent<Rigidbody>().useGravity = false;
camera_2.allowPickup = false;
camera_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), camera_2, "IdleDestroy"));
Vector3 computerRot = turret.gameObject.transform.localRotation.eulerAngles;
computerRot = new Vector3(computerRot.x, computerRot.y + 240, computerRot.z);
computer.SetParent(turret);
computer.transform.localPosition = new Vector3(0.45f, 0, 0.25f);
computer.transform.rotation = Quaternion.Euler(computerRot);
Vector3 launcherRot = new Vector3();
Vector3 rocketRot = new Vector3();
foreach (var entry in turret.gameObject.transform.GetAllChildren()) {
if (entry.name != "weapon_socket") continue;
launcherRot = entry.gameObject.transform.localRotation.eulerAngles;
launcherRot = new Vector3(launcherRot.x, launcherRot.y + 180, launcherRot.z);
rocketRot = entry.gameObject.transform.localRotation.eulerAngles;
rocketRot = new Vector3(rocketRot.x, rocketRot.y + 270, rocketRot.z);
}
launcher_1.SetParent(turret, "weapon_socket");
launcher_1.transform.localPosition = new Vector3(0, 0, 0);
launcher_1.transform.localRotation = Quaternion.Euler(launcherRot);
rocket_1.SetParent(turret, "weapon_socket");
rocket_1.transform.localPosition = new Vector3(0, -0.05f, 0.17f);
rocket_1.transform.localRotation = Quaternion.Euler(rocketRot);
rocket_2.SetParent(turret, "weapon_socket");
rocket_2.transform.localPosition = new Vector3(0, -0.05f, -0.17f);
rocket_2.transform.localRotation = Quaternion.Euler(rocketRot);
camera_1.SetParent(turret, "weapon_socket");
camera_1.transform.localPosition = new Vector3(0, 0.05f, -0.17f);
camera_1.transform.localRotation = Quaternion.Euler(rocketRot);
camera_2.SetParent(turret, "weapon_socket");
camera_2.transform.localPosition = new Vector3(0, 0.05f, 0.17f);
camera_2.transform.localRotation = Quaternion.Euler(rocketRot);
}
public void TryFireRocket() {
if (Time.time < nextShoot) return;
if (turret.target) if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance) return;
var rocketItem = HasAmmo();
if (rocketItem == null) return;
FireRocket(rocketItem);
nextShoot = Time.time + fireRate;
}
private void FireRocket(Item rocketItem) {
ServerProjectile rocket = CreateRocket(turret.muzzlePos.transform.position, rocketItem);
if (rocket == null) return;
TimedExplosive expl = rocket.gameObject.GetComponent<TimedExplosive>();
if (turret.target != null) {
float dist = Vector3.Distance(turret.muzzlePos.position, turret.target.transform.position);
float time = dist / rocketSpeed;
plugin.timer.Once(time - 4f, () => {
if (target) target.Hurt(damage);
}
);
}
expl.explosionRadius = explosionRadius;
rocket.gravityModifier = 0f;
rocket.speed = rocketSpeed;
rocket.InitializeVelocity(turret.muzzlePos.transform.forward);
Effect.server.Run("assets/prefabs/npc/patrol helicopter/effects/rocket_fire.prefab", turret.muzzlePos.position);
if (target != null) rocket.gameObject.AddComponent<HeatRocket>().target = turret.target;
}
private ServerProjectile CreateRocket(Vector3 launchPos, Item rocketItem) {
if (requiresAmmo) {
if (rocketItem == null) return null;
if (rocketItem.amount == 1) rocketItem.RemoveFromContainer();
else rocketItem.UseItem();
}
BaseEntity rocket;
switch (rocketItem.info.shortname) {
case "ammo.rocket.basic" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_basic.prefab", launchPos);
break;
case "ammo.rocket.fire" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_fire.prefab", launchPos);
break;
case "ammo.rocket.hv" : rocket = GameManager.server.CreateEntity("assets/prefabs/ammo/rocket/rocket_hv.prefab", launchPos);
break;
default : return null;
}
if (rocket == null) return null;
rocket.Spawn();
if (target) rocket.transform.LookAt(target.transform);
else rocket.transform.LookAt(turret.aimDir);
return rocket.GetComponent<ServerProjectile>();
}
}
private class JavelinTurret : MonoBehaviour {
private float aimRadius = plugin.jrocketLockonRadius;
private float fireRate = plugin.jrocketFireRate;
private float rocketSpeed = plugin.jrocketSpeed;
private float minHitDistance = plugin.jminHitDistance;
private float lockonTime = plugin.jrocketLockonTime;
private uint rocketLauncherSkin = plugin.jrocketLauncherSkin;
private float explosionRadius = plugin.jexplosionRadius;
private int soundEveryxUpdates = plugin.jlockonSoundEveryxUpdate;
private bool requiresAmmo = plugin.jrequiresAmmo;
private bool seekTarget = plugin.jSeekTarget;
private int updateCounter;
private bool isLockedOn;
private bool isLockingOn;
private float lockonFinish;
private float nextShoot;
private AutoTurret turret;
private BaseCombatEntity target;
private BaseCombatEntity externalTarget;
private DroppedItem launcher_1;
private DroppedItem rocket_1;
private DroppedItem rocket_2;
private DestroyOnGroundMissing desGround;
private GroundWatch groundWatch;
private void Awake() {
turret = gameObject.GetComponent<AutoTurret>();
InitAesthetics();
if (!plugin.javelinTurrets.Contains(turret)) plugin.javelinTurrets.Add(turret);
turret.sightRange = aimRadius;
if (!plugin.javelinIDs.Contains(turret.net.ID)) plugin.javelinIDs.Add(turret.net.ID);
desGround = GetComponent<DestroyOnGroundMissing>();
if (!desGround) gameObject.AddComponent<DestroyOnGroundMissing>();
groundWatch = GetComponent<GroundWatch>();
if (!groundWatch) gameObject.AddComponent<GroundWatch>();
groundWatch.CancelInvoke("OnPhysicsNeighbourChanged");
groundWatch.InvokeRepeating("OnPhysicsNeighbourChanged", 0, 0.5f);
SphereCollider collider = turret.gameObject.AddComponent<SphereCollider>();
collider.gameObject.layer = (int)Layer.Reserved1;
collider.radius = aimRadius;
collider.isTrigger = true;
}
private void Update() {
if (externalTarget) {
turret.SetTarget(externalTarget);
turret.UpdateAiming();
}
if (!turret.HasTarget()) {
if (isLockedOn) isLockedOn = false;
if (isLockingOn) isLockingOn = false;
return;
}
if (!isLockedOn) {
if (!isLockingOn) {
lockonFinish = Time.time + lockonTime;
isLockingOn = true;
}
else if (isLockingOn && Time.time > lockonFinish) LockToTarget(turret.target);
else if (isLockingOn) {
if (updateCounter == soundEveryxUpdates) {
Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", turret.transform.position);
updateCounter = 0;
return;
}
updateCounter++;
}
}
else {
if (Time.time < nextShoot) return;
if (Vector3.Distance(turret.muzzlePos.transform.position, turret.target.transform.position) < minHitDistance) return;
var rocketItem = HasAmmo();
if (rocketItem == null) return;
FireRocket(rocketItem);
nextShoot = Time.time + fireRate;
}
}
private void OnTriggerEnter(Collider col) {
if (col.name != "assets/prefabs/npc/m2bradley/bradleyapc.prefab") return;
turret.SetTarget(col.GetComponent<BaseCombatEntity>());
externalTarget = col.GetComponent<BaseCombatEntity>();
turret.UpdateAiming();
}
private void OnTriggerExit(Collider col) {
if (col.name != "assets/prefabs/npc/m2bradley/bradleyapc.prefab") return;
turret.SetTarget(null);
turret.TargetScan();
externalTarget = null;
turret.UpdateAiming();
isLockedOn = false;
isLockingOn = false;
}
private void OnDestroy() {
if (!launcher_1.IsDestroyed) launcher_1.Kill();
if (!rocket_1.IsDestroyed) rocket_1.Kill();
if (!rocket_2.IsDestroyed) rocket_2.Kill();
}
public void Destroy() {
if (plugin.rocketTurrets.Contains(turret)) plugin.rocketTurrets.Remove(turret);
if (plugin.turretIDs.Contains(turret.net.ID)) plugin.turretIDs.Remove(turret.net.ID);
OnDestroy();
if (this) Destroy(this);
}
private void DestroyTurret() {
if (turret != null) turret.Kill(BaseNetworkable.DestroyMode.Gib);
}
public void UnloadDestroy() {
if (plugin.rocketTurrets.Contains(turret)) plugin.rocketTurrets.Remove(turret);
OnDestroy();
Destroy(this);
}
private Item HasAmmo() {
if (plugin.permission.UserHasPermission(turret.OwnerID.ToString(), permissionNameAMMOUNLIMITED)) return ItemManager.CreateByName("ammo.rocket.basic");
return !requiresAmmo ? ItemManager.CreateByName("ammo.rocket.basic") : turret.inventory.itemList.FirstOrDefault(item => item.info.itemid == -742865266 || item.info.itemid == 1638322904 || item.info.itemid == -1841918730);
}
private void LockToTarget(BaseCombatEntity entity) {
isLockedOn = true;
isLockingOn = false;
nextShoot = Time.time + 0.3f;
target = entity;
}
private void InitAesthetics() {
launcher_1 = ItemManager.CreateByItemID(442886268, 1, rocketLauncherSkin).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
launcher_1.GetComponent<Rigidbody>().isKinematic = true;
launcher_1.GetComponent<Rigidbody>().useGravity = false;
launcher_1.allowPickup = false;
launcher_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), launcher_1, "IdleDestroy"));
rocket_1 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_1.GetComponent<Rigidbody>().isKinematic = true;
rocket_1.GetComponent<Rigidbody>().useGravity = false;
rocket_1.allowPickup = false;
rocket_1.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_1, "IdleDestroy"));
rocket_2 = ItemManager.CreateByItemID(-742865266).Drop(turret.transform.position, Vector3.zero).GetComponent<DroppedItem>();
rocket_2.GetComponent<Rigidbody>().isKinematic = true;
rocket_2.GetComponent<Rigidbody>().useGravity = false;
rocket_2.allowPickup = false;
rocket_2.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), rocket_2, "IdleDestroy"));
var launcherRot = new Vector3();
var rocketRot = new Vector3();
foreach (var entry in turret.gameObject.transform.GetAllChildren()) {
if (entry.name != "weapon_socket") continue;
launcherRot = entry.gameObject.transform.localRotation.eulerAngles;
launcherRot = new Vector3(launcherRot.x, launcherRot.y + 180, launcherRot.z);
rocketRot = entry.gameObject.transform.localRotation.eulerAngles;
rocketRot = new Vector3(rocketRot.x, rocketRot.y + 270, rocketRot.z);
}
launcher_1.SetParent(turret, "weapon_socket");
launcher_1.transform.localPosition = new Vector3(0, 0, 0);
launcher_1.transform.localRotation = Quaternion.Euler(launcherRot);
rocket_1.SetParent(turret, "weapon_socket");
rocket_1.transform.localPosition = new Vector3(0, -0.05f, 0.17f);
rocket_1.transform.localRotation = Quaternion.Euler(rocketRot);
rocket_2.SetParent(turret, "weapon_socket");
rocket_2.transform.localPosition = new Vector3(0, -0.05f, -0.17f);
rocket_2.transform.localRotation = Quaternion.Euler(rocketRot);
}
public void TryFireRocket() {
if (Time.time < nextShoot) return;
var rocketItem = HasAmmo();
if (rocketItem == null) return;
FireRocket(rocketItem);
nextShoot = Time.time + fireRate;
}
private void FireRocket(Item rocketItem) {
ServerProjectile rocket = CreateRocket(turret.muzzlePos.transform.position, rocketItem);
if (rocket == null) return;
TimedExplosive expl = rocket.gameObject.GetComponent<TimedExplosive>();
expl.explosionRadius = explosionRadius;
rocket.gravityModifier = 0f;
rocket.speed = rocketSpeed;
rocket.InitializeVelocity(turret.muzzlePos.transform.forward);
Effect.server.Run("assets/prefabs/npc/patrol h
// ... [Code preview truncated due to length. Full source in attached file] ...