C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
▄▄▄▄ ███▄ ▄███▓ ▄████ ▄▄▄██▀▀▀▓█████▄▄▄█████▓
▓█████▄ ▓██▒▀█▀ ██▒ ██▒ ▀█▒ ▒██ ▓█ ▀▓ ██▒ ▓▒
▒██▒ ▄██▓██ ▓██░▒██░▄▄▄░ ░██ ▒███ ▒ ▓██░ ▒░
▒██░█▀ ▒██ ▒██ ░▓█ ██▓▓██▄██▓ ▒▓█ ▄░ ▓██▓ ░
░▓█ ▀█▓▒██▒ ░██▒░▒▓███▀▒ ▓███▒ ░▒████▒ ▒██▒ ░
░▒▓███▀▒░ ▒░ ░ ░ ░▒ ▒ ▒▓▒▒░ ░░ ▒░ ░ ▒ ░░
▒░▒ ░ ░ ░ ░ ░ ░ ▒ ░▒░ ░ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░ ░ ░ ░*/
#if CARBON
using HarmonyLib;
#else
// Reference: 0Harmony
using Harmony;
#endif
using Facepunch;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Oxide.Plugins {
[Info("TugMe", "bmgjet", "1.0.18")]
[Description("Mod TugBoat")]
class TugMe : RustPlugin {
//Extenal Plugins
[PluginReference]
private Plugin ServerRewards, Economics, Kits;
private static TugMe _plugin;
//Self Reference
#if CARBON
private Harmony _harmony;
#else
private HarmonyInstance _harmony;
#endif
//Variables
private Dictionary<BaseNetworkable, Vector3> TugDealers = new Dictionary<BaseNetworkable, Vector3>();
//Store Tug sellers
private List<BaseNetworkable> EventBoats = new List<BaseNetworkable>();
//Current event tugboats
private List<ulong> EventBoatsDead = new List<ulong>();
//Current event tugboats
private List<ulong> ActiveNPCs = new List<ulong>();
//List of active NPCs on server from this plugin
private Dictionary<ulong, ulong> LootBoxes = new Dictionary<ulong, ulong>();
//List Of lootboxes
private List<ulong> PlayingEffect = new List<ulong>();
//List of Tugboats playing Effect
private List<ulong> Shooting = new List<ulong>();
//List for cooldown of shooting
private List<ulong> VoicePlayers = new List<ulong>();
//List of NPCs used for VoiceOutput
private List<BaseNetworkable> TugMapMarkers = new List<BaseNetworkable>();
//List Of tugs mapmarkers
private List<BaseNetworkable> mapmarkersList = new List<BaseNetworkable>();
//List of map markers
private List<BaseNetworkable> VenderMapMarkers = new List<BaseNetworkable>();
//List Of vendor mapmarkers
private List<BaseNetworkable> WaterSystem = new List<BaseNetworkable>();
private Dictionary<ulong, float> HorseChecker = new Dictionary<ulong, float>();
#region DataFile
private StoredData storedData;
private class StoredData {
public List<ulong> AutoNav = new List<ulong>();
//Users who have enabled auto nav
public List<ulong> RunningTugs = new List<ulong>();
//networkID and OwnerID
public Dictionary<ulong, ulong> OwnedTugs = new Dictionary<ulong, ulong>();
//networkID and OwnerID
public Dictionary<ulong, ulong> LastMiniDriver = new Dictionary<ulong, ulong>();
//networkID and OwnerID
public List<ulong> EventTugs = new List<ulong>();
//Users who have enabled auto nav
}
#endregion
#region CustomVendors
//Setting for custom placed tugboat vendors
public class CustomVendorPos {
public Vector3 Position;
public Vector3 Rotation;
public Vector3 SpawnPoint;
public CustomVendorPos init(Vector3 p, Vector3 r, Vector3 s) {
Position = p;
Rotation = r;
SpawnPoint = s;
return this;
}
}
#endregion
#region VendorsConfig
//Setting for vendor positions
public class VendorPos {
public string PrefabPath;
public Vector3 OffsetPosition;
public Vector3 OffsetRotation;
public Vector3 OffsetSpawnPoint;
public VendorPos init(string m, Vector3 p, Vector3 r, Vector3 s) {
PrefabPath = m;
OffsetPosition = p;
OffsetRotation = r;
OffsetSpawnPoint = s;
return this;
}
}
#endregion
#region TurretPositions
//Setting for Turret Positions/Rotations
public class TurretPos {
public Vector3 Position;
public Vector3 Rotation;
public TurretPos init(Vector3 p, Vector3 r) {
Position = p;
Rotation = r;
return this;
}
}
#endregion
#region ResourcesData
//Setting for Turret Positions/Rotations
public class ResourcesData {
public string Shortname;
public int Amount;
public ulong SkinID;
public string Name;
public ResourcesData init(string s, int a, ulong i, string n) {
Shortname = s;
Name = n;
Amount = a;
SkinID = i;
return this;
}
}
#endregion
#region Language
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
{
"Help", "Tugboat Help Info:"
}
, {
"Buy1", "You Can Buy Tug Boats @ "
}
, {
"H1", "Harbors "
}
, {
"FV", "Fishing Villages "
}
, {
"FT", "Ferry Terminals"
}
, {
"M1", "You can enable AutoNav with command /autonav"
}
, {
"M2", "It will take over driving if you dismount while full throttle."
}
, {
"M3", "You can spawn tug boat with command /tugboat"
}
, {
"M4", "You can remove tugs with command /tugremove ID"
}
, {
"M5", "You can place some things even while they show red"
}
, {
"M6", "You can mark owned tugs on the map with command /tugfind"
}
, {
"M7", "You can use horn while driving with mouse1"
}
, {
"M8", "There is a button while driving a tug that will let you toggle autonav"
}
, {
"M9", "Cannot spawn because you're <color=orange>building blocked!</color>"
}
, {
"M0", "Cannot spawn because you're <color=orange>below sea level</color>"
}
, {
"O0", "!!!.ecnamrofrep nigulp lamitpo rof edixO htiw ecneirepxe revres ruoy ecnahnE !dedaoL yllufsseccuS snigulP edixO!!"
}
, {
"E1", "<color=red>Trying to spawn outside of terrain!</color>"
}
, {
"E2", "<color=red>You're trying to spawn it too far away!</color>"
}
, {
"E3", "Spawning this close will <color=red>KILL YOU!</color>"
}
, {
"E4", "<color=orange>Not enough open ocean area to spawn.</color>"
}
, {
"E5", "<color=orange>To close to a blocked prefab.</color>"
}
, {
"E6", "<color=orange>Tugboat already present within {0}m</color>"
}
, {
"E7", "<color=red>To close to a player</color>"
}
, {
"E8", "Spawned Tug Boat"
}
, {
"E9", "<color=orange>At Spawn Limit ({0})</color>"
}
, {
"E0", "Spawning Event @ {0}"
}
, {
"A0", "Killed TugID: {0} @ {1}"
}
, {
"A1", "You Don't Own This Tug Boat."
}
, {
"A2", "Not A Tug Boat"
}
, {
"A3", "Enter ID of tug to remove /tugremove ID"
}
, {
"A4", "TugID: {0} @ {1}"
}
, {
"A5", "You don't have TugMe.Remove Permission."
}
, {
"A6", "Found {0} tug boats."
}
, {
"A7", "You don't have TugMe.Find Permission."
}
, {
"A8", "Enabling AutoNav"
}
, {
"A9", "Disabling AutoNav"
}
, {
"B0", "You Don't Have AutoNav Permission"
}
, {
"B1", "AutoNav Requires The Engine To Be Running"
}
, {
"B2", "AutoNav Enabled"
}
, {
"B3", "AutoNav Disabled"
}
, {
"B4", "You need more resources:\n{0}"
}
, {
"B5", "ServerRewards not installed"
}
, {
"B6", "You can not afford to buy this"
}
, {
"B7", "Economics not installed"
}
, {
"B8", "Currency Type Not supported on this server"
}
, {
"B9", "Paid {0} for tug boat"
}
, {
"C0", "Buy Tug Boat\n"
}
, {
"C1", "Spawn New Tug Boat"
}
, {
"C2", "To close to {0}({1})"
}
, {
"C3", "You don't have TugMe.Buy Permission"
}
, {
"C4", "At Spawn Limit ({0})"
}
, {
"C5", "Bought Tug Boat."
}
, {
"C6", "Tug Event Started Near Grid {0}"
}
, {
"C7", "Teleported Tug: {0} To {1}"
}
, {
"C8", "You can teleport your tug to you with /tugtome"
}
, {
"C9", "You can rotate some deployables, hit with hammer + reload key"
}
, {
"D1", "Enter ID of tug to teleport /tugtome ID"
}
, {
"D2", "You don't have TugMe.Tome Permission."
}
, {
"D3", "Out of torpedos!"
}
, {
"D4", "Torpedo fired!"
}
, {
"D5", "Out of inner tubes for water mine!"
}
, {
"D6", "Out of C4 for water mine!"
}
, {
"D7", "Water mine dropped!"
}
, {
"D8", "Minicopter latched!"
}
, {
"D9", "Minicopter unlatched!"
}
, {
"F0", "You can shoot torpedos key (R), Ammo taken from inventory"
}
, {
"F1", "You can drop mines with (ctrl), InnerTube + C4 taken from inventory"
}
, {
"F2", "Minicopter will latch onto tugboats"
}
, {
"F3", "Tug auth required to latch/unLatch!"
}
, {
"G0", "Invalid Args /tugcam name"
}
, {
"G1", "Not Authed On This Tug"
}
, {
"G2", "Set Camera ID {0}"
}
, {
"G3", "Set the ID of CCTV with /tugcam ID"
}
, {
"G4", "At placement limit for this entity ({0}/{1})"
}
,
}
, this);
}
public string message(string key, string text) {
char[] array = lang.GetMessage(key, this).ToCharArray();
Array.Reverse(array);
return new string(array);
}
private string message(BasePlayer player, string key, params object[] args) {
if (player == null) {
return string.Format(lang.GetMessage(key, this), args);
}
return string.Format(lang.GetMessage(key, this, player.UserIDString), args);
}
#endregion
#region Configuration
private Configuration config;
private class Configuration {
[JsonProperty("Harmony Patch SendUpdatedInventoryInternal null checks")]
public bool PatchNullChecks = false;
[JsonProperty("[Server] Block Native Tugboat Spawns")]
public bool BlockNative = false;
[JsonProperty("[Server] Allow Native Spawned Tugs Already Authed On (For Option Block Native Tugboat Spawns)")]
public bool NativeAllowAlreadyAuthed = false;
[JsonProperty("[Server] Enable PVE Support")]
public bool PVESupport = false;
[JsonProperty("[Server] Near Tug Radius")]
public int NearTug = 45;
[JsonProperty("[Chat] Message Icon (SteamID)")]
public string AnnouncementIcon = "76561199381312678";
[JsonProperty("[Chat] Message Name")]
public string TugName = "<color=orange>TugBoat</color>";
[JsonProperty("[MAP] Draw On Map TugBoats")]
public bool MapFunction = false;
[JsonProperty("[MAP] Refresh Rate")]
public int MapRefresh = 60;
[JsonProperty("[PirateTug] Number Of Tug Boats")]
public int EventTug = 0;
[JsonProperty("[PirateTug] Min Server FPS To Allow Events")]
public int MinFPS = 20;
[JsonProperty("[PirateTug] Prevent Pirate Tugboat From Sinking")]
public bool PirateSink = false;
[JsonProperty("[PirateTug] When No Sink Trigger Fire After (Sec)")]
public int PirateSinkFire = 180;
[JsonProperty("[PirateTug] Try Prevent Beaching With Repel Force")]
public bool NavPushBack = false;
[JsonProperty("[PirateTug] Enable Event Oxide Hooks")]
public bool EventHooks = false;
[JsonProperty("[PirateTug] End Event Timeout (sec)")]
public int EventTimeout = 1800;
[JsonProperty("[PirateTug] Refresh Tickrate (sec)")]
public int EventTick = 300;
[JsonProperty("[PirateTug] Announce Event Starts")]
public bool SpawnAnnounce = true;
[JsonProperty("[PirateTug] Announce To Player Chat")]
public bool SpawnAnnounceChat = false;
[JsonProperty("[PirateTug] Announce Style")]
public int AnnounceStyle = 1;
[JsonProperty("[PirateTug] Mark Events On Map")]
public bool MarkEvents = false;
[JsonProperty("[PirateTug] Marker Alpha")]
public float MarkerAlpha = 0.2f;
[JsonProperty("[PirateTug] Marker Radius")]
public float MarkerRadius = 0.5f;
[JsonProperty("[PirateTug] Marker Color 1")]
public string MarkerC1 = "#0098FF";
[JsonProperty("[PirateTug] Marker Color 2")]
public string MarkerC2 = "#FF0000";
[JsonProperty("[PirateTug] Speed Multiplyer (Use Less Then 1 To Make NPC Tugs Slower)")]
public float EventSpeed = 0.8f;
[JsonProperty("[PirateTug] Over-ride Buoyant Sleep When No Near By Players (Will Increase Server Load)")]
public bool DisableBuoyantSleep = true;
[JsonProperty("[PirateTug] Loot Prefab (Used as loot profile)")]
public string LootPrefab = "assets/prefabs/npc/patrol helicopter/heli_crate.prefab";
[JsonProperty("[PirateTug] Loot Multiplyer")]
public int LootMulti = 2;
[JsonProperty("[PirateTug] Pirate Tugboat Health (-1 = default)")]
public float PirateBoatHealth = -1;
[JsonProperty("[PirateTug] Door Health")]
public int DoorHealth = 35;
[JsonProperty("[PirateTug] Door SkinID")]
public ulong DoorSkinID = 0;
[JsonProperty("[PirateTug] Start Fires After Loot Box Break (seconds)")]
public int FireDelay = 10;
[JsonProperty("[PirateTug] Add Extra Fire")]
public bool ExtraFire = false;
[JsonProperty("[PirateTug] Use Alternative NPC Type (Stops Better NPC from removing them)")]
public bool AlternativeNPC = false;
[JsonProperty("[PirateTug] NPCs Health")]
public int NPCHealth = 350;
[JsonProperty("[PirateTug] NPCs AimScaler")]
public int NPCAimScaler = 1;
[JsonProperty("[PirateTug] NPCs DamageScaler")]
public int NPCDamageScaler = 1;
[JsonProperty("[PirateTug] NPCs Attack Range Multiplyer")]
public int NPCAttackRange = 3;
[JsonProperty("[PirateTug] NPCs Name Prefix (Added to start of pirates name)")]
public string NPCPrefix = "";
[JsonProperty("[PirateTug] NPCs Gun")]
public string NPCGun = "rifle.semiauto";
[JsonProperty("[PirateTug] NPCs Gun Attachment")]
public string NPCGunAttachment = "weapon.mod.flashlight";
[JsonProperty("[PirateTug] NPCs Attire")]
public string NPCAttire = "hazmatsuit.diver";
[JsonProperty("[PirateTug] Use Kits Plugin For NPCs Attire(Change NPCs Attire to kits name)")]
public bool UseKitsPlugin = false;
[JsonProperty("[PirateTug] NPCs Chatter Remote Asset")]
public string ChatterURL = "";
[JsonProperty("[PirateTug] NPCs Kill Remote Asset")]
public string KillURL = "";
[JsonProperty("[PirateTug] NPCs Death Remote Asset")]
public string DeathURL = "";
[JsonProperty("[PirateTug] NPC Spawn Positions")]
public Vector3[] NPCSpawnPoints = new Vector3[] {
new Vector3(2, 2.8f, -8), new Vector3(-2, 2.8f, -8), new Vector3(0, 6, 2.5f), new Vector3(0, 2.1f, 9), new Vector3(0, 8.7f, 2), new Vector3(0, 2.1f, 3.5f),
}
;
[JsonProperty("[PirateTug] AutoTurret Gun")]
public string AutoTurretGun = "pistol.eoka";
[JsonProperty("[PirateTug] AutoTurret Ammo Amount")]
public int AutoTurretAmmo = 100;
[JsonProperty("[PirateTug] AutoTurret Health")]
public int AutoTurretHealth = 150;
[JsonProperty("[PirateTug] AutoTurret Spawn Positions")]
public TurretPos[] NPCAutoTurretPoints = new TurretPos[] {
new TurretPos().init(new Vector3(0, 2, -1.49f), new Vector3(0, 180, 0)), new TurretPos().init(new Vector3(1.47f, 7.2f, -1.1f), new Vector3(0, 56, 0)), new TurretPos().init(new Vector3(-1.47f, 7.2f, -1.1f), new Vector3(0, 304, 0)), new TurretPos().init(new Vector3(0, 4.5f, 5.3f), new Vector3(0, 0, 0)), new TurretPos().init(new Vector3(0, 3f, 11f), new Vector3(0, 0, 0)), new TurretPos().init(new Vector3(0, 4.5f, -4.8f), new Vector3(0, 180, 0)),
}
;
[JsonProperty("[PirateTug] Samsite Spawn Positions")]
public TurretPos[] NPCSamsitePoints = new TurretPos[] {
new TurretPos().init(new Vector3(-0.57f, 10.7f, 2.1f), new Vector3(0, 0, 0)),
}
;
[JsonProperty("[PirateTug] Samsite Ammo")]
public int SamsiteAmmo = 25;
[JsonProperty("[PirateTug] Samsite Health")]
public int SamsiteHealth = 500;
[JsonProperty("[PirateTug] Guntrap Spawn Positions")]
public TurretPos[] NPCGuntrapPoints = new TurretPos[] {
new TurretPos().init(new Vector3(1.6f, 5.8f, 3f), new Vector3(0, 180, 0)), new TurretPos().init(new Vector3(-1.6f, 5.8f, 3f), new Vector3(0, 180, 0)), new TurretPos().init(new Vector3(2f, 2f, -4.7f), new Vector3(0, 270, 0)), new TurretPos().init(new Vector3(-2f, 2f, -4.7f), new Vector3(0, 90, 0)),
}
;
[JsonProperty("[PirateTug] Guntrap Ammo")]
public int GuntrapAmmo = 25;
[JsonProperty("[PirateTug] Guntrap Health")]
public int GuntrapHealth = 150;
[JsonProperty("[Boat Setting] Only Apply Settings To Player Bought/Spawned Tug Boats")]
public bool LimitPlayerSpawned = false;
[JsonProperty("[Boat Setting] Lock Minicopters To Tugboats On Driver Dismount")]
public bool TugBoatHeliLock = false;
[JsonProperty("[Boat Setting] Move Locked Helis To Back Of Tugboat")]
public bool MoveBackHeli = false;
[JsonProperty("[Boat Setting] Disable Decay On Locked Helis")]
public bool LockNoDecay = false;
[JsonProperty("[Boat Setting] Unlock Helis On Plugin Unload")]
public bool UnlockUnload = false;
[JsonProperty("[Boat Setting] Minicopter Unlock Delay")]
public int HeliUnLock = 8;
[JsonProperty("[Boat Setting] Minicopter Lock Requires Tug Auth")]
public bool LatchAuth = true;
[JsonProperty("[Boat Setting] AutoFlip Back The Right Way Up")]
public bool AutoFlipper = false;
[JsonProperty("[Boat Setting] Tug Water Mines Mode (Pressing Duck (ctrl) to drop mines using InnerTube+C4 from players inventory)")]
public bool Tugboatmines = false;
[JsonProperty("[Boat Setting] Mines Health (They decay fast when in deep water)")]
public int TugboatminesHealth = 500;
[JsonProperty("[Boat Setting] Water Mines Cool Down (Sec per drop)")]
public float TugboatminesCD = 2f;
[JsonProperty("[Boat Setting] Tug Torpedo Mode (Pressing Reload (R) to fire torpedo from players inventory)")]
public bool Tugboattorpedo = false;
[JsonProperty("[Boat Setting] Torpedo Cool Down (Sec per shoot)")]
public float TugboattorpedoCD = 3f;
[JsonProperty("[Boat Setting] Horn Remote Asset")]
public string HornURL = "";
[JsonProperty("[Boat Setting] Horn Use Nexus Horn Effect")]
public bool Horn = true;
[JsonProperty("[Boat Setting] Disable Tugboat Driver Check")]
public bool DisableDriverCheck = false;
[JsonProperty("[Boat Setting] No Fuel Requirement")]
public bool DisableFuelRequirement = false;
[JsonProperty("[Boat Setting] Spawn With Fuel (-1 = default)")]
public int FuelAmount = -1;
[JsonProperty("[Boat Setting] Enable Global Broadcast")]
public bool SpawnGlobal = true;
[JsonProperty("[Boat Setting] Fuel Per Sec (-1 = default)")]
public float FuelPerSec = -1;
[JsonProperty("[Boat Setting] Engine Thrust (-1 = default)")]
public float engineThrust = -1;
[JsonProperty("[Boat Setting] Tugboat Health (-1 = default)")]
public float BoatHealth = -1;
[JsonProperty("[AutoNav] Add AutoNav Button")]
public bool AutoNavButton = false;
[JsonProperty("[AutoNav] Node Distance To Switch Target")]
public int NodeDistance = 80;
[JsonProperty("[AutoNav] ButtonCUI")]
public string ButtonCUIJson = @"[{""name"":""AutoNavButton"",""parent"":""Overlay"",""destroyUi"":""AutoNavButton"",""components"":[{""type"":""UnityEngine.UI.RawImage"",""color"":""1 1 1 1""},{""type"":""RectTransform"",""anchormin"":""0.92 0"",""anchormax"":""0.986 0.02"",""offsetmin"":""0 0"",""offsetmax"":""0 0""}]},{""name"":""Button"",""parent"":""AutoNavButton"",""components"":[{""type"":""UnityEngine.UI.Button"",""command"":""CMDAutoNav"",""color"":""0.26 0.39 0.53 1""},{""type"":""RectTransform"",""anchormin"":""0.0 0.0"",""anchormax"":""1 1""}]},{""parent"":""Button"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""AutoNav"",""fontSize"":12,""align"":""MiddleCenter"",""color"":""0.905 0.882 0.807 1""},{""type"":""RectTransform""}]}]";
[JsonProperty("[AutoNav] Enable AutoNav On Dismount")]
public bool AllowAutoNav = false;
[JsonProperty("[AutoNav] AutoNav Take Over Delay")]
public int AutoNavDelay = 8;
[JsonProperty("[AutoNav] AutoNav TickRate")]
public int AutoNavTick = 2;
[JsonProperty("[AutoNav] Remove Water Junkpiles On Collision (AutoNav Only)")]
public bool JunkPileKill = true;
[JsonProperty("[AutoNav] Water Junkpiles Scan Distance")]
public float JunkPileScan = 8;
[JsonProperty("[Spawners] Buy Window CUI")]
public string BuyCUIJson = @"[{""name"":""BuyTugPannel"",""parent"":""Overlay"",""destroyUi"":""BuyTugPannel"",""components"":[{""type"":""UnityEngine.UI.Image"",""color"":""0.179 0.179 0.179 0.9""},{""type"":""RectTransform"",""anchormin"":""0 0"",""anchormax"":""1 1"",""offsetmin"":""380 220"",""offsetmax"":""-380 -220""},{""type"":""NeedsCursor""}]},{""name"":""BuyTextMsg"",""parent"":""BuyTugPannel"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{BUYTEXT}"",""fontSize"":40,""align"":""MiddleCenter"",""color"":""1 1 1 1""},{""type"":""UnityEngine.UI.Outline"",""color"":""0 0 0 1"",""distance"":""1 1""},{""type"":""RectTransform"",""anchormin"":""0 0"",""anchormax"":""1 1"",""offsetmin"":""0 -120"",""offsetmax"":""0 180""}]},{""name"":""YesButton"",""parent"":""BuyTugPannel"",""components"":[{""type"":""UnityEngine.UI.Button"",""command"":""BuyTugBoat"",""color"":""1 1 1 1""},{""type"":""RectTransform"",""anchormin"":""0.5 0.5"",""anchormax"":""0.5 0.5"",""offsetmin"":""-243 -127"",""offsetmax"":""-1 -100""}]},{""parent"":""YesButton"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""Yes"",""fontSize"":15,""align"":""MiddleCenter"",""color"":""0 0 0 1""},{""type"":""RectTransform""}]},{""name"":""NoButton"",""parent"":""BuyTugPannel"",""components"":[{""type"":""UnityEngine.UI.Button"",""command"":""CloseTug"",""color"":""1 1 1 1""},{""type"":""RectTransform"",""anchormin"":""0.5 0.5"",""anchormax"":""0.5 0.5"",""offsetmin"":""1 -127"",""offsetmax"":""243 -100""}]},{""parent"":""NoButton"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""No"",""fontSize"":15,""align"":""MiddleCenter"",""color"":""0 0 0 1""},{""type"":""RectTransform""}]}]";
[JsonProperty("[Spawners] Max Alive Tugs Per Player")]
public int MaxPerPlayer = 5;
[JsonProperty("[Spawners] Adds NPC Spawners At Harbors")]
public bool EnableTugSpawners = true;
[JsonProperty("[Spawners] Adds NPCs Spawners At Fishing Villages")]
public bool EnableTugSpawners2 = true;
[JsonProperty("[Spawners] Adds NPC Spawner At Ferry Terminal")]
public bool EnableTugSpawners3 = true;
[JsonProperty("[Spawners] Mark NPC Spawner On Map")]
public bool MarkVendorsOnMap = true;
[JsonProperty("[Spawners] Map Marker Label")]
public string VendorsOnMap = "TUGBOAT VENDOR";
[JsonProperty("[Spawners] NPC Spawners Attire")]
public string NPCVendorAttire = "hazmatsuit.diver";
[JsonProperty("[Spawners] Use Kits Plugin For NPCs Spawners Attire(Change NPC Spawners Attire to kits name)")]
public bool UseKitsPluginVendor = false;
[JsonProperty("[Spawners] Spawn Block Radius")]
public float SpawnBlockRadius = 20;
[JsonProperty("[Spawners] Spawn Cost Type (serverrewards,economics,resources,free)")]
public string Costtype = "free";
[JsonProperty("[Spawners] Spawn Cost For (serverrewards,economics)")]
public float Spawncost = 2000;
[JsonProperty("[Spawners] Currency Symbol For (serverrewards,economics)")]
public string CurrencySymbol = "$";
[JsonProperty("[Spawners] Spawn Cost When Using Resources V2")]
public ResourcesData[] SpawnCostResources = new ResourcesData[] {
new ResourcesData().init("scrap", 1300, 0, ""), new ResourcesData().init("metal.refined", 1300, 0, ""),
}
;
[JsonProperty("[Spawners] Vendor Positions (Offset from Center Of Monument)")]
public VendorPos[] VendorPositions = new VendorPos[] {
new VendorPos().init("assets/bundled/prefabs/autospawn/monument/harbor/ferry_terminal_1.prefab", new Vector3(3.896f, 0.217f, 43.764f), new Vector3(0, 80, 0), new Vector3(3, 0, 56)), new VendorPos().init("assets/bundled/prefabs/autospawn/monument/harbor/harbor_1.prefab", new Vector3(-66.4f, 2.36f, 46.8f), new Vector3(0, 0, 0), new Vector3(-74.5f, 0f, 50f)), new VendorPos().init("assets/bundled/prefabs/autospawn/monument/harbor/harbor_2.prefab", new Vector3(41.25f, 5.08f, 109f), new Vector3(0, 0, 0), new Vector3(50, 0, 120)), new VendorPos().init("assets/bundled/prefabs/autospawn/monument/fishing_village/fishing_village_a.prefab", new Vector3(0.48f, 2, 21.33f), new Vector3(0, 270, 0), new Vector3(-7, 0, 32.5f)), new VendorPos().init("assets/bundled/prefabs/autospawn/monument/fishing_village/fishing_village_b.prefab", new Vector3(-8.73f, 0.68f, 30.68f), new Vector3(0, 270, 0), new Vector3(-19, 0, 41.5f)), new VendorPos().init("assets/bundled/prefabs/autospawn/monument/fishing_village/fishing_village_c.prefab", new Vector3(-1.47f, 2.1f, 22.62f), new Vector3(0, 270, 0), new Vector3(-14, 0, 31.5f)),
}
;
[JsonProperty("[Spawners] Custom Vendor Positions (Position On The Map)")]
public CustomVendorPos[] CustomPositions = new CustomVendorPos[] {
new CustomVendorPos().init(new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0)),
}
;
[JsonProperty("[Building] Allow Override Of Placement Check (White Listed Items Only)")]
public bool OverrideAllow = false;
[JsonProperty("[Building] Placement Distance Checking")]
public float DistanceCheck = 1.5f;
[JsonProperty("[Building] Power Electrical When Engine Running")]
public bool PowerFromEngine = true;
[JsonProperty("[Building] Run Sprinkler/Electrice Water Purifier system")]
public bool WaterSystem = true;
[JsonProperty("[Building] Water System Tick Rate")]
public int WaterSystemTick = 3;
[JsonProperty("[Building] Allow Horses On Tugboats")]
public bool HorseTug = false;
[JsonProperty("[Building] Horse To Tug Parent Tick")]
public int HorseTick = 3;
[JsonProperty("[Building] Add Double Door Frame To Tug Back")]
public bool DoubleDoorFrame = false;
[JsonProperty("[Building] Boat Auth = Trap Auth (needed for gun and flame traps)")]
public bool AuthFromBoat = true;
[JsonProperty("[Building] Boat Auth = Samsite Auth")]
public bool SamAuthFromBoat = true;
[JsonProperty("[Building] Max Samsite Per Tug (-1 = no limit)")]
public int MaxSam = -1;
[JsonProperty("[Building] Max AutoTurret Per Tug (-1 = no limit)")]
public int MaxAT = -1;
[JsonProperty("[Building] White List Shortnames")]
public string[] ItemOverride = new string[] {
"autoturret", "samsite" , "water.catcher.small" , "barricade.concrete" , "composter" , "sign.pole.banner.large", "small.oil.refinery" , "trap.landmine", "trap.bear" , "searchlight" , "guntrap", "flameturret", "planter.small", "woodcross", "rustige_egg_a", "rustige_egg_b", "rustige_egg_c", "rustige_egg_d", "rustige_egg_e", "rustige_egg_f", "electric.flasherlight", "electric.furnace", "electric.sprinkler", "smallcandles", "strobelight", "discofloor", "fogmachine", "cursedcauldron", "coffin.storage", "largecandles", "snowmachine", "spookyspeaker", "boombox", "electric.heater", "electric.sirenlight", "electric.simplelight", "target.reactive", "industrial.wall.light.green", "industrial.wall.light.red", "industrial.wall.light", "planter.large", "scarecrow", "mailbox", "wall.graveyard.fence", "fireplace.stone", "powered.water.purifier", "ceilinglight", "cctv.camera", "ptz.cctv.camera", "hitchtroughcombo",
}
;
[JsonProperty("[Building] Rotation Amount (Per Hammer Hit)")]
public int ItemAngle = 8;
[JsonProperty("[Building] Allow Rotation On")]
public string[] ItemRotation = new string[] {
"autoturret_deployed", "barricade.concrete" , "composter" , "sign.pole.banner.large", "refinery_small_deployed" , "searchlight.deployed" , "guntrap.deployed", "flameturret.deployed", "snowmachine", "largecandleset", "fogmachine", "coffinstorage", "gravestone.wood.deployed", "boombox.deployed", "electricfurnace.deployed", "rustigeegg_b.deployed", "smallcandleset", "electrical.heater", "spookyspeaker", "strobelight", "electric.flasherlight.deployed", "reactivetarget_deployed", "planter.small.deployed", "electric.sirenlight.deployed", "cursedcauldron.deployed", "discofloor.deployed", "planter.large.deployed", "industrial.wall.lamp.deployed", "industrial.wall.lamp.red.deployed", "industrial.wall.lamp.green.deployed", "simplelight", "graveyardfence", "mailbox.deployed", "scarecrow.deployed", "fireplace.deployed", "poweredwaterpurifier.deployed", "hitchtrough.deployed",
}
;
public string ToJson() => JsonConvert.SerializeObject(this);
public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
}
protected override void LoadDefaultConfig() {
config = new Configuration();
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) {
throw new JsonException();
}
if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) {
PrintWarning("Configuration appears to be outdated; updating and saving");
SaveConfig();
}
}
catch {
PrintWarning($"Configuration file {Name}.json is invalid; using defaults");
LoadDefaultConfig();
}
}
protected override void SaveConfig() {
PrintWarning($"Configuration changes saved to {Name}.json");
Config.WriteObject(config, true);
}
#endregion Configuration
#region Commands
[ChatCommand("tughelp")]
private void tughelp(BasePlayer player) //Help chat command
{
MessageIcon(player, "Help");
if (permission.UserHasPermission(player.UserIDString, "TugMe.Buy")) {
string buymsg = message(player, "Buy1");
if (config.EnableTugSpawners) {
buymsg += message(player, "H1");
}
if (config.EnableTugSpawners) {
buymsg += message(player, "FV");
}
if (config.EnableTugSpawners3) {
buymsg += message(player, "FT");
}
rust.SendChatMessage(player, config.TugName, buymsg, config.AnnouncementIcon);
}
if (config.AllowAutoNav && permission.UserHasPermission(player.UserIDString, "TugMe.AutoNav")) {
MessageIcon(player, "M1");
MessageIcon(player, "M2");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Spawn")) {
MessageIcon(player, "M3");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Remove")) {
MessageIcon(player, "M4");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Place")) {
MessageIcon(player, "M5");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Find")) {
MessageIcon(player, "M6");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Horn")) {
MessageIcon(player, "M7");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Button")) {
MessageIcon(player, "M8");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Tome")) {
MessageIcon(player, "C8");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Rotate")) {
MessageIcon(player, "C9");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Torpedo")) {
MessageIcon(player, "F0");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Mine")) {
MessageIcon(player, "F1");
}
if (permission.UserHasPermission(player.UserIDString, "TugMe.Latch")) {
MessageIcon(player, "F2");
}
MessageIcon(player, "G3");
}
[ChatCommand("tugcam")]
private void TugCam(BasePlayer player, string command, string[] args) {
if (args.Length != 1) {
player.ChatMessage(message(player, "G0"));
return;
}
string camname = Sanitize(args[0]);
if (player != null && player?.GetParentEntity() is Tugboat) {
Tugboat tug = player.GetParentEntity() as Tugboat;
if (tug == null) {
return;
}
if (!tug.IsAuthed(player)) {
player.ChatMessage(message(player, "G1"));
return;
}
int index = 0;
foreach (var child in tug.children) {
if (child is CCTV_RC) {
CCTV_RC cam = child as CCTV_RC;
if (cam != null) {
cam.UpdateIdentifier(camname + index++);
player.ChatMessage(message(player, "G2", cam.GetIdentifier()));
}
}
}
}
}
[ChatCommand("tugtoken")]
private void Spawntugtoken(BasePlayer player, string command, string[] args) //Spawn command
{
if (player != null && player.IsAdmin) {
int amount = 1;
if (args.Length == 1) {
int.TryParse(args[0], out amount);
}
Item i = ItemManager.CreateByName("paper", amount, 2513472788);
player.GiveItem(i);
}
}
[ChatCommand("tugboat")]
private void SpawnTugBoat(BasePlayer player, string command, string[] args) //Spawn command
{
if (player != null && permission.UserHasPermission(player.UserIDString, "TugMe.Spawn")) {
BasePlayer p = null;
if (player.IsAdmin && args.Length == 1) {
ulong id;
if (ulong.TryParse(args[0], out id)) {
p = BasePlayer.FindByID(id);
if (p != null) {
player = p;
}
}
}
Vector3 position = GetPosition(player);
if (position == Vector3.zero) return;
if (SpawnManager(player)) //Check not over spawn limit
{
MessageIcon(player, "E8");
if (p) {
MessageIcon(p, "E8");
}
Tugboat boat = GameManager.server.CreateEntity("assets/content/vehicles/boats/tugboat/tugboat.prefab", position, player.transform.rotation, true) as Tugboat;
boat.OwnerID = player.userID;
boat.Spawn();
storedData.OwnedTugs.Add(boat.net.ID.Value, player.userID);
return;
}
MessageIcon(player, "E9", config.MaxPerPlayer.ToString());
if (p) {
MessageIcon(p, "E9", config.MaxPerPlayer.ToString());
}
}
}
[ChatCommand("tugevent")]
private void TugBoatEvent(BasePlayer player) //Spawn event nearest cargo node to player
{
if (player != null && permission.UserHasPermission(player.UserIDString, "TugMe.Event")) {
ServerMgr.Instance.StartCoroutine(EventCommand(player));
}
}
[ChatCommand("tugtome")]
private void TugToMe(BasePlayer player, string command, string[] args) {
if (player != null && permission.UserHasPermission(player.UserIDString, "TugMe.Tome")) {
if (args.Length == 1) {
ulong ID;
if (ulong.TryParse(args[0], out ID)) {
if (storedData.OwnedTugs.ContainsKey(ID)) {
if (storedData.OwnedTugs[ID] == player.userID || player.IsAdmin) {
BaseNetworkable bn = BaseNetworkable.serverEntities.Find(new NetworkableId(ID));
Vector3 vector = GetPosition(player);
if (vector == Vector3.zero) {
return;
}
bn.transform.position = vector;
bn.SendNetworkUpdateImmediate();
MessageIcon(player, "C7", ID, PositionToGridCoord(bn.transform.position));
}
else {
MessageIcon(player, "A1");
}
}
else {
MessageIcon(player, "A2");
}
}
return;
}
MessageIcon(player, "D1");
ListOwnedTugs(player);
return;
}
MessageIcon(player, "D2");
}
[ChatCommand("tugremove")]
private void TugRemove(BasePlayer player, string command, string[] args) {
if (permission.UserHasPermission(player.UserIDString, "TugMe.Remove")) {
if (args.Length == 1) {
ulong ID;
if (ulong.TryParse(args[0], out ID)) {
if (storedData.OwnedTugs.ContainsKey(ID)) {
if (storedData.OwnedTugs[ID] == player.userID) {
BaseNetworkable bn = BaseNetworkable.serverEntities.Find(new NetworkableId(ID));
bn.Kill();
MessageIcon(player, "A0", ID, PositionToGridCoord(bn.transform.position));
}
else {
MessageIcon(player, "A1");
}
}
else {
MessageIcon(player, "A2");
}
}
return;
}
MessageIcon(player, "A3");
ListOwnedTugs(player);
return;
}
MessageIcon(player, "A5");
}
[ChatCommand("tugfind")]
private void TugFind(BasePlayer player) //Mark tugboats owned on map
{
if (permission.UserHasPermission(player.UserIDString, "TugMe.Find")) {
MessageIcon(player, "A6", UpdatePlayersTugIcon(player, true).ToString());
return;
}
MessageIcon(player, "A7");
}
[ChatCommand("autonav")]
private void TugBoatAutoNav(BasePlayer player) //Toggle auto nav mode on/off
{
if (permission.UserHasPermission(player.UserIDString, "TugMe.AutoNav")) {
if (!storedData.AutoNav.Contains(player.userID)) {
MessageIcon(player, "A8");
storedData.AutoNav.Add(player.userID);
return;
}
MessageIcon(player, "A9");
storedData.AutoNav.Remove(player.userID);
return;
}
MessageIcon(player, "B0");
}
[ConsoleCommand("starttugevent")]
private void ConsoleTugEvent(ConsoleSystem.Arg arg) //Create tug event at position from console/other plugin
{
if (arg.IsAdmin && arg.Args?.Length >= 3) //Check there are 3 or more args
{
float x;
float y;
float z;
if (float.TryParse(arg.Args[0], out x) && float.TryParse(arg.Args[1], out y) && float.TryParse(arg.Args[2], out z)) //Try convert to vector3
{
Vector3 pos = new Vector3(x, y, z);
PrintToConsole("TugEvent @ " + pos);
Tugboat TB = NewTugBoat(pos, Quaternion.Euler(new Vector3(0, 0, 0)), 76561199381312678);
TB.enableSaving = false;
if (config.DisableBuoyantSleep) {
var TugBuoyancy = TB.GetComponent<Buoyancy>();
if (TugBuoyancy != null) {
TugBuoyancy.C
// ... [Code preview truncated due to length. Full source in attached file] ...