C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text;
using System;
namespace Oxide.Plugins {
[Info("MLRS Hellfire", "Timm3D", "1.0.8")]
[Description("Manage MLRS and/or call MLRS missiles to a specific point, in different ways.")]
internal class MLRSHellfire : RustPlugin {
#region Permissions
//Master Permission -> Let u do everything.DON'T GIVE THIS PERMISSION NORMAL PLAYERS!
private const string MLRSHellfire_Admin = "mlrshellfire.admin";
private const string MLRSHellfire_MLRSMountBypass = "mlrshellfire.mlrsmountbypass";
private const string MLRSHellfire_UseRemoteMLRS = "mlrshellfire.useremotemlrs";
private const string MLRSHellfire_RemoteMLRS_AllowTargetingPlayer = "mlrshellfire.allowtargetingplayer";
private const string MLRSHellfire_RemoteMLRS_MLRSBrokenBypass = "mlrshellfire.mlrsbrokenbypass";
#endregion
#region Oxide Stuff
private PluginConfig mConfig;
private void Init() {
permission.RegisterPermission(MLRSHellfire_Admin, this);
permission.RegisterPermission(MLRSHellfire_MLRSMountBypass, this);
permission.RegisterPermission(MLRSHellfire_UseRemoteMLRS, this);
permission.RegisterPermission(MLRSHellfire_RemoteMLRS_AllowTargetingPlayer, this);
permission.RegisterPermission(MLRSHellfire_RemoteMLRS_MLRSBrokenBypass, this);
}
protected override void LoadConfig() {
base.LoadConfig();
try {
mConfig = Config.ReadObject<PluginConfig>();
if (mConfig == null) {
LoadDefaultConfig();
SaveConfig();
}
if (mConfig.HellfireFireInterval <= 0.0f) mConfig.HellfireFireInterval = 0.1f;
if (mConfig.MLRSFireInterval <= 0.0f) mConfig.MLRSFireInterval = 0.1f;
if (mConfig.RemoteMLRSFireInterval <= 0f) mConfig.RemoteMLRSFireInterval = 0.1f;
}
catch {
LoadDefaultConfig();
SaveConfig();
return;
}
}
private PluginConfig GetDefaultConfig() {
return new PluginConfig {
PluginPicture = 76561198838421574, PluginPrefix = "<color=#191A28>[</color><color=#CC3B28>MLRS Hellfire</color><color=#191A28>]</color> ", HellfireRocketDamageModifier = 1.0f, HellfireRocketExplosiveRadiusModifier = 1.0f, HellfireFireInterval = 0.3f, MLRSFireInterval = 1.0f, RemoteMLRSFireInterval = 1.0f, AllowUsingOfMLRSForAllPlayers = true, HellFireMaxRocketAmountToSpawn = 50,
}
;
}
protected override void LoadDefaultConfig() {
mConfig = GetDefaultConfig();
}
protected override void SaveConfig() {
Config.WriteObject(mConfig, true);
}
class PluginConfig {
[JsonProperty]
public ulong PluginPicture {
get;
set;
}
[JsonProperty]
public string PluginPrefix {
get;
set;
}
[JsonProperty]
public float HellfireRocketDamageModifier {
get;
set;
}
[JsonProperty]
public float HellfireRocketExplosiveRadiusModifier {
get;
set;
}
[JsonProperty("MLRSFireInterval in seconds")]
public float MLRSFireInterval {
get;
set;
}
[JsonProperty("RemoteMLRSFireInterval in seconds")]
public float RemoteMLRSFireInterval {
get;
set;
}
[JsonProperty("HellfireFireInterval in seconds")]
public float HellfireFireInterval {
get;
set;
}
[JsonProperty("Allow using of MLRS for all players like in vanilla rust")]
public bool AllowUsingOfMLRSForAllPlayers {
get;
set;
}
[JsonProperty("Max amount of rockets which can spawn when using hellfire command with custom missle amount")]
public uint HellFireMaxRocketAmountToSpawn {
get;
set;
}
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["Note_MLRS_StartedAttack"]
= Note_MLRS_StartedAttack, ["Note_MLRS_FiringIn10Sec"] = Note_MLRS_FiringIn10Sec, ["Note_MLRS_Fixed"] = Note_MLRS_Fixed, ["Note_All_MLRS_Fixed"] = Note_All_MLRS_Fixed, ["Note_MLRS_Enabled"] = Note_MLRS_Enabled, ["Note_MLRS_Disabled"] = Note_MLRS_Disabled, ["Note_MLRS_Status_Enabled"] = Note_MLRS_Status_Enabled, ["Note_MLRS_Status_Disabled"] = Note_MLRS_Status_Disabled, ["Error_MLRS_NoMLRS"] = Error_MLRS_NoMLRS, ["Error_MLRS_CantFindPlayer"] = Error_MLRS_CantFindPlayer, ["Error_MLRS_NoMapMark"] = Error_MLRS_NoMapMark, ["Error_MLRS_Disabled"] = Error_MLRS_Disabled, ["Error_MLRS_IsBusy"] = Error_MLRS_IsBusy, ["Error_FoundMultiplePlayer"] = Error_FoundMultiplePlayer, ["Note_HellFire_StartedAttack"] = Note_HellFire_StartedAttack, ["Error_HellFire_NoMapMark"] = Error_HellFire_NoMapMark, ["Error_HellFire_InvalidAmount"] = Error_HellFire_InvalidAmount, ["Error_HellFire_CantFindPlayer"] = Error_HellFire_CantFindPlayer, ["Error_RemoteMLRS_NoMissles"] = Error_RemoteMLRS_NoMissles, ["Error_RemoteMLRS_InvalidAmount"] = Error_RemoteMLRS_InvalidAmount, ["Error_RemoteMLRS_NoMapMark"] = Error_RemoteMLRS_NoMapMark, ["Error_RemoteMLRS_MRLSBroken"] = Error_RemoteMLRS_MRLSBroken, ["Error_NoPermission"] = Error_NoPermission, ["Syntax_MLRS"] = Syntax_MLRS, ["Syntax_HellFire"] = Syntax_HellFire, ["Syntax_RemoteMLRS"] = Syntax_RemoteMLRS
}
, this, "en");
}
#endregion
#region Default Chat Messages
private const string Note_MLRS_StartedAttack = "<color=#F75B00>MLRS started to attack the target.</color>";
private const string Note_MLRS_FiringIn10Sec = "MLRS will start firing in 10 seconds!";
private const string Note_MLRS_Fixed = "Main MLRS has been fixed.";
private const string Note_All_MLRS_Fixed = "All found MLRS has been fixed.";
private const string Note_MLRS_Enabled = "The using of MLRS has been </color><color=#48B11E>enabled</color> for all players.";
private const string Note_MLRS_Disabled = "The using of MLRS has been </color><color=#F70000>disabled</color> for all players.";
private const string Note_MLRS_Status_Enabled = "MLRS is </color><color=#48B11E>enabled</color> for all players on the server.";
private const string Note_MLRS_Status_Disabled = "MLRS is </color><color=#F70000>disabled</color> for all players on the server.";
private const string Error_MLRS_NoMLRS = "</color><color=#F70000>No MRLS was found on the server.</color>";
private const string Error_MLRS_CantFindPlayer = "</color><color=#F70000>Couldn't find this player!</color>\n" + "Type <color=#E9AC3C>/mlrs</color> for help.";
private const string Error_MLRS_NoMapMark = "</color><color=#F70000>No map mark set.Please create a map marker on the map with the name \"MLRSTARGET\" to attack.</color>\n" + "Type <color=#E9AC3C>/mlrs</color> for help.";
private const string Error_MLRS_Disabled = "</color><color=#F70000>MLRS has been disabled on this server.</color>\n";
private const string Error_MLRS_IsBusy = "</color><color=#F70000>MLRS is currently busy.Try it again later.</color>\n";
private const string Note_HellFire_StartedAttack = "<color=#F75B00>Started hellfire attack to the target.</color>";
private const string Error_HellFire_NoMapMark = "</color><color=#F70000>No map mark set.Please mark a point on the map to attack.</color>\n" + "Type <color=#E9AC3C>/hellfire</color> for help.";
private const string Error_HellFire_InvalidAmount = "</color><color=#F70000>Invalid amount of rockets.</color>\n" + "Type <color=#E9AC3C>/hellfire</color> for help.";
private const string Error_HellFire_CantFindPlayer = "</color><color=#F70000>Couldn't find this player!</color>\n" + "Type <color=#E9AC3C>/hellfire</color> for help.";
private const string Error_FoundMultiplePlayer = "</color><color=#ffff00>Found multiple target players, you have to specify it more:</color> ";
private const string Error_RemoteMLRS_NoMissles = "</color><color=#F70000>You don't have any MLRS missles in your inventory!</color>\n" + "Type <color=#E9AC3C>/remotemlrs</color> for help.";
private const string Error_RemoteMLRS_InvalidAmount = "</color><color=#F70000>Invalid amount of rockets.</color>\n" + "Type <color=#E9AC3C>/remotemlrs</color> for help.";
private const string Error_RemoteMLRS_NoMapMark = "</color><color=#F70000>No map mark set.Please mark a point on the map to attack.</color>\n" + "Type <color=#E9AC3C>/remotemlrs</color> for help.";
private const string Error_RemoteMLRS_MRLSBroken = "</color><color=#F70000>MLRS is currently broken! Try it again later.</color>";
private const string Error_NoPermission = "</color><color=#F70000>You don't have the permission to use this plugin command!</color>";
private const string Syntax_MLRS = "<color=#4BF0FF>MLRS Commands:</color>\n" + "<color=#D97E29>/mlrsfire map</color> => MLRS will start to attack the marked spot on the map.\n" + "<color=#D97E29>/mlrsfire map</color> <color=#2990D9>(amount)</color> => MLRS will start to attack the marked spot on the map with the entered amount of rockets.\n" + "<color=#D97E29>/mlrsfire p {playername}</color> => MLRS will start to attack the target players spot.\n" + "<color=#D97E29>/mlrsfire p {playername}</color> <color=#2990D9>(amount)</color> => MLRS will start to attack the target players spot with the entered amount of rockets.\n" + "<color=#D97E29>/mlrsfireall map</color> => All found MLRS start to attack the marked spot on the map.\n" + "<color=#D97E29>/mlrsfireall map</color> <color=#2990D9>(amount)</color> => All found MLRS on this server start to attack the marked spot on the map with the entered amount of rockets.\n" + "<color=#D97E29>/mlrsfireall p {playername}</color> => All found MLRS will start to attack the target players spot.\n" + "<color=#D97E29>/mlrsfireall p {playername}</color> <color=#2990D9>(amount)</color> => All found MLRS will start to attack the target players spot with the entered amount of rockets.\n" + "<color=#D97E29>/mlrsfix</color> => Repears the active MLRS on the server.\n" + "<color=#D97E29>/mlrsfixall</color> => Repears all found MLRS on the server.\n" + "<color=#D97E29>/mlrs enable</color> => Allows all players to use MLRS like in vanilla rust.\n" + "<color=#D97E29>/mlrs disable</color> => Prevent all players to mount/use the MLRS on the server (can be bypassed with perm).\n" + "<color=#D97E29>/mlrs status</color> => Shows you if MLRS is enabled or disabled on this server.";
private const string Syntax_HellFire = "<color=#4BF0FF>HellFire Commands:</color>\n" + "<color=#D97E29>/hellfire p {playername}</color> => MLRS rocket spawns and start to attack the target players spot.\n" + "<color=#D97E29>/hellfire p {playername}</color> <color=#2990D9>(amount)</color> => x MLRS rockets spawning and start to attack the target players spot.\n" + "<color=#D97E29>/hellfire map</color> => MLRS Rocket spawns and start to attack the marked spot on the map.\n" + "<color=#D97E29>/hellfire map</color> <color=#2990D9>(amount)</color> => x MLRS Rocket spawning and start to attack the marked spot on the map.";
private const string Syntax_RemoteMLRS = "<color=#4BF0FF>RemoteMLRS Commands:</color>\n" + "<color=#FFED47>Info:</color> You need MLRS Rockets to call a remote MLRS attack.\n" + "<color=#D97E29>/remotemlrs p {playername}</color> => Calls MLRS attack to target players spot.Takes up to 12 MLRS rockets.(need extra perms)\n" + "<color=#D97E29>/remotemlrs p {playername}</color> <color=#2990D9>(amount)</color> => MLRS will start to attack the target players spot.Takes x (max 12) MLRS rockets (need extra perms)\n" + "<color=#D97E29>/remotemlrs map</color> => MLRS will start to attack the marked spot on the map.Takes up to 12 MLRS rockets.\n" + "<color=#D97E29>/remotemlrs map</color> <color=#2990D9>(amount)</color> => MLRS will start to attack the marked spot on the map.Takes x (max 12) MLRS rockets.\n";
#endregion
#region Used Hooks
object CanMountEntity(BasePlayer player, BaseMountable entity) {
if (!(entity is MLRS) || mConfig.AllowUsingOfMLRSForAllPlayers) return null;
if (!(player.IPlayer.HasPermission(MLRSHellfire_Admin) || player.IPlayer.HasPermission(MLRSHellfire_MLRSMountBypass))) {
ChatReply(player, lang.GetMessage("Error_MLRS_Disabled", this, player.UserIDString));
return false;
}
if (mainMLRS.isBusy) {
ChatReply(player, lang.GetMessage("Error_MLRS_IsBusy", this, player.UserIDString));
return false;
}
return null;
}
#endregion
#region Chat
private void ChatReply(BasePlayer player, string message) => Player.Reply(player, mConfig.PluginPrefix + message, mConfig.PluginPicture);
#endregion
#region Fields/Constants
/// <summary>
/// Path to MLRS missle prefab./// </summary>
private const string MLRSRocketPrefab = "assets/content/vehicles/mlrs/rocket_mlrs.prefab";
/// <summary>
/// Saves all active MLRS on the server./// </summary>
private static List<CustomMLRS> allActiveMRLSOnServer = GetAllActiveMLRS();
/// <summary>
/// This is used to save the damage of MLRS rockets./// </summary>
private static TimedExplosive mlrsRocketTimedExplosive;
/// <summary>
/// This is your main MLRS on your server./// </summary>
private static CustomMLRS mainMLRS = GetActiveMainMLRS();
private const string MapNoteTargetName = "MLRSTARGET";
#endregion
#region Plugin Logic
#region MLRS
[ChatCommand("mlrs")]
private void Mlrs(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
if (args.Length != 1) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
switch (args[0].ToLower()) {
case "enable" : {
mConfig.AllowUsingOfMLRSForAllPlayers = true;
SaveConfig();
ChatReply(player, lang.GetMessage("Note_MLRS_Enabled", this, player.UserIDString));
break;
}
case "disable" : {
mConfig.AllowUsingOfMLRSForAllPlayers = false;
SaveConfig();
ChatReply(player, lang.GetMessage("Note_MLRS_Disabled", this, player.UserIDString));
break;
}
case "status" : {
if (mConfig.AllowUsingOfMLRSForAllPlayers) ChatReply(player, lang.GetMessage("Note_MLRS_Status_Enabled", this, player.UserIDString));
else ChatReply(player, lang.GetMessage("Note_MLRS_Status_Disabled", this, player.UserIDString));
break;
}
default : {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
}
}
[ChatCommand("mlrsfire")]
private void MlrsFire(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
var mlrs = GetActiveMainMLRS();
if (mlrs == null) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMLRS", this, player.UserIDString));
return;
}
if (args.Length < 1 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
if (mainMLRS.isBusy) {
ChatReply(player, lang.GetMessage("Error_MLRS_IsBusy", this, player.UserIDString));
return;
}
Vector3 targetPosition;
int rocketsToSpawn = 0;
switch (args[0].ToLower()) {
case "p" : {
if (args.Length < 2 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
var targetPlayer = SearchAndGetTargetPlayer(args[1], player);
if (targetPlayer != null) {
targetPosition = targetPlayer.ServerPosition;
}
else {
return;
}
if (args.Length == 3) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[2], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
case "map" : {
if (args.Length < 1 || args.Length > 2) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
var worldPosition = GetTargetMapNotePosition(player);
if (worldPosition == Vector3.zero) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMapMark", this, player.UserIDString));
return;
}
targetPosition = worldPosition;
if (args.Length == 2) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[1], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
default : {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
}
mainMLRS.isBusy = true;
if (rocketsToSpawn == 0) rocketsToSpawn = 12;
mlrs.instance.SetRepaired();
var rocketContainer = mlrs.instance.GetRocketContainer();
var mlrsRocket = rocketContainer.allowedItem;
if (rocketsToSpawn > 12) {
rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn);
rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn - 12);
}
else rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn);
mlrs.instance.RocketAmmoCount = rocketsToSpawn;
mlrs.instance.nextRocketIndex = rocketsToSpawn - 1;
mlrs.instance.SetUserTargetHitPos(targetPosition);
ChatReply(player, lang.GetMessage("Note_MLRS_FiringIn10Sec", this, player.UserIDString));
timer.Once(10f, () => {
mlrs.instance.SetFlag(BaseEntity.Flags.Reserved8, b : true);
mlrs.instance.nextRocketIndex = Mathf.Min(mlrs.instance.RocketAmmoCount - 1, mlrs.instance.rocketTubes.Length - 1);
mlrs.instance.radiusModIndex = 0;
mlrs.instance.InvokeRepeating(mlrs.instance.FireNextRocket, 0f, mConfig.MLRSFireInterval);
ChatReply(player, lang.GetMessage("Note_MLRS_StartedAttack", this, player.UserIDString));
}
);
timer.Once((rocketsToSpawn * mConfig.MLRSFireInterval) + 11f, () => {
mainMLRS.isBusy = false;
}
);
}
[ChatCommand("mlrsfireall")]
private void MlrsFireAll(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
if (args.Length < 1 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
var allMLRS = GetAllActiveMLRS();
if (allMLRS.Count == 0) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMLRS", this, player.UserIDString));
return;
}
Vector3 targetPosition;
int rocketsToSpawn = 0;
switch (args[0].ToLower()) {
case "p" : {
if (args.Length < 2 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
var targetPlayer = SearchAndGetTargetPlayer(args[1], player);
if (targetPlayer != null) {
targetPosition = targetPlayer.ServerPosition;
}
else {
return;
}
if (args.Length == 3) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[2], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
case "map" : {
if (args.Length < 1 || args.Length > 2) {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
var worldPosition = GetTargetMapNotePosition(player);
if (worldPosition == Vector3.zero) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMapMark", this, player.UserIDString));
return;
}
targetPosition = worldPosition;
if (args.Length == 2) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[1], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
default : {
ChatReply(player, lang.GetMessage("Syntax_MLRS", this, player.UserIDString));
return;
}
}
if (rocketsToSpawn == 0) rocketsToSpawn = 12;
int busyMLRSCounter = 0;
int removedMLRSCounter = 0;
foreach (var mlrs in allMLRS) {
if (mlrs.instance == null) {
removedMLRSCounter++;
continue;
}
bool isMainMLRS = mlrs.mlrsId == mainMLRS.mlrsId;
if (isMainMLRS && mainMLRS.isBusy) {
busyMLRSCounter++;
continue;
}
if (mlrs.isBusy) {
busyMLRSCounter++;
continue;
}
if (isMainMLRS) mainMLRS.isBusy = true;
mlrs.isBusy = true;
mlrs.instance.SetRepaired();
var rocketContainer = mlrs.instance.GetRocketContainer();
var mlrsRocket = rocketContainer.allowedItem;
if (rocketsToSpawn > 12) {
rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn);
rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn - 12);
}
else rocketContainer.inventory.AddItem(mlrsRocket, rocketsToSpawn);
mlrs.instance.RocketAmmoCount = rocketsToSpawn;
mlrs.instance.nextRocketIndex = rocketsToSpawn - 1;
mlrs.instance.SetUserTargetHitPos(targetPosition);
timer.Once(10f, () => {
mlrs.instance.SetFlag(BaseEntity.Flags.Reserved8, b : true);
mlrs.instance.nextRocketIndex = Mathf.Min(mlrs.instance.RocketAmmoCount - 1, mlrs.instance.rocketTubes.Length - 1);
mlrs.instance.radiusModIndex = 0;
mlrs.instance.InvokeRepeating(mlrs.instance.FireNextRocket, 0f, mConfig.MLRSFireInterval);
}
);
timer.Once((rocketsToSpawn * mConfig.MLRSFireInterval) + 11f, () => {
if (isMainMLRS) mainMLRS.isBusy = false;
mlrs.isBusy = false;
}
);
}
if (busyMLRSCounter + removedMLRSCounter != allMLRS.Count) {
ChatReply(player, lang.GetMessage("Note_MLRS_FiringIn10Sec", this, player.UserIDString));
timer.Once(10f, () => {
ChatReply(player, lang.GetMessage("Note_MLRS_StartedAttack", this, player.UserIDString));
}
);
}
if (busyMLRSCounter != 0) // Neue Note
ChatReply(player, $"<color=#F75B00>{busyMLRSCounter}</color> of <color=#2990D9>{allMLRS.Count}</color> MLRS are currently busy and will be skipped for this operation.");
if (removedMLRSCounter != 0) // Neute Note
ChatReply(player, $"<color=#F75B00>{removedMLRSCounter}</color> of <color=#2990D9>{allMLRS.Count}</color> MLRS aren't there anymore.");
}
[ChatCommand("mlrsfix")]
private void MLRSFix(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
var mlrs = GetActiveMainMLRS();
if (mlrs == null) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMLRS", this, player.UserIDString));
return;
}
mlrs.instance.SetRepaired();
ChatReply(player, lang.GetMessage("Note_MLRS_Fixed", this, player.UserIDString));
}
[ChatCommand("mlrsfixall")]
private void MLRSFixAll(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
var allMlrs = GetAllActiveMLRS();
if (allMlrs == null) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMLRS", this, player.UserIDString));
return;
}
foreach (var mlrs in allMlrs) mlrs.instance.SetRepaired();
ChatReply(player, lang.GetMessage("Note_All_MLRS_Fixed", this, player.UserIDString));
}
#endregion
#region Remote MLRS
[ChatCommand("remotemlrs")]
private void RemoteMlrs(BasePlayer player, string command, string[] args) {
if (!(player.IPlayer.HasPermission(MLRSHellfire_Admin) || player.IPlayer.HasPermission(MLRSHellfire_UseRemoteMLRS))) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
var mlrs = GetActiveMainMLRS();
if (mlrs == null) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMLRS", this, player.UserIDString));
return;
}
if (mainMLRS.isBusy) {
ChatReply(player, lang.GetMessage("Error_MLRS_IsBusy", this, player.UserIDString));
return;
}
if (mlrs.instance.IsBroken()) {
if (!(player.IPlayer.HasPermission(MLRSHellfire_Admin) || player.IPlayer.HasPermission(MLRSHellfire_RemoteMLRS_MLRSBrokenBypass))) {
ChatReply(player, lang.GetMessage("Error_RemoteMLRS_MRLSBroken", this, player.UserIDString));
return;
}
}
if (args.Length < 1 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_RemoteMLRS", this, player.UserIDString));
return;
}
var mlrsMissleContainer = player.inventory.AllItems().Where(item => item.HasAmmo(Rust.AmmoTypes.MLRS_ROCKET)).ToArray();
if (mlrsMissleContainer.Length == 0) {
ChatReply(player, lang.GetMessage("Error_RemoteMLRS_NoMissles", this, player.UserIDString));
return;
}
Vector3 targetPosition;
int rocketsToSpawn = 0;
switch (args[0].ToLower()) {
case "p" : {
if (!(player.IPlayer.HasPermission(MLRSHellfire_Admin) || player.IPlayer.HasPermission(MLRSHellfire_RemoteMLRS_AllowTargetingPlayer))) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
if (args.Length < 2 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_RemoteMLRS", this, player.UserIDString));
return;
}
var targetPlayer = SearchAndGetTargetPlayer(args[1], player);
if (targetPlayer != null) {
targetPosition = targetPlayer.ServerPosition;
}
else {
return;
}
if (args.Length == 3) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[2], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
case "map" : {
if (args.Length < 1 || args.Length > 2) {
ChatReply(player, lang.GetMessage("Syntax_RemoteMLRS", this, player.UserIDString));
return;
}
var worldPosition = GetTargetMapNotePosition(player);
if (worldPosition == Vector3.zero) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMapMark", this, player.UserIDString));
return;
}
targetPosition = worldPosition;
if (args.Length == 2) {
int tmpAmount;
if (IsValidMLRSMissleAmount(args[1], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
default : {
ChatReply(player, lang.GetMessage("Syntax_RemoteMLRS", this, player.UserIDString));
return;
}
}
mainMLRS.isBusy = true;
if (rocketsToSpawn == 0) rocketsToSpawn = 12;
int missleAmount = 0;
foreach (var itemRocketContainer in mlrsMissleContainer) {
if (itemRocketContainer.amount <= 0) continue;
if (itemRocketContainer.amount >= rocketsToSpawn) {
missleAmount = rocketsToSpawn;
if ((itemRocketContainer.amount - rocketsToSpawn) > 0) itemRocketContainer.amount -= rocketsToSpawn;
else itemRocketContainer.DoRemove();
break;
}
else {
if ((missleAmount + itemRocketContainer.amount) > rocketsToSpawn) {
while (missleAmount != rocketsToSpawn) {
missleAmount++;
itemRocketContainer.amount--;
}
break;
}
else {
missleAmount += itemRocketContainer.amount;
itemRocketContainer.DoRemove();
}
}
}
mlrs.instance.SetRepaired();
var rocketContainer = mlrs.instance.GetRocketContainer();
var mlrsRocket = rocketContainer.allowedItem;
rocketContainer.inventory.AddItem(mlrsRocket, missleAmount);
mlrs.instance.RocketAmmoCount = missleAmount;
mlrs.instance.nextRocketIndex = missleAmount - 1;
mlrs.instance.rocketOwnerRef.Set(player);
mlrs.instance.SetUserTargetHitPos(targetPosition);
ChatReply(player, lang.GetMessage("Note_MLRS_FiringIn10Sec", this, player.UserIDString));
timer.Once(10f, () => {
mlrs.instance.SetFlag(BaseEntity.Flags.Reserved8, b : true);
mlrs.instance.nextRocketIndex = Mathf.Min(mlrs.instance.RocketAmmoCount - 1, mlrs.instance.rocketTubes.Length - 1);
mlrs.instance.radiusModIndex = 0;
mlrs.instance.InvokeRepeating(mlrs.instance.FireNextRocket, 0f, mConfig.RemoteMLRSFireInterval);
ChatReply(player, lang.GetMessage("Note_MLRS_StartedAttack", this, player.UserIDString));
}
);
timer.Once((missleAmount * mConfig.RemoteMLRSFireInterval) + 11f, () => {
mainMLRS.isBusy = false;
}
);
}
#endregion
#region Hellfire
[ChatCommand("hellfire")]
private void Hellfire(BasePlayer player, string command, string[] args) {
if (!player.IPlayer.HasPermission(MLRSHellfire_Admin)) {
ChatReply(player, lang.GetMessage("Error_NoPermission", this, player.UserIDString));
return;
}
if (args.Length < 1 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_HellFire", this, player.UserIDString));
return;
}
Vector3 targetPosition;
int rocketsToSpawn = 1;
switch (args[0].ToLower()) {
case "p" : {
if (args.Length < 2 || args.Length > 3) {
ChatReply(player, lang.GetMessage("Syntax_HellFire", this, player.UserIDString));
return;
}
var targetPlayer = SearchAndGetTargetPlayer(args[1], player);
if (targetPlayer != null) {
targetPosition = targetPlayer.ServerPosition;
}
else {
return;
}
if (args.Length == 3) {
int tmpAmount;
if (IsValidHellfireMissleAmount(args[2], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
case "map" : {
if (args.Length < 1 || args.Length > 2) {
ChatReply(player, lang.GetMessage("Syntax_HellFire", this, player.UserIDString));
return;
}
var worldPosition = GetTargetMapNotePosition(player);
if (worldPosition == Vector3.zero) {
ChatReply(player, lang.GetMessage("Error_MLRS_NoMapMark", this, player.UserIDString));
return;
}
targetPosition = worldPosition;
if (args.Length == 2) {
int tmpAmount;
if (IsValidHellfireMissleAmount(args[1], out tmpAmount)) rocketsToSpawn = tmpAmount;
else {
ChatReply(player, lang.GetMessage("Error_HellFire_InvalidAmount", this, player.UserIDString));
return;
}
}
break;
}
default : {
ChatReply(player, lang.GetMessage("Syntax_HellFire", this, player.UserIDString));
return;
}
}
if (rocketsToSpawn != 1) {
timer.Repeat(mConfig.HellfireFireInterval, rocketsToSpawn, () => {
ExecuteFireOperation(player, targetPosition);
}
);
}
else ExecuteFireOperation(player, targetPosition);
ChatReply(player, lang.GetMessage("Note_HellFire_StartedAttack", this, player.UserIDString));
}
#endregion
#region Missle Methods
private void ExecuteFireOperation(BasePlayer player, Vector3 targetPosition) {
float baseGravity;
Vector3 aimToTarget = GetAimToTarget(player.ServerPosition, targetPosition, out baseGravity);
var startPoint = player.ServerPosition;
startPoint.y += 15f;
ServerProjectile projectile;
if (CreateAndSpawnRocket(startPoint, aimToTarget, out projectile) == false) return;
projectile.gravityModifier = baseGravity / (0f - Physics.gravity.y);
}
private Vector3 GetAimToTarget(Vector3 startPosition, Vector3 targetPos, out float baseGravity) {
Vector3 vector = targetPos - startPosition;
float num = 90f;
float num2 = vector.Magnitude2D();
float y = vector.y;
float num5 = 40f;
baseGravity = ProjectileDistToGravity(Mathf.Max(num2, 50f), y, num5, num);
vector.Normalize();
vector.y = 0f;
Vector3 axis = Vector3.Cross(vector, Vector3.up);
vector = Quaternion.AngleAxis(num5, axis) * vector;
return vector;
}
private bool CreateAndSpawnRocket(Vector3 firingPos, Vector3 firingDir, out ServerProjectile mlrsRocketProjectile) {
RaycastHit hitInfo;
float launchOffset = 0f;
if (Physics.Raycast(firingPos, firingDir, out hitInfo, launchOffset, 1236478737)) launchOffset = hitInfo.distance - 0.1f;
var mlrsRocketEntity = GameManager.server.CreateEntity(MLRSRocketPrefab, firingPos + firingDir * launchOffset);
if (mlrsRocketEntity == null) {
mlrsRocketProjectile = null;
return false;
}
mlrsRocketProjectile = mlrsRocketEntity.GetComponent<ServerProjectile>();
var velocityVector = mlrsRocketProjectile.initialVelocity + firingDir * mlrsRocketProjectile.speed;
mlrsRocketProjectile.InitializeVelocity(velocityVector);
var mlrsRocket = mlrsRocketEntity as MLRSRocket;
if (mlrsRocket == null) return false;
ApplyMLRSRocketModfications(ref mlrsRocket);
mlrsRocket.Spawn();
return true;
}
#endregion
#region Helper Methods
private float ProjectileDistToGravity(float x, float y, float θ, float v) {
float num = θ * ((float)Math.PI / 180f);
float num2 = (v * v * x * Mathf.Sin(2f * num) - 2f * v * v * y * Mathf.Cos(num) * Mathf.Cos(num)) / (x * x);
if (float.IsNaN(num2) || num2 < 0.01f) {
num2 = 0f - Physics.gravity.y;
}
return num2;
}
private void ApplyMLRSRocketModfications(ref MLRSRocket mlrsRocket) {
mlrsRocket.explosionRadius *= mConfig.HellfireRocketExplosiveRadiusModifier;
mlrsRocket.damageTypes = GetDamageOfHellfireRocket(mlrsRocket).damageTypes;
}
private BasePlayer SearchAndGetTargetPlayer(string targetPlayername, BasePlayer callingPlayer) {
var targetPlayer = BasePlayer.activePlayerList.Where(x => x.displayName.ToLower().Contains(targetPlayername.ToLower())).ToArray();
var possibleAmountOfTargetPlayer = targetPlayer.Count();
if (possibleAmountOfTargetPlayer == 1) {
return targetPlayer[0];
}
if (!targetPlayer.Any()) {
ChatReply(callingPlayer, lang.GetMessage("Error_MLRS_CantFindPlayer", this, callingPlayer.UserIDString));
return null;
}
if (possibleAmountOfTargetPlayer > 1) {
var possibleTargets = string.Empty;
var allTargets = targetPlayer.Select(x => x.displayName).ToArray();
for (int i = 0; i < allTargets.Length; i++) {
if (i + 1 != allTargets.Length) {
possibleTargets += $"</color><color=#005fff>{allTargets[i]}</color>, ";
continue;
}
else {
possibleTargets += $"</color><color=#005fff>{allTargets[i]}</color>";
}
}
ChatReply(callingPlayer, lang.GetMessage("Error_FoundMultiplePlayer", this, callingPlayer.UserIDString) + possibleTargets);
return null;
}
return null;
}
private bool IsValidHellfireMissleAmount(string amount, out int rocketsToSpawn) {
uint tmpAmount;
rocketsToSpawn = 0;
if (uint.TryParse(amount, out tmpAmount)) {
if (tmpAmount > mConfig.HellFireMaxRocketAmountToSpawn) rocketsToSpawn = (int)mConfig.HellFireMaxRocketAmountToSpawn;
else rocketsToSpawn = (int)tmpAmount;
return true;
}
return false;
}
private bool IsValidMLRSMissleAmount(string amount, out int rocketsToSpawn) {
uint tmpAmount;
rocketsToSpawn = 0;
if (uint.TryParse(amount, out tmpAmount)) {
if (tmpAmount > 12) rocketsToSpawn = 12;
else rocketsToSpawn = (int)tmpAmount;
return true;
}
return false;
}
private static CustomMLRS GetActiveMainMLRS() {
if (mainMLRS != null) return mainMLRS;
foreach (var entity in BaseNetworkable.serverEntities) {
if (entity is MLRS) {
mainMLRS = new CustomMLRS((MLRS)entity);
return mainMLRS;
}
}
return null;
}
private static List<CustomMLRS> GetAllActiveMLRS() {
var allMLRS = _GetAllActiveMLRS();
if (allActiveMRLSOnServer != null) if (allMLRS.Count == allActiveMRLSOnServer.Count) // Bei löschen und neuspawnen eines MLRS, kann das neue nicht angesteuert werden, da dies nicht bemerkt wurde.return allActiveMRLSOnServer; // Einfach HashCode zusätzlich abgleichen und Yalla
allActiveMRLSOnServer = allMLRS;
return allActiveMRLSOnServer;
}
private static List<CustomMLRS> _GetAllActiveMLRS() {
var allFoundMLRS = new List<CustomMLRS>();
foreach (var entity in BaseNetworkable.serverEntities) if (entity is MLRS) allFoundMLRS.Add(new CustomMLRS((MLRS)entity));
return allFoundMLRS;
}
private TimedExplosive GetDamageOfHellfireRocket(MLRSRocket mlrsRocket) {
if (mlrsRocketTimedExplosive != null) return mlrsRocketTimedExplosive;
foreach (var damage in mlrsRocket.damageTypes) damage.amount *= mConfig.HellfireRocketDamageModifier;
mlrsRocketTimedExplosive = new TimedExplosive {
damageTypes = mlrsRocket.damageTypes
}
;
return mlrsRocketTimedExplosive;
}
private Vector3 GetTargetMapNotePosition(BasePlayer player) {
var target = player.State.pointsOfInterest.Where(p => p.label == MapNoteTargetName).ToList();
if (!target.Any()) {
return Vector3.zero;
}
return target.First().worldPosition;
}
#endregion
#region Custom MLRS
class CustomMLRS {
public CustomMLRS(MLRS mlrs) {
instance = mlrs;
mlrsId = mlrs.GetHashCode();
}
public readonly MLRS instance;
public bool isBusy = false;
public readonly int mlrsId;
}
#endregion
#endregion
}
}