C#:
using System.Collections.Generic;
using System.Collections;
using Oxide.Core.Configuration;
using Newtonsoft.Json;
using UnityEngine;
using System.Linq;
using Oxide.Core;
using System;
using Rust;
using static Oxide.Plugins.BradleyEx.BradleyEx;
namespace Oxide.Plugins {
[Info("Bradley", "Ts3Hosting", "1.3.4")]
[Description("Spawn Bradly at other monuments")]
public class Bradley : RustPlugin {
#region Vars
PathEntity pcdData;
private DynamicConfigFile PCDDATA;
public static Bradley _instance;
private BUTTON Main;
public Dictionary<BradleyAPC, MonumentName> BradleySaveData = new Dictionary<BradleyAPC, MonumentName>();
public Dictionary<BradleyAPC, string> BradleyCustomSaveData = new Dictionary<BradleyAPC, string>();
public Dictionary<BradleyAPC, string> BradleyCustomSaveDataRoad = new Dictionary<BradleyAPC, string>();
static System.Random random = new System.Random();
private readonly Dictionary<ulong, Timer> timers = new Dictionary<ulong, Timer>();
private const string theAdmin = "bradley.admin";
public Dictionary<ulong, DateTime> sleepers = new Dictionary<ulong, DateTime>();
#endregion
#region Localization
private new void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["nope"]
= "<color=#ce422b>You lack the perms to use this command!</color>", ["PathAddNew"] = "<color=#ce422b>You Added path marker {0} with speed {1}</color>", ["PauseAddTime"] = "<color=#ce422b>{1} second pause on path marker {0}</color>", ["SpeedAddTime"] = "<color=#ce422b>Speed to next path is now {1} set on path marker {0}</color>", ["Active"] = "<color=#ce422b>The controler is now activated.</color>", ["IsActive"] = "<color=#ce422b>The controller is already active...</color>", ["deactive"] = "<color=#ce422b>The controller is now deactivated.</color>", ["usagecommand"] = "<color=#ce422b>/bradley <activate, deactivate, new, edit, move, delete></color>", ["Newusage"] = "<color=#ce422b>/bradley new <SomeName></color>", ["NotActive"] = "<color=#ce422b>The controller is not active.</color>", ["New"] = "<color=#ce422b>Creating a new path..Use the default USE key to set path markers</color>", ["isthere"] = "<color=#ce422b>This path name already exists...Try editing it instead..</color>", ["editusage"] = "<color=#ce422b>/bradley edit <pathName></color>", ["Editing"] = "<color=#ce422b>You are now editing path {0}....</color>", ["isnotthere"] = "<color=#ce422b>Path {0} does not exist....</color>", ["moveusage"] = "<color=#ce422b>/bradley move <PathName> <pathNumber></color>", ["PathMoved"] = "<color=#ce422b>You just moved the path to your location...</color>", ["NoPath"] = "<color=#ce422b>That path number does not exist...</color>", ["NoPathname"] = "<color=#ce422b>That path name does not exist...</color>", ["deleteusage"] = "<color=#ce422b>/bradley delete <PathName></color>", ["delete"] = "<color=#ce422b>You just deleted path {0}...</color>", ["newHealth"] = "<color=#ce422b>Health changed from {0} to {1}</color>",
}
, this);
}
private void RegisterPermissions() {
permission.RegisterPermission(theAdmin, this);
}
#endregion
#region Config
private ConfigData configData;
class ConfigData {
[JsonProperty(PropertyName = "Monuments to add bradley to")]
public Settings settings {
get;
set;
}
[JsonProperty(PropertyName = "Roads to add bradley to")]
public SettingsRing settingsRing {
get;
set;
}
public class Settings {
public string Button {
get;
set;
}
public Dictionary<MonumentName, bradleyMonumentInfo> MonumentWithBradley {
get;
set;
}
}
public class SettingsRing {
public List<roadRing> RingRoadSettings {
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 {
Button = "USE", MonumentWithBradley = new Dictionary<MonumentName, bradleyMonumentInfo>() {
{
MonumentName.Airfield, new bradleyMonumentInfo()
}
, {
MonumentName.WaterTreatment, new bradleyMonumentInfo()
}
, {
MonumentName.Trainyard, new bradleyMonumentInfo()
}
, {
MonumentName.Powerplant, new bradleyMonumentInfo()
}
, {
MonumentName.Harbor_B, new bradleyMonumentInfo()
}
, {
MonumentName.Harbor_A, new bradleyMonumentInfo()
}
}
}
, settingsRing = new ConfigData.SettingsRing {
RingRoadSettings = new List<roadRing>()
}
, 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, 0, 1)) configData = baseConfig;
if (configData.Version < new VersionNumber(1, 3, 0)) configData.settings.MonumentWithBradley.Add(MonumentName.Harbor_A, new bradleyMonumentInfo());
configData.Version = Version;
PrintWarning("Config update completed!");
}
#endregion
#region The Button
private BUTTON ConvertToButton(string button) {
try {
return (BUTTON)Enum.Parse(typeof(BUTTON), button);
}
catch (Exception) {
return BUTTON.USE;
}
}
#endregion
#region Oxide Hooks
private void Init() {
if (configData.settingsRing.RingRoadSettings.Count <= 0) {
configData.settingsRing.RingRoadSettings.Add(new roadRing {
RingRoadEnabled = true, RespawnMin = 30, Can_Kill_NPC = false, IgnoreSleepers = false, moveForceMax_250_To_2000 = 650f, Health = 1000.0f, CanStop = true, FireRocketAtPlayerBase = false, RocketPrefab = "assets/prefabs/ammo/rocket/rocket_smoke.prefab"
}
);
;
SaveConfig();
}
else if (configData.settingsRing.RingRoadSettings[0].RocketPrefab == null) {
configData.settingsRing.RingRoadSettings[0].RocketPrefab = "assets/prefabs/ammo/rocket/rocket_smoke.prefab";
SaveConfig();
}
_instance = this;
PCDDATA = Interface.Oxide.DataFileSystem.GetFile(Name + "/CustomPaths");
LoadData();
}
private void OnServerInitialized() {
timer.Once(4f, () => {
getpath("airfield");
getpath("watertreatment");
getpath("trainyard");
getpath("powerplant");
getpath("harbor_b");
getpath("harbor_a");
if (configData.settingsRing.RingRoadSettings[0].RingRoadEnabled) spawnroad();
Main = ConvertToButton(configData.settings.Button);
RegisterPermissions();
foreach (var custom in pcdData.pEntity.ToList()) {
GetCustomPath(custom.Key);
}
}
);
}
void Unload() {
foreach (var Brad in BradleySaveData) {
Brad.Key?.Kill();
}
foreach (var BradCustom in BradleyCustomSaveData) {
BradCustom.Key?.Kill();
}
foreach (var BradCustomRoad in BradleyCustomSaveDataRoad) {
BradCustomRoad.Key?.Kill();
}
BradleySaveData.Clear();
BradleyCustomSaveData.Clear();
foreach (BasePlayer player in BasePlayer.activePlayerList) {
if (timers.ContainsKey(player.userID)) timers[player.userID].Destroy();
if (timers.ContainsKey(player.userID)) timers.Remove(player.userID);
}
var Controller = UnityEngine.Object.FindObjectsOfType<PathMaker>();
foreach (var insp in Controller) {
insp.OnDestroy();
}
}
private object CanEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (info == null || info.Initiator == null || !(info.Initiator is BradleyAPC)) return null;
if (entity != null && entity is BuildingBlock && info.Initiator is BradleyAPC) return true;
return null;
}
private object OnEntityTakeDamage(NPCPlayer player, HitInfo info) {
if (info == null || info.Initiator == null || !(info.Initiator is BradleyAPC) || player == null) return null;
BradleyAPC apc = info.Initiator as BradleyAPC;
if (apc == null) return null;
if (BradleySaveData.ContainsKey(apc) || BradleyCustomSaveData.ContainsKey(apc) || BradleyCustomSaveDataRoad.ContainsKey(apc)) {
info.damageTypes = new DamageTypeList();
return true;
}
return null;
}
object CanBradleyApcTarget(BradleyAPC apc, BaseEntity entity) {
if (BradleySaveData.ContainsKey(apc) || BradleyCustomSaveData.ContainsKey(apc) || BradleyCustomSaveDataRoad.ContainsKey(apc)) {
if (BradleyCustomSaveDataRoad.ContainsKey(apc)) {
if (entity is BasePlayer && configData.settingsRing.RingRoadSettings[0].IgnoreSleepers && (entity as BasePlayer).IsSleeping()) {
return false;
}
if (!configData.settingsRing.RingRoadSettings[0].Can_Kill_NPC) if (entity.IsNpc || entity is BaseNpc) return false;
}
if (BradleyCustomSaveData.ContainsKey(apc)) {
if (pcdData.pEntity.ContainsKey(BradleyCustomSaveData[apc]) && !pcdData.pEntity[BradleyCustomSaveData[apc]].Can_Kill_Npc) if (entity.IsNpc || entity is BaseNpc) return false;
}
else if (BradleySaveData.ContainsKey(apc) && !configData.settings.MonumentWithBradley[BradleySaveData[apc]].Can_Kill_NPC) if (entity.IsNpc || entity is BaseNpc) return false;
if (entity is BasePlayer) {
if ((entity as BasePlayer).IsSleeping() && sleepers.ContainsKey((entity as BasePlayer).userID) && sleepers[(entity as BasePlayer).userID] < DateTime.Now) return false;
if ((entity as BasePlayer).userID.IsSteamId()) return null;
else if (BradleySaveData.ContainsKey(apc) && !configData.settings.MonumentWithBradley[BradleySaveData[apc]].Can_Kill_NPC) return false;
}
}
return null;
}
void OnEntityDeath(BradleyAPC bradly, HitInfo info) {
if (BradleySaveData.ContainsKey(bradly)) {
MonumentName name = BradleySaveData[bradly];
if (!configData.settings.MonumentWithBradley.ContainsKey(name)) return;
int time = configData.settings.MonumentWithBradley[name].RespawnMinutes * 60;
timer.Once(time, () => {
getpath(name.ToString().ToLower());
}
);
BradleySaveData.Remove(bradly);
}
else if (BradleyCustomSaveDataRoad.ContainsKey(bradly)) {
int time1 = configData.settingsRing.RingRoadSettings[0].RespawnMin * 60;
timer.Once(time1, () => {
spawnroad();
}
);
BradleyCustomSaveDataRoad.Remove(bradly);
}
else if (BradleyCustomSaveData.ContainsKey(bradly)) {
string name1 = BradleyCustomSaveData[bradly];
int time1 = pcdData.pEntity[name1].RespawnMinutes * 60;
if (time1 <= 0) time1 = 30 * 60;
timer.Once(time1, () => {
GetCustomPath(name1);
}
);
BradleyCustomSaveData.Remove(bradly);
}
}
#endregion
#region Classes & Data
public class bradleyMonumentInfo {
public bool spawn = false;
public float Health = 1000;
public int RespawnMinutes = 30;
public bool Can_Kill_NPC = false;
}
public class roadRing {
public bool RingRoadEnabled;
public int RespawnMin;
public bool Can_Kill_NPC;
public bool IgnoreSleepers;
public float moveForceMax_250_To_2000;
public float Health;
public bool CanStop;
public bool FireRocketAtPlayerBase;
public bool DestroyBuildingBlocks;
public string RocketPrefab;
}
class PathEntity {
public Dictionary<string, Paths> pEntity = new Dictionary<string, Paths>();
}
class Paths {
public float startHealth;
public int RespawnMinutes;
public bool FollowPathBack;
public bool Can_Kill_Npc;
public Dictionary<int, pauseInfo> Path = new Dictionary<int, pauseInfo>();
}
class pauseInfo {
public Vector3 pos;
public int pause;
public float speed;
}
void LoadData() {
try {
pcdData = Interface.Oxide.DataFileSystem.ReadObject<PathEntity>(Name + "/CustomPaths");
}
catch {
PrintWarning("Couldn't load path data.Making new path data.");
pcdData = new PathEntity();
}
}
void SaveData() {
PCDDATA.WriteObject(pcdData);
}
private void OnBradleyApcInitialize(BradleyAPC bradley) {
if (BradleyCustomSaveData.ContainsKey(bradley)) {
//bradley._maxHealth = configs.options.startHealth;
//bradley.health = bradley._maxHealth;
}
}
#endregion
#region Fucntions
internal static Vector3[] FindPathRoad() {
PathList list = null;
Vector3[] points = null;
foreach (var pathFind in TerrainMeta.Path.Roads) {
if (pathFind.Path.GetStartPoint() == pathFind.Path.GetEndPoint()) {
list = pathFind;
break;
}
}
if (list != null) {
points = list.Path.Points;
if (points.Length > 0) {
return points;
}
}
_instance.PrintWarning("RoadRing Path Not Found");
return null;
}
internal static bool isPlayersBuilding(BaseEntity entity, ulong playerID) {
BuildingPrivlidge theBlock = entity?.GetBuildingPrivilege();
if (theBlock != null && theBlock.IsAuthed(playerID) || theBlock != null && theBlock.OwnerID == playerID) return true;
return false;
}
public void spawnroad() {
Vector3 position = Vector3.zero;
BradleyAPC bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.RoadRing = true;
BradleyCustomSaveDataRoad.Add(bradly, "new");
//Brad.Custom = true;
}
public void GetCustomPath(string name) {
foreach (var custom in pcdData.pEntity.ToList()) {
List<Vector3> Path = new List<Vector3>();
Path.Clear();
if (custom.Key.ToLower() == name) {
if (pcdData.pEntity[custom.Key].Path.Count <= 0) {
PrintError($"No path for bradley with datafile ({custom.Key})");
return;
}
Vector3 position = pcdData.pEntity[custom.Key].Path[0].pos;
BradleyAPC bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
bradly.ClearPath();
foreach (var customPath in pcdData.pEntity[custom.Key].Path.ToList()) {
Path.Add(customPath.Value.pos);
}
bradly.currentPath = Path;
bradly.pathLooping = true;
BradleyCustomSaveData.Add(bradly, name);
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.Custom = true;
Brad.MonumentName = name;
float health = bradly._maxHealth;
if (pcdData.pEntity[custom.Key].startHealth != null && pcdData.pEntity[custom.Key].startHealth >= 1) {
health = pcdData.pEntity[custom.Key].startHealth;
bradly._maxHealth = health;
bradly.health = bradly._maxHealth;
}
}
}
}
public void getpath(string name) {
foreach (var monument in UnityEngine.Object.FindObjectsOfType<MonumentInfo>()) {
BradleyAPC bradly = null;
List<Vector3> Path = new List<Vector3>();
Path.Clear();
bool canSpawn = false;
var monumentName = monument.GetMonumentName();
float health = 0;
if (!configData.settings.MonumentWithBradley.ContainsKey(monumentName) || !configData.settings.MonumentWithBradley[monumentName].spawn) continue;
else canSpawn = true;
if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "airfield") {
Vector3 position = monument.transform.TransformPoint(new Vector3(-86.86411f, 0.3000298f, 38.17391f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
BradleySaveData.Add(bradly, monumentName);
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
else if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "watertreatment") {
Vector3 position = monument.transform.TransformPoint(new Vector3(96.74454f, 0.1126404f, 31.32247f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
BradleySaveData.Add(bradly, monumentName);
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
else if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "trainyard") {
Vector3 position = monument.transform.TransformPoint(new Vector3(66.8533f, 0.1389904f, -2.566289f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
BradleySaveData.Add(bradly, monumentName);
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
else if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "powerplant") {
Vector3 position = monument.transform.TransformPoint(new Vector3(18.3474f, 0.1845f, 67.7239f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
BradleySaveData.Add(bradly, monumentName);
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
else if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "harbor_b") {
Vector3 position = monument.transform.TransformPoint(new Vector3(-30.7f, 4.9f, -77.9f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
BradleySaveData.Add(bradly, monumentName);
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
else if (canSpawn && name.ToLower() == monumentName.ToString().ToLower() && name.ToLower() == "harbor_a") {
Vector3 position = monument.transform.TransformPoint(new Vector3(100.5f, 5.1f, -21.75f));
bradly = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", position) as BradleyAPC;
bradly.enableSaving = false;
bradly.Spawn();
BradleySaveData.Add(bradly, monumentName);
bradly.ClearPath();
bradly.currentPath = Path;
bradly.pathLooping = true;
bradly.SendNetworkUpdateImmediate();
BradlyAI Brad = bradly.gameObject.AddComponent<BradlyAI>();
Brad.bradly = bradly;
Brad.monument = monument;
Brad.MonumentName = monumentName.ToString().ToLower();
}
if (!configData.settings.MonumentWithBradley.ContainsKey(monumentName) && configData.settings.MonumentWithBradley[monumentName].Health > 0) {
bradly._maxHealth = configData.settings.MonumentWithBradley[monumentName].Health;
bradly.health = bradly._maxHealth;
}
}
}
#endregion
#region Chat Commands
[ChatCommand("bradley")]
private void thePath(BasePlayer player, string cmd, string[] args) {
if (!permission.UserHasPermission(player.userID.ToString(), theAdmin)) {
SendReply(player, lang.GetMessage("nope", this, player.UserIDString));
return;
}
if (args.Length < 1) {
SendReply(player, string.Format(lang.GetMessage("usagecommand", this, player.UserIDString)));
return;
}
switch (args[0].ToLower()) {
case "activate" : PathMaker Checking = player.GetComponent<PathMaker>();
if (Checking == null) {
player.gameObject.AddComponent<PathMaker>();
SendReply(player, string.Format(lang.GetMessage("Active", this, player.UserIDString)));
}
else SendReply(player, string.Format(lang.GetMessage("IsActive", this, player.UserIDString)));
return;
case "new" : if (args.Length < 2) {
SendReply(player, string.Format(lang.GetMessage("Newusage", this, player.UserIDString)));
return;
}
PathMaker Controller = player.GetComponent<PathMaker>();
if (Controller == null) {
SendReply(player, string.Format(lang.GetMessage("NotActive", this, player.UserIDString)));
return;
}
if (!pcdData.pEntity.ContainsKey(args[1].ToLower())) {
pcdData.pEntity.Add(args[1].ToLower(), new Paths());
SaveData();
Controller.MonumentName = args[1].ToLower();
Controller.active = true;
SendReply(player, string.Format(lang.GetMessage("New", this, player.UserIDString)));
}
else {
SendReply(player, string.Format(lang.GetMessage("isthere", this, player.UserIDString)));
return;
}
return;
case "deactivate" : PathMaker deactive = player.GetComponent<PathMaker>();
if (deactive != null) {
deactive.active = false;
deactive.OnDestroy();
SendReply(player, string.Format(lang.GetMessage("deactive", this, player.UserIDString)));
}
return;
case "edit" : if (args.Length < 2) {
SendReply(player, string.Format(lang.GetMessage("editusage", this, player.UserIDString)));
return;
}
PathMaker Controlleredit = player.GetComponent<PathMaker>();
if (Controlleredit == null) {
SendReply(player, string.Format(lang.GetMessage("NotActive", this, player.UserIDString)));
return;
}
if (pcdData.pEntity.ContainsKey(args[1].ToLower())) {
Controlleredit.MonumentName = args[1].ToLower();
Controlleredit.update = true;
Controlleredit.active = true;
SendReply(player, string.Format(lang.GetMessage("Editing", this, player.UserIDString), args[1].ToLower()));
}
else {
SendReply(player, string.Format(lang.GetMessage("isnotthere", this, player.UserIDString), args[1].ToLower()));
return;
}
return;
case "move" : if (args.Length < 3) {
SendReply(player, string.Format(lang.GetMessage("moveusage", this, player.UserIDString)));
return;
}
PathMaker ControllerMove = player.GetComponent<PathMaker>();
if (ControllerMove == null) {
SendReply(player, string.Format(lang.GetMessage("NotActive", this, player.UserIDString)));
return;
}
var ids = default(int);
if (!int.TryParse(args[2], out ids)) {
SendReply(player, string.Format(lang.GetMessage("moveusage", this, player.UserIDString)));
return;
}
if (pcdData.pEntity.ContainsKey(args[1].ToLower())) {
if (pcdData.pEntity[args[1].ToLower()].Path.ContainsKey(ids)) {
pcdData.pEntity[args[1].ToLower()].Path[ids].pos = player.transform.position;
SaveData();
SendReply(player, string.Format(lang.GetMessage("PathMoved", this, player.UserIDString)));
return;
}
SendReply(player, string.Format(lang.GetMessage("NoPath", this, player.UserIDString)));
}
else {
SendReply(player, string.Format(lang.GetMessage("NoPathname", this, player.UserIDString)));
return;
}
return;
case "delete" : if (args.Length < 2) {
SendReply(player, string.Format(lang.GetMessage("deleteusage", this, player.UserIDString)));
return;
}
if (pcdData.pEntity.ContainsKey(args[1].ToLower())) {
pcdData.pEntity.Remove(args[1].ToLower());
SaveData();
foreach (var BradCustom in BradleyCustomSaveData.ToList()) {
if (BradCustom.Value == args[1].ToLower()) {
BradleyCustomSaveData.Remove(BradCustom.Key);
BradCustom.Key?.Kill();
}
}
SendReply(player, string.Format(lang.GetMessage("delete", this, player.UserIDString), args[1].ToLower()));
}
else SendReply(player, string.Format(lang.GetMessage("NoPathname", this, player.UserIDString)));
return;
case "health" : if (args.Length < 3) {
SendReply(player, string.Format(lang.GetMessage("healthusage", this, player.UserIDString)));
return;
}
if (pcdData.pEntity.ContainsKey(args[1].ToLower())) {
var health = default(float);
if (!float.TryParse(args[2], out health)) {
SendReply(player, string.Format(lang.GetMessage("healthusage", this, player.UserIDString)));
return;
}
float oldhealth = 0;
if (pcdData.pEntity[args[1].ToLower()].startHealth != null) oldhealth = pcdData.pEntity[args[1].ToLower()].startHealth;
pcdData.pEntity[args[1].ToLower()].startHealth = health;
SendReply(player, string.Format(lang.GetMessage("newHealth", this, player.UserIDString), oldhealth, health.ToString()));
SaveData();
return;
}
else {
SendReply(player, string.Format(lang.GetMessage("isnotthere", this, player.UserIDString), args[1].ToLower()));
return;
}
SendReply(player, string.Format(lang.GetMessage("healthusage", this, player.UserIDString)));
return;
default : break;
}
}
#endregion
#region Path Maker Controller
public class PathMaker : MonoBehaviour {
public BasePlayer player;
public string MonumentName = "";
public bool active;
public float nextPressTime;
public int total;
public bool update;
public Vector3 stop = Vector3.zero;
public float speedSet = 650.0f;
private void Awake() {
player = GetComponent<BasePlayer>();
}
public void OnDestroy() {
if (_instance.timers.ContainsKey(player.userID)) _instance.timers[player.userID].Destroy();
if (_instance.timers.ContainsKey(player.userID)) _instance.timers.Remove(player.userID);
if (_instance.pcdData.pEntity.ContainsKey(MonumentName)) {
if (_instance.pcdData.pEntity[MonumentName].Path.Count <= 0) _instance.pcdData.pEntity.Remove(MonumentName);
_instance.SaveData();
}
Destroy(this);
}
private void Update() {
if (MonumentName == "" || !_instance.pcdData.pEntity.ContainsKey(MonumentName)) return;
if (update) {
update = false;
total = _instance.pcdData.pEntity[MonumentName].Path.Count + 1;
}
if (player == null || !player.IsConnected) {
Destroy(this);
return;
}
if (!active) return;
if (player.serverInput.WasJustPressed(BUTTON.RELOAD)) {
float time = Time.realtimeSinceStartup;
if (nextPressTime < time) {
nextPressTime = time + 0.2f;
int newpos = total - 1;
if (_instance.pcdData.pEntity[MonumentName].Path.ContainsKey(newpos)) {
if (_instance.pcdData.pEntity[MonumentName].Path[newpos].speed >= 2000f) {
speedSet = 650.0f;
_instance.pcdData.pEntity[MonumentName].Path[newpos].speed = speedSet;
}
else {
_instance.pcdData.pEntity[MonumentName].Path[newpos].speed += 50.0f;
speedSet = _instance.pcdData.pEntity[MonumentName].Path[newpos].speed;
}
_instance.SendReply(player, _instance.lang.GetMessage("SpeedAddTime", _instance, player.UserIDString), newpos.ToString(), _instance.pcdData.pEntity[MonumentName].Path[newpos].speed);
}
}
}
if (player.serverInput.WasJustPressed(_instance.Main)) {
float time = Time.realtimeSinceStartup;
if (nextPressTime < time) {
nextPressTime = time + 0.2f;
if (Vector3.Distance(stop, player.transform.position) <= 0.01) {
int newpos = total - 1;
if (_instance.pcdData.pEntity[MonumentName].Path.ContainsKey(newpos)) {
if (_instance.pcdData.pEntity[MonumentName].Path[newpos].pause >= 60) {
_instance.pcdData.pEntity[MonumentName].Path[newpos].pause = 0;
}
else _instance.pcdData.pEntity[MonumentName].Path[newpos].pause += 10;
_instance.SendReply(player, _instance.lang.GetMessage("PauseAddTime", _instance, player.UserIDString), newpos.ToString(), _instance.pcdData.pEntity[MonumentName].Path[newpos].pause);
}
}
else {
stop = player.transform.position;
_instance.pcdData.pEntity[MonumentName].Path.Add(total, new pauseInfo());
_instance.pcdData.pEntity[MonumentName].Path[total].pos = player.transform.position;
_instance.pcdData.pEntity[MonumentName].Path[total].speed = speedSet;
_instance.SendReply(player, _instance.lang.GetMessage("PathAddNew", _instance, player.UserIDString), total.ToString(), speedSet.ToString());
total++;
}
_instance.SaveData();
}
}
if (_instance.timers.ContainsKey(player.userID)) return;
if (!_instance.pcdData.pEntity.ContainsKey(MonumentName)) return;
if (_instance.pcdData.pEntity[MonumentName].Path.Count <= 0) return;
_instance.timers[player.userID] = _instance.timer.Every(2.0f, () => {
foreach (var output in _instance.pcdData.pEntity[MonumentName].Path.ToList()) {
DrawUi("<size=40>" + output.Key.ToString() + "</size> Speed " + output.Value.speed.ToString(), output.Value.pos);
}
}
);
}
void DrawUi(string format, Vector3 pos) {
if (player == null || player.IsDead() || player.IsSleeping() || !player.IsConnected) return;
if (Vector3.Distance(player.transform.position, pos) > 100) return;
if (player.IsAdmin) {
player.SendConsoleCommand("ddraw.text", 2.0f, "#ffffff", pos + new Vector3(0, 0.5f, 0), format);
}
else {
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
player.SendNetworkUpdateImmediate();
player.SendConsoleCommand("ddraw.text", 2.0f, "#ffffff", pos + new Vector3(0, 0.5f, 0), format);
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
player.SendNetworkUpdateImmediate();
}
}
}
#endregion
#region BradlyAI Controller
public class BradlyAI : MonoBehaviour {
public BradleyAPC bradly;
public BasePlayer player;
public MonumentInfo monument;
public string MonumentName;
public List<Vector3> Path = new List<Vector3>();
private Coroutine QueuedRoutine;
public bool stopped;
public float lastSeenTime = 0f;
public int currentPathIndex;
public bool Custom;
public bool RoadRing;
public DateTime Active;
private Vector3 aimVector = Vector3.forward;
private Vector3 aimVectorTop = Vector3.forward;
private int oldpath = 0;
private bool IsAiming;
private bool reverse;
private bool isPausePos;
private DateTime pauseTime = DateTime.Now;
private DateTime NextpauseTime = DateTime.Now;
private int pauseIndex;
private bool okGo;
private float moveForce = 650.0f;
private float rocketTime {
get;
set;
}
private Dictionary<int, float> speed = new Dictionary<int, float>();
private Dictionary<int, int> stopPause = new Dictionary<int, int>();
private void Awake() {
bradly = GetComponent<BradleyAPC>();
Active = DateTime.Now.AddSeconds(2);
_instance.NextTick(() => {
//monument.GetMonumentName();
if (monument != null && _instance.configData.settings.MonumentWithBradley.ContainsKey(monument.GetMonumentName()) && _instance.configData.settings.MonumentWithBradley[monument.GetMonumentName()].Health > 0) {
bradly._maxHealth = _instance.configData.settings.MonumentWithBradley[monument.GetMonumentName()].Health;
bradly.health = bradly._maxHealth;
bradly.SendNetworkUpdateImmediate();
}
MakePath(RoadRing);
}
);
moveForce = 650f;
bradly.moveForceMax = moveForce;
rocketTime = Time.time + 10;
}
void Relocate() {
if (isPausePos) {
if (pauseTime <= DateTime.Now) {
NextpauseTime = DateTime.Now.AddSeconds(2);
isPausePos = false;
}
}
else if (bradly.targetList.Count <= 0 && !isPausePos) {
aimWeaponAt();
StartMoving();
CancelInvoke("Relocate");
return;
}
else if (!isPausePos && bradly.targetList.Count >= 1) {
foreach (var target in bradly.targetList.ToList()) {
if (target.entity is BasePlayer && (target.entity as BasePlayer).IsSleeping() && !_instance.sleepers.ContainsKey((target.entity as BasePlayer).userID)) _instance.sleepers.Add((target.entity as BasePlayer).userID, DateTime.Now.AddSeconds(10));
if (UnityEngine.Time.time > target.lastSeenTime + 10) {
bradly.targetList.Remove(target);
}
}
if (_instance.sleepers.Count > 0) foreach (var sleeper in _instance.sleepers.ToList()) {
if (sleeper.Value.AddSeconds(180) < DateTime.Now) _instance.sleepers.Remove(sleeper.Key);
}
}
}
private int isStuck {
get;
set;
}
private float nextStuckTime {
get;
set;
}
private Vector3 stuckPath {
get;
set;
}
private bool IsStuck() {
nextStuckTime = Time.time + 1.5f;
if (stopped) return false;
float distance = Vector3.Distance(stuckPath, bradly.transform.position);
if (distance > 0.01f) {
stuckPath = bradly.transform.position;
isStuck = 0;
}
else if (distance < 0.01f) isStuck++;
if (isStuck >= 5) {
isStuck = 0;
bradly.transform.position = Path[bradly.currentPathIndex];
return true;
}
return false;
}
public static bool IsOdd(int value) {
return value % 2 != 0;
}
private void MakePath(bool start = false) {
Path.Clear();
if (RoadRing) {
int number = 0;
Vector3[] newPath = FindPathRoad();
if (newPath == null || newPath.Length <= 0) {
_instance.PrintWarning("No path for bradley road ring.");
bradly?.Kill();
return;
}
foreach (Vector3 pos in newPath) {
if (IsOdd(number)) Path.Add(pos);
number++;
}
if (start) {
bradly.transform.position = Path[0];
bradly._maxHealth = _instance.configData.settingsRing.RingRoadSettings[0].Health;
bradly.health = bradly._maxHealth;
bradly.SendNetworkUpdateImmediate();
}
moveForce = _instance.configData.settingsRing.RingRoadSettings[0].moveForceMax_250_To_2000;
bradly.moveForceMax = moveForce;
}
else if (!Custom) {
var monumentName = monument.GetMonumentName();
if (MonumentName.ToLower() == "airfield") {
Path.Add(monument.transform.TransformPoint(new Vector3(-86.86411f, 0.3000298f, 38.17391f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-89.63014f, 0.232235f, 18.8835f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-136.7101f, 0.300005f, -9.763386f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-95.21716f, 0.309103f, -8.810207f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-70.59235f, 0.3139439f, -39.47253f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-44.59235f, 0.3139439f, -39.47253f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-36.59235f, 0.3139439f, -57.73223f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-02.59235f, 0.3139439f, -57.73223f)));
Path.Add(monument.transform.TransformPoint(new Vector3(6.59235f, 0.3139439f, -39.47253f)));
Path.Add(monument.transform.TransformPoint(new Vector3(16.50055f, 0.3000298f, -39.47253f)));
Path.Add(monument.transform.TransformPoint(new Vector3(145.2082f, 0.3000278f, -39.47253f)));
Path.Add(monument.transform.TransformPoint(new Vector3(136.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(45.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(45.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(7.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(7.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-30.1699f, 0.3000011f, -8.187582f)));
Path.Add(monument.transform.TransformPoint(new Vector3(-83.80389f,
// ... [Code preview truncated due to length. Full source in attached file] ...